Index: firmware/App/Services/NVRecordsDD.c =================================================================== diff -u -rb878faee61a0800b767d053ab3f65afb3790dacb -rf525d2be1e7038cacbe2bb34b8db3505cf26a350 --- firmware/App/Services/NVRecordsDD.c (.../NVRecordsDD.c) (revision b878faee61a0800b767d053ab3f65afb3790dacb) +++ firmware/App/Services/NVRecordsDD.c (.../NVRecordsDD.c) (revision f525d2be1e7038cacbe2bb34b8db3505cf26a350) @@ -151,15 +151,32 @@ // ********** private data ********** -// NVM Record variables +// 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_NVDATMGMT_RECORDS_JOBS ] = { + // 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 }, // NVDATAMGMT_SYSTEM_RECORD + {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SERVICE_GROUP_T), (U08*)&ddTempRxServiceGrp, (U08*)&ddTempRxServiceGrp.crc, DD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD + {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_CALIBRATION_RECORD_T), (U08*)&ddTempRxCalRecord, (U08*)&ddTempRxCalRecord.crc, DD_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD + {INSTIT_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_INSTITUTIONAL_GROUP_T), (U08*)&ddTempRxInstitGrp, (U08*)&ddTempRxInstitGrp.crc, DD_EVENT_INSTIT_RECORD_UPDATE }, // NVDATAMGMT_INSTITUTIONAL_RECORD + {USAGE_INFO_START_ADDRESS, sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddTempRxUsageGrp, (U08*)&ddTempRxUsageGrp.crc, DD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_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_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). -// Process records specifications -const PROCESS_RECORD_SPECS_T RECORDS_SPECS[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] +// Main Process records specifications +const PROCESS_RECORD_SPECS_T RECORDS_SPECS[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { // 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 }, // NVDATAMGMT_SYSTEM_RECORD {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SERVICE_GROUP_T), (U08*)&ddServiceGroup, (U08*)&ddServiceGroup.crc, DD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD @@ -183,7 +200,6 @@ static BOOL isPolynomialRecordValid( POLYNOMIAL_CAL_PAYLOAD_T* record ); static BOOL isDDSystemRecordValid( void ); static BOOL isDDServiceRecordValid( void ); -static BOOL isDDInstitutionalRecordValid( void ); static BOOL isDDUsageRecordValid( void ); static BOOL isDDCalibrationRecordValid( void ); static BOOL isDDDrainPumpRecordValid( DD_DRAIN_PUMP_CAL_RECORD_T* record ); @@ -235,6 +251,7 @@ nvDataMgmtSelfTestState = NVDATAMGMT_SELF_TEST_STATE_COMPLETE; nvDataMgmtSelfTestResult = SELF_TEST_STATUS_FAILED; break; + } return nvDataMgmtSelfTestResult; @@ -245,6 +262,11 @@ return RECORDS_SPECS[ job ]; } +PROCESS_RECORD_SPECS_T getTemporaryRxRecord( RECORD_JOBS_STATE_T job ) +{ + return tempRxRecords[ job ]; +} + /*********************************************************************//** * @brief * The handleSelfTestReadRecords waits for the records to be read @@ -278,45 +300,53 @@ static NVDATAMGMT_SELF_TEST_STATE_T handleSelfTestCheckCRC ( void ) { NVDATAMGMT_SELF_TEST_STATE_T state = NVDATAMGMT_SELF_TEST_STATE_COMPLETE; - BOOL haveCalGroupsPassed = TRUE; BOOL hasSystemRecordPassed = TRUE; BOOL hasServiceRecordPassed = TRUE; - BOOL hasInstitutionalRecordPassed = TRUE; + BOOL haveCalGroupsPassed = TRUE; BOOL hasUsageRecordPassed = TRUE; updateRecordReadStatus( NVDATAMGMT_RECORDS_CRC_CHECKED ); // Check all the calibration groups haveCalGroupsPassed = isDDCalibrationRecordValid(); - hasSystemRecordPassed = isDDSystemRecordValid(); hasServiceRecordPassed = isDDServiceRecordValid(); hasUsageRecordPassed = isDDUsageRecordValid(); // If any of the records did not pass, they should be filled - // with benign values. After that, schedule a write to sector 0 + // with benign values. After that, schedule a write to sector // to re-write the records with the benign values - if ( ( FALSE == hasServiceRecordPassed ) || ( FALSE == haveCalGroupsPassed ) || - ( FALSE == hasSystemRecordPassed ) || ( FALSE == hasInstitutionalRecordPassed ) ) + + // Validate system record + hasSystemRecordPassed = isDDSystemRecordValid(); + if ( FALSE == hasSystemRecordPassed ) { - enqueueSector0Records(); - SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_CALIBRATION_RECORD ].nvEvent, 0, 0 ); + enqueueEraseAndWriteSector ( NVDATAMGMT_SYSTEM_RECORD ); 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 ); } + // Validate service and calibration records + hasServiceRecordPassed = isDDServiceRecordValid(); + haveCalGroupsPassed = isDDCalibrationRecordValid(); + if ( ( FALSE == hasServiceRecordPassed ) || ( FALSE == haveCalGroupsPassed ) ) + { + enqueueEraseAndWriteSector ( NVDATAMGMT_SERVICE_RECORD ); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ].nvEvent, 0, 0 ); + SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_CALIBRATION_RECORD ].nvEvent, 0, 0 ); + } + // Validate usage info record if ( FALSE == hasUsageRecordPassed ) { - enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_USAGE_INFO_RECORD ); + enqueueEraseAndWriteSector ( NVDATAMGMT_USAGE_INFO_RECORD ); SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ); } // Check if the records' entire CRCs as well as the individual CRCs passed - if ( ( TRUE == haveCalGroupsPassed ) && ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) && ( TRUE == hasInstitutionalRecordPassed ) ) + if ( ( TRUE == hasSystemRecordPassed ) && ( TRUE == hasServiceRecordPassed ) && + ( TRUE == haveCalGroupsPassed ) && ( TRUE == hasUsageRecordPassed ) ) { updateRecordStartTimer( getMSTimerCount() ); updateNewNVRecordAvailableFlag( TRUE ); nvDataMgmtSelfTestResult = SELF_TEST_STATUS_PASSED; - } else { @@ -449,62 +479,6 @@ /*********************************************************************//** * @brief - * The isDDInstitutionalRecordValid function checks the validity of the HD - * institutional record. - * @details Inputs: ddInstitutionalGroup.ddInstitutionalRecord - * @details Outputs: none - * @return TRUE if the HD institutional record is valid otherwise FALSE - *************************************************************************/ -static BOOL isDDInstitutionalRecordValid( void ) -{ - BOOL status = TRUE; - U16 calcCRC = crc16( (U08*)&ddInstitutionalGroup.ddInstitutionalRecord, sizeof( DD_INSTITUTIONAL_RECORD_T ) - sizeof( U16 ) ); - U16 recordCRC = ddInstitutionalGroup.ddInstitutionalRecord.crc; - - if ( calcCRC != recordCRC ) - { - // CRC did not pass so set all values to default -// ddInstitutionalGroup.ddInstitutionalRecord.minBloodFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_BLOOD_FLOW, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxBloodFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_BLOOD_FLOW, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minDialysateFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_FLOW, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_FLOW, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minTxDurationMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_TREATMENT_DURATION, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxTxDurationMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_TREATMENT_DURATION, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minStopHeparinDispBeforeTxEndMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxStopHeparinDispBeforeTxEndMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minSalineBolusVolumeML = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_SALINE_BOLUS_VOLUME, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxSalineBolusVolumeML = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_SALINE_BOLUS_VOLUME, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minDialysateTempC = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_TEMPERATURE, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateTempC = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_TEMPERATURE, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minArtPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxArtPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minVenPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxVenPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minVenAsymPressLimitMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxVenAsymPressLimitMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minUFVolumeL = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_UF_VOLUME, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxUFVolumeL = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_UF_VOLUME, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minHeparinDispRateMLPHR = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxHeparinDispRateMLPHR = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minHeparinBolusVolumeML = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME, TRUE ); -// ddInstitutionalGroup.ddInstitutionalRecord.maxHeparinBolusVolumeML = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME, FALSE ); -// ddInstitutionalGroup.ddInstitutionalRecord.minRORejectionRatioPCT = DEFAULT_MAX_RO_REJECTION_RATIO_PCT; -// ddInstitutionalGroup.ddInstitutionalRecord.minInletWaterCondAlarmLimitUSPCM = DEFAULT_MIN_INLET_WATER_COND_ALARM_US_P_CM; -// ddInstitutionalGroup.ddInstitutionalRecord.calibrationTime = getRTCTimestamp(); -// ddInstitutionalGroup.ddInstitutionalRecord.crc = crc16 ( (U08*)&ddInstitutionalGroup.ddInstitutionalRecord, -// sizeof( DD_INSTITUTIONAL_RECORD_T ) - sizeof( U16 ) ); -// ddInstitutionalGroup.crc = crc16 ( (U08*)&ddInstitutionalGroup, 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 isDDUsageRecordValid function checks whether the DG usage information * is valid or not. * @details Inputs: ddUsageInfoGroup @@ -1095,6 +1069,10 @@ acidSensorCond = DEFAULT_BIC_TEST_ACID_SNSR_US_PER_CM; bicarbSensorCond = DEFAULT_BIC_TEST_BIC_SNSR_US_PER_CM; break; + + default: + // Software fault + break; } // CRC did not pass so set all values to default @@ -1167,7 +1145,7 @@ usageWriteTries = 0; status = TRUE; - enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_USAGE_INFO_RECORD ); + enqueueEraseAndWriteSector( NVDATAMGMT_USAGE_INFO_RECORD ); SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ); } else if ( ++usageWriteTries > MAX_NUM_OF_WRITE_TRIES ) @@ -1207,8 +1185,8 @@ 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 - enqueueSector0Records(); - enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_USAGE_INFO_RECORD ); + enqueueEraseAndWriteSector( NVDATAMGMT_SERVICE_RECORD ); + enqueueEraseAndWriteSector( NVDATAMGMT_USAGE_INFO_RECORD ); // Both the usage and service records have been updated SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_USAGE_INFO_RECORD ].nvEvent, 0, 0 ); SEND_EVENT_WITH_2_U32_DATA( RECORDS_SPECS[ NVDATAMGMT_SERVICE_RECORD ].nvEvent, 0, 0 ); @@ -1450,35 +1428,31 @@ { case NVDATAMGMT_CALIBRATION_RECORD: ddCalibrationRecord.crc = crc; - status = enqueueSector0Records(); break; case NVDATAMGMT_SYSTEM_RECORD: ddSystemGroup.ddSystemRecord.crc = crc; - status = enqueueSector0Records(); break; case NVDATAMGMT_SERVICE_RECORD: ddServiceGroup.ddServiceRecord.crc = crc; - status = enqueueSector0Records(); break; case NVDATAMGMT_INSTITUTIONAL_RECORD: ddInstitutionalGroup.ddInstitutionalRecord.crc = crc; - status = enqueueSector0Records(); break; case NVDATAMGMT_USAGE_INFO_RECORD: ddUsageInfoGroup.ddUsageInfo.crc = crc; - if ( getAvailableRecordQueueCount() > 0 ) - { - enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_USAGE_INFO_RECORD ); - status = TRUE; - } break; + default: + // Software fault + break; } + status = enqueueEraseAndWriteSector( nvJob ); + return status; }