Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r068f4f4de69017a1d9d24c6c67bf7d3e46b8caed -rb1f086e7cd292d5a97a7265075400274d60d4fbf --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 068f4f4de69017a1d9d24c6c67bf7d3e46b8caed) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision b1f086e7cd292d5a97a7265075400274d60d4fbf) @@ -8,7 +8,7 @@ * @file SyringePump.c * * @author (last) Dara Navaei -* @date (last) 15-Jun-2022 +* @date (last) 13-Jul-2022 * * @author (original) Sean Nash * @date (original) 04-Mar-2021 @@ -87,6 +87,7 @@ #define SYRINGE_PUMP_MAX_RATE_ERROR_ML_HR 0.1F ///< Maximum Heparin delivery rate error (in mL/hr). #define TEN_PCT_OVER_ALLOWANCE 1.1F ///< Allow 10 percent over target before alarming on over travel. #define FIVE_PCT_OVER_ALLOWANCE 1.05F ///< Allow 5 percent over target before alarming on over travel. +#define SYRINGE_PUMP_DAC_VOLTAGE_MAX_ERROR 0.05F ///< Force sensor POST check for DAC voltage - max delta. /// Expected position of empty in relation to home position. #define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84F ) @@ -189,6 +190,8 @@ static OVERRIDE_U32_T syringePumpADCandDACStatus = {0, 0, 0, 0}; ///< Syringe pump ADC and DAC status reported by FPGA. static OVERRIDE_U32_T syringePumpADCReadCtr = {0, 0, 0, 0}; ///< Syringe pump ADC read counter reported by FPGA. +static BOOL requireSyringeDetection; ///< Flag indicating whether syringe detection is required in the current state. + static F32 syringePumpSetRate; ///< Set rate for syringe pump (in mL/hr). static F32 forceAtEndOfSeek; ///< Force sensor reading in Volts at the end of seek. static U32 syringePumpSetToggleTime; ///< Set rate for syringe pump (in uSec/toggle). @@ -272,10 +275,9 @@ void initSyringePump( void ) { U32 i; - syringePumpState = SYRINGE_PUMP_INIT_STATE; heparinDeliveryState = HEPARIN_STATE_OFF; - + requireSyringeDetection = FALSE; syringePumpSetRate = 0.0; syringePumpSetToggleTime = 0; syringePumpSafetyVolumeDelivered = 0.0; @@ -496,15 +498,12 @@ { heparinDeliveryState = HEPARIN_STATE_STOPPED; } - if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) ) + if ( ( isSyringePumpHome() != TRUE ) && ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) ) { { - heparinDeliveryState = HEPARIN_STATE_STOPPED; - if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) ) - { - syringePumpSetRate = SYRINGE_PUMP_RETRACT_RATE; - syringePumpRetractRequested = TRUE; - } + heparinDeliveryState = HEPARIN_STATE_STOPPED; + syringePumpSetRate = SYRINGE_PUMP_RETRACT_RATE; + syringePumpRetractRequested = TRUE; } } @@ -605,7 +604,6 @@ { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (F32)SW_FAULT_ID_HD_SYRINGE_INVALID_BOLUS_CMD, syringePumpSetRate ) } - } return syringePumpBolusRequested; @@ -653,12 +651,13 @@ * The setSyringePumpDACVref function requests to set the DAC Vref setting. * @details Inputs: none * @details Outputs: syringePumpDACVrefSetRequested, syringePumpDACVref - * @param vRef voltage to set DAC Vref to (in V) * @return TRUE if request accepted, FALSE if not *************************************************************************/ -BOOL setSyringePumpDACVref( F32 vRef ) +BOOL setSyringePumpDACVref( void ) { - if ( ( vRef >= 0.0 ) && ( vRef <= 3.3 ) ) + F32 vRef = forceSensorCalRecord.hdHeparinForceSensorDACVoltage; + + if ( ( vRef >= 0.0 ) && ( vRef <= SYRINGE_PUMP_ADC_REF_V ) ) { if ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) { @@ -676,6 +675,20 @@ /*********************************************************************//** * @brief + * The syringeDetectionRequired function sets a flag indicating whether + * the syringe detection is required in current state. + * @details Inputs: none + * @details Outputs: requireSyringeDetection + * @param req True if syringe detection is required in the current state + * @return none + *************************************************************************/ +void syringeDetectionRequired( BOOL req ) +{ + requireSyringeDetection = req; +} + +/*********************************************************************//** + * @brief * The getSyringePumpVolumeDelivered function gets the current syringe pump * volume delivered. * @details Inputs: syringePumpVolumeDelivered @@ -939,7 +952,6 @@ *************************************************************************/ static void execSyringePumpMonitor( void ) { - F32 forceSensorBeforCal = 0.0; BOOL prevSyringeDetected = isSyringeDetected(); // Check if a new calibration is available @@ -960,45 +972,62 @@ // 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; +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP ) != SW_CONFIG_DISABLE_VALUE ) + { + syringePumpMeasSyringeDetectionSwitch.data = 0.0; // if syringe pump disabled, always report no detection + } + else +#endif + { + syringePumpMeasSyringeDetectionSwitch.data = ( (F32)getFPGASyringePumpADCChannel1() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; + } // Log syringe detect switch changes if ( prevSyringeDetected != isSyringeDetected() ) { sendTreatmentLogEventData( SYRINGE_DETECTION_SWITCH_CHANGED_EVENT, (F32)prevSyringeDetected, (F32)isSyringeDetected() ); } + // Handle syringe detect alarm management #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) #endif { - // On transition from not detected to detected - clear syringe removed alarm condition - if ( ( prevSyringeDetected != TRUE ) && ( TRUE == isSyringeDetected() ) ) + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + F32 hepRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); + + // Syringe detection not required if not using Heparin in treatment + if ( ( bolusVol > NEARLY_ZERO ) || ( hepRate > NEARLY_ZERO ) ) { - clearAlarmCondition( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_REMOVED ); + // On transition from not detected to detected or if syringe detection not required - clear syringe removed alarm condition + if ( ( ( prevSyringeDetected != TRUE ) && ( TRUE == isSyringeDetected() ) ) || ( requireSyringeDetection != TRUE ) ) + { + clearAlarmCondition( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_REMOVED ); + } + // If no syringe detected and detection is required, trigger alarm condition + else if ( ( FALSE == isSyringeDetected() ) && ( TRUE == requireSyringeDetection ) ) + { + activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_REMOVED ); + } + // On transition from detected to not detected - clear syringe detected alarm condition + if ( ( TRUE == prevSyringeDetected ) && ( isSyringeDetected() != TRUE ) ) + { + clearAlarmCondition( ALARM_ID_HD_SYRINGE_DETECTED ); + } + // If syringe detected and alarm active, maintain alarm condition + else if ( ( TRUE == isSyringeDetected() ) && ( TRUE == isAlarmActive( ALARM_ID_HD_SYRINGE_DETECTED ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_SYRINGE_DETECTED ); + } } - // If no syringe detected while syringe removed alarm is active, maintain alarm condition - else if ( ( FALSE == isSyringeDetected() ) && ( TRUE == isAlarmActive( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_REMOVED ) ) ) + else { - activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_REMOVED ); - } - // On transition from detected to not detected - clear syringe detected alarm condition - if ( ( TRUE == prevSyringeDetected ) && ( isSyringeDetected() != TRUE ) ) - { + clearAlarmCondition( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_REMOVED ); clearAlarmCondition( ALARM_ID_HD_SYRINGE_DETECTED ); } - // If syringe detected while syringe detected alarm is active, maintain alarm condition - else if ( ( TRUE == isSyringeDetected() ) && ( TRUE == isAlarmActive( ALARM_ID_HD_SYRINGE_DETECTED ) ) ) - { - activateAlarmNoData( ALARM_ID_HD_SYRINGE_DETECTED ); - } } - 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; + syringePumpMeasForce.data = ( (F32)getFPGASyringePumpADCChannel0() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; // Apply home offset to encoder position syringePumpLastPosition = getSyringePumpPosition(); @@ -1128,11 +1157,15 @@ SELF_TEST_STATUS_T execSyringePumpSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; - + F32 DACDeltaV; + // Read/check force sensor calibration BOOL calStatus = getNVRecord2Driver( GET_CAL_HEPARIN_FORCE_SENSOR, (U08*)&forceSensorCalRecord, sizeof( HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T ), 0, ALARM_ID_HD_HEPARIN_FORCE_SENSOR_INVALID_CAL_RECORD ); - if ( TRUE == calStatus ) + // Verify calibration + DACDeltaV = fabs( forceSensorCalRecord.hdHeparinForceSensorDACVoltage - getSyringePumpForceV() ); + + if ( ( TRUE == calStatus ) && ( DACDeltaV > SYRINGE_PUMP_DAC_VOLTAGE_MAX_ERROR ) ) { result = SELF_TEST_STATUS_PASSED; } @@ -1819,9 +1852,9 @@ syringePumpRampTimerCtr++; if ( syringePumpRampUpToggleTime > syringePumpSetToggleTime ) { - syringePumpRampUpToggleTime = (U32)((F32)SYRINGE_PUMP_START_RAMP_SPEED / - (F32)( ( syringePumpRampTimerCtr * syringePumpRampTimerCtr * syringePumpRampTimerCtr ) / SYRINGE_PUMP_RAMP_DIVISOR ) ); - syringePumpRampUpPct = syringePumpSetToggleTime / syringePumpRampUpToggleTime; + syringePumpRampUpToggleTime = (U32)( (F32)SYRINGE_PUMP_START_RAMP_SPEED / + ( (F32)( syringePumpRampTimerCtr * syringePumpRampTimerCtr * syringePumpRampTimerCtr ) / (F32)SYRINGE_PUMP_RAMP_DIVISOR ) ); + syringePumpRampUpPct = (F32)syringePumpSetToggleTime / (F32)syringePumpRampUpToggleTime; if ( syringePumpRampUpToggleTime > syringePumpSetToggleTime ) { setFPGASyringePumpStepToggleTime( syringePumpRampUpToggleTime );