Index: NVDataMgmt.c =================================================================== diff -u -r0229ed2875a9bb9b1a64ac9a4fac948f1ba1410c -r8dc8551a200e8353a563828ccc8dcb4ad9f47bfb --- NVDataMgmt.c (.../NVDataMgmt.c) (revision 0229ed2875a9bb9b1a64ac9a4fac948f1ba1410c) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision 8dc8551a200e8353a563828ccc8dcb4ad9f47bfb) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * -* @file NVDataMgmt.c +* @file NVDataMgmt.c * -* @author (last) Sean Nash -* @date (last) 24-Sep-2020 +* @author (last) Sean Nash +* @date (last) 12-Nov-2021 * -* @author (original) Dara Navaei -* @date (original) 12-Feb-2020 +* @author (original) Dara Navaei +* @date (original) 12-Feb-2020 * ***************************************************************************/ @@ -78,9 +78,10 @@ #define DG_CONSUMED_WATER_ADDRESS 0x00000020 // 32 ///< DG water consumption start address in RTC RAM (32). #define SERVICE_RECORD_START_ADDRESS 0x00000030 // 48 ///< Service date record start address in RTC RAM (HD/DG) (48). #define DG_SCHEDULED_RUNS_START_ADDRESS (SERVICE_RECORD_START_ADDRESS + sizeof(DG_SERVICE_GROUP_T)) ///< DG scheduled runs start address in RTC RAM. +#define DG_HEATERS_INFO_START_ADDRESS (DG_SCHEDULED_RUNS_START_ADDRESS + sizeof(DG_HEATERS_INFO_GROUP_T))///< DG heaters info start address in RTC RAM. #define COMMAND_TIME_OUT 500U ///< Timeout for an EEPROM or RTC command in ms. -/// EEPROM functions use the buffer length as the size of U32. So before send the length to any of FAPI functions, it should be divide by 4. +/// EEPROM functions use the buffer length as the size of U32. So before send the length to any of FAPI functions, it should be divided by 4. #define EEPROM_OPS_SIZE_OF_CONVERTER 4 // ********** Calibration data defines ********** @@ -105,11 +106,24 @@ #define RECORD_DEFAULT_OFFSET 0.0 ///< Record default offset. #define RECORD_DEFAULT_CONST 0.0 ///< Record default constant. #define RECORD_DEFAULT_RATIO 1.0 ///< Record default ratio. +// The service record interval is equivalent to 6 months +#define RECORD_DEFAULT_SERVICE_INTERVAL_S 15768000U ///< Record default service interval in seconds. +#define RECORD_DEFAULT_CHARACTER ' ' ///< Record default character. -/// Once a new calibration data is available the driver, sets a signal for the defined time. Once the time -/// is out, it turns the signal off. -#define NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS (1 * MS_PER_SECOND) +// Once a new calibration data is available the driver, sets a signal for the defined time. Once the time is out, it turns the signal off. +#define NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS (1 * MS_PER_SECOND) ///< New calibration available signal timeout in milliseconds. +// HD specific defines +#ifdef _HD_ +#endif + +// DG specific defines +#ifdef _DG_ +#define FLUSH_LINES_DEFAULT_VOLUME_L 0.01 ///< Water volume to flush when starting re-circulate mode in liters. +#define ACID_CONC_DEFAULT_MIXING_RATIO ( 2.35618 / FRACTION_TO_PERCENT_FACTOR ) ///< Ratio between RO water and acid concentrate mixing ratio. +#define BICARB_CONC_DEFAULT_MIXING_RATIO ( 4.06812 / FRACTION_TO_PERCENT_FACTOR ) ///< Ratio between RO water and bicarbonate concentrate mixing ratio. +#endif + /// NVDataMgmt self-test states enumeration. typedef enum NVDataMgmt_Self_Test_States { @@ -121,6 +135,7 @@ NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD, ///< Self test read log record. NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME, ///< Self test read treatment time. TODO combine with water consumption NVDATAMGMT_SELF_TEST_STATE_READ_WATER_CONSUMPTION, ///< Self test read water consumption. TODO combine with tx time + NVDATAMGMT_SELF_TEST_STATE_READ_DG_HEATERS_INFO, ///< Self test read DG heaters information. 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. @@ -181,7 +196,10 @@ NVDATAMGMT_CALIBRATION_RECORD = 0, ///< NVDataMgmt process write calibration record. NVDATAMGMT_SYSTEM_RECORD, ///< NVDataMgmt process write system record. NVDATAMGMT_SERVICE_RECORD, ///< NVDATAMgmt process service record. +#ifdef _DG_ NVDATAMGMT_SCHEDULED_RUNS_RECORD, ///< NVDataMgmt process scheduled runs record. + NVDATAMGMT_HEATERS_INFO_RECORD, ///< NVDataMgmt process heaters info record. +#endif NUM_OF_NVDATMGMT_RECORDS_JOBS ///< Number of NVDataMgmt records jobs. } RECORD_JOBS_STATE_T; @@ -311,13 +329,23 @@ U16 crc; ///< CRC for the DG scheduled runs structure. } DG_SCHEDULED_RUNS_GROUP_T; +/// DG usage record structure typedef struct { DG_USAGE_INFO_RECORD_T dgUsageInfo; ///< DG usage info record. U08 padding[ RECORD_PADDING_LENGTH(DG_USAGE_INFO_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) - RECORD_BYTE_SIZE(DG_USAGE_INFO_RECORD_T) ]; ///< DG scheduled run group padding. U16 crc; ///< CRC for the DG usage info structure. } DG_USAGE_INFO_GROUP_T; + +/// DG heaters record +typedef struct +{ + DG_HEATERS_RECORD_T dgHeatersInfo; ///< DG heaters info record. + U08 padding[ RECORD_PADDING_LENGTH(DG_HEATERS_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) - + RECORD_BYTE_SIZE(DG_HEATERS_RECORD_T) ]; ///< DG heater info group padding. + U16 crc; ///< CRC for the DG heaters info structure. +} DG_HEATERS_INFO_GROUP_T; #endif #ifdef _HD_ @@ -379,14 +407,17 @@ static DG_SERVICE_GROUP_T dgServiceGroup; ///< DG service group structure (including padding and final CRC). static DG_SCHEDULED_RUNS_GROUP_T dgScheduledRunsGroup; ///< DG scheduled run structure (including padding and final CRC). static DG_USAGE_INFO_GROUP_T dgUsageInfoGroup; ///< DG usage info structure (including padding and final CRC). +static DG_HEATERS_INFO_GROUP_T dgHeatersInfoGroup; ///< DG heaters info structure (including padding and final CRC). // Process records specifications -const PROCESS_RECORD_SPECS_T RECORDS_SPECS [ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { +const PROCESS_RECORD_SPECS_T RECORDS_SPECS[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { {CAL_RECORD_NV_MEM_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_RECORD_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_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*)&dgScheduledRunsGroup, (U08*)&dgScheduledRunsGroup.crc} // NVDATAMGMT_SCHEDULER_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*)&dgScheduledRunsGroup, (U08*)&dgScheduledRunsGroup.crc} , // NVDATAMGMT_SCHEDULER_RECORD + {DG_HEATERS_INFO_START_ADDRESS, sizeof(DG_HEATERS_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgHeatersInfoGroup, (U08*)&dgHeatersInfoGroup.crc} // NVDATAMGMT_HEATERS_INFO_RECORD }; #endif + #ifdef _HD_ static HD_CALIBRATION_RECORD_T hdCalibrationRecord; ///< HD calibration record structure. static HD_SYSTEM_GROUP_T hdSystemGroup; ///< HD system group structure (including padding and final CRC). @@ -399,6 +430,7 @@ {SERVICE_RECORD_START_ADDRESS, sizeof(HD_SERVICE_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdServiceGroup, (U08*)&hdServiceGroup.crc}, // NVDATAMGMT_PROCESS_LAST_SERVICE_RECORD }; #endif + static RECORD_JOBS_STATE_T recordToPublish; ///< Record to publish (i.e. calibration, system) static PROCESS_RECORD_STATE_T nvDataMgmtExecProcessRecordState = NVDATAMGMT_PROCESS_RECORD_STATE_IDLE; ///< NVDataMgmt exec process record state. static RECEIVE_RECORD_STATE_T nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; ///< NVDataMgmt exec receive record state. @@ -439,11 +471,14 @@ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadCalibrationRecord( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadSystemRecord( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadServiceRecord( void ); +#ifdef _DG_ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadScheduledRunsRecord( void ); +#endif #ifdef _HD_ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadHDTreatmentTime( void ); #endif #ifdef _DG_ +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadDGHeatersInfo( void ); static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadDGWaterConsumption( void ); #endif static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadLogRecord( void ); @@ -489,12 +524,18 @@ // Record check helper functions static BOOL areRecordsValid( void ); static BOOL isPolynomialRecordValid( POLYNOMIAL_CAL_PAYLOAD_T* record ); +#ifdef _DG +static void setRsrvdCalibrationRecordsToZero( void ); +#endif #ifdef _DG_ +static BOOL isDGSystemRecordValid( void ); +static BOOL isDGServiceRecordValid( void ); static BOOL isDGCalibrationRecordValid( void ); static BOOL isDGConcPumpRecordValid( DG_CONC_PUMPS_CAL_DATA_T* record ); static BOOL isDGDrainPumpRecordValid( DG_DRAIN_PUMP_CAL_RECORD_T* record ); static BOOL isDGROPumpRecordValid( DG_RO_PUMP_CAL_RECORD_T* record ); +static BOOL isDGPreROPurgeVolumeRecordValid( DG_PRE_RO_PURGE_VOLUME_T* record ); static BOOL isDGDrainLineVolRecordValid( DG_DRAIN_LINE_VOLUME_T* record ); static BOOL isDGReservoirVolRecordValid( DG_RESERVOIR_VOLUME_DATA_T* record ); static BOOL isDGGenericVolRecordValid( DG_GENERIC_VOLUME_DATA_T* record ); @@ -504,7 +545,10 @@ static BOOL isDGFanRecordValid( DG_FAN_CAL_RECORD_T* record ); static BOOL isDGAccelerometerSensorRecordValid( DG_ACCELEROMETER_SENSOR_CAL_RECORD_T* record ); #endif + #ifdef _HD_ +static BOOL isHDSystemRecordValid( void ); +static BOOL isHDServiceRecordValid( void ); static BOOL isHDCalibrationRecordValid( void ); static BOOL isHDValveRecordValid( HD_VALVE_CAL_PAYLOAD_T* record ); static BOOL isHDPumpRecordValid( HD_PUMP_CAL_PAYLOAD_T* record ); @@ -514,13 +558,7 @@ /*********************************************************************//** * @brief * The initNVDataMgmt function initializes the module. - * @details Inputs: nvDataMgmtSelfTestState, nvDataMgmtExecState, - * nvDataMgmtSelfTestResult, nvDataMgmtExecProcessRecordState, - * nvDataMgmtExecReceiveRecordState, queueRearIndex, queueFrontIndex, - * queueFrontIndex, queueCount, recordUpdateAddress, recordQueueRearIndex, - * recordQueueFrontIndex, recordQueueCount, recordAddressOffset, - * writtenRecordStatus, hasPublishRecordBeenRequested, isNewCalAvailable, - * newCalStartTimer + * @details Inputs: none * @details Outputs: nvDataMgmtSelfTestState, nvDataMgmtExecState, * nvDataMgmtSelfTestResult, nvDataMgmtExecProcessRecordState, * nvDataMgmtExecReceiveRecordState, queueRearIndex, queueFrontIndex, @@ -627,9 +665,6 @@ nvDataMgmtExecState = NVDATAMGMT_EXEC_STATE_IDLE; break; } - - // Check the calibration signal - monitorNewCalSignal(); } /*********************************************************************//** @@ -659,13 +694,16 @@ nvDataMgmtSelfTestState = handleSelfTestReadServiceRecord(); break; +#ifdef _DG_ case NVDATAMGMT_SELF_TEST_STATE_READ_SCHEDULED_RUNS_RECORD: nvDataMgmtSelfTestState = handleSelfTestReadScheduledRunsRecord(); break; +#endif case NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD: nvDataMgmtSelfTestState = handleSelfTestReadLogRecord(); break; + #ifdef _HD_ case NVDATAMGMT_SELF_TEST_STATE_READ_TREATMENT_TIME: nvDataMgmtSelfTestState = handleSelfTestReadHDTreatmentTime(); @@ -675,7 +713,12 @@ case NVDATAMGMT_SELF_TEST_STATE_READ_WATER_CONSUMPTION: nvDataMgmtSelfTestState = handleSelfTestReadDGWaterConsumption(); break; + + case NVDATAMGMT_SELF_TEST_STATE_READ_DG_HEATERS_INFO: + nvDataMgmtSelfTestState = handleSelfTestReadDGHeatersInfo(); + break; #endif + case NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC: nvDataMgmtSelfTestState = handleSelfTestCheckCRC(); break; @@ -744,6 +787,9 @@ nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; } } + + // Check the calibration signal + monitorNewCalSignal(); } /*********************************************************************//** @@ -782,16 +828,15 @@ * Dialin * @param totalMessages: total number of messages from Dialin * @param length: message length in bytes - * @param *addressPtr: address to the beginning of the calibration data from - * Dialin + * @param *addressPtr: address to the beginning of the calibration data from Dialin * @return TRUE if the request was successfully registered *************************************************************************/ BOOL setCalibrationRecord( 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 ) + if ( ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage ) && ( NVDATAMGMT_RECEIVE_RECORD_IDLE == nvDataMgmtExecReceiveRecordState ) ) { nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; recordReceiveStartTime = getMSTimerCount(); @@ -800,13 +845,13 @@ } // Check if there is still a message left to be received - if ( ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_RECEIVE ) && ( currentMessage <= totalMessages ) ) + if ( ( NVDATAMGMT_RECEIVE_RECORD_RECEIVE == nvDataMgmtExecReceiveRecordState ) && ( 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_CALIBRATION_RECORD ]; + PROCESS_RECORD_SPECS_T recordSpec = RECORDS_SPECS[ NVDATAMGMT_CALIBRATION_RECORD ]; U08* ptr = recordSpec.structAddressPtr; // Offset the pointer to length that we should start writing from @@ -819,7 +864,7 @@ // and 0 everything out since we are done writing if ( currentMessage == totalMessages ) { - U16 calcCRC = crc16 ( recordSpec.structAddressPtr, recordSpec.sizeofJob - sizeof(U16) ); + U16 calcCRC = crc16( recordSpec.structAddressPtr, recordSpec.sizeofJob - sizeof(U16) ); U16 recordCRC = *(U16*)recordSpec.structCRCPtr; if ( calcCRC != recordCRC ) @@ -835,12 +880,11 @@ BOOL scheduleStatus = enqueueSector0Records(); // Signal that there is a new calibration record available. - isNewCalAvailable = TRUE; newCalStartTimer = getMSTimerCount(); - - // Done with receiving data, go back to idle - nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; + isNewCalAvailable = TRUE; } + // Done with receiving data, go back to idle + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; } else { @@ -851,6 +895,11 @@ previousCalMessageNum = currentMessage; } } + else + { + status = FALSE; + nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; + } } return status; @@ -901,7 +950,7 @@ 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 ) + if ( ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage ) && ( NVDATAMGMT_RECEIVE_RECORD_IDLE == nvDataMgmtExecReceiveRecordState ) ) { nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_RECEIVE; recordReceiveStartTime = getMSTimerCount(); @@ -910,7 +959,7 @@ } // Check if there is still a message left to be received - if ( nvDataMgmtExecReceiveRecordState == NVDATAMGMT_RECEIVE_RECORD_RECEIVE && currentMessage <= totalMessages ) + if ( ( NVDATAMGMT_RECEIVE_RECORD_RECEIVE == nvDataMgmtExecReceiveRecordState ) && ( currentMessage <= totalMessages ) ) { // Check if the current message is different from the previous message by 1 if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousCalMessageNum ) ) @@ -976,7 +1025,7 @@ BOOL status = FALSE; // Check if the state machine is in idle state and then set the request - if ( nvDataMgmtExecProcessRecordState == NVDATAMGMT_PROCESS_RECORD_STATE_IDLE ) + if ( NVDATAMGMT_PROCESS_RECORD_STATE_IDLE == nvDataMgmtExecProcessRecordState ) { hasPublishRecordBeenRequested = TRUE; recordToPublish = NVDATAMGMT_SERVICE_RECORD; @@ -1068,6 +1117,7 @@ return status; } +#ifdef _DG_ /*********************************************************************//** * @brief * The getScheduledRunsRecord function sets the system state machine @@ -1173,6 +1223,7 @@ return status; } +#endif /*********************************************************************//** * @brief @@ -1326,7 +1377,7 @@ * @details Outputs: none * @return DG reservoirs volume record *************************************************************************/ -DG_RESERVOIR_VOLUME_RECORD_T getDGReservoirVolumeRecord( void ) +DG_RESERVOIR_VOLUME_RECORD_T getDGReservoirsVolumeRecord( void ) { return dgCalibrationRecord.dgCalibrationGroups.reservoirVolumesRecord; } @@ -1623,7 +1674,7 @@ hdUsageInfoGroup.hdUsageInfo.treatmentTime = hours; hdUsageInfoGroup.crc = crc16 ( (U08*)&hdUsageInfoGroup.hdUsageInfo.treatmentTime, sizeof(U32) ); - if ( !isQueueFull() ) + if ( FALSE == isQueueFull() ) { enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, HD_TREATMENT_TIME_ADDRESS, (U08*)&hdUsageInfoGroup, 0, sizeof(HD_USAGE_INFO_RECORD_T) ); @@ -1660,13 +1711,13 @@ { BOOL status = FALSE; dgUsageInfoGroup.dgUsageInfo.waterConsumption = liters; - dgUsageInfoGroup.crc = crc16 ( (U08*)&dgUsageInfoGroup.dgUsageInfo.waterConsumption, sizeof(U32) ); + dgUsageInfoGroup.crc = crc16 ( (U08*)&dgUsageInfoGroup.dgUsageInfo.waterConsumption, sizeof(U16) ); if ( !isQueueFull() ) { enqueue( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, DG_CONSUMED_WATER_ADDRESS, (U08*)&dgUsageInfoGroup, 0, sizeof(DG_USAGE_INFO_RECORD_T) ); - status = TRUE; + status = TRUE; //TODO this is not right use enqueueRecordJob function to schedule a write } return status; @@ -1683,6 +1734,45 @@ { return dgUsageInfoGroup.dgUsageInfo.waterConsumption; } + +/*********************************************************************//** + * @brief + * The getHeatersInfoReocrd returns the DG heaters info. + * @details Inputs: none + * @details Outputs: none + * @return DG heaters information record + ******************************************************************/ +DG_HEATERS_RECORD_T getHeatersInfoReocrd( void ) +{ + return dgHeatersInfoGroup.dgHeatersInfo; +} + +/*********************************************************************//** + * @brief + * The setHeatersInfoRecord sets a queue job to write the DG heaters info + * back to the RTC RAM. + * @details Inputs: none + * @details Outputs: dgHeatersInfoGroup + * @param addressPrt which is an address to the structure that is holding the + * heaters information. + * @return TRUE if queue is not full otherwise, FALSE + *************************************************************************/ +BOOL setHeatersInfoRecord( U08 *addressPtr ) +{ + BOOL status = FALSE; + memcpy( &dgHeatersInfoGroup.dgHeatersInfo, addressPtr, sizeof( DG_HEATERS_RECORD_T ) ); + // The crc is the DG heaters info and padding - the CRC U16 variable + dgHeatersInfoGroup.crc = crc16 ( (U08*)&dgHeatersInfoGroup.dgHeatersInfo, sizeof( dgHeatersInfoGroup ) - sizeof( U16 ) ); + + if ( FALSE == isQueueFull() ) + { + // Queue is not full, schedule a write to RTC RAM the write the heaters information record + enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_RTC, NVDATAMGMT_HEATERS_INFO_RECORD ); + status = TRUE; + } + + return status; +} #endif /*********************************************************************//** * @brief @@ -1700,9 +1790,9 @@ PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_CALIBRATION_RECORD ]; U32 startAddress = specs.startAddress; U08* bufferAddress = specs.structAddressPtr; - U32 maxBufferLength = ( specs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER ); + U32 maxBufferLength = specs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER; - Fapi_doMarginRead ( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength, Fapi_NormalRead ); + Fapi_doMarginRead( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength, Fapi_NormalRead ); currentTime = getMSTimerCount(); state = NVDATAMGMT_SELF_TEST_STATE_READ_CAL_RECORD; } @@ -1728,9 +1818,9 @@ PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SYSTEM_RECORD ]; U32 startAddress = specs.startAddress; U08* bufferAddress = specs.structAddressPtr; - U32 maxBufferLength = ( specs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER ); + U32 maxBufferLength = specs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER; - Fapi_doMarginRead ( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength, Fapi_NormalRead ); + Fapi_doMarginRead( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength, Fapi_NormalRead ); currentTime = getMSTimerCount(); state = NVDATAMGMT_SELF_TEST_STATE_READ_SYS_RECORD; } @@ -1750,11 +1840,11 @@ NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_SYS_RECORD; BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_NVDATA_EEPROM_OPS_FAILURE, (U08*)&state ); - if ( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmReady || timeoutStatus == TRUE ) + if ( ( Fapi_Status_FsmReady == FAPI_CHECK_FSM_READY_BUSY ) || ( TRUE == timeoutStatus ) ) { - if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + if ( RTC_RAM_STATE_READY == getRTCRAMState() ) { - PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SERVICE_RECORD ]; + PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ]; U32 startAddress = specs.startAddress; U32 maxBufferLength = specs.maxReadBufferSize; @@ -1781,18 +1871,18 @@ 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 ) + if ( ( RTC_RAM_STATUS_IDLE == getRTCRAMStatus() ) || ( TRUE == timeoutStatus ) ) { - PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SERVICE_RECORD ]; + PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ]; U08* bufferAddress = specs.structAddressPtr; U32 maxBufferLength = specs.maxReadBufferSize; getDataFromRAM( bufferAddress, maxBufferLength ); #ifdef _DG_ - if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + if ( RTC_RAM_STATE_READY == getRTCRAMState() ) { - PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SCHEDULED_RUNS_RECORD ]; + PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS[ NVDATAMGMT_SCHEDULED_RUNS_RECORD ]; U32 startAddress = specs.startAddress; U32 maxBufferLength = specs.maxReadBufferSize; @@ -1810,6 +1900,7 @@ return state; } +#ifdef _DG_ /*********************************************************************//** * @brief * The handleSelfTestReadScheduledRunsRecord reads the scheduled runs @@ -1821,21 +1912,22 @@ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadScheduledRunsRecord( void ) { NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_SCHEDULED_RUNS_RECORD; - BOOL timeoutStatus = didCommandTimeout ( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); + BOOL timeoutStatus = didCommandTimeout( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); - if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) + if ( ( RTC_RAM_STATUS_IDLE == getRTCRAMStatus() ) || ( TRUE == timeoutStatus ) ) { - PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS [ NVDATAMGMT_SCHEDULED_RUNS_RECORD ]; + PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS[ NVDATAMGMT_SCHEDULED_RUNS_RECORD ]; U08* bufferAddress = specs.structAddressPtr; U32 maxBufferLength = specs.maxReadBufferSize; getDataFromRAM( bufferAddress, maxBufferLength ); - state = NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC; + state = NVDATAMGMT_SELF_TEST_STATE_READ_DG_HEATERS_INFO; } return state; } +#endif #ifdef _HD_ /*********************************************************************//** * @brief @@ -1848,16 +1940,16 @@ 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 ); + BOOL timeoutStatus = didCommandTimeout( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); // If the RTC RAM is ready, read the results if ( getRTCRAMStatus() == RTC_RAM_STATUS_IDLE || timeoutStatus == TRUE ) { - getDataFromRAM ( (U08*)&hdUsageInfoGroup, sizeof(HD_USAGE_INFO_RECORD_T) ); + getDataFromRAM( (U08*)&hdUsageInfoGroup, sizeof(HD_USAGE_INFO_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) ); + readFromRAM( LOG_RECORD_START_ADDRESS, sizeof(LOG_RECORD_T) ); currentTime = getMSTimerCount(); state = NVDATAMGMT_SELF_TEST_STATE_READ_LOG_RECORD; } @@ -1869,6 +1961,49 @@ #ifdef _DG_ /*********************************************************************//** * @brief + * The handleSelfTestReadDGHeatersInfo reads the DG heaters information + * from RTC RAM. + * @details Inputs: none + * @details Outputs: dgHeatersInfoGroup + * @return next state + *************************************************************************/ +static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestReadDGHeatersInfo( void ) +{ + NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_READ_DG_HEATERS_INFO; + BOOL timeoutStatus = didCommandTimeout( ALARM_ID_RTC_RAM_OPS_ERROR, (U08*)&state ); + + if ( ( RTC_RAM_STATUS_IDLE == getRTCRAMStatus() ) || ( TRUE == timeoutStatus ) ) + { + PROCESS_RECORD_SPECS_T specs = RECORDS_SPECS[ NVDATAMGMT_HEATERS_INFO_RECORD ]; + U08* bufferAddress = specs.structAddressPtr; + U32 maxBufferLength = specs.maxReadBufferSize; + + getDataFromRAM( bufferAddress, maxBufferLength ); + + // Calculate the CRC of the record + U16 calcCRC = crc16 ( specs.structAddressPtr, specs.sizeofJob - sizeof(U16) ); + U16 recordCRC = *(U16*)specs.structCRCPtr; + + // If the CRCs are not equal, set the average fill flow to 0.0 + // Otherwise, keep the data so it can be used + if ( calcCRC != recordCRC ) + { + dgHeatersInfoGroup.dgHeatersInfo.averageFillFlow = 0.0; + dgHeatersInfoGroup.crc = recordCRC; + } + else + { + memcpy( &dgHeatersInfoGroup, bufferAddress, sizeof( DG_HEATERS_INFO_GROUP_T ) ); + } + + state = NVDATAMGMT_SELF_TEST_STATE_CHECK_CRC; + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleSelfTestReadDGWaterConsumption reads the DG water consumption * from RTC RAM. * @details Inputs: currentTime, waterConsumptionRecord @@ -1881,10 +2016,10 @@ 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 ) + if ( ( RTC_RAM_STATUS_IDLE == getRTCRAMStatus() ) || ( TRUE == timeoutStatus ) ) { getDataFromRAM ( (U08*)&dgUsageInfoGroup, sizeof(DG_USAGE_INFO_RECORD_T) ); - if ( getRTCRAMState() == RTC_RAM_STATE_READY ) + if ( RTC_RAM_STATE_READY == getRTCRAMState() ) { readFromRAM ( LOG_RECORD_START_ADDRESS, sizeof(LOG_RECORD_T) ); currentTime = getMSTimerCount(); @@ -1918,6 +2053,7 @@ currentTime = getMSTimerCount(); // Get ready for reading the manufacturing record + // TODO uncomment. currently not working This section is for phase 1B //Fapi_doMarginRead( (U32*)BANK7_SECTOR0_START_ADDRESS, addr, len, Fapi_NormalRead ); state = NVDATAMGMT_SELF_TEST_STATE_READ_SYS_RECORD; } @@ -1936,20 +2072,24 @@ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestCheckCRC ( void ) { NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_COMPLETE; - BOOL haveCalGroupsPassed = TRUE; - BOOL haveRecordsPassed = TRUE; + BOOL haveCalGroupsPassed = TRUE; + BOOL haveRecordsPassed = TRUE; + BOOL hasSystemRecordPassed = TRUE; + BOOL hasServiceRecordPassed = TRUE; -#ifndef DISABLE_CAL_CHECK // Check the integrity of the records as a whole. Check the upper layer CRC haveRecordsPassed = areRecordsValid(); -#endif #ifdef _DG_ // Check all the calibration groups - haveCalGroupsPassed = isDGCalibrationRecordValid(); + haveCalGroupsPassed = isDGCalibrationRecordValid(); + hasSystemRecordPassed = isDGSystemRecordValid(); + hasServiceRecordPassed = isDGServiceRecordValid(); #endif #ifdef _HD_ - haveCalGroupsPassed = isHDCalibrationRecordValid(); + haveCalGroupsPassed = isHDCalibrationRecordValid(); + hasSystemRecordPassed = isHDSystemRecordValid(); + hasServiceRecordPassed = isHDServiceRecordValid(); #endif // If any of the records did not pass, they should be filled @@ -1961,7 +2101,8 @@ } // Check if the records' entire CRCs as well as the individual CRCs passed - if ( haveCalGroupsPassed && haveRecordsPassed ) + if ( ( TRUE == haveCalGroupsPassed ) && ( TRUE == haveRecordsPassed ) && + ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) ) { nvDataMgmtSelfTestResult = SELF_TEST_STATUS_PASSED; } @@ -2015,7 +2156,7 @@ if ( powerOffIsImminent != TRUE ) { // If the record processing queue is not empty, process the queues - if ( !isRecordQueueEmpty() ) + if ( FALSE == isRecordQueueEmpty() ) { dequeueRecordJob(); @@ -2038,36 +2179,36 @@ } else if ( ops == NVDATAMGMT_READ ) { - maxBufferLength = jobSpecs.maxReadBufferSize; + maxBufferLength = jobSpecs.maxReadBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER; } } // TODO add the log queue later in the future phases. } // Check if a queue job is available - if ( areQueuesNotEmpty ) + if ( TRUE == areQueuesNotEmpty ) { if ( ops == NVDATAMGMT_ERASE_SECTOR ) { - Fapi_issueAsyncCommandWithAddress ( Fapi_EraseSector, (U32*)startAddress ); + Fapi_issueAsyncCommandWithAddress( Fapi_EraseSector, (U32*)startAddress ); state = NVDATAMGMT_EXEC_STATE_ERASE_EEPROM; } else if ( ops == NVDATAMGMT_WRITE && location == NVDATAMGMT_EEPROM ) { - Fapi_issueProgrammingCommand ( (U32*)startAddress, (U08*)bufferAddress, maxBufferLength, 0x00, 0, Fapi_DataOnly ); + Fapi_issueProgrammingCommand( (U32*)startAddress, (U08*)bufferAddress, maxBufferLength, 0x00, 0, Fapi_DataOnly ); state = NVDATAMGMT_EXEC_STATE_WRITE_TO_EEPROM; } else if ( ops == NVDATAMGMT_READ && location == NVDATAMGMT_EEPROM ) { - Fapi_doMarginRead ( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength, Fapi_NormalRead ); + Fapi_doMarginRead( (U32*)startAddress, (U32*)bufferAddress, maxBufferLength / EEPROM_OPS_SIZE_OF_CONVERTER, Fapi_NormalRead ); state = NVDATAMGMT_EXEC_STATE_READ_FROM_EEPROM; } else if ( ops == NVDATAMGMT_WRITE && location == NVDATAMGMT_RTC ) { if ( getRTCRAMState() == RTC_RAM_STATE_READY ) { currentTime = getMSTimerCount(); - writeToRAM ( startAddress, bufferAddress, maxBufferLength ); + writeToRAM( startAddress, bufferAddress, maxBufferLength ); state = NVDATAMGMT_EXEC_STATE_WRITE_TO_RTC; } } @@ -2111,12 +2252,13 @@ { currentTime = getMSTimerCount(); U32 startAddress = jobSpecs.startAddress + recordAddressOffset; + U32 maxBufferLength = jobSpecs.maxWriteBufferSize / EEPROM_OPS_SIZE_OF_CONVERTER; // Clear the buffer from the previous content memset( writtenRecordCheckBuffer, 0, sizeof(writtenRecordCheckBuffer)); // Issue a FAPI read command but only the bytes that were written, so use maxWriteBufferSize - Fapi_doMarginRead ( (U32*)startAddress, (U32*)writtenRecordCheckBuffer, jobSpecs.maxWriteBufferSize, Fapi_NormalRead ); + Fapi_doMarginRead( (U32*)startAddress, (U32*)writtenRecordCheckBuffer, maxBufferLength, Fapi_NormalRead ); state = NVDATAMGMT_EXEC_STATE_VERIFY_EEPROM_WRITE; } @@ -2138,7 +2280,7 @@ writtenRecordStatus = NVDATAMGMT_RECORD_NOT_CHECKED; // Issue the write command - Fapi_issueProgrammingCommand ( (U32*)memoryPtr, structPtr, jobSpecs.maxWriteBufferSize, 0x00, 0, Fapi_DataOnly ); + Fapi_issueProgrammingCommand( (U32*)memoryPtr, structPtr, jobSpecs.maxWriteBufferSize, 0x00, 0, Fapi_DataOnly ); } } } @@ -2436,7 +2578,7 @@ { PROCESS_RECORD_STATE_T state = NVDATAMGMT_PROCESS_RECORD_STATE_IDLE; - if ( hasPublishRecordBeenRequested ) + if ( TRUE == hasPublishRecordBeenRequested ) { // Set the publish flag to FALSE hasPublishRecordBeenRequested = FALSE; @@ -2526,13 +2668,13 @@ #endif break; - case NVDATAMGMT_SCHEDULED_RUNS_RECORD: #ifdef _DG_ + case NVDATAMGMT_SCHEDULED_RUNS_RECORD: // Pass the information to the CAN bus sendDGScheduledRunsRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); -#endif // There are no scheduled runs for HD right now. break; +#endif default: //Ignore @@ -2905,7 +3047,7 @@ *************************************************************************/ static void monitorNewCalSignal( void ) { - if ( didTimeout( newCalStartTimer, NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS ) && ( TRUE == isNewCalAvailable ) ) + if ( ( TRUE == didTimeout( newCalStartTimer, NEW_CAL_AVAILABLE_SIGNAL_TIMEOUT_MS ) ) && ( TRUE == isNewCalAvailable ) ) { isNewCalAvailable = FALSE; } @@ -2921,27 +3063,25 @@ *************************************************************************/ static BOOL areRecordsValid( void ) { - U32 i; - U16 calcCRC; - U16 recordCRC; - PROCESS_RECORD_SPECS_T spec; + ALARM_ID_T alarm; + BOOL status = TRUE; + PROCESS_RECORD_SPECS_T spec = RECORDS_SPECS [ NVDATAMGMT_CALIBRATION_RECORD ]; + U16 calcCRC = crc16 ( spec.structAddressPtr, spec.sizeofJob - sizeof(U16) ); + U16 recordCRC = *(U16*)spec.structCRCPtr; - for ( i = 0; i < NUM_OF_NVDATMGMT_RECORDS_JOBS; i++ ) + // If the CRCs do not match, break out of loop since POST will be failed + // regardless of the rest of the results + if ( calcCRC != recordCRC ) { - spec = RECORDS_SPECS [ i ]; - calcCRC = crc16 ( spec.structAddressPtr, spec.sizeofJob - sizeof(U16) ); - recordCRC = *(U16*)spec.structCRCPtr; - - // If the CRCs do not match, break out of loop since POST will be failed - // regardless of the rest of the results - if ( calcCRC != recordCRC ) - { -#ifndef DISABLE_CAL_CHECK - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_NVDATAMGMT_GROUP_RECORD_CRC_INVALID, i ); - status = FALSE; +#ifdef _DG_ + alarm = ALARM_ID_DG_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID; #endif - } +#ifdef _HD_ + alarm = ALARM_ID_HD_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID; +#endif + activateAlarmNoData( alarm ); + status = FALSE; } return status; @@ -2956,8 +3096,8 @@ * @details Outputs: none * @param record: pointer to a polynomial payload. The actual calibration * data to be checked - * @param isRecordNeeded: TRUE is the calibration record is need in the firmware - * right now otherwise, FALSE + * @param isRecordNeeded: TRUE is the calibration record is need in the + * firmware right now otherwise, FALSE * @return TRUE if the records' data is valid otherwise FALSE *************************************************************************/ static BOOL isPolynomialRecordValid( POLYNOMIAL_CAL_PAYLOAD_T* record ) @@ -2984,10 +3124,122 @@ return status; } +#ifdef _DG_ +/*********************************************************************//** + * @brief + * The setRsrvdCalibrationRecordsToZero function sets the calibration + * records reserved spaces to 0. This is to make sure they are not set + * to NaN. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +static void setRsrvdCalibrationRecordsToZero( void ) +{ + U32 i; + POLYNOMIAL_CAL_PAYLOAD_T* record; + // NOTE: the size of the reserved spaces in each calibration record do not have #define + // because they are based on assumptions and they may be reduced. + // Get the calibration record of the hardware (i.e. pressure sensor) + DG_PRES_SENSORS_CAL_RECORD_T* pressure = &dgCalibrationRecord.dgCalibrationGroups.presSensorsCalRecord; + for ( i = 0; i < 6; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&pressure->reservedSpace[ i ]; + memset( record, 0x0, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) ); + } + + DG_FLOW_SENSORS_CAL_RECORD_T* flow = &dgCalibrationRecord.dgCalibrationGroups.flowSensorsCalRecord; + for ( i = 0; i < 3; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&flow->reservedSpace[ i ]; + memset( record, 0x0, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) ); + } + + DG_TEMP_SENSORS_CAL_RECORD_T* temperature = &dgCalibrationRecord.dgCalibrationGroups.tempSensorsCalRecord; + for ( i = 0; i < 5; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&temperature->reservedSpace[ i ]; + memset( record, 0x0, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) ); + } + + DG_COND_SENSORS_CAL_RECORD_T* conductivity = &dgCalibrationRecord.dgCalibrationGroups.condSensorsCalRecord; + for ( i = 0; i < 2; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&conductivity->reservedSpace[ i ]; + memset( record, 0x0, sizeof(POLYNOMIAL_CAL_PAYLOAD_T) ); + } +} +#endif + #ifdef _DG_ /*********************************************************************//** * @brief + * The isDGSystemRecordValid function checks the validity of the DG system + * record. + * @details Inputs: dgSystemGroup.dgSystemRecord + * @details Outputs: none + * @return TRUE if the DG system record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGSystemRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&dgSystemGroup.dgSystemRecord, sizeof(DG_SYSTEM_RECORD_T) - sizeof(U16) ); + U16 recordCRC = dgSystemGroup.dgSystemRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + dgSystemGroup.dgSystemRecord.mfgDate = 0; + dgSystemGroup.dgSystemRecord.mfgLocation = 0; + memset( dgSystemGroup.dgSystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( dgSystemGroup.dgSystemRecord.topLevelPN ) ); + memset( dgSystemGroup.dgSystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( dgSystemGroup.dgSystemRecord.topLevelPN ) ); + // Recalculate the CRC with the default values + dgSystemGroup.dgSystemRecord.crc = crc16 ( (U08*)&dgSystemGroup.dgSystemRecord, sizeof(DG_SYSTEM_RECORD_T) - sizeof(U16) ); + + activateAlarmNoData( ALARM_ID_DG_INVALID_SYSTEM_RECORD_CRC ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The isDGServiceRecordValid function checks the validity of the DG service + * record. + * @details Inputs: dgServiceGroup.dgServiceRecord + * @details Outputs: none + * @return TRUE if the DG service record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGServiceRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&dgServiceGroup.dgServiceRecord, sizeof(DG_SERVICE_RECORD_T) - sizeof(U16) ); + U16 recordCRC = dgServiceGroup.dgServiceRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + dgServiceGroup.dgServiceRecord.lastServiceEpochDate = 0; + dgServiceGroup.dgServiceRecord.serviceIntervalSeconds = RECORD_DEFAULT_SERVICE_INTERVAL_S; + // Recalculate the CRC with the default values + dgServiceGroup.dgServiceRecord.crc = crc16 ( (U08*)&dgServiceGroup.dgServiceRecord, sizeof(DG_SERVICE_RECORD_T) - sizeof(U16) ); + + // Service record failure is also considered as RTC RAM failure + activateAlarmNoData( ALARM_ID_DG_INVALID_SERVICE_RECORD_CRC ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +/*********************************************************************//** + * @brief * The isDGCalibrationRecordValid function calls other functions to check * the validity of DG calibration record. * @details Inputs: dgCalibrationRecord @@ -3018,9 +3270,12 @@ } DG_FLOW_SENSORS_CAL_RECORD_T* flow = &dgCalibrationRecord.dgCalibrationGroups.flowSensorsCalRecord; - record = (POLYNOMIAL_CAL_PAYLOAD_T*)&flow->flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ]; - isHardwareRecordValid = isPolynomialRecordValid( record ); - isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + for ( i = 0; i < NUM_OF_CAL_DATA_FLOW_SENSORS; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&flow->flowSensors[ i ]; + isHardwareRecordValid = isPolynomialRecordValid( record ); + isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + } DG_LOAD_CELLS_CAL_RECORD_T* load = &dgCalibrationRecord.dgCalibrationGroups.loadCellsCalRecord; for ( i = 0; i < NUM_OF_CAL_DATA_LOAD_CELLS; i++ ) @@ -3061,6 +3316,10 @@ isHardwareRecordValid = isDGROPumpRecordValid( roPump ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + DG_PRE_RO_PURGE_VOLUME_T* preROPurgeVolume = &dgCalibrationRecord.dgCalibrationGroups.preROPurgeVolumeRecord; + isHardwareRecordValid = isDGPreROPurgeVolumeRecordValid( preROPurgeVolume ); + isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + DG_DRAIN_LINE_VOLUME_T* drainLineVol = &dgCalibrationRecord.dgCalibrationGroups.drainLineVolumeRecord; isHardwareRecordValid = isDGDrainLineVolRecordValid( drainLineVol ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; @@ -3124,6 +3383,14 @@ isHardwareRecordValid = isDGAccelerometerSensorRecordValid( accelerometer ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + // If the sub groups failed, they are all updated to their benign values + // so the main CRC of the calibration group is calculated again + if ( FALSE == isCalRecordValid ) + { + U16 finalCRC = crc16 ( (U08*)&dgCalibrationRecord, sizeof(DG_CALIBRATION_RECORD_T) - sizeof(U16) ); + dgCalibrationRecord.crc = finalCRC; + } + return isCalRecordValid; } @@ -3219,6 +3486,36 @@ /*********************************************************************//** * @brief + * The isDGPreROPurgeVolumeRecordValid function checks whether the + * calibration record of pre RO purge is valid or not. + * @details Inputs: none + * @details Outputs: none + * @param record: DG_PRE_RO_PURGE_VOLUME_T pointer + * @return TRUE if the record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGPreROPurgeVolumeRecordValid( DG_PRE_RO_PURGE_VOLUME_T* record ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16 ( (U08*)record, sizeof(DG_PRE_RO_PURGE_VOLUME_T) - sizeof(U16) ); + U16 recordCRC = record->crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + record->pressure2FlowRatio = RECORD_DEFAULT_RATIO; + record->volume = RECORD_DEFAULT_CONST; + record->calibrationTime = RECORD_DEFAULT_TIME; + record->crc = crc16 ( (U08*)record, sizeof(DG_PRE_RO_PURGE_VOLUME_T) - sizeof(U16) ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +/*********************************************************************//** + * @brief * The isDGDrainLineVolRecordValid function checks whether the calibration * record of drain line volume is valid or not. * @details Inputs: none @@ -3235,7 +3532,7 @@ if ( calcCRC != recordCRC ) { // CRC did not pass so set all values to default - record->volume = RECORD_DEFAULT_CONST; + record->volume = FLUSH_LINES_DEFAULT_VOLUME_L; record->calibrationTime = RECORD_DEFAULT_TIME; record->crc = crc16 ( (U08*)record, sizeof(DG_DRAIN_LINE_VOLUME_T) - sizeof(U16) ); @@ -3298,7 +3595,6 @@ // CRC did not pass so set all values to default record->volume = RECORD_DEFAULT_CONST; record->calibrationTime = RECORD_DEFAULT_TIME; - record->crc = crc16 ( (U08*)record, sizeof(DG_GENERIC_VOLUME_DATA_T) - sizeof(U16) ); // Set the to FALSE since the record is not valid status = FALSE; @@ -3327,7 +3623,7 @@ // CRC did not pass so set all values to default record->startVolume = RECORD_DEFAULT_CONST; record->reserverdSpace = RECORD_DEFAULT_CONST; - record->acidConcMixRatio = RECORD_DEFAULT_RATIO; + record->acidConcMixRatio = ACID_CONC_DEFAULT_MIXING_RATIO; record->calibrationTime = RECORD_DEFAULT_TIME; record->crc = crc16 ( (U08*)record, sizeof(DG_ACID_CONCENTRATE_T) - sizeof(U16) ); @@ -3358,13 +3654,10 @@ // CRC did not pass so set all values to default record->startVolume = RECORD_DEFAULT_CONST; record->reservedSpace = RECORD_DEFAULT_CONST; - record->bicarbConcMixRatio = RECORD_DEFAULT_RATIO; + record->bicarbConcMixRatio = BICARB_CONC_DEFAULT_MIXING_RATIO; record->calibrationTime = RECORD_DEFAULT_TIME; record->crc = crc16 ( (U08*)record, sizeof(DG_BICARB_CONCENTRATE_T) - sizeof(U16) ); - // Alarm if the CRC did not pass - activateAlarmNoData( ALARM_ID_NVDATAMGMT_INDIVIDUAL_RECORD_CRC_INVALID ); - // Set the to FALSE since the record is not valid status = FALSE; } @@ -3467,6 +3760,70 @@ #ifdef _HD_ /*********************************************************************//** * @brief + * The isHDSystemRecordValid function checks the validity of the HD system + * record. + * @details Inputs: hdSystemGroup.hdsystemRecord + * @details Outputs: none + * @return TRUE if the HD system record is valid otherwise FALSE + *************************************************************************/ +static BOOL isHDSystemRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&hdSystemGroup.hdsystemRecord, sizeof( HD_SYSTEM_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = hdSystemGroup.hdsystemRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + hdSystemGroup.hdsystemRecord.mfgDate = 0; + hdSystemGroup.hdsystemRecord.mfgLocation = 0; + memset( hdSystemGroup.hdsystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( hdSystemGroup.hdsystemRecord.topLevelPN ) ); + memset( hdSystemGroup.hdsystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( hdSystemGroup.hdsystemRecord.topLevelPN ) ); + // Recalculate the CRC with the default values + hdSystemGroup.hdsystemRecord.crc = crc16 ( (U08*)&hdSystemGroup.hdsystemRecord, sizeof( HD_SYSTEM_RECORD_T ) - sizeof( U16 ) ); + + activateAlarmNoData( ALARM_ID_HD_INVALID_SYSTEM_RECORD_CRC ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} + +/*********************************************************************//** + * @brief + * The isHDServiceRecordValid function checks the validity of the HD service + * record. + * @details Inputs: hdServiceGroup.hdServiceRecord + * @details Outputs: none + * @return TRUE if the HD service record is valid otherwise FALSE + *************************************************************************/ +static BOOL isHDServiceRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&hdServiceGroup.hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = hdServiceGroup.hdServiceRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + hdServiceGroup.hdServiceRecord.lastServiceEpochDate = 0; + hdServiceGroup.hdServiceRecord.serviceIntervalSeconds = RECORD_DEFAULT_SERVICE_INTERVAL_S; + // Recalculate the CRC with the default values + hdServiceGroup.hdServiceRecord.crc = crc16 ( (U08*)&hdServiceGroup.hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ) - sizeof( U16 ) ); + + // Service record failure is also considered as RTC RAM failure + activateAlarmNoData( ALARM_ID_HD_INVALID_SERVICE_RECORD_CRC ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} +/*********************************************************************//** + * @brief * The isHDCalibrationRecordValid function checks whether HD calibration * record is valid or not. * @details Inputs: none @@ -3740,7 +4097,6 @@ enqueueRecordJob( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_EEPROM, NVDATAMGMT_CALIBRATION_RECORD ); enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, NVDATAMGMT_CALIBRATION_RECORD ); enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_EEPROM, NVDATAMGMT_SYSTEM_RECORD ); - status = TRUE; }