Index: NVDataMgmt.c =================================================================== diff -u -r448294501a7a561274286907e9c20ab2400daff3 -rc0e7b9287da8b31bcb7d74c937f60ad263eeb710 --- NVDataMgmt.c (.../NVDataMgmt.c) (revision 448294501a7a561274286907e9c20ab2400daff3) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision c0e7b9287da8b31bcb7d74c937f60ad263eeb710) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 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) Dara Navaei +* @date (last) 03-Nov-2021 * -* @author (original) Dara Navaei -* @date (original) 12-Feb-2020 +* @author (original) Dara Navaei +* @date (original) 12-Feb-2020 * ***************************************************************************/ @@ -78,6 +78,7 @@ #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 divided by 4. @@ -134,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. @@ -196,6 +198,7 @@ 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; @@ -326,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_ @@ -394,12 +407,14 @@ 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 ] = { {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 @@ -463,6 +478,7 @@ 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 ); @@ -697,6 +713,10 @@ 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: @@ -1691,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; @@ -1714,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 @@ -1855,15 +1914,15 @@ 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 ); - 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 ]; 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; @@ -1902,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 @@ -2961,35 +3063,25 @@ *************************************************************************/ static BOOL areRecordsValid( void ) { - U32 i; - U16 calcCRC; - U16 recordCRC; - PROCESS_RECORD_SPECS_T spec; + ALARM_ID_T alarm; + BOOL status = TRUE; - BOOL isCheckRequired = 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 ) { #ifdef _DG_ - // Scheduled runs are not part this phase but it is part of the enums - // so they are ignored during checking - isCheckRequired = ( NVDATAMGMT_SCHEDULED_RUNS_RECORD == i ? FALSE : TRUE ); + alarm = ALARM_ID_DG_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID; #endif - if ( TRUE == isCheckRequired ) - { - 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 ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_NVDATAMGMT_GROUP_RECORD_CRC_INVALID, i ); - status = FALSE; - } - } - +#ifdef _HD_ + alarm = ALARM_ID_HD_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID; +#endif + activateAlarmNoData( alarm ); + status = FALSE; } return status; @@ -3105,7 +3197,7 @@ // 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 ); + activateAlarmNoData( ALARM_ID_DG_INVALID_SYSTEM_RECORD_CRC ); // Set the to FALSE since the record is not valid status = FALSE; @@ -3137,7 +3229,7 @@ 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 ); + activateAlarmNoData( ALARM_ID_DG_INVALID_SERVICE_RECORD_CRC ); // Set the to FALSE since the record is not valid status = FALSE; @@ -3178,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++ ) @@ -3563,9 +3658,6 @@ 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; }