Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r6a8d904f4316ed9d9f2f14f99afde63bef38eace -rceeba51c01b896855eb03ab81281a2b0f48c75d2 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 6a8d904f4316ed9d9f2f14f99afde63bef38eace) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision ceeba51c01b896855eb03ab81281a2b0f48c75d2) @@ -7,8 +7,8 @@ * * @file SelfTests.c * -* @author (last) Dara Navaei -* @date (last) 14-Dec-2022 +* @author (last) Sean Nash +* @date (last) 05-Feb-2023 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -46,12 +46,14 @@ #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 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 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 ( 7 * MS_PER_SECOND ) ///< Time to wait until we open VBT during normal pressure tests. +#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). @@ -69,10 +71,9 @@ #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%). +#define WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE 0.10F ///< Tolerance on integrated volume as a percentage (10%). #define WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE 20.0F ///< Tolerance on integrated volume in grams. #define WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G 20.0F ///< Tolerance in the load cell readings of the displacement in grams. #define WET_SELF_TEST_DISPLACEMENT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Time to displace dialysate in wet self-test in ms. @@ -87,16 +88,15 @@ #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 pressureSelfTestPreNormalStartTime; ///< Pressure dry self-test pre-normal start time. static U32 pressureSelfTestBloodPumpRunStartTime; ///< Pressure dry self-test blood pump runs start time. static U32 pressureSelfTestVenousTestStartTime; ///< Pressure dry self-test dip runs start time. static U32 pressureSelfTestNormalizedStartTime; ///< Normalized pressure dry self-test start time. @@ -115,9 +115,9 @@ 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 BOOL isValvesSettingSent; ///< Flag indicates valve setting change has been sent to DG. +static U32 selfTestCartridgeSettleTime; ///< Cartridge settle start time. 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. @@ -138,6 +138,7 @@ static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestHomeIdleState( void ); static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestStoppedState( 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 handleDrySelfTestPressureSensorsNormalSetupState( void ); @@ -257,9 +258,10 @@ useHeparin = ( ( bolusVol > 0.0 ) || ( hepRate > 0.0 ) ? TRUE : FALSE ); } - currentNoCartSelfTestsState = NO_CART_SELF_TESTS_START_STATE; + currentNoCartSelfTestsState = NO_CART_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; runPumpStartTime = 0; - havePumpsStarted = FALSE; + havePumpsStartedForNCST = FALSE; + pumpHomingRequestedForNCST = FALSE; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); @@ -291,13 +293,11 @@ *************************************************************************/ void execNoCartSelfTests( void ) { + NO_CART_SELF_TESTS_STATE_T priorSubState = currentNoCartSelfTestsState; + // execute no cartridge self-tests state machine switch ( currentNoCartSelfTestsState ) { - case NO_CART_SELF_TESTS_START_STATE: - currentNoCartSelfTestsState = NO_CART_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; - break; - case NO_CART_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE: currentNoCartSelfTestsState = handleNoCartSelfTestsWaitForClosedDoor(); break; @@ -338,6 +338,10 @@ // Self-tests flags should be handled by now, reset if flags not handled with current state resetSelfTestsFlags(); + if ( priorSubState != currentNoCartSelfTestsState ) + { + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentNoCartSelfTestsState ); + } // Publish current self-test time data if ( calcTimeSince( selfTestPreviousPublishDataTime ) >= SELF_TEST_TIME_DATA_PUB_INTERVAL ) { @@ -390,9 +394,9 @@ previousNormalVenousPressure = 0.0; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); + selfTestCartridgeSettleTime = getMSTimerCount(); + doorClosedRequired( FALSE, TRUE ); - doorClosedRequired( TRUE, TRUE ); - // Pumps should be off signalBloodPumpHardStop(); signalDialInPumpHardStop(); @@ -413,30 +417,18 @@ * @brief * The execDrySelfTests function executes the dry self-tests state machine. * @details Inputs: currentDrySelfTestsState - * @details Outputs: currentDrySelfTestsState + * @details Outputs: currentDrySelfTestsState, pressureSelfTestPreNormalStartTime * @return none *************************************************************************/ void execDrySelfTests( void ) { + DRY_SELF_TESTS_STATE_T priorSubState = currentDrySelfTestsState; + // execute dry self-tests state machine switch ( currentDrySelfTestsState ) { case DRY_SELF_TESTS_START_STATE: - // Ensure occlusion sensor has time to settle after cartridge insertion before starting dry self-tests - if ( TRUE == didTimeout( selfTestStartTime, CARTRIDGE_INSERT_PRESSURE_SETTLE_TIME_MS ) ) - { - setOcclusionInstallLevel(); // Record occlusion pressure level after a new cartridge is installed -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) ) - { - currentDrySelfTestsState = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; - } - else -#endif - { - currentDrySelfTestsState = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; - } - } + currentDrySelfTestsState = handleDrySelfTestStartState(); break; case DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE: @@ -447,14 +439,15 @@ currentDrySelfTestsState = handleDrySelfTestUsedCartridgeCheckState(); break; - case DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE: + case DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE: if ( SELF_TEST_STATUS_PASSED == execPresOcclDryTest() ) { setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); setValveAirTrap( STATE_OPEN ); + pressureSelfTestPreNormalStartTime = getMSTimerCount(); currentDrySelfTestsState = DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_SETUP_STATE; } break; @@ -514,6 +507,10 @@ // Self-tests flags should be handled by now, reset if flags not handled with current state resetSelfTestsFlags(); + if ( priorSubState != currentDrySelfTestsState ) + { + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentDrySelfTestsState ); + } // Publish current self-test time data if ( calcTimeSince( selfTestPreviousPublishDataTime ) >= SELF_TEST_TIME_DATA_PUB_INTERVAL ) { @@ -592,6 +589,8 @@ *************************************************************************/ void execWetSelfTests( void ) { + WET_SELF_TESTS_STATE_T priorSubState = currentWetSelfTestsState; + #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WET_SELF_TEST ) == SW_CONFIG_ENABLE_VALUE ) { @@ -606,11 +605,11 @@ currentWetSelfTestsState = handleWetSelfTestStartState(); break; - case WET_SELF_TESTS_SETUP_STATE: + case WET_SELF_TESTS_BUBBLE_CHECK_SETUP_STATE: currentWetSelfTestsState = handleWetSelfTestSetupState(); break; - case WET_SELF_TESTS_BUBBLES_STATE: + case WET_SELF_TESTS_BUBBLE_CHECK_STATE: currentWetSelfTestsState = handleWetSelfTestBubblesState(); break; @@ -661,6 +660,11 @@ // Self-tests flags should be handled by now, reset if flags not handled with current state resetSelfTestsFlags(); + + if ( priorSubState != currentWetSelfTestsState ) + { + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentWetSelfTestsState ); + } } /*********************************************************************//** @@ -758,19 +762,19 @@ NO_CART_SELF_TESTS_STATE_T state = NO_CART_SELF_TESTS_HOME_SYRINGE_PUMP_STATE; BOOL syringeHome = isSyringePumpHome(); BOOL syringeStopped = isSyringePumpStopped(); - BOOL syringePreload = isSyringePumpPreLoaded(); + BOOL syringePreloaded = isSyringePumpPreLoaded(); if ( TRUE == useHeparin ) { - if ( ( TRUE != syringeHome ) && ( TRUE == syringeStopped ) && ( FALSE == syringePreload ) ) + if ( ( TRUE != syringeHome ) && ( TRUE == syringeStopped ) && ( FALSE == syringePreloaded ) ) { retractSyringePump(); } - else if ( ( TRUE == syringeHome ) && ( TRUE == syringeStopped ) && ( FALSE == syringePreload ) ) + else if ( ( TRUE == syringeHome ) && ( TRUE == syringeStopped ) && ( FALSE == syringePreloaded ) ) { preloadSyringePlunger(); } - else if ( TRUE == syringePreload ) + else if ( TRUE == syringePreloaded ) { state = NO_CART_SELF_TESTS_PUMPS_STATE; } @@ -793,36 +797,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() ) { @@ -878,7 +887,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; } @@ -888,6 +898,52 @@ /*********************************************************************//** * @brief + * The handleDrySelfTestStartState function makes sure door is + * closed before starting self-tests. + * @details Inputs: none + * @details 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 pumpTrack = getSwitchStatus( PUMP_TRACK_SWITCH ); + + if ( STATE_CLOSED == pumpTrack ) + { + // 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 ) ) + { + setOcclusionInstallLevel(); // Record occlusion pressure level after a new cartridge is installed + doorClosedRequired( TRUE, TRUE ); +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) ) + { + state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; + } + else +#endif + { + state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; + } + } + } + + else + { + // doorClosedRequired() will trigger alarms if pumpTrack is open + 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 Inputs: none @@ -903,8 +959,7 @@ // Restart self-test start time selfTestStartTime = getMSTimerCount(); - // TODO: Use appropriate sensor driver - if (( STATE_CLOSED == frontDoor ) && (STATE_CLOSED == pumpTrack ) ) + if ( ( STATE_CLOSED == frontDoor ) && ( STATE_CLOSED == pumpTrack ) ) { state = DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE; setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); @@ -941,7 +996,7 @@ ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) ) { - state = DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE; + state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; } else { @@ -954,7 +1009,7 @@ #ifndef _RELEASE_ else { - state = DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE; + state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; } #endif } @@ -972,7 +1027,7 @@ * @brief * The handleDrySelfTestPressureSensorsSetupState function handles the setup * for pressure sensors dry self-test. - * @details Inputs: none + * @details Inputs: pressureSelfTestPreNormalStartTime * @details Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ @@ -994,33 +1049,40 @@ // 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 + if ( TRUE == didTimeout( pressureSelfTestPreNormalStartTime, PRE_NORMAL_PRESSURE_SELF_TEST_DELAY_MS ) ) + { + 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 + { + 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(); - 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 + { + state = DRY_SELF_TESTS_PRESSURE_SENSORS_VENOUS_SETUP_STATE; + } } } - else -#endif - { - // 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 ); - } - } - } return state; @@ -1112,7 +1174,8 @@ 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 ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, venousPressure, VENOUS_PRESSURE_SELF_TEST_FIRST_PASS_LIMIT_MMHG ); + setAirPumpState( AIR_PUMP_STATE_OFF ); } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1219,11 +1282,10 @@ // update peak pressure value from pressurized state // if pressure continues to increase due to filter lag. // Arterial goes negative while Venous goes positive. - if (arterialPressure < peakArterialPressure ) + if ( arterialPressure < peakArterialPressure ) { peakArterialPressure = arterialPressure; } - if ( venousPressure > peakVenousPressure ) { peakVenousPressure = venousPressure; @@ -1304,7 +1366,7 @@ * @brief * The handleDrySelfTestPressureSensorsNormalState function verify the readings of * pressure sensors after returning to normal state. - * @details Inputs: none + * @details Inputs: pressureSelfTestNormalizedStartTime * @details Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ @@ -1315,23 +1377,38 @@ F32 const arterialPressureDiff = fabs( getFilteredArterialPressure() - previousNormalArterialPressure ); F32 const venousPressureDiff = fabs( getFilteredVenousPressure() - previousNormalVenousPressure ); - // open VDI to Pos A after timer threshold - if ( TRUE == didTimeout( pressureSelfTestNormalizedStartTime, NORMALIZED_PRESSURE_SELF_TEST_VDI_TIMER ) ) +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) { - setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); + // open VDI to Pos A after timer threshold + if ( TRUE == didTimeout( pressureSelfTestNormalizedStartTime, NORMALIZED_PRESSURE_SELF_TEST_VDI_TIMER ) ) + { + setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); + } + // open air trap after time threshold. + if ( TRUE == didTimeout( pressureSelfTestNormalizedStartTime, NORMALIZED_PRESSURE_SELF_TEST_VBT_TIMERX ) ) + { + setValveAirTrap( STATE_OPEN ); + } } - - // open air trap after time threshold. - if ( TRUE == didTimeout( pressureSelfTestNormalizedStartTime, NORMALIZED_PRESSURE_SELF_TEST_VBT_TIMER ) ) + else +#endif { - setValveAirTrap( STATE_OPEN ); + // open air trap after time threshold. + if ( TRUE == didTimeout( pressureSelfTestNormalizedStartTime, NORMALIZED_PRESSURE_SELF_TEST_VBT_TIMER ) ) + { + setValveAirTrap( STATE_OPEN ); + } } - if ( ( arterialPressureDiff <= NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG ) && ( venousPressureDiff <= NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG ) ) + // After VBT opened, start looking to see if pressures normalize + if ( ( STATE_OPEN == getValveAirTrapStatus() ) && + ( arterialPressureDiff <= NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG ) && ( venousPressureDiff <= NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG ) ) { state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; } + // If pressures do not normalize within max t/o, alarm if ( TRUE == didTimeout( pressureSelfTestNormalizedStartTime, NORMALIZED_PRESSURE_SELF_TEST_TIME ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_NORMAL_TEST_FAILURE, arterialPressureDiff, venousPressureDiff ); @@ -1448,22 +1525,24 @@ doorClosedRequired( FALSE, FALSE ); - // Restart self-test start time - selfTestStartTime = getMSTimerCount(); - if ( TRUE == selfTestsResumeRequested ) { + // Restart self-test start time + selfTestStartTime = getMSTimerCount(); selfTestsResumeRequested = FALSE; - doorClosedRequired( TRUE, TRUE ); + selfTestCartridgeSettleTime = getMSTimerCount(); + #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) != SW_CONFIG_ENABLE_VALUE ) + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) ) { - state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; + doorClosedRequired( TRUE, TRUE ); + state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; } else #endif { - state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; + doorClosedRequired( FALSE, TRUE ); + state = DRY_SELF_TESTS_START_STATE; } } @@ -1474,30 +1553,24 @@ * @brief * The handleWetSelfTestStartState function handles setup state for wet * self-tests sub-mode. - * @details Inputs: reservoir one weight - * @details Outputs: setup valves and dialysate inlet pump + * @details Inputs: heparin bolus volume setting + * @details Outputs: setup valves * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestStartState( void ) { - WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_START_STATE; - F32 resOneWeight = getReservoirWeightLargeFilter( DG_RESERVOIR_1 ); - setupDisplacementVolume = fabs( resOneWeight - WET_SELF_TEST_RESERVOIR_ONE_SETUP_VOLUME_ML ); + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BUBBLE_CHECK_SETUP_STATE; 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 user set a Heparin bolus volume, request bolus to be initiated now 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; @@ -1509,25 +1582,18 @@ /*********************************************************************//** * @brief - * The handleWetSelfTestSetupState function setup reservoir one before - * the start of wet self-tests. - * @details Inputs: dialysate inlet flow rate - * @details Outputs: stop dialysate inlet pump + * The handleWetSelfTestSetupState function setup for bubble self-test + * check. + * @details Inputs: none + * @details Outputs: bubble detector self-test requested * @return the next state of wet self-tests state machine *************************************************************************/ 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_BUBBLE_CHECK_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; @@ -1547,7 +1613,7 @@ *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestBubblesState( void ) { - WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BUBBLES_STATE; + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BUBBLE_CHECK_STATE; if ( SELF_TEST_STATUS_PASSED == getBubbleSelfTestStatus( ADV ) ) { @@ -1662,9 +1728,9 @@ if ( ( TRUE == isValvesSettingSent ) && ( TRUE == getDGCommandResponse( DG_CMD_VALVE_SETTING, &cmdResp ) ) ) { - // Re-send command if DG rejects isValvesSettingSent = FALSE; + // Re-send command if DG rejects if ( DG_CMD_REQUEST_REJECT_REASON_NONE == cmdResp.rejectCode ) { setDialInPumpTargetFlowRate( DIP_FLOW_RATE_FIRST_DISPLACEMENT_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); @@ -1694,15 +1760,7 @@ { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE; - if ( ( TRUE == didTimeout( settleStartTime, RESERVOIR_SETTLE_TIME_MS ) ) && ( settleStartTime != 0 ) ) - { - reservoirVolume[ DG_RESERVOIR_1 ] = getReservoirWeight( DG_RESERVOIR_1 ); - reservoirVolume[ DG_RESERVOIR_2 ] = getReservoirWeight( DG_RESERVOIR_2 ); - displacementStartTime = getMSTimerCount(); - fmdIntegratedVolume = 0.0F; - settleStartTime = 0; - } - + // Once we've settled (5 sec), integrate flow to volume over duration of fluid transfer if ( 0 == settleStartTime ) { // This is not a volume for now and it is a flow rate. @@ -1717,6 +1775,16 @@ } } + // Wait for settle time, then initiate transfer test + if ( ( TRUE == didTimeout( settleStartTime, RESERVOIR_SETTLE_TIME_MS ) ) && ( settleStartTime != 0 ) ) + { + reservoirVolume[ DG_RESERVOIR_1 ] = getReservoirWeight( DG_RESERVOIR_1 ); + reservoirVolume[ DG_RESERVOIR_2 ] = getReservoirWeight( DG_RESERVOIR_2 ); + displacementStartTime = getMSTimerCount(); + fmdIntegratedVolume = 0.0F; + settleStartTime = 0; + } + if ( TRUE == doesAlarmStatusIndicateStop() ) { state = WET_SELF_TESTS_STOPPED_STATE; @@ -1805,9 +1873,9 @@ if ( ( TRUE == isValvesSettingSent ) && ( TRUE == getDGCommandResponse( DG_CMD_VALVE_SETTING, &cmdResp ) ) ) { - // Re-send command if DG rejects isValvesSettingSent = FALSE; + // Re-send command if DG rejects if ( DG_CMD_REQUEST_REJECT_REASON_NONE == cmdResp.rejectCode ) { setDialInPumpTargetFlowRate( DIP_FLOW_RATE_SECOND_DISPLACEMENT_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); @@ -1941,7 +2009,7 @@ { doorClosedRequired( TRUE, TRUE ); selfTestsResumeRequested = FALSE; - state = WET_SELF_TESTS_START_STATE; + 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? } return state;