Index: RTC.c =================================================================== diff -u -r4ecbb2c37b64a4b09f3173aa9e505749d156d466 -r4ac73efd2de887626a957f097adf4afe4c2d4f6e --- RTC.c (.../RTC.c) (revision 4ecbb2c37b64a4b09f3173aa9e505749d156d466) +++ RTC.c (.../RTC.c) (revision 4ac73efd2de887626a957f097adf4afe4c2d4f6e) @@ -165,6 +165,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; @@ -215,6 +216,8 @@ static BOOL syncDG2HDDateTimeFlag; ///< Flag indicating whether DG RTC should be sync'd to HD RTC. #endif +static U16 writeSaveBuffer[ MIBSPI_MAX_BUFFER_LENGTH + 1 ]; ///< Save buffer for verifying write to RTC + /// 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 }; @@ -244,6 +247,7 @@ 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(); /*********************************************************************//** * @brief @@ -355,6 +359,7 @@ { BOOL result; + isEpochValid( epoch); result = convertEpoch2DateTime( epoch ); result = setRTCTimestamp( RTCNewTimestampStruct.seconds, RTCNewTimestampStruct.minutes, @@ -363,6 +368,7 @@ RTCNewTimestampStruct.months, RTCNewTimestampStruct.years); + isEpochValid ( epoch ); return result; } @@ -447,6 +453,10 @@ RTCExecState = handleExecWriteState(); break; + case RTC_EXEC_STATE_VERIFY_WRITE: + RTCExecState = handleExecVerifyWriteState(); + break; + case RTC_EXEC_STATE_READ: RTCExecState = handleExecReadState(); break; @@ -949,6 +959,8 @@ epoch += ( lyrs * SECONDS_IN_LEAP_YEAR ); epoch += ( ( yrs - lyrs ) * SECONDS_IN_NORMAL_YEAR ); + isEpochValid ( epoch ); + return epoch; } @@ -962,6 +974,7 @@ *************************************************************************/ static BOOL convertEpoch2DateTime( U32 epoch ) { + isEpochValid( epoch ); BOOL result; RTC_TIMESTAMP_T dtTime; U32 i, dayCnt; @@ -1182,6 +1195,8 @@ isTimestampBufferReady = TRUE; } + memcpy(writeSaveBuffer, txBuffer, RTC_GENERAL_BUFFER_LENGTH * 2); + RTC_EXEC_STATE_T result = RTC_EXEC_STATE_WRITE; BOOL isStatusOk = serviceRTC( txBuffer, rxBuffer, RTC_GENERAL_BUFFER_LENGTH ); @@ -1201,7 +1216,7 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) #endif #ifdef _HD_ - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) + 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; hasWriteToRTCRequested = FALSE; @@ -1241,7 +1256,7 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) #endif #ifdef _HD_ - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) + 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; } @@ -1320,7 +1335,7 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) #endif #ifdef _HD_ - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) + 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; hasReadFromRAMRequested = FALSE; @@ -1374,8 +1389,56 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_RTC_RAM_OPS_FAILURE, result ) #endif #ifdef _HD_ + 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 ) +{ + RTC_EXEC_STATE_T result = RTC_EXEC_STATE_READ; + BOOL isStatusOk = serviceRTC( txBuffer, rxBuffer, RTC_GENERAL_BUFFER_LENGTH ); + + if ( ( RTC_SERVICE_COMPLETE == RTCServiceState ) && ( TRUE == isStatusOk ) ) + { + if ( TRUE == isRTCFunctional() ) + { + // Compare received buffer with what was transmitted + if ( 0 != memcmp( writeSaveBuffer, rxBuffer, RTC_GENERAL_BUFFER_LENGTH * 2 ) ) + { + U08 tempCharBuffer[64]; + sprintf( tempCharBuffer, "RTC Verify: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", + rxBuffer[0], rxBuffer[1], rxBuffer[2], rxBuffer[3], rxBuffer[4], rxBuffer[5], rxBuffer[1], + rxBuffer[6], rxBuffer[7], rxBuffer[8], rxBuffer[9], rxBuffer[10], rxBuffer[11] ); + broadcastData( MSG_ID_HD_DEBUG_EVENT, COMM_BUFFER_OUT_CAN_DG_BROADCAST, tempCharBuffer, strlen(tempCharBuffer) ); + } + } + + 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 +#ifdef _HD_ + 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; } @@ -1734,4 +1797,29 @@ 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; + + if ( epoch < 1689958503 ) + { + result = FALSE; + } + + if ( RTCTimestampStruct.years > ( YEAR_2021 - YEAR_2000 ) ) + { + result = false; + } + + return result; +} + + /**@}*/