Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -rc851d640df6889c1ac5b8b1a66340376463d0702 -r364631fbb6ffd3ab52271e1cc5b71ee9e2cc777f --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision c851d640df6889c1ac5b8b1a66340376463d0702) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 364631fbb6ffd3ab52271e1cc5b71ee9e2cc777f) @@ -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 ( 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). @@ -95,6 +97,7 @@ 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. @@ -113,7 +116,7 @@ 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 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). @@ -256,7 +259,7 @@ 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; havePumpsStartedForNCST = FALSE; pumpHomingRequestedForNCST = FALSE; @@ -296,10 +299,6 @@ // 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; @@ -419,7 +418,7 @@ * @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 ) @@ -441,14 +440,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; @@ -607,11 +607,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; @@ -764,19 +764,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; } @@ -998,7 +998,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 { @@ -1011,7 +1011,7 @@ #ifndef _RELEASE_ else { - state = DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE; + state = DRY_SELF_TESTS_CARTRIDGE_LOADED_CHECK_STATE; } #endif } @@ -1029,7 +1029,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 *************************************************************************/ @@ -1051,33 +1051,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; @@ -1169,8 +1176,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_FIRST_PASS_LIMIT_MMHG ); setAirPumpState( AIR_PUMP_STATE_OFF ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, venousPressure, VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG ); } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1277,11 +1284,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; @@ -1362,7 +1368,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 *************************************************************************/ @@ -1373,23 +1379,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 ); @@ -1534,21 +1555,19 @@ * @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_SETUP_STATE; - F32 resOneWeight = getReservoirWeightLargeFilter( DG_RESERVOIR_1 ); + 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 ); - 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 @@ -1565,15 +1584,15 @@ /*********************************************************************//** * @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_BUBBLES_STATE; + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BUBBLE_CHECK_STATE; selfTestBubble( ADV ); @@ -1596,7 +1615,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 ) ) { @@ -1711,9 +1730,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 ); @@ -1743,15 +1762,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. @@ -1766,6 +1777,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; @@ -1854,9 +1875,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 ); @@ -1990,7 +2011,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;