/************************************************************************** * * 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 SelfTests.h * * @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 "BloodFlow.h" #include "Bubbles.h" #include "DDInterface.h" #include "FPGA.h" #include "TxParams.h" #include "Pressures.h" #include "StatePreTxDrySelfTests.h" #include "Switches.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" /** * @addtogroup SelfTests * @{ */ // ********** 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 pressureSelfTestPreNormalStartTime; ///< Pressure dry self-test pre-normal start time. static U32 selfTestStartTime; ///< Timestamp when self-tests started static U32 selfTestPreviousPublishDataTime; ///< Last time progress data was published static U32 selfTestCartridgeSettleTime; ///< Delay timer after cartridge insertion static U32 syringeOcclusionDelayStartTime; ///< Delay before checking syringe occlusion static BOOL selfTestsResumeRequested; ///< Indicates resume request from STOPPED state static BOOL doorStateAfterCartridgeInstall; ///< Tracks door transition post cartridge insertion static BOOL dryPressureTestsCompleted; ///< Indicates pressure tests completion static BOOL cartridgeUsedTestRun; ///< Indicates cartridge-used check executed static BOOL occlusionBaselineWasSet; ///< Indicates baseline pressure established static BOOL heparinOcclusionTestRun; ///< Indicates heparin occlusion test executed static BOOL authResponseReceived; ///< Authentication response received from external subsystem static BOOL authResponseValidTubeSet; ///< Indicates whether tube set is valid static BOOL authResponseModalityAccepted; ///< Indicates whether tube set matches selected treatment modality static BOOL requestInstallMode; ///< Triggers transition to INSTALL mode when authentication fails static BOOL useHeparin; ///< Indicates whether heparin functionality is enabled for current treatment 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 whether arterial pressure target has been reached static U32 venousPressureStabilizationStartTime; // Start time for venous stabilization phase 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 test static U32 pressureSelfTestNormalizedStartTime; // Time when pressures normalized 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 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 handleDrySelfTestSyringePumpSeekState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalSetupState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsVenousSetupState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsVenousState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsArterialSetupState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsArterialState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsDecayState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsStabilityState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalState( 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 ); static void transitionToDrySelfTestsState( DRY_SELF_TESTS_STATE_T newState ); /*********************************************************************//** * @brief * The initSelfTests function initializes the SelfTests module. * @details Inputs: none * @details Outputs: SelfTests module initialized. * @return none *************************************************************************/ void initSelfTests( void ) { selfTestStartTime = 0; selfTestPreviousPublishDataTime = 0; syringeOcclusionDelayStartTime = 0; doorStateAfterCartridgeInstall = TRUE; } /*********************************************************************//** * @brief * The signalResumeSelfTests function signals the self-tests to resume * previous operation. * @details Inputs: none * @details Outputs: primeResumeRequested * @return none *************************************************************************/ void signalResumeSelfTests( void ) { selfTestsResumeRequested = TRUE; } /*********************************************************************//** * @brief * The resetSelfTestsFlags function resets all self-tests signal flags. * @details Inputs: none * @details 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 Inputs: dryPressureTestsCompleted, PreTreatmentSubState * @details Outputs: All pumps stopped * @return none *************************************************************************/ static void setupForSelfTestsStop( void ) { signalBloodPumpHardStop(); // if ( TRUE == isAlarmActive( ALARM_ID_TD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM ) ) // { // retractSyringePump(); // } // else // { // stopSyringePump(); // } setValvePosition( H13_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H20_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); // If the TD has finished no cart s.t. but not dry pressure tests, Open to vent pressure // to prevent air going to the Saline bag. if ( ( TD_PRE_TREATMENT_SELF_TEST_DRY_STATE == getPreTreatmentSubState() ) && ( FALSE == dryPressureTestsCompleted ) ) { setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValveAirTrap( STATE_OPEN ); } else { setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); setValveAirTrap( STATE_CLOSED ); } } /*********************************************************************//** * @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 Inputs: front door state * @details Outputs: Dry self-tests re-initialized, changed depending * on front door state * @return none *************************************************************************/ void transitionToDrySelfTests( void ) { // State Reset currentDrySelfTestsState = DRY_SELF_TESTS_START_STATE; pressureSelfTestBloodPumpRunStartTime = 0; pressureSelfTestNormalizedStartTime = 0; previousNormalArterialPressure = 0.0F; previousNormalVenousPressure = 0.0F; dryPressureTestsCompleted = FALSE; cartridgeUsedTestRun = FALSE; occlusionBaselineWasSet = FALSE; heparinOcclusionTestRun = FALSE; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); selfTestCartridgeSettleTime = getMSTimerCount(); doorClosedRequired( TRUE ); setCurrentSubState( (U32)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 Inputs: currentDrySelfTestsState * @details 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 = handleDrySelfTestPressureVenousSetupState(); 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 = handleDrySelfTestPressureArterialSetupState(); 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_PRIME_STATE: currentDrySelfTestsState = handleDrySelfTestSyringePumpPrimeState(); break; case DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_CHECK_STATE: currentDrySelfTestsState = handleDrySelfTestSyringePumpOcclusionCheckState(); break; case DRY_SELF_TESTS_COMPLETE_STATE: currentDrySelfTestsState = handleDrySelfTestCompleteState(); break; case DRY_SELF_TESTS_STOPPED_STATE: currentDrySelfTestsState = handleDrySelfTestStoppedState(); 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_NO_CART_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 Inputs: currentDrySelfTestsState * @details 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 it proceed resetArtVenPressureOffsets(); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_REQUEST_BARCODE_SCAN ); 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_REQUEST_BARCODE_SCAN ); 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; BOOL barcodeScanComplete = isBarcodeScanComplete(); BOOL barcodeScanSuccess = didBarcodeScanSucceed(); if ( TRUE == barcodeScanComplete ) { if ( TRUE == barcodeScanSuccess ) { // If Barcode is valid proceed to authentication SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_BARCODE_SCAN_SUCCESS ); state = DRY_SELF_TESTS_TUBE_SET_AUTHENTICATION_STATE; } else { // If barcode is valid it trigger an alarm activateAlarmNoData( ALARM_ID_TD_INSTALL_NEW_CARTRIDGE ); } } if ( TRUE == doesAlarmStatusIndicateStop() ) { if ( TRUE == isAlarmActive( ALARM_ID_TD_NO_CARTRIDGE_LOADED ) ) { // Reset baseline after reinstall 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 Sent: MSG_ID_TD_TUBE_SET_AUTH_RESULT * @details Inputs: authResponseReceived, authResponseValidTubeSet, * authResponseModalityAccepted * @details 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; BOOL authInvalid = TRUE; BOOL tubeSetIsValid = FALSE; BOOL modalityIsValid = FALSE; TUBE_SET_AUTH_RESULT_PAYLOAD_T payload; //Initialize Payload memset( (U08*)&payload, 0, sizeof( TUBE_SET_AUTH_RESULT_PAYLOAD_T ) ); // Check Response if ( TRUE == authResponseReceived ) { authResponseReceived = FALSE; tubeSetIsValid = authResponseValidTubeSet; modalityIsValid = authResponseModalityAccepted; / if ( TRUE == tubeSetIsValid ) { if ( TRUE == modalityIsValid ) { authInvalid = FALSE; } } // Result Handling if ( FALSE == authInvalid ) { // Valid + modality match payload.accepted = (U32)TRUE; payload.reason = (U32)AUTH_REASON_NONE; // requestSyringeSeek(); state = DRY_SELF_TESTS_SYRINGE_PUMP_SEEK_STATE; } else { payload.accepted = (U32)FALSE; if ( FALSE == tubeSetIsValid ) { // Invalid tube set activateAlarmNoData( ALARM_ID_TD_INVALID_TUBE_SET ); payload.reason = (U32)AUTH_REASON_INVALID; } else { // Modality mismatch payload.reason = (U32)AUTH_REASON_MODALITY_MISMATCH; } requestInstallMode = TRUE; } sendMessage( MSG_ID_TD_TUBE_SET_AUTHENTICATION_RESPONSE, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&payload, sizeof( TUBE_SET_AUTH_RESULT_PAYLOAD_T ) ); } 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 Inputs: useHeparin * @details 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 handleDrySelfTestPressureSensorsSetupState function handles the setup * for pressure sensors dry self-test. * @details Inputs: pressureSelfTestPreNormalStartTime * @details 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 handleDrySelfTestPressureVenousSetupState function handles the setup * for the venous pressure sensor dry self-test. * @details Inputs: none * @details Outputs: pressureSelfTestVenousTestStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureVenousSetupState( 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 { venousPressureStabilizationStartTime = getMSTimerCount(); peakVenousPressure = getFilteredVenousPressure(); state = DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE; } return state; } /*********************************************************************//** * @brief * The handleDrySelfTestVenousPressureStabilizationState function handles * venous pressure stabilization check. * @details Inputs: venousPressureStabilizationStartTime, peakVenousPressure * @details 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 Inputs: venousPressureLeakCheckStartTime, venousPressureP1 * @details 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 Inputs: venousPressureReliefStartTime * @details 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 Inputs: none * @details Outputs: pressureSelfTestArterialStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureArterialSetupState( 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 { 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 Inputs: pressureSelfTestArterialStartTime, * arterialPressureStabilizationStartTime * @details 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 Inputs: arterialPressureLeakCheckStartTime, arterialPressureP1 * @details 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 Inputs: arterialPressureReliefStartTime * @details 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_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 Inputs: none * @details 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_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 Inputs: syringeOcclusionDelayStartTime * @details 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 Inputs: selfTestsResumeRequested, occlusionBaselineWasSet, * dryPressureTestsCompleted, cartridgeUsedTestRun, heparinOcclusionTestRun * @details 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; if ( TRUE == isAlarmActive( ALARM_ID_TD_SYRINGE_PUMP_OCCLUSION ) ) { checkForSyringeOcclusion( FALSE ); } if ( TRUE == selfTestsResumeRequested ) { selfTestsResumeRequested = FALSE; selfTestStartTime = getMSTimerCount(); selfTestCartridgeSettleTime = getMSTimerCount(); if ( TRUE == heparinOcclusionTestRun ) { state = DRY_SELF_TESTS_COMPLETE_STATE; } else if ( TRUE == dryPressureTestsCompleted ) { state = DRY_SELF_TESTS_SYRINGE_PRIME_STATE; } else if ( TRUE == cartridgeUsedTestRun ) { state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; } else if ( FALSE == occlusionBaselineWasSet ) { 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 Inputs: none * @details 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 = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_TUBE_SET_AUTHENTICATION_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_SYRINGE_PUMP_SEEK_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_SYRINGE_PRIME_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); cmdBypassDialyzer( TRUE ); cmdChangeQd( targetDialysateFlowMLPM ); cmdChangeQuf( 0.0F ); } break; case DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_CHECK_STATE: { U32 targetDialysateFlowMLPM = 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 ); retractEjector(); 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_INVALID_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; } } /**@}*/