Index: NVDataMgmt.c =================================================================== diff -u -re1da2cdff2dc0a62f78c08a46976f937c8c7bdf5 -r30d739bd7fbf62a37de77fcf5d5c0cbd121c5bb3 --- NVDataMgmt.c (.../NVDataMgmt.c) (revision e1da2cdff2dc0a62f78c08a46976f937c8c7bdf5) +++ NVDataMgmt.c (.../NVDataMgmt.c) (revision 30d739bd7fbf62a37de77fcf5d5c0cbd121c5bb3) @@ -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 @@ -97,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. @@ -140,7 +144,7 @@ #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.25F ///< Reservoir temperature time constant C/min. -#define DEFAULT_UF_TEMP_TAU_C_PER_MIN -1.0F ///< Ultrafilter 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 0.0F ///< Fill acid 1251_1 acid sensor conductivity uS/cm. @@ -412,18 +416,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 @@ -470,18 +482,20 @@ 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 - {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 + // 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 }; #endif @@ -604,6 +618,7 @@ 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 ); @@ -891,12 +906,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 ); @@ -910,14 +936,20 @@ // CRC passed, enqueue an erase, a write of calibration data and a write of service record BOOL scheduleStatus = enqueueSector0Records(); +#ifdef _HD_ + // 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 ); +#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 ); } @@ -1085,6 +1117,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; @@ -1719,6 +1756,12 @@ status = TRUE; } break; + +#ifdef _HD_ + case NVDATAMGMT_INTITUTIONAL_RECORD: + hdInstitutionalGroup.hdInstitutionalRecord.crc = crc; + break; +#endif } return status; @@ -1760,6 +1803,7 @@ BOOL haveCalGroupsPassed = TRUE; BOOL hasSystemRecordPassed = TRUE; BOOL hasServiceRecordPassed = TRUE; + BOOL hasInstitutionalRecordPassed = TRUE; BOOL hasSWConfigRecordPassed = TRUE; BOOL hasUsageRecordPassed = TRUE; @@ -1776,24 +1820,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_ @@ -1811,7 +1859,7 @@ } // 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; @@ -2355,6 +2403,12 @@ #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_ @@ -3845,6 +3899,60 @@ /*********************************************************************//** * @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 = getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_BLOOD_FLOW ); + hdInstitutionalGroup.hdInstitutionalRecord.maxBloodFlowMLPM = getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_BLOOD_FLOW ); + hdInstitutionalGroup.hdInstitutionalRecord.minDialysateFlowMLPM = getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_DIALYSATE_FLOW ); + hdInstitutionalGroup.hdInstitutionalRecord.maxDialysateFlowMLPM = getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_DIALYSATE_FLOW ); + hdInstitutionalGroup.hdInstitutionalRecord.minTxDurationMIN = getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_TREATMENT_DURATION ); + hdInstitutionalGroup.hdInstitutionalRecord.maxTxDurationMIN = getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_TREATMENT_DURATION ); + hdInstitutionalGroup.hdInstitutionalRecord.minStopHeparinDispBeforeTxEndMIN = getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); + hdInstitutionalGroup.hdInstitutionalRecord.maxStopHeparinDispBeforeTxEndMIN = getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); + hdInstitutionalGroup.hdInstitutionalRecord.minSalineBolusVolumeML = getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); + hdInstitutionalGroup.hdInstitutionalRecord.maxSalineBolusVolumeML = getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); + hdInstitutionalGroup.hdInstitutionalRecord.minDialysateTempC = getF32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxDialysateTempC = getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + hdInstitutionalGroup.hdInstitutionalRecord.minArtPressLimitWindowMMHG = getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ); + hdInstitutionalGroup.hdInstitutionalRecord.maxArtPressLimitWindowMMHG = getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ); + hdInstitutionalGroup.hdInstitutionalRecord.minVenPressLimitWindowMMHG = getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ); + hdInstitutionalGroup.hdInstitutionalRecord.maxVenPressLimitWindowMMHG = getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ); + hdInstitutionalGroup.hdInstitutionalRecord.minVenAsymPressLimitMMHG = getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ); + hdInstitutionalGroup.hdInstitutionalRecord.maxVenAsymPressLimitMMHG = getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ); + hdInstitutionalGroup.hdInstitutionalRecord.minUFVolumeL = getF32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_UF_VOLUME ); + hdInstitutionalGroup.hdInstitutionalRecord.maxUFVolumeL = getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_UF_VOLUME ); + hdInstitutionalGroup.hdInstitutionalRecord.minHeparinDispRateMLPHR = getF32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); + hdInstitutionalGroup.hdInstitutionalRecord.maxHeparinDispRateMLPHR = getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); + hdInstitutionalGroup.hdInstitutionalRecord.minHeparinBolusVolumeML = getF32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + hdInstitutionalGroup.hdInstitutionalRecord.maxHeparinBolusVolumeML = getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + 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