Index: firmware/App/Controllers/RTC.c =================================================================== diff -u -r408e6e577818831b985f28e6bf777cd9f65b9849 -re20e8cd14d3965560e5ff38835270ef541e5abe6 --- firmware/App/Controllers/RTC.c (.../RTC.c) (revision 408e6e577818831b985f28e6bf777cd9f65b9849) +++ firmware/App/Controllers/RTC.c (.../RTC.c) (revision e20e8cd14d3965560e5ff38835270ef541e5abe6) @@ -20,46 +20,40 @@ #include "RTC.h" #include "mibspi.h" -// TODO: ADD FUNCTION HEADERS - // ********** Definitions ********** -#define RTC_REG_1_12_HOUR_MODE 0X0004 // 12-hour or 24-hour mode -#define RTC_REG_1_PORO 0X0008 // Power On Reset Override -#define RTC_REG_1_CLK_STOPPED 0X0020 // RTC source clock -#define RTC_REG_1_UNUSED 0X0040 // Unused -#define RTC_REG_1_EXT_CLK_MODE 0X0080 // RTC external or normal mode +#define RTC_REG_1_12_HOUR_MODE 0X0004 // 12-hour or 24-hour mode +#define RTC_REG_1_PORO 0X0008 // Power On Reset Override +#define RTC_REG_1_CLK_STOPPED 0X0020 // RTC source clock +#define RTC_REG_1_UNUSED 0X0040 // Unused +#define RTC_REG_1_EXT_CLK_MODE 0X0080 // RTC external or normal mode -#define RTC_REG_2_MASK 0X00FF -#define RTC_REG_2_MSF 0X0080 // Minute or second interrupt -#define RTC_REG_2_CDTF 0X0008 // Countdown timer interrupt -#define RTC_REG_2_AF 0X0010 // Alarm interrupt -#define RTC_REG_2_TSF2 0X0020 // Timestamp interrupt +#define RTC_REG_2_MASK 0X00FF +#define RTC_REG_2_MSF 0X0080 // Minute or second interrupt +#define RTC_REG_2_CDTF 0X0008 // Countdown timer interrupt +#define RTC_REG_2_AF 0X0010 // Alarm interrupt +#define RTC_REG_2_TSF2 0X0020 // Timestamp interrupt -#define RTC_REG_3_MASK 0X00FF -#define RTC_REG_3_BF 0x0008 +#define RTC_REG_3_MASK 0X00FF +#define RTC_REG_3_BF 0x0008 -// RTC registers indices +#define RTC_REG_1_INDEX 1U +#define RTC_REG_2_INDEX 2U +#define RTC_REG_3_INDEX 3U +#define RTC_SECONDS_INDEX 4U +#define RTC_MINUTES_INDEX 5U +#define RTC_HOURS_INDEX 6U +#define RTC_DAYS_INDEX 7U +#define RTC_WEEKDAYS_INDEX 8U +#define RTC_MONTHS_INDEX 9U +#define RTC_YEARS_INDEX 10U -#define RTC_REG_1_INDEX 1U -#define RTC_REG_2_INDEX 2U -#define RTC_REG_3_INDEX 3U -#define RTC_SECONDS_INDEX 4U -#define RTC_MINUTES_INDEX 5U -#define RTC_HOURS_INDEX 6U -#define RTC_DAYS_INDEX 7U -#define RTC_WEEKDAYS_INDEX 8U -#define RTC_MONTHS_INDEX 9U -#define RTC_YEARS_INDEX 10U +#define BUFFER_INDEX_0 0U +#define BUFFER_INDEX_1 1U +#define BUFFER_INDEX_2 2U +#define BUFFER_INDEX_3 3U +#define BUFFER_INDEX_4 4U -#define BUFFER_INDEX_0 0U -#define BUFFER_INDEX_1 1U -#define BUFFER_INDEX_2 2U -#define BUFFER_INDEX_3 3U -#define BUFFER_INDEX_4 4U - -// *************** MibSPI values ************* // - #define MIBSPI_MAX_BUFFER_LENGTH 127U #define MIBSPI_CONTINUOUS_MODE 4U #define MIBSPI_CHIP_SELECT_ACTIVE 1U @@ -76,8 +70,6 @@ #define MIBSPI_DATA_FORMAT_ZERO_BIT_SHIFT 8U #define MIBSPI_BUFFER_TRANS_BIT_SHIFT 8U -// *************** RTC definitions ************* // - #define RTC_RAM_PREP_BUFFER_LENGTH 3U #define RTC_TIMESTAMP_BUFFER_LENGTH 8U #define RTC_GENERAL_BUFFER_LENGTH 11U @@ -153,17 +145,17 @@ static RTC_GET_DATA_STATE_T RTCServiceState = RTC_SEND_COMMAND; static RTC_EXEC_STATE_T RTCExecState = RTC_EXEC_STATE_WAIT_FOR_POST; static SELF_TEST_STATUS_T RTCSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; -static RTC_RAM_STATUS_T RTCRAMStatus = RTC_RAM_STATUS_COMPLETE; +static RTC_RAM_STATUS_T RTCRAMStatus = RTC_RAM_STATUS_IDLE; static RTC_RAM_STATE_T RTCRAMState = RTC_RAM_STATE_READY; static RTC_TIMESTAMP_T RTCTimestampStruct; -static U32 RTCSelfTestTimer = 0; -static U32 RTCPreviousSecond = 0; -static U32 RAMBufferLength = 0; -static U32 lastEpochTime = 0; -static U32 previousTransferLength = 0; +static U32 RTCSelfTestTimer = 0; +static U32 RTCPreviousSecond = 0; +static U32 RAMBufferLength = 0; +static U32 lastEpochTime = 0; +static U32 previousTransferLength = 0; -static U32 timeCounter = 1; +static U32 timeCounter = 1; static U32 numberOfFailedRTCTransfers = 1; static BOOL hasWriteToRTCRequested = FALSE; @@ -214,7 +206,7 @@ *************************************************************************/ void initRTC() { - // Do nothing for now + RTCSelfTestState = RTC_SELF_TEST_STATE_START; } /************************************************************************* @@ -361,12 +353,32 @@ } } -// TODO: Make this a const +/************************************************************************* + * @brief getRTCTimestamp + * The getRTCTimestamp returns the current time in epoch + * @details + * Inputs : none + * Outputs : current time in epoch + * @param none + * @return lastEpochTime + *************************************************************************/ U32 getRTCTimestamp() { return lastEpochTime; } +/************************************************************************* + * @brief writeToRAM + * The writeToRAM checks whether the RAM status is idle and if it is, it + * will check input address and length to make sure they are within the + * range. If everything is fine, it will prepare the txBuffer and set the + * RAM status to busy + * @details + * Inputs : address, data, length + * Outputs : RTC_RAM_STATUS_T + * @param none + * @return RTC_RAM_STATUS_T + *************************************************************************/ RTC_RAM_STATUS_T writeToRAM( U16 address, U16* data, U32 length ) { RTC_RAM_STATUS_T status = RTCRAMStatus; @@ -409,6 +421,18 @@ return status; } +/************************************************************************* + * @brief readFromRAM + * The readFromRAM checks whether the RAM status is idle and if it is, it + * will check input address and length to make sure they are within the + * range. If everything is fine, it will prepare the txBuffer and set the + * RAM status to busy + * @details + * Inputs : address, length + * Outputs : RTC_RAM_STATUS_T + * @param none + * @return RTC_RAM_STATUS_T + *************************************************************************/ RTC_RAM_STATUS_T readFromRAM( U16 address, U32 length ) { RTC_RAM_STATUS_T status = RTCRAMStatus; @@ -427,6 +451,8 @@ { status = RTCRAMStatus = RTC_RAM_STATUS_IN_PROGRESS; + RTCRAMState = RTC_RAM_STATE_BUSY; + hasReadFromRAMRequested = TRUE; RAMBufferLength = length; @@ -444,27 +470,55 @@ } } } - else if ( status == RTC_RAM_STATUS_COMPLETE ) - { - RTCRAMStatus = RTC_RAM_STATUS_IDLE; - } return status; } +/************************************************************************* + * @brief getRTCRAMState + * The getRTCRAMState returns the RAM state + * @details + * Inputs : none + * Outputs : RTC_RAM_STATE_T + * @param none + * @return RTC_RAM_STATE_T + *************************************************************************/ RTC_RAM_STATE_T getRTCRAMState() { - RTC_RAM_STATE_T state = RTC_RAM_STATE_READY; - return RTCRAMState; } -// TODO: make this function a const +/************************************************************************* + * @brief getRTCRAMStatus + * The getRTCRAMStatus returns the RAM state. If the RAM status is complete + * it will set the RAM status to Idle and the RAM state to Ready + * @details + * Inputs : none + * Outputs : RTC_RAM_STATE_T + * @param none + * @return RTC_RAM_STATE_T + *************************************************************************/ RTC_RAM_STATUS_T getRTCRAMStatus() { + if ( RTCRAMStatus == RTC_RAM_STATUS_COMPLETE ) + { + RTCRAMStatus = RTC_RAM_STATUS_IDLE; + RTCRAMState = RTC_RAM_STATE_READY; + } + return RTCRAMStatus; } +/************************************************************************* + * @brief getDataFromRAM + * The getDataFromRAM populates the provided external buffer with the data + * in the specified address in the RAM + * @details + * Inputs : external buffer (pointer), length + * Outputs : none + * @param none + * @return none + *************************************************************************/ void getDataFromRAM( U16* externalBuffer, U32 length ) { U08 i; @@ -476,7 +530,21 @@ } // ********** Private functions ********* - +/************************************************************************* + * @brief serviceRTC + * The serviceRTC is the interface to the RTC chip: + * If it was called for the first time, it will send the command + * If the provided buffer length is not the same as previous, it will + * set the buffer length. Otherwise it will ignore it + * If it was not called for the first time, it will wait to the buffer + * to be transmitted and then it will populate the provided receive buffer + * If the transaction failed, it will try 3 time before it fails + * @details + * Inputs : bufferTransmit, bufferReceive, bufferLength + * Outputs : result (bool) + * @param none + * @return result (bool) + *************************************************************************/ static BOOL serviceRTC( U16* bufferTransmit, U16* bufferReceive, U16 bufferLength ) { BOOL result = FALSE; @@ -557,13 +625,24 @@ return result; } +/************************************************************************* + * @brief isRTCFunctional + * The isRTCFunctional checks whether the RTC is still functional by checking + * the bits in the first 3 control registers. The function ignore the clear + * flags + * @details + * Inputs : none + * Outputs : hasTestPassed (bool) + * @param none + * @return hasTestPassed (bool) + *************************************************************************/ static BOOL isRTCFunctional() { BOOL hasTestPassed = TRUE; - U16 controlReg1 = rxBuffer[RTC_REG_1_INDEX]; - U16 controlReg2 = rxBuffer[RTC_REG_2_INDEX]; - U16 controlReg3 = rxBuffer[RTC_REG_3_INDEX]; + U16 controlReg1 = rxBuffer[ RTC_REG_1_INDEX ]; + U16 controlReg2 = rxBuffer[ RTC_REG_2_INDEX ]; + U16 controlReg3 = rxBuffer[ RTC_REG_3_INDEX ]; // Ignore the clear flags controlReg2 = controlReg2 & ~RTC_REG_2_MSF; @@ -611,6 +690,15 @@ return hasTestPassed; } +/************************************************************************* + * @brief convertBCD2Decimal + * The convertBCD2Decimal converts the BCD values to decimal + * @details + * Inputs : bcd value + * Outputs : decimal value + * @param none + * @return decimal value + *************************************************************************/ static U08 convertBCD2Decimal( U08 bcd ) { U08 bcdHigh; @@ -625,6 +713,15 @@ return decimal; } +/************************************************************************* + * @brief convertDecimal2BCD + * The convertDecimal2BCD converts the decimal values to BCD + * @details + * Inputs : decimal value + * Outputs : bcd value + * @param none + * @return bcd value + *************************************************************************/ static U08 convertDecimal2BCD( U08 decimal ) { U08 decimalHigh; @@ -641,6 +738,15 @@ return bcd; } +/************************************************************************* + * @brief convertTime2Epoch + * The convertTime2Epoch converts the time into epoch (seconds from Jan 1 1970) + * @details + * Inputs : none + * Outputs : epochTime value + * @param none + * @return epochTime value + *************************************************************************/ static U32 convertTime2Epoch() { struct tm t; @@ -658,6 +764,16 @@ return (U32)epochTime; } +/************************************************************************* + * @brief updateReadTimestampStruct + * The updateReadTimestampStruct function updates the time struct after every + * read + * @details + * Inputs : none + * Outputs : none + * @param none + * @return none + *************************************************************************/ static void updateReadTimestampStruct() { U16 decimalSeconds = convertBCD2Decimal( rxBuffer[ RTC_SECONDS_INDEX ] ); @@ -676,6 +792,16 @@ RTCTimestampStruct.years = decimalYears; } +/************************************************************************* + * @brief setMibSPIBufferLength + * The setMibSPIBufferLength sets the MibSPI buffer length prior to every + * RTC transaction + * @details + * Inputs : length + * Outputs : ransferStatus (bool) + * @param none + * @return transferStatus (bool) + *************************************************************************/ static BOOL setMibSPIBufferLength( U16 length ) { BOOL transferStatus = FALSE; @@ -742,6 +868,15 @@ return transferStatus; } +/************************************************************************* + * @brief prepBufferForReadCommand + * The prepBufferForReadCommand sets the txBuffer for a read + * @details + * Inputs : length + * Outputs : none + * @param none + * @return none + *************************************************************************/ static void prepBufferForReadCommand( U16 length ) { txBuffer[ BUFFER_INDEX_0 ] = RTC_READ_FROM_REG0; @@ -753,6 +888,16 @@ } } +/************************************************************************* + * @brief handleExecWaitForPostState + * The handleExecWaitForPostState checks whether POST has completed and what + * was the result of the POST test. It will either go to Idle of Fault + * @details + * Inputs : none + * Outputs : result (RTC_EXEC_STATE_T) + * @param none + * @return result (RTC_EXEC_STATE_T) + *************************************************************************/ static RTC_EXEC_STATE_T handleExecWaitForPostState() { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_WAIT_FOR_POST; @@ -771,6 +916,17 @@ return result; } +/************************************************************************* + * @brief handleExecIdleState + * The handleExecIdleState checks whether read or write to RTC or RAM has + * been requested. If none of them have been requested, it will increment the + * timer + * @details + * Inputs : none + * Outputs : result (RTC_EXEC_STATE_T) + * @param none + * @return result (RTC_EXEC_STATE_T) + *************************************************************************/ static RTC_EXEC_STATE_T handleExecIdleState() { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_IDLE; @@ -801,6 +957,15 @@ return result; } +/************************************************************************* + * @brief handleExecWriteState + * The handleExecWriteState writes timestamp to RTC + * @details + * Inputs : none + * Outputs : result (RTC_EXEC_STATE_T) + * @param none + * @return result (RTC_EXEC_STATE_T) + *************************************************************************/ static RTC_EXEC_STATE_T handleExecWriteState() { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_WRITE; @@ -815,9 +980,6 @@ timeCounter = 1; hasWriteToRTCRequested = FALSE; - // Reset the RTC Service commands - RTCServiceState = RTC_SEND_COMMAND; - result = RTC_EXEC_STATE_IDLE; } else if ( RTCServiceState == RTC_SERVICE_COMPLETE && ! isStatusOk ) @@ -833,6 +995,15 @@ return result; } +/************************************************************************* + * @brief handleExecPrepRAMState + * The handleExecPrepRAMState prepares the RAM for read or write + * @details + * Inputs : none + * Outputs : result (RTC_EXEC_STATE_T) + * @param none + * @return result (RTC_EXEC_STATE_T) + *************************************************************************/ static RTC_EXEC_STATE_T handleExecPrepRAMState() { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_PREP_RAM; @@ -858,6 +1029,15 @@ return result; } +/************************************************************************* + * @brief handleExecWriteToRAMState + * The handleExecWriteToRAMState writes to RAM + * @details + * Inputs : none + * Outputs : result (RTC_EXEC_STATE_T) + * @param none + * @return result (RTC_EXEC_STATE_T) + *************************************************************************/ static RTC_EXEC_STATE_T handleExecWriteToRAMState() { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_WRITE_TO_RAM; @@ -874,7 +1054,7 @@ } else if ( RTCServiceState == RTC_SERVICE_COMPLETE && !isStatusOk ) { - result = RTC_EXEC_STATE_FAULT; + result = RTC_EXEC_STATE_IDLE; RTCRAMStatus = RTC_RAM_STATUS_FAILED; @@ -884,6 +1064,15 @@ return result; } +/************************************************************************* + * @brief handleExecReadFromRAMState + * The handleExecReadFromRAMState read from RAM + * @details + * Inputs : none + * Outputs : result (RTC_EXEC_STATE_T) + * @param none + * @return result (RTC_EXEC_STATE_T) + *************************************************************************/ static RTC_EXEC_STATE_T handleExecReadFromRAMState() { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_READ_FROM_RAM; @@ -894,16 +1083,33 @@ { result = RTC_EXEC_STATE_IDLE; + RTCRAMStatus = RTC_RAM_STATUS_COMPLETE; + hasReadFromRAMRequested = FALSE; } else if ( RTCServiceState == RTC_SERVICE_COMPLETE && !isStatusOk ) { - result = RTC_EXEC_STATE_FAULT; + result = RTC_EXEC_STATE_IDLE; + + RTCRAMStatus = RTC_RAM_STATUS_COMPLETE; + + hasReadFromRAMRequested = FALSE; } return result; } +/************************************************************************* + * @brief handleExecReadState + * The handleExecReadState reads timestamp from RTC. The function calls + * other functions to update the time struct and convert the latest time + * to epoch + * @details + * Inputs : none + * Outputs : result (RTC_EXEC_STATE_T) + * @param none + * @return result (RTC_EXEC_STATE_T) + *************************************************************************/ static RTC_EXEC_STATE_T handleExecReadState() { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_READ; @@ -935,8 +1141,16 @@ return result; } -// Private self test functions - +/************************************************************************* + * @brief handleSelfTestStart + * The handleSelfTestStart calls another function to prepare the txBuffer + * for a read and sets the state to control registers + * @details + * Inputs : none + * Outputs : result (RTC_SELF_TEST_STATE_T) + * @param none + * @return result (RTC_SELF_TEST_STATE_T) + *************************************************************************/ static RTC_SELF_TEST_STATE_T handleSelfTestStart() { RTC_SELF_TEST_STATE_T result = RTC_SELF_TEST_STATE_START; @@ -948,6 +1162,18 @@ return result; } +/************************************************************************* + * @brief handleSelfTestCheckCtrlRegs + * The handleSelfTestCheckCtrlRegs receives the control registers and calls + * another function to check whether RTC is function or not. If the RTC is + * functional, it will update the RTCPreviousSecond variable and sets the + * state machine to the next state + * @details + * Inputs : none + * Outputs : result (RTC_SELF_TEST_STATE_T) + * @param none + * @return result (RTC_SELF_TEST_STATE_T) + *************************************************************************/ static RTC_SELF_TEST_STATE_T handleSelfTestCheckCtrlRegs() { RTC_SELF_TEST_STATE_T result = RTC_SELF_TEST_STATE_CHECK_CTRL_REGS; @@ -978,6 +1204,17 @@ return result; } +/************************************************************************* + * @brief handleSelfTestWaitForFirstSecond + * The handleSelfTestWaitForFirstSecond continuously reads the RTC and compares + * latest second from RTC to the previous second and if it has changed, it will + * start the timer and set the state machine to the next state + * @details + * Inputs : none + * Outputs : result (RTC_SELF_TEST_STATE_T) + * @param none + * @return result (RTC_SELF_TEST_STATE_T) + *************************************************************************/ static RTC_SELF_TEST_STATE_T handleSelfTestWaitForFirstSecond() { RTC_SELF_TEST_STATE_T result = RTC_SELF_TEST_STATE_WAIT_FOR_FIRST_SECOND; @@ -1013,6 +1250,17 @@ return result; } +/************************************************************************* + * @brief handleSelfTestWaitForSecondSecond + * The handleSelfTestWaitForSecondSecond continuously reads the RTC and compares + * latest second from RTC to the previous second and if it has changed, it will + * set the state machine to the next state + * @details + * Inputs : none + * Outputs : result (RTC_SELF_TEST_STATE_T) + * @param none + * @return result (RTC_SELF_TEST_STATE_T) + *************************************************************************/ static RTC_SELF_TEST_STATE_T handleSelfTestWaitForSecondSecond() { RTC_SELF_TEST_STATE_T result = RTC_SELF_TEST_STATE_WAIT_FOR_SECOND_SECOND; @@ -1045,6 +1293,18 @@ return result; } +/************************************************************************* + * @brief handleSelfTestCheckAccuracy + * The handleSelfTestCheckAccuracy checks whether the time has been elapsed + * within the specified time tolerance. It will call another function to check + * whether one second has elapsed. If the time has elapsed, how much time has + * passed since the last second that was read from RTC + * @details + * Inputs : none + * Outputs : result (RTC_SELF_TEST_STATE_T) + * @param none + * @return result (RTC_SELF_TEST_STATE_T) + *************************************************************************/ static RTC_SELF_TEST_STATE_T handleSelfTestCheckAccuracy() { RTC_SELF_TEST_STATE_T result = RTC_SELF_TEST_STATE_CHECK_ACCURACY;