Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r4efd42acbcbde896a1e9e532db77a72bebea0bdc -rbc538f960d0bc8c72991817ea52efac4775ce953 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 4efd42acbcbde896a1e9e532db77a72bebea0bdc) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision bc538f960d0bc8c72991817ea52efac4775ce953) @@ -37,7 +37,6 @@ /// Default publication interval for syringe pump data. #define SYRINGE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) -#define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 1 * MS_PER_SECOND ) ///< Delay 1 second then check for syringe pump prime occlusion. #define BD_SYRINGE_ID_RADIUS_CM ( 1.4427 / 2.0 ) ///< Radius from inner diameter (in cm) of supported BD syringe. /// Milliliters per mm of syringe plunger travel. @@ -60,10 +59,7 @@ #define MIN_HEPARIN_CONTINUOUS_RATE 0.2 ///< Minimum continuous Heparin flow rate (in mL/hr). #define MAX_HEPARIN_CONTINUOUS_RATE 1.0 ///< Maximum continuous Heparin flow rate (in mL/hr). -#define MIN_HEPARIN_BOLUS_RATE 1.2 ///< Minimum Heparin bolus flow rate (in mL/hr). -#define MAX_HEPARIN_BOLUS_RATE 24.0 ///< Maximum Heparin bolus flow rate (in mL/hr). -#define HEPARIN_BOLUS_TIME_HR ( 5.0 / MIN_PER_HOUR ) ///< Duration (in hours) of Heparin bolus. -#define HEPARIN_BOLUS_TARGET_RATE_ML_PER_HR 40.0 ///< Heparin bolus target rate (in mL/hr). +#define HEPARIN_BOLUS_TARGET_RATE 40.0 ///< Heparin bolus target rate (in ml/hr); #define SYRINGE_PUMP_RETRACT_RATE 3600.0 ///< Retract rate is 5 mL/ 5 s = 1 mL/s = 3,600 mL/hr. #define SYRINGE_PUMP_SEEK_RATE 3600.0 ///< Seek plunger rate is 5 mL/ 5 s = 1 mL/s = 3,600 mL/hr. #define SYRINGE_PUMP_PRIME_RATE 635.0 ///< Prime rate is 0.5 mm ^ 2 x PI x 450 mm = 0.353 mL / 2s = 635 mL/hr. @@ -83,7 +79,7 @@ #define SYRINGE_PUMP_DAC_FULL_SCALE_BITS 4096.0 ///< Syringe pump DAC has has 4096 full scale counts (12-bit). #define SYRINGE_FORCE_OCCLUSION_THRESHOLD_V 3.2 ///< Force sensor threshold (in V) above which an occlusion is detected. -#define SYRINGE_FORCE_OCCLUSION_THRESHOLD_VOLT 0.5 ///< Force sensor threshold (in V) above which an occlusion is detected. +#define SYRINGE_FORCE_OCCLUSION_DIFF_V 0.5 ///< Force sensor difference (in V) which an occlusion alarm is triggered. #define SYRINGE_FORCE_PLUNGER_THRESHOLD_V 0.25 ///< Force sensor threshold (in V) above which we have engaged with plunger. #define SYRINGE_PUMP_SYRINGE_DETECT_THRESHOLD_V 2.0 ///< Syringe pump syringe detected threshold (in V). #define SYRINGE_PUMP_HOME_DETECT_THRESHOLD_V 0.25 ///< Syringe pump home detected threshold (in V). @@ -93,7 +89,7 @@ #define TEN_PCT_OVER_ALLOWANCE 1.1 ///< Allow 10 percent over target before alarming on over travel. #define FIVE_PCT_OVER_ALLOWANCE 1.05 ///< Allow 5 percent over target before alarming on over travel. -/// Expected position of empty in relation to home postion. +/// Expected position of empty in relation to home position. #define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84 ) /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5 ) @@ -190,7 +186,7 @@ static OVERRIDE_U32_T syringePumpADCReadCtr = {0, 0, 0, 0}; ///< Syringe pump ADC read counter reported by FPGA. static F32 syringePumpSetRate; ///< Set rate for syringe pump (in mL/hr). -static F32 forceAtStartOfPriming; ///< Force sensor reading in Volts at the start of the priming operation. +static F32 forceAtEndOfSeek; ///< Force sensor reading in Volts at the end of seek. static U32 syringePumpSetToggleTime; ///< Set rate for syringe pump (in uSec/toggle). static U32 syringePumpRampUpToggleTime; ///< Current ramp rate for syringe pump (in uSec/toggle). static F32 syringePumpSafetyVolumeDelivered; ///< Calculated volume (in mL) (from set rate over time). @@ -216,7 +212,6 @@ static BOOL syringePumpPlungerFound; ///< Flag indicates plunger was found. static BOOL syringeVolumeAdequate; ///< Flag indicates whether Heparin volume is sufficient to complete treatment. static BOOL syringePumpPrimeCompleted; ///< Flag indicates prime operation was completed. -static BOOL syringePumpCheckForOcclusionFlag; ///< Flag indicates it is time to check for prime occlusion. static BOOL syringePumpDACVrefWriteInProgress; ///< Flag indicates DAC Vref write is in progress. static F32 syringePumpDACVref; ///< DAC Vref setting for force sensor. @@ -225,7 +220,6 @@ static U32 syringePumpStallCtr; ///< Counts time when position is not changing during ramp. static U32 syringePumpStallRetryCount; ///< Counts pump ramp up stall retries. -static U32 syringeOcclusionDelayStartTime; ///< Used to calculate the 1 second delay time before check for prime occlusion. static HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T forceSensorCalRecord; ///< HD heparin force sensor calibration record. // ********** private function prototypes ********** @@ -255,8 +249,6 @@ static void calcSafetyVolumeDelivered( void ); static BOOL checkDirection( BOOL stopPump, MOTOR_DIR_T expDir ); static BOOL checkOcclusionOrEmpty( BOOL stopPump ); -static BOOL checkForPrimeOcclusion( BOOL stopPump ); -static BOOL checkForPrimeEmpty( BOOL stopPump ); static BOOL checkSyringeRemoved( BOOL stopPump ); static BOOL checkMaxTravel( BOOL stopPump, S32 maxPos ); static BOOL checkMeasRate( BOOL stopPump, F32 pctMargin ); @@ -298,7 +290,6 @@ syringePumpPlungerFound = FALSE; syringeVolumeAdequate = FALSE; syringePumpPrimeCompleted = FALSE; - syringePumpCheckForOcclusionFlag = FALSE; lastSyringePumpADCReadCtr = 0; @@ -530,7 +521,7 @@ if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( TRUE == isSyringeDetected() ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) && ( TRUE == syringePumpPlungerFound ) ) { - forceAtStartOfPriming = getSyringePumpForceV(); // Get the force sensor reading when syringe pump prime has been requested + forceAtEndOfSeek = getSyringePumpForceV(); // Get the force sensor reading when syringe pump prime has been requested (after seek) syringePumpSetRate = SYRINGE_PUMP_PRIME_RATE; syringePumpPrimeRequested = TRUE; resetHeparinVolumeDelivered(); @@ -563,10 +554,10 @@ *************************************************************************/ BOOL startHeparinBolus( void ) { - F32 tgtRate = HEPARIN_BOLUS_TARGET_RATE_ML_PER_HR; // fixed rate + F32 tgtRate = HEPARIN_BOLUS_TARGET_RATE; // fixed rate // If valid to start a bolus, kick it off - if ( ( tgtRate >= MIN_HEPARIN_BOLUS_RATE ) && ( tgtRate <= MAX_HEPARIN_BOLUS_RATE ) && ( FALSE == isSyringePumpHome() ) ) + if ( FALSE == isSyringePumpHome() ) { if ( ( TRUE == isSyringeDetected() ) && ( TRUE == syringePumpPrimeCompleted ) && ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( HEPARIN_STATE_STOPPED == heparinDeliveryState ) ) @@ -1313,7 +1304,7 @@ F32 contRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); U32 preStop = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); U32 setTxDur = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); - F32 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ) - HEPARIN_BOLUS_TIME_HR; + F32 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ); F32 txVolume = SYRINGE_PUMP_PRIME_VOLUME_ML + bolusVol + ( hepDurHr * contRate ); F32 syringeVol = ( SYRINGE_PUMP_EMPTY_POS - (F32)pos ) / SYRINGE_ENCODER_COUNTS_PER_ML; @@ -1324,14 +1315,14 @@ if ( ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) || ( syringeVol < txVolume ) ) { stopPump = TRUE; - syringePumpPlungerFound = TRUE; syringePumpVolumeDelivered.data = 0.0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = pos; // Check estimated syringe volume needed for treatment vs. volume detected - if insufficient for treatment needs, alarm if ( syringeVol >= txVolume ) { + syringePumpPlungerFound = TRUE; syringeVolumeAdequate = TRUE; } else @@ -1378,32 +1369,15 @@ rampSyringePump(); // Has prime volume been delivered? - if ( ( getSyringePumpVolumeDelivered() >= SYRINGE_PUMP_PRIME_VOLUME_ML ) && ( FALSE == syringePumpCheckForOcclusionFlag ) ) + if ( getSyringePumpVolumeDelivered() >= SYRINGE_PUMP_PRIME_VOLUME_ML ) { stopPump = TRUE; - // syringePumpPrimeCompleted = TRUE; - syringePumpCheckForOcclusionFlag = TRUE; // It is time to check for prime occlusion - syringeOcclusionDelayStartTime = getMSTimerCount(); // Get the current time to check for occlusion after 1 second has elapsed + syringePumpPrimeCompleted = TRUE; syringePumpVolumeDelivered.data = 0.0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = syringePumpPosition.data; } - // When syringe pump has primed, wait for 1 second then check for occlusion before declaring syringe pump prime is completed - if( TRUE == syringePumpCheckForOcclusionFlag ) - { - if ( TRUE == didTimeout( syringeOcclusionDelayStartTime, SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ) ) - { - stopPump = checkForPrimeOcclusion( stopPump ); - syringePumpPrimeCompleted = TRUE; - syringePumpCheckForOcclusionFlag = FALSE; - result = SYRINGE_PUMP_OFF_STATE; // Move to off state when check for occlusion is completed - } - } - - // Is the syringe pump empty? - stopPump = checkForPrimeEmpty( stopPump ); - // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); @@ -1417,7 +1391,7 @@ if ( TRUE == stopPump ) { stopSyringePump(); - // result = SYRINGE_PUMP_OFF_STATE; + result = SYRINGE_PUMP_OFF_STATE; } return result; @@ -1622,16 +1596,16 @@ * @param stopPump flag passed in by caller indicating whether pump should be stopped * @return TRUE if pump should be stopped, FALSE if not *************************************************************************/ -static BOOL checkForPrimeOcclusion( BOOL stopPump ) +BOOL checkForPrimeOcclusion( BOOL stopPump ) { BOOL result = stopPump; - F32 forceAtEndOfPriming = getSyringePumpForceV(); // Read the force sensor at the end of the priming - F32 forceDelta = forceAtEndOfPriming - forceAtStartOfPriming; // Occlusion is detected if force at end is > than force at begin by ~ 0.5 volts + F32 forceAtEndOfPriming = getSyringePumpForceV(); // Read the force sensor at the end of the priming + F32 forceDelta = forceAtEndOfPriming - forceAtEndOfSeek; // Occlusion is detected if force at end of prime is > than force at end of seek by ~ 0.5 volts - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, ( forceDelta >= SYRINGE_FORCE_OCCLUSION_THRESHOLD_VOLT ) ) ) + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, ( forceDelta >= SYRINGE_FORCE_OCCLUSION_DIFF_V ) ) ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, forceAtStartOfPriming, forceAtEndOfPriming ) // reuse this alarm after prime - forceAtStartOfPriming = 0.0; // reset this value in case we want to prime again + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, forceAtEndOfSeek, forceAtEndOfPriming ) // reuse this alarm after prime + forceAtEndOfSeek = 0.0; // reset this value in case we want to prime again result = TRUE; } @@ -1640,31 +1614,6 @@ /*********************************************************************//** * @brief - * The checkForPrimeEmpty function checks the force sensor for excessive - * pressure. Would indicate occlusion or jam or empty syringe. - * @details Inputs: syringePumpMeasForce.data, syringePumpPosition.data - * @details Outputs: alarm triggered if max force detected - * @param stopPump flag passed in by caller indicating whether pump should be stopped - * @return TRUE if pump should be stopped, FALSE if not - *************************************************************************/ -static BOOL checkForPrimeEmpty( BOOL stopPump ) -{ - BOOL result = stopPump; - F32 force = getSyringePumpForceV(); - S32 pos = getSyringePumpPosition(); - - if ( fabs( pos - SYRINGE_PUMP_EMPTY_POS ) < SYRINGE_PUMP_EMPTY_POS_MARGIN ) - { - heparinDeliveryState = HEPARIN_STATE_EMPTY; - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_EMPTY, (F32)pos, force ) - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief * The checkSyringeRemoved function checks whether the syringe has been removed. * This function should only be called from states that require the syringe to * be installed.