Index: RTC.c =================================================================== diff -u -r1ad549d610417a594093b226b5c67ac05ee13dea -r519a676a194a6d5045403fb75610acd98569ef97 --- RTC.c (.../RTC.c) (revision 1ad549d610417a594093b226b5c67ac05ee13dea) +++ RTC.c (.../RTC.c) (revision 519a676a194a6d5045403fb75610acd98569ef97) @@ -116,26 +116,28 @@ #define TEN 10U ///< Ten #define YEAR_2000 2000U ///< Year 2000 #ifndef USE_LIBRARY_TIME_FUNCTIONS -#define EPOCH_YEAR 1970U ///< Reference year to calculate epoch (1970) + #define EPOCH_BASE_YEAR 1970U ///< Reference year to calculate epoch (1970) #else -#define EPOCH_YEAR 1900U ///< Reference year to calculate epoch (1900) -#define YEAR_1900_TO_1970_SECONDS_DIFF 2208988800U ///< Difference in seconds from 1/1/1900 to 1/1/1970 (2208988800) -/// Six hour offset is needed because TI library works in CST. -#define OFFSET_6_HRS (6 * MIN_PER_HOUR * SEC_PER_MIN) + #define EPOCH_BASE_YEAR 1900U ///< Reference year to calculate epoch (1900) + #define YEAR_1900_TO_1970_SECONDS_DIFF 2208988800U ///< Difference in seconds from 1/1/1900 to 1/1/1970 (2208988800) + /// Six hour offset is needed because TI library works in CST. + #define OFFSET_6_HRS (6 * MIN_PER_HOUR * SEC_PER_MIN) + + #ifdef _VECTORCAST_ + #define LOCAL_TO_GTM_TIME_CONVERSION 8U ///< Local time to GTM conversion for VectorCAST + #endif #endif -#define SECS_IN_HOUR 3600 -#define MONTHS_IN_YEAR 12 -#define LEAP_YEAR_MONTH 1 -#define SECONDS_IN_NORMAL_YEAR ( SECONDS_IN_A_DAY * 365 ) -#define SECONDS_IN_LEAP_YEAR ( SECONDS_IN_A_DAY * 366 ) +#define SECS_IN_HOUR 3600 ///< Number of seconds in an hour. +#define MONTHS_IN_YEAR 12 ///< Number of months in a year. +#define LEAP_YEAR_MONTH ( 2 - 1 ) ///< Leap year month is February. Subtract 1 month for zero-based months. +#define SECONDS_IN_NORMAL_YEAR ( SECONDS_IN_A_DAY * 365 ) ///< Number of seconds in a normal year. +#define SECONDS_IN_LEAP_YEAR ( SECONDS_IN_A_DAY * 366 ) ///< Number of seconds in a leap year. +/// Number of seconds in 4 years. Includes an extra day for 1 leap within any 4 year period. static const U32 SECONDS_IN_4_YEARS = SECONDS_IN_NORMAL_YEAR * 3 + SECONDS_IN_LEAP_YEAR; +/// Number of seconds in 2 years. Assumes no leap year in 2 year period. static const U32 SECONDS_IN_2_YEARS = SECONDS_IN_NORMAL_YEAR * 2; -#ifdef _VECTORCAST_ -#define LOCAL_TO_GTM_TIME_CONVERSION 8U ///< Local time to GTM conversion for VectorCAST -#endif - /// RTC self-test state enumeration. typedef enum RTC_Self_Test_States { @@ -216,7 +218,7 @@ static U16 prepRAMBuffer[ RTC_RAM_PREP_BUFFER_LENGTH ]; ///< Buffer to send prep read/write commands to RTC RAM. static U16 RAMBuffer[ MIBSPI_MAX_BUFFER_LENGTH ]; ///< Buffer to read RTC RAM data. -/// Array of days in each month. +/// Array of days in each month. Assumes non-leap year. Must adjust days in February if leap year. static U32 daysInMonth[ 12 ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // ********** Private function prototypes ********* @@ -841,23 +843,24 @@ static U32 convertDateTime2Epoch( RTC_TIMESTAMP_T dateTime ) { U32 epoch; - U32 secs = dateTime.seconds; - U32 mins = dateTime.minutes; - U32 hrs = dateTime.hours; - U32 days = dateTime.days; - U32 mos = dateTime.months - 1; // convert months from 1..12 to 0..11 - U32 yrs = dateTime.years - EPOCH_YEAR; - U32 lyrs = ( yrs / 4 ) + ( yrs % 4 > 2 ? 1 : 0 ); - BOOL leap = ( dateTime.years % 4 == 0 ? TRUE : FALSE ); U32 i, dayCnt; + U32 secs = dateTime.seconds; // Expecting seconds to be 0..59. + U32 mins = dateTime.minutes; // Expecting minutes to be 0..59. + U32 hrs = dateTime.hours; // Expecting hours to be 0..23. + U32 days = dateTime.days - 1; // Expecting days to be 1..31. Current (partial) day covered by hrs, min, sec so subtract current day. + U32 yrs = dateTime.years + YEAR_2000 - EPOCH_BASE_YEAR; // Expecting 2-digit year - no century from our RTC - so must assume year is >= 2000 - then subtract epoch base year. + U32 lyrs = ( yrs / 4 ) + ( yrs % 4 > 2 ? 1 : 0 ); // First leap year after epoch base year (1970) is 1972 (so every 3rd of every 4 years). + BOOL leap = ( dateTime.years % 4 == 0 ? TRUE : FALSE ); + // Compute number of full days since start of given year. daysInMonth[ LEAP_YEAR_MONTH ] = ( TRUE == leap ? 29 : 28 ); dayCnt = 0; - for ( i = 0; i <= dateTime.months; i++ ) + for ( i = 1; i < dateTime.months; i++ ) // Expecting months to be 1..12 { - dayCnt += daysInMonth[ i ]; + dayCnt += daysInMonth[ i-1 ]; } + // Compute epoch from given date/time. epoch = secs + ( mins * SEC_PER_MIN ) + ( hrs * SECS_IN_HOUR ); epoch += ( days * SECONDS_IN_A_DAY ); epoch += ( dayCnt * SECONDS_IN_A_DAY ); @@ -894,7 +897,7 @@ U32 mins = oneHrEpoch / SEC_PER_MIN; U32 secs = oneHrEpoch - ( mins * SEC_PER_MIN ); - dtTime.years = EPOCH_YEAR + wholeYears; + dtTime.years = EPOCH_BASE_YEAR + wholeYears; dtTime.months = 0; dayCnt = 0; daysInMonth[ LEAP_YEAR_MONTH ] = ( TRUE == leapYear ? 29 : 28 ); @@ -934,7 +937,7 @@ // In epoch conversion, the months are 0-11 // so the months is decremented t.tm_mon = RTCTimestampStruct.months - 1; - t.tm_year = RTCTimestampStruct.years + YEAR_2000 - EPOCH_YEAR; + t.tm_year = RTCTimestampStruct.years + YEAR_2000 - EPOCH_BASE_YEAR; // Disabled daylight saving // If daylight saving is not disabled, MinGW in VectorCAST // may or may not calculate the value right @@ -971,11 +974,11 @@ // Convert epoch to date/time structure epoch += YEAR_1900_TO_1970_SECONDS_DIFF; - epoch -= OFFSET_6_HRS; // TODO - why is this needed? + epoch -= OFFSET_6_HRS; // For some reason, TI works in CST time zone instead of GMT ptm = gmtime( &epoch ); // Copy date/time stamp to our structure - RTCNewTimestampStruct.years = ptm->tm_year + EPOCH_YEAR; // epoch is seconds from 1/1/1900. - RTCNewTimestampStruct.months = ptm->tm_mon + 1; // months from gmtime() are 0..11 - convert to 1..12. + RTCNewTimestampStruct.years = ptm->tm_year + EPOCH_BASE_YEAR; // epoch is seconds from 1/1/1900. + RTCNewTimestampStruct.months = ptm->tm_mon + 1; // months from gmtime() are 0..11 - convert to 1..12. RTCNewTimestampStruct.days = ptm->tm_mday; RTCNewTimestampStruct.hours = ptm->tm_hour; RTCNewTimestampStruct.minutes = ptm->tm_min;