Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -rddf6c806a996119aee480bad2d7222385880c94a -r0a4dcd288d4347b85baaa0b07da568b6add5eac7 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision ddf6c806a996119aee480bad2d7222385880c94a) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 0a4dcd288d4347b85baaa0b07da568b6add5eac7) @@ -1,14 +1,14 @@ /************************************************************************** * -* 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) 28-Sep-2022 +* @date (last) 14-Dec-2022 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -41,20 +41,29 @@ #define PUMP_RUN_SELF_TEST_TIME_MS ( 15 * MS_PER_SECOND ) ///< Self-test time to run pumps in ms. #define PUMP_SELF_TEST_FLOW_RATE_ML_MIN 100 ///< Self-test pump flow rate in mL/min. -#define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 3 * MS_PER_SECOND ) ///< Delay 3 seconds then check for syringe pump prime occlusion. +#define BLOOD_PUMP_PRESSURE_SELF_TEST_FLOW 100 +#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 ( 5 * MS_PER_SECOND ) ///< Pressure self-test time to run blood pump in ms. -#define NORMALIZED_PRESSURE_SELF_TEST_TIME ( 4 * MS_PER_SECOND ) ///< Time to wait for pressure to normalize in ms. -#define STABILTY_PRESSURE_SELF_TEST_TIME ( 4 * MS_PER_SECOND ) ///< Time to wait for pressure to stabilize in ms. -#define DECAY_PRESSURE_SELF_TEST_TIME ( 2 * MS_PER_SECOND ) ///< time to wait for pressure to decay in ms. +#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 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_VDI_TIMER ( 5 * MS_PER_SECOND ) ///< Time to wait until we open VDI during normal pressure tests. -#define ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG -50.0F ///< Arterial pressure low limit after running blood pump. -#define VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG 400 ///< Venous pressure high limit after running blood pump. +#define ARTERIAL_DECAY_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Difference in arterial pressure readings after the pump stops (in mmHg). +#define VENOUS_DECAY_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Difference in venous pressure readings after the pump stops (in mmHg). +#define ARTERIAL_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Difference in arterial pressure readings while in a stable pressured state (in mmHg). +#define VENOUS_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Difference in venous pressure readings while in a stable pressured state (in mmHg). -#define DECAY_PRESSURE_DIFF_TOLERANCE_MMHG 5.0F ///< Difference in pressure readings after the pump stops (in mmHg). -#define STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG 2.0F ///< Difference in pressure readings while in a stable pressured state (in mmHg). -#define NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG 10.0F ///< Difference in pressure readings after return to normal state tolerance (in mmHg). +#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 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. @@ -66,15 +75,16 @@ #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. -#define RESERVOIR_SETTLE_TIME_MS ( 4 * MS_PER_SECOND ) ///< Time allotted for reservoir to settle in ms. +#define RESERVOIR_SETTLE_TIME_MS ( 5 * MS_PER_SECOND ) ///< Time allotted for reservoir to settle in ms. #define MAX_NO_CARTRIDGE_SELF_TEST_TIME 30 ///< Maximum no cartridge self-test time (in seconds). -#define MAX_DRY_SELF_TEST_TIME ( 3 * SEC_PER_MIN ) ///< Maximum dry self-test time (in seconds). +#define MAX_DRY_SELF_TEST_TIME ( 12 * SEC_PER_MIN ) ///< Maximum dry self-test time (in seconds). #define CARTRIDGE_INSERT_PRESSURE_SETTLE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Time (in ms) required to wait for occlusion pressure to settle after cartridge insertion. #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. /// 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 ) ); @@ -87,6 +97,7 @@ 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 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. @@ -128,8 +139,11 @@ static DRY_SELF_TESTS_STATE_T handleDrySelfTestWaitForDoorCloseState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestUsedCartridgeCheckState( void ); -static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsSetupState( void ); -static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsState( 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 ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsArterialSetupState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsArterialState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsDecayState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsStabilityState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalState( void ); @@ -440,25 +454,30 @@ setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); setValveAirTrap( STATE_OPEN ); - currentDrySelfTestsState = DRY_SELF_TESTS_PRESSURE_SENSORS_SETUP_STATE; + currentDrySelfTestsState = DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_SETUP_STATE; } -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_WORN_OUT_CARTRIDGE ) ) - { - setValveAirTrap( STATE_CLOSED ); - currentDrySelfTestsState = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; - } -#endif break; - case DRY_SELF_TESTS_PRESSURE_SENSORS_SETUP_STATE: - currentDrySelfTestsState = handleDrySelfTestPressureSensorsSetupState(); + case DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_SETUP_STATE: + currentDrySelfTestsState = handleDrySelfTestPressureSensorsNormalSetupState(); break; - case DRY_SELF_TESTS_PRESSURE_SENSORS_PRESSURIZED_STATE: - currentDrySelfTestsState = handleDrySelfTestPressureSensorsState(); + case DRY_SELF_TESTS_PRESSURE_SENSORS_VENOUS_SETUP_STATE: + currentDrySelfTestsState = handleDrySelfTestPressureSensorsVenousSetupState(); break; + case DRY_SELF_TESTS_PRESSURE_SENSORS_VENOUS: + currentDrySelfTestsState = handleDrySelfTestPressureSensorsVenousState(); + break; + + case DRY_SELF_TESTS_PRESSURE_SENSORS_ARTERIAL_SETUP_STATE: + currentDrySelfTestsState = handleDrySelfTestPressureSensorsArterialSetupState(); + break; + + case DRY_SELF_TESTS_PRESSURE_SENSORS_ARTERIAL: + currentDrySelfTestsState = handleDrySelfTestPressureSensorsArterialState(); + break; + case DRY_SELF_TESTS_PRESSURE_SENSORS_DECAY_STATE: currentDrySelfTestsState = handleDrySelfTestPressureSensorsDecayState(); break; @@ -736,16 +755,26 @@ static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestHomeSyringePumpState( void ) { NO_CART_SELF_TESTS_STATE_T state = NO_CART_SELF_TESTS_HOME_SYRINGE_PUMP_STATE; + BOOL syringeHome = isSyringePumpHome(); + BOOL syringeStopped = isSyringePumpStopped(); + BOOL syringePreload = isSyringePumpPreLoaded(); if ( TRUE == useHeparin ) { - if ( ( isSyringePumpHome() != TRUE ) && ( TRUE == isSyringePumpStopped() ) ) + if ( ( TRUE != syringeHome ) && ( TRUE == syringeStopped ) && ( FALSE == syringePreload ) ) { retractSyringePump(); } + else if ( ( TRUE == syringeHome ) && ( TRUE == syringeStopped ) && ( FALSE == syringePreload ) ) + { + preloadSyringePlunger(); + } + else if ( TRUE == syringePreload ) + { + state = NO_CART_SELF_TESTS_PUMPS_STATE; + } } - - if ( ( TRUE != useHeparin ) || ( TRUE == isSyringePumpHome() ) ) + else { state = NO_CART_SELF_TESTS_PUMPS_STATE; } @@ -921,6 +950,12 @@ { activateAlarmNoData( ALARM_ID_INSTALL_NEW_CARTRIDGE ); } +#ifndef _RELEASE_ + else + { + state = DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE; + } +#endif } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -940,32 +975,126 @@ * @details Outputs: none * @return the next state of dry self-tests state machine *************************************************************************/ -static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsSetupState( void ) +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalSetupState( void ) { - DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_PRESSURIZED_STATE; + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_SETUP_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; setupForSelfTestsStop(); } else - { // TODO - wait 1 sec before taking pressure readings and beginning pressure check - 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 ) ) + { + // 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 ) ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, previousNormalArterialPressure, previousNormalVenousPressure ); + // 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; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestPressureSensorsVenousSetupState function handles the setup + * for the venous pressure sensor dry self-test. + * @details Inputs: none + * @details Outputs: pressureSelfTestDialInPumpRunStartTime + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsVenousSetupState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_VENOUS; + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + else + { + setValvePosition( VDI, VALVE_POSITION_B_OPEN ); + 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(); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestPressureSensorsVenousState function tests the readings of + * the venous pressure sensor and verify they are in correct range. + * @details Inputs: pressureSelfTestDialInPumpRunStartTime + * @details Outputs: none + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsVenousState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_VENOUS; + F32 const venousPressure = getFilteredVenousPressure(); + + // End the test when reaching target pressure or time out + if ( VENOUS_PRESSURE_SELF_TEST_FIRST_PASS_LIMIT_MMHG <= venousPressure ) + { + signalDialInPumpHardStop(); + state = DRY_SELF_TESTS_PRESSURE_SENSORS_ARTERIAL_SETUP_STATE; + } + + if ( TRUE == didTimeout( pressureSelfTestDialInPumpRunStartTime, DIAL_IN_PUMP_RUN_TIME_PRESSURE_SELF_TEST ) ) + { + 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() ) + { + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestPressureSensorsArterialSetupState function handles the setup + * for the arterial pressure sensor dry self-test. + * @details Inputs: + * @details Outputs: pressureSelfTestBloodPumpRunStartTime + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsArterialSetupState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_ARTERIAL; + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + else + { setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); setValvePosition( VBA, VALVE_POSITION_B_OPEN ); setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); setValveAirTrap( STATE_CLOSED ); - setBloodPumpTargetFlowRate( PUMP_SELF_TEST_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setBloodPumpTargetFlowRate( BLOOD_PUMP_PRESSURE_SELF_TEST_FLOW, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); pressureSelfTestBloodPumpRunStartTime = getMSTimerCount(); } @@ -974,39 +1103,36 @@ /*********************************************************************//** * @brief - * The handleDrySelfTestPressureSensorsState function tests the readings of - * pressure sensors and verify they are in correct range. - * @details Inputs: peakArterialPressure, peakVenousPressure, + * The handleDrySelfTestPressureSensorsArterialState function tests the readings of + * the arterial pressure sensor and verify they are in correct range. + * @details Inputs: pressureSelfTestBloodPumpRunStartTime + * @details Outputs: peakVenousPressure, peakArterialPressure, * pressureSelfTestDecayStartTime - * @details Outputs: peakArterialPressure, peakVenousPressure, - * pressureSelfTestDecayStartTime * @return the next state of dry self-tests state machine *************************************************************************/ -static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsState( void ) +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsArterialState( void ) { - DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_PRESSURIZED_STATE; + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_ARTERIAL; F32 const arterialPressure = getFilteredArterialPressure(); F32 const venousPressure = getFilteredVenousPressure(); // End the test when reaching target pressure or time out - if ( TRUE == didTimeout( pressureSelfTestBloodPumpRunStartTime, BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ) ) + // Test pass when reading positive arterial pressure and negative venous pressure + if ( ( ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG >= arterialPressure ) && ( VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG <= venousPressure ) ) { - peakArterialPressure = arterialPressure; peakVenousPressure = venousPressure; - + peakArterialPressure = arterialPressure; signalBloodPumpHardStop(); - // Test pass when reading positive arterial pressure and negative venous pressure - if ( ( ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG >= arterialPressure ) && ( VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG <= venousPressure ) ) - { - pressureSelfTestDecayStartTime = getMSTimerCount(); - state = DRY_SELF_TESTS_PRESSURE_SENSORS_DECAY_STATE; - } - else - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, arterialPressure, venousPressure ); - } + + pressureSelfTestDecayStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_PRESSURE_SENSORS_DECAY_STATE; } + if ( TRUE == didTimeout( pressureSelfTestBloodPumpRunStartTime, BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, venousPressure, arterialPressure ); + } + if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; @@ -1022,8 +1148,7 @@ * the readings of pressure sensors after we have verified the sensors * are in the correct range by observing the loss in pressure once * the pump has stopped. - * @details Inputs: decayedArterialPressure, decayedVenousPressure, - * pressureSelfTestStabilityStartTime, peakArterialPressure, + * @details Inputs: pressureSelfTestDecayStartTime, peakArterialPressure, * peakVenousPressure * @details Outputs: decayedArterialPressure, decayedVenousPressure * pressureSelfTestStabilityStartTime @@ -1037,12 +1162,26 @@ F32 arterialDecayDiff = 0; F32 venousDecayDiff = 0; + // 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 ) + { + peakArterialPressure = arterialPressure; + } + + if ( venousPressure > peakVenousPressure ) + { + peakVenousPressure = venousPressure; + } + if ( ( TRUE == didTimeout( pressureSelfTestDecayStartTime, DECAY_PRESSURE_SELF_TEST_TIME ) ) ) { arterialDecayDiff = fabs( arterialPressure - peakArterialPressure ); venousDecayDiff = fabs( venousPressure - peakVenousPressure ); - if (arterialDecayDiff < DECAY_PRESSURE_DIFF_TOLERANCE_MMHG && venousDecayDiff < DECAY_PRESSURE_DIFF_TOLERANCE_MMHG) + if ( ( arterialDecayDiff < ARTERIAL_DECAY_PRESSURE_DIFF_TOLERANCE_MMHG ) && + ( venousDecayDiff < VENOUS_DECAY_PRESSURE_DIFF_TOLERANCE_MMHG ) ) { decayedArterialPressure = arterialPressure; decayedVenousPressure = venousPressure; @@ -1055,7 +1194,6 @@ } } - if ( TRUE == doesAlarmStatusIndicateStop() ) { state = DRY_SELF_TESTS_STOPPED_STATE; @@ -1085,11 +1223,12 @@ arterialStabilityDiff = fabs( getFilteredArterialPressure() - decayedArterialPressure ); venousStabilityDiff = fabs( getFilteredVenousPressure() - decayedVenousPressure ); - if (arterialStabilityDiff < STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG && venousStabilityDiff < STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG) + if ( ( arterialStabilityDiff < ARTERIAL_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG ) && + ( venousStabilityDiff < VENOUS_STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG ) ) { pressureSelfTestNormalizedStartTime = getMSTimerCount(); setValvePosition( VBV, VALVE_POSITION_B_OPEN ); - setValveAirTrap( STATE_OPEN ); + state = DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_STATE; } else @@ -1122,16 +1261,26 @@ 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 ) ) + { + setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); + } + + // 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 ) ) + { + state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; + } + if ( TRUE == didTimeout( pressureSelfTestNormalizedStartTime, NORMALIZED_PRESSURE_SELF_TEST_TIME ) ) { - if ( ( arterialPressureDiff <= NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG ) && ( venousPressureDiff <= NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG ) ) - { - state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; - } - else - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_NORMAL_TEST_FAILURE, arterialPressureDiff, venousPressureDiff ); - } + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_NORMAL_TEST_FAILURE, arterialPressureDiff, venousPressureDiff ); } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1165,6 +1314,7 @@ { state = DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE; syringeOcclusionDelayStartTime = getMSTimerCount(); // Get the current time to check for occlusion after 3 seconds has elapsed + signalActionToResumeFill(); } else { @@ -1173,19 +1323,20 @@ } else { - if ( TRUE == isSyringePumpHome() ) + if ( TRUE == isSyringePumpPreLoaded() ) { seekSyringePlunger(); } else { - retractSyringePump(); + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (U32)SW_FAULT_ID_HD_SYRINGE_NOT_PRELOADED ) } } } } else { + signalActionToResumeFill(); state = DRY_SELF_TESTS_COMPLETE_STATE; } @@ -1276,48 +1427,23 @@ static WET_SELF_TESTS_STATE_T handleWetSelfTestStartState( void ) { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_START_STATE; - DG_CMD_RESPONSE_T cmdResp; + 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 ); - F32 const resOneWeight = getReservoirWeightLargeFilter( DG_RESERVOIR_1 ); - setupDisplacementVolume = fabs( resOneWeight - WET_SELF_TEST_RESERVOIR_ONE_SETUP_VOLUME_ML ); + 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 ( FALSE == isValvesSettingSent ) + if ( ( bolusVol > 0.0F ) && ( getSyringePumpVolumeDelivered() < bolusVol ) ) { - isValvesSettingSent = TRUE; - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); - setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - - if ( resOneWeight > WET_SELF_TEST_RESERVOIR_ONE_SETUP_VOLUME_ML ) - { - cmdChangeDGValveSetting( DG_VALVE_SETTING_R1_TO_R2 ); - } - else - { - cmdChangeDGValveSetting( DG_VALVE_SETTING_R2_TO_R1 ); - } + startHeparinBolus(); // moved here from startHeparinPump() in Dialysis.c } - if ( ( TRUE == isValvesSettingSent ) && ( TRUE == getDGCommandResponse( DG_CMD_VALVE_SETTING, &cmdResp ) ) ) - { - // Re-send command if DG rejects - isValvesSettingSent = FALSE; + state = WET_SELF_TESTS_SETUP_STATE; - if ( FALSE == cmdResp.rejected ) - { - F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); - - setDialInPumpTargetFlowRate( DIP_FLOW_RATE_SETUP_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - fmdIntegratedVolume = 0.0; - - if ( ( bolusVol > 0.0 ) && ( 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; @@ -1398,14 +1524,21 @@ if ( BUBBLE_NOT_DETECTED == ADVBubbleStatus ) { + if ( TRUE == zeroBloodLeak() ) + { + state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; + } + else + { #ifndef _RELEASE_ - if ( ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_SELF_TEST ) != SW_CONFIG_ENABLE_VALUE ) && - ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SELF_TESTS_AIR_BUBBLE_CHECK ) != SW_CONFIG_ENABLE_VALUE ) ) + if ( ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_SELF_TEST ) == SW_CONFIG_ENABLE_VALUE ) ) + { + state = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; + } + else #endif - { - if ( TRUE == zeroBloodLeak() ) { - state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SENSOR_ZERO_SEQUENCE_FAILED ); } } } @@ -1437,8 +1570,9 @@ if ( SELF_TEST_STATUS_PASSED == getBloodLeakSelfTestStatus() ) { - settleStartTime = getMSTimerCount(); - state = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; + settleStartTime = getMSTimerCount(); + isValvesSettingSent = FALSE; + state = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1454,37 +1588,34 @@ * @brief * The handleWetSelfTestStartFirstDisplacementState function setups the valves * and pumps to start first dialysate displacement. - * @details Inputs: settleStartTime - * @details Outputs: setup valves and pump, reservoirVolume[] + * @details Inputs: settleStartTime, isValvesSettingSent + * @details Outputs: isValvesSettingSent * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementSetupState( void ) { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; DG_CMD_RESPONSE_T cmdResp; - if ( ( FALSE == isValvesSettingSent ) && ( TRUE == didTimeout( settleStartTime, RESERVOIR_SETTLE_TIME_MS ) ) ) + if ( FALSE == isValvesSettingSent ) { - reservoirVolume[ DG_RESERVOIR_1 ] = getReservoirWeightLargeFilter( DG_RESERVOIR_1 ); - reservoirVolume[ DG_RESERVOIR_2 ] = getReservoirWeightLargeFilter( DG_RESERVOIR_2 ); - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); cmdChangeDGValveSetting( DG_VALVE_SETTING_R1_TO_R2 ); isValvesSettingSent = TRUE; + settleStartTime = 0; } if ( ( TRUE == isValvesSettingSent ) && ( TRUE == getDGCommandResponse( DG_CMD_VALVE_SETTING, &cmdResp ) ) ) { // Re-send command if DG rejects isValvesSettingSent = FALSE; - if ( FALSE == cmdResp.rejected ) + 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 ); - displacementStartTime = getMSTimerCount(); - fmdIntegratedVolume = 0.0; - state = WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE; + settleStartTime = getMSTimerCount(); + state = WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE; } } @@ -1501,23 +1632,35 @@ * @brief * The handleWetSelfTestFirstDisplacementState function handles the first * dialysate displacement from reservoir 1 to reservoir 2. - * @details Inputs: firstDisplacementStartTime, measured dialysate flow rate - * @details Outputs: integrated volume + * @details Inputs: displacementStartTime, fmdIntegratedVolume, settleStartTime + * @details Outputs: settleStartTime, displacementStartTime * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementState( void ) { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE; - fmdIntegratedVolume += getMeasuredDialInFlowRate(); + 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 == didTimeout( displacementStartTime, WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ) + if ( 0 == settleStartTime ) { - signalDialInPumpHardStop(); - fmdIntegratedVolume = ( ( fmdIntegratedVolume * TASK_GENERAL_INTERVAL ) / ( SEC_PER_MIN * MS_PER_SECOND ) ); + // This is not a volume for now and it is a flow rate. + fmdIntegratedVolume += getMeasuredDialInFlowRate(); - settleStartTime = getMSTimerCount(); - state = WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE; + if ( TRUE == didTimeout( displacementStartTime, WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ) + { + signalDialInPumpHardStop(); + fmdIntegratedVolume = ( ( fmdIntegratedVolume * TASK_GENERAL_INTERVAL ) / ( WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ); + settleStartTime = getMSTimerCount(); + state = WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE; + } } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1539,43 +1682,39 @@ *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementVerifyState( void ) { - WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE; + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE; + F32 resOneDiffAfterDisplacement = reservoirVolume[ DG_RESERVOIR_1 ] - getReservoirWeight( DG_RESERVOIR_1 ); + F32 resTwoDiffAfterDisplacement = getReservoirWeight( DG_RESERVOIR_2 ) - reservoirVolume[ DG_RESERVOIR_2 ]; + F32 averageDisp = ( resOneDiffAfterDisplacement + resTwoDiffAfterDisplacement ) / 2.0F; + F32 integratedVolumeDiff = fabs( fmdIntegratedVolume - averageDisp ); + F32 integratedVolumeToTargetPercent = fabs( 1.0F - ( fmdIntegratedVolume / averageDisp ) ); + F32 integrateVolumeToleranceG = WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE; - if ( TRUE == didTimeout( settleStartTime, RESERVOIR_SETTLE_TIME_MS ) ) - { - F32 resOneDiffAfterDisplacement = reservoirVolume[ DG_RESERVOIR_1 ] - getReservoirWeightLargeFilter( DG_RESERVOIR_1 ); - F32 resTwoDiffAfterDisplacement = getReservoirWeightLargeFilter( DG_RESERVOIR_2 ) - reservoirVolume[ DG_RESERVOIR_2 ]; - F32 averageDisp = ( resOneDiffAfterDisplacement + resTwoDiffAfterDisplacement ) / 2.0; - F32 integratedVolumeDiff = fabs( fmdIntegratedVolume - averageDisp ); - F32 integratedVolumeToTargetPercent = fabs( 1.0 - ( fmdIntegratedVolume / averageDisp ) ); - F32 integrateVolumeToleranceG = WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE; - #ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_WET_SELF_TEST_WIDER_VOLUME_TOL ) ) - { - integrateVolumeToleranceG = 50.0F; - } + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_WET_SELF_TEST_WIDER_VOLUME_TOL ) ) + { + integrateVolumeToleranceG = 50.0F; + } #endif - SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, resOneDiffAfterDisplacement, resTwoDiffAfterDisplacement ) - SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, integratedVolumeDiff, WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE ) + SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, resOneDiffAfterDisplacement, resTwoDiffAfterDisplacement ) + SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, averageDisp, fmdIntegratedVolume ) - if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && - ( ( integratedVolumeDiff <= integrateVolumeToleranceG ) || - ( integratedVolumeToTargetPercent <= WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE ) ) ) + if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && + ( ( integratedVolumeDiff <= integrateVolumeToleranceG ) || + ( integratedVolumeToTargetPercent <= WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE ) ) ) + { + state = WET_SELF_TESTS_SECOND_DISPLACEMENT_SETUP_STATE; + } + else + { + if ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement) > WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) { - state = WET_SELF_TESTS_SECOND_DISPLACEMENT_SETUP_STATE; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_WET_LC_TEST_FAILURE, resOneDiffAfterDisplacement, resTwoDiffAfterDisplacement ); } else { - if ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement) > WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_WET_LC_TEST_FAILURE, resOneDiffAfterDisplacement, resTwoDiffAfterDisplacement ); - } - else - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_WET_FLOW_TEST_FAILURE, averageDisp, fmdIntegratedVolume ); - } + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_WET_FLOW_TEST_FAILURE, averageDisp, fmdIntegratedVolume ); } } @@ -1592,8 +1731,8 @@ * @brief * The handleWetSelfTestSecondDisplacementSetupState function setups the valves * and pumps to start second dialysate displacement. - * @details Inputs: settleStartTime - * @details Outputs: setup valves and pump, reservoirVolume[] + * @details Inputs: settleStartTime, isValvesSettingSent + * @details Outputs: isValvesSettingSent * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestSecondDisplacementSetupState( void ) @@ -1603,26 +1742,23 @@ if ( FALSE == isValvesSettingSent ) { - reservoirVolume[ DG_RESERVOIR_1 ] = getReservoirWeightLargeFilter( DG_RESERVOIR_1 ); - reservoirVolume[ DG_RESERVOIR_2 ] = getReservoirWeightLargeFilter( DG_RESERVOIR_2 ); - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - cmdChangeDGValveSetting( DG_VALVE_SETTING_R1_TO_R2 ); + cmdChangeDGValveSetting( DG_VALVE_SETTING_R2_TO_R1 ); isValvesSettingSent = TRUE; + settleStartTime = 0; } if ( ( TRUE == isValvesSettingSent ) && ( TRUE == getDGCommandResponse( DG_CMD_VALVE_SETTING, &cmdResp ) ) ) { // Re-send command if DG rejects isValvesSettingSent = FALSE; - if ( FALSE == cmdResp.rejected ) + 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 ); - displacementStartTime = getMSTimerCount(); - fmdIntegratedVolume = 0.0; - state = WET_SELF_TESTS_SECOND_DISPLACEMENT_STATE; + settleStartTime = getMSTimerCount(); + state = WET_SELF_TESTS_SECOND_DISPLACEMENT_STATE; } } @@ -1639,24 +1775,34 @@ * @brief * The handleWetSelfTestSecondDisplacementState function handles the first * dialysate displacement from reservoir 2 to reservoir 1. - * @details Inputs: firstDisplacementStartTime, measured dialysate flow rate - * @details Outputs: integrated volume + * @details Inputs: displacementStartTime, fmdIntegratedVolume, settleStartTime + * @details Outputs: displacementStartTime * @return the next state of wet self-tests state machine *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestSecondDisplacementState( void ) { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_SECOND_DISPLACEMENT_STATE; - fmdIntegratedVolume += getMeasuredDialInFlowRate(); + 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 == didTimeout( displacementStartTime, WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ) + if ( 0 == settleStartTime ) { - signalDialInPumpHardStop(); - // Convert flow into volume for period of general task interval - fmdIntegratedVolume = ( ( fmdIntegratedVolume * TASK_GENERAL_INTERVAL ) / ( SEC_PER_MIN * MS_PER_SECOND ) ); + fmdIntegratedVolume += getMeasuredDialInFlowRate(); - settleStartTime = getMSTimerCount(); - state = WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE; + if ( TRUE == didTimeout( displacementStartTime, WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ) + { + signalDialInPumpHardStop(); + fmdIntegratedVolume = ( ( fmdIntegratedVolume * TASK_GENERAL_INTERVAL ) / ( WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ); + settleStartTime = getMSTimerCount(); + state = WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE; + } } if ( TRUE == doesAlarmStatusIndicateStop() ) @@ -1678,43 +1824,39 @@ *************************************************************************/ static WET_SELF_TESTS_STATE_T handleWetSelfTestSecondDisplacementVerifyState( void ) { - WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE; + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE; + F32 resOneDiffAfterDisplacement = getReservoirWeight( DG_RESERVOIR_1 ) - reservoirVolume[ DG_RESERVOIR_1 ]; + F32 resTwoDiffAfterDisplacement = reservoirVolume[ DG_RESERVOIR_2 ] - getReservoirWeight( DG_RESERVOIR_2 ); + F32 avgDisp = ( resOneDiffAfterDisplacement + resTwoDiffAfterDisplacement ) / 2.0F; + F32 integratedVolumeDiff = fabs( fmdIntegratedVolume - avgDisp ); + F32 integratedVolumeToTargetPercent = fabs( 1.0F - ( fmdIntegratedVolume / avgDisp ) ); + F32 integrateVolumeToleranceG = WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE; - if ( TRUE == didTimeout( settleStartTime, RESERVOIR_SETTLE_TIME_MS ) ) - { - F32 resOneDiffAfterDisplacement = reservoirVolume[ DG_RESERVOIR_1 ] - getReservoirWeightLargeFilter( DG_RESERVOIR_1 ); - F32 resTwoDiffAfterDisplacement = getReservoirWeightLargeFilter( DG_RESERVOIR_2 ) - reservoirVolume[ DG_RESERVOIR_2 ]; - F32 avgDisp = ( resOneDiffAfterDisplacement + resTwoDiffAfterDisplacement ) / 2.0; - F32 integratedVolumeDiff = fabs( fmdIntegratedVolume - avgDisp ); - F32 integratedVolumeToTargetPercent = fabs( 1.0 - ( fmdIntegratedVolume / avgDisp ) ); - F32 integrateVolumeToleranceG = WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE; - #ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_WET_SELF_TEST_WIDER_VOLUME_TOL ) ) - { - integrateVolumeToleranceG = 50.0F; - } + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_WET_SELF_TEST_WIDER_VOLUME_TOL ) ) + { + integrateVolumeToleranceG = 50.0F; + } #endif - SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, resOneDiffAfterDisplacement, resTwoDiffAfterDisplacement ) - SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, integratedVolumeToTargetPercent, WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE ) + SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, resOneDiffAfterDisplacement, resTwoDiffAfterDisplacement ) + SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, avgDisp, fmdIntegratedVolume ) - if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && - ( ( integratedVolumeDiff <= integrateVolumeToleranceG ) || - ( integratedVolumeToTargetPercent <= WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE ) ) ) + if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && + ( ( integratedVolumeDiff <= integrateVolumeToleranceG ) || + ( integratedVolumeToTargetPercent <= WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE ) ) ) + { + state = WET_SELF_TESTS_COMPLETE_STATE; + } + else + { + if ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement) > WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) { - state = WET_SELF_TESTS_COMPLETE_STATE; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_WET_LC_TEST_FAILURE, resOneDiffAfterDisplacement, resTwoDiffAfterDisplacement ); } else { - if ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement) > WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_WET_LC_TEST_FAILURE, resOneDiffAfterDisplacement, resTwoDiffAfterDisplacement ); - } - else - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_WET_FLOW_TEST_FAILURE, avgDisp, fmdIntegratedVolume ); - } + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_WET_FLOW_TEST_FAILURE, avgDisp, fmdIntegratedVolume ); } }