Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r927dfd6e109af46160e5aef687f1b7c286d24703 -r3f325a9fe7cbfb660a3ddf274d471d635266c586 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 927dfd6e109af46160e5aef687f1b7c286d24703) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 3f325a9fe7cbfb660a3ddf274d471d635266c586) @@ -8,28 +8,31 @@ * @file ModePreTreat.c * * @author (last) Vijay Pamula -* @date (last) 12-Jun-2026 +* @date (last) 31-Jul-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 * ***************************************************************************/ +#include "AirPump.h" +#include "AirTrap.h" #include "BloodFlow.h" #include "Buttons.h" #include "DrySelfTests.h" #include "DDInterface.h" +#include "Messaging.h" #include "ModePreTreat.h" #include "OperationModes.h" -<<<<<<< HEAD #include "TaskGeneral.h" -======= #include "StatePreTxRecirculate.h" ->>>>>>> 0904e146ed12daa575b419612f5cdef5000fd0f5 +#include "SyringePump.h" +#include "TaskGeneral.h" #include "Timers.h" #include "TubeSetInstall.h" #include "TxParams.h" #include "Valves.h" +#include "Valve3Way.h" /** * @addtogroup TDPreTreatmentMode @@ -40,29 +43,41 @@ #define SUBMODE_COMPLETE_UI_TRANSITION_TIME_COUNT ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +/// Interval (ms/task time) at which the Pre-Treatment state data is published on the CAN bus. +#define PRE_TREATMENT_STATE_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) + +/// Initial offset used to stagger the Pre-Treatment state data broadcast. +#define PRE_TREATMENT_STATE_DATA_PUB_INITIAL_OFFSET 5U + // ********** private data ********** 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. -<<<<<<< HEAD static BOOL alarmActionResumeReceived; ///< Flag indicates alarm action resume received. static BOOL tubeSetInstallRequested; ///< Request to re-enter install flow (mid-treatment / failure) static U32 submodeCompleteTransitionTimeCounter; ///< Sub-mode completed transition wait time counter. -======= static BOOL continueFromRecirculateRequested; ///< Flag indicating a request to transition to Patient Connection state. ->>>>>>> 0904e146ed12daa575b419612f5cdef5000fd0f5 +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 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 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. + // ********** private function prototypes ********** -static TD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ); ///< Handle Water Sample state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestConsumableState( void ); ///< Handle Self Test Consumable state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestNoCartState( void ); ///< Handle Self Test No Cart state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); ///< Handle Install 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 handlePatientConnectionState( void ); ///< Handle Patient Connection state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleDrySelfTestState( void ); ///< Handle dry self tests state during Pre-Treatment +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 handlePatientConnectionState( void ); ///< Handle Patient Connection state during Pre-Treatment +static void publishPreTreatmentStates( void ); ///< Publish Pre-Treatment states to the UI. /*********************************************************************//** * @brief @@ -76,9 +91,19 @@ { // Start a fresh Treatment Parameters session for this run. initTreatmentParameters(); - currentPreTreatmentState = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; - goToInstallStateRequested = FALSE; - continueFromRecirculateRequested = FALSE; + currentPreTreatmentState = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; + goToInstallStateRequested = FALSE; + continueFromRecirculateRequested = FALSE; + treatmentStartRequested = FALSE; + preTreatmentStateBroadcastTimerCtr = PRE_TREATMENT_STATE_DATA_PUB_INITIAL_OFFSET; + + preTreatmentStatePublishInterval = (OVERRIDE_U32_T) + { + PRE_TREATMENT_STATE_DATA_PUB_INTERVAL, + PRE_TREATMENT_STATE_DATA_PUB_INTERVAL, + PRE_TREATMENT_STATE_DATA_PUB_INTERVAL, + 0 + }; } /*********************************************************************//** @@ -117,6 +142,7 @@ U32 execPreTreatmentMode( void ) { BOOL stop = isStopButtonPressed(); + TD_PRE_TREATMENT_MODE_STATE_T prevPreTreatmentState = currentPreTreatmentState; if ( TRUE == stop ) { @@ -126,18 +152,6 @@ // Execute mode state machine switch ( currentPreTreatmentState ) { - case TD_PRE_TREATMENT_WATER_SAMPLE_STATE: - currentPreTreatmentState = handleWaterSampleState(); - break; - - case TD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE: - currentPreTreatmentState = handleSelfTestConsumableState(); - break; - - case TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE: - currentPreTreatmentState = handleSelfTestNoCartState(); - break; - case TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE: currentPreTreatmentState = handleInstallState(); break; @@ -163,7 +177,9 @@ break; default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, (U32)currentPreTreatmentState ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, + SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, + (U32)currentPreTreatmentState ); break; } @@ -184,57 +200,63 @@ } /*********************************************************************//** - * @brief - * The handleWaterSampleState function executes the Water Sample state of - * pre-treatment mode. - * @details \b Inputs: TODO fill up if any - * @details \b Outputs: TODO fill up if any - * @return next Pre-Treatment mode state. - *************************************************************************/ -static TD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ) +* @brief +* The setPreTreatStateTransition function sets the actuators and variables +* for the state transition in Pre-Treatment mode. +* @details \b Inputs: currentPreTreatmentState +* @details \b Outputs: Actuate valves, pumps as desired +* @return none +**************************************************************************/ +static void setPreTreatStateTransition( void ) { - TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_WATER_SAMPLE_STATE; + switch ( currentPreTreatmentState ) + { + case TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE: + // H4 and H5 are controlled by the Tube Set Install Service. + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + stopSyringePump(); + break; - // TODO: Transition to Self test consumable state on completion when implemented - // state = TD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; + case TD_PRE_TREATMENT_SELF_TEST_DRY_STATE: + // TODO: actuator configuration + break; - return state; -} + case TD_PRE_TREATMENT_PRIME_STATE: + // TODO: actuator configuration + break; -/*********************************************************************//** - * @brief - * The handleSelfTestConsumableState function executes the Self Test - * Consumable state of pre-treatment mode. - * @details \b Inputs: TODO fill up if any - * @details \b Outputs: TODO fill up if any - * @return next Pre-Treatment mode state. - *************************************************************************/ -static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestConsumableState( void ) -{ - TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; + case TD_PRE_TREATMENT_CONFIRM_RX_STATE: + // No action required. + break; - // TODO: Transition to Self test no cart state on completion when implemented - // state = TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; + case TD_PRE_TREATMENT_RECIRCULATE_STATE: + // No action required. + break; - return state; -} + case TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE: + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + stopSyringePump(); -/*********************************************************************//** - * @brief - * The handleSelfTestNoCartState function executes the Self Test No Cart - * state of pre-treatment mode. - * @details \b Inputs: TODO fill up if any - * @details \b Outputs: TODO fill up if any - * @return next Pre-Treatment mode state. - *************************************************************************/ -static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestNoCartState( void ) -{ - TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; + // TODO: Set H5 ejector Off. + // TODO: Command DD to bypass dialyzer, set QDt to prescribed rate, + // Quf to 0, and Qs to 0. + break; - // TODO: Transition to Tubing set install state on completion when implemented - // state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; - - return state; + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, + SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, + (U32)currentPreTreatmentState ); + break; + } } /*********************************************************************//** @@ -262,7 +284,7 @@ /*********************************************************************//** * @brief - * The handleSelfTestDryState function performs dry self-test. + * The handleDrySelfTestState function performs dry self-test. * @details \b Inputs: none * @details \b Outputs: transition to prime state on user request * @return current state (sub-mode) @@ -283,7 +305,7 @@ if ( TRUE == tubeSetInstallRequested ) { tubeSetInstallRequested = FALSE; - state = TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; +// state = TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; } if ( DRY_SELF_TESTS_COMPLETE_STATE == getDrySelfTestsState() ) @@ -292,10 +314,10 @@ { submodeCompleteTransitionTimeCounter = 0; state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; - // TODO // transitionToPrime(); } } + return state; } @@ -334,12 +356,7 @@ if ( TRUE == continueFromRecirculateRequested ) { continueFromRecirculateRequested = FALSE; - - // TODO: Change to TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE - // when Patient Connection state is implemented. - // state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; - - requestNewOperationMode( MODE_TREA ); + state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; } return state; @@ -382,7 +399,7 @@ getTreatmentParameterU32( TREATMENT_PARAM_BICARBONATE ) ); } - state = TD_PRE_TREATMENT_RECIRCULATE_STATE; + state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; } return state; @@ -391,19 +408,22 @@ /*********************************************************************//** * @brief * The handlePatientConnectionState function executes the Patient - * Connection state of pre-treatment mode. - * @details \b Inputs: TODO fill up if any - * @details \b Outputs: TODO fill up if any - * @return next Pre-Treatment mode state. + * Connection pre-treatment step. + * @details \b Inputs: treatmentStartRequested. + * @details \b Outputs: Requests transition to Treatment Mode when the + * UI Start Treatment request is received. + * @return current Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ) { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; - // TODO : after implementing this state, place the transition in the right place + if ( TRUE == treatmentStartRequested ) + { + treatmentStartRequested = FALSE; + requestNewOperationMode( MODE_TREA ); + } - //requestNewOperationMode( MODE_TREA ); - return state; } @@ -423,7 +443,7 @@ /*********************************************************************//** * @brief * The PreTxRequestContinueFromRecirculate function signals a request to - * transition the Pre-Treatment mode state machine to Patient Connection state. + * transition the Pre-Treatment mode state machine to Confirm Rx state. * @details \b Inputs: none * @details \b Outputs: continueFromRecirculateRequested * @return none @@ -435,6 +455,68 @@ /*********************************************************************//** * @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; + + 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 ) ) + + { + 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 ) ); + + 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. + *************************************************************************/ +BOOL signalPreTreatmentBackoutToStandby( void ) +{ + BOOL accepted = FALSE; + + if ( ( MODE_PRET == getCurrentOperationMode() ) && + ( TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE == currentPreTreatmentState ) && + ( TRUE == isTubeSetInstallAwaitingConfirmation() ) ) + { + requestNewOperationMode( MODE_STAN ); + accepted = TRUE; + } + + return accepted; +} + +/*********************************************************************//** + * @brief * The signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in Pre-Treatment Mode. * @details \b Inputs: currentPreTreatmentState @@ -463,4 +545,64 @@ } } +/*********************************************************************//** + * @brief + * The publishPreTreatmentStates function publishes the current + * Pre-Treatment state and associated sub-state data to the UI. + * @details \b Inputs: currentPreTreatmentState, preTreatmentStatePublishInterval + * preTreatmentStateBroadcastTimerCtr. + * @details \b Outputs: preTreatmentStateBroadcastTimerCtr. + * @return none + *************************************************************************/ +static void publishPreTreatmentStates( void ) +{ + if ( ++preTreatmentStateBroadcastTimerCtr >= getU32OverrideValue( &preTreatmentStatePublishInterval ) ) + { + PRE_TREATMENT_STATES_DATA_PAYLOAD_T payload = { 0 }; + + preTreatmentStateBroadcastTimerCtr = 0; + + payload.mSubMode = (U32)currentPreTreatmentState; + payload.mInstallState = (U32)getTubeSetInstallState(); + payload.mSelfTestDryState = 0; + payload.mPrimeState = 0; + payload.mRecirculateState = getPreTxRecirculateState(); + payload.mConfirmRxState = 0; + payload.mHeparinState = 0; + payload.mPatientConnectionState = 0; + + broadcastData( MSG_ID_TD_PRE_TREATMENT_STATES_DATA, + COMM_BUFFER_OUT_CAN_TD_BROADCAST, + (U08 *)&payload, + sizeof( PRE_TREATMENT_STATES_DATA_PAYLOAD_T ) ); + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testPreTreatmentStatePublishIntervalOverride function overrides or + * resets the Pre-Treatment state data publication interval. + * @details \b Inputs: message + * @details \b Outputs: preTreatmentStatePublishInterval + * @param message Override message from Dial-in containing the interval + * in milliseconds, or a reset command. + * @return TRUE if the override or reset is successful, otherwise FALSE. + *************************************************************************/ +BOOL testPreTreatmentStatePublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + result = u32BroadcastIntervalOverride( message, + &preTreatmentStatePublishInterval, + TASK_GENERAL_INTERVAL ); + + return result; +} + /**@}*/