Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -rc3cf7af051c1ee070df90a9c072df16be48f478f -r9055124b17389e04131b44c00915c33c72db3ae6 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision c3cf7af051c1ee070df90a9c072df16be48f478f) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 9055124b17389e04131b44c00915c33c72db3ae6) @@ -156,6 +156,7 @@ static U32 syringePumpDataPublicationTimerCounter; ///< Used to schedule syringe pump data publication to CAN bus. static U32 syringePumpSpeedCalcTimerCounter; ///< Used to calculate measured rate from change in position over time. static U32 syringePumpRampTimerCtr; ///< Used to track ramp up time. +static HEPARIN_STATE_T heparinDeliveryState; ///< Current state of Heparin delivery. /// Interval (in ms) at which to publish syringe pump data to CAN bus. static OVERRIDE_U32_T syringePumpDataPublishInterval = { SYRINGE_PUMP_DATA_PUB_INTERVAL, SYRINGE_PUMP_DATA_PUB_INTERVAL, 0, 0 }; @@ -175,11 +176,13 @@ static S32 syringePumpPosition1SecAgo; ///< Position recorded at last 1 Hz speed check. static BOOL syringePumpRetractRequested; ///< Flag indicates a retract operation is requested. -static BOOL syringePumpPrimeRequested; ///< Flag indicates plunger seek and Heparin prime operations are requested. +static BOOL syringePumpSeekRequested; ///< Flag indicates a plunger seek operation is requested. +static BOOL syringePumpPrimeRequested; ///< Flag indicates a Heparin prime operation is requested. static BOOL syringePumpBolusRequested; ///< Flag indicates start or resume of a Heparin bolus operation is requested. static BOOL syringePumpContinuousRequested; ///< Flag indicates start or resume of a Heparin continuous delivery operation is requested. static BOOL syringePumpDACVrefSetRequested; ///< Flag indicates request to set DAC Vref for force sensor. +static BOOL syringePumpPositionKnown; ///< Flag indicates we know position from a prior retract to home. static BOOL syringePumpPlungerFound; ///< Flag indicates plunger was found. static BOOL syringePumpPrimeCompleted; ///< Flag indicates prime operation was completed. @@ -230,6 +233,7 @@ void initSyringePump( void ) { syringePumpState = SYRINGE_PUMP_INIT_STATE; + heparinDeliveryState = HEPARIN_STATE_OFF; syringePumpSelfTestState = SYRINGE_PUMP_SELF_TEST_STATE_START; syringePumpSetRate = 0.0; @@ -244,6 +248,7 @@ syringePumpSpeedCalcTimerCounter = 0; syringePumpRampTimerCtr = 0; + syringePumpPositionKnown = FALSE; syringePumpPlungerFound = FALSE; syringePumpPrimeCompleted = FALSE; @@ -263,6 +268,7 @@ static void resetSyringePumpRequestFlags( void ) { syringePumpRetractRequested = FALSE; + syringePumpSeekRequested = FALSE;;; syringePumpPrimeRequested = FALSE; syringePumpBolusRequested = FALSE; syringePumpContinuousRequested = FALSE; @@ -271,6 +277,121 @@ /*********************************************************************//** * @brief + * The userHeparinRequest function handles a command request from the user + * to pause or resume Heparin delivery. + * @details Inputs: none + * @details Outputs: + * @param cmd command from user + * @return TRUE if request accepted, FALSE if not + *************************************************************************/ +BOOL userHeparinRequest( HEPARIN_CMD_T cmd ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + + if ( MODE_TREA == getCurrentOperationMode() ) + { + if ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) + { + if ( HEPARIN_CMD_PAUSE == cmd ) + { + if ( HEPARIN_STATE_DISPENSING == heparinDeliveryState ) + { + accepted = TRUE; + heparinDeliveryState = HEPARIN_STATE_PAUSED; + stopSyringePump(); + } + else + { + rejReason = REQUEST_REJECT_REASON_HEPARIN_PAUSE_INVALID_IN_THIS_STATE; + } + } + else if ( HEPARIN_CMD_RESUME == cmd ) + { + if ( HEPARIN_STATE_PAUSED == heparinDeliveryState ) + { + accepted = TRUE; + heparinDeliveryState = HEPARIN_STATE_DISPENSING; + startHeparinContinuous(); + } + else + { + rejReason = REQUEST_REJECT_REASON_HEPARIN_NOT_PAUSED; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_INVALID_COMMAND; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; + } + + sendHeparinCommandResponse( (U32)accepted, (U32)rejReason, (U32)heparinDeliveryState ); + + return accepted; +} + +/*********************************************************************//** + * @brief + * The setHeparinOff function requests Heparin state be set to off - + * indicates syringe pump will not be needed in this treatment. + * @details Inputs: none + * @details Outputs: heparinDeliveryState + * @return none + *************************************************************************/ +void setHeparinOff( void ) +{ + heparinDeliveryState = HEPARIN_STATE_OFF; +} + +/*********************************************************************//** + * @brief + * The setHeparinStopped function requests Heparin state be set to stopped - + * indicates syringe pump will be needed in this treatment. + * @details Inputs: none + * @details Outputs: heparinDeliveryState + * @return none + *************************************************************************/ +void setHeparinStopped( void ) +{ + heparinDeliveryState = HEPARIN_STATE_STOPPED; +} + +/*********************************************************************//** + * @brief + * The setHeparinCompleted function requests Heparin state be set to completed - + * indicates we have entered the Heparin pre-stop period of this treatment. + * @details Inputs: none + * @details Outputs: heparinDeliveryState + * @return none + *************************************************************************/ +void setHeparinCompleted( void ) +{ + heparinDeliveryState = HEPARIN_STATE_COMPLETED; +} + +/*********************************************************************//** + * @brief + * The getHeparinState function returns the current Heparin state. + * @details Inputs: heparinDeliveryState + * @details Outputs: none + * @return heparinDeliveryState + *************************************************************************/ +HEPARIN_STATE_T getHeparinState( void ) +{ + return heparinDeliveryState; +} + +/*********************************************************************//** + * @brief * The stopSyringePump function requests syringe pump be stopped. * @details Inputs: none * @details Outputs: syringePumpSetRate, syringePumpRetractRequested, syringePumpState @@ -281,6 +402,10 @@ syringePumpSetRate = 0.0; setFPGASyringePumpStepToggleTime( SYRINGE_PUMP_MICROSTEP_TOGGLE_TIME_FOR_STOP ); syringePumpState = SYRINGE_PUMP_OFF_STATE; + if ( ( HEPARIN_STATE_INITIAL_BOLUS == heparinDeliveryState ) || ( HEPARIN_STATE_DISPENSING == heparinDeliveryState ) ) + { + heparinDeliveryState = HEPARIN_STATE_STOPPED; + } } /*********************************************************************//** @@ -292,7 +417,7 @@ *************************************************************************/ BOOL retractSyringePump( void ) { - if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( FALSE == isSyringeDetected() ) ) + if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( FALSE == isSyringeDetected() ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) ) { syringePumpSetRate = SYRINGE_PUMP_RETRACT_RATE; syringePumpRetractRequested = TRUE; @@ -303,17 +428,36 @@ /*********************************************************************//** * @brief - * The primeSyringePump function requests plunger seek and prime operations. + * The seekSyringePlunger function requests plunger seek operation. * @details Inputs: syringePumpState - * @details Outputs: syringePumpSetRate, syringePumpBolusRequested + * @details Outputs: syringePumpSetRate, syringePumpSeekRequested * @return TRUE if request accepted, FALSE if not *************************************************************************/ -BOOL primeSyringePump( void ) +BOOL seekSyringePlunger( void ) { if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( TRUE == isSyringeDetected() ) && - ( TRUE == isSyringePumpHome() ) ) + ( TRUE == syringePumpPositionKnown ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) ) { syringePumpSetRate = SYRINGE_PUMP_SEEK_RATE; + syringePumpSeekRequested = TRUE; + } + + return syringePumpSeekRequested; +} + +/*********************************************************************//** + * @brief + * The primeSyringePump function requests a prime operation. + * @details Inputs: syringePumpState + * @details Outputs: syringePumpSetRate, syringePumpPrimeRequested + * @return TRUE if request accepted, FALSE if not + *************************************************************************/ +BOOL primeSyringePump( void ) +{ + if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( TRUE == isSyringeDetected() ) && + ( heparinDeliveryState != HEPARIN_STATE_OFF ) && ( TRUE == syringePumpPlungerFound ) ) + { + syringePumpSetRate = SYRINGE_PUMP_PRIME_RATE; syringePumpPrimeRequested = TRUE; } @@ -337,7 +481,8 @@ // If valid to start a bolus, kick it off if ( ( tgtRate >= MIN_HEPARIN_BOLUS_RATE ) && ( tgtRate <= MAX_HEPARIN_BOLUS_RATE ) && ( FALSE == isSyringePumpHome() ) ) { - if ( ( TRUE == isSyringeDetected() ) && ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) ) + if ( ( TRUE == isSyringeDetected() ) && ( TRUE == syringePumpPrimeCompleted ) && + ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( HEPARIN_STATE_STOPPED == heparinDeliveryState ) ) { syringePumpSetRate = tgtRate; syringePumpBolusRequested = TRUE; @@ -366,7 +511,8 @@ if ( ( flowRate >= MIN_HEPARIN_CONTINUOUS_RATE ) && ( flowRate <= MAX_HEPARIN_CONTINUOUS_RATE ) && ( FALSE == isSyringePumpHome() ) ) { - if ( ( TRUE == isSyringeDetected() ) && ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) ) + if ( ( TRUE == isSyringeDetected() ) && ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && + ( ( ( HEPARIN_STATE_STOPPED == heparinDeliveryState ) || ( HEPARIN_STATE_PAUSED == heparinDeliveryState ) ) ) ) { syringePumpSetRate = flowRate; syringePumpContinuousRequested = TRUE; @@ -630,7 +776,7 @@ *************************************************************************/ BOOL isSyringePumpPrimed( void ) { - return syringePumpPrimeCompleted; + return syringePumpPrimeCompleted;; } /*********************************************************************//** @@ -772,16 +918,22 @@ { result = SYRINGE_PUMP_RETRACT_STATE; } - else if ( TRUE == syringePumpPrimeRequested ) + else if ( TRUE == syringePumpSeekRequested ) { result = SYRINGE_PUMP_SEEK_STATE; } + else if ( TRUE == syringePumpPrimeRequested ) + { + result = SYRINGE_PUMP_PRIME_STATE; + } else if ( TRUE == syringePumpBolusRequested ) { + heparinDeliveryState = HEPARIN_STATE_INITIAL_BOLUS; result = SYRINGE_PUMP_HEP_BOLUS_STATE; } else if ( TRUE == syringePumpContinuousRequested ) { + heparinDeliveryState = HEPARIN_STATE_DISPENSING; result = SYRINGE_PUMP_HEP_CONTINUOUS_STATE; } else if ( TRUE == syringePumpDACVrefSetRequested ) @@ -840,6 +992,7 @@ syringePumpHomePositionOffset = getFPGASyringePumpEncoderPosition(); syringePumpPosition.data = 0; syringePumpVolumeStartPosition = 0; + syringePumpPositionKnown = TRUE; syringePumpVolumeDelivered.data = 0.0; syringePumpPlungerFound = FALSE; syringePumpPrimeCompleted = FALSE; @@ -875,14 +1028,10 @@ // Is plunger contact detected? if ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) { + stopPump = TRUE; syringePumpPlungerFound = TRUE; syringePumpVolumeDelivered.data = 0.0; syringePumpVolumeStartPosition = syringePumpPosition.data; - syringePumpSetRate = SYRINGE_PUMP_PRIME_RATE; - // Calculate target FPGA rate from set rate in mL/hr converted to microstep toggle interval in uSec - calcStepperToggleTimeForTargetRate( syringePumpSetRate ); - setFPGASyringePumpStepToggleTime( syringePumpRampUpToggleTime ); - result = SYRINGE_PUMP_PRIME_STATE; } // Has syringe been removed? @@ -1011,18 +1160,21 @@ // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); - // Check volume vs. safety volume - stopPump = checkVolumeVsSafetyVolume( stopPump, SYRINGE_PUMP_VOLUME_CHECK_MARGIN ); - // Check for occlusion stopPump = checkOcclusionOrEmpty( stopPump ); - // Check for commanded vs. meas. rate - stopPump = checkMaxMeasRate( stopPump, SYRINGE_PUMP_RATE_CHECK_MARGIN ); + // Check if time to stop Heparin delivery + // TODO - implement pre-stop check // Check position > max travel stopPump = checkMaxTravel( stopPump, SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ); + // Check for commanded vs. meas. rate + stopPump = checkMaxMeasRate( stopPump, SYRINGE_PUMP_RATE_CHECK_MARGIN ); + + // Check volume vs. safety volume + stopPump = checkVolumeVsSafetyVolume( stopPump, SYRINGE_PUMP_VOLUME_CHECK_MARGIN ); + // If anything found that would require stopping the pump, stop pump and go to off state if ( TRUE == stopPump ) { @@ -1079,6 +1231,7 @@ 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 ) } else @@ -1133,6 +1286,7 @@ if ( pos > ( SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ) ) { result = TRUE; + heparinDeliveryState = HEPARIN_STATE_EMPTY; SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_EMPTY, (F32)pos, getSyringePumpForceV() ) } else if ( pos > maxPos ) @@ -1306,9 +1460,11 @@ data.syringePumpPosition = getSyringePumpPosition(); data.syringePumpSetRate = syringePumpSetRate; data.syringePumpState = (U32)syringePumpState; + data.heparinDeliveryState = (U32)heparinDeliveryState; data.syringePumpVolumeDelivered = getSyringePumpVolumeDelivered(); - broadcastSyringePumpData( data ); + broadcastSyringePumpData( data ); + broadcastHeparinData( data.syringePumpVolumeDelivered ); syringePumpDataPublicationTimerCounter = 0; } } @@ -1411,7 +1567,11 @@ result = retractSyringePump(); break; - case SYRINGE_PUMP_OP_SEEK_AND_PRIME: + case SYRINGE_PUMP_OP_SEEK: + result = seekSyringePlunger(); + break; + + case SYRINGE_PUMP_OP_PRIME: result = primeSyringePump(); break;