Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -rcd21cbb4e733bfdf52f83bdca7a905645022c572 -r4bae2d153f4242a52c8602df3e5161d6f1f122ef --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision cd21cbb4e733bfdf52f83bdca7a905645022c572) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 4bae2d153f4242a52c8602df3e5161d6f1f122ef) @@ -1,20 +1,21 @@ /************************************************************************** * -* Copyright (c) 2021-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2023 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) Dara Navaei -* @date (last) 14-Dec-2022 +* @author (last) Sean Nash +* @date (last) 04-Jan-2023 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 * ***************************************************************************/ +#include "AirPump.h" #include "AirTrap.h" #include "BloodFlow.h" #include "BloodLeak.h" @@ -45,8 +46,8 @@ #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 BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ( 20 * MS_PER_SECOND ) ///< Pressure self-test time to run blood pump in ms. -#define DIAL_IN_PUMP_RUN_TIME_PRESSURE_SELF_TEST ( 20 * MS_PER_SECOND ) ///< Pressure self-test time to run dip in ms. +#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 ( 30 * 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. @@ -60,15 +61,14 @@ #define ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG -200.0F ///< Arterial pressure low limit after running blood pump. #define VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG 200.0F ///< Venous pressure high limit after running blood pump. -#define VENOUS_PRESSURE_SELF_TEST_FIRST_PASS_LIMIT_MMHG 200.0F ///< Venous pressure high limit after running dpi in first test. +#define VENOUS_PRESSURE_SELF_TEST_FIRST_PASS_LIMIT_MMHG 250.0F ///< Venous pressure high limit after running air pump in first test. #define NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG 20.0F ///< Difference in pressure readings after return to normal state tolerance (in mmHg). #define DIP_FLOW_RATE_SETUP_ML_MIN 150 ///< Dialysate inlet pump flow rate during the setup for wet self-test. #define DIP_FLOW_RATE_FIRST_DISPLACEMENT_ML_MIN 100 ///< Dialysate inlet pump flow rate during the first displacement in wet self-test. #define DIP_FLOW_RATE_SECOND_DISPLACEMENT_ML_MIN 600 ///< Dialysate inlet pump flow rate during the second displacement in wet self-test. -#define WET_SELF_TEST_RESERVOIR_ONE_SETUP_VOLUME_ML 1200.0F ///< Setup volume for reservoir one before wet self-test in ml. #define WET_SELF_TEST_FIRST_DISPLACEMENT_TARGET_VOLUME_ML 100.0F ///< Target of first displacement volume in ml. #define WET_SELF_TEST_SECOND_DISPLACEMENT_TARGET_VOLUME_ML 600.0F ///< Target of second displacement volume in ml. #define WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE 0.05F ///< Tolerance on integrated volume as a percentage (5%). @@ -86,18 +86,16 @@ #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. -/// Multiplier to conver flow (mL/min) into volume (mL) for period of general task interval. -static const F32 SELF_TEST_FLOW_INTEGRATOR = ( ( 1.0F * TASK_GENERAL_INTERVAL ) / ( SEC_PER_MIN * MS_PER_SECOND ) ); - // ********** private data ********** static NO_CART_SELF_TESTS_STATE_T currentNoCartSelfTestsState; ///< Current state of the no cartridge self-tests state machine. static U32 runPumpStartTime; ///< Beginning time when pumps start running -static BOOL havePumpsStarted; ///< Flag indicates pumps have started running for self-test. +static BOOL havePumpsStartedForNCST; ///< Flag indicates pumps have started running for no cartridge pumps self-test. +static BOOL pumpHomingRequestedForNCST; ///< Flag indicates pumps should be homed after running no cartridge pumps self-test. static DRY_SELF_TESTS_STATE_T currentDrySelfTestsState; ///< Current state of the dry self-tests state machine. static U32 pressureSelfTestBloodPumpRunStartTime; ///< Pressure dry self-test blood pump runs start time. -static U32 pressureSelfTestDialInPumpRunStartTime; ///< Pressure dry self-test dip runs start time. +static U32 pressureSelfTestVenousTestStartTime; ///< Pressure dry self-test dip runs start time. static U32 pressureSelfTestNormalizedStartTime; ///< Normalized pressure dry self-test start time. static U32 pressureSelfTestDecayStartTime; ///< Decay pressure dry self-test start time. static U32 pressureSelfTestStabilityStartTime; ///< Stability pressure dry self-test start time. @@ -114,7 +112,6 @@ static U32 displacementStartTime; ///< Dialysate displacement starting time. static F32 fmdIntegratedVolume; ///< FMD integrated volume over displacement time. static F32 reservoirVolume[ NUM_OF_DG_RESERVOIRS ]; ///< Hold the current volume of all reservoirs. -static F32 setupDisplacementVolume; ///< Hold the setup displacement volume to get reservoir one to target volume. static BOOL isValvesSettingSent; ///< Flag indicates valve setting change has been send to DG. static U32 selfTestStartTime; ///< Starting time of self-test (in ms). @@ -258,7 +255,8 @@ currentNoCartSelfTestsState = NO_CART_SELF_TESTS_START_STATE; runPumpStartTime = 0; - havePumpsStarted = FALSE; + havePumpsStartedForNCST = FALSE; + pumpHomingRequestedForNCST = FALSE; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); @@ -792,36 +790,41 @@ * @brief * The handleNoCartSelfTestPumpsState function runs blood, dialysate inlet, * dialysate outlet pumps for certain time to make sure no alarms occur. - * @details Inputs: none - * @details Outputs: Ran self-test for blood, dialysate in, dialysate out pumps + * @details Inputs: havePumpsStartedForNCST + * @details Outputs: pumpHomingRequestedForNCST, + * Ran self-test for blood, dialysate in, dialysate out pumps * @return the next state of no cartridge self-tests state machine *************************************************************************/ static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestPumpsState( void ) { NO_CART_SELF_TESTS_STATE_T state = NO_CART_SELF_TESTS_PUMPS_STATE; - if ( FALSE == havePumpsStarted ) + if ( FALSE == havePumpsStartedForNCST ) { - havePumpsStarted = TRUE; + havePumpsStartedForNCST = TRUE; setBloodPumpTargetFlowRate( PUMP_SELF_TEST_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialInPumpTargetFlowRate( PUMP_SELF_TEST_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialOutPumpTargetRate( PUMP_SELF_TEST_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); runPumpStartTime = getMSTimerCount(); } - if ( TRUE == didTimeout( runPumpStartTime, PUMP_RUN_SELF_TEST_TIME_MS ) ) + if ( TRUE == pumpHomingRequestedForNCST ) { - signalBloodPumpHardStop(); - signalDialInPumpHardStop(); - signalDialOutPumpHardStop(); - // Home pumps for cartridge installation homeBloodPump(); homeDialInPump(); homeDialOutPump(); state = NO_CART_SELF_TESTS_HOME_IDLE_STATE; } + else if ( TRUE == didTimeout( runPumpStartTime, PUMP_RUN_SELF_TEST_TIME_MS ) ) + { + // Request homing of pumps for cartridge installation + signalBloodPumpHardStop(); + signalDialInPumpHardStop(); + signalDialOutPumpHardStop(); + pumpHomingRequestedForNCST = TRUE; + } if ( TRUE == doesAlarmStatusIndicateStop() ) { @@ -877,7 +880,8 @@ if ( TRUE == selfTestsResumeRequested ) { selfTestsResumeRequested = FALSE; - havePumpsStarted = FALSE; + havePumpsStartedForNCST = FALSE; + pumpHomingRequestedForNCST = FALSE; doorClosedRequired( TRUE, TRUE ); state = NO_CART_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; } @@ -986,9 +990,28 @@ } else { - // Wait for reservoirs to drain before starting this test - if ( ( getLoadCellWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) < MAX_EMPTY_RESERVOIR_WEIGHT_G ) && ( getLoadCellWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) < MAX_EMPTY_RESERVOIR_WEIGHT_G ) ) +#ifndef _RELEASE_ + if ( SW_CONFIG_DISABLE_VALUE != getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) { + + // Wait for reservoirs to drain before starting this test + if ( ( getLoadCellWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) < MAX_EMPTY_RESERVOIR_WEIGHT_G ) && ( getLoadCellWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) < MAX_EMPTY_RESERVOIR_WEIGHT_G ) ) + { + // TODO - wait 1 sec before taking pressure readings and beginning pressure check + previousNormalArterialPressure = getFilteredArterialPressure(); + previousNormalVenousPressure = getFilteredVenousPressure(); + state = DRY_SELF_TESTS_PRESSURE_SENSORS_VENOUS_SETUP_STATE; + + // 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_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, previousNormalArterialPressure, previousNormalVenousPressure ); + } + } + } + else +#endif + { // TODO - wait 1 sec before taking pressure readings and beginning pressure check previousNormalArterialPressure = getFilteredArterialPressure(); previousNormalVenousPressure = getFilteredVenousPressure(); @@ -1000,6 +1023,7 @@ SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, previousNormalArterialPressure, previousNormalVenousPressure ); } } + } return state; @@ -1010,7 +1034,7 @@ * The handleDrySelfTestPressureSensorsVenousSetupState function handles the setup * for the venous pressure sensor dry self-test. * @details Inputs: none - * @details Outputs: pressureSelfTestDialInPumpRunStartTime + * @details Outputs: pressureSelfTestVenousTestStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsVenousSetupState( void ) @@ -1024,13 +1048,35 @@ } else { - setValvePosition( VDI, VALVE_POSITION_B_OPEN ); +#ifndef _RELEASE_ + if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) + { +#endif + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); +#ifndef _RELEASE_ + } + else + { + setValvePosition( VDI, VALVE_POSITION_B_OPEN ); + } +#endif setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); setValvePosition( VBA, VALVE_POSITION_B_OPEN ); setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); setValveAirTrap( STATE_CLOSED ); - setDialInPumpTargetFlowRate( DIAL_IN_PUMP_PRESSURE_SELF_TEST_FLOW, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - pressureSelfTestDialInPumpRunStartTime = getMSTimerCount(); +#ifndef _RELEASE_ + if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) + { +#endif + setAirPumpState( AIR_PUMP_STATE_ON ); +#ifndef _RELEASE_ + } + else + { + setDialInPumpTargetFlowRate( DIAL_IN_PUMP_PRESSURE_SELF_TEST_FLOW, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } +#endif + pressureSelfTestVenousTestStartTime = getMSTimerCount(); } return state; @@ -1040,7 +1086,7 @@ * @brief * The handleDrySelfTestPressureSensorsVenousState function tests the readings of * the venous pressure sensor and verify they are in correct range. - * @details Inputs: pressureSelfTestDialInPumpRunStartTime + * @details Inputs: pressureSelfTestVenousTestStartTime * @details Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ @@ -1052,11 +1098,22 @@ // End the test when reaching target pressure or time out if ( VENOUS_PRESSURE_SELF_TEST_FIRST_PASS_LIMIT_MMHG <= venousPressure ) { - signalDialInPumpHardStop(); +#ifndef _RELEASE_ + if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) + { +#endif + setAirPumpState( AIR_PUMP_STATE_OFF ); +#ifndef _RELEASE_ + } + else + { + signalDialInPumpHardStop(); + } +#endif state = DRY_SELF_TESTS_PRESSURE_SENSORS_ARTERIAL_SETUP_STATE; } - if ( TRUE == didTimeout( pressureSelfTestDialInPumpRunStartTime, DIAL_IN_PUMP_RUN_TIME_PRESSURE_SELF_TEST ) ) + if ( TRUE == didTimeout( pressureSelfTestVenousTestStartTime, VENOUS_PRESSURE_SELF_TEST_MAX_TEST_TIME ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, venousPressure, VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG ); } @@ -1426,24 +1483,20 @@ *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestStartState( void ) { - WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_START_STATE; + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_SETUP_STATE; F32 resOneWeight = getReservoirWeightLargeFilter( DG_RESERVOIR_1 ); - setupDisplacementVolume = fabs( resOneWeight - WET_SELF_TEST_RESERVOIR_ONE_SETUP_VOLUME_ML ); F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); isValvesSettingSent = TRUE; setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - setDialInPumpTargetFlowRate( DIP_FLOW_RATE_SETUP_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); fmdIntegratedVolume = 0.0F; if ( ( bolusVol > 0.0F ) && ( getSyringePumpVolumeDelivered() < bolusVol ) ) { startHeparinBolus(); // moved here from startHeparinPump() in Dialysis.c } - state = WET_SELF_TESTS_SETUP_STATE; - if ( TRUE == doesAlarmStatusIndicateStop() ) { state = WET_SELF_TESTS_STOPPED_STATE; @@ -1463,17 +1516,10 @@ *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestSetupState( void ) { - WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_SETUP_STATE; + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BUBBLES_STATE; - setupDisplacementVolume -= ( SELF_TEST_FLOW_INTEGRATOR * getMeasuredDialInFlowRate() ); + selfTestBubble( ADV ); - if ( setupDisplacementVolume <= 0.0 ) - { - signalDialInPumpHardStop(); - selfTestBubble( ADV ); - state = WET_SELF_TESTS_BUBBLES_STATE; - } - if ( TRUE == doesAlarmStatusIndicateStop() ) { state = WET_SELF_TESTS_STOPPED_STATE;