Index: firmware/App/Services/NVRecordsDD.c =================================================================== diff -u -r2e65cae607c3ee68326f82d6134b0de3777559f9 -rb925bf251dfd5584a0839cee93ccf8566a0ec2fb --- firmware/App/Services/NVRecordsDD.c (.../NVRecordsDD.c) (revision 2e65cae607c3ee68326f82d6134b0de3777559f9) +++ firmware/App/Services/NVRecordsDD.c (.../NVRecordsDD.c) (revision b925bf251dfd5584a0839cee93ccf8566a0ec2fb) @@ -13,7 +13,6 @@ ***************************************************************************/ #include // For memcpy -//#include "Common.h" #include "DDDefs.h" #include "NVJobQ.h" #include "NVMessagingDD.h" @@ -81,15 +80,21 @@ #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. -// NOTE: assuming the macro is calculating the padding length for a non-volatile memory. For NV, 16 bytes is used and buffer and for the RTC RAM 64 bytes is used. +// Padding length calculation: (DD struct size % bytes to write(16) == 0 ? 0 : ((DD struct size / bytes to write(16)) + 1) * bytes to write(16)) - DD struct size. +// NOTE: assuming the macro is calculating the padding length for a non-volatile memory. For NV, 16 bytes is used for buffer. // If the size of the structure + a 2-byte crc mod 16 is 0, then the size of the padding is 0 // Otherwise, the (((structure size + crc) / 16) + 1) * 16. In the calculations, a + 1 is added since the division has a decimal so + 1 is used // 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)) ///< DD padding length macro. +#define RECORD_PADDING_LENGTH(rcrd, buf) ( RECORD_BYTE_SIZE( rcrd ) % buf == 0 ? 0 : \ + ( ( ( ( RECORD_BYTE_SIZE( rcrd ) / buf) + 1 ) ) * buf ) \ + - RECORD_BYTE_SIZE( rcrd ) ) ///< DD padding length macro. +#define SYSTEM_RECORD_PADDING_LENGTH ( RECORD_PADDING_LENGTH( DD_SYSTEM_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES ) ) +#define SERVICE_RECORD_PADDING_LENGTH ( RECORD_PADDING_LENGTH( DD_SERVICE_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES ) ) +#define CALIBRATION_RECORD_PADDING_LENGTH ( RECORD_PADDING_LENGTH( DD_CALIBRATION_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES ) ) +#define INSTITUTIONAL_RECORD_PADDING_LENGTH ( RECORD_PADDING_LENGTH( DD_INSTITUTIONAL_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES ) ) +#define USAGE_INFO_RECORD_PADDING_LENGTH ( RECORD_PADDING_LENGTH( DD_USAGE_INFO_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES ) ) + #pragma pack(push, 1) // ********** DD record structures ********** @@ -106,74 +111,57 @@ DD_BICARB_CONCENTRATES_RECORD_T bicarbConcentratesRecord; ///< DD bicarb concentrates calibration record DD_ACCEL_SENSOR_CAL_RECORD_T accelerometerSensorCalRecord; ///< DD accelerometer sensor. DD_BLOOD_LEAK_SENSOR_CAL_RECORD_T bloodLeakSensorCalRecord; ///< DD blood leak detector calibration record -} DD_CALIBRATION_GROUPS_T; +} DD_CALIBRATION_RECORD_T; /// DD calibration records structure typedef struct { - DD_CALIBRATION_GROUPS_T ddCalibrationGroups; ///< DD calibration groups. - U08 padding[ RECORD_PADDING_LENGTH(DD_CALIBRATION_GROUPS_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD calibration record padding byte array. - U16 crc; ///< CRC for the DG calibration record structure. -} DD_CALIBRATION_RECORD_T; + DD_CALIBRATION_RECORD_T ddCalibrationRecord; ///< DD calibration groups. + U08 padding[ CALIBRATION_RECORD_PADDING_LENGTH ]; ///< DD calibration record padding byte array. + U16 crc; ///< CRC for the DG calibration record structure. +} DD_CALIBRATION_GROUP_T; /// DD system group structure typedef struct { - DD_SYSTEM_RECORD_T ddSystemRecord; ///< DD system record. - U08 padding[ RECORD_PADDING_LENGTH(DD_SYSTEM_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD system group padding byte array. - U16 crc; ///< CRC for the DG system group structure. + DD_SYSTEM_RECORD_T ddSystemRecord; ///< DD system record. + U08 padding[ SYSTEM_RECORD_PADDING_LENGTH ]; ///< DD system group padding byte array. + U16 crc; ///< CRC for the DG system group structure. } DD_SYSTEM_GROUP_T; /// DD service record structure typedef struct { - DD_SERVICE_RECORD_T ddServiceRecord; ///< DD service record. - U08 padding[ RECORD_PADDING_LENGTH(DD_SERVICE_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD service group padding. - U16 crc; ///< CRC for the DG service structure. + DD_SERVICE_RECORD_T ddServiceRecord; ///< DD service record. + U08 padding[ SERVICE_RECORD_PADDING_LENGTH ]; ///< DD service group padding. + U16 crc; ///< CRC for the DG service structure. } DD_SERVICE_GROUP_T; /// DD institutional record structure typedef struct { - DD_INSTITUTIONAL_RECORD_T ddInstitutionalRecord; ///< DD institutional record. - U08 padding[ RECORD_PADDING_LENGTH(DD_INSTITUTIONAL_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD institutional group padding. - U16 crc; ///< CRC for the HD institutional structure. + DD_INSTITUTIONAL_RECORD_T ddInstitutionalRecord; ///< DD institutional record. + U08 padding[ INSTITUTIONAL_RECORD_PADDING_LENGTH ]; ///< DD institutional group padding. + U16 crc; ///< CRC for the HD institutional structure. } DD_INSTITUTIONAL_GROUP_T; /// DD usage record structure typedef struct { - DD_USAGE_INFO_RECORD_T ddUsageInfo; ///< DD usage info record. - U08 padding[ RECORD_PADDING_LENGTH(DD_USAGE_INFO_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD scheduled run group padding. - U16 crc; ///< CRC for the DG usage info structure. + DD_USAGE_INFO_RECORD_T ddUsageInfoRecord; ///< DD usage info record. + U08 padding[ USAGE_INFO_RECORD_PADDING_LENGTH ]; ///< DD scheduled run group padding. + U16 crc; ///< CRC for the DG usage info structure. } DD_USAGE_INFO_GROUP_T; #pragma pack(pop) // ********** private data ********** -/// Temporary Record variable used only for receiving record before crc verification -static DD_SYSTEM_GROUP_T ddTempRxSystemGrp; ///< DD system group structure (including padding and final CRC). -static DD_SERVICE_GROUP_T ddTempRxServiceGrp; ///< DD service group structure (including padding and final CRC). -static DD_CALIBRATION_RECORD_T ddTempRxCalRecord; ///< DD calibration record structure (including padding and final CRC). -static DD_INSTITUTIONAL_GROUP_T ddTempRxInstitGrp; ///< DD institutional group structure (including padding and final CRC). -static DD_USAGE_INFO_GROUP_T ddTempRxUsageGrp; ///< DD usage info structure (including padding and final CRC). - -/// Temporary Process records specifications used only for receiving -static PROCESS_RECORD_SPECS_T tempRxRecords[ NUM_OF_NVM_RECORD_TYPES ] = { - // Start address Size of the job Record structure pointer Record CRC pointer Event calibration record update - {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SYSTEM_GROUP_T), (U08*)&ddTempRxSystemGrp, (U08*)&ddTempRxSystemGrp.crc, DD_EVENT_SYSTEM_RECORD_UPDATE }, // NVM_SYSTEM_RECORD - {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SERVICE_GROUP_T), (U08*)&ddTempRxServiceGrp, (U08*)&ddTempRxServiceGrp.crc, DD_EVENT_SERVICE_UPDATE }, // NVM_SERVICE_RECORD - {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_CALIBRATION_RECORD_T), (U08*)&ddTempRxCalRecord, (U08*)&ddTempRxCalRecord.crc, DD_EVENT_CAL_RECORD_UPDATE }, // NVM_CALIBRATION_RECORD - {INSTIT_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_INSTITUTIONAL_GROUP_T), (U08*)&ddTempRxInstitGrp, (U08*)&ddTempRxInstitGrp.crc, DD_EVENT_INSTIT_RECORD_UPDATE }, // NVM_INSTITUTIONAL_RECORD - {USAGE_INFO_START_ADDRESS, sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddTempRxUsageGrp, (U08*)&ddTempRxUsageGrp.crc, DD_EVENT_USAGE_INFO_UPDATE }, // NVM_USAGE_INFO_RECORD -}; - /// Main NVM Record variables static DD_SYSTEM_GROUP_T ddSystemGroup; ///< DD system group structure (including padding and final CRC). static DD_SERVICE_GROUP_T ddServiceGroup; ///< DD service group structure (including padding and final CRC). -static DD_CALIBRATION_RECORD_T ddCalibrationRecord; ///< DD calibration record structure (including padding and final CRC). +static DD_CALIBRATION_GROUP_T ddCalibrationGroup; ///< DD calibration record structure (including padding and final CRC). static DD_INSTITUTIONAL_GROUP_T ddInstitutionalGroup; ///< DD institutional group structure (including padding and final CRC). static DD_USAGE_INFO_GROUP_T ddUsageInfoGroup; ///< DD usage info structure (including padding and final CRC). @@ -182,7 +170,7 @@ // Start address Size of the job Record structure pointer Record CRC pointer Event calibration record update {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SYSTEM_GROUP_T), (U08*)&ddSystemGroup, (U08*)&ddSystemGroup.crc, DD_EVENT_SYSTEM_RECORD_UPDATE }, // NVM_SYSTEM_RECORD {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SERVICE_GROUP_T), (U08*)&ddServiceGroup, (U08*)&ddServiceGroup.crc, DD_EVENT_SERVICE_UPDATE }, // NVM_SERVICE_RECORD - {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_CALIBRATION_RECORD_T), (U08*)&ddCalibrationRecord, (U08*)&ddCalibrationRecord.crc, DD_EVENT_CAL_RECORD_UPDATE }, // NVM_CALIBRATION_RECORD + {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_CALIBRATION_GROUP_T), (U08*)&ddCalibrationGroup, (U08*)&ddCalibrationGroup.crc, DD_EVENT_CAL_RECORD_UPDATE }, // NVM_CALIBRATION_RECORD {INSTIT_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_INSTITUTIONAL_GROUP_T), (U08*)&ddInstitutionalGroup, (U08*)&ddInstitutionalGroup.crc, DD_EVENT_INSTIT_RECORD_UPDATE }, // NVM_INSTITUTIONAL_RECORD {USAGE_INFO_START_ADDRESS, sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddUsageInfoGroup, (U08*)&ddUsageInfoGroup.crc, DD_EVENT_USAGE_INFO_UPDATE }, // NVM_USAGE_INFO_RECORD }; @@ -211,6 +199,15 @@ static BOOL isDDAccelerometerSensorRecordValid( DD_ACCEL_SENSOR_CAL_RECORD_T* record ); static BOOL isDDBloodLeakSesnorValid( DD_BLOOD_LEAK_SENSOR_CAL_RECORD_T* record ); +static void initDDSystemRecord( void ); +static void initDDServiceRecord( void ); +static void initDDInstitutionalRecord( void ); +static void initDDUsageRecord( void ); +static void initDDCalibrationRecord( void ); + +static void updateRecordPadding( NVM_RECORD_TYPE_T recType ); +static void updateRecordCRC( NVM_RECORD_TYPE_T recType ); + /*********************************************************************//** * @brief * The initNVRecordsDD function initializes the NV records data management @@ -227,6 +224,19 @@ nvmSelfTestState = NVM_SELF_TEST_STATE_READ_RECORDS; nvmSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; usageWriteTries = 0; + + initDDSystemRecord(); + initDDServiceRecord(); + initDDInstitutionalRecord(); + initDDCalibrationRecord(); + initDDUsageRecord(); + + int i; + for( i = 0; i < NUM_OF_NVM_RECORD_TYPES; i++ ) + { + updateRecordPadding(i); + updateRecordCRC(i); + } } /*********************************************************************//** @@ -285,20 +295,6 @@ /*********************************************************************//** * @brief - * The getTemporaryRxRecord function gets the temporary RX record - * specification for the given job. - * @details \b Inputs: tempRxRecords - * @details \b Outputs: none - * @param job Record job identifier used to select the temporary RX record - * @return tempRxRecords[job] corresponding temporary RX record - *************************************************************************/ -PROCESS_RECORD_SPECS_T getTemporaryRxRecord( NVM_RECORD_TYPE_T job ) -{ - return tempRxRecords[ job ]; -} - -/*********************************************************************//** - * @brief * The handleSelfTestReadRecords function waits for the records to be * read and updates the state when reading is complete. * @details \b Inputs: isSelfTestReadRecordsDone @@ -459,27 +455,22 @@ if ( calcCRC != recordCRC ) { // CRC did not pass so set all values to default -// memset( ddSystemGroup.ddSystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( ddSystemGroup.ddSystemRecord.topLevelPN ) ); -// memset( ddSystemGroup.ddSystemRecord.topLevelSN, RECORD_DEFAULT_CHARACTER, sizeof( ddSystemGroup.ddSystemRecord.topLevelSN ) ); - ddSystemGroup.ddSystemRecord.isROFeatured = FALSE; - ddSystemGroup.ddSystemRecord.isROFeaturedBoostPump = FALSE; - ddSystemGroup.ddSystemRecord.mfgDate = 0; - ddSystemGroup.ddSystemRecord.mfgLocation = 0; + initDDSystemRecord(); // Recalculate the CRC with the default values - ddSystemGroup.ddSystemRecord.crc = crc16 ( (U08*)&ddSystemGroup.ddSystemRecord, sizeof( DD_SYSTEM_RECORD_T ) - sizeof( U16 ) ); - ddSystemGroup.crc = crc16 ( (U08*)&ddSystemGroup, sizeof( DD_SYSTEM_GROUP_T ) - sizeof( U16 ) ); - status = FALSE; + updateRecordCRC( NVM_SYSTEM_RECORD ); + status = FALSE; + activateAlarmNoData( ALARM_ID_DD_NVM_INVALID_SYSTEM_RECORD_CRC ); } else { // Verify the serial number from the system record -// if ( RECORD_DEFAULT_CHARACTER == ddSystemGroup.ddSystemRecord.topLevelSN[ 0 ] ) -// { -// activateAlarmNoData( ALARM_ID_DD_NVM_INVALID_SERIAL_NUMBER ); -// } + if ( RECORD_DEFAULT_CHARACTER == ddSystemGroup.ddSystemRecord.topLevelSN[ 0 ] ) + { + activateAlarmNoData( ALARM_ID_DD_NVM_INVALID_SERIAL_NUMBER ); + } } return status; @@ -506,16 +497,13 @@ if ( calcCRC != recordCRC ) { // CRC did not pass so set all values to default - ddServiceGroup.ddServiceRecord.isHDFOnlineFluid = FALSE; - ddServiceGroup.ddServiceRecord.waterRecovery = 0; - ddServiceGroup.ddServiceRecord.serviceLoc = 0; - ddServiceGroup.ddServiceRecord.lastServiceEpochDate = 0; - ddServiceGroup.ddServiceRecord.serviceIntervalSeconds = RECORD_DEFAULT_SERVICE_INTERVAL_S; -// ddServiceGroup.ddServiceRecord.lastResetTimeEpoch = getRTCTimestamp(); - ddServiceGroup.ddServiceRecord.crc = crc16 ( (U08*)&ddServiceGroup.ddServiceRecord, sizeof( DD_SERVICE_RECORD_T ) - sizeof( U16 ) ); - ddServiceGroup.crc = crc16 ( (U08*)&ddServiceGroup, sizeof( DD_SERVICE_GROUP_T ) - sizeof( U16 ) ); - status = FALSE; + initDDServiceRecord(); + // Recalculate the CRC with the default values + updateRecordCRC( NVM_SERVICE_RECORD ); + + status = FALSE; + // Service record failure activateAlarmNoData( ALARM_ID_DD_NVM_INVALID_SERVICE_RECORD_CRC ); } @@ -543,35 +531,12 @@ if ( calcCRC != recordCRC ) { // CRC did not pass so set all values to default - ddInstitutionalGroup.ddInstitutionalRecord.minDialysateFlowMLPM = DEFAULT_MIN_DIALYSATE_FLOW_MLPM; - ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateFlowMLPM = DEFAULT_MAX_DIALYSATE_FLOW_MLPM; - ddInstitutionalGroup.ddInstitutionalRecord.minDialysateTempC = DEFAULT_MIN_DIALYSATE_TEMP_C; - ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateTempC = DEFAULT_MAX_DIALYSATE_TEMP_C; - ddInstitutionalGroup.ddInstitutionalRecord.minAcidConcentrate = DEFAULT_MIN_ACID_CONCENTRATE; - ddInstitutionalGroup.ddInstitutionalRecord.maxAcidConcentrate = DEFAULT_MAX_ACID_CONCENTRATE; - ddInstitutionalGroup.ddInstitutionalRecord.minBicarbCartridgeSizeG = DEFAULT_MIN_BICARB_CARTRIDGE_SIZE_G; - ddInstitutionalGroup.ddInstitutionalRecord.maxBicarbCartridgeSizeG = DEFAULT_MAX_BICARB_CARTRIDGE_SIZE_G; - ddInstitutionalGroup.ddInstitutionalRecord.minSodiumMEQL = DEFAULT_MIN_SODIUM_MEQL; - ddInstitutionalGroup.ddInstitutionalRecord.maxSodiumMEQL = DEFAULT_MAX_SODIUM_MEQL; - ddInstitutionalGroup.ddInstitutionalRecord.minBicarbonateMEQL = DEFAULT_MIN_BICARBONATE_MEQL; - ddInstitutionalGroup.ddInstitutionalRecord.maxBicarbonateMEQL = DEFAULT_MAX_BICARBONATE_MEQL; - ddInstitutionalGroup.ddInstitutionalRecord.minRORejectionRatioPCT = DEFAULT_MAX_RO_REJECTION_RATIO_PCT; - ddInstitutionalGroup.ddInstitutionalRecord.disinfectionFrequency = DEFAULT_NUM_OF_DISINFECTION_FREQUENCY; - ddInstitutionalGroup.ddInstitutionalRecord.disinfectionCycleTime = DEFAULT_NUM_OF_DISINFECTION_CYCLE_TIME; - ddInstitutionalGroup.ddInstitutionalRecord.minInletWaterCondAlarmLimitUSPCM = DEFAULT_MIN_INLET_WATER_COND_ALARM_US_P_CM; - ddInstitutionalGroup.ddInstitutionalRecord.maxInletWaterCondAlarmLimitUSPCM = DEFAULT_MAX_INLET_WATER_COND_ALARM_US_P_CM; - ddInstitutionalGroup.ddInstitutionalRecord.acidConcentrateJugSizeL = DEFAULT_ACID_CONCENTRATE_JUG_SIZE; - ddInstitutionalGroup.ddInstitutionalRecord.minAcidAlarmLimitPCT = DEFAULT_MIN_ACID_ALARM_US_P_CM; - ddInstitutionalGroup.ddInstitutionalRecord.minBicarbAlarmLimitPCT = DEFAULT_MIN_BICARB_ALARM_US_P_CM; - ddInstitutionalGroup.ddInstitutionalRecord.postTreatDrainOption = DEFAULT_POST_TREATMENT_DRAIN_OPTION; - ddInstitutionalGroup.ddInstitutionalRecord.postTreatDryBicarbOption = DEFAULT_POST_TREATMENT_DRY_BICARB_OPTION; + initDDInstitutionalRecord(); + // Recalculate the CRC with the default values + updateRecordCRC( NVM_INSTITUTIONAL_RECORD ); -// ddInstitutionalGroup.ddInstitutionalRecord.calibrationTime = getRTCTimestamp(); - ddInstitutionalGroup.ddInstitutionalRecord.crc = crc16 ( (U08*)&ddInstitutionalGroup.ddInstitutionalRecord, - sizeof( DD_INSTITUTIONAL_RECORD_T ) - sizeof( U16 ) ); - ddInstitutionalGroup.crc = crc16 ( (U08*)&ddInstitutionalGroup, sizeof( DD_INSTITUTIONAL_GROUP_T ) - sizeof( U16 ) ); - status = FALSE; + status = FALSE; // Institutional record failure is also considered as RTC RAM failure activateAlarmNoData( ALARM_ID_DD_NVM_INVALID_INSTITUTIONAL_RECORD_CRC ); @@ -594,22 +559,18 @@ static BOOL isDDUsageRecordValid( void ) { BOOL status = TRUE; - U16 calcCRC = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfo, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); - U16 recordCRC = ddUsageInfoGroup.ddUsageInfo.crc; + U16 calcCRC = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfoRecord, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = ddUsageInfoGroup.ddUsageInfoRecord.crc; if ( calcCRC != recordCRC ) { - ddUsageInfoGroup.ddUsageInfo.roWaterGenTotalL = 0.0F; - ddUsageInfoGroup.ddUsageInfo.roWaterGenSinceLastServiceL = 0.0F; - ddUsageInfoGroup.ddUsageInfo.lastBasicFlushCompleteDateEpoch = 0; - ddUsageInfoGroup.ddUsageInfo.lastHeatDisCompleteDateEpoch = 0; - ddUsageInfoGroup.ddUsageInfo.lastHeatActiveCoolCompleteDateEpoch = 0; - ddUsageInfoGroup.ddUsageInfo.lastFilterFlushCompleteDateEpoch = 0; -// ddUsageInfoGroup.ddUsageInfo.lastResetTimeEpoch = getRTCTimestamp(); - ddUsageInfoGroup.ddUsageInfo.crc = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfo, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); - ddUsageInfoGroup.crc = crc16( (U08*)&ddUsageInfoGroup, sizeof( DD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); - status = FALSE; + // CRC did not pass so set all values to default + initDDUsageRecord(); + // Recalculate the CRC with the default values + updateRecordCRC( NVM_USAGE_INFO_RECORD ); + status = FALSE; + activateAlarmNoData( ALARM_ID_DD_NVM_INVALID_USAGE_RECORD_CRC ); } @@ -623,8 +584,8 @@ * updates them with benign values if invalid. * @details \b Alarms: ALARM_ID_DD_NVM_INVALID_CALIBRATION_RECORD_CRC if * CRC check fails or any sub-record is invalid - * @details \b Inputs: ddCalibrationRecord - * @details \b Outputs: ddCalibrationRecord + * @details \b Inputs: ddCalibrationGroup + * @details \b Outputs: ddCalibrationGroup * @return TRUE if the DD calibration record is valid otherwise FALSE *************************************************************************/ static BOOL isDDCalibrationRecordValid( void ) @@ -633,7 +594,7 @@ POLYNOMIAL_CAL_PAYLOAD_T* record; BOOL isHardwareRecordValid = TRUE; BOOL isCalRecordValid = TRUE; - U16 recordCRC = crc16 ( (U08*)&ddCalibrationRecord, sizeof( DD_CALIBRATION_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = crc16 ( (U08*)&ddCalibrationGroup, sizeof( DD_CALIBRATION_GROUP_T ) - sizeof( U16 ) ); // Create a benign polynomial calibration record. This record is used to // clear the reserved calibration record. The reserved spaces are not used @@ -643,7 +604,7 @@ benignPolynomialCalRecord( &tempRecord ); // Get the calibration record of the hardware (i.e. pressure sensor) - DD_PRES_SENSORS_CAL_RECORD_T* pressure = &ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord; + DD_PRES_SENSORS_CAL_RECORD_T* pressure = &ddCalibrationGroup.ddCalibrationRecord.presSensorsCalRecord; // The ones that are an array, are looped through for ( i = 0; i < NUM_OF_PRESSURE_SENSORS; i++ ) { @@ -658,59 +619,59 @@ isCalRecordValid = ( isCalRecordValid == FALSE ) ? FALSE : isHardwareRecordValid; } - DD_TEMP_SENSORS_CAL_RECORD_T* temperature = &ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord; + DD_TEMP_SENSORS_CAL_RECORD_T* temperature = &ddCalibrationGroup.ddCalibrationRecord.tempSensorsCalRecord; for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) { record = (POLYNOMIAL_CAL_PAYLOAD_T*)&temperature->tempSensors[ i ]; isHardwareRecordValid = isPolynomialRecordValid( record ); isCalRecordValid = ( isCalRecordValid == FALSE ) ? FALSE : isHardwareRecordValid; } - DD_CONC_PUMPS_CAL_RECORD_T* concPump = &ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord; + DD_CONC_PUMPS_CAL_RECORD_T* concPump = &ddCalibrationGroup.ddCalibrationRecord.concentratePumpsRecord; for ( i = 0; i < NUM_OF_CONCENTRATE_PUMPS; i++ ) { record = (POLYNOMIAL_CAL_PAYLOAD_T*)&concPump->concentratePumps[ i ]; isHardwareRecordValid = isPolynomialRecordValid( record ); isCalRecordValid = ( isCalRecordValid == FALSE ) ? FALSE : isHardwareRecordValid; } - DD_D12_DIALYSATE_PUMP_RECORD_T* d12Pump = &ddCalibrationRecord.ddCalibrationGroups.d12DialysatePumpRecord; + DD_D12_DIALYSATE_PUMP_RECORD_T* d12Pump = &ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord; isHardwareRecordValid = isDDPumpD12RecordValid( d12Pump ); isCalRecordValid = ( isCalRecordValid == FALSE ) ? FALSE : isHardwareRecordValid; - DD_D48_DIALYSATE_PUMP_RECORD_T* d48Pump = &ddCalibrationRecord.ddCalibrationGroups.d48DialysatePumpRecord; + DD_D48_DIALYSATE_PUMP_RECORD_T* d48Pump = &ddCalibrationGroup.ddCalibrationRecord.d48DialysatePumpRecord; record = (POLYNOMIAL_CAL_PAYLOAD_T*)&d48Pump->d48DialysatePump; isHardwareRecordValid = isPolynomialRecordValid( record ); isCalRecordValid = ( isCalRecordValid == FALSE ) ? FALSE : isHardwareRecordValid; - DD_ACID_CONCENTRATES_RECORD_T* acidConc = &ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord; + DD_ACID_CONCENTRATES_RECORD_T* acidConc = &ddCalibrationGroup.ddCalibrationRecord.acidConcentratesRecord; for ( i = 0; i < NUM_OF_CAL_DATA_ACID_CONCENTRATES; i++ ) { isHardwareRecordValid = isDDAcidConcentrateRecordValid( &acidConc->acidConcentrate[ i ] ); isCalRecordValid = ( isCalRecordValid == FALSE ) ? FALSE : isHardwareRecordValid; } - DD_BICARB_CONCENTRATES_RECORD_T* bicarbConc = &ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord; + DD_BICARB_CONCENTRATES_RECORD_T* bicarbConc = &ddCalibrationGroup.ddCalibrationRecord.bicarbConcentratesRecord; for ( i = 0; i < NUM_OF_CAL_DATA_BICARB_CONCENTRATES; i++ ) { isHardwareRecordValid = isDDBicarbConcentrateRecordValid( &bicarbConc->bicarbConcentrate[ i ] ); isCalRecordValid = ( isCalRecordValid == FALSE ) ? FALSE : isHardwareRecordValid; } - DD_ACCEL_SENSOR_CAL_RECORD_T* accelerometer = &ddCalibrationRecord.ddCalibrationGroups.accelerometerSensorCalRecord; + DD_ACCEL_SENSOR_CAL_RECORD_T* accelerometer = &ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord; isHardwareRecordValid = isDDAccelerometerSensorRecordValid( accelerometer ); isCalRecordValid = ( isCalRecordValid == FALSE ) ? FALSE : isHardwareRecordValid; - DD_BLOOD_LEAK_SENSOR_CAL_RECORD_T* bloodLeak = &ddCalibrationRecord.ddCalibrationGroups.bloodLeakSensorCalRecord; + DD_BLOOD_LEAK_SENSOR_CAL_RECORD_T* bloodLeak = &ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord; isHardwareRecordValid = isDDBloodLeakSesnorValid( bloodLeak ); 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 != ddCalibrationRecord.crc ) ) + if ( ( FALSE == isCalRecordValid ) || ( recordCRC != ddCalibrationGroup.crc ) ) { isCalRecordValid = FALSE; - ddCalibrationRecord.crc = crc16 ( (U08*)&ddCalibrationRecord, sizeof( DD_CALIBRATION_RECORD_T ) - sizeof( U16 ) ); + ddCalibrationGroup.crc = crc16 ( (U08*)&ddCalibrationGroup, sizeof( DD_CALIBRATION_GROUP_T ) - sizeof( U16 ) ); activateAlarmNoData( ALARM_ID_DD_NVM_INVALID_CALIBRATION_RECORD_CRC ); } @@ -869,6 +830,240 @@ return status; } + +static void initDDSystemRecord( void ) +{ + ddSystemGroup.ddSystemRecord.isROFeatured = FALSE; + ddSystemGroup.ddSystemRecord.isROFeaturedBoostPump = FALSE; + memset( ddSystemGroup.ddSystemRecord.topLevelPN, RECORD_DEFAULT_CHARACTER, sizeof( ddSystemGroup.ddSystemRecord.topLevelPN ) ); + memset( ddSystemGroup.ddSystemRecord.topLevelSN, RECORD_DEFAULT_CHARACTER, sizeof( ddSystemGroup.ddSystemRecord.topLevelSN ) ); + ddSystemGroup.ddSystemRecord.mfgLocation = 0; + ddSystemGroup.ddSystemRecord.mfgDate = 0; +} + +static void initDDServiceRecord( void ) +{ + ddServiceGroup.ddServiceRecord.isHDFOnlineFluid = FALSE; + ddServiceGroup.ddServiceRecord.waterRecovery = 0; + ddServiceGroup.ddServiceRecord.serviceLoc = 0; + ddServiceGroup.ddServiceRecord.lastServiceEpochDate = 0; + ddServiceGroup.ddServiceRecord.serviceIntervalSeconds = RECORD_DEFAULT_SERVICE_INTERVAL_S; +// ddServiceGroup.ddServiceRecord.lastResetTimeEpoch = getRTCTimestamp(); +} + +static void initDDInstitutionalRecord( void ) +{ + ddInstitutionalGroup.ddInstitutionalRecord.minDialysateFlowMLPM = DEFAULT_MIN_DIALYSATE_FLOW_MLPM; + ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateFlowMLPM = DEFAULT_MAX_DIALYSATE_FLOW_MLPM; + ddInstitutionalGroup.ddInstitutionalRecord.minDialysateTempC = DEFAULT_MIN_DIALYSATE_TEMP_C; + ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateTempC = DEFAULT_MAX_DIALYSATE_TEMP_C; + ddInstitutionalGroup.ddInstitutionalRecord.minAcidConcentrate = DEFAULT_MIN_ACID_CONCENTRATE; + ddInstitutionalGroup.ddInstitutionalRecord.maxAcidConcentrate = DEFAULT_MAX_ACID_CONCENTRATE; + ddInstitutionalGroup.ddInstitutionalRecord.minBicarbCartridgeSizeG = DEFAULT_MIN_BICARB_CARTRIDGE_SIZE_G; + ddInstitutionalGroup.ddInstitutionalRecord.maxBicarbCartridgeSizeG = DEFAULT_MAX_BICARB_CARTRIDGE_SIZE_G; + ddInstitutionalGroup.ddInstitutionalRecord.minSodiumMEQL = DEFAULT_MIN_SODIUM_MEQL; + ddInstitutionalGroup.ddInstitutionalRecord.maxSodiumMEQL = DEFAULT_MAX_SODIUM_MEQL; + ddInstitutionalGroup.ddInstitutionalRecord.minBicarbonateMEQL = DEFAULT_MIN_BICARBONATE_MEQL; + ddInstitutionalGroup.ddInstitutionalRecord.maxBicarbonateMEQL = DEFAULT_MAX_BICARBONATE_MEQL; + ddInstitutionalGroup.ddInstitutionalRecord.minRORejectionRatioPCT = DEFAULT_MAX_RO_REJECTION_RATIO_PCT; + ddInstitutionalGroup.ddInstitutionalRecord.disinfectionFrequency = DEFAULT_NUM_OF_DISINFECTION_FREQUENCY; + ddInstitutionalGroup.ddInstitutionalRecord.disinfectionCycleTime = DEFAULT_NUM_OF_DISINFECTION_CYCLE_TIME; + ddInstitutionalGroup.ddInstitutionalRecord.minInletWaterCondAlarmLimitUSPCM = DEFAULT_MIN_INLET_WATER_COND_ALARM_US_P_CM; + ddInstitutionalGroup.ddInstitutionalRecord.maxInletWaterCondAlarmLimitUSPCM = DEFAULT_MAX_INLET_WATER_COND_ALARM_US_P_CM; + ddInstitutionalGroup.ddInstitutionalRecord.acidConcentrateJugSizeL = DEFAULT_ACID_CONCENTRATE_JUG_SIZE; + ddInstitutionalGroup.ddInstitutionalRecord.minAcidAlarmLimitPCT = DEFAULT_MIN_ACID_ALARM_US_P_CM; + ddInstitutionalGroup.ddInstitutionalRecord.minBicarbAlarmLimitPCT = DEFAULT_MIN_BICARB_ALARM_US_P_CM; + ddInstitutionalGroup.ddInstitutionalRecord.postTreatDrainOption = DEFAULT_POST_TREATMENT_DRAIN_OPTION; + ddInstitutionalGroup.ddInstitutionalRecord.postTreatDryBicarbOption = DEFAULT_POST_TREATMENT_DRY_BICARB_OPTION; +// ddInstitutionalGroup.ddInstitutionalRecord.calibrationTime = getRTCTimestamp(); +} + +static void initDDUsageRecord( void ) +{ + ddUsageInfoGroup.ddUsageInfoRecord.roWaterGenTotalL = 0.0F; + ddUsageInfoGroup.ddUsageInfoRecord.roWaterGenSinceLastServiceL = 0.0F; + ddUsageInfoGroup.ddUsageInfoRecord.lastBasicFlushCompleteDateEpoch = 0; + ddUsageInfoGroup.ddUsageInfoRecord.lastHeatDisCompleteDateEpoch = 0; + ddUsageInfoGroup.ddUsageInfoRecord.lastHeatActiveCoolCompleteDateEpoch = 0; + ddUsageInfoGroup.ddUsageInfoRecord.lastFilterFlushCompleteDateEpoch = 0; +// ddUsageInfoGroup.ddUsageInfoRecord.lastResetTimeEpoch = getRTCTimestamp(); +} + +static void initDDCalibrationRecord( void ) +{ + U32 i; + POLYNOMIAL_CAL_PAYLOAD_T* record; + + DD_PRES_SENSORS_CAL_RECORD_T* pressure = &ddCalibrationGroup.ddCalibrationRecord.presSensorsCalRecord; + for ( i = 0; i < NUM_OF_PRESSURE_SENSORS; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&pressure->pressureSensors[ i ]; + benignPolynomialCalRecord( record ); + } + + DD_TEMP_SENSORS_CAL_RECORD_T* temperature = &ddCalibrationGroup.ddCalibrationRecord.tempSensorsCalRecord; + for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&temperature->tempSensors[ i ]; + benignPolynomialCalRecord( record ); + } + + DD_CONC_PUMPS_CAL_RECORD_T* concPump = &ddCalibrationGroup.ddCalibrationRecord.concentratePumpsRecord; + for ( i = 0; i < NUM_OF_CONCENTRATE_PUMPS; i++ ) + { + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&concPump->concentratePumps[ i ]; + benignPolynomialCalRecord( record ); + } + + ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord.targetPumpSpeed = DEFAULT_D12_PUMP_TARGET_SPEED; + ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord.calibrationTime = RECORD_DEFAULT_TIME; + ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord.crc = crc16 ( (U08*)record, + sizeof( DD_D12_DIALYSATE_PUMP_RECORD_T ) - sizeof( U16 ) ); + + DD_D48_DIALYSATE_PUMP_RECORD_T* d48Pump = &ddCalibrationGroup.ddCalibrationRecord.d48DialysatePumpRecord; + record = (POLYNOMIAL_CAL_PAYLOAD_T*)&d48Pump->d48DialysatePump; + benignPolynomialCalRecord( record ); + + DD_ACID_CONCENTRATES_RECORD_T* acidConc = &ddCalibrationGroup.ddCalibrationRecord.acidConcentratesRecord; + for ( i = 0; i < NUM_OF_CAL_DATA_ACID_CONCENTRATES; i++ ) + { + acidConc->acidConcentrate[ i ].acidConcMixRatio = DEFAULT_ACID_CONC_MIXING_RATIO; + acidConc->acidConcentrate[ i ].acidFullBottleVolumeML = DEFAULT_ACID_BOTTLE_VOL_ML; + acidConc->acidConcentrate[ i ].acidConductivityUSPerCM = DEFAULT_ACID_COND_US_PER_CM; + acidConc->acidConcentrate[ i ].acidBottleTemperature = DEFAULT_ACID_BOTTLE_TEMP_C; + acidConc->acidConcentrate[ i ].calibrationTime = RECORD_DEFAULT_TIME; + acidConc->acidConcentrate[ i ].crc = crc16 ( (U08*)record, sizeof( DD_ACID_CONCENTRATE_T ) - sizeof( U16 ) ); + } + + DD_BICARB_CONCENTRATES_RECORD_T* bicarbConc = &ddCalibrationGroup.ddCalibrationRecord.bicarbConcentratesRecord; + for ( i = 0; i < NUM_OF_CAL_DATA_BICARB_CONCENTRATES; i++ ) + { + bicarbConc->bicarbConcentrate[ i ].bicarbConcMixRatio = DEFAULT_BICARB_CONC_MIXING_RATIO; + bicarbConc->bicarbConcentrate[ i ].bicarbStartVolumeML = DEFAULT_BICARB_BOTTLE_VOL_ML; + bicarbConc->bicarbConcentrate[ i ].bicarbConductivityUSPerCM = DEFAULT_BICARB_COND_US_PER_CM; + bicarbConc->bicarbConcentrate[ i ].bicarbBottleTemperature = DEFAULT_BICARB_BOTTLE_TEMP_C; + bicarbConc->bicarbConcentrate[ i ].calibrationTime = RECORD_DEFAULT_TIME; + bicarbConc->bicarbConcentrate[ i ].crc = crc16 ( (U08*)record, sizeof( DD_BICARB_CONCENTRATE_T ) - sizeof( U16 ) ); + } + + ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord.accelXOffset = RECORD_DEFAULT_OFFSET; + ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord.accelYOffset = RECORD_DEFAULT_OFFSET; + ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord.accelZOffset = RECORD_DEFAULT_OFFSET; + ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord.calibrationTime = RECORD_DEFAULT_TIME; + ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord.crc = crc16 ( (U08*)record, sizeof(DD_ACCEL_SENSOR_CAL_RECORD_T) - sizeof(U16) ); + + ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord.setPoint = DEFAULT_BLOOD_LEAK_SET_POINT; + ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord.calibrationTime = RECORD_DEFAULT_TIME; + ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord.crc = crc16 ( (U08*)record, sizeof( DD_BLOOD_LEAK_SENSOR_CAL_RECORD_T ) - sizeof( U16 ) ); +} + +static void updateRecordPadding( NVM_RECORD_TYPE_T recType ) +{ + U32 i = 0; + + switch( recType ) + { + case NVM_SYSTEM_RECORD: + { + for ( i = 0; i < SYSTEM_RECORD_PADDING_LENGTH; i++ ) + { + ddSystemGroup.padding[ i ] = 0; + } + } + break; + case NVM_SERVICE_RECORD: + { + for ( i = 0; i < SERVICE_RECORD_PADDING_LENGTH; i++ ) + { + ddServiceGroup.padding[ i ] = 0; + } + } + break; + case NVM_CALIBRATION_RECORD: + { + for ( i = 0; i < CALIBRATION_RECORD_PADDING_LENGTH; i++ ) + { + ddCalibrationGroup.padding[ i ] = 0; + } + } + break; + + case NVM_INSTITUTIONAL_RECORD: + { + for ( i = 0; i < INSTITUTIONAL_RECORD_PADDING_LENGTH; i++ ) + { + ddInstitutionalGroup.padding[ i ] = 0; + } + } + break; + + case NVM_USAGE_INFO_RECORD: + { + for ( i = 0; i < USAGE_INFO_RECORD_PADDING_LENGTH; i++ ) + { + ddUsageInfoGroup.padding[ i ] = 0; + } + } + break; + + default: + break; + } +} + + +static void updateRecordCRC( NVM_RECORD_TYPE_T recType ) +{ + U32 i = 0; + + switch( recType ) + { + case NVM_SYSTEM_RECORD: + { + ddSystemGroup.ddSystemRecord.crc = crc16 ( (U08*)&ddSystemGroup.ddSystemRecord, + sizeof( DD_SYSTEM_RECORD_T ) - sizeof( U16 ) ); + ddSystemGroup.crc = crc16 ( (U08*)&ddSystemGroup, + sizeof( DD_SYSTEM_GROUP_T ) - sizeof( U16 ) ); + } + break; + case NVM_SERVICE_RECORD: + { + ddServiceGroup.ddServiceRecord.crc = crc16 ( (U08*)&ddServiceGroup.ddServiceRecord, + sizeof( DD_SERVICE_RECORD_T ) - sizeof( U16 ) ); + ddServiceGroup.crc = crc16 ( (U08*)&ddServiceGroup, + sizeof( DD_SERVICE_GROUP_T ) - sizeof( U16 ) ); + } + break; + case NVM_CALIBRATION_RECORD: + { + ddCalibrationGroup.crc = crc16 ( (U08*)&ddCalibrationGroup, + sizeof( DD_CALIBRATION_GROUP_T ) - sizeof( U16 ) ); + } + break; + + case NVM_INSTITUTIONAL_RECORD: + { + ddInstitutionalGroup.ddInstitutionalRecord.crc = crc16 ( (U08*)&ddInstitutionalGroup.ddInstitutionalRecord, + sizeof( DD_INSTITUTIONAL_RECORD_T ) - sizeof( U16 ) ); + ddInstitutionalGroup.crc = crc16 ( (U08*)&ddInstitutionalGroup, + sizeof( DD_INSTITUTIONAL_GROUP_T ) - sizeof( U16 ) ); + } + break; + + case NVM_USAGE_INFO_RECORD: + { + ddUsageInfoGroup.ddUsageInfoRecord.crc = crc16 ( (U08*)&ddUsageInfoGroup.ddUsageInfoRecord, + sizeof( DD_SERVICE_RECORD_T ) - sizeof( U16 ) ); + ddUsageInfoGroup.crc = crc16 ( (U08*)&ddUsageInfoGroup, + sizeof( DD_SERVICE_GROUP_T ) - sizeof( U16 ) ); + } + break; + + default: + break; + } +} + /*********************************************************************//** * @brief * The setLastDisinfectDate function updates the last disinfect time in @@ -890,27 +1085,27 @@ switch ( disinfect ) { case USAGE_INFO_BASIC_FLUSH: - ddUsageInfoGroup.ddUsageInfo.lastBasicFlushCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfoRecord.lastBasicFlushCompleteDateEpoch = epochTime; break; case USAGE_INFO_HEAT_DIS: - ddUsageInfoGroup.ddUsageInfo.lastHeatDisCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfoRecord.lastHeatDisCompleteDateEpoch = epochTime; break; case USAGE_INFO_FILTER_FLUSH: - ddUsageInfoGroup.ddUsageInfo.lastFilterFlushCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfoRecord.lastFilterFlushCompleteDateEpoch = epochTime; break; case USAGE_INFO_HEAT_DIS_ACTIVE_COOL: - ddUsageInfoGroup.ddUsageInfo.lastHeatActiveCoolCompleteDateEpoch = epochTime; + ddUsageInfoGroup.ddUsageInfoRecord.lastHeatActiveCoolCompleteDateEpoch = epochTime; break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_NVM_INVALID_USAGE_INFO_SELECTED, ( U32 )disinfect ); break; } - ddUsageInfoGroup.ddUsageInfo.crc = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfo, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + ddUsageInfoGroup.ddUsageInfoRecord.crc = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfoRecord, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); ddUsageInfoGroup.crc = crc16( (U08*)&ddUsageInfoGroup, sizeof( DD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); usageWriteTries = 0; status = TRUE; @@ -951,8 +1146,8 @@ ddServiceGroup.ddServiceRecord.crc = crc16( (U08*)&ddServiceGroup.ddServiceRecord, sizeof( DD_SERVICE_RECORD_T ) - sizeof( U16 ) ); ddServiceGroup.crc = crc16( (U08*)&ddServiceGroup, sizeof( DD_SERVICE_GROUP_T ) - sizeof( U16 ) ); // Update the DG usage info - ddUsageInfoGroup.ddUsageInfo.roWaterGenSinceLastServiceL = 0; - ddUsageInfoGroup.ddUsageInfo.crc = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfo, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); + ddUsageInfoGroup.ddUsageInfoRecord.roWaterGenSinceLastServiceL = 0; + ddUsageInfoGroup.ddUsageInfoRecord.crc = crc16( (U08*)&ddUsageInfoGroup.ddUsageInfoRecord, sizeof( DD_USAGE_INFO_RECORD_T ) - sizeof( U16 ) ); ddUsageInfoGroup.crc = crc16( (U08*)&ddUsageInfoGroup, sizeof( DD_USAGE_INFO_GROUP_T ) - sizeof( U16 ) ); // Service record has been touched so the entire sector 0 of the EEPROM must be rewritten @@ -1004,7 +1199,7 @@ * raises the specified alarm if invalid data is detected. * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if invalid record is * selected, nvAlarm if non-volatile data is invalid - * @details \b Inputs: ddCalibrationRecord + * @details \b Inputs: ddCalibrationGroup * @details \b Outputs: none * @param nvData The non-volatile data to be copied * @param bufferAddress Address of the provided buffer @@ -1025,61 +1220,61 @@ switch ( nvData ) { case GET_CAL_PRESSURE_SENOSRS: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.presSensorsCalRecord; + nvDataLength = sizeof( ddCalibrationGroup.ddCalibrationRecord.presSensorsCalRecord ); for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.presSensorsCalRecord.pressureSensors[ i ].calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationGroup.ddCalibrationRecord.presSensorsCalRecord.pressureSensors[ i ].calibrationTime ? TRUE : FALSE ); break; case GET_CAL_TEMP_SENSORS: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.tempSensorsCalRecord; + nvDataLength = sizeof( ddCalibrationGroup.ddCalibrationRecord.tempSensorsCalRecord ); for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.tempSensorsCalRecord.tempSensors[ i ].calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationGroup.ddCalibrationRecord.tempSensorsCalRecord.tempSensors[ i ].calibrationTime ? TRUE : FALSE ); break; case GET_CAL_CONCENTRATE_PUMPS_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.concentratePumpsRecord; + nvDataLength = sizeof( ddCalibrationGroup.ddCalibrationRecord.concentratePumpsRecord ); for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.concentratePumpsRecord.concentratePumps[ i ].calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationGroup.ddCalibrationRecord.concentratePumpsRecord.concentratePumps[ i ].calibrationTime ? TRUE : FALSE ); break; case GET_CAL_D12_PUMP_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.d12DialysatePumpRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.d12DialysatePumpRecord ); - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.d12DialysatePumpRecord.calibrationTime ? TRUE : FALSE ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord; + nvDataLength = sizeof( ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord ); + isNVDataInvalid |= ( 0 == ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord.calibrationTime ? TRUE : FALSE ); break; case GET_CAL_D48_PUMP_RECORD: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.d48DialysatePumpRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.d48DialysatePumpRecord ); - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.d48DialysatePumpRecord.d48DialysatePump.calibrationTime ? TRUE : FALSE ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.d48DialysatePumpRecord; + nvDataLength = sizeof( ddCalibrationGroup.ddCalibrationRecord.d48DialysatePumpRecord ); + isNVDataInvalid |= ( 0 == ddCalibrationGroup.ddCalibrationRecord.d48DialysatePumpRecord.d48DialysatePump.calibrationTime ? TRUE : FALSE ); break; case GET_CAL_ACID_CONCENTREATES: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.acidConcentratesRecord; + nvDataLength = sizeof( ddCalibrationGroup.ddCalibrationRecord.acidConcentratesRecord ); for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.acidConcentratesRecord.acidConcentrate[ i ].calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationGroup.ddCalibrationRecord.acidConcentratesRecord.acidConcentrate[ i ].calibrationTime ? TRUE : FALSE ); break; case GET_CAL_BICARB_CONCENTRATES: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.bicarbConcentratesRecord; + nvDataLength = sizeof( ddCalibrationGroup.ddCalibrationRecord.bicarbConcentratesRecord ); for ( i = 0; i < numOfSnsrs2Check; i++ ) - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.bicarbConcentratesRecord.bicarbConcentrate[ i ].calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationGroup.ddCalibrationRecord.bicarbConcentratesRecord.bicarbConcentrate[ i ].calibrationTime ? TRUE : FALSE ); break; case GET_CAL_ACCEL_SENSORS: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.accelerometerSensorCalRecord; - isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.accelerometerSensorCalRecord.calibrationTime ? TRUE : FALSE ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord; + isNVDataInvalid = ( 0 == ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord.calibrationTime ? TRUE : FALSE ); break; case GET_CAL_BLOOD_LEAK_SENSOR: - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.bloodLeakSensorCalRecord; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.bloodLeakSensorCalRecord ); - isNVDataInvalid = ( 0 == ddCalibrationRecord.ddCalibrationGroups.bloodLeakSensorCalRecord.calibrationTime ? TRUE : FALSE ); + nvDataStartPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord; + nvDataLength = sizeof( ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord ); + isNVDataInvalid = ( 0 == ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord.calibrationTime ? TRUE : FALSE ); break; case GET_SYSTEM_RECORD: @@ -1098,8 +1293,8 @@ break; case GET_USAGE_RECORD: - nvDataStartPtr = (U08*)&ddUsageInfoGroup.ddUsageInfo; - nvDataLength = sizeof( ddUsageInfoGroup.ddUsageInfo ); + nvDataStartPtr = (U08*)&ddUsageInfoGroup.ddUsageInfoRecord; + nvDataLength = sizeof( ddUsageInfoGroup.ddUsageInfoRecord ); break; default: @@ -1133,6 +1328,264 @@ return ( FALSE == isNVDataInvalid ? TRUE : FALSE ); } +BOOL setNVMRecord( NVM_RECORD_TYPE_T recType, U08* bufferAddress ) +{ + BOOL result = FALSE; + U08* destPtr = NULL; + U16 dataSize = 0; + + switch( recType ) + { + case NVM_SYSTEM_RECORD: + destPtr = (U08*)&ddSystemGroup.ddSystemRecord; + dataSize = sizeof( ddSystemGroup.ddSystemRecord ); + break; + + case NVM_SERVICE_RECORD: + destPtr = (U08*)&ddServiceGroup.ddServiceRecord; + dataSize = sizeof( ddServiceGroup.ddServiceRecord ); + break; + + case NVM_USAGE_INFO_RECORD: + destPtr = (U08*)&ddUsageInfoGroup.ddUsageInfoRecord; + dataSize = sizeof( ddUsageInfoGroup.ddUsageInfoRecord ); + break; + + default: + break; + } + + if ( (destPtr != NULL ) && ( bufferAddress != NULL ) && ( dataSize > 0 ) ) + { + + memcpy( destPtr, bufferAddress, dataSize ); + result = TRUE; + } + + return result; + +} + +BOOL setNVMCalRecord( DD_CAL_REC_TYPE calRecType, U08* bufferAddress, U08 idx ) +{ + BOOL result = FALSE; + U08* destPtr = NULL; + U16 dataSize = 0; + + switch (calRecType) + { + case DD_CAL_RECORD_PRESSURE_SENSOR: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.presSensorsCalRecord.pressureSensors[ idx ]; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.presSensorsCalRecord.pressureSensors[ 0 ] ); + break; + + case DD_CAL_RECORD_TEMPERATURE_SENSOR: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.tempSensorsCalRecord.tempSensors[ idx ]; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.tempSensorsCalRecord.tempSensors[ 0 ] ); + break; + + case DD_CAL_RECORD_CONCENTRATE_PUMP: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.concentratePumpsRecord.concentratePumps[ idx ]; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.concentratePumpsRecord.concentratePumps[ 0 ] ); + break; + + case DD_CAL_RECORD_D12_PUMP: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.d12DialysatePumpRecord ); + break; + + case DD_CAL_RECORD_D48_PUMP: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.d48DialysatePumpRecord; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.d48DialysatePumpRecord ); + break; + + case DD_CAL_RECORD_ACID_CONCENTRATE: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.acidConcentratesRecord.acidConcentrate[ idx ]; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.acidConcentratesRecord.acidConcentrate[ 0 ] ); + break; + + case DD_CAL_RECORD_BICARB_CONCENTRATE: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.bicarbConcentratesRecord.bicarbConcentrate[ idx ]; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.bicarbConcentratesRecord.bicarbConcentrate[ 0 ] ); + break; + + case DD_CAL_RECORD_ACCELEROMETER_SENSOR: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.accelerometerSensorCalRecord ); + break; + + case DD_CAL_RECORD_BLLOD_LEAK_SENSOR: + destPtr = (U08*)&ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord; + dataSize = sizeof( ddCalibrationGroup.ddCalibrationRecord.bloodLeakSensorCalRecord ); + break; + + default: + break; + } + + if ( (destPtr != NULL ) && ( bufferAddress != NULL ) && ( dataSize > 0 ) ) + { + memcpy( destPtr, bufferAddress, dataSize ); + result = TRUE; + } + + return result; +} + +BOOL setNVMInstitRecord( DD_INSTIT_REC_TYPE institRecType, U08 *valuePtr ) +{ + BOOL result = FALSE; + + U08 *destPtr = NULL; + U16 dataSize = 0; + + switch (institRecType) + { + case DD_INSTIT_MIN_DIALYSATE_FLOW_MLPM: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minDialysateFlowMLPM; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MAX_DIALYSATE_FLOW_MLPM: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateFlowMLPM; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MIN_DIALYSATE_TEMP_C: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minDialysateTempC; + dataSize = sizeof(F32); + break; + + case DD_INSTIT_MAX_DIALYSATE_TEMP_C: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateTempC; + dataSize = sizeof(F32); + break; + + case DD_INSTIT_MIN_ACID_CONCENTRATE: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minAcidConcentrate; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MAX_ACID_CONCENTRATE: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.maxAcidConcentrate; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MIN_BICARB_CARTRIDGE_SIZE_G: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minBicarbCartridgeSizeG; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MAX_BICARB_CARTRIDGE_SIZE_G: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.maxBicarbCartridgeSizeG; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MIN_SODIUM_MEQL: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minSodiumMEQL; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MAX_SODIUM_MEQL: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.maxSodiumMEQL; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MIN_BICARBONATE_MEQL: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minBicarbonateMEQL; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MAX_BICARBONATE_MEQL: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.maxBicarbonateMEQL; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_MIN_RO_REJECTION_RATIO_PCT: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minRORejectionRatioPCT; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_DISINFECTION_FREQUENCY: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.disinfectionFrequency; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_DISINFECTION_CYCLE_TIME: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.disinfectionCycleTime; + dataSize = sizeof(F32); + break; + + case DD_INSTIT_MIN_INLET_WATER_COND_ALARM_LIMIT_USPCM: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minInletWaterCondAlarmLimitUSPCM; + dataSize = sizeof(F32); + break; + + case DD_INSTIT_MAX_INLET_WATER_COND_ALARM_LIMIT_USPCM: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.maxInletWaterCondAlarmLimitUSPCM; + dataSize = sizeof(F32); + break; + + case DD_INSTIT_ACID_CONCENTRATE_JUG_SIZE_L: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.acidConcentrateJugSizeL; + dataSize = sizeof(F32); + break; + + case DD_INSTIT_MIN_ACID_ALARM_LIMIT_PCT: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minAcidAlarmLimitPCT; + dataSize = sizeof(F32); + break; + + case DD_INSTIT_MIN_BICARB_ALARM_LIMIT_PCT: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.minBicarbAlarmLimitPCT; + dataSize = sizeof(F32); + break; + + case DD_INSTIT_POST_TREAT_DRAIN_OPTION: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.postTreatDrainOption; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_POST_TREAT_DRY_BICARB_OPTION: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.postTreatDryBicarbOption; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_CALIBRATION_TIME: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.calibrationTime; + dataSize = sizeof(U32); + break; + + case DD_INSTIT_CRC: + destPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord.crc; + dataSize = sizeof(U32); + break; + + + default: + break; + } + + if ( ( NULL != destPtr ) && ( NULL != valuePtr ) && ( dataSize > 0 ) ) + { + memcpy( destPtr, valuePtr, dataSize ); + + // Update CRC after every change + ddInstitutionalGroup.crc = crc16( (U08*)&ddInstitutionalGroup.ddInstitutionalRecord, + sizeof( DD_INSTITUTIONAL_RECORD_T ) - sizeof(U16) ); + + result = TRUE; + } + + return result; +} + +void sendNVEvent( NVM_RECORD_TYPE_T recType, U32 d1, U32 d2 ) +{ + + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[recType].nvEvent, d1, d2 ); +} + /*********************************************************************//** * @brief * The updateNVSelfTestResult function updates the NV data management @@ -1176,6 +1629,7 @@ } + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -1188,21 +1642,21 @@ * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if invalid job is * selected * @details \b Inputs: none - * @details \b Outputs: ddCalibrationRecord, ddSystemGroup, + * @details \b Outputs: ddCalibrationGroup, ddSystemGroup, * ddServiceGroup, ddInstitutionalGroup, ddUsageInfoGroup * @param job The job whose CRC needs to be overridden * @param crc The CRC value to be set * @return TRUE if the job was scheduled successfully otherwise FALSE *************************************************************************/ BOOL updateNVRecordCRC( U32 job, U16 crc ) { - BOOL status = FALSE; + BOOL status = FALSE; NVM_RECORD_TYPE_T nvJob = (NVM_RECORD_TYPE_T)job; switch( nvJob ) { case NVM_CALIBRATION_RECORD: - ddCalibrationRecord.crc = crc; + ddCalibrationGroup.crc = crc; break; case NVM_SYSTEM_RECORD: @@ -1218,7 +1672,7 @@ break; case NVM_USAGE_INFO_RECORD: - ddUsageInfoGroup.ddUsageInfo.crc = crc; + ddUsageInfoGroup.ddUsageInfoRecord.crc = crc; break; default: