Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r66dda999c5736ecec046197ff1c843c01f6aecc5 -r402885eda2ed755a079c854d1228ac5f76cbec7c --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 66dda999c5736ecec046197ff1c843c01f6aecc5) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 402885eda2ed755a079c854d1228ac5f76cbec7c) @@ -7,8 +7,8 @@ * * @file SelfTests.c * -* @author (last) Bill Bracken -* @date (last) 22-Aug-2022 +* @author (last) Dara Navaei +* @date (last) 22-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. @@ -70,6 +74,8 @@ #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. + /// 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 ) ); @@ -82,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. @@ -118,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 ); @@ -438,6 +452,14 @@ 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; @@ -650,15 +672,13 @@ { NO_CART_SELF_TESTS_STATE_T state = NO_CART_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; OPN_CLS_STATE_T frontDoor = getSwitchStatus( FRONT_DOOR ); - OPN_CLS_STATE_T pumpTrack = getSwitchStatus( PUMP_TRACK_SWITCH ); signalBloodPumpHardStop(); signalDialInPumpHardStop(); signalDialOutPumpHardStop(); selfTestStartTime = getMSTimerCount(); - // TODO: Use appropriate sensor driver - if ( ( STATE_CLOSED == frontDoor ) && ( STATE_CLOSED == pumpTrack ) ) + if ( STATE_CLOSED == frontDoor ) { state = NO_CART_SELF_TESTS_PRESSURE_CHECKS_STATE; } @@ -878,6 +898,9 @@ DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE; BUBBLE_STATUS_T const ADVBubbleStatus = getBubbleStatus( ADV ); + + SEND_EVENT_WITH_2_U32_DATA(HD_EVENT_DRY_SELF_TEST_CARTRIDGE_RESULT,(U32)ADVBubbleStatus,(U32)BUBBLE_DETECTED) + if ( ( BUBBLE_DETECTED == ADVBubbleStatus ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) ) @@ -920,6 +943,12 @@ 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 ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, previousNormalArterialPressure, previousNormalVenousPressure ); + } + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); setValvePosition( VBA, VALVE_POSITION_B_OPEN ); @@ -936,8 +965,10 @@ * @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 ) @@ -947,21 +978,112 @@ 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; + + 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 ); } } @@ -1424,6 +1546,9 @@ } #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 ) + if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && ( ( integratedVolumeDiff <= integrateVolumeToleranceG ) || ( integratedVolumeToTargetPercent <= WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE ) ) ) @@ -1559,6 +1684,10 @@ 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 ) + if ( ( fabs( resOneDiffAfterDisplacement - resTwoDiffAfterDisplacement ) <= WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G ) && ( ( integratedVolumeDiff <= integrateVolumeToleranceG ) || ( integratedVolumeToTargetPercent <= WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE ) ) )