Index: NVDataMgmt.c =================================================================== diff -u -re865487e2b48d708713b2bcce3d03f378a3d5207 -r51178541e201275f227c8b3e8084a455bb78cf39 --- NVDataMgmt.c (.../NVDataMgmt.c) (revision e865487e2b48d708713b2bcce3d03f378a3d5207) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision 51178541e201275f227c8b3e8084a455bb78cf39) @@ -22,165 +22,212 @@ #include "NVDataMgmt.h" #include "RTC.h" #include "system.h" -#include "Utilities.h" #include "Timers.h" +#include "Utilities.h" // Private defines -#define QUEUE_MAX_SIZE 20U -#define QUEUE_START_INDEX 0U -#define MIN_QUEUE_COUNT_FOR_DATA_LOG 3U +#define QUEUE_MAX_SIZE 20U ///< Max queue size +#define QUEUE_START_INDEX 0U ///< Queue start index +#define MIN_JOBS_NEEDED_FOR_DATA_LOG 3U ///< Min queue required for data log (3) +#define MIN_JOBS_NEEDED_FOR_SECTOR_0 4U ///< Min queue count needed to write all (4) records back in sector 0 // The clock frequency comes from HCLK_FREQ and it has to be rounded up to the // nearest number -#define ROUNDED_HCLK_FREQ FLOAT_TO_INT_WITH_ROUND(HCLK_FREQ) -#define BANK7_SECTOR_0_31_ENABLE_BIT_MASK 0x0000000F -#define BANK7_SECTOR_32_63_ENABLE_BIT_MASK 0x00000000 +#define ROUNDED_HCLK_FREQ FLOAT_TO_INT_WITH_ROUND(HCLK_FREQ) ///< Rounded HCLK for EERPOM clock +#define BANK7_SECTOR_0_31_ENABLE_BIT_MASK 0x0000000F ///< Bank7 sector 0 t0 31 enable mask +#define BANK7_SECTOR_32_63_ENABLE_BIT_MASK 0x00000000 ///< Bank7 sector 32 to 63 enable mask -#define BANK7_SECTOR0_START_ADDRESS 0xF0200000 -#define BANK7_SECTOR0_END_ADDRESS 0xF0203FFF +#define BANK7_SECTOR0_START_ADDRESS 0xF0200000 ///< Bank7 sector 0 start address +#define BANK7_SECTOR0_END_ADDRESS 0xF0203FFF ///< Bank7 sector 0 end address -#define BANK7_SECTOR1_START_ADDRESS 0xF0204000 -#define BANK7_SECTOR1_END_ADDRESS 0xF0207FFF +#define BANK7_SECTOR1_START_ADDRESS 0xF0204000 ///< Bank7 sector 1 start address +#define BANK7_SECTOR1_END_ADDRESS 0xF0207FFF ///< Bank7 sector 1 end address -#define BANK7_SECTOR2_START_ADDRESS 0xF0208000 -#define BANK7_SECTOR2_END_ADDRESS 0xF020BFFF +#define BANK7_SECTOR2_START_ADDRESS 0xF0208000 ///< Bank7 sector 2 start address +#define BANK7_SECTOR2_END_ADDRESS 0xF020BFFF ///< Bank7 sector 2 end address -#define BANK7_SECTOR3_START_ADDRESS 0xF020C000 -#define BANK7_SECTOR3_END_ADDRESS 0xF020FFFF +#define BANK7_SECTOR3_START_ADDRESS 0xF020C000 ///< Bank7 sector 3 start address +#define BANK7_SECTOR3_END_ADDRESS 0xF020FFFF ///< Bank7 sector 3 end address -#define MAX_EEPROM_WRITE_BUFFER_BYTES 16U //Assert -#define MAX_JOB_DATA_SIZE_BYTES 32U -#define LOG_DATA_START_INDEX 0U -#define MAX_NUM_OF_SECTORS_FOR_LOG_DATA 3U +#define MAX_EEPROM_WRITE_BUFFER_BYTES 16U ///< Max allowed bytes for an EEPROM write (16 bytes) + +#define MAX_JOB_DATA_SIZE_BYTES 32U ///< Max bytes per job (32 bytes) +#define LOG_DATA_START_INDEX 0U ///< Log data start index +#define MAX_NUM_OF_SECTORS_FOR_LOG_DATA 3U ///< Max number of sector (3 sectors) #define MAX_LOG_DATA_PER_SECTOR (((BANK7_SECTOR1_END_ADDRESS + 1) - \ - BANK7_SECTOR1_START_ADDRESS) / MAX_JOB_DATA_SIZE_BYTES) -#define MAX_NUM_OF_DATA_LOGS_IN_SECTOR3 (MAX_NUM_OF_SECTORS_FOR_LOG_DATA * MAX_LOG_DATA_PER_SECTOR) -#define MAX_NUM_OF_DATA_LOGS_IN_SECTOR2 ((MAX_NUM_OF_SECTORS_FOR_LOG_DATA - 1) * MAX_LOG_DATA_PER_SECTOR) -#define MAX_NUM_OF_DATA_LOGS_IN_SECTOR1 ((MAX_NUM_OF_SECTORS_FOR_LOG_DATA - 2) * MAX_LOG_DATA_PER_SECTOR) + BANK7_SECTOR1_START_ADDRESS) / MAX_JOB_DATA_SIZE_BYTES) ///< Max log data per sector (512 for now) +#define MAX_NUM_OF_EVENTS_IN_SECTOR3 (MAX_NUM_OF_SECTORS_FOR_LOG_DATA * MAX_LOG_DATA_PER_SECTOR) ///< Max number of accumulated logs in sector 3 (1536) +#define MAX_NUM_OF_EVENTS_IN_SECTOR2 ((MAX_NUM_OF_SECTORS_FOR_LOG_DATA - 1) * MAX_LOG_DATA_PER_SECTOR) ///< Max number of accumulated logs in sector 2 (1024) +#define MAX_NUM_OF_EVENTS_IN_SECTOR1 ((MAX_NUM_OF_SECTORS_FOR_LOG_DATA - 2) * MAX_LOG_DATA_PER_SECTOR) ///< Max number of accumulated logs in sector 1 (512) -// Data addresses in EEPROM and RTC RAM -#define BOOTLOADER_FLAG_ADDRESS 0x00000000 -#define BOOTLOADER_FLAG_LENGTH_BYTES 4U -#define LOG_RECORD_START_ADDRESS 0x00000010 // 16 -#define MFG_RECORD_START_ADDRESS 0X00000020 // 32 -#define HD_TREATMENT_TIME_ADDRESS 0X00000030 // 48 -#define DG_CONSUMED_WATER_ADDRESS 0X00000040 // 64 +// Data addresses and length in RTC RAM +#define BOOTLOADER_FLAG_ADDRESS 0x00000000 ///< Bootloader start address in RTC RAM (0) +#define BOOTLOADER_FLAG_LENGTH_BYTES 4U ///< Bootloader number of bytes (4 bytes) +#define LOG_RECORD_START_ADDRESS 0x00000010 // 16 ///< Log record start address in RTC RAM (16) +#define HD_TREATMENT_TIME_ADDRESS 0X00000030 // 48 ///< HD treatment time start address in RTC RAM (48) +#define DG_CONSUMED_WATER_ADDRESS 0X00000040 // 64 ///< DG water consumption start address in RTC RAM (64) +#define SERVICE_DATE_START_ADDRESS 0X00000050 // 80 ///< Service date record start address in RTC RAM (80) +#define LAST_DISINFECTION_DATE_ADDRESS 0x00000060 // 96 ///< Last disinfection date start address in RTC RAM (96) -#define CAL_RECORD_START_ADDRESS (BANK7_SECTOR0_START_ADDRESS + 0x100) +// Data addresses in EEPROM +#define CALIBRATION_RECORD_START_ADDRESS (BANK7_SECTOR0_START_ADDRESS + 0x100) ///< Calibration record start address in EEPROM +#define COMMAND_TIME_OUT 500U // time in ms ///< Timeout for an EEPROM or RTC command in ms +/// NVDataMgmt self test states typedef enum NVDataMgmt_Self_Test_States { - NVDATAMGMT_SELF_TEST_STATE_START = 0, - NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD, - NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME, - NVDATAMGMT_SELF_TEST_STATE_READ_WATER_CONSUMPTION, - NVDATAMGMT_SELF_TEST_STATE_READ_MFG_RECORD, - NVDATAMGMT_SELF_TEST_STATE_READ_CAL_RECORD, - NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC, - NVDATAMGMT_SELF_TEST_STATE_COMPLETE, - NUM_OF_NVDATAMGMT_SELF_TEST_STATES + NVDATAMGMT_SELF_TEST_STATE_START = 0, ///< Self test start + NVDATAMGMT_SELF_TEST_STATE_ENABLE_EEPROM, ///< Self test enable EERPOM + NVDATAMGMT_SELF_TEST_STATE_READ_BOOTLOADER_FLAG, ///< Self test read bootloader + NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD, ///< Self test read log record + NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME, ///< Self test read treatment time + NVDATAMGMT_SELF_TEST_STATE_READ_WATER_CONSUMPTION, ///< Self test read water consumption + NVDATAMGMT_SELF_TEST_STATE_READ_MFG_RECORD, ///< Self test read manufacturing record + NVDATAMGMT_SELF_TEST_STATE_READ_CAL_RECORD, ///< Self test read calibration record + NVDATAMGMT_SELF_TEST_STATE_READ_SERVICE_RECORD, ///< Self test read service record + NVDATAMGMT_SELF_TEST_STATE_READ_LAST_DISINFECTION_DATE, ///< Self test read last disinfection date + NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC, ///< Self test check CRC + NVDATAMGMT_SELF_TEST_STATE_COMPLETE, ///< Self test complete + NUM_OF_NVDATAMGMT_SELF_TEST_STATES ///< Total number of self test states } NVDATAMGMT_SELF_TEST_STATE_T; +/// NVDataMgmt Exec states typedef enum NVDataMgmt_Exec_State { - NVDATAMGMT_EXEC_STATE_WAIT_FOR_POST = 0, - NVDATAMGMT_EXEC_STATE_IDLE, - NVDATAMGMT_EXEC_STATE_WRITE_TO_EEPROM, - NVDATAMGMT_EXEC_STATE_READ_FROM_EEPROM, - NVDATAMGMT_EXEC_STATE_ERASE_EEPROM, - NVDATAMGMT_EXEC_STATE_WRITE_TO_RTC, - NVDATAMGMT_EXEC_STATE_READ_FROM_RTC, - NVDATAMGMT_EXEC_STATE_FAULT, - NUM_OF_NVDATAMGMT_EXEC_STATES + NVDATAMGMT_EXEC_STATE_WAIT_FOR_POST = 0, ///< Exec state wait for POST + NVDATAMGMT_EXEC_STATE_IDLE, ///< Exec state Idle + NVDATAMGMT_EXEC_STATE_WRITE_TO_EEPROM, ///< Exec state write to EEPROM + NVDATAMGMT_EXEC_STATE_READ_FROM_EEPROM, ///< Exec state read from EEPROM + NVDATAMGMT_EXEC_STATE_ERASE_EEPROM, ///< Exec state erase EEPROM + NVDATAMGMT_EXEC_STATE_WRITE_TO_RTC, ///< Exec state write to RTC + NVDATAMGMT_EXEC_STATE_READ_FROM_RTC, ///< Exec state read from RTC + NUM_OF_NVDATAMGMT_EXEC_STATES ///< Total number of exec states } NVDATAMGMT_EXEC_STATE_T; +/// NVDataMgmt memory operation modes typedef enum NVDataMgmt_Operation { - NVDATAMGMT_NONE = 0, - NVDATAMGMT_WRITE, - NVDATAMGMT_READ, - NVDATAMGMT_ERASE_SECTOR, - NUM_OF_NVDATAMGMT_OPS_STATES + NVDATAMGMT_NONE = 0, ///< Default mode to prevent any accidental ops + NVDATAMGMT_WRITE, ///< Operation mode write + NVDATAMGMT_READ, ///< Operation mode read + NVDATAMGMT_ERASE_SECTOR, ///< Operation mode erase a sector (EEPROM) + NUM_OF_NVDATAMGMT_OPS_STATES ///< Total number of operation states } NVDATAMGMT_OPERATION_STATE_T; +/// NVDataMgmt memory locations typedef enum NVDataMgmt_Location { - NVDATAMGMT_EEPROM = 0, - NVDATAMGMT_RTC, - NUM_OF_NVDATAMGMT_LOC_STATES + NVDATAMGMT_EEPROM = 0, ///< Location EEPROM + NVDATAMGMT_RTC, ///< Location RTC (RAM) + NUM_OF_NVDATAMGMT_LOC_STATES ///< Total number of location states } NVDATAMGMT_LOCATION_STATE_T; #pragma pack(push, 1) +/// Memory operations struct typedef struct { - NVDATAMGMT_OPERATION_STATE_T memoryOperation; - NVDATAMGMT_LOCATION_STATE_T memoryLocation; - U32* startAddress; - U08 buffer [ MAX_JOB_DATA_SIZE_BYTES ]; - READ_DATA_T* externalAddress; - U32 length; + NVDATAMGMT_OPERATION_STATE_T memoryOperation; ///< Memory operation + NVDATAMGMT_LOCATION_STATE_T memoryLocation; ///< Memory location + U32* startAddress; ///< Operation start address + U08 buffer [ MAX_JOB_DATA_SIZE_BYTES ]; ///< Buffer + READ_DATA_T* externalAddress; ///< External address of a buffer + U32 length; ///< Length of a buffer } MEMORY_OPS_T; +/// Log header struct typedef struct { - U16 recordCount; - U16 nextWriteIndex; - U16 nextReadIndex; + U16 recordCount; ///< Record count + U16 nextWriteIndex; ///< Next write index + U16 nextReadIndex; ///< Next read index + BOOL isHdrCorrupted; ///< Log header corruption flag } LOG_HEADER_T; +/// Log record struct typedef struct { - LOG_HEADER_T logHeader; - U16 crc; + LOG_HEADER_T logHeader; ///< Log header struct + U16 crc; ///< Log header CRC } LOG_RECORD_T; +/// Treatment time struct typedef struct { - U32 treatmentTime; - U16 crc; + U32 treatmentTime; ///< Treatment time + U16 crc; ///< Treatment time CRC } TREATMENT_TIME_RECORD_T; +/// Water consumption struct typedef struct { - U32 waterConsumption; - U16 crc; -} WATER_CONSUPTION_T; + U32 waterConsumption; ///< Water consumption + U16 crc; ///< Water consumption CRC +} WATER_CONSUMPTION_RECORD_T; +/// Manufacturing data struct typedef struct { - MFG_DATA_T mfgData; - U16 crc; + MFG_DATA_T mfgData; ///< Manufacturing data struct + U16 crc; ///< Manufacturing data CRC } MFG_RECORD_T; +/// Service record struct typedef struct { - CALIBRATION_DATA_T calData; - U16 crc; + SERVICE_DATA_T serviceData; ///< Service date struct + U16 crc; ///< Service data CRC +} SERVICE_RECORD_T; + +/// Calibration record struct +typedef struct +{ + CALIBRATION_DATA_T calData; ///< Calibration data struct + U16 crc; ///< Calibration data CRC } CALIBRATION_RECORD_T; +/// Last disinfection record struct typedef struct { - U32 epochTime; - U32 eventCode; - U32 subCode; - F32 data1; - F32 data2; - F32 data3; - F32 data4; - F32 data5; -} LOG_DATA_T; + DISINFECTION_DATE_T date; ///< Disinfection date (char array) + U16 crc; ///< Disinfection date CRC +} LAST_DISINFECTION_RECORD_T; #pragma pack(pop) +// Private variables + +static MEMORY_OPS_T jobQueue [ QUEUE_MAX_SIZE ]; ///< Job queue buffer +static MEMORY_OPS_T currentJob; ///< Current job +static LOG_RECORD_T logRecord; ///< Log record variable +static TREATMENT_TIME_RECORD_T treatmentTimeRecord; ///< Treatment time record +static WATER_CONSUMPTION_RECORD_T waterConsumptionRecord; ///< Water consumption record +static MFG_RECORD_T mfgRecord; ///< Manufacturing record +static CALIBRATION_RECORD_T calibrationRecord; ///< Calibration record +static SERVICE_RECORD_T serviceRecord; ///< Service record +static LAST_DISINFECTION_RECORD_T lastDisinfectionRecord; ///< Disinfection record +static U08 queueRearIndex = QUEUE_START_INDEX; ///< Queue rear index +static U08 queueFrontIndex = QUEUE_START_INDEX; ///< Queue front index +static U08 queueCount = 0; ///< Queue count +static NVDATAMGMT_SELF_TEST_STATE_T NVDataMgmtSelfTestState = NVDATAMGMT_SELF_TEST_STATE_START; ///< NVDataMgmt self test state variable +static NVDATAMGMT_EXEC_STATE_T NVDataMgmtExecState = NVDATAMGMT_EXEC_STATE_WAIT_FOR_POST; ///< NVDataMgmt exec state variable +static SELF_TEST_STATUS_T NVDataMgmtSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; ///< NVDataMgmt self test result +static U32 bootloaderFlag = 0; ///< Bootloader flag +static BOOL hasCommandTimedout = FALSE; ///< Boolean flag for timeout of the commands +static U32 currentTime = 0; ///< Current time + // Private functions static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestStart ( void ); +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestEnableEEPROM ( void ); +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadBootloaderFlag ( void ); +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadHDTreatmentTime ( void ); +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadDGWaterConsumption ( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadLogRecord ( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadMfgRecord ( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadCalibrationRecord ( void ); -static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadHDTreatmentTime ( void ); -static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadDGWaterConsumption ( void ); +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadServiceRecord ( void ); +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadLastDisinfectionDate ( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestCheckCRC ( void ); static NVDATAMGMT_EXEC_STATE_T handleExecWaitForPostState ( void ); @@ -203,34 +250,13 @@ static BOOL isQueueEmpty ( void ); static BOOL isQueueFull ( void ); static U32 getAvailableQueueCount ( void ); +static BOOL enqueueBank7Sector0Records ( void ); -// Private variables +// Helper functions -static MEMORY_OPS_T jobQueue [ QUEUE_MAX_SIZE ]; -static U08 readBuffer [ MAX_JOB_DATA_SIZE_BYTES ]; // TODO: REMOVE THIS -static MEMORY_OPS_T currentJob; -static LOG_HEADER_T logHeader; // Change this -static TREATMENT_TIME_RECORD_T treatmentTimeRecord; -static WATER_CONSUPTION_T waterConsumptionRecord; -static LOG_DATA_T logData; -static MFG_RECORD_T mfgRecord; -static CALIBRATION_RECORD_T calibrationRecord; -static U08 queueRearIndex = QUEUE_START_INDEX; -static U08 queueFrontIndex = QUEUE_START_INDEX; -static U08 queueCount = 0; -static Fapi_StatusType EEPROMStatus = Fapi_Status_Success; -static NVDATAMGMT_SELF_TEST_STATE_T NVDataMgmtSelfTestState = NVDATAMGMT_SELF_TEST_STATE_START; -static NVDATAMGMT_EXEC_STATE_T NVDataMgmtExecState = NVDATAMGMT_EXEC_STATE_WAIT_FOR_POST; -static SELF_TEST_STATUS_T NVDataMgmtSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; -static BOOL isServiceOnEntry = TRUE; -static U32 bootloaderFlag = 0; +static BOOL didCommandTimeout ( ALARM_ID_T alarm, U08* state ); +static BOOL eraseDataLogSectors ( void ); -// REMOVE THIS CODE -//static U08 tempBufferForTest[5] = {'5', 'Y', 'I', 'D', 'P'}; -static U08 readBufferForTest [ 36 ]; -static READ_DATA_T mytest; -// REMOVE THIS CODE - /************************************************************************* * @brief initNVDataMgmt * The initNVDataMgmt initializes EEPROM @@ -242,16 +268,14 @@ *************************************************************************/ void initNVDataMgmt ( void ) { - // TODO: initialize all the necessary variables NVDataMgmtSelfTestState = NVDATAMGMT_SELF_TEST_STATE_START; - EEPROMStatus = Fapi_Status_Success; NVDataMgmtExecState = NVDATAMGMT_EXEC_STATE_WAIT_FOR_POST; NVDataMgmtSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; - isServiceOnEntry = TRUE; queueRearIndex = QUEUE_START_INDEX; queueFrontIndex = QUEUE_START_INDEX; - EEPROMStatus = Fapi_initializeFlashBanks( ROUNDED_HCLK_FREQ ); - EEPROMStatus = Fapi_setActiveFlashBank( Fapi_FlashBank7 ); + queueCount = 0; + Fapi_initializeFlashBanks( ROUNDED_HCLK_FREQ ); + Fapi_setActiveFlashBank( Fapi_FlashBank7 ); } /************************************************************************* @@ -261,63 +285,154 @@ * calls another function to erase sector 0 and write the new manufacturing * data. * @details - * Inputs : data - * Outputs : status (BOOL) + * Inputs : MFG_DATA_T (data) + * Outputs : BOOL * @param none - * @return status (BOOL) + * @return BOOL *************************************************************************/ BOOL setMfgData ( MFG_DATA_T data ) { - BOOL status = FALSE; mfgRecord.mfgData = data; - U16 calculateCRC = crc16 ( (U08*)&mfgRecord.mfgData, sizeof( MFG_DATA_T ) ); - mfgRecord.crc = calculateCRC; + mfgRecord.crc = crc16 ( (U08*)&mfgRecord.mfgData, sizeof(MFG_DATA_T) ); + BOOL status = enqueueBank7Sector0Records(); + return status; +} - //TODO Add min jobs?? - if ( !isQueueFull() ) +/************************************************************************* + * @brief getMfgData + * The getMfgData returns the data in the struct that holds manufacturing + * record to buffer that the caller has provided + * @details + * Inputs : MFG_DATA_T* (buffer) + * Outputs : BOOL (status) + * @param none + * @return BOOL (status) + *************************************************************************/ +BOOL getMfgData ( MFG_DATA_T* buffer ) +{ + BOOL status = FALSE; + + if ( buffer != NULL ) { - enqueue ( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, BANK7_SECTOR0_START_ADDRESS, 0, 0, 0 ); - enqueue ( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, BANK7_SECTOR0_START_ADDRESS, - (U08*)&mfgRecord, 0, sizeof(MFG_RECORD_T) ); + memcpy ( buffer, (U08*)&mfgRecord.mfgData, sizeof(MFG_DATA_T) ); status = TRUE; } return status; } /************************************************************************* - * @brief getMfgData - * The getMfgData returns the data in the struct that hold manufacturing + * @brief setCalibrationData + * The setCalibrationData updates the struct that holds the calibration data, + * calls another function to calculate the CRC for the provided data and + * calls another function to erase sector 0 and write the new manufacturing + * data. + * @details + * Inputs : MFG_DATA_T (data) + * Outputs : BOOL + * @param none + * @return BOOL + *************************************************************************/ +BOOL setCalibrationData ( CALIBRATION_DATA_T data ) +{ + calibrationRecord.calData = data; + calibrationRecord.crc = crc16 ( (U08*)&calibrationRecord.calData, + sizeof(CALIBRATION_DATA_T) ); + // The entire sector 0 must be erased and re-written again + BOOL status = enqueueBank7Sector0Records(); + return status; +} + +/************************************************************************* + * @brief getCalibrationData + * The getCalibrationData returns the data in the struct that hold calibration * record to buffer that the caller has provided * @details - * Inputs : buffer - * Outputs : none + * Inputs : CALIBRATION_DATA_T* (buffer) + * Outputs : BOOL (status) * @param none - * @return none + * @return BOOL (status) *************************************************************************/ -void getMfgData ( U08* buffer ) +BOOL getCalibrationData ( CALIBRATION_DATA_T* buffer ) { - memcpy ( buffer, (U08*)&mfgRecord, sizeof(MFG_RECORD_T) ); + BOOL status = FALSE; + + if ( buffer != NULL ) + { + memcpy ( buffer, (U08*)&calibrationRecord.calData, sizeof(CALIBRATION_DATA_T) ); + status = TRUE; + } + + return status; + } +/************************************************************************* + * @brief setServiceDate + * The setServiceDate updates the struct that holds the calibration data, + * calls another function to calculate the CRC for the provided data if + * there is enough queues available, it schedules a write to RTC RAM + * @details + * Inputs : SERVICE_DATA_T (data) + * Outputs : BOOL + * @param none + * @return BOOL + *************************************************************************/ +BOOL setServiceDate ( SERVICE_DATA_T data ) +{ + BOOL status = FALSE; + serviceRecord.serviceData = data; + serviceRecord.crc = crc16 ( (U08*)&serviceRecord.serviceData, sizeof(SERVICE_DATA_T) ); + + if ( !isQueueFull() ) + { + enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, SERVICE_DATE_START_ADDRESS, + (U08*)&serviceRecord, 0, sizeof(SERVICE_RECORD_T) ); + status = TRUE; + } + + return status; } /************************************************************************* + * @brief getServiceDate + * The getServiceDate returns the data in the struct that holds service + * date to buffer that the caller has provided + * @details + * Inputs : SERVICE_DATA_T* (buffer) + * Outputs : BOOL (status) + * @param none + * @return BOOL (status) + *************************************************************************/ +BOOL getServiceDate ( SERVICE_DATA_T* buffer ) +{ + BOOL status = FALSE; + + if ( buffer != NULL ) + { + memcpy ( buffer, (U08*)&serviceRecord.serviceData, sizeof(SERVICE_DATA_T) ); + status = TRUE; + } + + return status; +} + +/************************************************************************* * @brief writeLogData * The writeLogData checks if the queue is not full and if it is not, it calls * enqueue to schedule a job for writing the log data * @details - * Inputs : data + * Inputs : LOG_DATA_T* (data) * Outputs : BOOL * @param none * @return BOOL *************************************************************************/ -BOOL writeLogData ( U08* data ) +BOOL writeLogData ( LOG_DATA_T* data ) { BOOL status = FALSE; - U32 availableQueue = getAvailableQueueCount(); - if ( availableQueue >= MIN_QUEUE_COUNT_FOR_DATA_LOG ) + // If the header is corrupted, no more data is allowed to be written + if ( !isQueueFull() && logRecord.logHeader.isHdrCorrupted == FALSE ) { - enqueue ( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, 0, data, 0, sizeof(LOG_HEADER_T) ); + enqueue ( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, 0, (U08*)&data, 0, sizeof(LOG_DATA_T) ); status = TRUE; } @@ -329,7 +444,7 @@ * The readLogData checks if the queue is not full and if it is not, it calls * enqueue to schedule a job for writing the log data * @details - * Inputs : data + * Inputs : READ_DATA_T* (buffer), U32 (length) * Outputs : BOOL * @param none * @return BOOL @@ -339,7 +454,7 @@ BOOL status = FALSE; U32 availableQueue = getAvailableQueueCount(); - if ( availableQueue >= MIN_QUEUE_COUNT_FOR_DATA_LOG ) + if ( availableQueue >= MIN_JOBS_NEEDED_FOR_DATA_LOG ) { enqueue( NVDATAMGMT_READ, NVDATAMGMT_EEPROM, 0, 0, buffer, length ); status = TRUE; @@ -358,45 +473,128 @@ * @param none * @return BOOL *************************************************************************/ -BOOL setTreatmentTime ( U32 mins ) +BOOL setTreatmentTime ( U32 hours ) { BOOL status = FALSE; + treatmentTimeRecord.treatmentTime = hours; + treatmentTimeRecord.crc = crc16 ( (U08*)&treatmentTimeRecord.treatmentTime, sizeof(U32) ); if ( !isQueueFull() ) { enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, HD_TREATMENT_TIME_ADDRESS, - (U08*)&mins, 0, sizeof(mins) ); + (U08*)&treatmentTimeRecord, 0, sizeof(TREATMENT_TIME_RECORD_T) ); status = TRUE; } return status; } /************************************************************************* - * @brief setLitersOfFilteredWater - * The setLitersOfFilteredWater sets a queue job to write the amount of water + * @brief getTreatmentTime + * The getTreatmentTime returns the total number treatment hours of the + * HD device + * @details + * Inputs : none + * Outputs : U32 + * @param none + * @return U32 + *************************************************************************/ +U32 getTreatmentTime ( void ) +{ + return treatmentTimeRecord.treatmentTime; +} + +/************************************************************************* + * @brief setWaterConsumption + * The setWaterConsumption sets a queue job to write the amount of water * that has been consumed in DG * @details * Inputs : U32 (liters) * Outputs : BOOL * @param none * @return BOOL *************************************************************************/ -BOOL setLitersOfFilteredWater ( U32 liters ) +BOOL setWaterConsumption ( U32 liters ) { BOOL status = FALSE; + waterConsumptionRecord.waterConsumption = liters; + waterConsumptionRecord.crc = crc16 ( (U08*)&waterConsumptionRecord.waterConsumption, sizeof(U32) ); if ( !isQueueFull() ) { enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, DG_CONSUMED_WATER_ADDRESS, - (U08*)&liters, 0, sizeof(liters) ); + (U08*)&waterConsumptionRecord, 0, sizeof(WATER_CONSUMPTION_RECORD_T) ); status = TRUE; } return status; } /************************************************************************* + * @brief getWaterConsumption + * The getWaterConsumption returns the amount of consumed water + * @details + * Inputs : none + * Outputs : U32 + * @param none + * @return U32 + *************************************************************************/ +U32 getWaterConsumption ( void ) +{ + return waterConsumptionRecord.waterConsumption; +} + +/************************************************************************* + * @brief setDisinfectionDate + * The setDisinfectionDate gets the last disinfection date, calculates the + * CRC for it and if the queue is not full, it schedules a write to RTC RAM + * to store the last date + * @details + * Inputs : DISINFECTION_DATE_T (date) + * Outputs : BOOL (status) + * @param none + * @return BOOL (status) + *************************************************************************/ +BOOL setDisinfectionDate ( DISINFECTION_DATE_T date ) +{ + BOOL status = FALSE; + memcpy ( lastDisinfectionRecord.date.disinfectionDate, date.disinfectionDate, sizeof(DISINFECTION_DATE_T) ); + lastDisinfectionRecord.crc = crc16 ( (U08*)&lastDisinfectionRecord.date.disinfectionDate, sizeof(DISINFECTION_DATE_T) ); + + if ( !isQueueFull() ) + { + enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, LAST_DISINFECTION_DATE_ADDRESS, + (U08*)&lastDisinfectionRecord, 0, sizeof(LAST_DISINFECTION_RECORD_T) ); + status = TRUE; + } + + return status; +} + +/************************************************************************* + * @brief getDisinfectionDate + * The getDisinfectionDate populates the provided buffer with the last + * disinfection date + * @details + * Inputs : DISINFECTION_DATE_T* (buffer) + * Outputs : BOOL (status) + * @param none + * @return BOOL (status) + *************************************************************************/ +BOOL getDisinfectionDate ( DISINFECTION_DATE_T* buffer ) +{ + BOOL status = FALSE; + + if ( buffer != NULL ) + { + memcpy ( buffer, lastDisinfectionRecord.date.disinfectionDate, sizeof(DISINFECTION_DATE_T) ); + status = TRUE; + } + + return status; +} + +/************************************************************************* * @brief execNVDataMgmtSelfTest * The execNVDataMgmtSelfTest runs the NVDataMgmt POST during the self test * @details @@ -414,6 +612,16 @@ NVDataMgmtSelfTestState = handleSelfTestStart(); break; + case NVDATAMGMT_SELF_TEST_STATE_ENABLE_EEPROM: + + NVDataMgmtSelfTestState = handleSelfTestEnableEEPROM(); + break; + + case NVDATAMGMT_SELF_TEST_STATE_READ_BOOTLOADER_FLAG: + + NVDataMgmtSelfTestState = handleSelfTestReadBootloaderFlag(); + break; + case NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD: NVDataMgmtSelfTestState = handleSelfTestReadLogRecord(); @@ -439,19 +647,31 @@ NVDataMgmtSelfTestState = handleSelfTestReadCalibrationRecord(); break; + case NVDATAMGMT_SELF_TEST_STATE_READ_SERVICE_RECORD: + + NVDataMgmtSelfTestState = handleSelfTestReadServiceRecord(); + break; + + case NVDATAMGMT_SELF_TEST_STATE_READ_LAST_DISINFECTION_DATE: + + NVDataMgmtSelfTestState = handleSelfTestReadLastDisinfectionDate(); + break; + case NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC: NVDataMgmtSelfTestState = handleSelfTestCheckCRC(); break; case NVDATAMGMT_SELF_TEST_STATE_COMPLETE: - // Done with the state - // TODO: If POST failed, set the proper alarm + // Done with POST. Do nothing break; default: - //TODO: Alarm + + SET_ALARM_WITH_2_U32_DATA ( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_NVDATAMGMT_INVALID_SELF_TEST_STATE, + NVDataMgmtSelfTestState ); + NVDataMgmtSelfTestState = NVDATAMGMT_SELF_TEST_STATE_COMPLETE; NVDataMgmtSelfTestResult = SELF_TEST_STATUS_FAILED; break; } @@ -460,6 +680,43 @@ } /************************************************************************* + * @brief setBootloaderFlag + * The setBootloaderFlag sets the bootloader flag to RTC RAM + * @details + * Inputs : U32 (flag) + * Outputs : BOOL + * @param none + * @return BOOL + *************************************************************************/ +BOOL setBootloaderFlag ( U32 flag ) +{ + BOOL status = FALSE; + + if ( !isQueueFull() ) + { + enqueue ( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, BOOTLOADER_FLAG_ADDRESS, + (U08*)&flag, 0, BOOTLOADER_FLAG_LENGTH_BYTES ); + status = TRUE; + } + + return status; +} + +/************************************************************************* + * @brief getBootloaderFlag + * The getBootloaderFlag gets the bootloader flag from RTC RAM + * @details + * Inputs : none + * Outputs : U32 (flag value) + * @param none + * @return U32 (flag value) + *************************************************************************/ +U32 getBootloaderFlag( void ) +{ + return bootloaderFlag; +} + +/************************************************************************* * @brief execNVDataMgmt * The execNVDataMgmt runs the NVDataMgmt main tasks * @details @@ -507,19 +764,17 @@ NVDataMgmtExecState = handleExecReadFromRAMState(); break; - case NVDATAMGMT_EXEC_STATE_FAULT: - - // Something failed set the alarms - // TODO: set the alarms and stuff - break; - default: - NVDataMgmtExecState = NVDATAMGMT_EXEC_STATE_FAULT; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_NVDATAMGMT_EXEC_INVALID_STATE, + NVDataMgmtExecState ); + NVDataMgmtExecState = NVDATAMGMT_EXEC_STATE_IDLE; break; } } +// Private functions + /************************************************************************* * @brief handleSelfTestStart * The handleSelfTestStart enables the EEPROM bank sectors @@ -531,115 +786,173 @@ *************************************************************************/ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestStart ( void ) { - NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_START; - if ( isServiceOnEntry ) + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_ENABLE_EEPROM; + + Fapi_enableEepromBankSectors( BANK7_SECTOR_0_31_ENABLE_BIT_MASK, + BANK7_SECTOR_32_63_ENABLE_BIT_MASK ); + // Get the time to check for timeout + currentTime = getMSTimerCount(); + + return state; +} + +/************************************************************************* + * @brief handleSelfTestEnableEEPROM + * The handleSelfTestEnableEEPROM waits for EEPROM to return with ready from + * enabling the EEPROM command + * @details + * Inputs : none + * Outputs : NVDATAMGMT_SELF_TEST_STATE_T + * @param none + * @return NVDATAMGMT_SELF_TEST_STATE_T + *************************************************************************/ +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestEnableEEPROM ( void ) +{ + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_ENABLE_EEPROM; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_NVDATA_EEPROM_OPS_FAILURE, (U08*)&state ); + + if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) { - EEPROMStatus = Fapi_enableEepromBankSectors( BANK7_SECTOR_0_31_ENABLE_BIT_MASK, - BANK7_SECTOR_32_63_ENABLE_BIT_MASK ); - isServiceOnEntry = FALSE; + // Enable was successful, Request a read for bootloader + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + { + readFromRAM( BOOTLOADER_FLAG_ADDRESS, BOOTLOADER_FLAG_LENGTH_BYTES ); + // Get the time to check for timeout + currentTime = getMSTimerCount(); + state = NVDATAMGMT_SELF_TEST_STATE_READ_BOOTLOADER_FLAG; + } } - else if ( EEPROMStatus == Fapi_Status_Success ) - { -/*#ifdef _HD_ - state = NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME; -#else - state = NVDATAMGMT_SELF_TEST_STATE_READ_WATER_CONSUMPTION; -#endif*/ - state = NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD; - isServiceOnEntry = TRUE; - } return state; } /************************************************************************* - * @brief handleSelfTestReadLogRecord - * The handleSelfTestReadLogRecord reads the log record from RTC RAM + * @brief handleSelfTestReadBootloaderFlag + * The handleSelfTestReadBootloaderFlag reads the bootloader flag + * from RTC RAM * @details * Inputs : none * Outputs : NVDATAMGMT_SELF_TEST_STATE_T * @param none * @return NVDATAMGMT_SELF_TEST_STATE_T *************************************************************************/ -static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadLogRecord ( void ) +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadBootloaderFlag ( void ) { - NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD; - if ( isServiceOnEntry && getRTCRAMState() == RTC_RAM_STATE_READY ) + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_BOOTLOADER_FLAG; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); + + // If the read for bootloader is done, read it + if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) { - readFromRAM ( LOG_RECORD_START_ADDRESS, sizeof(LOG_HEADER_T) ); - isServiceOnEntry= FALSE; - } - if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE ) - { - getDataFromRAM ( (U08*)&logHeader, sizeof(LOG_HEADER_T) ); - /*U08 i; - U08* logPtr = (U08*)&logRecord; - getDataFromRAM ( readBuffer, sizeof(LOG_HEADER_T) ); - for ( i = 0; i < sizeof(LOG_HEADER_T); i++ ) + getDataFromRAM( (U08*)&bootloaderFlag, BOOTLOADER_FLAG_LENGTH_BYTES ); +// If the device is HD, read treatment time, +// If the device is DG, read water consumption +#ifdef _HD_ + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) { - *logPtr = ( readBuffer[ i ] & MASK_OFF_MSB ); - logPtr++; - }*/ - state = NVDATAMGMT_SELF_TEST_STATE_READ_MFG_RECORD; - isServiceOnEntry = TRUE; + readFromRAM ( HD_TREATMENT_TIME_ADDRESS, sizeof(TREATMENT_TIME_RECORD_T) ); + currentTime = getMSTimerCount(); + state = NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME; + } +#else + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + { + readFromRAM ( DG_CONSUMED_WATER_ADDRESS, sizeof(WATER_CONSUMPTION_RECORD_T) ); + currentTime = getMSTimerCount(); + state = NVDATAMGMT_SELF_TEST_STATE_READ_WATER_CONSUMPTION; + } +#endif } + return state; } +/************************************************************************* + * @brief handleSelfTestReadHDTreatmentTime + * The handleSelfTestReadHDTreatmentTime reads the HD treatment time + * from RTC RAM + * @details + * Inputs : none + * Outputs : NVDATAMGMT_SELF_TEST_STATE_T + * @param none + * @return NVDATAMGMT_SELF_TEST_STATE_T + *************************************************************************/ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadHDTreatmentTime ( void ) { NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); - if ( isServiceOnEntry && getRTCRAMState() == RTC_RAM_STATE_READY ) + // If the RTC RAM is ready, read the results + if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) { - readFromRAM ( LOG_RECORD_START_ADDRESS, sizeof(TREATMENT_TIME_RECORD_T) ); - isServiceOnEntry= FALSE; + getDataFromRAM ( (U08*)&treatmentTimeRecord, sizeof(TREATMENT_TIME_RECORD_T) ); + // If the RAM is ready, request a read for the log records (RAM) + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + { + readFromRAM ( LOG_RECORD_START_ADDRESS, sizeof(LOG_RECORD_T) ); + currentTime = getMSTimerCount(); + state = NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD; + } } - if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE ) - { - getDataFromRAM ( (U08*)&logHeader, sizeof(TREATMENT_TIME_RECORD_T) ); - state = NVDATAMGMT_SELF_TEST_STATE_READ_MFG_RECORD; - isServiceOnEntry = TRUE; - } return state; - } + +/************************************************************************* + * @brief handleSelfTestReadDGWaterConsumption + * The handleSelfTestReadDGWaterConsumption reads the DG water consumption + * from RTC RAM + * @details + * Inputs : none + * Outputs : NVDATAMGMT_SELF_TEST_STATE_T + * @param none + * @return NVDATAMGMT_SELF_TEST_STATE_T + *************************************************************************/ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadDGWaterConsumption ( void ) { NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_WATER_CONSUMPTION; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); + // If the RAM is ready, request a read for water consumption + if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) + { + getDataFromRAM ( (U08*)&waterConsumptionRecord, sizeof(WATER_CONSUMPTION_RECORD_T) ); + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + { + readFromRAM ( LOG_RECORD_START_ADDRESS, sizeof(LOG_RECORD_T) ); + currentTime = getMSTimerCount(); + state = NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD; + } + } return state; - } /************************************************************************* - * @brief handleSelfTestReadCalibrationRecord - * The handleSelfTestReadCalibrationRecord reads the calibration record - * from EEPROM + * @brief handleSelfTestReadLogRecord + * The handleSelfTestReadLogRecord reads the log record from RTC RAM * @details * Inputs : none * Outputs : NVDATAMGMT_SELF_TEST_STATE_T * @param none * @return NVDATAMGMT_SELF_TEST_STATE_T *************************************************************************/ -static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadMfgRecord ( void ) +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadLogRecord ( void ) { - NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_MFG_RECORD; + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); - if ( isServiceOnEntry ) + // If the RAM is in Idle, read the log records + if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) { - EEPROMStatus = Fapi_doMarginRead ( (U32*)BANK7_SECTOR0_START_ADDRESS, (U32*)&mfgRecord, - sizeof(MFG_DATA_T), Fapi_NormalRead ); - isServiceOnEntry = FALSE; + getDataFromRAM ( (U08*)&logRecord, sizeof(LOG_RECORD_T) ); + + currentTime = getMSTimerCount(); + // Get ready for reading the manufacturing record + Fapi_doMarginRead ( (U32*)BANK7_SECTOR0_START_ADDRESS, (U32*)&mfgRecord, + sizeof(MFG_RECORD_T), Fapi_NormalRead ); + state = NVDATAMGMT_SELF_TEST_STATE_READ_MFG_RECORD; } - else if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady ) - { - // TODO: Change this to the next state to read - state = NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC; - isServiceOnEntry = TRUE; - } return state; } @@ -654,26 +967,109 @@ * @param none * @return NVDATAMGMT_SELF_TEST_STATE_T *************************************************************************/ +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadMfgRecord ( void ) +{ + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_MFG_RECORD; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_NVDATA_EEPROM_OPS_FAILURE, (U08*)&state ); + + // Wait for the read from EEPROM to be successful + if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) + { + currentTime = getMSTimerCount(); + // Send the read command for calibration record + Fapi_doMarginRead ( (U32*)CALIBRATION_RECORD_START_ADDRESS, (U32*)&calibrationRecord, + sizeof(CALIBRATION_RECORD_T), Fapi_NormalRead ); + state = NVDATAMGMT_SELF_TEST_STATE_READ_CAL_RECORD; + } + + return state; +} + +/************************************************************************* + * @brief handleSelfTestReadCalibrationRecord + * The handleSelfTestReadCalibrationRecord reads the calibration record + * from EEPROM + * @details + * Inputs : none + * Outputs : NVDATAMGMT_SELF_TEST_STATE_T + * @param none + * @return NVDATAMGMT_SELF_TEST_STATE_T + *************************************************************************/ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadCalibrationRecord ( void ) { NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_CAL_RECORD; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_NVDATA_EEPROM_OPS_FAILURE, (U08*)&state ); - if ( isServiceOnEntry ) + // If the EEPROM read was successful, request a read from RAM to + // read the service record + if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) { - EEPROMStatus = Fapi_doMarginRead ( (U32*)(CAL_RECORD_START_ADDRESS ), (U32*)&calibrationRecord, - sizeof(CALIBRATION_DATA_T), Fapi_NormalRead ); - isServiceOnEntry = FALSE; + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + { + currentTime = getMSTimerCount(); + readFromRAM( SERVICE_DATE_START_ADDRESS, sizeof(SERVICE_RECORD_T) ); + state = NVDATAMGMT_SELF_TEST_STATE_READ_SERVICE_RECORD; + } } - else if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady ) + + return state; +} + +/************************************************************************* + * @brief handleSelfTestReadServiceRecord + * The handleSelfTestReadServiceRecord reads the service dates from RTC + * RAM + * @details + * Inputs : none + * Outputs : NVDATAMGMT_SELF_TEST_STATE_T + * @param none + * @return NVDATAMGMT_SELF_TEST_STATE_T + *************************************************************************/ +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadServiceRecord ( void ) +{ + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_SERVICE_RECORD; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); + + if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) { - state = NVDATAMGMT_SELF_TEST_STATE_COMPLETE; - isServiceOnEntry = TRUE; + getDataFromRAM ( (U08*)&serviceRecord, sizeof(SERVICE_RECORD_T) ); + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + { + currentTime = getMSTimerCount(); + readFromRAM( LAST_DISINFECTION_DATE_ADDRESS, sizeof(LAST_DISINFECTION_RECORD_T) ); + state = NVDATAMGMT_SELF_TEST_STATE_READ_LAST_DISINFECTION_DATE; + } } return state; } /************************************************************************* + * @brief handleSelfTestReadLastDisinfectionDate + * The handleSelfTestReadLastDisinfectionDate reads the last disinfection date + * from RTC RAM + * @details + * Inputs : none + * Outputs : NVDATAMGMT_SELF_TEST_STATE_T + * @param none + * @return NVDATAMGMT_SELF_TEST_STATE_T + *************************************************************************/ +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadLastDisinfectionDate ( void ) +{ + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_LAST_DISINFECTION_DATE; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); + + if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) + { + getDataFromRAM ( (U08*)&lastDisinfectionRecord, sizeof(LAST_DISINFECTION_RECORD_T) ); + state = NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC; + } + + return state; + +} + +/************************************************************************* * @brief handleSelfTestCheckCRC * The handleSelfTestCheckCRC calculates the CRC of the records and compares * them to the CRC that was read. If they don't match, it will fail POST @@ -688,27 +1084,75 @@ NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_COMPLETE; BOOL hasCRCPassed = TRUE; U16 calcCRC; - U16 CRC; - - calcCRC = crc16 ( (U08*)&mfgRecord.mfgData, sizeof(MFG_DATA_T) ); - CRC = mfgRecord.crc; - //hasCRCPassed = (calcCRC==CRC ? TRUE : FALSE); - //if ( calcCRC != CRC ) - // { - // hasCRCPassed = FALSE; - //} - - // Disabled since there is no data - // TODO: enable this code - /*calcCRC = crc16 ( (U08*)&calibrationRecord.calData, sizeof(CALIBRATION_RECORD_T) ); - CRC = calibrationRecord.crc; - if ( calcCRC != CRC ) + U16 recordCRC; +#ifdef _HD_ + calcCRC = crc16 ( (U08*)&treatmentTimeRecord.treatmentTime, sizeof(U32) ); + recordCRC = treatmentTimeRecord.crc; + if ( calcCRC != recordCRC ) { hasCRCPassed = FALSE; - }*/ - - if ( hasCRCPassed ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_NVDATA_HW_USAGE_DATA_CRC_ERROR, recordCRC, calcCRC ); + } +#else + calcCRC = crc16 ( (U08*)&waterConsumptionRecord.waterConsumption, sizeof(U32) ); + recordCRC = waterConsumptionRecord.crc; + if ( calcCRC != recordCRC ) { + hasCRCPassed = FALSE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_NVDATA_HW_USAGE_DATA_CRC_ERROR, recordCRC, calcCRC ); + } + // Check the CRC for last disinfection date + calcCRC = crc16 ( (U08*)&lastDisinfectionRecord.date.disinfectionDate, sizeof(DISINFECTION_DATE_T) ); + recordCRC = lastDisinfectionRecord.crc; + if ( calcCRC != recordCRC ) + { + hasCRCPassed = FALSE; + SET_ALARM_WITH_2_U32_DATA( AlARM_ID_NVDATA_DISINFECTION_DATE_CRC_ERROR, recordCRC, calcCRC ); + } +#endif + // Check log header record + calcCRC = crc16 ( (U08*)&logRecord.logHeader, sizeof(LOG_HEADER_T) ); + recordCRC = logRecord.crc; + if ( calcCRC != recordCRC ) + { + hasCRCPassed = FALSE; + // CRC for the log record has failed. The flag will be set to true + // The log header will be set to full by having the record count be at + // maximum number of counts (1536 in this case) and the read index be a 0 + // of the beginning of the log sectors + logRecord.logHeader.recordCount = MAX_NUM_OF_EVENTS_IN_SECTOR3; + logRecord.logHeader.nextReadIndex = 0; + logRecord.logHeader.nextReadIndex = 0; + logRecord.logHeader.isHdrCorrupted = TRUE; + } + // Check CRC for manufacturing record + calcCRC = crc16 ( (U08*)&mfgRecord.mfgData, sizeof(MFG_DATA_T) ); + recordCRC = mfgRecord.crc; + if ( calcCRC != recordCRC ) + { + hasCRCPassed = FALSE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_NVDATA_MFG_RECORD_CRC_ERROR, recordCRC, calcCRC ); + } + // Check CRC for calibration record + calcCRC = crc16 ( (U08*)&calibrationRecord.calData, sizeof(CALIBRATION_DATA_T) ); + recordCRC = calibrationRecord.crc; + if ( calcCRC != recordCRC ) + { + hasCRCPassed = FALSE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_NVDATA_CAL_RECORD_CRC_ERROR, recordCRC, calcCRC ); + } + // Check CRC for service record + calcCRC = crc16 ( (U08*)&serviceRecord.serviceData, sizeof(SERVICE_DATA_T) ); + recordCRC = serviceRecord.crc; + if ( calcCRC != recordCRC ) + { + hasCRCPassed = FALSE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_NVDATA_SRVC_RECORD_CRC_ERROR, recordCRC, calcCRC ); + } + // There should be no failed CRCs or no command should + // timeout for the self test to pass + if ( hasCRCPassed && !hasCommandTimedout ) + { NVDataMgmtSelfTestResult = SELF_TEST_STATUS_PASSED; } else @@ -731,41 +1175,12 @@ static NVDATAMGMT_EXEC_STATE_T handleExecWaitForPostState ( void ) { NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_WAIT_FOR_POST; - if ( NVDataMgmtSelfTestState == NVDATAMGMT_SELF_TEST_STATE_COMPLETE && - NVDataMgmtSelfTestResult == SELF_TEST_STATUS_PASSED ) - { - // TODO: REMOVE THIS CODE - logData.epochTime = 1582583436; - logData.eventCode = NVDATAMGMT_DEVICE_TURNED_ON; - logData.subCode = 14587; - logData.data1 = 2.4; - logData.data2 = 13; - logData.data3 = 223.58; - logData.data4 = 80.125; - logData.data5 = 68; - mytest.status = NVDATAMGMT_READ_IDLE; - mytest.externalBuffer = readBufferForTest; - - //writeLogData ( (U08*)&logData ); - readLogData ( &mytest, 5 ); - - /*MFG_DATA_T test; - char sys[7] = {'A', 'B', 'C', 'D', '3', '6', '7'}; - char hw[5] = {'3', '4', '5', '6', '7'}; - char date[10]={'2', '0', '2', '0','-', '0', '3','-', '0', '5'}; - memcpy ( test.SYSSerialNumber, sys, 7 ); - memcpy ( test.HWSerialNumber, hw, 5 ); - memcpy ( test.mfgDate, date, 10 ); - setMfgData(test);*/ - - // TODO: REMOVE THIS CODE - state = NVDATAMGMT_EXEC_STATE_IDLE; - } - else if ( NVDataMgmtSelfTestState == NVDATAMGMT_SELF_TEST_STATE_COMPLETE ) + if ( NVDataMgmtSelfTestState == NVDATAMGMT_SELF_TEST_STATE_COMPLETE ) { state = NVDATAMGMT_EXEC_STATE_IDLE; } + return state; } @@ -788,26 +1203,50 @@ dequeue(); NVDATAMGMT_OPERATION_STATE_T ops = currentJob.memoryOperation; NVDATAMGMT_LOCATION_STATE_T location = currentJob.memoryLocation; + U32* startAddress = currentJob.startAddress; + U32 length = currentJob.length; if ( ops == NVDATAMGMT_WRITE && location == NVDATAMGMT_EEPROM ) { + currentTime = getMSTimerCount(); + Fapi_issueProgrammingCommand ( startAddress, currentJob.buffer, length, + 0x00, 0, Fapi_DataOnly ); state = NVDATAMGMT_EXEC_STATE_WRITE_TO_EEPROM; } else if ( ops == NVDATAMGMT_READ && location == NVDATAMGMT_EEPROM ) { + currentTime = getMSTimerCount(); + Fapi_doMarginRead ( startAddress, (U32*)( currentJob.externalAddress->externalBuffer ), + length, Fapi_NormalRead ); + // Change the status to in progress until the read operation is done + currentJob.externalAddress->status = NVDATAMGMT_READ_IN_PROGRESS; state = NVDATAMGMT_EXEC_STATE_READ_FROM_EEPROM; } else if ( ops == NVDATAMGMT_ERASE_SECTOR ) { + currentTime = getMSTimerCount(); + Fapi_issueAsyncCommandWithAddress ( Fapi_EraseSector, startAddress ); state = NVDATAMGMT_EXEC_STATE_ERASE_EEPROM; } else if ( ops == NVDATAMGMT_WRITE && location == NVDATAMGMT_RTC ) { - state = NVDATAMGMT_EXEC_STATE_WRITE_TO_RTC; + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + { + currentTime = getMSTimerCount(); + writeToRAM ( (U32)startAddress, currentJob.buffer, length ); + state = NVDATAMGMT_EXEC_STATE_WRITE_TO_RTC; + } + } else if ( ops == NVDATAMGMT_READ && location == NVDATAMGMT_RTC ) { - state = NVDATAMGMT_EXEC_STATE_READ_FROM_RTC; + if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + { + currentTime = getMSTimerCount(); + readFromRAM( (U32)startAddress, length ); + currentJob.externalAddress->status = NVDATAMGMT_READ_IN_PROGRESS; + state = NVDATAMGMT_EXEC_STATE_READ_FROM_RTC; + } } } @@ -827,19 +1266,13 @@ static NVDATAMGMT_EXEC_STATE_T handleExecWriteToEEPROMState ( void ) { NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_WRITE_TO_EEPROM; - if ( isServiceOnEntry ) + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_NVDATA_EEPROM_OPS_FAILURE, (U08*)&state ); + + if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) { - EEPROMStatus = Fapi_issueProgrammingCommand ( currentJob.startAddress, - currentJob.buffer, - currentJob.length, - 0x00, 0, Fapi_DataOnly ); - isServiceOnEntry = FALSE; - } - else if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady ) - { state = NVDATAMGMT_EXEC_STATE_IDLE; - isServiceOnEntry = TRUE; } + return state; } @@ -856,21 +1289,12 @@ static NVDATAMGMT_EXEC_STATE_T handleExecReadFromEEPROMState ( void ) { NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_READ_FROM_EEPROM; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_NVDATA_EEPROM_OPS_FAILURE, (U08*)&state ); - if ( isServiceOnEntry ) + if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) { - EEPROMStatus = Fapi_doMarginRead ( currentJob.startAddress, - (U32*)currentJob.externalAddress->externalBuffer, - currentJob.length, Fapi_NormalRead ); - // Change the status to in progress until the read operation is done - currentJob.externalAddress->status = NVDATAMGMT_READ_IN_PROGRESS; - isServiceOnEntry = FALSE; - } - else if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady ) - { currentJob.externalAddress->status = NVDATAMGMT_READ_COMPLETE; state = NVDATAMGMT_EXEC_STATE_IDLE; - isServiceOnEntry = TRUE; } return state; @@ -889,17 +1313,11 @@ static NVDATAMGMT_EXEC_STATE_T handleExecEraseState ( void ) { NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_ERASE_EEPROM; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_NVDATA_EEPROM_OPS_FAILURE, (U08*)&state ); - if ( isServiceOnEntry ) + if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) { - EEPROMStatus = Fapi_issueAsyncCommandWithAddress ( Fapi_EraseSector, - currentJob.startAddress ); - isServiceOnEntry = FALSE; - } - else if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady ) - { state = NVDATAMGMT_EXEC_STATE_IDLE; - isServiceOnEntry = TRUE; } return state; @@ -919,18 +1337,11 @@ static NVDATAMGMT_EXEC_STATE_T handleExecWriteToRAMState ( void ) { NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_WRITE_TO_RTC; + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); - if ( isServiceOnEntry && getRTCRAMState() == RTC_RAM_STATE_READY ) + if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) { - writeToRAM ( (U32)( currentJob.startAddress ), - currentJob.buffer, - currentJob.length ); - isServiceOnEntry= FALSE; - } - if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE ) - { state = NVDATAMGMT_EXEC_STATE_IDLE; - isServiceOnEntry = TRUE; } return state; @@ -951,27 +1362,25 @@ static NVDATAMGMT_EXEC_STATE_T handleExecReadFromRAMState ( void ) { NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_READ_FROM_RTC; - if ( isServiceOnEntry && getRTCRAMState() == RTC_RAM_STATE_READY ) + BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); + + if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) { - readFromRAM( (U32)( currentJob.startAddress ), - currentJob.length ); - isServiceOnEntry= FALSE; - } - if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE ) - { - getDataFromRAM( currentJob.buffer, - currentJob.length ); + getDataFromRAM( currentJob.externalAddress->externalBuffer, currentJob.length ); + currentJob.externalAddress->status = NVDATAMGMT_READ_COMPLETE; state = NVDATAMGMT_EXEC_STATE_IDLE; - isServiceOnEntry = TRUE; } + return state; } /************************************************************************* * @brief setMemoryOpsStruct * The setMemoryOpsStruct fills up the job struct * @details - * Inputs : none + * Inputs : NVDATAMGMT_OPERATION_STATE_T (ops), NVDATAMGMT_LOCATION_STATE_T + * (location), U32 (startAddress), U08* (data), READ_DATA_T* (extAddress) + * U32 (length) * Outputs : none * @param none * @return none @@ -987,15 +1396,19 @@ { queueCount++; queueRearIndex = INC_WRAP( queueRearIndex, 0, QUEUE_MAX_SIZE - 1 ); + + jobQueue [ myAddIndex ].memoryOperation = ops; + jobQueue [ myAddIndex ].memoryLocation = location; + jobQueue [ myAddIndex ].startAddress = (U32*)startAddress; + jobQueue [ myAddIndex ].length = length; + jobQueue [ myAddIndex ].externalAddress = extAddress; + + if ( extAddress == 0 ) + { + memcpy ( jobQueue [ myAddIndex ].buffer, data, length ); + } } _enable_IRQ(); - - jobQueue [ myAddIndex ].memoryOperation = ops; - jobQueue [ myAddIndex ].memoryLocation = location; - jobQueue [ myAddIndex ].startAddress = (U32*)startAddress; - jobQueue [ myAddIndex ].length = length; - jobQueue [ myAddIndex ].externalAddress = extAddress; - memcpy ( jobQueue [ myAddIndex ].buffer, data, length ); } /************************************************************************* @@ -1005,10 +1418,10 @@ * header accordingly. If the write is not at the edge, it will prepare a * normal write to EEPROM job. * @details - * Inputs : data - * Outputs : opsStartAddress + * Inputs : U08* (data) + * Outputs : U32 (opsStartAddress) * @param none - * @return opsStartAddress + * @return U32 (opsStartAddress) *************************************************************************/ static U32 prepareWriteLogJobAndGetStartAddress ( U08* data ) { @@ -1020,30 +1433,35 @@ // The write address is calculated using the next write index and is and offset from // the start of sector 1. Sectors 1,2, and 3 have been allocated for logging data - opsStartAddress = ( logHeader.nextWriteIndex * MAX_JOB_DATA_SIZE_BYTES ) + BANK7_SECTOR1_START_ADDRESS; - modulus = logHeader.nextWriteIndex % MAX_LOG_DATA_PER_SECTOR; + opsStartAddress = ( logRecord.logHeader.nextWriteIndex * MAX_JOB_DATA_SIZE_BYTES ) + BANK7_SECTOR1_START_ADDRESS; + modulus = logRecord.logHeader.nextWriteIndex % MAX_LOG_DATA_PER_SECTOR; // Modulus is 0 so it is at any of the edges if ( modulus == 0 ) { - // If full + // If full (1536) // 1. set readIndexChange = +512 // 2. set recordCountchange = -512 - readIndexChange = MAX_LOG_DATA_PER_SECTOR; - logHeader.recordCount = logHeader.recordCount - MAX_LOG_DATA_PER_SECTOR; - + if ( logRecord.logHeader.recordCount >= MAX_NUM_OF_EVENTS_IN_SECTOR3 - 1 ) + { + logRecord.logHeader.recordCount = logRecord.logHeader.recordCount - MAX_LOG_DATA_PER_SECTOR; + readIndexChange = MAX_LOG_DATA_PER_SECTOR; + } setMemoryOpsStruct ( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, opsStartAddress, 0, 0, 0 ); } // Check for wrap in 1536 which is at the end of sector 3 - writeIndexChange = INC_WRAP( logHeader.nextWriteIndex, LOG_DATA_START_INDEX, MAX_NUM_OF_DATA_LOGS_IN_SECTOR3 - 1 ); - logHeader.nextWriteIndex = writeIndexChange; - logHeader.recordCount = logHeader.recordCount + recordCountChange; - logHeader.nextReadIndex = logHeader.nextReadIndex + readIndexChange; + writeIndexChange = INC_WRAP( logRecord.logHeader.nextWriteIndex, LOG_DATA_START_INDEX, MAX_NUM_OF_EVENTS_IN_SECTOR3 - 1 ); + logRecord.logHeader.nextWriteIndex = writeIndexChange; + logRecord.logHeader.recordCount = logRecord.logHeader.recordCount + recordCountChange; + logRecord.logHeader.nextReadIndex = logRecord.logHeader.nextReadIndex + readIndexChange; + logRecord.logHeader.isHdrCorrupted = FALSE; + // Calculate the CRC for the new record + logRecord.crc = crc16 ( (U08*)&logRecord.logHeader, sizeof(LOG_HEADER_T) ); // Update the log record setMemoryOpsStruct ( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, LOG_RECORD_START_ADDRESS, - (U08*)&logHeader, 0, sizeof( LOG_HEADER_T ) ); + (U08*)&logRecord, 0, sizeof(LOG_RECORD_T) ); return opsStartAddress; } @@ -1054,22 +1472,37 @@ * address of the EEPROM. * @details * Inputs : none - * Outputs : opsStartAddress + * Outputs : U32 (opsStartAddress) * @param none - * @return opsStartAddress + * @return U32 (opsStartAddress) *************************************************************************/ -static U32 prepareReadLogJobAndGetStartAddress( void ) +static U32 prepareReadLogJobAndGetStartAddress ( void ) { - // The write address is calculated using the next write index and is and offset from + // The read address is calculated using the next read index and is an offset from // the start of sector 1. Sectors 1,2, and 3 have been allocated for logging data - U32 opsStartAddress = ( logHeader.nextReadIndex * MAX_JOB_DATA_SIZE_BYTES ) + BANK7_SECTOR1_START_ADDRESS; + U32 opsStartAddress = ( logRecord.logHeader.nextReadIndex * MAX_JOB_DATA_SIZE_BYTES ) + BANK7_SECTOR1_START_ADDRESS; - U16 readIndexChange = INC_WRAP( logHeader.nextReadIndex, LOG_DATA_START_INDEX, MAX_NUM_OF_DATA_LOGS_IN_SECTOR3 - 1 ); - logHeader.nextReadIndex = readIndexChange; + U16 readIndexChange = INC_WRAP( logRecord.logHeader.nextReadIndex, LOG_DATA_START_INDEX, MAX_NUM_OF_EVENTS_IN_SECTOR3 - 1 ); + logRecord.logHeader.nextReadIndex = readIndexChange; + // Check if the read index has been wrapped to 0 and the flag is for data corruption + // is true, the record count will be 0 and the data corruption flag will be false for + // normal operations + if ( logRecord.logHeader.nextReadIndex == 0 && logRecord.logHeader.isHdrCorrupted == TRUE ) + { + logRecord.logHeader.recordCount = 0; + // If there are enough queues to schedule 3 erases + // the flag will be turned off + if ( eraseDataLogSectors () ) + { + logRecord.logHeader.isHdrCorrupted = FALSE; + } + } + logRecord.crc = crc16 ( (U08*)&logRecord.logHeader, sizeof(LOG_HEADER_T) ); + // Update the log record setMemoryOpsStruct ( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, LOG_RECORD_START_ADDRESS, - (U08*)&logHeader, 0, sizeof( LOG_HEADER_T ) ); + (U08*)&logRecord, 0, sizeof(LOG_RECORD_T) ); return opsStartAddress; } @@ -1083,7 +1516,9 @@ * it schedules the write jobs. The function breaks the write to EEPROM jobs to * 16 bytes at the time * @details - * Inputs : ops, location, startAddress, data, length + * Inputs : NVDATAMGMT_OPERATION_STATE_T (ops), NVDATAMGMT_LOCATION_STATE_T + * (location), U32 (startAddress), U08* (data), READ_DATA_T* (extAddress) + * U32 (length) * Outputs : none * @param none * @return none @@ -1109,7 +1544,6 @@ // Setup EEPROM read log event else if ( ops == NVDATAMGMT_READ && location == NVDATAMGMT_EEPROM ) { - //maxBufferLength = MAX_JOB_DATA_SIZE_BYTES; if ( startAddress == 0 ) { opsStartAddress = prepareReadLogJobAndGetStartAddress(); @@ -1157,18 +1591,16 @@ _disable_IRQ(); tempIndex = queueFrontIndex; - if ( FALSE == isQueueFull() ) + if ( !isQueueEmpty() ) { queueFrontIndex = INC_WRAP( queueFrontIndex, 0, QUEUE_MAX_SIZE - 1 ); + currentJob = jobQueue [ tempIndex ]; } - _enable_IRQ(); - - currentJob = jobQueue [ tempIndex ]; - if ( queueCount > 0 ) { queueCount--; } + _enable_IRQ(); } /************************************************************************* @@ -1222,10 +1654,95 @@ * Inputs : none * Outputs : U32 * @param none - * @return BOOL + * @return U32 *************************************************************************/ static U32 getAvailableQueueCount ( void ) { - return QUEUE_MAX_SIZE - queueCount - 1; + return QUEUE_MAX_SIZE - queueCount; } +/************************************************************************* + * @brief enqueueBank7Sector0Records + * The enqueueBank7Sector0Records checks whether there are enough number of + * queues for erasing and setting the records. If there are enough queues, + * it schedules an erase job and then schdules jobs to write all the records + * back to Bank 7 Sector 0 + * @details + * Inputs : none + * Outputs : BOOL + * @param none + * @return BOOL + *************************************************************************/ +static BOOL enqueueBank7Sector0Records( void ) +{ + BOOL status = FALSE; + U32 currentQueueCount = getAvailableQueueCount(); + + if ( currentQueueCount >= MIN_JOBS_NEEDED_FOR_SECTOR_0 ) + { + // Sector 0 must be erased first + enqueue ( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, BANK7_SECTOR0_START_ADDRESS, 0, 0, 0 ); + enqueue ( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, BANK7_SECTOR0_START_ADDRESS, + (U08*)&mfgRecord, 0, sizeof(MFG_RECORD_T) ); + enqueue ( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, CALIBRATION_RECORD_START_ADDRESS, + (U08*)&calibrationRecord, 0, sizeof(CALIBRATION_RECORD_T) ); + status = TRUE; + } + + return status; +} + +/************************************************************************* + * @brief didCommandTimedout + * The didCommandTimedout checks whether the a command whether RTC RAM or + * EEPROM has timedout. If it has timedout, it sets the alarm and turns + * flag to TRUE + * @details + * Inputs : ALARM_ID_T (alarm), U08* state (pointer to the state) + * Outputs : BOOL + * @param none + * @return BOOL + *************************************************************************/ +static BOOL didCommandTimeout ( ALARM_ID_T alarm, U08* state ) +{ + /* + * NOTE: The state is a pointer so it can cover both the self test + * states and exec states + */ + BOOL status = FALSE; + + if ( didTimeout( currentTime, COMMAND_TIME_OUT ) ) + { + SET_ALARM_WITH_1_U32_DATA( alarm, *state ); + hasCommandTimedout = TRUE; + status = TRUE; + } + + return status; +} + +/************************************************************************* + * @brief eraseDataLogSectors + * The eraseDataLogSectors checks whether there are enough queues available + * and if there are, it schedules 3 erases to erase sectors 1,2, and 3 + * @details + * Inputs : none + * Outputs : BOOL + * @param none + * @return BOOL + *************************************************************************/ +static BOOL eraseDataLogSectors ( void ) +{ + BOOL status = FALSE; + U32 availableQueue = getAvailableQueueCount(); + + if ( availableQueue >= MIN_JOBS_NEEDED_FOR_DATA_LOG ) + { + enqueue( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, BANK7_SECTOR1_START_ADDRESS, 0, 0, 0 ); + enqueue( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, BANK7_SECTOR2_START_ADDRESS, 0, 0, 0 ); + enqueue( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, BANK7_SECTOR3_START_ADDRESS, 0, 0, 0 ); + status = TRUE; + } + + return status; +}