/************************************************************************** * * 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 StatePreTxDrySelfTests.c * * @author (last) Varshini Nagabooshanam * @date (last) 01-Apr-2026 * * @author (original) Varshini Nagabooshanam * @date (original) 01-Apr-2026 * ***************************************************************************/ #include "AirPump.h" #include "AirTrap.h" #include "BloodFlow.h" #include "Bubbles.h" #include "Buttons.h" #include "Common.h" #include "DDInterface.h" #include "LevelSensors.h" #include "Messaging.h" #include "ModePreTreat.h" #include "ModeTreatment.h" #include "OperationModes.h" #include "Pressures.h" #include "RotaryValve.h" #include "StatePreTxDrySelfTests.h" #include "Switches.h" #include "TaskGeneral.h" #include "Timers.h" #include "TDCommon.h" #include "TxParams.h" #include "Utilities.h" #include "Valves.h" #include "Valve3Way.h" /** * @addtogroup StatePreTxDrySelfTests * @{ */ // ********** private definitions ********** // Syringe pump #define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 1 * MS_PER_SECOND ) ///< Delay before checking syringe pump occlusion after prime. // Pressure self-test timing #define PRE_NORMAL_PRESSURE_SELF_TEST_DELAY_MS ( 5 * MS_PER_SECOND ) ///< Delay before capturing baseline arterial and venous pressures. #define STABILTY_PRESSURE_SELF_TEST_TIME ( 5 * MS_PER_SECOND ) ///< Time allowed for pressure stabilization. #define VENOUS_PRESSURE_LEAK_CHECK_TIME ( 4 * MS_PER_SECOND ) ///< Time to monitor venous pressure decay (leak check). #define ARTERIAL_PRESSURE_LEAK_CHECK_TIME ( 4 * MS_PER_SECOND ) ///< Time to monitor arterial pressure decay (leak check). #define CARTRIDGE_INSERT_PRESSURE_SETTLE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Time required for pressure settling after cartridge insertion. //Pressure self-test pump flow #define BLOOD_PUMP_PRESSURE_SELF_TEST_FLOW 100 ///< Blood pump flow rate during arterial pressure self-test (mL/min). // Pressure thresholds #define ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG -200.0F ///< Target arterial pressure threshold during pressure build. #define VENOUS_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Max allowed venous pressure variation during stabilization. #define ARTERIAL_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Max allowed arterial pressure variation during stabilization. #define VENOUS_LEAK_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Max allowed venous pressure difference during leak check. #define ARTERIAL_LEAK_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Max allowed arterial pressure difference during leak check. #define VENOUS_RELIEF_PRESSURE_THRESHOLD_MMHG 20.0F ///< Venous pressure must return within this threshold after relief. #define ARTERIAL_RELIEF_PRESSURE_THRESHOLD_MMHG 20.0F ///< Arterial pressure must return within this threshold after relief. // Pressure self-test timeout values #define ARTERIAL_PRESSURE_SELF_TEST_MAX_TIME ( 30 * MS_PER_SECOND ) ///< Max time allowed to reach arterial pressure target. // General dry self-test timing #define MAX_DRY_SELF_TEST_TIME ( 12 * SEC_PER_MIN ) ///< Maximum total dry self-test duration. #define SELF_TEST_TIME_DATA_PUB_INTERVAL ( 1 * MS_PER_SECOND ) ///< Interval for publishing self-test progress data. /// Payload structure for response to validate from cloud typedef struct { U32 accepted; U32 reason; } TUBE_SET_AUTH_RESULT_PAYLOAD_T; // ********** private data ********** static DRY_SELF_TESTS_STATE_T currentDrySelfTestsState; ///< Current state of Dry Self-Test state machine static U32 selfTestStartTime; ///< Start time of dry self-tests static U32 selfTestPreviousPublishDataTime; ///< Last progress data publish time static U32 selfTestCartridgeSettleTime; ///< Delay after cartridge insertion static U32 syringeOcclusionDelayStartTime; ///< Delay before syringe occlusion check static BOOL selfTestsResumeRequested; ///< Resume requested from STOPPED state static BOOL doorStateAfterCartridgeInstall; ///< Tracks door transition after cartridge install static BOOL useHeparin; ///< Indicates whether heparin is enabled static BOOL barcodeScanResponseReceived; ///< Barcode response received flag static BOOL barcodeScanSuccessful; ///< Barcode scan result static BOOL authResponseReceived; ///< Indicates authentication response received static BOOL authResponseValidTubeSet; ///< Indicates tube set is valid static BOOL authResponseModalityAccepted; ///< Indicates tube set modality is accepted static BOOL dryPressureTestsCompleted; ///< Indicates dry pressure tests completed static BOOL cartridgeUsedTestRun; ///< Indicates cartridge-used test executed static BOOL occlusionBaselineWasSet; ///< Indicates occlusion baseline established static BOOL heparinOcclusionTestRun; ///< Indicates heparin occlusion test executed static F32 previousNormalArterialPressure; ///< Arterial pressure at baseline static F32 previousNormalVenousPressure; ///< Venous pressure at baseline static F32 peakVenousPressure; ///< Peak venous pressure during stabilization static F32 venousPressureP1; ///< First stable venous pressure sample static F32 venousPressureP2; ///< Second venous pressure sample for leak check static F32 peakArterialPressure; ///< Peak arterial pressure during stabilization static F32 arterialPressureP1; ///< First stable arterial pressure sample static F32 arterialPressureP2; ///< Second arterial pressure sample for leak check static BOOL arterialPressureTargetReached; ///< Indicates arterial pressure target reached static U32 pressureSelfTestPreNormalStartTime; ///< Start time for pre-normal pressure setup delay static U32 venousPressureStabilizationStartTime; ///< Start time for venous stabilization static U32 venousPressureLeakCheckStartTime; ///< Start time for venous leak check static U32 venousPressureReliefStartTime; ///< Start time for venous pressure relief static U32 pressureSelfTestBloodPumpRunStartTime; ///< Blood pump run start for pressure self-test static U32 pressureSelfTestNormalizedStartTime; ///< Start time for pressure normalization static U32 pressureSelfTestArterialStartTime; ///< Start time for arterial pressure build-up static U32 arterialPressureStabilizationStartTime; ///< Start time for arterial stabilization static U32 arterialPressureLeakCheckStartTime; ///< Start time for arterial leak check static U32 arterialPressureReliefStartTime; ///< Start time for arterial pressure relief // ********** private function prototypes ********** static void resetSelfTestsFlags( void ); static void setupForSelfTestsStop( void ); static void setAlarmResumePerDoorAndLatch( void ); static void transitionToDrySelfTestsState( DRY_SELF_TESTS_STATE_T newState ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestStartState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestWaitForDoorCloseState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestUsedCartridgeCheckState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestCartridgeLoadedCheckState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestTubeSetAuthenticationState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpSeekState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorNormalSetupState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureSetupState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureStabilizationState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureLeakCheckState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureReliefState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureSetupState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureStabilizationState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureLeakCheckState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureReliefState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpPrimeState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpOcclusionDetectionState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestStoppedState( void ); /*********************************************************************//** * @brief * The initSelfTests function initializes the SelfTests module. * @details \b Inputs: none * @details \b Outputs: SelfTests module initialized. * @return none *************************************************************************/ void initSelfTests( void ) { currentDrySelfTestsState = DRY_SELF_TESTS_START_STATE; selfTestStartTime = 0; selfTestPreviousPublishDataTime = 0; selfTestCartridgeSettleTime = 0; syringeOcclusionDelayStartTime = 0; doorStateAfterCartridgeInstall = TRUE; dryPressureTestsCompleted = FALSE; cartridgeUsedTestRun = FALSE; occlusionBaselineWasSet = FALSE; heparinOcclusionTestRun = FALSE; } /*********************************************************************//** * @brief * The signalResumeSelfTests function signals the self-tests to resume * previous operation. * @details \b Inputs: none * @details \b Outputs: primeResumeRequested * @return none *************************************************************************/ void signalResumeSelfTests( void ) { selfTestsResumeRequested = TRUE; } /*********************************************************************//** * @brief * The resetSelfTestsFlags function resets all self-tests signal flags. * @details \b Inputs: none * @details \b Outputs: signal flags set to FALSE * @return none *************************************************************************/ static void resetSelfTestsFlags( void ) { selfTestsResumeRequested = FALSE; } /*********************************************************************//** * @brief * The setupForSelfTestsStop function sets actuators appropriately for self-tests * states. * @details \b Inputs: dryPressureTestsCompleted, PreTreatmentSubState * @details \b Outputs: All pumps stopped * @return none *************************************************************************/ static void setupForSelfTestsStop( void ) { signalBloodPumpHardStop(); // Air trap control to stopp endAirTrapControl(); // if ( TRUE == isAlarmActive( ALARM_ID_TD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM ) ) // { // retractSyringePump(); // } // else // { // stopSyringePump(); // } // Set valves set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); // Vent pressure only during dry self-test if pressure tests not completed if ( ( TD_PRE_TREATMENT_SELF_TEST_DRY_STATE == getPreTreatmentSubState() ) && ( FALSE == dryPressureTestsCompleted ) ) { setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); } else { setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); } } /*********************************************************************//** * @brief * The setAlarmResumePerDoorAndLatch function enables resume only when * required conditions are satisfied. * @details \b Inputs: Front door switch state * @details \b Outputs: resume alarm enabled/disabled * @return none *************************************************************************/ static void setAlarmResumePerDoorAndLatch( void ) { BOOL doorClosed = FALSE; doorClosed = ( STATE_CLOSED == getSwitchState( H9_SWCH ) ); if ( TRUE == doorClosed ) { setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); } else { setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); } } /*********************************************************************//** * @brief * The transitionToDrySelfTests function resets anything required before * the start of dry self-tests. * @details \b Inputs: front door state * @details \b Outputs: Dry self-tests re-initialized, changed depending * on front door state * @return none *************************************************************************/ void transitionToDrySelfTests( void ) { pressureSelfTestBloodPumpRunStartTime = 0; pressureSelfTestNormalizedStartTime = 0; previousNormalArterialPressure = 0.0F; previousNormalVenousPressure = 0.0F; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); selfTestCartridgeSettleTime = getMSTimerCount(); doorClosedRequired( TRUE ); setCurrentSubState( (U32)currentDrySelfTestsState ); transitionToDrySelfTestsState( currentDrySelfTestsState ); signalBloodPumpHardStop(); // stopSyringePump(); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); if ( STATE_CLOSED == getSwitchState( H9_SWCH ) ) { setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); } else { setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); } resetSelfTestsFlags(); } /*********************************************************************//** * @brief * The execDrySelfTests function executes the dry self-tests state machine. * @details \b Inputs: currentDrySelfTestsState * @details \b Outputs: currentDrySelfTestsState, pressureSelfTestPreNormalStartTime * @return none *************************************************************************/ void execDrySelfTests( void ) { DRY_SELF_TESTS_STATE_T priorSubState = currentDrySelfTestsState; switch ( currentDrySelfTestsState ) { case DRY_SELF_TESTS_START_STATE: currentDrySelfTestsState = handleDrySelfTestStartState(); break; case DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE: currentDrySelfTestsState = handleDrySelfTestWaitForDoorCloseState(); break; case DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE: currentDrySelfTestsState = handleDrySelfTestUsedCartridgeCheckState(); break; case DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE: currentDrySelfTestsState = handleDrySelfTestCartridgeLoadedCheckState(); break; case DRY_SELF_TESTS_TUBE_SET_AUTHENTICATION_STATE: currentDrySelfTestsState = handleDrySelfTestTubeSetAuthenticationState(); break; case DRY_SELF_TESTS_SYRINGE_PUMP_SEEK_STATE: currentDrySelfTestsState = handleDrySelfTestSyringePumpSeekState(); break; case DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE: currentDrySelfTestsState = handleDrySelfTestPressureSensorNormalSetupState(); break; case DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE: currentDrySelfTestsState = handleDrySelfTestVenousPressureSetupState(); break; case DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE: currentDrySelfTestsState = handleDrySelfTestVenousPressureStabilizationState(); break; case DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE: currentDrySelfTestsState = handleDrySelfTestVenousPressureLeakCheckState(); break; case DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE: currentDrySelfTestsState = handleDrySelfTestVenousPressureReliefState(); break; case DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE: currentDrySelfTestsState = handleDrySelfTestArterialPressureSetupState(); break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE: currentDrySelfTestsState = handleDrySelfTestArterialPressureStabilizationState(); break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE: currentDrySelfTestsState = handleDrySelfTestArterialPressureLeakCheckState(); break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE: currentDrySelfTestsState = handleDrySelfTestArterialPressureReliefState(); break; case DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE: currentDrySelfTestsState = handleDrySelfTestSyringePumpPrimeState(); break; case DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_CHECK_STATE: currentDrySelfTestsState = handleDrySelfTestSyringePumpOcclusionDetectionState(); break; case DRY_SELF_TESTS_STOPPED_STATE: currentDrySelfTestsState = handleDrySelfTestStoppedState(); break; case DRY_SELF_TESTS_COMPLETE_STATE: break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_NO_CARTRIDGE_SELF_TEST_STATE, currentDrySelfTestsState ); break; } // Self-tests flags should be handled by now, reset if flags not handled with current state resetSelfTestsFlags(); if ( priorSubState != currentDrySelfTestsState ) { setCurrentSubState( (U32)currentDrySelfTestsState ); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, priorSubState, currentDrySelfTestsState ); } // Publish current self-test time data if ( calcTimeSince( selfTestPreviousPublishDataTime ) >= SELF_TEST_TIME_DATA_PUB_INTERVAL ) { U32 const elapsedSelfTestTimeInSecs = calcTimeSince( selfTestStartTime ) / MS_PER_SECOND; SELF_TEST_DRY_PAYLOAD_T data; selfTestPreviousPublishDataTime = getMSTimerCount(); data.timeout = MAX_DRY_SELF_TEST_TIME; data.countdown = ( elapsedSelfTestTimeInSecs <= MAX_DRY_SELF_TEST_TIME ? ( MAX_DRY_SELF_TEST_TIME - elapsedSelfTestTimeInSecs ) : 0 ); broadcastData( MSG_ID_TD_DRY_SELF_TEST_PROGRESS_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( SELF_TEST_DRY_PAYLOAD_T ) ); } } /*********************************************************************//** * @brief * The getDrySelfTestsState function returns the current state of dry self-tests sub-mode. * @details \b Inputs: currentDrySelfTestsState * @details \b Outputs: none * @return current dry self-tests state *************************************************************************/ U32 getDrySelfTestsState( void ) { return (U32)currentDrySelfTestsState; } /*********************************************************************//** * @brief * The handleDrySelfTestStartState function makes sure door is * closed before starting self-tests. * @details \b Inputs: none * @details \b Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestStartState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_START_STATE; OPN_CLS_STATE_T frontDoorSwitch = getSwitchState( H9_SWCH ); // Want to pinch off saline once door closed after cartridge install handleDoorCloseAfterCartridgeInsertion(); if ( STATE_CLOSED == frontDoorSwitch ) { // Ensure occlusion sensor has time to settle after cartridge insertion before starting dry self-tests if ( TRUE == didTimeout( selfTestCartridgeSettleTime, CARTRIDGE_INSERT_PRESSURE_SETTLE_TIME_MS ) ) { doorClosedRequired( TRUE ); state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; } } if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestWaitForDoorCloseState function makes sure door is * closed before starting self-tests. * @details \b Inputs: none * @details \b Outputs: selfTestStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestWaitForDoorCloseState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; OPN_CLS_STATE_T frontDoorSwitch = getSwitchState( H9_SWCH ); // Restart self-test start time selfTestStartTime = getMSTimerCount(); if ( STATE_CLOSED == frontDoorSwitch ) { state = DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE; } if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } return state; } /*********************************************************************//** * @brief * Verifies that the installed cartridge is unused (dry) by checking * bubble detectors and air trap levels. * @details \b Inputs: none * @details \b Outputs: cartridgeUsedTestRun * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestUsedCartridgeCheckState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE; BUBBLE_STATE_T bubbleStatus = getBubbleDetectedState( H18_BBLD ); AIR_TRAP_LEVELS_T lowerAirTrap = getLevelSensorState( H17_LEVL ); AIR_TRAP_LEVELS_T upperAirTrap = getLevelSensorState( H16_LEVL ); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_DRY_SELF_TEST_CARTRIDGE_RESULT, (U32)bubbleStatus, (U32)BUBBLE_DETECTED ); // Check if cartridge is dry if ( ( BUBBLE_DETECTED == bubbleStatus ) && ( AIR_TRAP_LEVEL_AIR == lowerAirTrap ) && ( AIR_TRAP_LEVEL_AIR == upperAirTrap ) ) { // If catridge is valid proceed resetArtVenPressureOffsets(); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_TUBING_SET_BARCODE_SCAN_REQUEST, 0, 0 ); state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; } else { // Allow wet cartridge only for test configuration if ( TRUE == getTestConfigStatus( TEST_CONFIG_USE_WET_CARTRIDGE ) ) { SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_TUBING_SET_BARCODE_SCAN_REQUEST, 0, 0 ); cartridgeUsedTestRun = TRUE; state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; } else { // If cartridge is invalid it triggers an alarm activateAlarmNoData( ALARM_ID_TD_INSTALL_NEW_BLOOD_TUBING_SET ); } } if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } return state; } /*********************************************************************//** * @brief * Verifies that a cartridge is installed and barcode scan is successful. * @details \b Inputs: barcode scan status * @details \b Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestCartridgeLoadedCheckState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; if ( TRUE == barcodeScanResponseReceived ) { barcodeScanResponseReceived = FALSE; if ( TRUE == barcodeScanSuccessful ) { // If barcode is athuenticated move to next state SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_TUBING_SET_BARCODE_SCAN_AUTHENTICATED, 0, 0 ); state = DRY_SELF_TESTS_TUBE_SET_AUTHENTICATION_STATE; } else { // If barcode authentication is failed trigger an alarm activateAlarmNoData( ALARM_ID_TD_INSTALL_NEW_CARTRIDGE ); } } if ( TRUE == doesAlarmStatusIndicateStop() ) { if ( TRUE == isAlarmActive( ALARM_ID_TD_NO_CARTRIDGE_LOADED ) ) { occlusionBaselineWasSet = FALSE; } state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestTubeSetAuthenticationState function handles tube set * authentication and processes the authentication response. * @details \b Message \b Received: MSG_ID_UI_TUBE_SET_AUTHENTICATION_RESPONSE * @details \b Message \b Sent: MSG_ID_TD_TUBE_SET_AUTHENTICATION_RESPONSE * @details \b Inputs: authResponseReceived, authResponseValidTubeSet, * authResponseModalityAccepted * @details \b Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestTubeSetAuthenticationState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_TUBE_SET_AUTHENTICATION_STATE; TUBE_SET_AUTH_RESULT_PAYLOAD_T payload; // Initialize the payload memset( (U08*)&payload, 0, sizeof(payload) ); if ( TRUE == authResponseReceived ) { authResponseReceived = FALSE; if ( ( TRUE == authResponseValidTubeSet ) && ( TRUE == authResponseModalityAccepted ) ) { // Checking validity and modality match payload.accepted = TRUE; payload.reason = REQUEST_REJECT_REASON_NONE; state = DRY_SELF_TESTS_SYRINGE_PUMP_SEEK_STATE; } else { payload.accepted = FALSE; if ( FALSE == authResponseValidTubeSet ) { // If invalid tube set occurs trigger an alarm payload.reason = REQUEST_REJECT_REASON_TD_AUTHENTICATION_INVALID; activateAlarmNoData( ALARM_ID_TD_INVALID_TUBE_SET ); } else { // Modality mismatch payload.reason = REQUEST_REJECT_REASON_TD_AUTHENTICATION_MODALITY_MISMATCH; } } // Send response to UI sendMessage( MSG_ID_TD_TUBE_SET_AUTHENTICATION_RESPONSE, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&payload, sizeof(payload) ); } if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestSyringePumpSeekState function handles the syringe * pump seek dry self-test state. * @details \b Inputs: useHeparin * @details \b Outputs: pressureSelfTestPreNormalStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpSeekState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_SYRINGE_PUMP_SEEK_STATE; // BOOL done = FALSE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } // else // { // using Heparin? // if ( TRUE == useHeparin ) // { // syringe pump is not busy? // if ( FALSE == isSyringePumpRunning() ) // { // seek completed? // if ( TRUE == isSyringePlungerFound() ) // { // move on when seek completed // done = TRUE; // } // else // { // pre-load completed? // if ( TRUE == isSyringePumpPreLoaded() ) // { // initiate seek plunger operation // seekSyringePlunger(); // } // else // { // pre-load syringe // preloadSyringePlunger(); // } // } // } // } // else // { // not using Heparin, so move on // done = TRUE; // } // } // } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestPressureSensorNormalSetupState function handles the setup * for pressure sensors dry self-test. * @details \b Inputs: pressureSelfTestPreNormalStartTime * @details \b Outputs: previousNormalArterialPressure, previousNormalVenousPressure * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorNormalSetupState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else { // wait for pressure to equalize w/ atmosphere and tare arterial and venous pressures if ( TRUE == didTimeout( pressureSelfTestPreNormalStartTime, PRE_NORMAL_PRESSURE_SELF_TEST_DELAY_MS ) ) { setArtVenPressureOffsets(); state = DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestVenousPressureSetupState function handles the setup * for the venous pressure sensor dry self-test. * @details \b Inputs: none * @details \b Outputs: venousPressureStabilizationStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureSetupState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else { // Log start of venous pressure test SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_DRY_SELF_TEST_PRESSURE_RESULT, (U32)DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE, 0 ); venousPressureStabilizationStartTime = getMSTimerCount(); peakVenousPressure = getFilteredVenousPressure(); state = DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE; } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestVenousPressureStabilizationState function handles * venous pressure stabilization check. * @details \b Inputs: venousPressureStabilizationStartTime, peakVenousPressure * @details \b Outputs: venousPressureP1 * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureStabilizationState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else if ( TRUE == didTimeout( venousPressureStabilizationStartTime, STABILTY_PRESSURE_SELF_TEST_TIME ) ) { F32 current = getFilteredVenousPressure(); F32 diff = fabs( peakVenousPressure - current ); if ( diff < VENOUS_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG ) { venousPressureP1 = current; venousPressureLeakCheckStartTime = getMSTimerCount(); state = DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE; } else { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, diff, VENOUS_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG ); state = DRY_SELF_TESTS_STOPPED_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestVenousPressureLeakCheckState function handles * venous pressure leak check. * @details \b Inputs: venousPressureLeakCheckStartTime, venousPressureP1 * @details \b Outputs: venousPressureP2 * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureLeakCheckState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else if ( TRUE == didTimeout( venousPressureLeakCheckStartTime, VENOUS_PRESSURE_LEAK_CHECK_TIME ) ) { venousPressureP2 = getFilteredVenousPressure(); F32 diff = fabs( venousPressureP1 - venousPressureP2 ); if ( diff <= VENOUS_LEAK_PRESSURE_DIFF_TOLERANCE_MMHG ) { venousPressureReliefStartTime = getMSTimerCount(); state = DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE; } else { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, diff, VENOUS_LEAK_PRESSURE_DIFF_TOLERANCE_MMHG ); state = DRY_SELF_TESTS_STOPPED_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestVenousPressureReliefState function handles * venous pressure relief state. * @details \b Inputs: venousPressureReliefStartTime * @details \b Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureReliefState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else if ( TRUE == didTimeout( venousPressureReliefStartTime, STABILTY_PRESSURE_SELF_TEST_TIME ) ) { F32 current = getFilteredVenousPressure(); if ( current <= VENOUS_RELIEF_PRESSURE_THRESHOLD_MMHG ) { state = DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE; } else { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, current ); state = DRY_SELF_TESTS_STOPPED_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestPressureArterialSetupState function handles the setup * for the arterial pressure sensor dry self-test. * @details \b Inputs: none * @details \b Outputs: pressureSelfTestArterialStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureSetupState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else { // Log start of arterial pressure test SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_DRY_SELF_TEST_PRESSURE_RESULT, (U32)DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE, 0 ); pressureSelfTestArterialStartTime = getMSTimerCount(); arterialPressureTargetReached = FALSE; state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE; } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestArterialPressureStabilizationState function monitors * arterial pressure, verifies target pressure is reached, and records P1 * after stabilization. * @details \b Inputs: pressureSelfTestArterialStartTime, * arterialPressureStabilizationStartTime * @details \b Outputs: peakArterialPressure, arterialPressureP1, * arterialPressureLeakCheckStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureStabilizationState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE; F32 arterialPressure = getFilteredArterialPressure(); if ( TRUE == doesAlarmStatusIndicateStop() ) { arterialPressureTargetReached = FALSE; state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else { // Once reached to target if ( FALSE == arterialPressureTargetReached ) { if ( arterialPressure <= ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG ) { peakArterialPressure = arterialPressure; arterialPressureStabilizationStartTime = getMSTimerCount(); arterialPressureTargetReached = TRUE; } if ( TRUE == didTimeout( pressureSelfTestArterialStartTime, ARTERIAL_PRESSURE_SELF_TEST_MAX_TIME ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, arterialPressure, ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG ); state = DRY_SELF_TESTS_STOPPED_STATE; } } // Stability Check P1 else { if ( TRUE == didTimeout( arterialPressureStabilizationStartTime, STABILTY_PRESSURE_SELF_TEST_TIME ) ) { F32 diff = fabs( peakArterialPressure - arterialPressure ); if ( diff < ARTERIAL_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG ) { arterialPressureP1 = arterialPressure; arterialPressureLeakCheckStartTime = getMSTimerCount(); arterialPressureTargetReached = FALSE; state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE; } else { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, diff, ARTERIAL_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG ); arterialPressureTargetReached = FALSE; state = DRY_SELF_TESTS_STOPPED_STATE; } } } } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestArterialPressureLeakCheckState function verifies * arterial pressure leak by comparing P1 and P2. * @details \b Inputs: arterialPressureLeakCheckStartTime, arterialPressureP1 * @details \b Outputs: arterialPressureP2 * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureLeakCheckState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else if ( TRUE == didTimeout( arterialPressureLeakCheckStartTime, ARTERIAL_PRESSURE_LEAK_CHECK_TIME ) ) { arterialPressureP2 = getFilteredArterialPressure(); F32 diff = fabs( arterialPressureP1 - arterialPressureP2 ); if ( diff <= ARTERIAL_LEAK_PRESSURE_DIFF_TOLERANCE_MMHG ) { arterialPressureReliefStartTime = getMSTimerCount(); state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE; } else { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, diff, ARTERIAL_LEAK_PRESSURE_DIFF_TOLERANCE_MMHG ); state = DRY_SELF_TESTS_STOPPED_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestArterialPressureReliefState function relieves * arterial pressure and verifies return to baseline. * @details \b Inputs: arterialPressureReliefStartTime * @details \b Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureReliefState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else if ( TRUE == didTimeout( arterialPressureReliefStartTime, STABILTY_PRESSURE_SELF_TEST_TIME ) ) { F32 pressure = getFilteredArterialPressure(); if ( fabs( pressure ) <= ARTERIAL_RELIEF_PRESSURE_THRESHOLD_MMHG ) { state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; } else { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, pressure ); state = DRY_SELF_TESTS_STOPPED_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestSyringePumpPrimeState function handles the prime * operation for syringe pump. * @details \b Inputs: none * @details \b Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpPrimeState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; if ( TRUE == useHeparin ) { // if ( FALSE == isSyringePumpRunning() ) // { // if ( TRUE == isSyringePlungerFound() ) // { // if ( TRUE == isSyringePumpPrimed() ) // { // state = DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE; // syringeOcclusionDelayStartTime = getMSTimerCount(); // Get the current time to check for occlusion after 3 seconds has elapsed // } // else // { // primeSyringePump(); // } // } // else // { // if ( TRUE == isSyringePumpPreLoaded() ) // { // seekSyringePlunger(); // } // else // { // preloadSyringePlunger(); // } // } // } } else { state = DRY_SELF_TESTS_COMPLETE_STATE; } if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestSyringePumpOcclusionDetectionState function handles * occlusion detection after prime has completed. * @details \b Inputs: syringeOcclusionDelayStartTime * @details \b Outputs: heparinOcclusionTestRun * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpOcclusionDetectionState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_CHECK_STATE; if ( TRUE == didTimeout( syringeOcclusionDelayStartTime, SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ) ) { // if ( FALSE == checkForSyringeOcclusion( FALSE ) ) // transition to complete state only when occlusion is removed // { // state = DRY_SELF_TESTS_COMPLETE_STATE; // } heparinOcclusionTestRun = TRUE; } if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestStoppedState function handles the stopped dry self-tests * operation. * @details \b Inputs: selfTestsResumeRequested, occlusionBaselineWasSet, * dryPressureTestsCompleted, cartridgeUsedTestRun, heparinOcclusionTestRun * @details \b Outputs: selfTestsResumeRequested, selfTestStartTime, selfTestCartridgeSettleTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestStoppedState( void ) { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_STOPPED_STATE; setAlarmResumePerDoorAndLatch(); doorClosedRequired( FALSE ); // if not enough heparin alarm, pre-load pusher after retract completes if ( TRUE == isAlarmActive( ALARM_ID_TD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM ) ) { // prevent resume until syringe is retracted and pre-loaded setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); // if ( TRUE != isSyringePumpRunning() ) // { // if ( TRUE == isSyringePumpHome() ) // { // preloadSyringePlunger(); // } // else if ( TRUE == isSyringePumpPreLoaded() ) // { // setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); // } // } } // if heparin occlusin alarm, keep calling check function so alarm condition will clear when resolved if ( TRUE == isAlarmActive( ALARM_ID_TD_SYRINGE_PUMP_OCCLUSION ) ) // { // checkForSyringeOcclusion( FALSE ); // } // depressurized the line from failed pressure self tests. if ( FALSE == dryPressureTestsCompleted ) { if ( getFilteredVenousPressure() <= VENOUS_LEAK_PRESSURE_DIFF_TOLERANCE_MMHG ) { setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); endAirTrapControl(); } } // if resume request, resume dry self-tests if ( TRUE == selfTestsResumeRequested ) { // Restart self-test start time selfTestsResumeRequested = FALSE; selfTestStartTime = getMSTimerCount(); selfTestCartridgeSettleTime = getMSTimerCount(); doorClosedRequired( TRUE ); if ( TRUE == heparinOcclusionTestRun ) { state = DRY_SELF_TESTS_COMPLETE_STATE; } else if ( TRUE == dryPressureTestsCompleted ) { state = ALARM_ID_TD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM; } else { setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); if ( TRUE == cartridgeUsedTestRun ) { resetArtVenPressureOffsets(); state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; } else if ( TRUE != occlusionBaselineWasSet ) { selfTestCartridgeSettleTime = getMSTimerCount(); state = DRY_SELF_TESTS_START_STATE; } else { state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; } } } return state; } /*********************************************************************//** * @brief * The transitionToDrySelfTestsState function handles the transition to * dry self-test states by setting actuators. * @details \b Inputs: none * @details \b Outputs: none * @param newState the targeted dry self-test state * @return none *************************************************************************/ static void transitionToDrySelfTestsState( DRY_SELF_TESTS_STATE_T newState ) { switch ( newState ) { case DRY_SELF_TESTS_START_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_TUBE_SET_AUTHENTICATION_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_SYRINGE_PUMP_SEEK_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); startAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); setBloodPumpTargetFlowRate( BLOOD_PUMP_PRESSURE_SELF_TEST_FLOW, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_CHECK_STATE: { U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); signalBloodPumpHardStop(); setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); endAirTrapControl(); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_COMPLETE_STATE: signalBloodPumpHardStop(); endAirTrapControl(); cmdChangeQuf( 0.0F ); break; case DRY_SELF_TESTS_STOPPED_STATE: setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setAlarmResumePerDoorAndLatch(); doorClosedRequired( FALSE ); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_DRY_SELF_TEST_STATE, (U32)newState ); break; } } /*********************************************************************//** * @brief * The handleDoorCloseAfterCartridgeInsertion function handles the check * for door close after cartridge install so that saline line can be pinched. * @details Inputs: door states * @details Outputs: doorStateAfterCartridgeInstall * @return none *************************************************************************/ void handleDoorCloseAfterCartridgeInsertion( void ) { OPN_CLS_STATE_T frontDoorSwitch = getSwitchState( H9_SWCH ); if ( STATE_OPEN == frontDoorSwitch ) { doorStateAfterCartridgeInstall = FALSE; } if ( ( STATE_CLOSED == frontDoorSwitch ) && ( FALSE == doorStateAfterCartridgeInstall ) ) { setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); doorStateAfterCartridgeInstall = TRUE; } } /**@}*/