Index: RTC.c =================================================================== diff -u -r4ecbb2c37b64a4b09f3173aa9e505749d156d466 -rfa7f79bcc698e6973ab725d5e65fbcf18b8a4731 --- RTC.c (.../RTC.c) (revision 4ecbb2c37b64a4b09f3173aa9e505749d156d466) +++ RTC.c (.../RTC.c) (revision fa7f79bcc698e6973ab725d5e65fbcf18b8a4731) @@ -7,8 +7,8 @@ * * @file RTC.c * -* @author (last) Bill Bracken -* @date (last) 30-Jun-2023 +* @author (last) Michael Garthwaite +* @date (last) 01-Mar-2023 * * @author (original) Dara Navaei * @date (original) 11-Jan-2020 @@ -129,6 +129,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. @@ -165,6 +167,7 @@ RTC_EXEC_STATE_READ_FROM_RAM, ///< Exec state read from RAM RTC_EXEC_STATE_READ, ///< Exec state read RTC_EXEC_STATE_WRITE, ///< Exec state write + RTC_EXEC_STATE_VERIFY_WRITE, ///< Exec state verify RTC write NUM_OF_RTC_EXEC_STATES ///< Total number of exec states } RTC_EXEC_STATE_T; @@ -211,6 +214,8 @@ static U16 previousFPGATimerCount; ///< Previous FPGA timer count; static OVERRIDE_U32_T rtcControlRegister1 = { 0, 0, 0, 0 }; ///< RTC control register 1. static OVERRIDE_U32_T rtcControlRegister3 = { 0, 0, 0, 0 }; ///< RTC control register 3. +static U16 writeSaveBuffer[ MIBSPI_MAX_BUFFER_LENGTH + 1 ]; ///< Buffer to store data written to RTC. + #ifdef _DG_ static BOOL syncDG2HDDateTimeFlag; ///< Flag indicating whether DG RTC should be sync'd to HD RTC. #endif @@ -244,7 +249,9 @@ static RTC_EXEC_STATE_T handleExecWriteToRAMState( void ); static RTC_EXEC_STATE_T handleExecReadFromRAMState( void ); static RTC_EXEC_STATE_T handleExecWriteState( void ); +static RTC_EXEC_STATE_T handleExecVerifyWriteState( void ); + /*********************************************************************//** * @brief * The initRTC initializes the RTC module. @@ -347,21 +354,16 @@ * @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); return result; } @@ -447,6 +449,10 @@ RTCExecState = handleExecWriteState(); break; + case RTC_EXEC_STATE_VERIFY_WRITE: + RTCExecState = handleExecVerifyWriteState(); + break; + case RTC_EXEC_STATE_READ: RTCExecState = handleExecReadState(); break; @@ -711,6 +717,8 @@ BOOL result = FALSE; BOOL isBufferOk = FALSE; + static U08 tempCharBuffer[64]; + if ( isRTCServiceOnEntry ) { RTCServiceState = RTC_SEND_COMMAND; @@ -759,6 +767,9 @@ // Transfer to RTC failed. This transfer // should be done in 50ms numberOfFailedRTCTransfers++; + memset( tempCharBuffer, 0x00, sizeof(tempCharBuffer) ); + sprintf( tempCharBuffer, "$RTC SPI: %d, %d", RTCServiceState, numberOfFailedRTCTransfers ); + broadcastData( MSG_ID_DG_DEBUG_EVENT, COMM_BUFFER_OUT_CAN_DG_BROADCAST, tempCharBuffer, strlen(tempCharBuffer) + 1 ); } // Done with read (successful of failed) // get ready for another call @@ -962,27 +973,28 @@ *************************************************************************/ static BOOL convertEpoch2DateTime( U32 epoch ) { + 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 days34 = ( oneYears > 0 ? ( oneYrEpoch - SECONDS_IN_LEAP_YEAR ) / SECONDS_IN_A_DAY : oneYrEpoch / SECONDS_IN_A_DAY ); - U32 days12 = ( oneYears > 0 ? ( oneYrEpoch - SECONDS_IN_NORMAL_YEAR ) / SECONDS_IN_A_DAY : oneYrEpoch / SECONDS_IN_A_DAY ); - U32 days = ( twoYears > 0 ? days34 : days12 ); - 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 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 days34 = ( oneYears > 0 ? ( oneYrEpoch - SECONDS_IN_LEAP_YEAR ) / SECONDS_IN_A_DAY : oneYrEpoch / SECONDS_IN_A_DAY ); + U32 days12 = ( oneYears > 0 ? ( oneYrEpoch - SECONDS_IN_NORMAL_YEAR ) / SECONDS_IN_A_DAY : oneYrEpoch / SECONDS_IN_A_DAY ); + U32 days = ( twoYears > 0 ? days34 : days12 ); + 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; - dtTime.years = EPOCH_BASE_YEAR + wholeYears; - dtTime.months = 0; dayCnt = 0; daysInMonth[ LEAP_YEAR_MONTH ] = ( TRUE == leapYear ? 29 : 28 ); for ( i = 0; i < MONTHS_IN_YEAR; i++ ) @@ -994,13 +1006,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 + 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 ); return result; + } /*********************************************************************//** @@ -1187,12 +1200,15 @@ if ( RTCServiceState == RTC_SERVICE_COMPLETE && isStatusOk ) { + memcpy(writeSaveBuffer, txBuffer, ( RTC_GENERAL_BUFFER_LENGTH * 2 ) ); + releaseSemaphore( SEMAPHORE_RTC ); // Reset the counter to start with the new read timeCounter = 1; hasWriteToRTCRequested = FALSE; - result = RTC_EXEC_STATE_IDLE; + prepBufferForReadCommand(RTC_GENERAL_BUFFER_LENGTH); + result = RTC_EXEC_STATE_VERIFY_WRITE; } else if ( RTCServiceState == RTC_SERVICE_COMPLETE ) { @@ -1374,6 +1390,60 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) #endif #ifdef _HD_ +<<<<<<< Updated upstream +======= + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) +#endif + result = RTC_EXEC_STATE_IDLE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleExecVerifyWriteState reads timestamp from RT to verify the + * RTC write was successful. + * @details Inputs: RTCServiceState, lastEpochTime, timeCounter, txBuffer, rxBuffer + * @details Outputs: lastEpochTime, timeCounter, alarm if any RTC operations error + * occurred + * @return next state + *************************************************************************/ +static RTC_EXEC_STATE_T handleExecVerifyWriteState( void ) +{ + + static U08 tempCharBuffer[128]; + static int writeCounter = 0; + + RTC_EXEC_STATE_T result = RTC_EXEC_STATE_VERIFY_WRITE; + BOOL isStatusOk = serviceRTC( txBuffer, rxBuffer, RTC_GENERAL_BUFFER_LENGTH ); + + if ( ( RTC_SERVICE_COMPLETE == RTCServiceState ) && ( TRUE == isStatusOk ) ) + { + if ( writeCounter++ > 3 ) + { + writeSaveBuffer[7] = ~writeSaveBuffer[7]; + writeCounter = 0; + } + // Compare received buffer with what was transmitted + if ( 0 != memcmp( &writeSaveBuffer[1], &rxBuffer[1], ( RTC_GENERAL_BUFFER_LENGTH - 1 )* 2 ) ) + { + memset(tempCharBuffer, 0x00, sizeof(tempCharBuffer)); + printf( tempCharBuffer, "$RTC Verify: %02X:%02X, %02X:%02X, %02X:%02X, %02X:%02X, %02X:%02X, %02X:%02X, %02X:%02X, %02X:%02X, %02X:%02X, %02X:%02X, %02X:%02X-END", + rxBuffer[0], writeSaveBuffer[0], rxBuffer[1], writeSaveBuffer[1], rxBuffer[2], writeSaveBuffer[2], rxBuffer[3], writeSaveBuffer[3], + rxBuffer[4], writeSaveBuffer[4], rxBuffer[5], writeSaveBuffer[5], rxBuffer[6], writeSaveBuffer[6], rxBuffer[7], writeSaveBuffer[7], + rxBuffer[8], writeSaveBuffer[8], rxBuffer[9], writeSaveBuffer[9], rxBuffer[10], writeSaveBuffer[10] ); + broadcastData( MSG_ID_DG_DEBUG_EVENT, COMM_BUFFER_OUT_CAN_DG_BROADCAST, tempCharBuffer, strlen(tempCharBuffer) + 1); + } + + releaseSemaphore( SEMAPHORE_RTC ); + + result = RTC_EXEC_STATE_IDLE; + } + else if ( RTC_SERVICE_COMPLETE == RTCServiceState ) + { + releaseSemaphore( SEMAPHORE_RTC ); +#ifdef _DG_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) #endif result = RTC_EXEC_STATE_IDLE; @@ -1734,4 +1804,38 @@ return result; } +/*********************************************************************//** + * @brief + * The isEpochValid check if epoch is valid + * @details Inputs: epoch time + * @details Outputs: None + * @return TRUE if epoch is valid, else false + *************************************************************************/ +BOOL isEpochValid( U32 epoch ) +{ + BOOL result = TRUE; + static U08 tempCharBuffer[64]; + + static int epochCounter = 0; + + memset(tempCharBuffer, 0x00, sizeof(tempCharBuffer) ); + + if ( epochCounter++ > 3) + { + epoch = 0; + epochCounter = 0; + } + + if ( epoch < 1689958503 ) + { + result = FALSE; + + memset(tempCharBuffer, 0x00, sizeof(tempCharBuffer)); + sprintf( tempCharBuffer, "$RTC HD epoch: %d", epoch); + broadcastData( MSG_ID_DG_DEBUG_EVENT, COMM_BUFFER_OUT_CAN_DG_BROADCAST, tempCharBuffer, strlen(tempCharBuffer) + 1); + } + + return result; +} + /**@}*/