- Timestamp: added functions to handle times with ns resolution

pull/215/head
Michael Zillgith 6 years ago
parent d0da45be41
commit 33db13de16

@ -1,7 +1,7 @@
/*
* iec61850_common.c
*
* Copyright 2013 Michael Zillgith
* Copyright 2013-2020 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -341,14 +341,12 @@ Timestamp_setSubsecondPrecision(Timestamp* self, int subsecondPrecision)
void
Timestamp_setTimeInSeconds(Timestamp* self, uint32_t secondsSinceEpoch)
{
uint8_t* timeArray = (uint8_t*) &secondsSinceEpoch;
uint8_t* valueArray = self->val;
#if (ORDER_LITTLE_ENDIAN == 1)
memcpyReverseByteOrder(valueArray, timeArray, 4);
#else
memcpy(valueArray, timeArray, 4);
#endif
valueArray[0] = (secondsSinceEpoch / 0x1000000 & 0xff);
valueArray[1] = (secondsSinceEpoch / 0x10000 & 0xff);
valueArray[2] = (secondsSinceEpoch / 0x100 & 0xff);
valueArray[3] = (secondsSinceEpoch & 0xff);
self->val[4] = 0;
self->val[5] = 0;
@ -358,18 +356,16 @@ Timestamp_setTimeInSeconds(Timestamp* self, uint32_t secondsSinceEpoch)
}
void
Timestamp_setTimeInMilliseconds(Timestamp* self, uint64_t millisSinceEpoch)
Timestamp_setTimeInMilliseconds(Timestamp* self, msSinceEpoch millisSinceEpoch)
{
uint32_t timeval32 = (uint32_t) (millisSinceEpoch / 1000LL);
uint8_t* timeArray = (uint8_t*) &timeval32;
uint8_t* valueArray = self->val;
#if (ORDER_LITTLE_ENDIAN == 1)
memcpyReverseByteOrder(valueArray, timeArray, 4);
#else
memcpy(valueArray, timeArray, 4);
#endif
valueArray[0] = (timeval32 / 0x1000000 & 0xff);
valueArray[1] = (timeval32 / 0x10000 & 0xff);
valueArray[2] = (timeval32 / 0x100 & 0xff);
valueArray[3] = (timeval32 & 0xff);
uint32_t remainder = (millisSinceEpoch % 1000LL);
uint32_t fractionOfSecond = (remainder) * 16777 + ((remainder * 216) / 1000);
@ -382,32 +378,57 @@ Timestamp_setTimeInMilliseconds(Timestamp* self, uint64_t millisSinceEpoch)
/* don't touch time quality */
}
void
Timestamp_setTimeInNanoseconds(Timestamp* self, nsSinceEpoch nsTime)
{
uint32_t timeval32 = (nsTime / 1000000000LLU);
uint8_t* valueArray = self->val;
valueArray[0] = (timeval32 / 0x1000000 & 0xff);
valueArray[1] = (timeval32 / 0x10000 & 0xff);
valueArray[2] = (timeval32 / 0x100 & 0xff);
valueArray[3] = (timeval32 & 0xff);
uint64_t remainder = (nsTime % 1000000000LLU);
remainder = remainder << 24;
remainder = remainder / 1000000000UL;
uint32_t fractionOfSecond = (uint32_t) remainder;
/* encode fraction of second */
valueArray[4] = ((fractionOfSecond >> 16) & 0xff);
valueArray[5] = ((fractionOfSecond >> 8) & 0xff);
valueArray[6] = (fractionOfSecond & 0xff);
/* don't touch time quality */
}
uint32_t
Timestamp_getTimeInSeconds(Timestamp* self)
{
uint32_t timeval32;
uint8_t* valueArray = self->val;
#if (ORDER_LITTLE_ENDIAN == 1)
memcpyReverseByteOrder((uint8_t*) &timeval32, valueArray, 4);
#else
memcpy((uint8_t*) &timeval32, valueArray, 4);
#endif
timeval32 = valueArray[3];
timeval32 += valueArray[2] * 0x100;
timeval32 += valueArray[1] * 0x10000;
timeval32 += valueArray[0] * 0x1000000;
return timeval32;
}
uint64_t
msSinceEpoch
Timestamp_getTimeInMs(Timestamp* self)
{
uint32_t timeval32;
uint8_t* valueArray = self->val;
#if (ORDER_LITTLE_ENDIAN == 1)
memcpyReverseByteOrder((uint8_t*) &timeval32, valueArray, 4);
#else
memcpy((uint8_t*) &timeval32, valueArray, 4);
#endif
timeval32 = valueArray[3];
timeval32 += valueArray[2] * 0x100;
timeval32 += valueArray[1] * 0x10000;
timeval32 += valueArray[0] * 0x1000000;
uint32_t fractionOfSecond = 0;
@ -422,6 +443,33 @@ Timestamp_getTimeInMs(Timestamp* self)
return (uint64_t) msVal;
}
nsSinceEpoch
Timestamp_getTimeInNs(Timestamp* self)
{
uint32_t timeval32;
uint8_t* valueArray = self->val;
timeval32 = valueArray[3];
timeval32 += valueArray[2] * 0x100;
timeval32 += valueArray[1] * 0x10000;
timeval32 += valueArray[0] * 0x1000000;
uint32_t fractionOfSecond;
fractionOfSecond = valueArray[6];
fractionOfSecond += valueArray[5] * 0x100;
fractionOfSecond += valueArray[4] * 0x10000;
uint64_t nsVal = fractionOfSecond;
nsVal = nsVal * 1000000000UL;
nsVal = nsVal >> 24;
uint64_t timeval64 = (uint64_t) timeval32 * 1000000000LLU + nsVal;
return timeval64;
}
void
Timestamp_setByMmsUtcTime(Timestamp* self, MmsValue* mmsValue)
{

@ -418,9 +418,12 @@ Timestamp_clearFlags(Timestamp* self);
LIB61850_API uint32_t
Timestamp_getTimeInSeconds(Timestamp* self);
LIB61850_API uint64_t
LIB61850_API msSinceEpoch
Timestamp_getTimeInMs(Timestamp* self);
LIB61850_API nsSinceEpoch
Timestamp_getTimeInNs(Timestamp* self);
LIB61850_API bool
Timestamp_isLeapSecondKnown(Timestamp* self);
@ -450,11 +453,39 @@ Timestamp_getSubsecondPrecision(Timestamp* self);
LIB61850_API void
Timestamp_setSubsecondPrecision(Timestamp* self, int subsecondPrecision);
/**
* \brief Set the time in seconds
*
* NOTE: the fractionOfSecond part is set to zero
* NOTE: the subSecondPrecision is not touched
*
* \param self the Timestamp instance
* \param secondsSinceEpoch the seconds since unix epoch (unix timestamp)
*/
LIB61850_API void
Timestamp_setTimeInSeconds(Timestamp* self, uint32_t secondsSinceEpoch);
/**
* \brief Set the time in milliseconds
*
* NOTE: the subSecondPrecision is not touched
*
* \param self the Timestamp instance
* \param msTime the milliseconds since unix epoch
*/
LIB61850_API void
Timestamp_setTimeInMilliseconds(Timestamp* self, msSinceEpoch msTime);
/**
* \brief Set the time in nanoseconds
*
* NOTE: the subSecondPrecision is not touched
*
* \param self the Timestamp instance
* \param msTime the nanoseconds since unix epoch
*/
LIB61850_API void
Timestamp_setTimeInMilliseconds(Timestamp* self, uint64_t millisSinceEpoch);
Timestamp_setTimeInNanoseconds(Timestamp* self, nsSinceEpoch nsTime);
LIB61850_API void
Timestamp_setByMmsUtcTime(Timestamp* self, MmsValue* mmsValue);

Loading…
Cancel
Save