Index: firmware/App/Modes/StateTxBloodPrime.c =================================================================== diff -u -r6b9b882169f108f9a5072dc60cdabbc1687aafcc -r8d0569c37baa53ecc7073c03d5e03ca423656c70 --- firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision 6b9b882169f108f9a5072dc60cdabbc1687aafcc) +++ firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision 8d0569c37baa53ecc7073c03d5e03ca423656c70) @@ -67,6 +67,7 @@ static BLOOD_PRIME_STATE_T bloodPrimeState; ///< Current state of the blood prime sub-mode. static BLOOD_PRIME_STATE_T bloodPrimeResumeState; ///< Blood prime sub-state prior to pause. +static BLOOD_PRIME_STATE_T bolusCallingState; ///< Fluid Bolus calling state. static BOOL pendingPauseRequest; ///< Flag indicating UI has requested blood prime pause. static BOOL pendingResumeRequest; ///< Flag indicating UI has requested blood prime resume. static BOOL pendingFlowChangeRequest; ///< Flag indicating UI has requested blood prime flow change @@ -80,9 +81,10 @@ static U32 bloodPrimePublishTimerCtr; ///< Timer counter for determining interval for blood prime status to be published. static U32 lastBloodPrimeFlowRate_mL_min; ///< Flow rate prior to pausing blood prime. static U32 requestedBloodFlowRate_mL_min; ///< Requested blood flow rate from UI. -static U32 bloodPrimeStartMS = 0; ///< Start time of Blood Prime (ms timer count) -static U32 bloodPrimeTimeoutSec = 0; ///< -static U32 bloodPrimeCountdownSec = 0; ///< +static U32 bloodPrimeStartMS; ///< Start time of Blood Prime (ms timer count) +static U32 bloodPrimeTimeoutSec; ///< Blood prime pause timeout duration (broadcast to UI) +static U32 bloodPrimeCountdownSec; ///< Blood prime pause countdown remaining time (broadcast to UI) +static U32 pausedElapsedMS; ///< Elapsed pause time saved when fluid bolus starts from paused state. /// Interval (in task intervals) at which to publish blood prime data to CAN bus. static OVERRIDE_U32_T bloodPrimePublishInterval = { BLOOD_PRIME_DATA_PUBLISH_INTERVAL, BLOOD_PRIME_DATA_PUBLISH_INTERVAL, BLOOD_PRIME_DATA_PUBLISH_INTERVAL, 0 }; @@ -115,6 +117,7 @@ bloodPrimeState = BLOOD_PRIME_RAMP_STATE; bloodPrimeResumeState = BLOOD_PRIME_RAMP_STATE; + bolusCallingState = BLOOD_PRIME_RAMP_STATE; bloodPrimeRampControlTimerCtr = 0; bloodPrimePublishTimerCtr = BLOOD_PRIME_DATA_PUBLISH_INTERVAL - 2; // setup so publish will occur time after next cumulativeBloodPrimeVolume_mL.data = 0.0; @@ -133,7 +136,9 @@ } bloodPrimeRampStep_mL = rampRateSpan / estRampSeconds; bloodPrimeStartMS = 0; - + bloodPrimeTimeoutSec = 0; + bloodPrimeCountdownSec = 0; + pausedElapsedMS = 0; fluidBolusRequested = FALSE; } @@ -194,7 +199,6 @@ pendingPauseRequest = FALSE; pendingResumeRequest = FALSE; pendingFlowChangeRequest = FALSE; - fluidBolusRequested = FALSE; } /*********************************************************************//** @@ -312,6 +316,7 @@ { fluidBolusRequested = FALSE; bloodPrimeResumeState = bloodPrimeState; + bolusCallingState = bloodPrimeState; lastBloodPrimeFlowRate_mL_min = getTargetBloodFlowRate(); // Start bolus and transition to bolus state signalStartFluidBolus( lastBloodPrimeFlowRate_mL_min ); @@ -377,6 +382,7 @@ { fluidBolusRequested = FALSE; bloodPrimeResumeState = bloodPrimeState; + bolusCallingState = bloodPrimeState; lastBloodPrimeFlowRate_mL_min = getTargetBloodFlowRate(); // Start bolus and transition to bolus state signalStartFluidBolus( lastBloodPrimeFlowRate_mL_min ); @@ -406,13 +412,29 @@ if ( TRUE == pendingResumeRequest ) { pendingResumeRequest = FALSE; + bolusCallingState = bloodPrimeResumeState; setBloodPumpTargetFlowRate( (U32)lastBloodPrimeFlowRate_mL_min, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); // Open art/ven pinch valves setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); // Return to state prior to pause result = bloodPrimeResumeState; } + // When UI requests fluid bolus + else if ( TRUE == fluidBolusRequested ) + { + fluidBolusRequested = FALSE; + bolusCallingState = bloodPrimeState; + // Save elapsed time + pausedElapsedMS = calcTimeSince( bloodPrimeStartMS ); + // Start bolus and transition to bolus state + signalStartFluidBolus( lastBloodPrimeFlowRate_mL_min ); + result = BLOOD_PRIME_FLUID_BOLUS_STATE; + } + else + { + // No action required. + } return result; } @@ -421,8 +443,9 @@ * @brief * The handleBloodPrimeFluidBolusState function handles the fluid bolus * state of the blood prime sub-mode. - * @details \b Inputs: bloodPrimeResumeState, lastBloodPrimeFlowRate_mL_min - * @details \b Outputs: bloodPrimeState + * @details \b Inputs: bolusCallingState, lastBloodPrimeFlowRate_mL_min, + * bloodPrimeStartMS, pausedElapsedMS + * @details \b Outputs: bolusCallingState * @return next blood prime state *************************************************************************/ static BLOOD_PRIME_STATE_T handleBloodPrimeFluidBolusState( void ) @@ -432,10 +455,23 @@ // Restore actuators and return to pre-bolus sub-state upon bolus complete or abort if ( FALSE == isFluidBolusActive() ) { - setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); - setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); - setBloodPumpTargetFlowRate( lastBloodPrimeFlowRate_mL_min, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - result = bloodPrimeResumeState; + if( BLOOD_PRIME_PAUSED_STATE == bolusCallingState ) + { + // Resume from saved elapsed + bloodPrimeStartMS = getMSTimerCount() - pausedElapsedMS; + pausedElapsedMS = 0; + // Arterial valve is open to saline, not required here + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + else + { + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); + setBloodPumpTargetFlowRate( lastBloodPrimeFlowRate_mL_min, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + + result = bolusCallingState; } return result; @@ -557,7 +593,7 @@ * @brief * The handleBloodPrimePauseTimer function monitors the Blood Prime * pause timer. -* @details Inputs: bloodPrimeStartMS +* @details Inputs: bloodPrimeStartMS, pausedElapsedMS * @details Outputs: bloodPrimeTimeoutSec, bloodPrimeCountdownSec * @details Alarms: ALARM_ID_TD_BLOOD_PRIME_PAUSE_WARNING * ALARM_ID_TD_BLOOD_PRIME_PAUSE_TIMEOUT @@ -568,9 +604,18 @@ U32 elapsedMS; U32 elapsedSec; - if ( BLOOD_PRIME_PAUSED_STATE == bloodPrimeState ) + if ( ( BLOOD_PRIME_PAUSED_STATE == bloodPrimeState ) || ( BLOOD_PRIME_PAUSED_STATE == bolusCallingState ) ) { - elapsedMS = calcTimeSince( bloodPrimeStartMS ); + if ( BLOOD_PRIME_FLUID_BOLUS_STATE == bloodPrimeState ) + { + // Time frozen during bolus + elapsedMS = pausedElapsedMS; + } + else + { + elapsedMS = calcTimeSince( bloodPrimeStartMS ); + } + elapsedSec = elapsedMS / MS_PER_SECOND; bloodPrimeTimeoutSec = BLOOD_PRIME_PAUSE_TIMEOUT_SEC; if ( elapsedSec < BLOOD_PRIME_PAUSE_TIMEOUT_SEC ) @@ -603,19 +648,17 @@ * @brief * The bloodPrimeSetPendingFluidBolusRequest function handles a fluid bolus * request while in blood prime sub-mode. - * @details \b Inputs: bloodPrimeState + * @details \b Inputs: none * @details \b Outputs: fluidBolusRequested * @return TRUE if request is accepted, FALSE if rejected. *************************************************************************/ BOOL signalBloodPrimeFluidBolusRequest( void ) { BOOL result = FALSE; - if ( ( BLOOD_PRIME_RAMP_STATE == bloodPrimeState ) || ( BLOOD_PRIME_RUN_STATE == bloodPrimeState ) ) - { - fluidBolusRequested = TRUE; - result = TRUE; - } + // Allow from all the states + fluidBolusRequested = TRUE; + result = TRUE; return result; }