Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r7229fed020e9f3398bd5ccc8a3f5576cedc322b0 -r1406dcedbc65edd2c134cf2e0861bb5aa2e569da --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 7229fed020e9f3398bd5ccc8a3f5576cedc322b0) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 1406dcedbc65edd2c134cf2e0861bb5aa2e569da) @@ -7,8 +7,8 @@ * * @file SelfTests.c * -* @author (last) Sean Nash -* @date (last) 15-May-2023 +* @author (last) Michael Garthwaite +* @date (last) 01-Jun-2023 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -91,6 +91,8 @@ #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 ********** static NO_CART_SELF_TESTS_STATE_T currentNoCartSelfTestsState; ///< Current state of the no cartridge self-tests state machine. @@ -125,6 +127,7 @@ static U32 selfTestStartTime; ///< Starting time of self-test (in ms). static U32 selfTestPreviousPublishDataTime; ///< Last time self-test time data is being published (in ms). static U32 syringeOcclusionDelayStartTime; ///< Used to calculate the 1 second delay time before check for prime occlusion. +static U32 bloodLeakDebubbleStartTimeMS; ///< Blood leak detector debubble start time in milliseconds. static BOOL useHeparin; ///< Flag indicates the user of heparin. @@ -163,6 +166,7 @@ static WET_SELF_TESTS_STATE_T handleWetSelfTestSetupState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestBubblesState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestPrimeCheckState( void ); +static WET_SELF_TESTS_STATE_T handleWetSelfTestBloodLeakDetectorDebubbleState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestBloodLeakDetectorState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementSetupState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementState( void ); @@ -295,7 +299,7 @@ pumpHomingRequestedForNCST = FALSE; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); - + setCurrentSubState( (U32)currentNoCartSelfTestsState ); doorClosedRequired( TRUE, TRUE ); // Pumps should be off @@ -371,6 +375,7 @@ if ( priorSubState != currentNoCartSelfTestsState ) { + setCurrentSubState( (U32)currentNoCartSelfTestsState ); SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentNoCartSelfTestsState ); } // Publish current self-test time data @@ -428,7 +433,7 @@ selfTestPreviousPublishDataTime = getMSTimerCount(); selfTestCartridgeSettleTime = getMSTimerCount(); doorClosedRequired( FALSE, TRUE ); - + setCurrentSubState( (U32)currentDrySelfTestsState ); // Pumps should be off signalBloodPumpHardStop(); signalDialInPumpHardStop(); @@ -532,6 +537,7 @@ if ( priorSubState != currentDrySelfTestsState ) { + setCurrentSubState( (U32)currentDrySelfTestsState ); SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentDrySelfTestsState ); } // Publish current self-test time data @@ -578,6 +584,7 @@ isValvesSettingSent = FALSE; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); + bloodLeakDebubbleStartTimeMS = getMSTimerCount(); // Pumps should be off signalBloodPumpHardStop(); @@ -633,6 +640,10 @@ currentWetSelfTestsState = handleWetSelfTestPrimeCheckState(); break; + case WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_DEBUBBLE_STATE: + currentWetSelfTestsState = handleWetSelfTestBloodLeakDetectorDebubbleState(); + break; + case WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE: currentWetSelfTestsState = handleWetSelfTestBloodLeakDetectorState(); break; @@ -679,6 +690,7 @@ if ( priorSubState != currentWetSelfTestsState ) { + setCurrent4thLevelState( currentWetSelfTestsState ); SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentWetSelfTestsState ); } } @@ -712,7 +724,7 @@ * The handleNoCartridgeWaitForClosedDoor function executes the wait for * door to be closed state of no cartridge self-tests state machine. * @details Inputs: none - * @details Outputs: none + * @details Outputs: selfTestStartTime * @return the next state of no cartridge self-tests state machine *************************************************************************/ static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestsWaitForClosedDoor( void ) @@ -895,8 +907,9 @@ * @brief * The handleNoCartSelfTestStoppedState function handles the stopped no * cartridge self-tests operation. - * @details Inputs: none - * @details Outputs: none + * @details Inputs: selfTestsResumeRequested + * @details Outputs: selfTestStartTime, selfTestsResumeRequested, + * havePumpsStartedForNCST, pumpHomingRequestedForNCST * @return the next state of no cart self-tests state machine *************************************************************************/ static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestStoppedState( void ) @@ -941,8 +954,6 @@ { setOcclusionInstallLevel(); // Record occlusion pressure level after a new cartridge is installed doorClosedRequired( TRUE, TRUE ); - signalAllowDGFillRes1(); - signalAllowDGFillRes2(); state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; } } @@ -964,7 +975,7 @@ * The handleDrySelfTestWaitForDoorCloseState function makes sure door is * closed before starting self-tests. * @details Inputs: none - * @details Outputs: none + * @details Outputs: selfTestStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestWaitForDoorCloseState( void ) @@ -1043,7 +1054,7 @@ * The handleDrySelfTestCartridgeLoadedCheckState function verifies a cartridge * is installed by checking sufficient pressure at OB sensor. * @details Inputs: none - * @details Outputs: none + * @details Outputs: dryPressureTestsCompleted * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestCartridgeLoadedCheckState( void ) @@ -1081,7 +1092,7 @@ * The handleDrySelfTestPressureSensorsSetupState function handles the setup * for pressure sensors dry self-test. * @details Inputs: pressureSelfTestPreNormalStartTime - * @details Outputs: none + * @details Outputs: previousNormalArterialPressure, previousNormalVenousPressure * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalSetupState( void ) @@ -1454,19 +1465,6 @@ setupForSelfTestsStop(); } -#ifndef _RELEASE_ - if ( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) || // Allow res 1&2 fills now if air pump not disabled - ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) ) ) - { - if ( state != DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE ) - { - signalAllowDGFlushFills(); - signalAllowDGFillRes1(); - signalAllowDGFillRes2(); - } - } -#endif - return state; } @@ -1503,8 +1501,8 @@ * @brief * The handleDrySelfTestStoppedState function handles the stopped dry self-tests * operation. - * @details Inputs: none - * @details Outputs: none + * @details Inputs: selfTestsResumeRequested + * @details Outputs: selfTestsResumeRequested, selfTestStartTime, selfTestCartridgeSettleTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestStoppedState( void ) @@ -1653,19 +1651,6 @@ { state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; } - else - { -#ifndef _RELEASE_ - if ( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_SELF_TEST ) ) ) - { - state = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; - } - else -#endif - { - activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SENSOR_ZERO_SEQUENCE_FAILED ); - } - } } else { @@ -1683,22 +1668,79 @@ /*********************************************************************//** * @brief + * The handleWetSelfTestBloodLeakDetectorDebubbleState function runs the + * dialin pump in bypass mode to remove the potential bubbles from the + * blood leak detector prior to command another zero sequence. + * @details Inputs: bloodLeakDebubbleStartTimeMS + * @details Outputs: none + * @return the next state of wet self-tests state machine + *************************************************************************/ +static WET_SELF_TESTS_STATE_T handleWetSelfTestBloodLeakDetectorDebubbleState( void ) +{ + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_DEBUBBLE_STATE; + + if ( TRUE == didTimeout( bloodLeakDebubbleStartTimeMS, BLOOD_LEAK_DETECTOR_DEBUBBLE_TIMEOUT_MS ) ) + { + signalDialInPumpHardStop(); + + if ( FALSE == isDialInPumpRunning() ) + { + if ( TRUE == zeroBloodLeak() ) + { + state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; + } + } + } + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = WET_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleWetSelfTestBloodLeakDetectorState function handles zeroing and * self-test for blood leak detector. * @details Inputs: none - * @details Outputs: next self-test state + * @details Outputs: bloodLeakDebubbleStartTimeMS, settleStartTime, + * isValvesSettingSent * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestBloodLeakDetectorState( void ) { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; + SELF_TEST_STATUS_T status = getBloodLeakSelfTestStatus(); - if ( SELF_TEST_STATUS_PASSED == getBloodLeakSelfTestStatus() ) + if ( SELF_TEST_STATUS_PASSED == status ) { settleStartTime = getMSTimerCount(); isValvesSettingSent = FALSE; state = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; } + else if ( SELF_TEST_STATUS_FAILED == status ) + { + if ( TRUE == hasBloodLeakZeroSequenceFailed() ) + { +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SENSOR_ZERO_SEQUENCE_FAILED ); + } + } + else + { + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); + setDialInPumpTargetFlowRate( DIALYSATE_FLOW_RATE_FOR_RECIRC, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + bloodLeakDebubbleStartTimeMS = getMSTimerCount(); + state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_DEBUBBLE_STATE; + } + } if ( TRUE == doesAlarmStatusIndicateStop() ) { @@ -2016,7 +2058,7 @@ * The handleWetSelfTestStoppedState function handles the stopped wet self-tests * operation. * @details Inputs: selfTestsResumeRequested - * @details Outputs: selfTestsResumeRequested + * @details Outputs: selfTestsResumeRequested, selfTestStartTime * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestStoppedState( void ) @@ -2028,6 +2070,8 @@ if ( TRUE == selfTestsResumeRequested ) { + // 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?