Index: NVDataMgmt.c =================================================================== diff -u -r89f99fccb9ae7dda71cfef84d4ea8cb59502fa9a -r0ee608e8de70aef91f5bdf7ebfa1f1cccf2e43dd --- NVDataMgmt.c (.../NVDataMgmt.c) (revision 89f99fccb9ae7dda71cfef84d4ea8cb59502fa9a) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision 0ee608e8de70aef91f5bdf7ebfa1f1cccf2e43dd) @@ -80,9 +80,9 @@ #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 LAST_SERVICE_RECORD_START_ADDRESS 0X00000050 // 80 ///< Last service date record start address in RTC RAM (HD/DG) (80). +#define SERVICE_RECORD_START_ADDRESS 0X00000050 // 80 ///< Last service date record start address in RTC RAM (HD/DG) (80). #define LAST_DISINFECTION_DATE_ADDRESS 0x00000060 // 96 //TODO remove ///< Last disinfection date start address in RTC RAM (96). -#define DG_SCHEDULER_RECORD_START_ADDRESS 0x00000070 // 112 ///< DG scheduler record start address in RTC RAM (112). +#define DG_SCHEDULED_RUNS_START_ADDRESS 0x00000070 // 112 ///< DG scheduler record start address in RTC RAM (112). // Data addresses in EEPROM #define CALIBRATION_RECORD_START_ADDRESS ( BANK7_SECTOR0_START_ADDRESS + sizeof(MFG_RECORD_T) ) ///< Calibration record start address in EEPROM. @@ -92,17 +92,17 @@ #define ERASE_CALIBRATION_KEY 0xD2C3B4A5 ///< 32-bit key required for clearing calibration data. // ********** Calibration data defines ********** -#define NUM_OF_BYTES_PER_CAL_PAYLOAD 150U ///< Number of bytes per calibration payload. -#define CAL_DATA_SEND_INTERVAL_COUNT ( MS_PER_SECOND / ( 5 * TASK_GENERAL_INTERVAL ) ) ///< Calibration data send time interval in counts. -#define CAL_DATA_RECEIVE_TIMEOUT_MS ( 4 * MS_PER_SECOND ) ///< Calibration data receive all the data packets timeout in ms. -#define CAL_DATA_MAX_MESSAGE_DFFIRENCE 1 ///< Calibration data receive message different from the previous message. -#define CAL_DATA_FIRST_RECEIVING_MSG_NUM 1 ///< Calibration data first receiving message number. -#define SYSTEM_DATA_NV_MEM_START_ADDRESS BANK7_SECTOR0_START_ADDRESS + 2048 ///< System record storage start address in NV memory. +#define NUM_OF_BYTES_PER_CAL_PAYLOAD 150U ///< Number of bytes per calibration payload. +#define CAL_DATA_SEND_INTERVAL_COUNT ( MS_PER_SECOND / ( 5 * TASK_GENERAL_INTERVAL ) ) ///< Calibration data send time interval in counts. +#define RECORD_DATA_RECEIVE_TIMEOUT_MS ( 4 * MS_PER_SECOND ) ///< Record data receive all the data packets timeout in ms. +#define RECORD_DATA_MAX_MESSAGE_DFFIRENCE 1 ///< Calibration data receive message different from the previous message. +#define RECORD_DATA_FIRST_RECEIVING_MSG_NUM 1 ///< Calibration data first receiving message number. +#define SYSTEM_DATA_NV_MEM_START_ADDRESS BANK7_SECTOR0_START_ADDRESS + 2048 ///< System record storage start address in NV memory. #define RECORD_BYTE_SIZE(r) ( sizeof(r) + sizeof(U16) ) ///< Record byte size macro. // Padding length calculation: (DG struct size % bytes to write(16) == 0 ? 0 : (DG struct size / bytes to write(16)) + 1) * bytes to write(16) /// DG padding length macro that is calculated with the size of the provided structure. -#define RECORD_PADDING_LENGTH(r, b) ( RECORD_BYTE_SIZE(r) % b == 0 ? 0 : ( (U32)(RECORD_BYTE_SIZE(r) / b) + 1 ) ) * b +#define RECORD_PADDING_LENGTH(rcrd, buf) ( RECORD_BYTE_SIZE(rcrd) % buf == 0 ? 0 : ( (U32)(RECORD_BYTE_SIZE(rcrd) / buf) + 1 ) ) * buf /// NVDataMgmt self-test states enumeration. typedef enum NVDataMgmt_Self_Test_States @@ -175,8 +175,8 @@ { NVDATAMGMT_CALIBRATION_RECORD = 0, ///< NVDataMgmt process write calibration record. NVDATAMGMT_SYSTEM_RECORD, ///< NVDataMgmt process write system record. - NVDATAMGMT_LAST_SERVICE_RECORD, ///< NVDATAMgmt process last service record. - NVDATAMGMT_SCHEDULER_RECORD, ///< NVDataMgmt process scheduler record. + NVDATAMGMT_SERVICE_RECORD, ///< NVDATAMgmt process service record. + NVDATAMGMT_SCHEDULED_RUNS_RECORD, ///< NVDataMgmt process scheduled runs record. NUM_OF_NVDATMGMT_RECORDS_JOBS ///< Number of NVDataMgmt records jobs. } RECORD_JOBS_STATE_T; @@ -189,6 +189,15 @@ NUM_OF_NVDATAMGMT_RECORD_VALIDITY_CHECK ///< Number of NVDataMgmt validity check states. } RECORD_VALIDITY_CHECK_T; +/// NVDataMgmt active queue +typedef enum NVDataMgmt_Active_Queue +{ + NVDATAMGMT_QUEUE_NONE = 0, ///< NVDataMgmt queue none. + NVDATAMGMT_PROCESS_RECORDS, ///< NVDataMgmt process records. + NVDATAMGMT_PROCESS_LOGS, ///< NVDataMgmt process logs. + NUM_OF_NVDATAMGMT_QUEUES ///< Number of NVDataMgmt queues. +} ACTIVE_QUEUE_T; + #pragma pack(push, 1) /// Process records specifications structure typedef struct @@ -324,17 +333,20 @@ /// DG service record structure typedef struct { - DG_LAST_SERVICE_RECORD_T dgLastServiceRecord; ///< DG last service record. - U08 padding[ RECORD_PADDING_LENGTH(DG_LAST_SERVICE_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) - - RECORD_BYTE_SIZE(DG_LAST_SERVICE_RECORD_T) ]; ///< DG last service group padding. - U16 crc; ///< CRC for the DG last service structure. -} DG_LAST_SERVICE_GROUP_T; + DG_SERVICE_RECORD_T dgServiceRecord; ///< DG service record. + U08 padding[ RECORD_PADDING_LENGTH(DG_SERVICE_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) - + RECORD_BYTE_SIZE(DG_SERVICE_RECORD_T) ]; ///< DG service group padding. + U16 crc; ///< CRC for the DG service structure. +} DG_SERVICE_GROUP_T; /// DG scheduler record structure typedef struct { - //TODO fill up -} DG_SCHEDULER_RECORD_T; + DG_SCHEDULED_RUN_RECORD_T dgScheduledRun; ///< DG scheduled runs. + U08 padding[ RECORD_PADDING_LENGTH(DG_SCHEDULED_RUN_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) - + RECORD_BYTE_SIZE(DG_SCHEDULED_RUN_RECORD_T) ]; ///< DG scheduled run group padding. + U16 crc; ///< CRC for the DG automated test time structure. +} DG_SCHEDULED_RUNS_GROUP_T; /// HD calibration records structure typedef struct @@ -346,19 +358,21 @@ { HD_CALIBRATION_GROUPS_T hdCalibratiobGroups; } HD_CALIBRATION_RECORD_T; + #pragma pack(pop) // Calibration variables #ifdef _DG_ -static DG_CALIBRATION_RECORD_T dgCalibrationRecord; ///< DG calibration record structure (including padding and final CRC). -static DG_SYSTEM_GROUP_T dgSystemGroup; ///< DG system group structure (including padding and final CRC). -static DG_LAST_SERVICE_GROUP_T dgLastServiceGroup; ///< DG last service group structure (including padding and final CRC). +static DG_CALIBRATION_RECORD_T dgCalibrationRecord; ///< DG calibration record structure (including padding and final CRC). +static DG_SYSTEM_GROUP_T dgSystemGroup; ///< DG system group structure (including padding and final CRC). +static DG_SERVICE_GROUP_T dgServiceGroup; ///< DG service group structure (including padding and final CRC). +static DG_SCHEDULED_RUNS_GROUP_T dgScheduledRunGroup; ///< DG scheduled run structure (including padding and final CRC). // Process records specifications const PROCESS_RECORD_SPECS_T RECORDS_SPECS [ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { - {BANK7_SECTOR0_START_ADDRESS, sizeof(DG_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_CALIBRATION_RECORD_T), (U08*)&dgCalibrationRecord, (U08*)&(dgCalibrationRecord.crc)}, // NVDATAMGMT_CALIBRATION_RECORD - {SYSTEM_DATA_NV_MEM_START_ADDRESS, sizeof(DG_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_SYSTEM_GROUP_T), (U08*)&dgSystemGroup, (U08*)&dgSystemGroup.crc}, // NVDATAMGMT_SYSTEM_RECORD - {LAST_SERVICE_RECORD_START_ADDRESS, sizeof(DG_LAST_SERVICE_RECORD_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgLastServiceGroup, (U08*)&dgLastServiceGroup.crc}, // NVDATAMGMT_PROCESS_LAST_SERVICE_RECORD - {DG_SCHEDULER_RECORD_START_ADDRESS, sizeof(DG_SCHEDULER_RECORD_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, 0, 0} // NVDATAMGMT_SCHEDULER_RECORD + {BANK7_SECTOR0_START_ADDRESS, sizeof(DG_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_CALIBRATION_RECORD_T), (U08*)&dgCalibrationRecord, (U08*)&(dgCalibrationRecord.crc)}, // NVDATAMGMT_CALIBRATION_RECORD + {SYSTEM_DATA_NV_MEM_START_ADDRESS, sizeof(DG_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_SYSTEM_GROUP_T), (U08*)&dgSystemGroup, (U08*)&dgSystemGroup.crc}, // NVDATAMGMT_SYSTEM_RECORD + {SERVICE_RECORD_START_ADDRESS, sizeof(DG_SERVICE_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgServiceGroup, (U08*)&dgServiceGroup.crc}, // NVDATAMGMT_PROCESS_LAST_SERVICE_RECORD + {DG_SCHEDULED_RUNS_START_ADDRESS, sizeof(DG_SCHEDULED_RUNS_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgScheduledRunGroup, (U08*)&dgScheduledRunGroup.crc} // NVDATAMGMT_SCHEDULER_RECORD }; #else if _HD_ static HD_CALIBRATION_RECORD_T hdCalibrationRecord; ///< HD calibration record. @@ -372,7 +386,7 @@ static U32 calSendDataIntervalCounter = 0; ///< Calibration data send to CAN bust interval counter. static U32 previousCalMessageNum = 0; ///< Calibration previous message number. static U32 recordUpdateAddress = 0; ///< DG record update address for all the write operations. -static U32 calDataReceiveStartTime = 0; ///< Time stamp the calibration/service was received. +static U32 recordReceiveStartTime = 0; ///< Time stamp the calibration/service was received. static PROCESS_RECORD_JOB_T recordJobQueue[ QUEUE_MAX_SIZE ]; ///< Record queue jobs. static U08 recordQueueRearIndex; ///< Record queue rear index. static U08 recordQueueFrontIndex; ///< Record queue front index. @@ -381,6 +395,7 @@ static U32 recordAddressOffset; ///< Record address offset. static RECORD_VALIDITY_CHECK_T writtenRecordStatus; ///< Record data write validity check. static U08 writtenRecordCheckBuffer[ MAX_EEPROM_WRITE_BUFFER_BYTES ]; ///< Written record validity check buffer. +static ACTIVE_QUEUE_T activeQueue; ///< Active queue. // Private variables static MEMORY_LOG_OPS_T jobQueue [ QUEUE_MAX_SIZE ]; ///< Job queue buffer. @@ -484,7 +499,7 @@ writtenRecordStatus = NVDATAMGMT_RECORD_NOT_CHECKED; hasPublishRecordBeenRequested = FALSE; - // Initialize and activate the flash bank 7 + // Initialize and activate flash bank 7 Fapi_initializeFlashBanks( ROUNDED_HCLK_FREQ ); Fapi_setActiveFlashBank( Fapi_FlashBank7 ); Fapi_enableEepromBankSectors( BANK7_SECTOR_0_31_ENABLE_BIT_MASK, BANK7_SECTOR_32_63_ENABLE_BIT_MASK ); @@ -707,9 +722,9 @@ { // Check if the data receiving process has timed out. The exec receive record // state machine is asynchronous so it is checked in this state machine - if ( didTimeout( calDataReceiveStartTime, CAL_DATA_RECEIVE_TIMEOUT_MS ) ) + if ( didTimeout( recordReceiveStartTime, RECORD_DATA_RECEIVE_TIMEOUT_MS ) ) { - // exec receive state machine timed out. Schedule a read to update the structure + // Exec receive state machine timed out. Schedule a read to update the structure enqueueRecordJob( NVDATAMGMT_READ, NVDATAMGMT_EEPROM, NVDATAMGMT_CALIBRATION_RECORD ); nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; } @@ -758,10 +773,10 @@ BOOL status = TRUE; // If the calibration message number is the first message number and receive exec state is idle, switch to idle - if ( CAL_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage && nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_IDLE ) + if ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage && nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_IDLE ) { nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; - calDataReceiveStartTime = getMSTimerCount(); + recordReceiveStartTime = getMSTimerCount(); previousCalMessageNum = 0; recordUpdateAddress = 0; } @@ -770,7 +785,7 @@ if ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_RECEIVE && currentMessage <= totalMessages ) { // Check if the current message is different from the previous message by 1 - if ( CAL_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) + if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) { // Define a pointer that points to the DG calibration record PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS [ NVDATAMGMT_CALIBRATION_RECORD ]; @@ -861,10 +876,10 @@ BOOL status = TRUE; // If the calibration message number is the first message number and receive exec state is idle, switch to idle - if ( CAL_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage && nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_IDLE ) + if ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage && nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_IDLE ) { nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; - calDataReceiveStartTime = getMSTimerCount(); + recordReceiveStartTime = getMSTimerCount(); previousCalMessageNum = 0; recordUpdateAddress = 0; } @@ -873,7 +888,7 @@ if ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_RECEIVE && currentMessage <= totalMessages ) { // Check if the current message is different from the previous message by 1 - if ( CAL_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) + if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) { // Define a pointer that points to the DG calibration record PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS [ NVDATAMGMT_SYSTEM_RECORD ]; @@ -895,7 +910,7 @@ if ( calcCRC != recordCRC ) { // CRC failed, request a read to read the data back from NV memory and update the structure - enqueueRecordJob( NVDATAMGMT_READ, NVDATAMGMT_EEPROM, NVDATAMGMT_CALIBRATION_RECORD ); + enqueueRecordJob( NVDATAMGMT_READ, NVDATAMGMT_EEPROM, NVDATAMGMT_SYSTEM_RECORD ); nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; status = FALSE; } @@ -922,17 +937,223 @@ return status; } -BOOL getLastServiceRecord( void ) +/*********************************************************************//** + * @brief + * The getServiceRecord function sets the system state machine + * to read and publish service record. + * @details Inputs: hasPublishRecordBeenRequested, NVDataMgmtExecCalState + * @details Outputs: hasPublishRecordBeenRequested + * @return TRUE if the request was successfully registered + *************************************************************************/ +BOOL getServiceRecord( void ) { + BOOL status = FALSE; + // Check if the state machine is in idle state and then set the request + if ( nvDataMgmtExecProcessRecordState == NVDATAMGMT_PROCESS_RECORD_STATE_IDLE ) + { + hasPublishRecordBeenRequested = TRUE; + recordToPublish = NVDATAMGMT_SERVICE_RECORD; + status = TRUE; + } + + return status; } -BOOL setLastServiceRecord( U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ) + +/*********************************************************************//** + * @brief + * The setServiceRecord function writes the service record that + * is received from Dialin into the service structure. + * @details Inputs: none + * @details Outputs: none + * @param currentMessage: current message number that is received from + * Dialin + * @param totalMessages: total number of messages from Dialin + * @param length: message length in bytes + * @param *addressPtr: address to the beginning of the service data data from + * Dialin + * @return TRUE if the request was successfully registered + *************************************************************************/ +BOOL setServiceRecord( U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ) { + BOOL status = TRUE; + // If the calibration message number is the first message number and receive exec state is idle, switch to idle + if ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage && nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_IDLE ) + { + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; + recordReceiveStartTime = getMSTimerCount(); + previousCalMessageNum = 0; + recordUpdateAddress = 0; + } + + // Check if there is still a message left to be received + if ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_RECEIVE && currentMessage <= totalMessages ) + { + // Check if the current message is different from the previous message by 1 + if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) + { + // Define a pointer that points to the DG calibration record + PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS [ NVDATAMGMT_SERVICE_RECORD ]; + U08* ptr = recordSpec.structAddressPtr; + + // Offset the pointer to length that we should start writing from + ptr += recordUpdateAddress; + + memcpy(ptr, addressPtr, length); + + // Check if the current message is total messages + // and 0 everything out since we are done writing + if ( currentMessage == totalMessages ) + { + U16 calcCRC = crc16 ( recordSpec.structAddressPtr, recordSpec.sizeofJob - sizeof(U16) ); + // Get the CRC of the structure without the last 16 bits which is the CRC as well as the padding values + U16 recordCRC = *(U16*)recordSpec.structCRCPtr; + + if ( calcCRC != recordCRC ) + { + // CRC failed, request a read to read the data back from NV memory and update the structure + enqueueRecordJob( NVDATAMGMT_READ, NVDATAMGMT_RTC, NVDATAMGMT_SERVICE_RECORD ); + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; + status = FALSE; + } + else + { + // CRC passed write the last service record to the RTC RAM + enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, NVDATAMGMT_SERVICE_RECORD ); + + // TODO FOR TESTING ONLY REMOVE + enqueueRecordJob( NVDATAMGMT_READ, NVDATAMGMT_RTC, NVDATAMGMT_SERVICE_RECORD ); + // TODO FOR TESTING ONLY REMOVE + + // Done with receiving data, go back to idle + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; + } + } + else + { + // Update the length as it has successfully been written + recordUpdateAddress += length; + + // Now the current message is the previous message + previousCalMessageNum = currentMessage; + } + } + } + + return status; } /*********************************************************************//** * @brief + * The getScheduledRunsRecord function sets the system state machine + * to read and publish the scheduled runs record. + * @details Inputs: hasPublishRecordBeenRequested, NVDataMgmtExecCalState, + * recordToPublish + * @details Outputs: hasPublishRecordBeenRequested, recordToPublish + * @return TRUE if the request was successfully registered + *************************************************************************/ +BOOL getScheduledRunsRecord( void ) +{ + BOOL status = FALSE; + + // Check if the state machine is in idle state and then set the request + if ( nvDataMgmtExecProcessRecordState == NVDATAMGMT_PROCESS_RECORD_STATE_IDLE ) + { + hasPublishRecordBeenRequested = TRUE; + recordToPublish = NVDATAMGMT_SCHEDULED_RUNS_RECORD; + status = TRUE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The setScheduledRunsRecord function writes the scheduled runs record that + * is received from Dialin into the scheduled runs structure. + * @details Inputs: none + * @details Outputs: none + * @param currentMessage: current message number that is received from + * Dialin + * @param totalMessages: total number of messages from Dialin + * @param length: message length in bytes + * @param *addressPtr: address to the beginning of the scheduled runs data from + * Dialin + * @return TRUE if the request was successfully registered + *************************************************************************/ +BOOL setScheduledRunsRecord( U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ) +{ + BOOL status = TRUE; + + // If the calibration message number is the first message number and receive exec state is idle, switch to idle + if ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage && nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_IDLE ) + { + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; + recordReceiveStartTime = getMSTimerCount(); + previousCalMessageNum = 0; + recordUpdateAddress = 0; + } + + // Check if there is still a message left to be received + if ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_RECEIVE && currentMessage <= totalMessages ) + { + // Check if the current message is different from the previous message by 1 + if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) + { + // Define a pointer that points to the DG calibration record + PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS [ NVDATAMGMT_SERVICE_RECORD ]; + U08* ptr = recordSpec.structAddressPtr; + + // Offset the pointer to length that we should start writing from + ptr += recordUpdateAddress; + + memcpy(ptr, addressPtr, length); + + // Check if the current message is total messages + // and 0 everything out since we are done writing + if ( currentMessage == totalMessages ) + { + U16 calcCRC = crc16 ( recordSpec.structAddressPtr, recordSpec.sizeofJob - sizeof(U16) ); + // Get the CRC of the structure without the last 16 bits which is the CRC as well as the padding values + U16 recordCRC = *(U16*)recordSpec.structCRCPtr; + + if ( calcCRC != recordCRC ) + { + // CRC failed, request a read to read the data back from NV memory and update the structure + enqueueRecordJob( NVDATAMGMT_READ, NVDATAMGMT_RTC, NVDATAMGMT_SCHEDULED_RUNS_RECORD ); + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; + status = FALSE; + } + else + { + // CRC passed write the last service record to the RTC RAM + enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, NVDATAMGMT_SCHEDULED_RUNS_RECORD ); + + // TODO FOR TESTING ONLY REMOVE + enqueueRecordJob( NVDATAMGMT_READ, NVDATAMGMT_RTC, NVDATAMGMT_SCHEDULED_RUNS_RECORD ); + // TODO FOR TESTING ONLY REMOVE + + // Done with receiving data, go back to idle + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; + } + } + else + { + // Update the length as it has successfully been written + recordUpdateAddress += length; + + // Now the current message is the previous message + previousCalMessageNum = currentMessage; + } + } + } + + return status; +} + +/*********************************************************************//** + * @brief * The getDGPressureSensorsCalibrationRecord function returns the DG pressure * sensors structure. * @details Inputs: none @@ -1726,14 +1947,15 @@ *************************************************************************/ static NVDATAMGMT_EXEC_STATE_T handleExecIdleState ( void ) { + // TODO add the logging features back NVDATAMGMT_EXEC_STATE_T state = NVDATAMGMT_EXEC_STATE_IDLE; NVDATAMGMT_OPERATION_STATE_T ops; NVDATAMGMT_LOCATION_STATE_T location; U32 startAddress; U08* bufferAddress; U32 maxBufferLength; - BOOL areQueuesEmpty = FALSE; + BOOL areQueuesNotEmpty = FALSE; // If the record processing queue is not empty, process the queues if ( !isRecordQueueEmpty() ) @@ -1744,12 +1966,13 @@ PROCESS_RECORD_SPECS_T jobSpecs = RECORDS_SPECS [ job ]; // Set the record address offset to 0 since a job will just be started recordAddressOffset = 0; - areQueuesEmpty = TRUE; + areQueuesNotEmpty = TRUE; ops = recordCurrentJob.memoryOperation; location = recordCurrentJob.memoryLocation; currentTime = getMSTimerCount(); startAddress = jobSpecs.startAddress + recordAddressOffset; bufferAddress = jobSpecs.structAddressPtr + recordAddressOffset; + activeQueue = NVDATAMGMT_PROCESS_RECORDS; // Choose the right buffer size if ( ops == NVDATAMGMT_WRITE ) @@ -1763,7 +1986,7 @@ } // Check if a queue job is available - if ( areQueuesEmpty ) + if ( areQueuesNotEmpty ) { if ( ops == NVDATAMGMT_ERASE_SECTOR ) { @@ -1780,46 +2003,12 @@ Fapi_doMarginRead ( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength, Fapi_NormalRead ); state = NVDATAMGMT_EXEC_STATE_READ_FROM_EEPROM; } - } - - // TODO clean up - // Check if the queue is not empty and the calibration/service status is none - // Processing calibration and service status have priority - /*if ( !isQueueEmpty() ) - { - 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 ( (U32*)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 ( (U32*)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, (U32*)startAddress ); - state = NVDATAMGMT_EXEC_STATE_ERASE_EEPROM; - } else if ( ops == NVDATAMGMT_WRITE && location == NVDATAMGMT_RTC ) { if ( getRTCRAMState() == RTC_RAM_STATE_READY ) { currentTime = getMSTimerCount(); - writeToRAM ( startAddress, currentJob.buffer, length ); + writeToRAM ( startAddress, bufferAddress, maxBufferLength ); state = NVDATAMGMT_EXEC_STATE_WRITE_TO_RTC; } } @@ -1828,12 +2017,12 @@ if ( getRTCRAMState() == RTC_RAM_STATE_READY ) { currentTime = getMSTimerCount(); - readFromRAM( startAddress, length ); + readFromRAM( startAddress, maxBufferLength ); currentJob.externalAddress->status = NVDATAMGMT_READ_IN_PROGRESS; state = NVDATAMGMT_EXEC_STATE_READ_FROM_RTC; } } - }*/ + } return state; } @@ -1970,8 +2159,14 @@ if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) { - // TODO bring this back for logging - //currentJob.externalAddress->status = NVDATAMGMT_READ_COMPLETE; + // Signal the external client that the read is complete. + // This is only needed for reading the data logs and not the records + if ( activeQueue == NVDATAMGMT_PROCESS_LOGS ) + { + currentJob.externalAddress->status = NVDATAMGMT_READ_COMPLETE; + activeQueue = NVDATAMGMT_QUEUE_NONE; + } + state = NVDATAMGMT_EXEC_STATE_IDLE; } @@ -2027,7 +2222,7 @@ * RAM was ready, and if the RAM got back to Idle after the read command, * it calls another function to read the data back from RTC RAM and * it sets the state to Idle. - * @details Inputs: currentJob + * @details Inputs: activeQueue, currentJob, recordCurrentJob * @details Outputs: currentJob * @return next state *************************************************************************/ @@ -2038,8 +2233,24 @@ if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) { - getDataFromRAM( currentJob.externalAddress->externalBuffer, currentJob.length ); - currentJob.externalAddress->status = NVDATAMGMT_READ_COMPLETE; + U08* bufferPtr = 0; + U32 length; + + if ( activeQueue == NVDATAMGMT_PROCESS_RECORDS ) + { + RECORD_JOBS_STATE_T job = recordCurrentJob.recordJob; + PROCESS_RECORD_SPECS_T jobSpecs = RECORDS_SPECS [ job ]; + bufferPtr = jobSpecs.structAddressPtr; + length = jobSpecs.sizeofJob; + } + else + { + // TODO add the rest of the items for for logging + currentJob.externalAddress->status = NVDATAMGMT_READ_COMPLETE; + } + + getDataFromRAM( bufferPtr, length ); + state = NVDATAMGMT_EXEC_STATE_IDLE; } @@ -2121,28 +2332,30 @@ switch( recordToPublish ) { case NVDATAMGMT_CALIBRATION_RECORD: - // Pass the information to be written to CAN bus + // Pass the information to the CAN bus sendDGCalibrationRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; case NVDATAMGMT_SYSTEM_RECORD: - // Pass the information to be written to CAN bus + // Pass the information to the CAN bus sendDGSystemRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; - case NVDATAMGMT_LAST_SERVICE_RECORD: + case NVDATAMGMT_SERVICE_RECORD: + // Pass the information to the CAN bus + sendDGServiceRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; - case NVDATAMGMT_SCHEDULER_RECORD: + case NVDATAMGMT_SCHEDULED_RUNS_RECORD: + // Pass the information to the CAN bus + sendDGScheduledRunsRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); break; default: //Ignore break; } - - calPublishMessageCount++; calSendDataIntervalCounter = 0; } Index: NVDataMgmt.h =================================================================== diff -u -r89f99fccb9ae7dda71cfef84d4ea8cb59502fa9a -r0ee608e8de70aef91f5bdf7ebfa1f1cccf2e43dd --- NVDataMgmt.h (.../NVDataMgmt.h) (revision 89f99fccb9ae7dda71cfef84d4ea8cb59502fa9a) +++ NVDataMgmt.h (.../NVDataMgmt.h) (revision 0ee608e8de70aef91f5bdf7ebfa1f1cccf2e43dd) @@ -45,12 +45,13 @@ NUM_OF_MFG_LOC ///< Number of manufacturing location. } MFG_LOCATION_T; -typedef enum last_service_location +/// Service location enumeration. +typedef enum service_location { - LAST_SERVICE_LOC_FACTORY = 0, ///< Last service location factory (HD/DG). - LAST_SERVICE_LOC_FIELD, ///< Last service location field (HD/DG). - NUM_OF_LAST_SERVICE_LOC ///< Number of last service location. -} LAST_SERVICE_LOCATION_T; + SERVICE_LOC_FACTORY = 0, ///< Service location factory (HD/DG). + SERVICE_LOC_FIELD, ///< Service location field (HD/DG). + NUM_OF_SERVICE_LOC ///< Number of service location. +} SERVICE_LOCATION_T; /// Log event enumeration. typedef enum log_event @@ -167,6 +168,15 @@ NUM_OF_CAL_DATA_BICARB_CONCENTRATES } CAL_DATA_DG_BICARB_CONCENTRATE_T; +/// DG scheduled runs +typedef enum dg_scheduled_runs +{ + FLUSH = 0, + HEAT_DISINFECT, + CHEMICAL_DISINFECT, + NUM_OF_DG_SCHEDULED_RUNS +} SCHEDULED_DG_RUNS_T; + #pragma pack(push, 1) /// Payload record structure for a linear calibration message. TODO remove typedef struct @@ -368,16 +378,26 @@ U16 crc; ///< CRC for the DG system record structure. } DG_SYSTEM_RECORD_T; -/// DG last service record structure +/// DG service record structure typedef struct { - LAST_SERVICE_LOCATION_T lastServiceLoc; ///< DG last service location. - U32 lastServiceDate; ///< DG last service date. + SERVICE_LOCATION_T lastServiceLoc; ///< DG service location. + U32 lastServiceDate; ///< DG service date. U16 crc; ///< CRC for the DG last service record structure. -} DG_LAST_SERVICE_RECORD_T; +} DG_SERVICE_RECORD_T; +typedef struct +{ + U32 lastRunTime; + U16 crc; +} DG_SCHEDULED_RUN_T; -/********************** OLD STRUCTS REMOVE ******************/ +typedef struct +{ + DG_SCHEDULED_RUN_T dgScheduledRun[ NUM_OF_DG_SCHEDULED_RUNS ]; +} DG_SCHEDULED_RUN_RECORD_T; + +/********************** OLD STRUCTS TODO REMOVE ******************/ /// Manufacturing data structure. TODO remove typedef struct mfg_Data { @@ -456,12 +476,16 @@ BOOL getSystemRecord( void ); BOOL setSystemRecord( U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); -BOOL getLastServiceRecord( void ); -BOOL setLastServiceRecord( U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); +BOOL getServiceRecord( void ); +BOOL setServiceRecord( U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); +BOOL getScheduledRunsRecord( void ); +BOOL setScheduledRunsRecord( U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); + DG_PRES_SENSORS_CAL_RECORD_T getDGPressureSensorsCalibrationRecord( void ); void getDGFlowSensorsCalibrationRecord( U08* buffer ); +// TODO clean up BOOL setBootloaderFlag ( U32 flag ); U32 getBootloaderFlag ( void ); Index: NVDataMgmtDGRecords.h =================================================================== diff -u --- NVDataMgmtDGRecords.h (revision 0) +++ NVDataMgmtDGRecords.h (revision 0ee608e8de70aef91f5bdf7ebfa1f1cccf2e43dd) @@ -0,0 +1,13 @@ +/* + * NVDataMgmtDGRecords.h + * + * Created on: Feb 12, 2021 + * Author: fw + */ + +#ifndef FWCOMMON_NVDATAMGMTDGRECORDS_H_ +#define FWCOMMON_NVDATAMGMTDGRECORDS_H_ + + + +#endif /* FWCOMMON_NVDATAMGMTDGRECORDS_H_ */ Index: RTC.c =================================================================== diff -u -rcd1dbf44ebce97f61ad4a757d47449562ec366f0 -r0ee608e8de70aef91f5bdf7ebfa1f1cccf2e43dd --- RTC.c (.../RTC.c) (revision cd1dbf44ebce97f61ad4a757d47449562ec366f0) +++ RTC.c (.../RTC.c) (revision 0ee608e8de70aef91f5bdf7ebfa1f1cccf2e43dd) @@ -954,7 +954,7 @@ { RTC_EXEC_STATE_T result = RTC_EXEC_STATE_WAIT_FOR_POST; - if ( RTCSelfTestState == RTC_SELF_TEST_STATE_COMPLETE ) + //if ( RTCSelfTestState == RTC_SELF_TEST_STATE_COMPLETE ) { result = RTC_EXEC_STATE_IDLE; }