Index: firmware/App/Controllers/RTC.c =================================================================== diff -u -re0ad341ad6390bafe0954af43d09e9b8577b1042 -r706a2e3f1718102cd34bd7f255901e5e7b8910cb --- firmware/App/Controllers/RTC.c (.../RTC.c) (revision e0ad341ad6390bafe0954af43d09e9b8577b1042) +++ firmware/App/Controllers/RTC.c (.../RTC.c) (revision 706a2e3f1718102cd34bd7f255901e5e7b8910cb) @@ -19,6 +19,7 @@ #include "RTC.h" #include "mibspi.h" +#include // ********** private definitions ********** #define RTC_REG_1_12_HOUR_MODE 0X0004 #define RTC_REG_1_PORO 0X0008 @@ -44,12 +45,15 @@ // This command puts RTC into read mode from // address 0 -#define RTC_READ_ALL 0x00A0 +#define RTC_READ_FROM_REG0 0x00A0 +#define RTC_WRITE_TO_REG3 0x0023 + #define RTC_ACCURACY_TIMEOUT 1000 //ms #define RTC_ACCURACY_TIMEOUT_TOLERANCE 1050 //ms #define NUM_OF_ITEMS_TO_READ 11 +#define TIMER_COUNTER_TO_REQUEST_READ 18 typedef enum RTC_Self_Test_States { @@ -71,52 +75,50 @@ { RTC_EXEC_STATE_WAIT_FOR_POST = 0, RTC_EXEC_STATE_WAIT_FOR_COUNTER, - RTC_EXEC_STATE_READ + RTC_EXEC_STATE_READ, + RTC_EXEC_STATE_WRITE, + RTC_EXEC_STATE_FAULT } RTC_EXEC_STATE_T; +static struct RTCTimestamp +{ + U16 seconds; + U16 minutes; + U16 hours; + U16 days; + U16 weekdays; + U16 months; + U16 years; +} ts; static RTC_SELF_TEST_STATE_T RTCSelfTestState = RTC_SELF_TEST_STATE_START; -static RTC_GET_DATA_STATE_T RTCGetDataState = RTC_SEND_COMMAND; +static RTC_GET_DATA_STATE_T RTCServiceState = RTC_SEND_COMMAND; 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; +static BOOL hasWriteTimestampRequested = FALSE; // TODO: Increase the size of the buffer 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 U16 txBuffer[] = {RTC_READ_FROM_REG0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; -static struct RTCTimestamp +// ********** Private functions ********* +void serviceRTC( U16* buffer ) { - 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() -{ - switch ( RTCGetDataState ) + switch ( RTCServiceState ) { case RTC_SEND_COMMAND: - mibspiSetData(mibspiREG3, 0, txBuffer); + mibspiSetData(mibspiREG3, 0, buffer); mibspiTransfer(mibspiREG3, 0); - RTCGetDataState = RTC_WAIT_FOR_TRANSFER_AND_READ; + RTCServiceState = RTC_WAIT_FOR_TRANSFER_AND_READ; break; case RTC_WAIT_FOR_TRANSFER_AND_READ: @@ -125,7 +127,7 @@ { mibspiGetData(mibspiREG3, 0, rxBuffer); - RTCGetDataState = RTC_READ_COMPLETE; + RTCServiceState = RTC_READ_COMPLETE; } break; @@ -139,28 +141,6 @@ } } - -// 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; @@ -207,6 +187,94 @@ return hasTestPassed; } +U08 convertBCD2Decimal( U08 bcd ) +{ + U08 bcdHigh; + U08 bcdLow; + U08 decimal; + + bcdHigh = ( bcd & 0xF0 ) >> 4; + bcdLow = ( bcd & 0x0F ); + + decimal = ( bcdHigh * 10 ) + bcdLow; + + return decimal; +} + +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; +} + +U32 convertTime2Epoch() +{ + // Either convert time to epoch or use the C time.h library + // to convert to epoch + + struct tm t; + time_t epochTime; + + t.tm_sec = ts.seconds; + t.tm_min = ts.minutes; + t.tm_hour= ts.hours; + t.tm_mday= ts.days; + t.tm_mon = ts.months; + t.tm_year= ts.years + 2000; + t.tm_isdst = -1; + + epochTime = mktime(&t); + + return (U32)epochTime; +} + +void updateTimestampStruct() +{ + ts.seconds = rxBuffer[RTC_SECONDS_INDEX]; + ts.minutes = rxBuffer[RTC_MINUTES_INDEX]; + ts.hours = rxBuffer[RTC_HOURS_INDEX]; + ts.days = rxBuffer[RTC_DAYS_INDEX]; + ts.months = rxBuffer[RTC_MONTHS_INDEX]; + ts.years = rxBuffer[RTC_YEARS_INDEX]; +} + +// ********** Public functions ********** +void initRTC() +{ + // Do nothing for now +} + +// TODO: Does this function need to return a bool? +void setRTCTimestamp( U08 secs, U08 mins, U08 hours, U08 days, U08 months, U16 years ) +{ + hasWriteTimestampRequested = TRUE; + + U16 decimalSeconds = convertDecimal2BCD( secs ); + U16 decimalMins = convertDecimal2BCD( mins ); + U16 decimalHours = convertDecimal2BCD( hours ); + U16 decimalDays = convertDecimal2BCD( days ); + U16 decimalMonths = convertDecimal2BCD( months ); + U16 decimalYears = convertDecimal2BCD( years - 2000 ); + + ts.seconds = decimalSeconds; + ts.minutes = decimalMins; + ts.hours = decimalHours; + ts.days = decimalDays; + ts.weekdays = 0; // Weekdays will not be used + ts.months = decimalMonths; + ts.years = decimalYears; +} + SELF_TEST_STATUS_T execRTCSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; @@ -215,19 +283,19 @@ { case RTC_SELF_TEST_STATE_START: - getRTCData(); + serviceRTC( &txBuffer[0] ); RTCSelfTestState = RTC_SELF_TEST_STATE_CHECK_CTRL_REGS; break; case RTC_SELF_TEST_STATE_CHECK_CTRL_REGS: - getRTCData(); + serviceRTC( &txBuffer[0] ); - if ( RTCGetDataState == RTC_READ_COMPLETE ) + if ( RTCServiceState == RTC_READ_COMPLETE ) { // Reset the states - RTCGetDataState = RTC_SEND_COMMAND; + RTCServiceState = RTC_SEND_COMMAND; if ( isRTCFunctional() ) { @@ -243,12 +311,12 @@ case RTC_SELF_TEST_STATE_COMPARE_SECONDS: - getRTCData(); + serviceRTC( &txBuffer[0] ); - if ( RTCGetDataState == RTC_READ_COMPLETE ) + if ( RTCServiceState == RTC_READ_COMPLETE ) { // Reset the states - RTCGetDataState = RTC_SEND_COMMAND; + RTCServiceState = RTC_SEND_COMMAND; U32 RTCCurrentSecond = rxBuffer[RTC_SECONDS_INDEX]; @@ -296,37 +364,6 @@ return result; } -U08 convertBCD2Decimal( U08 bcd ) -{ - U08 bcdHigh; - U08 bcdLow; - U08 decimal; - - bcdHigh = ( bcd & 0xF0 ) >> 4; - bcdLow = ( bcd & 0x0F ); - - decimal = ( bcdHigh * 10 ) + bcdLow; - - return decimal; -} - -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 ) @@ -341,41 +378,80 @@ case RTC_EXEC_STATE_WAIT_FOR_COUNTER: - if ( hasWriteBeenRequested ) + if ( hasWriteTimestampRequested ) { + // FOR DEBUGGING ONLY, REMOVE THIS CODE + setRTCTimestamp(0, 10, 17, 8, 12, 2019); - } + U16 timestamp[8] = {RTC_WRITE_TO_REG3, ts.seconds, ts.minutes, ts.hours, + ts.days, ts.weekdays, ts.months, + ts.years}; - if ( timeCounter == 18 ) + serviceRTC( ×tamp[0] ); + + RTCExecState = RTC_EXEC_STATE_WRITE; + } + // If write to RTC has been requested, we don't have to read + // write must be finished first + else if ( timeCounter == TIMER_COUNTER_TO_REQUEST_READ ) { // Reset the states - RTCGetDataState = RTC_SEND_COMMAND; + RTCServiceState = RTC_SEND_COMMAND; - getRTCData(); - + serviceRTC( &txBuffer[0] ); RTCExecState = RTC_EXEC_STATE_READ; } else { timeCounter++; } break; + case RTC_EXEC_STATE_WRITE: + serviceRTC( 0 ); + + if ( RTCServiceState == RTC_READ_COMPLETE ) + { + // Write finished. Reset the counter to start + // the read again + timeCounter = 1; + hasWriteTimestampRequested = FALSE; + RTCExecState = RTC_EXEC_STATE_WAIT_FOR_COUNTER; + } + + break; + case RTC_EXEC_STATE_READ: - getRTCData(); + serviceRTC( &txBuffer[0] ); - if ( RTCGetDataState == RTC_READ_COMPLETE ) + if ( RTCServiceState == RTC_READ_COMPLETE ) { - U08 testDate = (U08)rxBuffer[RTC_SECONDS_INDEX]; + if ( isRTCFunctional() ) + { + // FOR TESTING ONLY REMOVE THE CODE + //U08 testDate = (U08)rxBuffer[RTC_SECONDS_INDEX]; + //convertBCD2Decimal( testDate ); - convertBCD2Decimal( testDate ); + updateTimestampStruct(); + convertTime2Epoch(); - timeCounter = 1; - RTCExecState = RTC_EXEC_STATE_WAIT_FOR_COUNTER; + + timeCounter = 1; + RTCExecState = RTC_EXEC_STATE_WAIT_FOR_COUNTER; + } + else + { + RTCExecState = RTC_EXEC_STATE_FAULT; + } } break; + case RTC_EXEC_STATE_FAULT: + // Something failed set the alarms + // TODO: set the alarms and stuff + break; + default: break; } Index: firmware/App/Controllers/RTC.h =================================================================== diff -u -re0ad341ad6390bafe0954af43d09e9b8577b1042 -r706a2e3f1718102cd34bd7f255901e5e7b8910cb --- firmware/App/Controllers/RTC.h (.../RTC.h) (revision e0ad341ad6390bafe0954af43d09e9b8577b1042) +++ firmware/App/Controllers/RTC.h (.../RTC.h) (revision 706a2e3f1718102cd34bd7f255901e5e7b8910cb) @@ -22,7 +22,7 @@ void initRTC( void ); void execRTC( void ); -BOOL setRTCTimestamp( U08 secs, U08 mins, U08 hours, U08 days, U08 months, U08 years ); +void setRTCTimestamp( U08 secs, U08 mins, U08 hours, U08 days, U08 months, U16 years ); SELF_TEST_STATUS_T execRTCSelfTest( void );