Index: RTC.c =================================================================== diff -u -ra89fd55052e2e467f9ae2fdc828e84272c142022 -rfab687e5e82471ff0fda2205baf9d47f52cee8fc --- RTC.c (.../RTC.c) (revision a89fd55052e2e467f9ae2fdc828e84272c142022) +++ RTC.c (.../RTC.c) (revision fab687e5e82471ff0fda2205baf9d47f52cee8fc) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file RTC.c * * @author (last) Dara Navaei -* @date (last) 09-Nov-2021 +* @date (last) 24-May-2022 * * @author (original) Dara Navaei * @date (original) 11-Jan-2020 @@ -23,6 +23,7 @@ #include "SystemCommMessages.h" #include "Timers.h" #include "Utilities.h" +#include /** * @addtogroup RTC @@ -124,6 +125,8 @@ #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. +#define DAYS_IN_NORMAL_YEAR (365) ///< Number of days in a normal year. +#define DAYS_IN_LEAP_YEAR (366) ///< Number of days 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. @@ -312,21 +315,22 @@ * @brief * The setRTCEpoch sets the clock from a given epoch. * @details Inputs: none -* @details Outputs: RTCNewTimestampStruct +* @details Outputs: none * @param epoch date/time stamp epoch -* @return TRUE if clock set, FALSE if not. +* @return TRUE if valid epoch time received, FALSE if not. +* @note If the epoch time is valid, the RTCNewTimeStampStruct updated *************************************************************************/ BOOL setRTCEpoch( U32 epoch ) { BOOL result; result = convertEpoch2DateTime( epoch ); - result = setRTCTimestamp( RTCNewTimestampStruct.seconds, - RTCNewTimestampStruct.minutes, - RTCNewTimestampStruct.hours, - RTCNewTimestampStruct.days, - RTCNewTimestampStruct.months, - RTCNewTimestampStruct.years); +// result = setRTCTimestamp( RTCNewTimestampStruct.seconds, +// RTCNewTimestampStruct.minutes, +// RTCNewTimestampStruct.hours, +// RTCNewTimestampStruct.days, +// RTCNewTimestampStruct.months, +// RTCNewTimestampStruct.years); return result; } @@ -458,11 +462,13 @@ RTC_RAM_STATUS_T writeToRAM( U32 address, U08* data, U32 length ) { RTC_RAM_STATUS_T status = RTCRAMStatus; - U16 castedAddress = (U16)( address & MASK_OFF_MSW ); + U16 maskedAddress = (U16)( address & MASK_OFF_MSW ); + U16 castedHighAddress = maskedAddress / BITS_8_FULL_SCALE; + U16 castedLowAddress = maskedAddress % BITS_8_FULL_SCALE; if ( status == RTC_RAM_STATUS_IDLE ) { - if ( castedAddress > MAX_ALLOWED_RTC_RAM_ADDRESS ) + if ( maskedAddress > MAX_ALLOWED_RTC_RAM_ADDRESS ) { status = RTC_RAM_STATUS_ILLEGAL_ADDRESS; } @@ -474,14 +480,16 @@ { U08 i; - RTCRAMStatus = status = RTC_RAM_STATUS_IN_PROGRESS; - RTCRAMState = RTC_RAM_STATE_BUSY; - hasWriteToRAMRequested = TRUE; - RAMBufferLength = length; + RTCRAMStatus = RTC_RAM_STATUS_IN_PROGRESS; + status = RTC_RAM_STATUS_IN_PROGRESS; + RTCRAMState = RTC_RAM_STATE_BUSY; + hasWriteToRAMRequested = TRUE; + RAMBufferLength = length; prepRAMBuffer [ RTC_PREP_RAM_INDEX ] = RTC_PREP_RAM_READ_WRITE; - prepRAMBuffer [ RTC_RAM_HIGH_ADDRESS_INDEX ] = 0x0000; - prepRAMBuffer [ RTC_RAM_LOW_ADDRESS_INDEX ] = castedAddress; - txBuffer [ BUFFER_INDEX_0 ] = RTC_WRITE_TO_RAM; + prepRAMBuffer [ RTC_RAM_HIGH_ADDRESS_INDEX ] = castedHighAddress; + prepRAMBuffer [ RTC_RAM_LOW_ADDRESS_INDEX ] = castedLowAddress; + txBuffer [ BUFFER_INDEX_0 ] = RTC_WRITE_TO_RAM; + for ( i = 0; i < RAMBufferLength; i++ ) { txBuffer [ i + BUFFER_INDEX_1 ] = data [ i ]; @@ -509,11 +517,13 @@ RTC_RAM_STATUS_T readFromRAM( U32 address, U32 length ) { RTC_RAM_STATUS_T status = RTCRAMStatus; - U16 castedAddress = (U16)( address & MASK_OFF_MSW ); + U16 maskedAddress = (U16)( address & MASK_OFF_MSW ); + U16 castedHighAddress = maskedAddress / BITS_8_FULL_SCALE; + U16 castedLowAddress = maskedAddress % BITS_8_FULL_SCALE; if ( status == RTC_RAM_STATUS_IDLE ) { - if ( castedAddress > MAX_ALLOWED_RTC_RAM_ADDRESS ) + if ( maskedAddress > MAX_ALLOWED_RTC_RAM_ADDRESS ) { status = RTC_RAM_STATUS_ILLEGAL_ADDRESS; } @@ -525,14 +535,16 @@ { U08 i; - status = RTCRAMStatus = RTC_RAM_STATUS_IN_PROGRESS; - RTCRAMState = RTC_RAM_STATE_BUSY; - hasReadFromRAMRequested = TRUE; - RAMBufferLength = length; + status = RTC_RAM_STATUS_IN_PROGRESS; + RTCRAMStatus = RTC_RAM_STATUS_IN_PROGRESS; + RTCRAMState = RTC_RAM_STATE_BUSY; + hasReadFromRAMRequested = TRUE; + RAMBufferLength = length; prepRAMBuffer[ RTC_PREP_RAM_INDEX ] = RTC_PREP_RAM_READ_WRITE; - prepRAMBuffer[ RTC_RAM_HIGH_ADDRESS_INDEX ] = 0x0000; - prepRAMBuffer[ RTC_RAM_LOW_ADDRESS_INDEX ] = castedAddress; - txBuffer[ BUFFER_INDEX_0 ] = RTC_READ_FROM_RAM; + prepRAMBuffer[ RTC_RAM_HIGH_ADDRESS_INDEX ] = castedHighAddress; + prepRAMBuffer[ RTC_RAM_LOW_ADDRESS_INDEX ] = castedLowAddress; + txBuffer[ BUFFER_INDEX_0 ] = RTC_READ_FROM_RAM; + for ( i = 0; i < RAMBufferLength; i++ ) { txBuffer[ i + BUFFER_INDEX_1 ] = 0x0000; @@ -703,7 +715,16 @@ *************************************************************************/ static BOOL isRTCFunctional( void ) { + ALARM_ID_T alarm; BOOL hasTestPassed = TRUE; + +#ifdef _DG_ + alarm = ALARM_ID_DG_RTC_CONFIG_ERROR; +#endif +#ifdef _HD_ + alarm = ALARM_ID_HD_RTC_CONFIG_ERROR; +#endif + #ifndef DISABLE_RTC_CONFIG U16 controlReg1 = rxBuffer[ RTC_REG_1_INDEX ]; U16 controlReg2 = rxBuffer[ RTC_REG_2_INDEX ]; @@ -722,32 +743,34 @@ if ( controlReg1 & RTC_REG_1_12_HOUR_MODE_MASK ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_CONFIG_ERROR, controlReg1, RTC_REG_1_12_HOUR_MODE_MASK ); + SET_ALARM_WITH_2_U32_DATA( alarm, controlReg1, RTC_REG_1_12_HOUR_MODE_MASK ); hasTestPassed = FALSE; } if ( controlReg1 & RTC_REG_1_PORO ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_CONFIG_ERROR, controlReg1, RTC_REG_1_PORO ); + SET_ALARM_WITH_2_U32_DATA( alarm, controlReg1, RTC_REG_1_PORO ); hasTestPassed = FALSE; } if ( controlReg1 & RTC_REG_1_CLK_STOPPED_MASK ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_CONFIG_ERROR, controlReg1, RTC_REG_1_CLK_STOPPED_MASK ); + SET_ALARM_WITH_2_U32_DATA( alarm, controlReg1, RTC_REG_1_CLK_STOPPED_MASK ); hasTestPassed = FALSE; } if ( controlReg1 & RTC_REG_1_UNUSED_MASK ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_CONFIG_ERROR, controlReg1, RTC_REG_1_UNUSED_MASK ); + SET_ALARM_WITH_2_U32_DATA( alarm, controlReg1, RTC_REG_1_UNUSED_MASK ); hasTestPassed = FALSE; } if ( controlReg1 & RTC_REG_1_EXT_CLK_MODE_MASK ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_CONFIG_ERROR, controlReg1, RTC_REG_1_EXT_CLK_MODE_MASK ); + SET_ALARM_WITH_2_U32_DATA( alarm, controlReg1, RTC_REG_1_EXT_CLK_MODE_MASK ); hasTestPassed = FALSE; } if ( controlReg3 & RTC_REG_3_BLF_MASK ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_BATTERY_LOW, controlReg3, RTC_REG_3_BLF_MASK ); +#ifdef _DG_ + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_RTC_BATTERY_LOW, controlReg3, RTC_REG_3_BLF_MASK ); +#endif hasTestPassed = FALSE; } #endif @@ -862,24 +885,41 @@ BOOL result; RTC_TIMESTAMP_T dtTime; U32 i, dayCnt; - U32 fourYears = epoch / SECONDS_IN_4_YEARS; - U32 twoYrEpoch = epoch - ( fourYears * SECONDS_IN_4_YEARS ); - U32 twoYears = twoYrEpoch / SECONDS_IN_2_YEARS; - U32 oneYrEpoch = twoYrEpoch - ( twoYears * SECONDS_IN_2_YEARS ); - U32 oneYears = ( twoYears > 0 ? oneYrEpoch / SECONDS_IN_LEAP_YEAR : oneYrEpoch / SECONDS_IN_NORMAL_YEAR ); - U32 days = ( twoYears > 0 ? ( oneYrEpoch - SECONDS_IN_LEAP_YEAR ) / SECONDS_IN_A_DAY : ( oneYrEpoch - SECONDS_IN_NORMAL_YEAR ) / SECONDS_IN_A_DAY ); - U32 wholeYears = ( fourYears * 4 ) + ( twoYears * 2 ) + oneYears; - BOOL leapYear = ( twoYears > 0 && 0 == oneYears ? TRUE : FALSE ); - U32 oneDayEpoch= oneYrEpoch % SECONDS_IN_A_DAY; - U32 hours = oneDayEpoch / SECS_IN_HOUR; - U32 oneHrEpoch = oneDayEpoch - ( hours * SECS_IN_HOUR ); - U32 mins = oneHrEpoch / SEC_PER_MIN; - U32 secs = oneHrEpoch - ( mins * SEC_PER_MIN ); + U32 days; + U32 fourYears = epoch / SECONDS_IN_4_YEARS; + U32 twoYrEpoch = epoch - ( fourYears * SECONDS_IN_4_YEARS ); + U32 twoYears = twoYrEpoch / SECONDS_IN_2_YEARS; + U32 oneYrEpoch = twoYrEpoch - ( twoYears * SECONDS_IN_2_YEARS ); + U32 oneYears = ( twoYears > 0 ? oneYrEpoch / SECONDS_IN_LEAP_YEAR : oneYrEpoch / SECONDS_IN_NORMAL_YEAR ); + U32 remainDays = ( twoYears > 0 ? ( SECONDS_IN_LEAP_YEAR - oneYrEpoch ) / SECONDS_IN_A_DAY : ( SECONDS_IN_NORMAL_YEAR - oneYrEpoch ) / SECONDS_IN_A_DAY ); + U32 wholeYears = ( fourYears * 4 ) + ( twoYears * 2 ) + oneYears; + BOOL leapYear = ( twoYears > 0 && 0 == oneYears ? TRUE : FALSE ); + U32 oneDayEpoch = oneYrEpoch % SECONDS_IN_A_DAY; + U32 hours = oneDayEpoch / SECS_IN_HOUR; + U32 oneHrEpoch = oneDayEpoch - ( hours * SECS_IN_HOUR ); + U32 mins = oneHrEpoch / SEC_PER_MIN; + U32 secs = oneHrEpoch - ( mins * SEC_PER_MIN ); + dtTime.years = EPOCH_BASE_YEAR + wholeYears; dtTime.months = 0; dayCnt = 0; - daysInMonth[ LEAP_YEAR_MONTH ] = ( TRUE == leapYear ? 29 : 28 ); + + /* + * Adjust days in February and calculate actual day of the + * year based upon whether or not the year is a leap year. + */ + if (leapYear) + { + daysInMonth[ LEAP_YEAR_MONTH ] = 29; + days = DAYS_IN_LEAP_YEAR - remainDays; + } + else + { + daysInMonth[ LEAP_YEAR_MONTH ] = 28; + days = DAYS_IN_NORMAL_YEAR - remainDays; + } + for ( i = 0; i < MONTHS_IN_YEAR; i++ ) { if ( days >= dayCnt ) @@ -889,12 +929,14 @@ } dayCnt += daysInMonth[ i ]; } - dtTime.days += 1; // days will be number of full days in current month so need to add 1 for the partial current day to get day of month +//wjb dtTime.days += 1; // days will be number of full days in current month so need to add 1 for the partial current day to get day of month dtTime.hours = hours; dtTime.minutes = mins; dtTime.seconds = secs; result = setRTCTimestamp( dtTime.seconds, dtTime.minutes, dtTime.hours, dtTime.days, dtTime.months, dtTime.years ); + printf("epoch: %d, sec: %d, min: %d, days: %d, mon: %d, year: %d\n", epoch, dtTime.seconds, dtTime.minutes, dtTime.hours, dtTime.days, dtTime.months, dtTime.years); + return result; } @@ -1228,19 +1270,13 @@ if ( RTCServiceState == RTC_SERVICE_COMPLETE && isStatusOk ) { - if ( isRTCFunctional() ) + if ( TRUE == isRTCFunctional() ) { RTC_DATA_T data; updateReadTimestampStruct(); lastEpochTime = convertDateTime2Epoch( RTCTimestampStruct ); timeCounter = 1; -#ifdef _DG_ - broadcastData( MSG_ID_RTC_EPOCH, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&lastEpochTime, sizeof( U32 ) ); -#else - broadcastData( MSG_ID_RTC_EPOCH, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&lastEpochTime, sizeof( U32 ) ); -#endif - timeCounter = 1; data.epochTime = lastEpochTime; #ifdef _DG_ @@ -1274,8 +1310,10 @@ static RTC_SELF_TEST_STATE_T handleSelfTestStart( void ) { RTC_SELF_TEST_STATE_T result = RTC_SELF_TEST_STATE_START; - RTCSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; + RTCSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; + prepBufferForReadCommand( RTC_GENERAL_BUFFER_LENGTH ); + result = RTC_SELF_TEST_STATE_CHECK_CTRL_REGS; return result; @@ -1333,7 +1371,7 @@ static RTC_SELF_TEST_STATE_T handleSelfTestWaitForFirstSecond( void ) { RTC_SELF_TEST_STATE_T result = RTC_SELF_TEST_STATE_WAIT_FOR_FIRST_SECOND; - BOOL isStatusOk = serviceRTC( txBuffer, rxBuffer, RTC_GENERAL_BUFFER_LENGTH ); + BOOL isStatusOk = serviceRTC( txBuffer, rxBuffer, RTC_GENERAL_BUFFER_LENGTH ); if ( ( RTC_SERVICE_COMPLETE == RTCServiceState ) && ( TRUE == isStatusOk ) ) { @@ -1343,22 +1381,22 @@ if ( RTCCurrentSecond != RTCPreviousSecond ) { - RTCPreviousSecond = RTCCurrentSecond; + RTCPreviousSecond = RTCCurrentSecond; previousFPGATimerCount = getFPGATimerCount(); - RTCSelfTestTimer = getMSTimerCount(); - result = RTC_SELF_TEST_STATE_CHECK_ACCURACY; + RTCSelfTestTimer = getMSTimerCount(); + result = RTC_SELF_TEST_STATE_CHECK_ACCURACY; } } else { RTCSelfTestResult = SELF_TEST_STATUS_FAILED; - result = RTC_SELF_TEST_STATE_COMPLETE; + result = RTC_SELF_TEST_STATE_COMPLETE; } } else if ( RTCServiceState == RTC_SERVICE_COMPLETE ) { RTCSelfTestResult = SELF_TEST_STATUS_FAILED; - result = RTC_SELF_TEST_STATE_COMPLETE; + result = RTC_SELF_TEST_STATE_COMPLETE; } return result; @@ -1382,22 +1420,30 @@ if ( ( TRUE == isStatusOk ) && ( rxBuffer[ RTC_SECONDS_INDEX ] != RTCPreviousSecond ) ) { - S32 const elapsedTime = (S32)calcTimeSince( RTCSelfTestTimer ); - S32 const deltaTime = elapsedTime - (S32)MS_PER_SECOND; - S32 const elapsedFPGATime = (S32)u16DiffWithWrap( previousFPGATimerCount, getFPGATimerCount() ); - result = RTC_SELF_TEST_STATE_COMPLETE; - RTCSelfTestResult = SELF_TEST_STATUS_PASSED; + ALARM_ID_T alarm; + S32 elapsedTime = (S32)calcTimeSince( RTCSelfTestTimer ); + S32 deltaTime = elapsedTime - (S32)MS_PER_SECOND; + S32 elapsedFPGATime = (S32)u16DiffWithWrap( previousFPGATimerCount, getFPGATimerCount() ); + result = RTC_SELF_TEST_STATE_COMPLETE; + RTCSelfTestResult = SELF_TEST_STATUS_PASSED; +#ifdef _DG_ + alarm = ALARM_ID_DG_RTC_OR_TIMER_ACCURACY_FAILURE; +#endif +#ifdef _HD_ + alarm = ALARM_ID_HD_RTC_OR_TIMER_ACCURACY_FAILURE; +#endif + if ( abs( deltaTime ) > RTC_ACCURACY_TOLERANCE ) { RTCSelfTestResult = SELF_TEST_STATUS_FAILED; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_OR_TIMER_ACCURACY_FAILURE, (U32)deltaTime, RTC_ACCURACY_TOLERANCE ); + SET_ALARM_WITH_2_U32_DATA( alarm, (U32)deltaTime, RTC_ACCURACY_TOLERANCE ); } if ( abs( elapsedFPGATime - elapsedTime ) > FPGA_ACCURACY_TOLERANCE ) { RTCSelfTestResult = SELF_TEST_STATUS_FAILED; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RTC_OR_TIMER_ACCURACY_FAILURE, (U32)elapsedFPGATime, (U32)elapsedTime ); + SET_ALARM_WITH_2_U32_DATA( alarm, (U32)elapsedFPGATime, (U32)elapsedTime ); } }