Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -ra43e8d7086cdfa6f6208306e5b23de13ffb8a014 -r8254d0eaea0d25b62e41dc4189ec7cabbcf4c226 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision a43e8d7086cdfa6f6208306e5b23de13ffb8a014) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 8254d0eaea0d25b62e41dc4189ec7cabbcf4c226) @@ -8,7 +8,7 @@ * @file ModePreTreat.c * * @author (last) Vijay Pamula -* @date (last) 12-Aug-2026 +* @date (last) 17-Aug-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 @@ -50,6 +50,11 @@ /// Initial offset used to stagger the Pre-Treatment state data broadcast. #define PRE_TREATMENT_STATE_DATA_PUB_INITIAL_OFFSET 5U +#define PRE_TX_DEFAULT_QD_ML_MIN 400 ///< Default dialysate flow rate during recirculation when Rx is not entered in mL/min. +#define PRE_TX_INTERMEDIATE_QD_ML_MIN 300 ///< Intermediate dialysate flow rate for low prescribed Qd in mL/min. +#define PRE_TX_LOW_QD_THRESHOLD_ML_MIN 200 ///< Maximum prescribed Qd requiring the intermediate Qd transition in mL/min. +#define PRE_TX_LOW_QD_TRANSITION_TIME_MS ( 4 * SEC_PER_MIN * MS_PER_SECOND ) ///< Low Qd transition time before applying the prescribed Qd in milliseconds. + // ********** private data ********** static TD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState; ///< Current Pre-Treatment sub-state @@ -61,18 +66,23 @@ static BOOL treatmentStartRequested; ///< Flag indicating the UI requested treatment start. static U32 preTreatmentStateBroadcastTimerCtr; ///< Pre-Treatment state data broadcast timer counter. static OVERRIDE_U32_T preTreatmentStatePublishInterval; ///< Pre-Treatment state data publication interval override. +static BOOL lowQdTransitionActive; ///< Flag indicating low Qd transition is active. +static U32 lowQdTransitionStartTime; ///< Start time of the low Qd transition. +static BOOL defaultQdApplied; ///< Flag indicating default Qd has been applied while Rx is unavailable. +static BOOL preTreatmentRxUpdated; ///< Flag indicating a new or updated Rx was received. // ********** private function prototypes ********** -static void setPreTreatStateTransition( void ); ///< Configure actuators and variables for Pre-Treatment state transitions. -static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); ///< Handle Install state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleDrySelfTestState( void ); ///< Handle Self Test Dry state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); ///< Handle Prime state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); ///< Handle Recirculate state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); ///< Handle Confirm Rx state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleHeparinSetupState( void ); ///< Handle Heparin Setup state during Pre-Treatment. -static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); ///< Handle Patient Connection state during Pre-Treatment -static void publishPreTreatmentStates( void ); ///< Publish Pre-Treatment states to the UI. +static void setPreTreatStateTransition( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleDrySelfTestState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleHeparinSetupState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); +static void handlePreTreatmentQdTransition( void ); +static void publishPreTreatmentStates( void ); /*********************************************************************//** * @brief @@ -92,6 +102,10 @@ continueFromHeparinSetupRequested = FALSE; treatmentStartRequested = FALSE; submodeCompleteTransitionTimeCounter = 0; + lowQdTransitionActive = FALSE; + lowQdTransitionStartTime = 0U; + defaultQdApplied = FALSE; + preTreatmentRxUpdated = FALSE; preTreatmentStateBroadcastTimerCtr = PRE_TREATMENT_STATE_DATA_PUB_INITIAL_OFFSET; preTreatmentStatePublishInterval = (OVERRIDE_U32_T) { @@ -185,6 +199,10 @@ break; } + if ( currentPreTreatmentState > TD_PRE_TREATMENT_PRIME_STATE ) + { + handlePreTreatmentQdTransition(); + } if ( prevPreTreatmentState != currentPreTreatmentState ) { setPreTreatStateTransition(); @@ -415,6 +433,10 @@ F32 bicarbConvFactor = BICARBONATE_CONVERSION_FACTOR; F32 presUFVolumeL = 0.0F; F32 presUFRateMlMin = 0.0F; + U32 prescribedQd = 0U; + F32 prescribedDialTemp = 0.0F; + F32 ddQd = 0.0F; + F32 ddDialTemp = 0.0F; U32 ddSubMode = getDDSubMode(); TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; DD_OP_MODE_T ddOpMode = getDDOpMode(); @@ -426,9 +448,24 @@ { presUFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); presUFRateMlMin = ( presUFVolumeL * (F32)ML_PER_LITER ) / (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); + prescribedQd = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + prescribedDialTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + + ddQd = (F32)prescribedQd; + ddDialTemp = prescribedDialTemp; + + if ( ( prescribedQd <= PRE_TX_LOW_QD_THRESHOLD_ML_MIN ) && + ( ( TRUE == lowQdTransitionActive ) || ( TRUE == preTreatmentRxUpdated ) ) ) + { + ddQd = (F32)PRE_TX_INTERMEDIATE_QD_ML_MIN; + ddDialTemp = prescribedDialTemp + 1.0F; + } + // Direct DD to generate dialysate and bypass while priming blood - cmdStartGenerateDialysate( (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presUFRateMlMin, - getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), TRUE, + cmdStartGenerateDialysate( ddQd, + presUFRateMlMin, + ddDialTemp, + TRUE, getTreatmentParameterF32( TREATMENT_PARAM_ACID_CONCENTRATE_CONV_FACTOR ), bicarbConvFactor, getTreatmentParameterU32( TREATMENT_PARAM_SODIUM ), @@ -472,6 +509,73 @@ /*********************************************************************//** * @brief + * The handlePreTreatmentQdTransition function manages the dialysate flow + * and temperature transition after priming is complete. + * @details \b Inputs: preTreatmentRxUpdated, lowQdTransitionActive, + * lowQdTransitionStartTime, defaultQdApplied, treatment parameters. + * @details \b Outputs: preTreatmentRxUpdated, lowQdTransitionActive, + * lowQdTransitionStartTime, defaultQdApplied, dialysate flow rate, + * dialysate target temperature. + * @return none. + *************************************************************************/ +static void handlePreTreatmentQdTransition( void ) +{ + U32 prescribedQd; + F32 prescribedDialTemp; + + if ( TRUE != getValidTreatParamsReceived() ) + { + if ( TRUE != defaultQdApplied ) + { + cmdChangeQd( PRE_TX_DEFAULT_QD_ML_MIN ); + defaultQdApplied = TRUE; + } + } + else + { + prescribedQd = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + prescribedDialTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + + if ( TRUE == preTreatmentRxUpdated ) + { + preTreatmentRxUpdated = FALSE; + defaultQdApplied = FALSE; + + if ( prescribedQd <= PRE_TX_LOW_QD_THRESHOLD_ML_MIN ) + { + if ( TRUE != lowQdTransitionActive ) + { + cmdChangeQd( PRE_TX_INTERMEDIATE_QD_ML_MIN ); + + lowQdTransitionStartTime = getMSTimerCount(); + lowQdTransitionActive = TRUE; + } + + cmdChangeDialysateTemperature( prescribedDialTemp + 1.0F ); + } + else + { + cmdChangeQd( prescribedQd ); + cmdChangeDialysateTemperature( prescribedDialTemp ); + + lowQdTransitionActive = FALSE; + } + } + + if ( ( TRUE == lowQdTransitionActive ) && + ( TRUE == didTimeout( lowQdTransitionStartTime, + PRE_TX_LOW_QD_TRANSITION_TIME_MS ) ) ) + { + cmdChangeQd( prescribedQd ); + cmdChangeDialysateTemperature( prescribedDialTemp ); + + lowQdTransitionActive = FALSE; + } + } +} + +/*********************************************************************//** + * @brief * The PreTxRequestTubeSetInstall function signals a request to transition * the Pre-Treatment mode state machine to Install state. * @details \b Inputs: none @@ -573,6 +677,19 @@ /*********************************************************************//** * @brief + * The signalPreTreatmentRxUpdated function signals that a new or updated + * treatment prescription has been received during Pre-Treatment. + * @details \b Inputs: none. + * @details \b Outputs: preTreatmentRxUpdated. + * @return none. + *************************************************************************/ +void signalPreTreatmentRxUpdated( void ) +{ + preTreatmentRxUpdated = TRUE; +} + +/*********************************************************************//** + * @brief * The signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in Pre-Treatment Mode. * @details \b Inputs: currentPreTreatmentState and current Heparin Setup sub-state.