/************************************************************************** * * Copyright (c) 2026-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 StatePreTxHeparinSetup.c * * @author (last) Vijay Pamula * @date (last) 06-Jun-2026 * * @author (original) Vijay Pamula * @date (original) 06-Jun-2026 * ***************************************************************************/ #include "AlarmMgmtTD.h" #include "Messaging.h" #include "ModePreTreat.h" #include "OperationModes.h" #include "StatePreTxHeparinSetup.h" #include "SyringePump.h" #include "TxParams.h" /** * @addtogroup StatePreTxHeparinSetup * @{ */ // ********** private definitions ********** /// Enumeration of Pre-Treatment Heparin Setup sub-states. typedef enum { PRE_TX_HEPARIN_SETUP_PRELOAD_STATE = 0, ///< Preload heparin syringe state. PRE_TX_HEPARIN_SETUP_AWAIT_SYRINGE_LOAD_CONFIRMATION_STATE, ///< Await syringe load confirmation state. PRE_TX_HEPARIN_SETUP_SEEK_STATE, ///< Seek syringe plunger state. PRE_TX_HEPARIN_SETUP_PRIME_STATE, ///< Prime heparin line state. PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE, ///< Heparin setup occlusion check state. PRE_TX_HEPARIN_SETUP_BOLUS_STATE, ///< Deliver heparin bolus state. PRE_TX_HEPARIN_SETUP_PAUSED_STATE, ///< Paused state. NUM_OF_PRE_TX_HEPARIN_SETUP_STATES ///< Number of pre-treatment heparin setup substates. } PRE_TX_HEPARIN_SETUP_STATE_T; // ********** private data ********** static PRE_TX_HEPARIN_SETUP_STATE_T currentPreTxHeparinSetupState; ///< Current state of the pre-treatment heparin setup state machine. static PRE_TX_HEPARIN_SETUP_STATE_T interruptedPreTxHeparinSetupState; ///< Pre-treatment heparin setup substate interrupted by a recoverable alarm. static BOOL heparinSetupResumeRequested; ///< Flag indicates alarm requesting to resume pre-treatment heparin setup. static BOOL syringeLoadConfirmed; ///< Flag indicates user confirmed syringe load. // ********** private function prototypes ********** static void resetPreTxHeparinSetupFlags( void ); static void setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_STATE_T state ); static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinPreloadState( void ); static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinAwaitSyringeLoadConfirmationState( void ); static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinSeekState( void ); static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinPrimeState( void ); static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinOcclusionCheckState( void ); static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinBolusState( void ); static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinPausedState( void ); /*********************************************************************//** * @brief * The initPreTxHeparinSetup function initializes the pre-treatment * heparin setup state machine. * @details Inputs: none * @details Outputs: Pre-treatment heparin setup initialized. * @return none *************************************************************************/ void initPreTxHeparinSetup( void ) { currentPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_PRELOAD_STATE; interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_PRELOAD_STATE; resetPreTxHeparinSetupFlags(); } /*********************************************************************//** * @brief * The transitionToPreTxHeparinSetup function prepares for transition * into the pre-treatment heparin setup state. * @details Inputs: none * @details Outputs: Heparin setup initialized. * @return none *************************************************************************/ void transitionToPreTxHeparinSetup( void ) { setCurrentSubState( (U32)currentPreTxHeparinSetupState ); } /*********************************************************************//** * @brief * The execPreTxHeparinSetup function executes the pre-treatment heparin * setup state machine. * @details Inputs: currentPreTxHeparinSetupState * @details Outputs: currentPreTxHeparinSetupState * @return none *************************************************************************/ void execPreTxHeparinSetup( void ) { PRE_TX_HEPARIN_SETUP_STATE_T priorSubState = currentPreTxHeparinSetupState; switch ( currentPreTxHeparinSetupState ) { case PRE_TX_HEPARIN_SETUP_PRELOAD_STATE: currentPreTxHeparinSetupState = handlePreTxHeparinPreloadState(); break; case PRE_TX_HEPARIN_SETUP_AWAIT_SYRINGE_LOAD_CONFIRMATION_STATE: currentPreTxHeparinSetupState = handlePreTxHeparinAwaitSyringeLoadConfirmationState(); break; case PRE_TX_HEPARIN_SETUP_SEEK_STATE: currentPreTxHeparinSetupState = handlePreTxHeparinSeekState(); break; case PRE_TX_HEPARIN_SETUP_PRIME_STATE: currentPreTxHeparinSetupState = handlePreTxHeparinPrimeState(); break; case PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE: currentPreTxHeparinSetupState = handlePreTxHeparinOcclusionCheckState(); break; case PRE_TX_HEPARIN_SETUP_BOLUS_STATE: currentPreTxHeparinSetupState = handlePreTxHeparinBolusState(); break; case PRE_TX_HEPARIN_SETUP_PAUSED_STATE: currentPreTxHeparinSetupState = handlePreTxHeparinPausedState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_PRE_TX_HEPARIN_SETUP_STATE, currentPreTxHeparinSetupState ); break; } if ( priorSubState != currentPreTxHeparinSetupState ) { setCurrentSubState( (U32)currentPreTxHeparinSetupState ); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, priorSubState, currentPreTxHeparinSetupState ); } resetPreTxHeparinSetupFlags(); } /*********************************************************************//** * @brief * The getPreTxHeparinSetupState function returns the current state of the * pre-treatment heparin setup state machine. * @details Inputs: currentPreTxHeparinSetupState * @details Outputs: none * @return Current pre-treatment heparin setup state. *************************************************************************/ U32 getPreTxHeparinSetupState( void ) { return (U32)currentPreTxHeparinSetupState; } /*********************************************************************//** * @brief * The signalResumePreTxHeparinSetup function signals a resume request for * the pre-treatment heparin setup state machine. * @details Inputs: none * @details Outputs: heparinSetupResumeRequested * @return none *************************************************************************/ void signalResumePreTxHeparinSetup( void ) { heparinSetupResumeRequested = TRUE; } /*********************************************************************//** * @brief * The signalPreTxHeparinSyringeLoadConfirmed function signals that the * user confirmed syringe load. * @details Inputs: none * @details Outputs: syringeLoadConfirmed * @return none *************************************************************************/ void signalPreTxHeparinSyringeLoadConfirmed( void ) { syringeLoadConfirmed = TRUE; } /*********************************************************************//** * @brief * The resetPreTxHeparinSetupFlags function resets all signal flags used by * the pre-treatment heparin setup state machine. * @details Inputs: none * @details Outputs: Signal flags reset. * @return none *************************************************************************/ static void resetPreTxHeparinSetupFlags( void ) { heparinSetupResumeRequested = FALSE; syringeLoadConfirmed = FALSE; } /*********************************************************************//** * @brief * The setupPreTxHeparinState function configures the syringe pump for the * specified pre-treatment heparin setup state. * @details Inputs: state * @details Outputs: Syringe pump configured for the specified state. * @return none *************************************************************************/ static void setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_STATE_T state ) { stopSyringePump(); switch ( state ) { case PRE_TX_HEPARIN_SETUP_PRELOAD_STATE: resetPreLoadStatus(); preloadSyringePlunger(); break; case PRE_TX_HEPARIN_SETUP_SEEK_STATE: seekSyringePlunger(); break; case PRE_TX_HEPARIN_SETUP_PRIME_STATE: primeSyringePump(); break; case PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE: // No additional setup required. break; case PRE_TX_HEPARIN_SETUP_BOLUS_STATE: startHeparinBolus(); break; case PRE_TX_HEPARIN_SETUP_PAUSED_STATE: // Syringe pump already stopped above. break; default: break; } } /*********************************************************************//** * @brief * The handlePreTxHeparinPreloadState function handles the preload state. * @details \b Inputs: none * @details \b Outputs: Next pre-treatment heparin setup state. * @return Current or next pre-treatment heparin setup state. *************************************************************************/ static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinPreloadState( void ) { PRE_TX_HEPARIN_SETUP_STATE_T state = PRE_TX_HEPARIN_SETUP_PRELOAD_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_PRELOAD_STATE; setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PAUSED_STATE ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; } else if ( ( FALSE == isSyringePumpRunning() ) && ( FALSE == isSyringePumpPreLoaded() ) ) { setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PRELOAD_STATE ); } else if ( TRUE == isSyringePumpPreLoaded() ) { state = PRE_TX_HEPARIN_SETUP_AWAIT_SYRINGE_LOAD_CONFIRMATION_STATE; } return state; } /*********************************************************************//** * @brief * The handlePreTxHeparinAwaitSyringeLoadConfirmationState function handles * the await syringe load confirmation state. * @details \b Inputs: none * @details \b Outputs: Next pre-treatment heparin setup state. * @return Current or next pre-treatment heparin setup state. *************************************************************************/ static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinAwaitSyringeLoadConfirmationState( void ) { PRE_TX_HEPARIN_SETUP_STATE_T state = PRE_TX_HEPARIN_SETUP_AWAIT_SYRINGE_LOAD_CONFIRMATION_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_AWAIT_SYRINGE_LOAD_CONFIRMATION_STATE; setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PAUSED_STATE ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; } else if ( TRUE == syringeLoadConfirmed ) { setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_SEEK_STATE ); state = PRE_TX_HEPARIN_SETUP_SEEK_STATE; } return state; } /*********************************************************************//** * @brief * The handlePreTxHeparinSeekState function handles the seek state. * @details \b Alarms: ALARM_ID_TD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM * if the syringe contains insufficient heparin for the prescribed treatment. * @details \b Inputs: none * @details \b Outputs: Next pre-treatment heparin setup state. * @return Current or next pre-treatment heparin setup state. *************************************************************************/ static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinSeekState( void ) { PRE_TX_HEPARIN_SETUP_STATE_T state = PRE_TX_HEPARIN_SETUP_SEEK_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_SEEK_STATE; setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PAUSED_STATE ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; } else if ( TRUE == isSyringePlungerFound() ) { if ( TRUE == isSyringeVolumeAdequate() ) { setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PRIME_STATE ); state = PRE_TX_HEPARIN_SETUP_PRIME_STATE; } else { interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_SEEK_STATE; setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PAUSED_STATE ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; } } return state; } /*********************************************************************//** * @brief * The handlePreTxHeparinPrimeState function handles the prime state. * @details \b Inputs: none * @details \b Outputs: Next pre-treatment heparin setup state. * @return Current or next pre-treatment heparin setup state. *************************************************************************/ static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinPrimeState( void ) { PRE_TX_HEPARIN_SETUP_STATE_T state = PRE_TX_HEPARIN_SETUP_PRIME_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_PRIME_STATE; setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PAUSED_STATE ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; } else if ( TRUE == isSyringePumpPrimed() ) { setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE ); state = PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE; } return state; } /*********************************************************************//** * @brief * The handlePreTxHeparinOcclusionCheckState function handles the heparin * pump occlusion check state. * @details \b Alarms: ALARM_ID_TD_SYRINGE_PUMP_OCCLUSION if the * heparin pump occlusion check fails. * @details \b Inputs: none * @details \b Outputs: Next pre-treatment heparin setup state. * @return Current or next pre-treatment heparin setup state. *************************************************************************/ static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinOcclusionCheckState( void ) { PRE_TX_HEPARIN_SETUP_STATE_T state = PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE; setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PAUSED_STATE ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; } else if ( FALSE == checkForSyringeOcclusion( FALSE ) ) { // Occlusion check passed. Continue to bolus if prescribed; otherwise continue to Patient Connection. if ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ) > 0.0F ) { setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_BOLUS_STATE ); state = PRE_TX_HEPARIN_SETUP_BOLUS_STATE; } else { PreTxRequestContinueFromHeparinSetupRequested(); } } else { // Occlusion check failed. Alarm is handled by checkForSyringeOcclusion(). interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE; setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PAUSED_STATE ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; } return state; } /*********************************************************************//** * @brief * The handlePreTxHeparinBolusState function handles the bolus state. * @details \b Inputs: none * @details \b Outputs: Next pre-treatment heparin setup state. * @return Current or next pre-treatment heparin setup state. *************************************************************************/ static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinBolusState( void ) { PRE_TX_HEPARIN_SETUP_STATE_T state = PRE_TX_HEPARIN_SETUP_BOLUS_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { interruptedPreTxHeparinSetupState = PRE_TX_HEPARIN_SETUP_BOLUS_STATE; setupPreTxHeparinState( PRE_TX_HEPARIN_SETUP_PAUSED_STATE ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; } else if ( TRUE == isSyringePumpStopped() ) { PreTxRequestContinueFromHeparinSetupRequested(); } return state; } /*********************************************************************//** * @brief * The handlePreTxHeparinPausedState function handles the paused state. * @details \b Inputs: none * @details \b Outputs: Next pre-treatment heparin setup state. * @return Current or next pre-treatment heparin setup state. *************************************************************************/ static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinPausedState( void ) { PRE_TX_HEPARIN_SETUP_STATE_T state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; if ( TRUE == heparinSetupResumeRequested ) { // Resume from Preload, Await Syringe Load Confirmation, or Seek by // retracting the syringe and restarting the preload sequence. if ( ( PRE_TX_HEPARIN_SETUP_PRELOAD_STATE == interruptedPreTxHeparinSetupState ) || ( PRE_TX_HEPARIN_SETUP_AWAIT_SYRINGE_LOAD_CONFIRMATION_STATE == interruptedPreTxHeparinSetupState ) || ( PRE_TX_HEPARIN_SETUP_SEEK_STATE == interruptedPreTxHeparinSetupState ) ) { retractSyringePump(); state = PRE_TX_HEPARIN_SETUP_PRELOAD_STATE; } else { // Resume from the interrupted state after the alarm is cleared. state = interruptedPreTxHeparinSetupState; switch ( state ) { case PRE_TX_HEPARIN_SETUP_PRIME_STATE: case PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE: case PRE_TX_HEPARIN_SETUP_BOLUS_STATE: setupPreTxHeparinState( state ); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_PRE_TX_HEPARIN_SETUP_STATE, interruptedPreTxHeparinSetupState ); state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; break; } } } return state; } /**@}*/