Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r9e2e190687fb9809a3890ae6f1cee0d860c3db46 -r9d80274d4f31715890d519f5f9fbe445c4614046 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 9e2e190687fb9809a3890ae6f1cee0d860c3db46) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 9d80274d4f31715890d519f5f9fbe445c4614046) @@ -24,6 +24,7 @@ #include "Messaging.h" #include "ModeService.h" #include "ModeTreatment.h" +#include "ModeTreatment.h" //#include "NVDataMgmt.h" #include "OperationModes.h" #include "Pressures.h" @@ -187,7 +188,7 @@ initTreatmentPaused(); // initRinseback(); // initTreatmentRecirc(); -// initTreatmentEnd(); + initTreatmentEnd(); initFluidBolus(); // Started the treatment - set the start time in epoch @@ -822,7 +823,7 @@ { TREATMENT_STATE_T result = TREATMENT_END_STATE; -// // Handle final rinseback alarm response from user + // Handle final rinseback alarm response from user // if ( TRUE == initiateRinsebackAlarmResponseRequest ) // { // signalTreatmentEndAlarmRinsebackUserAction(); Index: firmware/App/Modes/StateTxDialysis.c =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -r9d80274d4f31715890d519f5f9fbe445c4614046 --- firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 9d80274d4f31715890d519f5f9fbe445c4614046) @@ -223,14 +223,36 @@ setBloodFlowRate = bPFlow; // Make rate changes in real time if currently performing dialysis. - if ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) + if ( TREATMENT_DIALYSIS_STATE == getTreatmentState() || (TREATMENT_END_STATE==getTreatmentState() )) { setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); } } + /*********************************************************************//** * @brief + * The setDialysisBloodPumpFlowRate function sets the blood pump flow rate parameter. + * This function should be called prior to beginning dialysis treatment + * and when the user changes the blood flow rate during treatment. + * @details \b Inputs: none + * @details \b Outputs: setBloodFlowRate + * @param bPFlow target blood pump flow rate (in mL/min) + * @return none + *************************************************************************/ +void setDialysisBloodPumpFlowRateEndTx( U32 bPFlow ) +{ + setBloodFlowRate = bPFlow; + + // Make rate changes in real time if currently performing dialysis. + if ( (TREATMENT_END_STATE == getTreatmentState() )) + { + setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + } +} + +/*********************************************************************//** + * @brief * The setDialysisDDParams function sets the dialysate rate and ultrafiltration * volume and rate parameters. * @details \b Inputs: none Index: firmware/App/Modes/TreatmentEnd.c =================================================================== diff -u -r9e2e190687fb9809a3890ae6f1cee0d860c3db46 -r9d80274d4f31715890d519f5f9fbe445c4614046 --- firmware/App/Modes/TreatmentEnd.c (.../TreatmentEnd.c) (revision 9e2e190687fb9809a3890ae6f1cee0d860c3db46) +++ firmware/App/Modes/TreatmentEnd.c (.../TreatmentEnd.c) (revision 9d80274d4f31715890d519f5f9fbe445c4614046) @@ -4,10 +4,12 @@ * Created on: Aug 5, 2026 * Author: fw */ +#include "DDInterface.h" #include "AirTrap.h" #include "BloodFlow.h" #include "ModeTreatment.h" +#include "ModeStandby.h" #include "OperationModes.h" #include "SyringePump.h" #include "TaskGeneral.h" @@ -17,7 +19,9 @@ #include "FluidBolus.h" #include "AlarmMgmt.h" #include "TxParams.h" - +#include "Bubbles.h" +#include "Switches.h" +#include "Common.h" /** * @addtogroup TreatmentEnd * @{ @@ -56,6 +60,7 @@ static BOOL txEndAlarmEndTreatmentOnlyRequested; ///< User requested "End Treatment Only" via alarm action / UI message. static BOOL txEndBolusRequested; ///< User requested a fluid bolus while in End of Treatment. static BOOL txEndEscalated; ///< Tracks whether the high-priority alarm has already been raised, to avoid re-triggering every cycle. +static ENDTREATMENT_STATES_T txEndPriorStateBeforeBolus; // ********** private function prototypes ********** @@ -102,32 +107,23 @@ void transitionToTreatmentEnd( void ) { initTreatmentEnd(); - - // Dialyzer bypass — confirmed real call (DDInterface.c). cmdBypassDialyzer( TRUE ); - - // Heparin stop — confirmed real call. stopSyringePump(); + // Set user alarm recovery actions allowed in this state + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); - // DD saline / substitution branch. - // Confirmed real DD calls exist (DDInterface.c): cmdStopGenerateDialysate() for saline, - // cmdChangeQd() to set Qdt=Qb for substitution branch (generation already running/bypassed - // from treatment start, no separate "mode" command needed). - // TODO CONFIRM: real flag/param that indicates priming fluid was saline vs substitution - // (per manager: check bolus flags + substitution rate — exact names not yet located). - // TODO CONFIRM (PRS-429 conflict): requirement text says Qdt = institutionally configured - // Rinseback Flow Rate for the substitution branch, but the PRS's own rationale note says - // Qdt = Qb. Code below uses Qb pending resolution — verify before finalizing. - if ( TRUE == /* TODO: real saline-fluid check */ FALSE ) + // Require BP door to be closed during this state + doorClosedRequired( TRUE ); + if ( FLUID_TYPE_SALINE == getFluidType() ) { - cmdStopGenerateDialysate(); + cmdStopGenerateDialysate(); // saline branch — DD stops } else { - // Qdt = Qb — confirmed real call pattern (StatePreTxRecirculate.c uses - // cmdChangeQd(getTreatmentParameterU32(TREATMENT_PARAM_...))). Blood flow rate - // source confirmed as TREATMENT_PARAM_BLOOD_FLOW per TxParams.h accessor pattern. - cmdChangeQd( (F32)getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ); + // Direct DD to bypass dialysate and set substitution to universal flow rate + cmdChangeQd( (U32)getTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) ); // substitution branch — DD keeps running, Qdt=Qb } // Substitution flow Off — confirmed real call (DDInterface.c). Modality scope (all vs @@ -138,20 +134,13 @@ setCurrentSubState( (U32)treatmentEndState ); setupForTxEndWait4RinsebackState(); - if ( FLUID_TYPE_SALINE == getFluidType() ) - { - cmdStopGenerateDialysate(); // saline branch — DD stops - } - else - { - cmdChangeQd( (F32)getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ); // substitution branch — DD keeps running, Qdt=Qb - } // Venous bubble detection stays enabled always — confirmed real call, same pattern - // used in ModeTreatment.c's transitionToTreatmentMode(): - // setVenousBubbleDetectionEnabled( H18_BBLD, TRUE ); + // used in ModeTreatment.c's transitionToTreatmentMode(). +#ifndef TEST_UI_ONLY + setVenousBubbleDetectionEnabled( H18_BBLD, TRUE ); +#endif - // Trigger the low-priority End of Treatment alarm — this IS the notification (no UI dialog). activateAlarmNoData( ALARM_ID_TD_END_OF_TREATMENT ); } @@ -299,19 +288,12 @@ // path before wiring the real call — hold here until confirmed. Once resolved, // this branch calls the real rinseback transition function (name still TBD). } - else if ( TRUE == txEndAlarmEndTreatmentOnlyRequested ) - { - // Set via signalTreatmentEndOnlyRequest(), called by the UI message handler - // when "End Treatment Only" is selected. - // PENDING: confirm exact call with whoever implemented Post-Treatment mode — - // per your note, this returns to the original/prior state, consistent with the - // MODE_POST pattern already seen elsewhere in ModeTreatment.c - // (e.g. requestNewOperationMode(MODE_POST)). Wire once confirmed. - } + else if ( TRUE == txEndBolusRequested ) { + txEndPriorStateBeforeBolus = TX_END_WAIT_FOR_RINSEBACK_STATE; result = TX_END_FLUID_BOLUS_STATE; - // TODO: confirm real fluid bolus initiate call. + signalStartFluidBolus( TX_END_BP_FLOW_RATE_ML_MIN ); } return result; @@ -326,14 +308,23 @@ *************************************************************************/ static ENDTREATMENT_STATES_T handleTxEndFluidBolusState( void ) { - ENDTREATMENT_STATES_T result = TX_END_FLUID_BOLUS_STATE; + ENDTREATMENT_STATES_T result = TX_END_FLUID_BOLUS_STATE; - // Confirmed: execFluidBolus() is already called unconditionally every cycle at the - // mode level (ModeTreatment.c's execTreatmentMode()), regardless of Treatment End - // substate — no local call needed here. This substate only needs to poll completion. - // TODO: confirm real fluid bolus completion-check call for this codebase. + if ( FALSE == isFluidBolusActive() ) + { + result = txEndPriorStateBeforeBolus; - return result; + if ( TX_END_PAUSED_STATE == txEndPriorStateBeforeBolus ) + { + setupForTxEndPausedState(); + } + else + { + setupForTxEndWait4RinsebackState(); + } + } + + return result; } /*********************************************************************//** @@ -346,22 +337,27 @@ *************************************************************************/ static ENDTREATMENT_STATES_T handleTxEndPausedState( void ) { - ENDTREATMENT_STATES_T result = TX_END_PAUSED_STATE; + ENDTREATMENT_STATES_T result = TX_END_PAUSED_STATE; - if ( TRUE == txEndAlarmRinsebackRequested ) - { - // PENDING: same rinseback call as Wait for Rinseback — pending flag check. - } - else if ( TRUE == txEndAlarmEndTreatmentOnlyRequested ) - { - // PENDING: same operation-mode-change call as Wait for Rinseback. - } - else if ( FALSE == doesAlarmStatusIndicateStop() ) - { - // Confirmed real call, same pattern used to detect the stop condition on entry. - setupForTxEndWait4RinsebackState(); - result = TX_END_WAIT_FOR_RINSEBACK_STATE; - } + if ( TRUE == txEndAlarmRinsebackRequested ) + { + // PENDING: same rinseback call as Wait for Rinseback. + } + else if ( TRUE == txEndAlarmEndTreatmentOnlyRequested ) + { + // PENDING: same operation-mode-change call as Wait for Rinseback. + } + else if ( TRUE == txEndBolusRequested ) + { + txEndPriorStateBeforeBolus = TX_END_PAUSED_STATE; + result = TX_END_FLUID_BOLUS_STATE; + signalStartFluidBolus( TX_END_BP_FLOW_RATE_ML_MIN ); + } + else if ( FALSE == isBloodRecircBlocked() ) + { + setupForTxEndWait4RinsebackState(); + result = TX_END_WAIT_FOR_RINSEBACK_STATE; + } return result; } @@ -415,16 +411,20 @@ txEndAlarmRinsebackRequested = TRUE; } -void signalTreatmentEndOnlyRequest( void ) -{ - txEndAlarmEndTreatmentOnlyRequested = TRUE; -} -void signalTreatmentEndFluidBolusRequest( void ) +BOOL signalTreatmentEndFluidBolusRequest( void ) { - txEndBolusRequested = TRUE; -} + BOOL result = FALSE; + if ( ( TX_END_WAIT_FOR_RINSEBACK_STATE == treatmentEndState ) || + ( TX_END_PAUSED_STATE == treatmentEndState ) ) + { + txEndBolusRequested = TRUE; + result = TRUE; + } + + return result; +} /*********************************************************************//** * @brief * The getCurrentTreatmentEndState function returns the current substate of Index: firmware/App/Modes/TreatmentEnd.h =================================================================== diff -u -r9e2e190687fb9809a3890ae6f1cee0d860c3db46 -r9d80274d4f31715890d519f5f9fbe445c4614046 --- firmware/App/Modes/TreatmentEnd.h (.../TreatmentEnd.h) (revision 9e2e190687fb9809a3890ae6f1cee0d860c3db46) +++ firmware/App/Modes/TreatmentEnd.h (.../TreatmentEnd.h) (revision 9d80274d4f31715890d519f5f9fbe445c4614046) @@ -39,7 +39,7 @@ U32 getCurrentTreatmentEndState( void ); void signalTreatmentEndRinsebackRequest( void ); void signalTreatmentEndOnlyRequest( void ); -void signalTreatmentEndFluidBolusRequest( void ); +BOOL signalTreatmentEndFluidBolusRequest( void ); /**@}*/ Index: firmware/App/Services/StateServices/FluidBolus.c =================================================================== diff -u -r8345f0415ce34f2f47afcbf613a00216769f51c6 -r9d80274d4f31715890d519f5f9fbe445c4614046 --- firmware/App/Services/StateServices/FluidBolus.c (.../FluidBolus.c) (revision 8345f0415ce34f2f47afcbf613a00216769f51c6) +++ firmware/App/Services/StateServices/FluidBolus.c (.../FluidBolus.c) (revision 9d80274d4f31715890d519f5f9fbe445c4614046) @@ -469,10 +469,10 @@ // rejReason = ( result == TRUE ) ? REQUEST_REJECT_REASON_NONE : REQUEST_REJECT_REASON_INVALID_TREATMENT_SUB_STATE; // break; // -// case TREATMENT_END_STATE: -// result = signalTreatmentEndFluidBolusRequest(); -// rejReason = ( result == TRUE ) ? REQUEST_REJECT_REASON_NONE : REQUEST_REJECT_REASON_INVALID_TREATMENT_SUB_STATE; -// break; + case TREATMENT_END_STATE: + result = signalTreatmentEndFluidBolusRequest(); + rejReason = ( result == TRUE ) ? REQUEST_REJECT_REASON_NONE : REQUEST_REJECT_REASON_INVALID_TREATMENT_SUB_STATE; + break; default: rejReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE;