/************************************************************************** * * Copyright (c) 2025-2026 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ModePreTreat.c * * @author (last) Varshini Nagabooshanam * @date (last) 26-Jan-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 * ***************************************************************************/ #include "BloodFlow.h" #include "Buttons.h" #include "Messaging.h" #include "ModePreTreat.h" #include "OperationModes.h" #include "PeristalticPump.h" #include "Switches.h" #include "TaskGeneral.h" #include "TDDefs.h" #include "Timers.h" #include "TxParams.h" /** * @addtogroup TDPreTreatmentMode * @{ */ // ********** private definitions ********** ///< Auto-Load timeout interval (ms/task time) #define AUTO_LOAD_TIMEOUT_INTERVAL ( ( 10 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) //< Blood pump flow rate (mL/min) for Auto-Load operation #define AUTO_LOAD_BLOOD_FLOW_RATE_ML_MIN 100U // ********** private data ********** static BOOL confirmTubesetPlaced; ///< Flag indicating user has confirmed tubeset is placed static U32 autoLoadTimerCounter; ///< Auto-Load operation timer counter static TD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState; ///< Current Pre-Treatment sub-state static PRE_TX_INSTALL_STATE_T currentPreTxInstallState; ///< Current Pre-Treatment Install sub-state // ********** 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 handleSelfTestDryState( 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 PRE_TX_INSTALL_STATE_T handleAwaitTubesetConfirmationState( void ); ///< Handle Await Tubset Install Confirmation sub-state static PRE_TX_INSTALL_STATE_T handleAutoLoadState( void ); ///< Handle Auto-Load sub-state /*********************************************************************//** * @brief * The initPreTreatmentMode function initializes the Pre-Treatment mode. * @details Inputs: none * @details Outputs: Resets the Treatment Parameters session and sets the initial * Pre-Treatment sub-state. * @return none **************************************************************************/ void initPreTreatmentMode( void ) { // Start a fresh Treatment Parameters session for this run. resetTreatmentParameters(); currentPreTreatmentState = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; currentPreTxInstallState = PRE_TX_INSTALL_STATE_AWAIT_TUBING_SET_CONFIRMATION; confirmTubesetPlaced = FALSE; autoLoadTimerCounter = 0; } /*********************************************************************//** * @brief * The transitionToPreTreatmentMode function prepares the system for * entry into Pre-Treatment mode. * @details Inputs: none * @details Outputs: Initializes mode specific state and returns the starting * Pre-Treatment sub-state. * @return Initial Pre-Treatment sub-state **************************************************************************/ U32 transitionToPreTreatmentMode( void ) { initPreTreatmentMode(); return (U32)currentPreTreatmentState; } /*********************************************************************//** * @brief * The execPreTreatmentMode function executes the Pre-Treatment * mode state machine. * @details Inputs: stop button status and system conditions via helpers. * @details Outputs: Advances the Pre-Treatment sub-state and * previously received user confirmations. * @return current Pre-Treatment sub-state. *************************************************************************/ U32 execPreTreatmentMode( void ) { BOOL stop = isStopButtonPressed(); if ( TRUE == stop ) { activateAlarmNoData( ALARM_ID_TD_TREATMENT_STOPPED_BY_USER ); } // 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; case TD_PRE_TREATMENT_SELF_TEST_DRY_STATE: // currentPreTreatmentState = handleSelfTestDryState(); break; case TD_PRE_TREATMENT_PRIME_STATE: // currentPreTreatmentState = handlePrimeState(); break; case TD_PRE_TREATMENT_RECIRCULATE_STATE: // currentPreTreatmentState = handleRecirculateState(); break; case TD_PRE_TREATMENT_CONFIRM_RX_STATE: // Confirm Rx state currentPreTreatmentState = handleRxState(); break; case TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE: // currentPreTreatmentState = handlePatientConnectionState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, (U32)currentPreTreatmentState ); break; } return (U32)currentPreTreatmentState; } /*********************************************************************//** * @brief * The handleWaterSampleState function executes the Water Sample state of * pre-treatment mode. * @details Inputs: TODO fill up if any * @details Outputs: TODO fill up if any * @return next Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ) { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_WATER_SAMPLE_STATE; // TODO: Transition to Self test consumable state on completion when implemented // state = TD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; return state; } /*********************************************************************//** * @brief * The handleSelfTestConsumableState function executes the Self Test * Consumable state of pre-treatment mode. * @details Inputs: TODO fill up if any * @details 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; // TODO: Transition to Self test no cart state on completion when implemented // state = TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; return state; } /*********************************************************************//** * @brief * The handleSelfTestNoCartState function executes the Self Test No Cart * state of pre-treatment mode. * @details Inputs: TODO fill up if any * @details 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: Transition to Tubing set install state on completion when implemented // state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; return state; } /*********************************************************************//** * @brief * The handleInstallState function executes the Pre-Treatment Install * state machine. * @details Inputs: currentPreTxInstallState * @details Outputs: Advances the Pre-Treatment Install sub-state and * next Pre-Treatment top-level state when install is complete. * @return current Pre-Treatment state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ) { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; switch(currentPreTxInstallState) { case PRE_TX_INSTALL_STATE_AWAIT_TUBING_SET_CONFIRMATION: currentPreTxInstallState = handleAwaitTubesetConfirmationState(); break; case PRE_TX_INSTALL_STATE_AUTO_LOAD: currentPreTxInstallState = handleAutoLoadState(); if ( NUM_OF_PRE_TX_INSTALL_SUB_STATES == currentPreTxInstallState ) { state = TD_PRE_TREATMENT_SELF_TEST_DRY_STATE; } break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TX_INSTALL_INVALID_STATE, (U32)currentPreTxInstallState ); break; } return state; } /*********************************************************************//** * @brief * The handleSelfTestDryState function executes the Self Test Dry state * of pre-treatment mode. * @details Inputs: TODO fill up if any * @details Outputs: TODO fill up if any * @return next Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ) { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_SELF_TEST_DRY_STATE; // TODO: Transition to Prime state on completion when implemented // state = TD_PRE_TREATMENT_PRIME_STATE; return state; } /*********************************************************************//** * @brief * The handlePrimeState function executes the Prime state of * pre-treatment mode. * @details Inputs: TODO fill up if any * @details Outputs: TODO fill up if any * @return next Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ) { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_PRIME_STATE; // TODO: Transition to Recirculate state on completion when implemented // state = TD_PRE_TREATMENT_RECIRCULATE_STATE; return state; } /*********************************************************************//** * @brief * The handleRecirculateState function executes the Recirculate state of * pre-treatment mode. * @details Inputs: TODO fill up if any * @details Outputs: TODO fill up if any * @return next Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ) { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_RECIRCULATE_STATE; // TODO: Transition to Confirm RX state on completion when implemented // state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; return state; } /*********************************************************************//** * @brief * The handleRxState function executes the Confirm Rx pre-treatment step. * @details Inputs: none * @details Outputs: Requests transition to Treatment mode when the prescription * is valid and confirmed otherwise remains in Confirm Rx. * @return next Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ) { BOOL paramsValid = getValidTreatParamsReceived(); BOOL paramsConfirmed = getTreatParamsConfirmed(); TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; // Valid + confirmed – move to next state: Patient Connection if ( ( TRUE == paramsValid ) && ( TRUE == paramsConfirmed ) ) { state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; } return state; } /*********************************************************************//** * @brief * The handlePatientConnectionState function executes the Patient * Connection state of pre-treatment mode. * @details Inputs: TODO fill up if any * @details Outputs: TODO fill up if any * @return next 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 requestNewOperationMode( MODE_TREA ); return state; } /*********************************************************************//** * @brief * The handleAwaitTubesetConfirmationState function handles the Await * tubeset confirmation state of Pre-Treatement mode install state * machine. Should wait for the user to confirm the tubeset is placed, * and verifies that the blood pump door (H9) is closed. * @details Inputs: confirmTubsetPlaced * @details Outputs: confirmTubesetPlaced * return next Pre-Treatment Install sub-state *************************************************************************/ static PRE_TX_INSTALL_STATE_T handleAwaitTubesetConfirmationState( void ) { PRE_TX_INSTALL_STATE_T subState = PRE_TX_INSTALL_STATE_AWAIT_TUBING_SET_CONFIRMATION; if ( TRUE == confirmTubesetPlaced ) { // Door closed required from Auto-loading onwards, set to false if not required in subsequent states doorClosedRequired( TRUE ); confirmTubesetPlaced = FALSE; setBloodPumpTargetFlowRate( AUTO_LOAD_BLOOD_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); subState = PRE_TX_INSTALL_STATE_AUTO_LOAD; } return subState; } /*********************************************************************//** * @brief * The handleAutoLoadState function handles the Auto-Load state of * Pre-Treatement mode install state. * @details Inputs: autoLoadTimerCounter * @details Outputs: autoLoadTimerCounter * return next Pre-Treatment Install sub-state *************************************************************************/ static PRE_TX_INSTALL_STATE_T handleAutoLoadState( void ) { PRE_TX_INSTALL_STATE_T subState = PRE_TX_INSTALL_STATE_AUTO_LOAD; // Timeout check if ( ++autoLoadTimerCounter >= AUTO_LOAD_TIMEOUT_INTERVAL ) { signalBloodPumpHardStop(); SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_AUTO_LOAD_EJECT_BP_TIMEOUT, isPeristalticPumpHome(), autoLoadTimerCounter ); } else if ( TRUE == isPeristalticPumpHome() ) { signalBloodPumpHardStop(); autoLoadTimerCounter = 0; subState = NUM_OF_PRE_TX_INSTALL_SUB_STATES; } return subState; } /*********************************************************************//** * @brief * The handleAutoLoadRequest function handles a UI request to * confirm tubeset installation. * @details Inputs: none * @details Outputs: confirmTubesetPlaced * @param message UI message which includes the user confirmation of * tubset installation. * @return TRUE if confirmation/rejection accepted, FALSE if not *************************************************************************/ BOOL handleAutoLoadRequest( MESSAGE_T *message ) { BOOL result = FALSE; BOOL notInValidState = FALSE; TD_OP_MODE_T mode = getCurrentOperationMode(); UI_RESPONSE_PAYLOAD_T response; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_INVALID_PAYLOAD_LENGTH; if ( 0 == message->hdr.payloadLen ) { notInValidState = ( ( ( TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE != currentPreTreatmentState ) || ( PRE_TX_INSTALL_STATE_AWAIT_TUBING_SET_CONFIRMATION != currentPreTxInstallState ) ) ? TRUE : FALSE ); if ( ( mode != MODE_PRET ) || ( TRUE == notInValidState ) ) { rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; } else { confirmTubesetPlaced = TRUE; result = TRUE; rejReason = REQUEST_REJECT_REASON_NONE; } } response.accepted = result; response.rejectionReason = rejReason; sendMessage( MSG_ID_TD_ADJUST_DISPOSABLES_CONFIRM_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)(&response), sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } /**@}*/