Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -rb3076db63d3e6515746948fba3a4c2bf9aad9c27 -rf673a49d52be60f2b75f41b2ff713cd520e634bf --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision b3076db63d3e6515746948fba3a4c2bf9aad9c27) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision f673a49d52be60f2b75f41b2ff713cd520e634bf) @@ -7,8 +7,8 @@ * * @file SelfTests.c * -* @author (last) James Walter Taylor -* @date (last) 26-Jul-2023 +* @author (last) Michael Garthwaite +* @date (last) 29-Jul-2023 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -47,14 +47,13 @@ #define DIAL_IN_PUMP_PRESSURE_SELF_TEST_FLOW 400 #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. @@ -152,6 +149,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 ); @@ -486,6 +484,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 +586,7 @@ { wetSelfTestsResult = FALSE; currentWetSelfTestsState = WET_SELF_TESTS_START_STATE; + checkpointWetSelfTestsState = WET_SELF_TESTS_START_STATE; settleStartTime = 0; displacementStartTime = 0; fmdIntegratedVolume = 0.0; @@ -1065,29 +1068,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 +1095,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 +1179,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; } } @@ -1620,7 +1667,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 +1678,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_BUBBLE_CHECK_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1643,7 +1691,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 +1705,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_BUBBLE_CHECK_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1669,7 +1718,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 ) @@ -1703,6 +1752,7 @@ } 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(); } @@ -1751,7 +1801,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 ) @@ -1788,6 +1838,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1800,7 +1851,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 ) @@ -1833,6 +1884,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1845,7 +1897,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 ) @@ -1878,6 +1930,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1890,7 +1943,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 ) @@ -1940,6 +1993,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1952,7 +2006,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 ) @@ -1985,6 +2039,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_SECOND_DISPLACEMENT_SETUP_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -1997,7 +2052,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 ) @@ -2028,6 +2083,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_SECOND_DISPLACEMENT_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -2040,7 +2096,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 ) @@ -2090,6 +2146,7 @@ if ( TRUE == doesAlarmStatusIndicateStop() ) { + checkpointWetSelfTestsState = WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE; state = WET_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } @@ -2101,7 +2158,7 @@ * @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 *************************************************************************/ @@ -2125,7 +2182,37 @@ 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? + + 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;