Index: NVDataMgmt.c =================================================================== diff -u -rd62b73b3f8d61512d86ba9e44342f95dad0f2f2f -r364e0ff6df6a25257cf60be7578559814f5033f9 --- NVDataMgmt.c (.../NVDataMgmt.c) (revision d62b73b3f8d61512d86ba9e44342f95dad0f2f2f) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision 364e0ff6df6a25257cf60be7578559814f5033f9) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2020-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2025 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 * * @author (last) Dara Navaei -* @date (last) 11-May-2023 +* @date (last) 27-May-2025 * * @author (original) Dara Navaei * @date (original) 12-Feb-2020 @@ -23,6 +23,9 @@ #include "system.h" // For fapi operations #include "F021.h" // For fapi operations +#ifdef _HD_ +#include "ModeTreatmentParams.h" +#endif #include "MsgQueues.h" #include "NVDataMgmt.h" #include "OperationModes.h" @@ -43,7 +46,7 @@ #define QUEUE_MAX_SIZE 20U ///< Max queue size. #define QUEUE_START_INDEX 0U ///< Queue start index. #define MIN_JOBS_NEEDED_FOR_DATA_LOG 3U ///< Min queue required for data log (3). -#define MIN_JOBS_NEEDED_FOR_SECTOR_0 4U ///< Min queue count needed to write all (4) records back in sector 0. +#define MIN_JOBS_NEEDED_FOR_SECTOR_0 5U ///< Min queue count needed to erase and write all (5) records back in sector 0. #define MAX_NUM_OF_WRITE_TRIES 3U ///< Max number of write tries. // The clock frequency comes from HCLK_FREQ and it has to be rounded up to the nearest number @@ -76,14 +79,15 @@ #define MAX_NUM_OF_EVENTS_IN_SECTOR1 ((MAX_NUM_OF_SECTORS_FOR_LOG_DATA - 2) * MAX_LOG_DATA_PER_SECTOR) ///< Max number of accumulated logs in sector 1 (512). // Data addresses and length in RTC RAM -#define LOG_RECORD_START_ADDRESS 0x00000000 // 0 ///< Log record start address in RTC RAM (0). -#define HD_USAGE_INFO_START_ADDRESS 0x00000010 // 16 ///< HD usage info start address in RTC RAM (16). -#define DG_USAGE_INFO_START_ADDRESS 0x00000030 // 48 ///< DG usage info start address in RTC RAM (48). +#define LOG_RECORD_START_ADDRESS 0x00000000 /* 0 */ ///< Log record start address in RTC RAM (0). +#define HD_USAGE_INFO_START_ADDRESS 0x00000010 /* 16 */ ///< HD usage info start address in RTC RAM (16). +#define DG_USAGE_INFO_START_ADDRESS 0x00000030 /* 48 */ ///< DG usage info start address in RTC RAM (48). #define DG_SCHEDULED_RUNS_START_ADDRESS (DG_USAGE_INFO_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 SW_CONFIGS_START_ADDRESS 0x00000100 // 256 ///< Software configurations start address in RTC RAM. +#define SW_CONFIGS_START_ADDRESS 0x00000100 /* 256 */ ///< Software configurations start address in RTC RAM. #define COMMAND_TIME_OUT (1 * MS_PER_SECOND) ///< 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. #define EEPROM_OPS_SIZE_OF_CONVERTER 4 @@ -96,6 +100,7 @@ #define SYSTEM_RECORD_NV_MEM_START_ADDRESS (BANK7_SECTOR0_START_ADDRESS) ///< System record storage start address in NV memory. #define SERVICE_RECORD_NV_MEM_START_ADDRESS (BANK7_SECTOR0_START_ADDRESS + BITS_12_FULL_SCALE) ///< Service record storage start address in NV memory. #define CAL_RECORD_NV_MEM_START_ADDRESS (SERVICE_RECORD_NV_MEM_START_ADDRESS + BITS_12_FULL_SCALE) ///< Calibration record storage start address in NV memory. +#define INSTIT_RECORD_NV_MEM_START_ADDRESS (CAL_RECORD_NV_MEM_START_ADDRESS + BITS_12_FULL_SCALE) ///< Institutional 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 struct size. @@ -105,7 +110,7 @@ // to round up. The result is then multiplied by 16 bytes to get the number of bytes needed and is subtracted from the size of the structure and CRC. #define RECORD_PADDING_LENGTH(rcrd, buf) (RECORD_BYTE_SIZE(rcrd) % buf == 0 ? 0 : \ ((((RECORD_BYTE_SIZE(rcrd) / buf) + 1)) * buf) \ - - RECORD_BYTE_SIZE(rcrd)) /// DG padding length macro. + - RECORD_BYTE_SIZE(rcrd)) ///< DG padding length macro. #define RECORD_DEFAULT_TIME 0U ///< Record default time (calibration/set). #define RECORD_FOURTH_ORDER_COEFF 0.0F ///< Record fourth order coefficient. @@ -125,6 +130,10 @@ #ifdef _HD_ #define DEFAULT_BLOOD_LEAK_SET_POINT 20 ///< Blood leak default set point. #define DEFAULT_HEPARIN_PUMP_VOLTAGE 0.15F ///< Heparin pump default voltage. +#define DEFAULT_ENABLE_CHEM_DISINFECT 0 ///< Disable chemical disinfect in institutional record. +#define DEFAULT_MAX_RO_REJECTION_RATIO_PCT 90 ///< Max RO rejection ratio in percent. +#define DEFAULT_MIN_INLET_WATER_COND_ALARM_US_P_CM 200.0F ///< Min inlet water conductivity alarm limit in uS/cm. +#define DEFAULT_MIN_VEN_WIDE_WINDOW_LIMIT_MMHG 0 ///< Min venous wide window limit in mmHG. #endif // DG specific defines @@ -138,23 +147,25 @@ #define DEFAULT_ACID_BOTTLE_VOL_ML 3430.0F ///< Record default acid bottle volume in milliliters. #define DEFAULT_ACID_COND_US_PER_CM 11645.05F ///< Record default acid conductivity in uS/cm. #define DEFAULT_ACID_BOTTLE_TEMP_C 23.5F ///< Record default acid bottle temperature in C. -#define DEFAULT_RSRVR_TEMP_TAU_C_PER_MIN -0.512F ///< Reservoir temperature time constant C/min. -#define DEFAULT_UF_TEMP_TAU_C_PER_MIN -4.565F ///< Ultrafilter temperature time constant C/min. +#define DEFAULT_RSRVR_TEMP_TAU_C_PER_MIN -0.25F ///< Reservoir temperature time constant C/min. +#define DEFAULT_UF_TEMP_TAU_C_PER_MIN -0.6F ///< Ultrafilter temperature time constant C/min. #define DEFAULT_UF_VOLUME_ML 700 ///< Ultrafilter volume in milliliters. -#define DEFAULT_FILL_1251_1_ACID_SNSR_US_PER_CM 11518.05F ///< Fill acid 1251_1 acid sensor conductivity uS/cm. +#define DEFAULT_FILL_1251_1_ACID_SNSR_US_PER_CM 0.0F ///< Fill acid 1251_1 acid sensor conductivity uS/cm. #define DEFAULT_FILL_1251_1_BIC_SNSR_US_PER_CM 13616.23F ///< Fill acid 1251_1 bicarb sensor conductivity uS/cm. -#define DEFAULT_FILL_2251_0_ACID_SNSR_US_PER_CM 11645.05F ///< Fill acid 2251_0 acid sensor conductivity uS/cm. +#define DEFAULT_FILL_2251_0_ACID_SNSR_US_PER_CM 0.0F ///< Fill acid 2251_0 acid sensor conductivity uS/cm. #define DEFAULT_FILL_2251_0_BIC_SNSR_US_PER_CM 13734.88F ///< Fill acid 2251_0 bicarb sensor conductivity uS/cm. -#define DEFAULT_FILL_3251_9_ACID_SNSR_US_PER_CM 11773.1F ///< Fill acid 3251_9 acid sensor conductivity uS/cm. +#define DEFAULT_FILL_3251_9_ACID_SNSR_US_PER_CM 0.0F ///< Fill acid 3251_9 acid sensor conductivity uS/cm. #define DEFAULT_FILL_3251_9_BIC_SNSR_US_PER_CM 13854.49F ///< Fill acid 3251_9 bicarb sensor conductivity uS/cm. -#define DEFAULT_ACID_TEST_1251_1_US_PER_CM 12118.71F ///< Acid test acid 1251_1 acid conductivity uS/cm. -#define DEFAULT_ACID_TEST_2251_0_US_PER_CM 12252.1F ///< Acid test acid 2251_0 acid conductivity uS/cm. -#define DEFAULT_ACID_TEST_3251_9_US_PER_CM 12386.57F ///< Acid acid 3251_9 acid conductivity uS/cm. +#define DEFAULT_ACID_TEST_1251_1_US_PER_CM 13768.28F ///< Acid test acid 1251_1 acid conductivity uS/cm. +#define DEFAULT_ACID_TEST_2251_0_US_PER_CM 13919.05F ///< Acid test acid 2251_0 acid conductivity uS/cm. +#define DEFAULT_ACID_TEST_3251_9_US_PER_CM 14071.04F ///< Acid acid 3251_9 acid conductivity uS/cm. #define DEFAULT_BIC_TEST_ACID_SNSR_US_PER_CM 0.0F ///< Bicarb test acid sensor conductivity uS/cm. #define DEFAULT_BIC_TEST_BIC_SNSR_US_PER_CM 3890.0F ///< Bicarb test bicarb sensor conductivity uS/cm. + +#define DEFAULT_COND_SENSOR_TEMP_COMP_COEEF 0.0207F ///< Conductivity sensor temperature compensation coefficient. #endif /// NVDataMgmt self-test states enumeration. @@ -297,6 +308,7 @@ DG_LOAD_CELLS_CAL_RECORD_T loadCellsCalRecord; ///< DG load cells. DG_TEMP_SENSORS_CAL_RECORD_T tempSensorsCalRecord; ///< DG temperature sensors. DG_COND_SENSORS_CAL_RECORD_T condSensorsCalRecord; ///< DG conductivity sensors. + DG_COND_SENSORS_TEMP_COMP_CAL_RECORD_T condSensorsTempCompCalRecord; ///< DG conductivity sensors temperature compensation. DG_CONC_PUMPS_CAL_RECORD_T concentratePumpsRecord; ///< DG concentrate pumps. DG_DRAIN_PUMP_CAL_RECORD_T drainPumpRecord; ///< DG drain pump. DG_RO_PUMP_CAL_RECORD_T roPumpRecord; ///< DG RO pump. @@ -310,6 +322,7 @@ DG_FANS_CAL_RECORD_T fansRecord; ///< DG fans. DG_ACCEL_SENSOR_CAL_RECORD_T accelerometerSensorCalRecord; ///< DG accelerometer sensor. DG_HEATING_CAL_RECORD_T heatingCalRecord; ///< DG heating calibration record. + DG_CHEMICALS_FILL_COND_CAL_RECORD_T fillCondCalRecord; ///< DG fill acid/bicarb target conductivities calibration record. } DG_CALIBRATION_GROUPS_T; /// DG calibration records structure @@ -407,18 +420,26 @@ typedef struct { HD_SERVICE_RECORD_T hdServiceRecord; ///< HD service record. - U08 padding[ RECORD_PADDING_LENGTH(HD_SERVICE_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) ]; ///< HD service group padding. + U08 padding[ RECORD_PADDING_LENGTH(HD_SERVICE_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< HD service group padding. U16 crc; ///< CRC for the HD service structure. } HD_SERVICE_GROUP_T; /// HD usage info record structure typedef struct { HD_USAGE_INFO_RECORD_T hdUsageInfo; ///< HD usage info record. - U08 padding[ RECORD_PADDING_LENGTH(HD_USAGE_INFO_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) ]; ///< HD scheduled run group padding. + U08 padding[ RECORD_PADDING_LENGTH(HD_USAGE_INFO_RECORD_T, MAX_RTC_RAM_OPS_BUFFER_BYTES) ]; ///< HD usage info group padding. U16 crc; ///< CRC for the HD usage info structure. } HD_USAGE_INFO_GROUP_T; +/// HD institutional record structure +typedef struct +{ + HD_INSTITUTIONAL_RECORD_T hdInstitutionalRecord; ///< HD institutional record. + U08 padding[ RECORD_PADDING_LENGTH(HD_INSTITUTIONAL_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< HD institutional group padding. + U16 crc; ///< CRC for the HD institutional structure. +} HD_INSTITUTIONAL_GROUP_T; + #ifndef _RELEASE_ /// HD software configurations group typedef struct @@ -445,22 +466,18 @@ static DG_SW_CONFIG_GROUP_T dgSWConfigGroup; ///< DG Software configurations structure(including padding and final CRC). #endif -// TODO this is temporary until it is added to the cal records -static DG_CHEMICALS_FILL_COND_CAL_RECORD_T tempChemsRecordRemove; -// TODO this is temporary until it is added to the cal records - // Process records specifications const PROCESS_RECORD_SPECS_T RECORDS_SPECS[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { // Start address Size of the job Max write bytes per job Max read bytes per job Record structure pointer Record CRC pointer Memory location Event calibration record update {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_EEPROM, DG_EVENT_CAL_RECORD_UPDATE }, // 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_EEPROM, DG_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DG_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DG_SERVICE_GROUP_T), (U08*)&dgServiceGroup, (U08*)&dgServiceGroup.crc, NVDATAMGMT_EEPROM, DG_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD -#ifndef _RELEASE_ - {SW_CONFIGS_START_ADDRESS, sizeof(DG_SW_CONFIG_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgSWConfigGroup, (U08*)&dgSWConfigGroup.crc, NVDATAMGMT_RTC, DG_EVENT_SW_CONFIG_UPDATE }, // NVDATAMGMT_SW_CONFIG_RECORD -#endif {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_RTC, DG_EVENT_SCHEDULED_RUNS_UPDATE }, // 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_RTC, DG_EVENT_HEATERS_INFO_UPDATE }, // NVDATAMGMT_HEATERS_INFO_RECORD - {DG_USAGE_INFO_START_ADDRESS, sizeof(DG_USAGE_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgUsageInfoGroup, (U08*)&dgUsageInfoGroup.crc, NVDATAMGMT_RTC, DG_EVENT_USAGE_INFO_UPDATE } // NVDATAMGMT_USAGE_INFO_RECORD + {DG_USAGE_INFO_START_ADDRESS, sizeof(DG_USAGE_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgUsageInfoGroup, (U08*)&dgUsageInfoGroup.crc, NVDATAMGMT_RTC, DG_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO_RECORD +#ifndef _RELEASE_ + {SW_CONFIGS_START_ADDRESS, sizeof(DG_SW_CONFIG_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&dgSWConfigGroup, (U08*)&dgSWConfigGroup.crc, NVDATAMGMT_RTC, DG_EVENT_SW_CONFIG_UPDATE } // NVDATAMGMT_SW_CONFIG_RECORD +#endif }; #endif @@ -469,19 +486,21 @@ static HD_SYSTEM_GROUP_T hdSystemGroup; ///< HD system group structure (including padding and final CRC). static HD_SERVICE_GROUP_T hdServiceGroup; ///< HD service group structure (including padding and final CRC). static HD_USAGE_INFO_GROUP_T hdUsageInfoGroup; ///< HD usage info group structure (including padding and final CRC). +static HD_INSTITUTIONAL_GROUP_T hdInstitutionalGroup; ///< HD institutional group structure (including padding and final CRC). #ifndef _RELEASE_ static HD_SW_CONFIG_GROUP_T hdSWConfigGroup; ///< HD Software configurations structure(including padding and final CRC). #endif // Process records specifications const PROCESS_RECORD_SPECS_T RECORDS_SPECS [ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { - // Start address Size of the job Max write bytes per job Max read bytes per job Record structure pointer Record CRC pointer Memory location Event calibration record update - {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_CALIBRATION_RECORD_T), (U08*)&hdCalibrationRecord, (U08*)&hdCalibrationRecord.crc, NVDATAMGMT_EEPROM, HD_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD - {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_SYSTEM_GROUP_T), (U08*)&hdSystemGroup, (U08*)&hdSystemGroup.crc, NVDATAMGMT_EEPROM, HD_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD - {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_SERVICE_GROUP_T), (U08*)&hdServiceGroup, (U08*)&hdServiceGroup.crc, NVDATAMGMT_EEPROM, HD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_PROCESS_LAST_SERVICE_RECORD + // Start address Size of the job Max write bytes per job Max read bytes per job Record structure pointer Record CRC pointer Memory location Event calibration record update + {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_CALIBRATION_RECORD_T), (U08*)&hdCalibrationRecord, (U08*)&hdCalibrationRecord.crc, NVDATAMGMT_EEPROM, HD_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD + {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_SYSTEM_GROUP_T), (U08*)&hdSystemGroup, (U08*)&hdSystemGroup.crc, NVDATAMGMT_EEPROM, HD_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD + {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_SERVICE_GROUP_T), (U08*)&hdServiceGroup, (U08*)&hdServiceGroup.crc, NVDATAMGMT_EEPROM, HD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD + {INSTIT_RECORD_NV_MEM_START_ADDRESS, sizeof(HD_INSTITUTIONAL_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(HD_INSTITUTIONAL_GROUP_T), (U08*)&hdInstitutionalGroup, (U08*)&hdInstitutionalGroup.crc, NVDATAMGMT_EEPROM, HD_EVENT_INSTIT_RECORD_UPDATE }, // NVDATAMGMT_INTITUTIONAL_RECORD + {HD_USAGE_INFO_START_ADDRESS, sizeof(HD_USAGE_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdUsageInfoGroup, (U08*)&hdUsageInfoGroup.crc, NVDATAMGMT_RTC, HD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO #ifndef _RELEASE_ - {SW_CONFIGS_START_ADDRESS, sizeof(HD_SW_CONFIG_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdSWConfigGroup, (U08*)&hdSWConfigGroup.crc, NVDATAMGMT_RTC, HD_EVENT_SW_CONFIG_UPDATE }, // NVDATAMGMT_SW_CONFIG_RECORD + {SW_CONFIGS_START_ADDRESS, sizeof(HD_SW_CONFIG_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdSWConfigGroup, (U08*)&hdSWConfigGroup.crc, NVDATAMGMT_RTC, HD_EVENT_SW_CONFIG_UPDATE } // NVDATAMGMT_SW_CONFIG_RECORD #endif - {HD_USAGE_INFO_START_ADDRESS, sizeof(HD_USAGE_INFO_GROUP_T), MAX_RTC_RAM_OPS_BUFFER_BYTES, MAX_RTC_RAM_OPS_BUFFER_BYTES, (U08*)&hdUsageInfoGroup, (U08*)&hdUsageInfoGroup.crc, NVDATAMGMT_RTC, HD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO }; #endif @@ -509,7 +528,9 @@ static MEMORY_LOG_OPS_T currentJob; ///< Current job. static LOG_RECORD_T logRecord; ///< Log record variable. static U08 queueRearIndex; ///< Queue rear index. +#ifdef ENABLE_LOCAL_LOGGING static U08 queueFrontIndex; ///< Queue front index. +#endif static U08 queueCount; ///< Queue count. static NVDATAMGMT_SELF_TEST_STATE_T nvDataMgmtSelfTestState; ///< NVDataMgmt self-test state variable. static NVDATAMGMT_EXEC_STATE_T nvDataMgmtExecState; ///< NVDataMgmt exec state variable. @@ -544,10 +565,12 @@ U32 startAddress, U08* data, READ_DATA_T* extAddress, U32 length ); static void enqueue( NVDATAMGMT_OPERATION_STATE_T ops, NVDATAMGMT_LOCATION_STATE_T location, U32 startAddress, U08* data, READ_DATA_T* extAddress, U32 length ); +#ifdef ENABLE_LOCAL_LOGGING static void dequeue( void ); +static BOOL isQueueEmpty( void ); +#endif static U32 prepareWriteLogJobAndGetStartAddress( U08* data ); static U32 prepareReadLogJobAndGetStartAddress( void ); -static BOOL isQueueEmpty( void ); static BOOL isQueueFull( void ); static U32 getAvailableQueueCount( void ); @@ -577,7 +600,6 @@ static BOOL isDGServiceRecordValid( void ); static BOOL isDGUsageRecordValid( 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 ); @@ -590,14 +612,16 @@ static BOOL isDGFanRecordValid( DG_FAN_CAL_RECORD_T* record ); static BOOL isDGAccelerometerSensorRecordValid( DG_ACCEL_SENSOR_CAL_RECORD_T* record ); static BOOL isDGHeatingCalRecordValid( DG_HEATING_CAL_RECORD_T* record ); -static BOOL isDGFillConductiviesRecordValid( DG_ACID_BICARB_FILL_COND_VALUES_T* record, DG_FILL_COND_OPS_T test, DG_ACID_TYPES_T acidType ); +static BOOL isDGFillConductiviesRecordValid( DG_ACID_BICARB_FILL_COND_VALUES_T* record, DG_ACID_TYPES_T acidType, DG_FILL_COND_OPS_T operation ); +static BOOL isDGCondSensorsTemperatureCompensationRecordValid( DG_COND_SENSOR_TEMP_COMP_CAL_PAYLOAD_T* record ); #endif #ifdef _HD_ static BOOL isHDSystemRecordValid( void ); static BOOL isHDServiceRecordValid( void ); static BOOL isHDUsageRecordValid( void ); static BOOL isHDCalibrationRecordValid( void ); +static BOOL isHDInstitutionalRecordValid( void ); static BOOL isHDValveRecordValid( HD_VALVE_CAL_PAYLOAD_T* record ); static BOOL isHDPumpRecordValid( HD_PUMP_CAL_PAYLOAD_T* record ); static BOOL isHDAccelerometerSensorValid( HD_ACCELEROMETER_SENSOR_CAL_RECORD_T* record ); @@ -627,7 +651,9 @@ nvDataMgmtExecProcessRecordState = NVDATAMGMT_PROCESS_RECORD_STATE_IDLE; nvDataMgmtExecReceiveRecordState = NVDATAMGMT_RECEIVE_RECORD_IDLE; queueRearIndex = QUEUE_START_INDEX; +#ifdef ENABLE_LOCAL_LOGGING queueFrontIndex = QUEUE_START_INDEX; +#endif queueCount = 0; recordUpdateAddress = 0; recordQueueRearIndex = QUEUE_START_INDEX; @@ -883,12 +909,23 @@ // and 0 everything out since we are done writing if ( currentMessage == totalMessages ) { - U16 calcCRC = crc16 ( recordSpec.structAddressPtr, recordSpec.sizeofJob - sizeof(U16) ); + // Assume the institutional record is fine unless the record is really the institutional record + BOOL isInstRcrdValid = TRUE; + 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; + U16 recordCRC = *(U16*)recordSpec.structCRCPtr; - if ( calcCRC != recordCRC ) +#ifdef _HD_ + if ( NVDATAMGMT_INTITUTIONAL_RECORD == job ) + { + isInstRcrdValid = isNVInstitutionalRecordInRange( &hdInstitutionalGroup.hdInstitutionalRecord ); + status = isInstRcrdValid; + } +#endif + + if ( ( calcCRC != recordCRC ) || ( FALSE == isInstRcrdValid ) ) { + // Institutional record has failed so do not write it into the NV memory and read back what was in the NV memory // CRC failed, request a read to read the data back from NV memory and update the structure enqueueRecordJob( NVDATAMGMT_READ, recordSpec.dataLoc, job ); @@ -902,14 +939,28 @@ // CRC passed, enqueue an erase, a write of calibration data and a write of service record BOOL scheduleStatus = enqueueSector0Records(); +#ifdef _HD_ + MESSAGE_T institMsg; + // Got new data for the EEPROM records, set the latest institutional record to treatment parameters to make sure + // the treatment parameters have the record available all the time + setNVInstitutionalRecordToTxParamsRecord( &hdInstitutionalGroup.hdInstitutionalRecord ); + + // Received new institutional record and it is valid, send it to the UI to be up to date + institMsg.hdr.msgID = 0; + institMsg.hdr.payloadLen = 0; + handleSendInstitutionalRecordToUI( &institMsg ); + // Received new institutional record and it is valid, send it to the DG to be up to date + handleDGRequestInstitutionalValues( &institMsg ); +#endif + // Signal that there is a new calibration record available. // NOTE: as of now, this signal will be sent even after the system record is sent - newCalStartTimer = getMSTimerCount(); - isNewCalAvailable = TRUE; + newCalStartTimer = getMSTimerCount(); + isNewCalAvailable = TRUE; } else { - // CRC passed write the last service record to the RTC RAM + // CRC passed write the last record to the RTC RAM enqueueRecordJob( NVDATAMGMT_WRITE, recordSpec.dataLoc, job ); } @@ -1077,6 +1128,11 @@ nvDataLength = sizeof( hdUsageInfoGroup.hdUsageInfo ); break; + case GET_INSTITUTIONAL_RECORD: + nvDataStartPtr = (U08*)&hdInstitutionalGroup.hdInstitutionalRecord; + nvDataLength = sizeof( hdInstitutionalGroup.hdInstitutionalRecord ); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_NV_RECORD_SELECTED, nvData ) break; @@ -1130,6 +1186,13 @@ isNVDataInvalid |= ( 0 == dgCalibrationRecord.dgCalibrationGroups.condSensorsCalRecord.condSensors[ i ].calibrationTime ? TRUE : FALSE ); break; + case GET_CAL_CONDUCTIVITY_SENSORS_TEMP_COMP: + nvDataStartPtr = (U08*)&dgCalibrationRecord.dgCalibrationGroups.condSensorsTempCompCalRecord; + nvDataLength = sizeof( dgCalibrationRecord.dgCalibrationGroups.condSensorsTempCompCalRecord ); + for ( i = 0; i < numOfSnsrs2Check; i++ ) + isNVDataInvalid |= ( 0 == dgCalibrationRecord.dgCalibrationGroups.condSensorsTempCompCalRecord.condSensorsTempComp[ i ].calibrationTime ? TRUE : FALSE ); + break; + case GET_CAL_TEMP_SENSORS: nvDataStartPtr = (U08*)&dgCalibrationRecord.dgCalibrationGroups.tempSensorsCalRecord; nvDataLength = sizeof( dgCalibrationRecord.dgCalibrationGroups.tempSensorsCalRecord ); @@ -1199,19 +1262,20 @@ break; case GET_CAL_FILL_CONDUCTIVITIES_RECORD: - nvDataStartPtr = (U08*)&tempChemsRecordRemove.fillCondValues; - nvDataLength = sizeof( tempChemsRecordRemove.fillCondValues ); - /* TODO un-comment when it is added to calibration record - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_1251_1 ][ FILL_COND_NORMAL_OP ].calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_1251_1 ][ FILL_COND_ACID_TEST ].calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_1251_1 ][ FILL_COND_BICARB_TEST ].calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_2251_0 ][ FILL_COND_NORMAL_OP ].calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_2251_0 ][ FILL_COND_ACID_TEST ].calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_2251_0 ][ FILL_COND_BICARB_TEST ].calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_3251_9 ][ FILL_COND_NORMAL_OP ].calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_3251_9 ][ FILL_COND_ACID_TEST ].calibrationTime ? TRUE : FALSE ); - isNVDataInvalid |= ( 0 == tempChemsRecordRemove.fillCondValues[ ACID_08_3251_9 ][ FILL_COND_BICARB_TEST ].calibrationTime ? TRUE : FALSE ); - */ + { + DG_FILL_COND_OPS_T fillOps; + + nvDataStartPtr = (U08*)&dgCalibrationRecord.dgCalibrationGroups.fillCondCalRecord.fillCondValues; + nvDataLength = sizeof( dgCalibrationRecord.dgCalibrationGroups.fillCondCalRecord.fillCondValues ); + + for ( i = 0; i < numOfSnsrs2Check; i++ ) + { + for ( fillOps = FILL_COND_NORMAL_OP; fillOps < NUM_OF_FILL_COND_TEST; fillOps++ ) + { + isNVDataInvalid |= ( 0 == dgCalibrationRecord.dgCalibrationGroups.fillCondCalRecord.fillCondValues[ i ][ fillOps ].calibrationTime ? TRUE : FALSE ); + } + } + } break; case GET_INF_HEATERS_RECORD: @@ -1469,6 +1533,47 @@ return status; } + +/*********************************************************************//** + * @brief + * The isChemDisinfectEnabledInInstitRecord returns the enable/disable + * status of the chemical disinfect in institutional record + * @details Inputs: hdInstitutionalGroup + * Output: none + * @return TRUE if chemical disinfect is enabled otherwise, FALSE + *************************************************************************/ +BOOL isChemDisinfectEnabledInInstitRecord( void ) +{ + BOOL status = ( DEFAULT_ENABLE_CHEM_DISINFECT == hdInstitutionalGroup.hdInstitutionalRecord.enableChemicalDisinfect ? FALSE : TRUE ); + + return status; +} + +/*********************************************************************//** + * @brief + * The getMinRORejectionRatioInInstitRecordPCT returns the value of the min RO + * rejection ratio in institutional record in percent + * @details Inputs: hdInstitutionalGroup + * Output: none + * @return the min RO rejection ratio in institutional record in percent + *************************************************************************/ +U32 getMinRORejectionRatioInInstitRecordPCT( void ) +{ + return hdInstitutionalGroup.hdInstitutionalRecord.minRORejectionRatioPCT; +} + +/*********************************************************************//** + * @brief + * The getMinInletWaterConductivityLimitInstitRecord returns the value of + * the inlet water conductivity alarm limit in uS/cm in institutional record + * @details Inputs: hdInstitutionalGroup + * Output: none + * @return the inlet water conductivity alarm limit in uS/cm in institutional record + *************************************************************************/ +F32 getMinInletWaterConductivityLimitInstitRecordUSPCM( void ) +{ + return hdInstitutionalGroup.hdInstitutionalRecord.minInletWaterCondAlarmLimitUSPCM; +} #endif #ifdef _DG_ /*********************************************************************//** @@ -1703,6 +1808,13 @@ status = TRUE; } break; + +#ifdef _HD_ + case NVDATAMGMT_INTITUTIONAL_RECORD: + hdInstitutionalGroup.hdInstitutionalRecord.crc = crc; + status = enqueueSector0Records(); + break; +#endif } return status; @@ -1744,6 +1856,7 @@ BOOL haveCalGroupsPassed = TRUE; BOOL hasSystemRecordPassed = TRUE; BOOL hasServiceRecordPassed = TRUE; + BOOL hasInstitutionalRecordPassed = TRUE; BOOL hasSWConfigRecordPassed = TRUE; BOOL hasUsageRecordPassed = TRUE; @@ -1760,24 +1873,28 @@ #endif #endif #ifdef _HD_ - haveCalGroupsPassed = isHDCalibrationRecordValid(); - hasSystemRecordPassed = isHDSystemRecordValid(); - hasServiceRecordPassed = isHDServiceRecordValid(); - hasUsageRecordPassed = isHDUsageRecordValid(); + haveCalGroupsPassed = isHDCalibrationRecordValid(); + hasSystemRecordPassed = isHDSystemRecordValid(); + hasServiceRecordPassed = isHDServiceRecordValid(); + hasInstitutionalRecordPassed = isHDInstitutionalRecordValid(); + hasUsageRecordPassed = isHDUsageRecordValid(); #ifndef _RELEASE_ - hasSWConfigRecordPassed = isSWConfigRecordValid(); + hasSWConfigRecordPassed = isSWConfigRecordValid(); #endif #endif // If any of the records did not pass, they should be filled // with benign values. After that, schedule a write to sector 0 // to re-write the records with the benign values - if ( ( FALSE == hasServiceRecordPassed ) || ( FALSE == haveCalGroupsPassed ) || ( FALSE == hasSystemRecordPassed ) ) + if ( ( FALSE == hasServiceRecordPassed ) || ( FALSE == haveCalGroupsPassed ) || ( FALSE == hasSystemRecordPassed ) || ( FALSE == hasInstitutionalRecordPassed ) ) { enqueueSector0Records(); SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_CALIBRATION_RECORD ].nvEvent, 0, 0 ) SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_SYSTEM_RECORD ].nvEvent, 0, 0 ) SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ].nvEvent, 0, 0 ) +#ifdef _HD_ + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_INTITUTIONAL_RECORD ].nvEvent, 0, 0 ) +#endif } #ifndef _RELEASE_ @@ -1795,11 +1912,19 @@ } // Check if the records' entire CRCs as well as the individual CRCs passed - if ( ( TRUE == haveCalGroupsPassed ) && ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) ) + if ( ( TRUE == haveCalGroupsPassed ) && ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) && ( TRUE == hasInstitutionalRecordPassed ) ) { newCalStartTimer = getMSTimerCount(); isNewCalAvailable = TRUE; nvDataMgmtSelfTestResult = SELF_TEST_STATUS_PASSED; + +#ifdef _HD_ + MESSAGE_T institMsg; + // Received new institutional record and it is valid, send it to the UI to be up to date + institMsg.hdr.msgID = 0; + institMsg.hdr.payloadLen = 0; + handleSendInstitutionalRecordToUI( &institMsg ); +#endif } else { @@ -2339,6 +2464,13 @@ #endif break; +#ifdef _HD_ + case NVDATAMGMT_INTITUTIONAL_RECORD: + sendHDInstitutionalRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); + break; +#endif + +#ifndef _RELEASE_ case NVDATAMGMT_SW_CONFIG_RECORD: #ifdef _DG_ sendDGSWConfigRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); @@ -2347,6 +2479,7 @@ sendHDSWConfigRecord( calPublishMessageCount + 1, calPublishTotalMessages, length, startPtr ); #endif break; +#endif case NVDATAMGMT_USAGE_INFO_RECORD: #ifdef _DG_ @@ -2588,6 +2721,7 @@ } } +#ifdef ENABLE_LOCAL_LOGGING /*********************************************************************//** * @brief * The dequeue function removes a job from the job queue if it is not empty. @@ -2612,7 +2746,9 @@ } _enable_IRQ(); } +#endif +#ifdef ENABLE_LOCAL_LOGGING /*********************************************************************//** * @brief * The isQueueEmpty checks whether the queue is empty and if it is empty, @@ -2632,6 +2768,7 @@ return isEmpty; } +#endif /*********************************************************************//** * @brief @@ -2685,7 +2822,7 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_MANAGEMENT_OPS_TIMEOUT, state ) #endif #ifdef _HD_ - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_MANAGEMENT_OPS_TIMEOUT, state ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_NVDATA_MANAGEMENT_OPS_TIMEOUT, state ) #endif status = TRUE; } @@ -3004,10 +3141,18 @@ isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; } + DG_COND_SENSORS_TEMP_COMP_CAL_RECORD_T* condTemp = &dgCalibrationRecord.dgCalibrationGroups.condSensorsTempCompCalRecord; + for ( i = 0; i < NUM_OF_CAL_DATA_COND_SENSORS_TEMP_COMP; i++ ) + { + isHardwareRecordValid = isDGCondSensorsTemperatureCompensationRecordValid( &condTemp->condSensorsTempComp[ i ] ); + isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + } + DG_CONC_PUMPS_CAL_RECORD_T* concPump = &dgCalibrationRecord.dgCalibrationGroups.concentratePumpsRecord; for ( i = 0; i < NUM_OF_CAL_DATA_DG_CONC_PUMPS; i++ ) { - isHardwareRecordValid = isDGConcPumpRecordValid( &concPump->concentratePumps[ i ] ); + record = &concPump->concentratePumps[ i ]; + isHardwareRecordValid = isPolynomialRecordValid( record ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; } @@ -3090,6 +3235,17 @@ isHardwareRecordValid = isDGHeatingCalRecordValid( heating ); isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; + DG_FILL_COND_OPS_T j; + DG_CHEMICALS_FILL_COND_CAL_RECORD_T* acidBicarbTempRecord = &dgCalibrationRecord.dgCalibrationGroups.fillCondCalRecord; + for ( i = 0; i < NUM_OF_ACID_TYPE; i++ ) + { + for ( j = FILL_COND_NORMAL_OP; j < NUM_OF_FILL_COND_TEST; j++ ) + { + isHardwareRecordValid = isDGFillConductiviesRecordValid( &acidBicarbTempRecord->fillCondValues[ i ][ j ], (DG_ACID_TYPES_T)i, (DG_FILL_COND_OPS_T)j ); + 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 ) || ( recordCRC != dgCalibrationRecord.crc ) ) @@ -3100,54 +3256,11 @@ activateAlarmNoData( ALARM_ID_DG_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID ); } - - // TODO add this check to the calibration records - // This record is not part of the calibration record yet - U08 j; - DG_CHEMICALS_FILL_COND_CAL_RECORD_T* acidBicarbTempRecord = &tempChemsRecordRemove; - for ( i = 0; i < NUM_OF_ACID_TYPE; i++ ) - { - for ( j = 0; j < NUM_OF_FILL_COND_TEST; j++ ) - { - isDGFillConductiviesRecordValid( &acidBicarbTempRecord->fillCondValues[ i ][ j ], (DG_FILL_COND_OPS_T)j, (DG_ACID_TYPES_T)i ); - } - } - // TODO add this check to the calibration records. this is temporary - return isCalRecordValid; } /*********************************************************************//** * @brief - * The isDGConcPumpRecordValid function checks whether the calibration - * record of concentrate pump is valid or not. - * @details Inputs: none - * @details Outputs: none - * @param record: DG_CONC_PUMPS_CAL_DATA_T pointer - * @return TRUE if the record is valid otherwise FALSE - *************************************************************************/ -static BOOL isDGConcPumpRecordValid( DG_CONC_PUMPS_CAL_DATA_T* record ) -{ - BOOL status = TRUE; - U16 calcCRC = crc16 ( (U08*)record, sizeof( DG_CONC_PUMPS_CAL_DATA_T ) - sizeof( U16 ) ); - U16 recordCRC = record->crc; - - if ( calcCRC != recordCRC ) - { - // CRC did not pass so set all values to default - record->stepSpeed2FlowRatio = RECORD_DEFAULT_RATIO; - record->calibrationTime = RECORD_DEFAULT_TIME; - record->crc = crc16 ( (U08*)record, sizeof( DG_CONC_PUMPS_CAL_DATA_T ) - sizeof( U16 ) ); - - // Set the to FALSE since the record is not valid - status = FALSE; - } - - return status; -} - -/*********************************************************************//** - * @brief * The isDGDrainPumpRecordValid function checks whether the calibration * record of drain pump is valid or not. * @details Inputs: none @@ -3286,7 +3399,7 @@ // CRC did not pass so set all values to default record->maxResidualFluid = RECORD_DEFAULT_CONST; record->normalFillVolume = RECORD_DEFAULT_CONST; - record->rsrvrUnfilledWeight = RECORD_DEFAULT_CONST; + record->rsrvrUnfilledWeight = EMPTY_RESERVOIR_WEIGHT_GRAMS; record->rsrvrVolume = RECORD_DEFAULT_CONST; record->calibrationTime = RECORD_DEFAULT_TIME; record->crc = crc16 ( (U08*)record, sizeof(DG_RESERVOIR_VOLUME_DATA_T) - sizeof(U16) ); @@ -3520,7 +3633,7 @@ * @param acidType whcih is the type of acid that its values are checked (e.g. 0-1251-1) * @return TRUE if the record is valid otherwise FALSE *************************************************************************/ -static BOOL isDGFillConductiviesRecordValid( DG_ACID_BICARB_FILL_COND_VALUES_T* record, DG_FILL_COND_OPS_T operation, DG_ACID_TYPES_T acidType ) +static BOOL isDGFillConductiviesRecordValid( DG_ACID_BICARB_FILL_COND_VALUES_T* record, DG_ACID_TYPES_T acidType, DG_FILL_COND_OPS_T operation ) { BOOL status = TRUE; U16 calcCRC = crc16 ( (U08*)record, sizeof(DG_ACID_BICARB_FILL_COND_VALUES_T) - sizeof(U16) ); @@ -3590,6 +3703,7 @@ // CRC did not pass so set all values to default record->acidConduSPerCM = acidSensorCond; record->bicarbConduSPerCM = bicarbSensorCond; + record->calibrationTime = RECORD_DEFAULT_TIME; record->crc = crc16 ( (U08*)record, sizeof(DG_ACID_BICARB_FILL_COND_VALUES_T) - sizeof(U16) ); // Set the to FALSE since the record is not valid @@ -3598,6 +3712,38 @@ return status; } + +/*********************************************************************//** + * @brief + * The isDGCondSensorsTemperatureCompensationRecordValid function checks whether + * the conductivity sensors temperature compensation record is valid or not + * @details Inputs: none + * @details Outputs: none + * @param record: DG_COND_SENSOR_TEMP_COMP_CAL_PAYLOAD_T pointer containing the + * conductivity sensors temperature compensation calibration payload + * @return TRUE if the record is valid otherwise FALSE + *************************************************************************/ +static BOOL isDGCondSensorsTemperatureCompensationRecordValid( DG_COND_SENSOR_TEMP_COMP_CAL_PAYLOAD_T* record ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16 ( (U08*)record, sizeof(DG_COND_SENSOR_TEMP_COMP_CAL_PAYLOAD_T) - sizeof(U16) ); + U16 recordCRC = record->crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + record->gain = RECORD_DEFAULT_GAIN; + record->coefficient = DEFAULT_COND_SENSOR_TEMP_COMP_COEEF; + record->offset = RECORD_DEFAULT_OFFSET; + record->calibrationTime = RECORD_DEFAULT_TIME; + record->crc = crc16 ( (U08*)record, sizeof(DG_COND_SENSOR_TEMP_COMP_CAL_PAYLOAD_T) - sizeof(U16) ); + + // Set the to FALSE since the record is not valid + status = FALSE; + } + + return status; +} #endif #ifdef _HD_ /*********************************************************************//** @@ -3786,6 +3932,64 @@ /*********************************************************************//** * @brief + * The isHDInstitutionalRecordValid function checks the validity of the HD + * institutional record. + * @details Inputs: hdInstitutionalGroup.hdInstitutionalRecord + * @details Outputs: none + * @return TRUE if the HD institutional record is valid otherwise FALSE + *************************************************************************/ +static BOOL isHDInstitutionalRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&hdInstitutionalGroup.hdInstitutionalRecord, sizeof( HD_INSTITUTIONAL_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = hdInstitutionalGroup.hdInstitutionalRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default + hdInstitutionalGroup.hdInstitutionalRecord.minBloodFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_BLOOD_FLOW, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxBloodFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_BLOOD_FLOW, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minDialysateFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_FLOW, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxDialysateFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_FLOW, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minTxDurationMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_TREATMENT_DURATION, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxTxDurationMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_TREATMENT_DURATION, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minStopHeparinDispBeforeTxEndMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxStopHeparinDispBeforeTxEndMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minSalineBolusVolumeML = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_SALINE_BOLUS_VOLUME, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxSalineBolusVolumeML = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_SALINE_BOLUS_VOLUME, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minDialysateTempC = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_TEMPERATURE, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxDialysateTempC = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_TEMPERATURE, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minArtPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxArtPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minVenPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxVenPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minVenAsymPressLimitMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxVenAsymPressLimitMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minUFVolumeL = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_UF_VOLUME, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxUFVolumeL = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_UF_VOLUME, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minHeparinDispRateMLPHR = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxHeparinDispRateMLPHR = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.minHeparinBolusVolumeML = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME, TRUE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxHeparinBolusVolumeML = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME, FALSE ); + hdInstitutionalGroup.hdInstitutionalRecord.enableChemicalDisinfect = DEFAULT_ENABLE_CHEM_DISINFECT; + hdInstitutionalGroup.hdInstitutionalRecord.minRORejectionRatioPCT = DEFAULT_MAX_RO_REJECTION_RATIO_PCT; + hdInstitutionalGroup.hdInstitutionalRecord.minInletWaterCondAlarmLimitUSPCM = DEFAULT_MIN_INLET_WATER_COND_ALARM_US_P_CM; + hdInstitutionalGroup.hdInstitutionalRecord.minVenPressWideLimitWindowMMHG = DEFAULT_MIN_VEN_WIDE_WINDOW_LIMIT_MMHG; + hdInstitutionalGroup.hdInstitutionalRecord.calibrationTime = getRTCTimestamp(); + hdInstitutionalGroup.hdInstitutionalRecord.crc = crc16 ( (U08*)&hdInstitutionalGroup.hdInstitutionalRecord, + sizeof( HD_INSTITUTIONAL_RECORD_T ) - sizeof( U16 ) ); + hdInstitutionalGroup.crc = crc16 ( (U08*)&hdInstitutionalGroup, sizeof( HD_INSTITUTIONAL_GROUP_T ) - sizeof( U16 ) ); + status = FALSE; + + // Institutional record failure is also considered as RTC RAM failure + activateAlarmNoData( ALARM_ID_HD_INVALID_INSTITUTIONAL_RECORD_CRC ); + } + + return status; +} + +/*********************************************************************//** + * @brief * The isHDPumpRecordValid function checks whether the calibration record * of HD pump(s) is valid or not. * @details Inputs: none @@ -3936,8 +4140,8 @@ /*********************************************************************//** * @brief * The enqueueRecordJob function enqueues a new record job. - * @details Inputs: queueFrontIndex, queueCount, recordJobQueue - * @details Outputs: queueFrontIndex, queueCount, recordJobQueue + * @details Inputs: recordQueueRearIndex, queueCount, recordJobQueue + * @details Outputs: recordQueueRearIndex, queueCount, recordJobQueue * @param ops: memory operation (i.e write, read) * @param location: memory location which are either EEPROM or RTC RAM * @param job: type of job (i.e write calibration data) @@ -3997,7 +4201,6 @@ U32 tempIndex; PROCESS_RECORD_JOB_T tempJob; BOOL status = FALSE; - BOOL checkUIStatus = TRUE; // Initialize the structure per CppCheck run tempJob.memoryLocation = NVDATAMGMT_EEPROM; @@ -4013,22 +4216,28 @@ } _enable_IRQ(); + if ( NVDATAMGMT_RTC == tempJob.memoryLocation ) + { #ifdef _HD_ - checkUIStatus = ( TRUE == uiCommunicated() ? TRUE : FALSE ); + if ( TRUE == uiCommunicated() ) #endif - - if ( ( NVDATAMGMT_RTC == tempJob.memoryLocation ) && ( TRUE == checkUIStatus ) ) - { - if ( ( RTC_RAM_STATE_READY == getRTCRAMState() ) && ( TRUE == getSemaphore( SEMAPHORE_RTC ) ) ) { - status = TRUE; + if ( ( RTC_RAM_STATE_READY == getRTCRAMState() ) && ( TRUE == getSemaphore( SEMAPHORE_RTC ) ) ) + { + status = TRUE; + } } } - else if ( ( NVDATAMGMT_EEPROM == tempJob.memoryLocation ) && ( TRUE == checkUIStatus ) ) + else if ( NVDATAMGMT_EEPROM == tempJob.memoryLocation ) { - if ( Fapi_Status_FsmReady == FAPI_CHECK_FSM_READY_BUSY ) +#ifdef _HD_ + if ( TRUE == uiCommunicated() ) +#endif { - status = TRUE; + if ( Fapi_Status_FsmReady == FAPI_CHECK_FSM_READY_BUSY ) + { + status = TRUE; + } } }