Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -rc34ad5cb83749cca78001409699a1fecf1436b7f -rbec2091316934aae16f00c637139c5d7b29cb26d --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision c34ad5cb83749cca78001409699a1fecf1436b7f) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision bec2091316934aae16f00c637139c5d7b29cb26d) @@ -8,7 +8,7 @@ * @file ModePreTreat.c * * @author (last) Vijay Pamula -* @date (last) 31-Jul-2026 +* @date (last) 12-Aug-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 @@ -23,6 +23,7 @@ #include "Messaging.h" #include "ModePreTreat.h" #include "OperationModes.h" +#include "StatePreTxHeparinSetup.h" #include "StatePreTxRecirculate.h" #include "SyringePump.h" #include "TaskGeneral.h" @@ -54,7 +55,8 @@ static TD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState; ///< Current Pre-Treatment sub-state static BOOL goToInstallStateRequested; ///< Flag indicating a request to transition to Install state. -static BOOL continueFromRecirculateRequested; ///< Flag indicating a request to transition to Confirm Rx. +static BOOL continueFromRecirculateRequested; ///< Flag indicating a request to transition to Confirm Rx state. +static BOOL continueFromHeparinSetupRequested; ///< Flag indicating a request to transition to Patient Connection state. 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. @@ -71,13 +73,13 @@ 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 ); - /*********************************************************************//** -* @briefs +* @brief * The initPreTreatmentMode function initializes the Pre-Treatment mode. * @details Inputs: none * @details Outputs: Initializes the Treatment Parameters session and sets the initial @@ -88,9 +90,12 @@ { // Start a fresh Treatment Parameters session for this run. initTreatmentParameters(); + initPreTxHeparinSetup(); + currentPreTreatmentState = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; goToInstallStateRequested = FALSE; continueFromRecirculateRequested = FALSE; + continueFromHeparinSetupRequested = FALSE; treatmentStartRequested = FALSE; lowQdTransitionActive = FALSE; lowQdTransitionStartTime = 0U; @@ -174,6 +179,10 @@ currentPreTreatmentState = handleRecirculateState(); break; + case TD_PRE_TREATMENT_HEPARIN_SETUP_STATE: + currentPreTreatmentState = handleHeparinSetupState(); + break; + case TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE: currentPreTreatmentState = handlePatientConnectionState(); break; @@ -233,6 +242,10 @@ // No action required. break; + case TD_PRE_TREATMENT_HEPARIN_SETUP_STATE: + // Heparin Setup transition is already handled in handleRxState(). + break; + case TD_PRE_TREATMENT_RECIRCULATE_STATE: // No action required. break; @@ -272,12 +285,12 @@ { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; - // call tube set install service to auto-load tube set + // Call Tube Set Install Service to auto-load the tube set. execTubeSetInstall(); if ( TRUE == isTubeSetInstallComplete() ) { - state = TD_PRE_TREATMENT_SELF_TEST_DRY_STATE; + state = TD_PRE_TREATMENT_SELF_TEST_DRY_STATE ; } return state; @@ -351,6 +364,29 @@ /*********************************************************************//** * @brief + * The handleHeparinSetupState function executes the Heparin Setup state of + * pre-treatment mode. + * @details \b Inputs: continueFromHeparinSetupRequested. + * @details \b Outputs: continueFromHeparinSetupRequested + * @return next Pre-Treatment mode state. + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handleHeparinSetupState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_HEPARIN_SETUP_STATE; + + execPreTxHeparinSetup(); + + if ( TRUE == continueFromHeparinSetupRequested ) + { + continueFromHeparinSetupRequested = FALSE; + state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleRxState function executes the Confirm Rx pre-treatment step. * @details \b Inputs: none * @details \b Outputs: Requests transition to the next Pre-Treatment state when the prescription @@ -361,6 +397,8 @@ { BOOL paramsValid = getValidTreatParamsReceived(); BOOL paramsConfirmed = getTreatParamsConfirmed(); + BOOL heparinIsPrescribed = ( ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ) > 0.0F ) || + ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DELIVERY_RATE ) > 0.0F ) ) ? TRUE : FALSE; BOOL isDialysateGoodToDeliver = TRUE; // TODO replace TRUE with getDialysateGoodToDeliverStatus() when we are ready F32 bicarbConvFactor = BICARBONATE_CONVERSION_FACTOR; F32 presUFVolumeL = 0.0F; @@ -373,10 +411,9 @@ TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; DD_OP_MODE_T ddOpMode = getDDOpMode(); - // Valid + confirmed - move to Patient Connection state + // Valid + confirmed – move to Heparin Setup or Patient Connection. if ( ( TRUE == paramsValid ) && ( TRUE == paramsConfirmed ) ) { - // TODO this command of requesting dialysate delivery will move to appropriate state in pre-treatment once implemented if ( ( ddOpMode == DD_MODE_PREG ) && ( ddSubMode == DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND ) ) { presUFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); @@ -404,8 +441,15 @@ getTreatmentParameterU32( TREATMENT_PARAM_SODIUM ), getTreatmentParameterU32( TREATMENT_PARAM_BICARBONATE ) ); } - - state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; + if ( TRUE == heparinIsPrescribed ) + { + transitionToPreTxHeparinSetup(); + state = TD_PRE_TREATMENT_HEPARIN_SETUP_STATE; + } + else + { + state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; + } } return state; @@ -449,56 +493,55 @@ U32 prescribedQd; F32 prescribedDialTemp; - if ( FALSE == getValidTreatParamsReceived() ) + if ( TRUE != getValidTreatParamsReceived() ) { - if ( FALSE == defaultQdApplied ) + if ( TRUE != defaultQdApplied ) { - cmdChangeQd( (F32)PRE_TX_DEFAULT_QD_ML_MIN ); + cmdChangeQd( PRE_TX_DEFAULT_QD_ML_MIN ); defaultQdApplied = TRUE; } - - return; } - - prescribedQd = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); - - prescribedDialTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); - - if ( TRUE == preTreatmentRxUpdated ) + else { - preTreatmentRxUpdated = FALSE; - defaultQdApplied = FALSE; + prescribedQd = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + prescribedDialTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); - if ( prescribedQd <= PRE_TX_LOW_QD_THRESHOLD_ML_MIN ) + if ( TRUE == preTreatmentRxUpdated ) { - if ( FALSE == lowQdTransitionActive ) + preTreatmentRxUpdated = FALSE; + defaultQdApplied = FALSE; + + if ( prescribedQd <= PRE_TX_LOW_QD_THRESHOLD_ML_MIN ) { - cmdChangeQd( PRE_TX_INTERMEDIATE_QD_ML_MIN ); + if ( TRUE != lowQdTransitionActive ) + { + cmdChangeQd( PRE_TX_INTERMEDIATE_QD_ML_MIN ); - lowQdTransitionStartTime = getMSTimerCount(); - lowQdTransitionActive = TRUE; + lowQdTransitionStartTime = getMSTimerCount(); + lowQdTransitionActive = TRUE; + } + + cmdChangeDialysateTemperature( prescribedDialTemp + 1.0F ); } + else + { + cmdChangeQd( prescribedQd ); + cmdChangeDialysateTemperature( prescribedDialTemp ); - cmdChangeDialysateTemperature( prescribedDialTemp + 1.0F ); + lowQdTransitionActive = FALSE; + } } - else + + if ( ( TRUE == lowQdTransitionActive ) && + ( TRUE == didTimeout( lowQdTransitionStartTime, + PRE_TX_LOW_QD_TRANSITION_TIME_MS ) ) ) { 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; - } } /*********************************************************************//** @@ -529,64 +572,77 @@ /*********************************************************************//** * @brief - * The handleStartTreatmentRequest function handles the UI request to - * start treatment. - * @details \b Message \b Received: MSG_ID_UI_START_TREATMENT_REQUEST. - * @details \b Message \b Sent: MSG_ID_TD_START_TREATMENT_RESPONSE. - * @details \b Inputs: current operation mode and Pre-Treatment state. - * @details \b Outputs: treatmentStartRequested. - * @param message Pointer to the received Start Treatment request message. - * @return TRUE if the request was accepted, otherwise FALSE. + * The PreTxRequestContinueFromHeparinSetupRequested function signals a request to + * transition the Pre-Treatment mode state machine to Patient Connection state. + * @details \b Inputs: none + * @details \b Outputs: continueFromHeparinSetupRequested + * @return none *************************************************************************/ +void PreTxRequestContinueFromHeparinSetupRequested( void ) +{ + continueFromHeparinSetupRequested = TRUE; +} + +/*********************************************************************//** +* @brief +* The handleStartTreatmentRequest function handles the UI request to +* start treatment. +* @details \b Message \b Received: MSG_ID_UI_START_TREATMENT_REQUEST. +* @details \b Message \b Sent: MSG_ID_TD_START_TREATMENT_RESPONSE. +* @details \b Inputs: current operation mode and Pre-Treatment state. +* @details \b Outputs: treatmentStartRequested. +* @param message Pointer to the received Start Treatment request message. +* @return TRUE if the request was accepted, otherwise FALSE. +*************************************************************************/ BOOL handleStartTreatmentRequest( MESSAGE_T *message ) { - TD_OP_MODE_T mode = getCurrentOperationMode(); - TD_PRE_TREATMENT_MODE_STATE_T preTxState = currentPreTreatmentState; - U32 payloadLen = message->hdr.payloadLen; - BOOL accepted = FALSE; - UI_RESPONSE_PAYLOAD_T response; + TD_OP_MODE_T mode = getCurrentOperationMode(); + TD_PRE_TREATMENT_MODE_STATE_T preTxState = currentPreTreatmentState; + U32 payloadLen = message->hdr.payloadLen; + BOOL accepted = FALSE; + UI_RESPONSE_PAYLOAD_T response; - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + response.accepted = FALSE; + response.rejectionReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; - if ( ( 0U == payloadLen ) && ( MODE_PRET == mode ) && - ( TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE == preTxState ) ) + if ( ( 0U == payloadLen ) && ( MODE_PRET == mode ) && + ( TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE == preTxState ) ) - { - treatmentStartRequested = TRUE; - accepted = TRUE; - response.accepted = TRUE; - response.rejectionReason = REQUEST_REJECT_REASON_NONE; - } + { + treatmentStartRequested = TRUE; + accepted = TRUE; + response.accepted = TRUE; + response.rejectionReason = REQUEST_REJECT_REASON_NONE; + } - sendMessage( MSG_ID_TD_START_TREATMENT_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, - (U08 *)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); + sendMessage( MSG_ID_TD_START_TREATMENT_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, + (U08 *)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); - return accepted; + return accepted; } /*********************************************************************//** - * @brief - * The signalPreTreatmentBackoutToStandby function handles a request to - * back out of Pre-Treatment to Standby. - * @details \b Inputs: current operation mode, currentPreTreatmentState, - * and Tube Set Install state. - * @details \b Outputs: Requests Standby Mode when backout is allowed. - * @return TRUE if the request is accepted, otherwise FALSE. - *************************************************************************/ +* @brief +* The signalPreTreatmentBackoutToStandby function handles a request to +* back out of Pre-Treatment to Standby. +* @details \b Inputs: current operation mode, currentPreTreatmentState, +* and Tube Set Install state. +* @details \b Outputs: Requests Standby Mode when backout is allowed. +* @return TRUE if the request is accepted, otherwise FALSE. +*************************************************************************/ BOOL signalPreTreatmentBackoutToStandby( void ) { - BOOL accepted = FALSE; + BOOL accepted = FALSE; - if ( ( MODE_PRET == getCurrentOperationMode() ) && - ( TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE == currentPreTreatmentState ) && - ( TRUE == isTubeSetInstallAwaitingConfirmation() ) ) - { - requestNewOperationMode( MODE_STAN ); - accepted = TRUE; - } + if ( ( MODE_PRET == getCurrentOperationMode() ) && + ( TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE == currentPreTreatmentState ) && + ( TRUE == isTubeSetInstallAwaitingConfirmation() ) ) + { + requestNewOperationMode( MODE_STAN ); + accepted = TRUE; + } - return accepted; + return accepted; } /*********************************************************************//** @@ -606,28 +662,47 @@ * @brief * The signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in Pre-Treatment Mode. - * @details \b Inputs: currentPreTreatmentState - * @details \b Outputs: given alarm action executed - * @param action ID of alarm action to execute + * @details \b Inputs: currentPreTreatmentState and current Heparin Setup sub-state. + * @details \b Outputs: Alarm action handled for the active Pre-Treatment state. + * @param action ID of alarm action to execute. * @return none *************************************************************************/ void signalAlarmActionToPreTreatmentMode( ALARM_ACTION_T action ) { switch ( action ) { case ALARM_ACTION_STOP: - // TODO add logic once we have pre-treatment mode developed + // TODO add logic once we have pre-treatment mode developed. break; case ALARM_ACTION_RESUME: - if ( TD_PRE_TREATMENT_RECIRCULATE_STATE == currentPreTreatmentState ) - { + if ( TD_PRE_TREATMENT_RECIRCULATE_STATE == currentPreTreatmentState ) + { signalResumePreTxRecirculate(); - } - break; + } + else if ( TD_PRE_TREATMENT_HEPARIN_SETUP_STATE == currentPreTreatmentState ) + { + signalResumePreTxHeparinSetup(); + } + else + { + // No action required. + } + break; + case ALARM_ACTION_ACK: + if ( ( TD_PRE_TREATMENT_HEPARIN_SETUP_STATE == currentPreTreatmentState ) && + ( TRUE == isPreTxHeparinAwaitingSyringeLoadConfirmation() ) && + ( FALSE == isAlarmActive( ALARM_ID_TD_PRE_TX_HEPARIN_LOAD_SYRINGE ) ) ) + { + // OK on the Load Syringe clear-only alarm confirms that + // the syringe was loaded and resumes the paused state. + signalResumePreTxHeparinSetup(); + } + break; + default: - // do not handle other actions in pre-treatment mode + // Do not handle other actions in Pre-Treatment mode. break; } }