/************************************************************************** * * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file RTC.c * * @date 27-Nov-2019 * @author D. Navaei * * @brief Monitor/Controller Real Time Clock * **************************************************************************/ #include "Common.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 #define RTC_REG_1_UNUSED 0X0040 #define RTC_REG_1_EXT_CLK_MODE 0X0080 #define RTC_REG_2_MASK 0X0000 #define RTC_REG_3_MASK 0X0008 // RTC registers indices #define RTC_REG_1_INDEX 1 #define RTC_REG_2_INDEX 2 #define RTC_REG_3_INDEX 3 #define RTC_SECONDS_INDEX 4 #define RTC_MINUTES_INDEX 5 #define RTC_HOURS_INDEX 6 #define RTC_DAYS_INDEX 7 #define RTC_WEEKDAYS_INDEX 8 #define RTC_MONTHS_INDEX 9 #define RTC_YEARS_INDEX 10 // This command puts RTC into read mode from // address 0 #define RTC_READ_ALL 0x00A0 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_COMPLETE } RTC_SELF_TEST_STATE_T; typedef enum RTC_read_data { RTC_SEND_COMMAND = 0, RTC_WAIT_FOR_TRANSFER_AND_READ, RTC_READ_COMPLETE } RTC_GET_DATA_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; // TODO: Increase the size of the buffer static U16 rxBuffer[11]; static U16 txBuffer[] = {RTC_READ_ALL, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; // TODO: add the pointer to the buffers in the input arguments void getRTCData() { switch ( RTCGetDataState ) { case RTC_SEND_COMMAND: mibspiSetData(mibspiREG3, 0, txBuffer); mibspiTransfer(mibspiREG3, 0); RTCGetDataState = RTC_WAIT_FOR_TRANSFER_AND_READ; break; case RTC_WAIT_FOR_TRANSFER_AND_READ: if ( mibspiIsTransferComplete(mibspiREG3, 0) ) { mibspiGetData(mibspiREG3, 0, rxBuffer); RTCGetDataState = RTC_READ_COMPLETE; } break; case RTC_READ_COMPLETE: // Done with reading and transfer do nothing break; default: // TODO: Set an alarm or try multiple times (3 times) before failing break; } } BOOL isRTCFunctional() { BOOL hasTestPassed = TRUE; U16 controlReg1 = rxBuffer[RTC_REG_1_INDEX]; U16 controlReg2 = rxBuffer[RTC_REG_2_INDEX]; U16 controlReg3 = rxBuffer[RTC_REG_2_INDEX]; if ( ! controlReg1 & RTC_REG_1_12_HOUR_MODE ) { // Set the alarm for 24 hour mode hasTestPassed = FALSE; } if ( ! controlReg1 & RTC_REG_1_PORO ) { // Set the alarm for PORO low mode hasTestPassed = FALSE; } if ( ! controlReg1 & RTC_REG_1_CLK_STOPPED ) { // Set the alarm for clock stopped mode hasTestPassed = FALSE; } if ( ! controlReg1 & RTC_REG_1_UNUSED ) { // Set the alarm for unused bit set to 1 mode hasTestPassed = FALSE; } if ( ! controlReg1 & RTC_REG_1_EXT_CLK_MODE ) { // Set the alarm for clock set on external mode hasTestPassed = FALSE; } if ( ! controlReg2 & RTC_REG_2_MASK ) { // Set the alarm for register 2 hasTestPassed = FALSE; } if ( ! controlReg3 & RTC_REG_3_MASK ) { // Set the alarm for register 3 hasTestPassed = FALSE; } return hasTestPassed; } SELF_TEST_STATUS_T execRTCSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; switch ( RTCSelfTestState ) { case RTC_SELF_TEST_STATE_START: getRTCData(); RTCSelfTestState = RTC_SELF_TEST_STATE_CHECK_CTRL_REGS; case RTC_SELF_TEST_STATE_CHECK_CTRL_REGS: getRTCData(); if ( RTCGetDataState == RTC_READ_COMPLETE ) { // Reset the states RTCGetDataState = RTC_SEND_COMMAND; if ( isRTCFunctional() ) { result = SELF_TEST_STATUS_PASSED; RTCSelfTestState = RTC_SELF_TEST_STATE_IN_PROGRESS; } else { result = SELF_TEST_STATUS_FAILED; RTCSelfTestState = RTC_SELF_TEST_STATE_COMPLETE; } } break; case RTC_SELF_TEST_STATE_IN_PROGRESS: break; case RTC_SELF_TEST_STATE_COMPLETE: break; default: // TODO: Add the alarms result = SELF_TEST_STATUS_FAILED; break; } return result; } BOOL readRTCData() { BOOL transferStatus = mibspiIsTransferComplete(mibspiREG3, 0); if ( transferStatus ) { mibspiGetData(mibspiREG3, 0, rxBuffer); } return transferStatus; } void initRTC() { } void execRTC() { }