Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r1abc0349c736a70fb56db6895947abfbba0eee22 -r8d0569c37baa53ecc7073c03d5e03ca423656c70 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 1abc0349c736a70fb56db6895947abfbba0eee22) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 8d0569c37baa53ecc7073c03d5e03ca423656c70) @@ -21,6 +21,7 @@ #include "OperationModes.h" #include "Timers.h" #include "TxParams.h" +#include "Valves.h" /** * @addtogroup TDPreTreatmentMode @@ -65,6 +66,10 @@ { initPreTreatmentMode(); + // TODO: remove these homeValve() when SELF_TEST_NO_CART_STATE is implemented (homing valves is handled over there). + homeValve(H1_VALV, 0, 0); + homeValve(H19_VALV, 0, 0); + return (U32)currentPreTreatmentState; } Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r1abc0349c736a70fb56db6895947abfbba0eee22 -r8d0569c37baa53ecc7073c03d5e03ca423656c70 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 1abc0349c736a70fb56db6895947abfbba0eee22) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 8d0569c37baa53ecc7073c03d5e03ca423656c70) @@ -71,7 +71,7 @@ static BOOL treatmentCompleted; ///< Flag indicates whether the treatment has completed. static U32 presTreatmentTimeSecs; ///< Prescribed treatment time (in seconds). -static F32 presUFVolumeMl; ///< Prescribed ultrafiltration volume (in L). +static F32 presUFVolumeMl; ///< Prescribed ultrafiltration volume (in mL). static F32 presUFRateMlMin; ///< Prescribed ultrafiltration rate (in mL/Min). static U32 treatmentTimeMS; ///< Elapsed treatment time (in ms). @@ -433,7 +433,8 @@ } // If alarm fires while bolus is active, abort the bolus - if ( ( TRUE == doesAlarmStatusIndicateStop() ) && ( TRUE == isFluidBolusActive() ) ) + if ( ( TRUE == doesAlarmStatusIndicateStop() ) && ( TRUE == isFluidBolusActive() ) && + ( currentTreatmentState != TREATMENT_PAUSED_STATE ) ) { signalAbortFluidBolus(); } @@ -919,7 +920,7 @@ payload.rinsebackState = 0; // getCurrentRinsebackState(); payload.txRecircState = 0; // getCurrentTreatmentRecircState(); payload.txEndState = 0; // getCurrentTreatmentEndState(); - payload.txSalBolusState = 0; // + payload.txFluidBolusState = getCurrentFluidBolusState(); payload.txHepState = 0; // broadcastData( MSG_ID_TD_TREATMENT_STATE_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)(&payload), sizeof( TREATMENT_STATE_DATA_T ) ); } Index: firmware/App/Modes/ModeTreatment.h =================================================================== diff -u -re9e339870c5ed01230963f00d400331ab879c91f -r8d0569c37baa53ecc7073c03d5e03ca423656c70 --- firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision e9e339870c5ed01230963f00d400331ab879c91f) +++ firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 8d0569c37baa53ecc7073c03d5e03ca423656c70) @@ -55,7 +55,7 @@ U32 rinsebackState; ///< Rinse back state. U32 txRecircState; ///< Treatment recirc state. U32 txEndState; ///< Treatment end state. - U32 txSalBolusState; ///< Saline bolus state. + U32 txFluidBolusState; ///< Fluid bolus state. U32 txHepState; ///< Heparin state. } TREATMENT_STATE_DATA_T; 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; } Index: firmware/App/Modes/StateTxDialysis.c =================================================================== diff -u -r83163b27c604072469c28623ba0e4ed9786e294a -r8d0569c37baa53ecc7073c03d5e03ca423656c70 --- firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 83163b27c604072469c28623ba0e4ed9786e294a) +++ firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 8d0569c37baa53ecc7073c03d5e03ca423656c70) @@ -520,7 +520,7 @@ { BOOL result = FALSE; - // Only allow from both UF & UF pause states + // Allow from both UF & UF pause states fluidBolusRequested = TRUE; result = TRUE; Index: firmware/App/Services/FluidBolus.c =================================================================== diff -u -r83163b27c604072469c28623ba0e4ed9786e294a -r8d0569c37baa53ecc7073c03d5e03ca423656c70 --- firmware/App/Services/FluidBolus.c (.../FluidBolus.c) (revision 83163b27c604072469c28623ba0e4ed9786e294a) +++ firmware/App/Services/FluidBolus.c (.../FluidBolus.c) (revision 8d0569c37baa53ecc7073c03d5e03ca423656c70) @@ -111,9 +111,9 @@ * The execFluidBolus function executes the fluid bolus state machine. * @details \b Inputs: currentFluidBolusState * @details \b Outputs: currentFluidBolusState - * @return Current fluid bolus state machine. + * @return none *************************************************************************/ -FLUID_BOLUS_STATE_T execFluidBolus( void ) +void execFluidBolus( void ) { FLUID_BOLUS_STATE_T priorState = currentFluidBolusState; @@ -148,7 +148,18 @@ // Publish fluid bolus data at set interval (whether we are delivering one or not) publishFluidBolusData(); +} +/*********************************************************************//** + * @brief + * The getCurrentFluidBolusState function returns the current state of the + * Fluid Bolus service. + * @details \b Inputs: currentFluidBolusState + * @details \b Outputs: none + * @return currentFluidBolusState + *************************************************************************/ +FLUID_BOLUS_STATE_T getCurrentFluidBolusState( void ) +{ return currentFluidBolusState; } @@ -267,8 +278,7 @@ data.tgtFluidVolumeMl = getTreatmentParameterU32( TREATMENT_PARAM_FLUID_BOLUS_VOLUME ); data.bolFluidVolumeMl = bolusFluidVolumeDelivered_mL; data.cumFluidVolumeMl = totalFluidVolumeDelivered_mL; - data.fluidBolusState = currentFluidBolusState; - data.bolusPermitted = ( FALSE == isFluidBolusActive() ) ? pubBolusPermitted : FALSE; + data.bolusPermitted = pubBolusPermitted; broadcastData( MSG_ID_TD_FLUID_BOLUS_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( FLUID_BOLUS_DATA_PAYLOAD_T ) ); @@ -376,7 +386,7 @@ state = FLUID_BOLUS_IDLE_STATE; } // Determine if bolus is complete or stopped by user - if ( ( bolusFluidVolumeDelivered_mL >= bolusTargetVolume ) || ( TRUE == fluidBolusAbortRequested ) ) + else if ( ( bolusFluidVolumeDelivered_mL >= bolusTargetVolume ) || ( TRUE == fluidBolusAbortRequested ) ) { fluidBolusAbortRequested = FALSE; state = FLUID_BOLUS_IDLE_STATE; @@ -386,10 +396,9 @@ // No action required } - // complete or abort or alarm + // Bolus ended, stop blood pump and record delivered volume if ( state != FLUID_BOLUS_SALINE_IN_PROGRESS_STATE ) { - // Hard stop blood signalBloodPumpHardStop(); completeBolusToCumulative(); } Index: firmware/App/Services/FluidBolus.h =================================================================== diff -u -r6b9b882169f108f9a5072dc60cdabbc1687aafcc -r8d0569c37baa53ecc7073c03d5e03ca423656c70 --- firmware/App/Services/FluidBolus.h (.../FluidBolus.h) (revision 6b9b882169f108f9a5072dc60cdabbc1687aafcc) +++ firmware/App/Services/FluidBolus.h (.../FluidBolus.h) (revision 8d0569c37baa53ecc7073c03d5e03ca423656c70) @@ -48,7 +48,6 @@ U32 tgtFluidVolumeMl; ///< Target Fluid volume in mL. F32 bolFluidVolumeMl; ///< Bolus Fluid volume in mL. F32 cumFluidVolumeMl; ///< Cumulative Fluid volume in mL. - U32 fluidBolusState; ///< Current Fluid Bolus state. BOOL bolusPermitted; ///< True if Bolus is permitted currently. } FLUID_BOLUS_DATA_PAYLOAD_T; #pragma pack(pop) @@ -57,9 +56,10 @@ void initFluidBolus( void ); void publishFluidBolusData( void ); +void execFluidBolus( void ); void setBolusPermitted( BOOL permitted ); -FLUID_BOLUS_STATE_T execFluidBolus( void ); +FLUID_BOLUS_STATE_T getCurrentFluidBolusState( void ); FLUID_BOLUS_MEDIUM_T getFluidBolusMedium( void ); BOOL isFluidBolusActive( void );