Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r8e08352e9e7d8749d8f093c6bc57e6dbc32605d5 -r3f2b9de757500da37e0ed8881e4e906d94f3076c --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 8e08352e9e7d8749d8f093c6bc57e6dbc32605d5) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 3f2b9de757500da37e0ed8881e4e906d94f3076c) @@ -14,10 +14,12 @@ * @date (original) 02-Mar-2021 * ***************************************************************************/ +#include #include "AlarmMgmt.h" #include "FPGA.h" -#include "ModeTreatmentParams.h" +#include "ModeTreatmentParams.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SafetyShutdown.h" @@ -216,6 +218,7 @@ static U32 syringePumpStallCtr; ///< Counts time when position is not changing during ramp. static U32 syringePumpStallRetryCount; ///< Counts pump ramp up stall retries. +static HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T forceSensorCalRecord; ///< HD heparin force sensor calibration record. // ********** private function prototypes ********** @@ -251,6 +254,7 @@ static BOOL checkVolumeVsSafetyVolume( BOOL stopPump, F32 pctMargin ); static BOOL checkForStall( BOOL stopPump ); static void publishSyringePumpData( void ); +static BOOL processCalibrationData( void ); /*********************************************************************//** * @brief @@ -946,6 +950,15 @@ *************************************************************************/ static void execSyringePumpMonitor( void ) { + F32 forceSensorBeforCal = 0.0; + + // Check if a new calibration is available + if ( TRUE == isNewCalibrationRecordAvailable() ) + { + // Get the new calibration data and check its validity + processCalibrationData(); + } + S32 encPosition = getFPGASyringePumpEncoderPosition(); // Get latest FPGA status @@ -957,7 +970,14 @@ // Get latest ADC data and convert to V syringePumpMeasHome.data = ( (F32)getFPGASyringePumpADCChannel2() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; syringePumpMeasSyringeDetectionSwitch.data = ( (F32)getFPGASyringePumpADCChannel1() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; - syringePumpMeasForce.data = ( (F32)getFPGASyringePumpADCChannel0() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; + + forceSensorBeforCal = ( (F32)getFPGASyringePumpADCChannel0() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; + syringePumpMeasForce.data = pow(forceSensorBeforCal, 4) * forceSensorCalRecord.hdHeparinForceSensor.fourthOrderCoeff + + pow(forceSensorBeforCal, 3) * forceSensorCalRecord.hdHeparinForceSensor.thirdOrderCoeff + + pow(forceSensorBeforCal, 2) * forceSensorCalRecord.hdHeparinForceSensor.secondOrderCoeff + + forceSensorBeforCal * forceSensorCalRecord.hdHeparinForceSensor.gain + + forceSensorCalRecord.hdHeparinForceSensor.offset; + // Apply home offset to encoder position syringePumpLastPosition = getSyringePumpPosition(); syringePumpPosition.data = encPosition - syringePumpHomePositionOffset; @@ -1059,6 +1079,33 @@ // Publish syringe pump data on interval publishSyringePumpData(); +} + +/*********************************************************************//** + * @brief + * The execSyringePumpSelfTest function executes the state machine for the + * syringe pump self-test. + * @details Inputs: none + * @details Outputs: none + * @return the current state of the BloodFlow self-test. + *************************************************************************/ +SELF_TEST_STATUS_T execSyringePumpSelfTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + + BOOL calStatus = processCalibrationData(); + + if ( TRUE == calStatus ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + result = SELF_TEST_STATUS_FAILED; + activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_SELF_TEST_FAILURE ); + } + + return result; } /*********************************************************************//** @@ -1813,6 +1860,43 @@ broadcastHeparinData( data.syringePumpVolumeDelivered ); syringePumpDataPublicationTimerCounter = 0; } +} + +/*********************************************************************//** + * @brief + * The processCalibrationData function gets the calibration data and makes + * sure it is valid by checking the calibration date. The calibration date + * should not be 0. + * @details Inputs: none + * @details Outputs: forceSensorCalRecord + * @return TRUE if the calibration record is valid, otherwise FALSE + *************************************************************************/ +static BOOL processCalibrationData( void ) +{ + BOOL status = TRUE; + + // Get the calibration record from NVDataMgmt + HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T calData = getHDHeparinForceSensorCalibrationRecord(); + + // Check if the calibration data that was received from NVDataMgmt is legitimate + // The calibration date item should not be zero. If the calibration date is 0, + // then the heparin force sensors data is not stored in the NV memory or it was corrupted. + if ( 0 == calData.hdHeparinForceSensor.calibrationTime ) + { +#ifndef SKIP_CAL_CHECK + activateAlarmNoData( ALARM_ID_HD_HEPARIN_FORCE_SENSOR_INVALID_CAL_RECORD ); + status = FALSE; +#endif + } + + // The calibration data was valid, update the local copy + forceSensorCalRecord.hdHeparinForceSensor.fourthOrderCoeff = calData.hdHeparinForceSensor.fourthOrderCoeff; + forceSensorCalRecord.hdHeparinForceSensor.thirdOrderCoeff = calData.hdHeparinForceSensor.thirdOrderCoeff; + forceSensorCalRecord.hdHeparinForceSensor.secondOrderCoeff = calData.hdHeparinForceSensor.secondOrderCoeff; + forceSensorCalRecord.hdHeparinForceSensor.gain = calData.hdHeparinForceSensor.gain; + forceSensorCalRecord.hdHeparinForceSensor.offset = calData.hdHeparinForceSensor.offset; + + return status; }