Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r87d883239d8367b92840cade0802dc36d9c83d80 -r8466e63f95f65a3ffb18c3af85ac99328e41167b --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 87d883239d8367b92840cade0802dc36d9c83d80) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 8466e63f95f65a3ffb18c3af85ac99328e41167b) @@ -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,12 +218,12 @@ 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 ********** static void resetSyringePumpRequestFlags( void ); static void execSyringePumpMonitor( void ); -static U32 getPublishSyringePumpDataInterval( void ); static S32 getSyringePumpPosition( void ); static F32 getSyringePumpMeasRate( void ); static F32 getSyringePumpSyringeDetectorV( void ); @@ -251,6 +253,7 @@ static BOOL checkVolumeVsSafetyVolume( BOOL stopPump, F32 pctMargin ); static BOOL checkForStall( BOOL stopPump ); static void publishSyringePumpData( void ); +static BOOL processCalibrationData( void ); /*********************************************************************//** * @brief @@ -351,6 +354,7 @@ accepted = TRUE; heparinDeliveryState = HEPARIN_STATE_PAUSED; stopSyringePump(); + sendTreatmentLogEventData( HEPARIN_PAUSE_RESUME_EVENT, HEPARIN_STATE_DISPENSING, HEPARIN_STATE_PAUSED ); } else { @@ -363,6 +367,7 @@ { accepted = TRUE; startHeparinContinuous(); + sendTreatmentLogEventData( HEPARIN_PAUSE_RESUME_EVENT, HEPARIN_STATE_PAUSED, HEPARIN_STATE_DISPENSING ); } else { @@ -619,26 +624,6 @@ /*********************************************************************//** * @brief - * The getPublishSyringePumpDataInterval function gets the syringe pump data - * publication interval. - * @details Inputs: syringePumpDataPublishInterval - * @details Outputs: none - * @return the current syringe pump data publication interval (in task intervals). - *************************************************************************/ -static U32 getPublishSyringePumpDataInterval( void ) -{ - U32 result = syringePumpDataPublishInterval.data; - - if ( OVERRIDE_KEY == syringePumpDataPublishInterval.override ) - { - result = syringePumpDataPublishInterval.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief * The getSyringePumpVolumeDelivered function gets the current syringe pump * volume delivered. * @details Inputs: syringePumpVolumeDelivered @@ -944,6 +929,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 @@ -955,7 +949,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; @@ -1057,6 +1058,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; } /*********************************************************************//** @@ -1788,7 +1816,7 @@ static void publishSyringePumpData( void ) { // Publish syringe pump data on interval - if ( ++syringePumpDataPublicationTimerCounter >= getPublishSyringePumpDataInterval() ) + if ( ++syringePumpDataPublicationTimerCounter >= getU32OverrideValue( &syringePumpDataPublishInterval ) ) { SYRINGE_PUMP_DATA_PAYLOAD_T data; @@ -1811,6 +1839,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; }