Index: firmware/App/Modes/ModePostTreat.c =================================================================== diff -u -re121c9aa3c07a60246e64f83c1dc7e93cf48c7f7 -rc0db3b4001bf2d0b15e590c0244b22690db961ed --- firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision e121c9aa3c07a60246e64f83c1dc7e93cf48c7f7) +++ firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision c0db3b4001bf2d0b15e590c0244b22690db961ed) @@ -7,8 +7,8 @@ * * @file ModePostTreat.c * -* @author (last) Michael Garthwaite -* @date (last) 09-Jun-2023 +* @author (last) Sean Nash +* @date (last) 11-Aug-2023 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -51,8 +51,7 @@ /// Post-Treatment drain reservoirs state machine. typedef enum Drain_States { - DRAIN_DG_DEPRIME_STATE = 0, ///< Drain DG De-prime dialysate lines of excess fluid state. - DRAIN_RESERVOIR_SWITCH_STATE, ///< Switch reservoir state. + DRAIN_RESERVOIR_SWITCH_STATE = 0, ///< Switch reservoir state. DRAIN_RESERVOIR_START_DRAIN_STATE, ///< Drain reservoir start drain state. DRAIN_RESERVOIR_DRAIN_STATE, ///< Drain first reservoir state. DRAIN_RESERVOIR_COMPLETE_STATE, ///< Drain complete state. @@ -62,11 +61,10 @@ // ********** private data ********** static BOOL patientDisconnectionConfirmed; ///< Flag indicates user confirms patient disconnection. +static bool patientDisconnectHandled; ///< Flag indicates patient disconnect actions have been handled static BOOL disposableRemovalConfirmed; ///< Flag indicates user confirms disposable removal. static BOOL rinseConcentrateLines; ///< FLag indicates to rinse concentrate lines. static BOOL isThisFirstDrain; ///< Flag to indicate whether this is the first time the reservoir is drained. -static BOOL drainDGDePrimeActive; ///< FLag to indicate DePrime DG Dialysate lines active -static U32 drainDGDePrimeStarttime; ///< DG DePrime start time static BOOL dgCommandSent; ///< Flag indicates whether a DG command has been already sent. static HD_POST_TREATMENT_STATE_T currentPostTreatmentState; ///< Current state of post-treatment mode state machine. static DRAIN_STATE_T currentDrainReservoirState; ///< Current drain reservoir state. @@ -85,7 +83,6 @@ static HD_POST_TREATMENT_STATE_T handlePostTreatmentVerifyState( void ); static void execDrainReservoirs( void ); -static DRAIN_STATE_T handleDrainDePrimeDGDialysateLinesState( void ); static DRAIN_STATE_T handleDrainReservoirSwitchState( void ); static DRAIN_STATE_T handleDrainReservoirStartDrainState( void ); static DRAIN_STATE_T handleDrainReservoirDrainState( void ); @@ -103,15 +100,14 @@ void initPostTreatmentMode( void ) { patientDisconnectionConfirmed = FALSE; + patientDisconnectHandled = FALSE; disposableRemovalConfirmed = FALSE; rinseConcentrateLines = FALSE; isThisFirstDrain = TRUE; dgCommandSent = FALSE; currentPostTreatmentState = HD_POST_TREATMENT_DRAIN_RESERVOIRS_STATE; - currentDrainReservoirState = DRAIN_DG_DEPRIME_STATE; + currentDrainReservoirState = DRAIN_RESERVOIR_SWITCH_STATE; postTreatmentPublishTimerCounter = 0; - drainDGDePrimeActive = FALSE; - drainDGDePrimeStarttime = 0; // Reset treatment log data memset( &treatmentLogData, 0x0, sizeof( TREATMENT_LOG_DATA_PAYLOAD_T ) ); @@ -316,6 +312,32 @@ /*********************************************************************//** * @brief + * The requestPostTxNext requests to go to next screen after treatment record + * review screen in post-treatment mode + * @details Inputs: currentPostTreatmentState + * @details Outputs: none + * @return none + *************************************************************************/ +void requestPostTxNext( void ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + + if ( currentPostTreatmentState >= HD_POST_TREATMENT_DISPOSABLE_REMOVAL_STATE ) + { + accepted = TRUE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DRAIN_NOT_COMPLETE; + } + + // Respond to user request to move to next screen + sendPostTxNextCmdResponse( accepted, (U32)rejReason ); +} + +/*********************************************************************//** + * @brief * The signalUserConfirmDisposableRemoval signals post-treatment mode * user has confirmed disposable removal. * @details Inputs: none @@ -353,6 +375,41 @@ /*********************************************************************//** * @brief + * The checkPostTreatmentPatientDisconnect function checks UI patient + * disconnect and handles valve release, pump homing, door requirement. + * @details Inputs: patientDisconnectionConfirmed, patientDisconnectHandled + * @details Outputs: patientDisconnectHandled, home pumps, open valves, + * retract syringe, door closed requirement. + * @return none + *************************************************************************/ +static void checkPostTreatmentPatientDisconnect( void ) +{ + VALVE_T valve; + + if ( ( TRUE == patientDisconnectionConfirmed ) && ( FALSE == patientDisconnectHandled ) ) + { + // home valves and pumps while front door is still closed. + homeBloodPump(); + homeDialInPump(); + homeDialOutPump(); + for ( valve = VDI; valve < NUM_OF_VALVES; valve++ ) + { + setValvePosition( valve, VALVE_POSITION_A_INSERT_EJECT ); + } + if ( ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ) > 0.0 ) || + ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ) > 0.0 ) ) + { + retractSyringePump(); + } + doorClosedRequired( FALSE, FALSE ); + // NOTE: patientDisconnectionConfirmed is NOT reset because + // Patient Disconnect State needs it to move to next state + patientDisconnectHandled = TRUE; + } +} + +/*********************************************************************//** + * @brief * The handlePostTreatmentDrainReservoirsState function executes drain reservoirs * operation state machine and transition to next state once completed. * @details Inputs: currentDrainReservoirState @@ -361,17 +418,17 @@ *************************************************************************/ static HD_POST_TREATMENT_STATE_T handlePostTreatmentDrainReservoirsState( void ) { - HD_POST_TREATMENT_STATE_T state = HD_POST_TREATMENT_DRAIN_RESERVOIRS_STATE; + HD_POST_TREATMENT_STATE_T state = HD_POST_TREATMENT_DRAIN_RESERVOIRS_STATE; execDrainReservoirs(); if ( DRAIN_RESERVOIR_COMPLETE_STATE == currentDrainReservoirState ) { // Done with draining the reservoirs state = HD_POST_TREATMENT_PATIENT_DISCONNECTION_STATE; - doorClosedRequired( FALSE, FALSE ); setCurrentSubState( NO_SUB_STATE ); } + checkPostTreatmentPatientDisconnect(); return state; } @@ -390,6 +447,8 @@ OPN_CLS_STATE_T frontDoor = getSwitchStatus( FRONT_DOOR ); OPN_CLS_STATE_T pumpTrack = getSwitchStatus( PUMP_TRACK_SWITCH ); + checkPostTreatmentPatientDisconnect(); + #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_INTERACTION ) ) { @@ -400,6 +459,7 @@ if ( TRUE == patientDisconnectionConfirmed ) { patientDisconnectionConfirmed = FALSE; + patientDisconnectHandled = FALSE; state = HD_POST_TREATMENT_DISPOSABLE_REMOVAL_STATE; } @@ -497,13 +557,21 @@ static void execDrainReservoirs( void ) { DRAIN_STATE_T priorSubState = currentDrainReservoirState; + DG_OP_MODE_T dgMode = getDGOpMode(); + if ( DG_MODE_STAN == dgMode ) + { // In case DG was reset/power cycled, re-start DG so we can drain the reservoirs + cmdStartDG(); + currentDrainReservoirState = DRAIN_RESERVOIR_SWITCH_STATE; + } + else if ( DG_MODE_FAUL == dgMode ) + { // In case DG faulted, skip DG drain states and move on + currentDrainReservoirState = DRAIN_RESERVOIR_COMPLETE_STATE; + } + + // Execute post-tx drain state machine switch ( currentDrainReservoirState ) { - case DRAIN_DG_DEPRIME_STATE: - currentDrainReservoirState = handleDrainDePrimeDGDialysateLinesState(); - break; - case DRAIN_RESERVOIR_SWITCH_STATE: currentDrainReservoirState = handleDrainReservoirSwitchState(); break; @@ -535,65 +603,6 @@ /*********************************************************************//** * @brief - * The handleDrainDePrimeDGDialysateLinesState function de-primes the return - * dialysate line so that it will not leak when user disconnects the line - * from the DG. - * @details Inputs: drainDGDePrimeActive - * @details Outputs: drainDGDePrimeActive - * @return next state - *************************************************************************/ -static DRAIN_STATE_T handleDrainDePrimeDGDialysateLinesState( void ) -{ - DRAIN_STATE_T state = DRAIN_DG_DEPRIME_STATE; - - if ( ( ( DG_MODE_GENE == getDGOpMode() ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == getDGSubMode() ) ) || ( DG_MODE_FAUL == getDGOpMode() ) ) - { - if ( FALSE == drainDGDePrimeActive ) - { - // First entry - Run DPi slow reverse, VDi, VDo closed in init, DPo Off in init. - setDialInPumpTargetFlowRate( DIP_DRAIN_DG_FLOW_RATE_ML_MIN, MOTOR_DIR_REVERSE, PUMP_CONTROL_MODE_OPEN_LOOP ); - drainDGDePrimeStarttime = getMSTimerCount(); - drainDGDePrimeActive = TRUE; - } - } - if ( TRUE == drainDGDePrimeActive ) - { - // Thereafter, check for time elapsed - if ( TRUE == didTimeout( drainDGDePrimeStarttime, DIP_DRAIN_DG_RUNTIME_MS ) ) - { - VALVE_T valve; - - drainDGDePrimeActive = FALSE; - signalDialInPumpHardStop( ); - if ( getDGOpMode() != DG_MODE_FAUL ) - { - state = DRAIN_RESERVOIR_SWITCH_STATE; - } - else - { - state = DRAIN_RESERVOIR_COMPLETE_STATE; - } - // home valves and pumps while front door is still closed. - homeBloodPump(); - homeDialInPump(); - homeDialOutPump(); - for ( valve = VDI; valve < NUM_OF_VALVES; valve++ ) - { - setValvePosition( valve, VALVE_POSITION_A_INSERT_EJECT ); - } - if ( ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ) > 0.0 ) || - ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ) > 0.0 ) ) - { - retractSyringePump(); - } - } - } - - return state; -} - -/*********************************************************************//** - * @brief * The handleDrainReservoirSwitchState function waits for DG to complete * reservoir switch. * @details Inputs: isThisFirstDrain, dgCommandSent @@ -602,9 +611,10 @@ *************************************************************************/ static DRAIN_STATE_T handleDrainReservoirSwitchState( void ) { - DRAIN_STATE_T state = DRAIN_RESERVOIR_SWITCH_STATE; + DRAIN_STATE_T state = DRAIN_RESERVOIR_SWITCH_STATE; + DG_OP_MODE_T dgMode = getDGOpMode(); - if ( ( DG_MODE_GENE == getDGOpMode() ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == getDGSubMode() ) ) + if ( ( DG_MODE_GENE == dgMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == getDGSubMode() ) ) { DG_CMD_RESPONSE_T dgCmdResp;