Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r727f30438c094ec62abe1fad1f5a8962cd304a4d -rcd5be724d5a3ba7457e761191d82f278654d7f5c --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 727f30438c094ec62abe1fad1f5a8962cd304a4d) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision cd5be724d5a3ba7457e761191d82f278654d7f5c) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2021-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2024 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.c * -* @author (last) Sean Nash -* @date (last) 19-Jul-2023 +* @author (last) Bill Bracken +* @date (last) 18-Oct-2023 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -43,18 +43,17 @@ #define PUMP_RUN_SELF_TEST_TIME_MS ( 15 * MS_PER_SECOND ) ///< Self-test time to run pumps in ms. #define PUMP_SELF_TEST_FLOW_RATE_ML_MIN 100 ///< Self-test pump flow rate in mL/min. -#define BLOOD_PUMP_PRESSURE_SELF_TEST_FLOW 100 -#define DIAL_IN_PUMP_PRESSURE_SELF_TEST_FLOW 400 +#define BLOOD_PUMP_PRESSURE_SELF_TEST_FLOW 100 ///< Pressure self-test BP flow rate in mL/min. +#define DIAL_IN_PUMP_PRESSURE_SELF_TEST_FLOW 400 ///< Pressure self-test DPi flow rate in mL/min. #define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 1 * MS_PER_SECOND ) ///< Delay 1 second then check for syringe pump prime occlusion. -#define PRE_NORMAL_PRESSURE_SELF_TEST_DELAY_MS ( 1 * MS_PER_SECOND ) ///< Delay 1 second prior to getting initial normal baseline pressures. +#define PRE_NORMAL_PRESSURE_SELF_TEST_DELAY_MS ( 5 * MS_PER_SECOND ) ///< Delay 5 second prior to getting initial normal baseline pressures. #define BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ( 30 * MS_PER_SECOND ) ///< Pressure self-test time to run blood pump in ms. #define VENOUS_PRESSURE_SELF_TEST_MAX_TEST_TIME ( 60 * MS_PER_SECOND ) ///< Pressure self-test time to run venous self test in ms. #define DECAY_PRESSURE_SELF_TEST_TIME ( 4 * MS_PER_SECOND ) ///< time to wait for pressure to decay in ms. #define STABILTY_PRESSURE_SELF_TEST_TIME ( 5 * MS_PER_SECOND ) ///< Time to wait for pressure to stabilize in ms. #define NORMALIZED_PRESSURE_SELF_TEST_TIME ( 20 * MS_PER_SECOND ) ///< Time to wait for pressure to normalize in ms. #define NORMALIZED_PRESSURE_SELF_TEST_VBT_TIMER ( 1 * MS_PER_SECOND ) ///< Time to wait until we open VBT during normal pressure tests. -#define NORMALIZED_PRESSURE_SELF_TEST_VBT_TIMERX ( 7 * MS_PER_SECOND ) ///< Time to wait until we open VBT during normal pressure tests (for old builds that don't support air pump). #define NORMALIZED_PRESSURE_SELF_TEST_VDI_TIMER ( 5 * MS_PER_SECOND ) ///< Time to wait until we open VDI during normal pressure tests. #define ARTERIAL_DECAY_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Difference in arterial pressure readings after the pump stops (in mmHg). @@ -88,9 +87,6 @@ #define SELF_TEST_TIME_DATA_PUB_INTERVAL ( MS_PER_SECOND ) ///< Interval (ms/task time) at which self-test time data is published on the CAN bus. -#define PRESSURE_CHECK_START_PRESSURE_TOLERANCE_MMHG 10.0F ///< Prior to dry pressure leak test, arterial and venous pressure sensors should read zero +/- this tolerance. -#define MAX_EMPTY_RESERVOIR_WEIGHT_G 15.0F ///< Maximum reservoir weight to be considered empty for cartridge pressure leak test. - #define BLOOD_LEAK_DETECTOR_DEBUBBLE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Blood leak detector debubble timeout in milliseconds. // ********** private data ********** @@ -117,6 +113,7 @@ static BOOL wetSelfTestsResult; ///< Result of wet self-tests. static WET_SELF_TESTS_STATE_T currentWetSelfTestsState; ///< Current state of the wet self-tests state machine. +static WET_SELF_TESTS_STATE_T checkpointWetSelfTestsState; ///< Checkpoint state of the wet self tests state machine. static U32 settleStartTime; ///< Wait for reservoir to settle start time. static U32 displacementStartTime; ///< Dialysate displacement starting time. static F32 fmdIntegratedVolume; ///< FMD integrated volume over displacement time. @@ -130,6 +127,7 @@ static U32 bloodLeakDebubbleStartTimeMS; ///< Blood leak detector debubble start time in milliseconds. static BOOL useHeparin; ///< Flag indicates the user of heparin. +static BOOL heparinOcclusionTestRun; ///< Flag indicates whether the heparin occlusion test has been run. static BOOL selfTestsResumeRequested; ///< Flag indicates user requesting self-tests resume. static BOOL cartridgeUsedTestRun; ///< Flag indicates whether the used cartridge test has been run. static BOOL occlusionBaselineWasSet; ///< Flag indicates whether the blood pump occlusion baseline for installed cartridge has been set. @@ -152,6 +150,7 @@ 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 ); @@ -222,7 +221,7 @@ * @brief * The setupForSelfTestsStop function sets actuators appropriately for self-tests * states. - * @details Inputs: none + * @details Inputs: dryPressureTestsCompleted, PreTreatmentSubState * @details Outputs: All pumps stopped * @return none *************************************************************************/ @@ -244,9 +243,21 @@ setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( VDO, VALVE_POSITION_A_INSERT_EJECT ); - setValvePosition( VBA, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( VBV, VALVE_POSITION_A_INSERT_EJECT ); - setValveAirTrap( STATE_CLOSED ); + + // If the HD has finished no cart s.t. but not dry pressure tests, Open VBT to vent pressure + // to prevent air going to the Saline bag. + if ( ( HD_PRE_TREATMENT_SELF_TEST_DRY_STATE == getPreTreatmentSubState() ) && ( FALSE == dryPressureTestsCompleted ) ) + { + setValvePosition( VBA, VALVE_POSITION_B_OPEN ); + setValveAirTrap( STATE_OPEN ); + } + + else + { + setValvePosition( VBA, VALVE_POSITION_A_INSERT_EJECT ); + setValveAirTrap( STATE_CLOSED ); + } } /*********************************************************************//** @@ -428,6 +439,7 @@ dryPressureTestsCompleted = FALSE; cartridgeUsedTestRun = FALSE; occlusionBaselineWasSet = FALSE; + heparinOcclusionTestRun = FALSE; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); selfTestCartridgeSettleTime = getMSTimerCount(); @@ -486,6 +498,10 @@ currentDrySelfTestsState = handleDrySelfTestCartridgeLoadedCheckState(); break; + case DRY_SELF_TESTS_SYRINGE_PUMP_SEEK_STATE: + currentDrySelfTestsState = handleDrySelfTestSyringePumpSeekState(); + break; + case DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_SETUP_STATE: currentDrySelfTestsState = handleDrySelfTestPressureSensorsNormalSetupState(); break; @@ -584,6 +600,7 @@ { wetSelfTestsResult = FALSE; currentWetSelfTestsState = WET_SELF_TESTS_START_STATE; + checkpointWetSelfTestsState = WET_SELF_TESTS_START_STATE; settleStartTime = 0; displacementStartTime = 0; fmdIntegratedVolume = 0.0; @@ -605,6 +622,8 @@ setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); + setCurrent4thLevelState( currentWetSelfTestsState ); + resetSelfTestsFlags(); } @@ -966,14 +985,11 @@ state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; } } - else + + if ( TRUE == doesAlarmStatusIndicateStop() ) { - // doorClosedRequired() will trigger alarms if pumpTrack is open - if ( TRUE == doesAlarmStatusIndicateStop() ) - { - state = DRY_SELF_TESTS_STOPPED_STATE; - setupForSelfTestsStop(); - } + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); } return state; @@ -1065,29 +1081,16 @@ * The handleDrySelfTestCartridgeLoadedCheckState function verifies a cartridge * is installed by checking sufficient pressure at OB sensor. * @details Inputs: none - * @details Outputs: dryPressureTestsCompleted + * @details Outputs: occlusionBaselineWasSet * @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_USED_CARTRIDGE_CHECK_STATE; + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; if ( SELF_TEST_STATUS_PASSED == execPresOcclDryTest() ) { - setArtVenPressureOffsets(); - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); - setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - setValvePosition( VBA, VALVE_POSITION_B_OPEN ); // need open path from PBA to VBT - setValvePosition( VBV, VALVE_POSITION_A_INSERT_EJECT ); // need open path from PBA to VBT - setValveAirTrap( STATE_OPEN ); - pressureSelfTestPreNormalStartTime = getMSTimerCount(); - state = DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_SETUP_STATE; - - if ( TRUE == getTestConfigStatus( TEST_CONFIG_USE_WET_CARTRIDGE ) ) - { - dryPressureTestsCompleted = TRUE; - state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; - } + state = DRY_SELF_TESTS_SYRINGE_PUMP_SEEK_STATE; } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1105,6 +1108,74 @@ /*********************************************************************//** * @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; + } + } + + // setup for pressure tests when done + if ( TRUE == done ) + { + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); + setValvePosition( VBA, VALVE_POSITION_B_OPEN ); // need open path from PBA to VBT + setValvePosition( VBV, VALVE_POSITION_A_INSERT_EJECT ); // need open path from PBA to VBT + setValveAirTrap( STATE_OPEN ); + pressureSelfTestPreNormalStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_SETUP_STATE; + + if ( TRUE == getTestConfigStatus( TEST_CONFIG_USE_WET_CARTRIDGE ) ) + { // skip pressure tests if using wet cartridge + dryPressureTestsCompleted = TRUE; + state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleDrySelfTestPressureSensorsSetupState function handles the setup * for pressure sensors dry self-test. * @details Inputs: pressureSelfTestPreNormalStartTime @@ -1121,22 +1192,11 @@ 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 ) ) - { // Record baseline pressures before pressurizing blood side circuit side of cartridge - previousNormalArterialPressure = getFilteredArterialPressure(); - previousNormalVenousPressure = getFilteredVenousPressure(); - - // Check to see if sensor is within normal ranges before we execute pressure sensor tests - if ( ( fabs( previousNormalArterialPressure ) > PRESSURE_CHECK_START_PRESSURE_TOLERANCE_MMHG ) || - ( fabs( previousNormalVenousPressure ) > PRESSURE_CHECK_START_PRESSURE_TOLERANCE_MMHG ) ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, previousNormalArterialPressure, previousNormalVenousPressure ); - } - else - { - state = DRY_SELF_TESTS_PRESSURE_SENSORS_VENOUS_SETUP_STATE; - } + { + setArtVenPressureOffsets(); + state = DRY_SELF_TESTS_PRESSURE_SENSORS_VENOUS_SETUP_STATE; } } @@ -1488,8 +1548,8 @@ * @brief * The handleDrySelfTestSyringePumpOcclusionDetectionState function handles * occlusion detection after prime has completed. - * @details Inputs: none - * @details Outputs: none + * @details Inputs: syringeOcclusionDelayStartTime + * @details Outputs: heparinOcclusionTestRun * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpOcclusionDetectionState( void ) @@ -1502,6 +1562,7 @@ { state = DRY_SELF_TESTS_COMPLETE_STATE; } + heparinOcclusionTestRun = TRUE; } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1518,7 +1579,7 @@ * The handleDrySelfTestStoppedState function handles the stopped dry self-tests * operation. * @details Inputs: selfTestsResumeRequested, occlusionBaselineWasSet, - * dryPressureTestsCompleted, cartridgeUsedTestRun + * dryPressureTestsCompleted, cartridgeUsedTestRun, heparinOcclusionTestRun * @details Outputs: selfTestsResumeRequested, selfTestStartTime, selfTestCartridgeSettleTime * @return the next state of dry self-tests state machine *************************************************************************/ @@ -1546,6 +1607,23 @@ } } + // if heparin occlusin alarm, keep calling check function so alarm condition will clear when resolved + if ( TRUE == isAlarmActive( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION ) ) + { + checkForSyringeOcclusion( FALSE ); + } + + // Set VBA to Pos A and close VBT after we have + // depressurized the line from failed pressure self tests. + if ( FALSE == dryPressureTestsCompleted ) + { + if ( getFilteredVenousPressure() <= NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG ) + { + setValvePosition( VBA, VALVE_POSITION_A_INSERT_EJECT ); + setValveAirTrap( STATE_CLOSED ); + } + } + // if resume request, resume dry self-tests if ( TRUE == selfTestsResumeRequested ) { @@ -1555,8 +1633,12 @@ selfTestCartridgeSettleTime = getMSTimerCount(); doorClosedRequired( TRUE, TRUE ); - if ( TRUE == dryPressureTestsCompleted ) + if ( TRUE == heparinOcclusionTestRun ) { + state = DRY_SELF_TESTS_COMPLETE_STATE; + } + else if ( TRUE == dryPressureTestsCompleted ) + { state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; } else @@ -1601,9 +1683,9 @@ setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); // if user set a Heparin bolus volume, request bolus to be initiated now - if ( ( bolusVol > 0.0F ) && ( getSyringePumpVolumeDelivered() < bolusVol ) ) + if ( bolusVol > 0.0F ) { - startHeparinBolus(); // moved here from startHeparinPump() in Dialysis.c + startHeparinBolus(); // Function will only start bolus if necessary } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1620,7 +1702,7 @@ * The handleWetSelfTestSetupState function setup for bubble self-test * check. * @details Inputs: none - * @details Outputs: bubble detector self-test requested + * @details Outputs: bubble detector self-test requested, checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestSetupState( void ) @@ -1631,6 +1713,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_BUBBLE_CHECK_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1643,7 +1726,7 @@ * The handleWetSelfTestBubblesState function waiting for air bubble detectors * self-tests to finish. * @details Inputs: bubbleSelfTestStatus - * @details Outputs: none + * @details Outputs: checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestBubblesState( void ) @@ -1657,6 +1740,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_BUBBLE_CHECK_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1669,7 +1753,7 @@ * The handleWetSelfTestPrimeCheckState function checks arterial and venous * lines to make sure they are primed. * @details Inputs: Arterial and venous bubble detectors status - * @details Outputs: Test pass/fail + * @details Outputs: Test pass/fail, checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestPrimeCheckState( void ) @@ -1679,18 +1763,31 @@ if ( BUBBLE_NOT_DETECTED == ADVBubbleStatus ) { - if ( TRUE == zeroBloodLeak() ) + if ( FALSE == isAlarmActive( ALARM_ID_HD_PRE_TREATMENT_WET_PRIME_TEST_FAILURE ) ) { - state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; + if ( TRUE == zeroBloodLeak() ) + { + state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; // all is good to go to the next state + } } + else + { // Stick in this state, until bubbles no longer detected/Alarm cleared + if ( STATE_CLOSED == getSwitchStatus( PUMP_TRACK_SWITCH ) ) // Spurious bubble alarms occur when the cartridge is disturbed (unlatched) + { + clearAlarmCondition( ALARM_ID_HD_PRE_TREATMENT_WET_PRIME_TEST_FAILURE ); + } + } } else { - activateAlarmNoData( ALARM_ID_HD_PRE_TREATMENT_WET_PRIME_TEST_FAILURE ); + if ( STATE_CLOSED == getSwitchStatus( PUMP_TRACK_SWITCH ) ) + { + activateAlarmNoData( ALARM_ID_HD_PRE_TREATMENT_WET_PRIME_TEST_FAILURE ); + } } - - if ( TRUE == doesAlarmStatusIndicateStop() ) + if ( TRUE == doesAlarmStatusIndicateStop() ) // WET_PRIME_TEST_FAILURE will force the self-tests to stop { + checkpointWetSelfTestsState = WET_SELF_TESTS_PRIME_CHECK_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1739,7 +1836,7 @@ * self-test for blood leak detector. * @details Inputs: none * @details Outputs: bloodLeakDebubbleStartTimeMS, settleStartTime, - * isValvesSettingSent + * isValvesSettingSent, checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestBloodLeakDetectorState( void ) @@ -1757,6 +1854,7 @@ { if ( TRUE == hasBloodLeakZeroSequenceFailed() ) { + zeroBloodLeakReset(); #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) #endif @@ -1776,6 +1874,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1788,7 +1887,7 @@ * The handleWetSelfTestStartFirstDisplacementState function setups the valves * and pumps to start first dialysate displacement. * @details Inputs: settleStartTime, isValvesSettingSent - * @details Outputs: isValvesSettingSent + * @details Outputs: isValvesSettingSent, checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementSetupState( void ) @@ -1821,6 +1920,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1833,7 +1933,7 @@ * The handleWetSelfTestFirstDisplacementState function handles the first * dialysate displacement from reservoir 1 to reservoir 2. * @details Inputs: displacementStartTime, fmdIntegratedVolume, settleStartTime - * @details Outputs: settleStartTime, displacementStartTime + * @details Outputs: settleStartTime, displacementStartTime, checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementState( void ) @@ -1866,6 +1966,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1878,7 +1979,7 @@ * The handleWetSelfTestFirstDisplacementVerifyState function checks the load cell * readings and FMD integrated volume after the first dialysate displacement. * @details Inputs: settleStartTime, fmdIntegratedVolume - * @details Outputs: none + * @details Outputs: checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementVerifyState( void ) @@ -1928,6 +2029,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1940,7 +2042,7 @@ * The handleWetSelfTestSecondDisplacementSetupState function setups the valves * and pumps to start second dialysate displacement. * @details Inputs: settleStartTime, isValvesSettingSent - * @details Outputs: isValvesSettingSent + * @details Outputs: isValvesSettingSent, checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestSecondDisplacementSetupState( void ) @@ -1973,6 +2075,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_SECOND_DISPLACEMENT_SETUP_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1985,7 +2088,7 @@ * The handleWetSelfTestSecondDisplacementState function handles the first * dialysate displacement from reservoir 2 to reservoir 1. * @details Inputs: displacementStartTime, fmdIntegratedVolume, settleStartTime - * @details Outputs: displacementStartTime + * @details Outputs: displacementStartTime, checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestSecondDisplacementState( void ) @@ -2016,6 +2119,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_SECOND_DISPLACEMENT_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -2028,7 +2132,7 @@ * The handleWetSelfTestSecondDisplacementVerifyState function checks the load cell * readings and FMD integrated volume after the second dialysate displacement. * @details Inputs: settleStartTime, reservoirVolume[], reservoirs' weights - * @details Outputs: verify correctness of dialysate flow meter and load cell + * @details Outputs: verify correctness of dialysate flow meter and load cell, checkpointWetSelfTestsState * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestSecondDisplacementVerifyState( void ) @@ -2078,6 +2182,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -2089,24 +2194,68 @@ * @brief * The handleWetSelfTestStoppedState function handles the stopped wet self-tests * operation. - * @details Inputs: selfTestsResumeRequested + * @details Inputs: selfTestsResumeRequested, checkpointWetSelfTestsState * @details Outputs: selfTestsResumeRequested, selfTestStartTime * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestStoppedState( void ) { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_STOPPED_STATE; + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); setAlarmResumePerDoorAndLatch(); doorClosedRequired( FALSE, FALSE ); if ( TRUE == selfTestsResumeRequested ) { + if ( BUBBLE_NOT_DETECTED == getBubbleStatus( ADV ) ) + { + if ( STATE_CLOSED == getSwitchStatus( PUMP_TRACK_SWITCH ) ) // Spurious bubble alarms occur when the cartridge is disturbed (unlatched) + { + clearAlarmCondition( ALARM_ID_HD_PRE_TREATMENT_WET_PRIME_TEST_FAILURE ); + } + } // Restart self-test start time selfTestStartTime = getMSTimerCount(); doorClosedRequired( TRUE, TRUE ); selfTestsResumeRequested = FALSE; - state = WET_SELF_TESTS_START_STATE; // TODO - should start state make sure there is sufficient/appropriate res volumes to restart wet self-tests? and if not, should it signal res mgmt to drain and fill R1 and R2 before resuming wet self-tests? + + // if user set a Heparin bolus volume, request bolus to be initiated now + if ( bolusVol > 0.0F ) + { + startHeparinBolus(); // Function will only start bolus if necessary + } + + switch( checkpointWetSelfTestsState ) + { + case WET_SELF_TESTS_BUBBLE_CHECK_SETUP_STATE: + case WET_SELF_TESTS_BUBBLE_CHECK_STATE: + case WET_SELF_TESTS_PRIME_CHECK_STATE: + case WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE: + state = WET_SELF_TESTS_START_STATE; + break; + + case WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE: + case WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE: + state = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; + break; + + case WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE: + state = WET_SELF_TESTS_SECOND_DISPLACEMENT_SETUP_STATE; + break; + + case WET_SELF_TESTS_SECOND_DISPLACEMENT_SETUP_STATE: + case WET_SELF_TESTS_SECOND_DISPLACEMENT_STATE: + state = WET_SELF_TESTS_SECOND_DISPLACEMENT_SETUP_STATE; + break; + + case WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE: + case WET_SELF_TESTS_COMPLETE_STATE: + state = WET_SELF_TESTS_COMPLETE_STATE; + + default: + state = WET_SELF_TESTS_START_STATE; + } } return state;