Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r586ec774e2006f0f9b4aef2ff2ce15dc0ccb4789 -r86ccf9565595418e7424e5cd26b5abdd63482f04 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 586ec774e2006f0f9b4aef2ff2ce15dc0ccb4789) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 86ccf9565595418e7424e5cd26b5abdd63482f04) @@ -7,8 +7,8 @@ * * @file SelfTests.c * -* @author (last) Sean Nash -* @date (last) 13-Jul-2022 +* @author (last) Michael Garthwaite +* @date (last) 07-Sep-2022 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -45,10 +45,14 @@ #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 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 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 DIP_FLOW_RATE_SETUP_ML_MIN 150 ///< Dialysate inlet pump flow rate during the setup for wet self-test. @@ -84,8 +88,14 @@ 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 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. static F32 previousNormalArterialPressure; ///< Holds the previous normal arterial pressure reading. static F32 previousNormalVenousPressure; ///< Holds the previous normal venous pressure reading. +static F32 peakArterialPressure; ///< Holds the peak arterial pressure reading. +static F32 peakVenousPressure; ///< Holds the peak normal venous pressure reading. +static F32 decayedArterialPressure; ///< Holds the decayed arterial pressure reading after blood pump is stopped. +static F32 decayedVenousPressure; ///< Holds the decayed venous pressure reading after blood pump is stopped. static BOOL wetSelfTestsResult; ///< Result of wet self-tests. static WET_SELF_TESTS_STATE_T currentWetSelfTestsState; ///< Current state of the wet self-tests state machine. @@ -120,6 +130,8 @@ 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 handleDrySelfTestPressureSensorsDecayState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsStabilityState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpPrimeState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpOcclusionDetectionState( void ); @@ -391,7 +403,6 @@ *************************************************************************/ void execDrySelfTests( void ) { - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; // execute dry self-tests state machine switch ( currentDrySelfTestsState ) @@ -438,10 +449,18 @@ currentDrySelfTestsState = handleDrySelfTestPressureSensorsSetupState(); break; - case DRY_SELF_TESTS_PRESSURE_SENSORS_STATE: + case DRY_SELF_TESTS_PRESSURE_SENSORS_PRESSURIZED_STATE: currentDrySelfTestsState = handleDrySelfTestPressureSensorsState(); break; + case DRY_SELF_TESTS_PRESSURE_SENSORS_DECAY_STATE: + currentDrySelfTestsState = handleDrySelfTestPressureSensorsDecayState(); + break; + + case DRY_SELF_TESTS_PRESSURE_SENSORS_STABILITY_STATE: + currentDrySelfTestsState = handleDrySelfTestPressureSensorsStabilityState(); + break; + case DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_STATE: currentDrySelfTestsState = handleDrySelfTestPressureSensorsNormalState(); break; @@ -469,11 +488,6 @@ // Self-tests flags should be handled by now, reset if flags not handled with current state resetSelfTestsFlags(); - if ( SELF_TEST_STATUS_FAILED == result ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, currentDrySelfTestsState ); - } - // Publish current self-test time data if ( calcTimeSince( selfTestPreviousPublishDataTime ) >= SELF_TEST_TIME_DATA_PUB_INTERVAL ) { @@ -925,7 +939,7 @@ *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsSetupState( void ) { - DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_STATE; + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_PRESSURIZED_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { @@ -959,32 +973,136 @@ * @brief * The handleDrySelfTestPressureSensorsState function tests the readings of * pressure sensors and verify they are in correct range. - * @details Inputs: none - * @details Outputs: none + * @details Inputs: peakArterialPressure, peakVenousPressure, + * pressureSelfTestDecayStartTime + * @details Outputs: peakArterialPressure, peakVenousPressure, + * pressureSelfTestDecayStartTime * @return the next state of dry self-tests state machine *************************************************************************/ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsState( void ) { - DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_STATE; + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_PRESSURIZED_STATE; 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 ) ) || - ( ( ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG >= arterialPressure ) && ( VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG <= venousPressure ) ) ) + if ( TRUE == didTimeout( pressureSelfTestBloodPumpRunStartTime, BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ) ) { + peakArterialPressure = arterialPressure; + peakVenousPressure = venousPressure; + signalBloodPumpHardStop(); // Test pass when reading positive arterial pressure and negative venous pressure - if ( ( arterialPressure < 0) && ( venousPressure > 0 ) ) + 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 ); + } + } + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestPressureSensorsDecayState function verifies + * 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, + * peakVenousPressure + * @details Outputs: decayedArterialPressure, decayedVenousPressure + * pressureSelfTestStabilityStartTime + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsDecayState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_DECAY_STATE; + F32 const arterialPressure = getFilteredArterialPressure(); + F32 const venousPressure = getFilteredVenousPressure(); + F32 arterialDecayDiff = 0; + F32 venousDecayDiff = 0; + + // update peak pressure value from pressurized state + // if pressure continues to increase due to filter lag + 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) + { + decayedArterialPressure = arterialPressure; + decayedVenousPressure = venousPressure; + pressureSelfTestStabilityStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_PRESSURE_SENSORS_STABILITY_STATE; + } + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, arterialDecayDiff, venousDecayDiff ); + } + } + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestPressureSensorsStabilityState function verifies the readings of + * pressure sensors in a stable, pressurized state after decay has been observed. + * @details Inputs: pressureSelfTestNormalizedStartTime, decayedArterialPressure + * decayedVenousPressure + * @details Outputs: pressureSelfTestNormalizedStartTime + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsStabilityState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSORS_STABILITY_STATE; + F32 arterialStabilityDiff = 0; + F32 venousStabilityDiff = 0; + + if ( ( TRUE == didTimeout( pressureSelfTestStabilityStartTime, STABILTY_PRESSURE_SELF_TEST_TIME ) ) ) + { + arterialStabilityDiff = fabs( getFilteredArterialPressure() - decayedArterialPressure ); + venousStabilityDiff = fabs( getFilteredVenousPressure() - decayedVenousPressure ); + + if (arterialStabilityDiff < STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG && venousStabilityDiff < STABILITY_PRESSURE_DIFF_TOLERANCE_MMHG) + { + pressureSelfTestNormalizedStartTime = getMSTimerCount(); setValvePosition( VBV, VALVE_POSITION_B_OPEN ); setValveAirTrap( STATE_OPEN ); - pressureSelfTestNormalizedStartTime = getMSTimerCount(); state = DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_STATE; } else { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, arterialPressure, venousPressure ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, arterialStabilityDiff, venousStabilityDiff ); } } @@ -1439,13 +1557,13 @@ 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 ) ) + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) ) { integrateVolumeToleranceG = 50.0F; } #endif - SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, resOneDiffAfterDisplacement, resOneDiffAfterDisplacement ) + 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 ) if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && @@ -1578,13 +1696,13 @@ 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 ) ) + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) ) { integrateVolumeToleranceG = 50.0F; } #endif - SEND_EVENT_WITH_2_F32_DATA( HD_EVENT_WET_SELF_TEST_DISPLACEMENT_RESULT, resOneDiffAfterDisplacement, resOneDiffAfterDisplacement ) + 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 ) if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) &&