Index: firmware/App/Controllers/RTC.c =================================================================== diff -u -ra635fc9674913460c74831add7886c85d8aaf8f1 -re0ad341ad6390bafe0954af43d09e9b8577b1042 --- firmware/App/Controllers/RTC.c (.../RTC.c) (revision a635fc9674913460c74831add7886c85d8aaf8f1) +++ firmware/App/Controllers/RTC.c (.../RTC.c) (revision e0ad341ad6390bafe0954af43d09e9b8577b1042) @@ -15,12 +15,11 @@ **************************************************************************/ #include "Common.h" +#include "Timers.h" #include "RTC.h" #include "mibspi.h" - // ********** private definitions ********** -// TODO: Add the definition of all the registers #define RTC_REG_1_12_HOUR_MODE 0X0004 #define RTC_REG_1_PORO 0X0008 #define RTC_REG_1_CLK_STOPPED 0X0020 @@ -47,30 +46,65 @@ // address 0 #define RTC_READ_ALL 0x00A0 +#define RTC_ACCURACY_TIMEOUT 1000 //ms +#define RTC_ACCURACY_TIMEOUT_TOLERANCE 1050 //ms + +#define NUM_OF_ITEMS_TO_READ 11 + typedef enum RTC_Self_Test_States { RTC_SELF_TEST_STATE_START = 0, RTC_SELF_TEST_STATE_CHECK_CTRL_REGS, - RTC_SELF_TEST_STATE_IN_PROGRESS, + RTC_SELF_TEST_STATE_COMPARE_SECONDS, + RTC_SELF_TEST_STATE_CHECK_ACCURACY, RTC_SELF_TEST_STATE_COMPLETE } RTC_SELF_TEST_STATE_T; -typedef enum RTC_read_data +typedef enum RTC_Read_Data { RTC_SEND_COMMAND = 0, RTC_WAIT_FOR_TRANSFER_AND_READ, RTC_READ_COMPLETE } RTC_GET_DATA_STATE_T; +typedef enum RTC_Exec_State +{ + RTC_EXEC_STATE_WAIT_FOR_POST = 0, + RTC_EXEC_STATE_WAIT_FOR_COUNTER, + RTC_EXEC_STATE_READ +} RTC_EXEC_STATE_T; + static RTC_SELF_TEST_STATE_T RTCSelfTestState = RTC_SELF_TEST_STATE_START; static RTC_GET_DATA_STATE_T RTCGetDataState = RTC_SEND_COMMAND; -static U32 RTCTestTimer = 0; +static RTC_EXEC_STATE_T RTCExecState = RTC_EXEC_STATE_WAIT_FOR_POST; +static U32 RTCSelfTestTimer = 0; +static U32 RTCPreviousSecond = 0; + +static U32 timeCounter = 1; + +static BOOL hasWriteBeenRequested = FALSE; + // TODO: Increase the size of the buffer -static U16 rxBuffer[11]; +static U16 rxBuffer[NUM_OF_ITEMS_TO_READ]; static U16 txBuffer[] = {RTC_READ_ALL, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; +static struct RTCTimestamp +{ + U08 seconds; + U08 minutes; + U08 hours; + U08 days; + U08 months; + U08 years; +} timestamp; + +void initRTC() +{ + // Do nothing for now +} + // TODO: add the pointer to the buffers in the input arguments void getRTCData() { @@ -105,6 +139,28 @@ } } + +// TODO: Does this function need to return a bool? +BOOL setRTCTimestamp( U08 secs, U08 mins, U08 hours, U08 days, U08 months, U08 years ) +{ + hasWriteBeenRequested = TRUE; + + U08 decimalSeconds = convertDecimal2BCD( secs ); + U08 decimalMins = convertDecimal2BCD( mins ); + U08 decimalHours = convertDecimal2BCD( hours ); + U08 decimalDays = convertDecimal2BCD( days ); + U08 decimalMonths = convertDecimal2BCD( months ); + U08 decimalYears = convertDecimal2BCD( years ); + + timestamp.seconds = decimalSeconds; + timestamp.minutes = decimalMins; + timestamp.hours = decimalHours; + timestamp.days = decimalDays; + timestamp.months = decimalMonths; + timestamp.years = decimalYears; +} + + BOOL isRTCFunctional() { BOOL hasTestPassed = TRUE; @@ -162,8 +218,8 @@ getRTCData(); RTCSelfTestState = RTC_SELF_TEST_STATE_CHECK_CTRL_REGS; + break; - case RTC_SELF_TEST_STATE_CHECK_CTRL_REGS: getRTCData(); @@ -175,8 +231,7 @@ if ( isRTCFunctional() ) { - result = SELF_TEST_STATUS_PASSED; - RTCSelfTestState = RTC_SELF_TEST_STATE_IN_PROGRESS; + RTCSelfTestState = RTC_SELF_TEST_STATE_COMPARE_SECONDS; } else { @@ -186,11 +241,49 @@ } break; - case RTC_SELF_TEST_STATE_IN_PROGRESS: + case RTC_SELF_TEST_STATE_COMPARE_SECONDS: + getRTCData(); + if ( RTCGetDataState == RTC_READ_COMPLETE ) + { + // Reset the states + RTCGetDataState = RTC_SEND_COMMAND; + + U32 RTCCurrentSecond = rxBuffer[RTC_SECONDS_INDEX]; + + if ( RTCPreviousSecond == 0 ) + { + RTCPreviousSecond = RTCCurrentSecond; + } + else if ( RTCCurrentSecond > RTCPreviousSecond ) + { + RTCSelfTestTimer = getMSTimerCount(); + + RTCSelfTestState = RTC_SELF_TEST_STATE_CHECK_ACCURACY; + } + } break; + case RTC_SELF_TEST_STATE_CHECK_ACCURACY: + + if ( didTimeout( RTCSelfTestTimer, RTC_ACCURACY_TIMEOUT ) ) + { + U32 elapsedTime = calcTimeSince(RTCSelfTestTimer); + + if ( elapsedTime > RTC_ACCURACY_TIMEOUT_TOLERANCE ) + { + result = SELF_TEST_STATUS_FAILED; + } + else + { + result = SELF_TEST_STATUS_PASSED; + } + + RTCSelfTestState = RTC_SELF_TEST_STATE_COMPLETE; + } + break; + case RTC_SELF_TEST_STATE_COMPLETE: break; @@ -203,30 +296,92 @@ return result; } - - -BOOL readRTCData() +U08 convertBCD2Decimal( U08 bcd ) { - BOOL transferStatus = mibspiIsTransferComplete(mibspiREG3, 0); + U08 bcdHigh; + U08 bcdLow; + U08 decimal; - if ( transferStatus ) - { - mibspiGetData(mibspiREG3, 0, rxBuffer); - } + bcdHigh = ( bcd & 0xF0 ) >> 4; + bcdLow = ( bcd & 0x0F ); - return transferStatus; + decimal = ( bcdHigh * 10 ) + bcdLow; + + return decimal; } -void initRTC() +U08 convertDecimal2BCD( U08 decimal ) { + U08 decimalHigh; + U08 decimalLow; + U08 bcd; + + // Assuming all the decimal provided + // are maximum 2 digits + decimalHigh = decimal / 10; + decimalLow = decimal % 10; + + bcd = (decimalHigh << 4) + decimalLow; + + return bcd; } + void execRTC() { + switch ( RTCExecState ) + { + case RTC_EXEC_STATE_WAIT_FOR_POST: + if ( RTCSelfTestState == RTC_SELF_TEST_STATE_COMPLETE ) + { + RTCExecState = RTC_EXEC_STATE_WAIT_FOR_COUNTER; + } + break; + case RTC_EXEC_STATE_WAIT_FOR_COUNTER: + if ( hasWriteBeenRequested ) + { + + } + + if ( timeCounter == 18 ) + { + // Reset the states + RTCGetDataState = RTC_SEND_COMMAND; + + getRTCData(); + + RTCExecState = RTC_EXEC_STATE_READ; + } + else + { + timeCounter++; + } + break; + + case RTC_EXEC_STATE_READ: + + getRTCData(); + + if ( RTCGetDataState == RTC_READ_COMPLETE ) + { + U08 testDate = (U08)rxBuffer[RTC_SECONDS_INDEX]; + + convertBCD2Decimal( testDate ); + + timeCounter = 1; + RTCExecState = RTC_EXEC_STATE_WAIT_FOR_COUNTER; + } + break; + + default: + break; + } } + +