Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r64f6bd52b1c84609e1920810b32722f0ce4f4e60 -rcd5be724d5a3ba7457e761191d82f278654d7f5c --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 64f6bd52b1c84609e1920810b32722f0ce4f4e60) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision cd5be724d5a3ba7457e761191d82f278654d7f5c) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2020-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2024 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 Prime.c * * @author (last) Sean Nash -* @date (last) 17-Jul-2023 +* @date (last) 02-Oct-2023 * * @author (original) Quang Nguyen * @date (original) 08-Dec-2020 @@ -40,8 +40,8 @@ #define MAX_PRIME_TIME ( 30 * SEC_PER_MIN ) ///< Maximum prime time (in seconds). #define PRIME_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the prime data is published on the CAN bus. -#define BLOOD_PUMP_FAST_FLOW_RATE_PURGE_AIR_ML_MIN 300 ///< Blood pump fast flow rate to fill fluid. -#define BLOOD_PUMP_SLOW_FLOW_RATE_PURGE_AIR_ML_MIN 150 ///< Blood pump slow flow rate after fluid reach lower level of air trap sensor. +#define BLOOD_PUMP_INIT_FLOW_RATE_PURGE_AIR_ML_MIN 150 ///< Blood pump initial flow rate before fluid reach upper level of air trap sensor. +#define BLOOD_PUMP_SLOW_FLOW_RATE_PURGE_AIR_ML_MIN 50 ///< Blood pump slow flow rate for subsequent returns to purge state. #define BLOOD_PUMP_SALINE_FLOW_RATE_PURGE_AIR_ML_MIN 200 ///< Blood pump very slow flow rate during prime saline dialyzer state #define BLOOD_PUMP_SLOW_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 150 ///< Blood pump slow flow rate during prime recirculate blood circuit state. #define BLOOD_PUMP_FAST_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 300 ///< Blood pump fast flow rate during prime recirculate blood circuit state. @@ -99,6 +99,7 @@ NUM_OF_PRIME_BUBBLE_CLEAR_STATES ///< Number of bubble clear states. } PRIME_BUBBLE_CLEAR_STATE_T; +/// Dialyzer volume data record structure. typedef struct { U32 bloodVolume; ///< Blood volume of the dialyzer in mL. U32 dialysateVolume; ///< Dialysate volume of the dialyzer in mL. @@ -129,7 +130,6 @@ static BOOL primeStartRequested; ///< Flag indicates user requesting to start prime. static BOOL primeResumeRequested; ///< Flag indicates user requesting prime resume. -static BOOL primeFirstPurgePass; ///< Flag indicates to transition to a faster purge speed. static U32 noAirDetectedStartTime; ///< starting time when detecting no air. static U32 purgeAirTimeOutStartTime; ///< Starting time for purge air state time out. @@ -149,7 +149,7 @@ static void resetPrimeFlags(); static void setupForPrimePause( void ); static void broadcastPrimingStatus( void ); -static void purgeAirValvesBloodPumpControl( void ); +static void purgeAirValvesBloodPumpControl( BOOL firstTime ); static void handlePrimeBubbleClear( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeWaitForUserStartState( void ); @@ -195,7 +195,6 @@ void transitionToPrime( void ) { primeStartTime = getMSTimerCount(); - primeFirstPurgePass = TRUE; setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); @@ -459,11 +458,12 @@ * @brief * The purgeAirValvesBloodPumpControl function controls valves and blood pump * to purge air. - * @details Inputs: primeFirstPurgePass + * @details Inputs: None * @details Outputs: run blood pump, close VDI, VDO, VBA and VBV valves, open VBT valve - * @return current state (sub-mode) + * @param firstTime flag indicating whether this is first time setting up for purge state + * @return none *************************************************************************/ -static void purgeAirValvesBloodPumpControl( void ) +static void purgeAirValvesBloodPumpControl( BOOL firstTime ) { setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); @@ -473,9 +473,11 @@ signalDialOutPumpHardStop(); signalDialInPumpHardStop(); - if ( FALSE == primeFirstPurgePass ) + + // For subsequent returns to blood side purge air state, slow down BP to prevent bubbles from getting up into PBo line + if ( TRUE == firstTime ) { - setBloodPumpTargetFlowRate( BLOOD_PUMP_FAST_FLOW_RATE_PURGE_AIR_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setBloodPumpTargetFlowRate( BLOOD_PUMP_INIT_FLOW_RATE_PURGE_AIR_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); } else { @@ -584,13 +586,17 @@ else #endif { - if ( TRUE == primeStartRequested ) + if ( TRUE == doesAlarmStatusIndicateStop() ) { + setupForPrimePause(); + state = HD_PRIME_PAUSE; + } + else if ( TRUE == primeStartRequested ) + { primeStartRequested = FALSE; state = HD_PRIME_SALINE_SETUP_STATE; } } - return state; } @@ -608,7 +614,7 @@ { HD_PRE_TREATMENT_PRIME_STATE_T state = HD_PRIME_SALINE_PURGE_AIR_STATE; - purgeAirValvesBloodPumpControl(); + purgeAirValvesBloodPumpControl( TRUE ); purgeAirTimeOutStartTime = getMSTimerCount(); primeSalineDialyzerBubbleClearStartTime = getMSTimerCount(); @@ -630,8 +636,8 @@ * @brief * The handlePrimePurgeAirState function checks for air trap level and moves * to blood circuit circulation state if fluid is detected at upper sensor. - * @details Inputs: air trap levels, primeFirstPurgePass, purgeAirTimeOutStartTime - * @details Outputs: runs blood pump, control valves to trap air, primeFirstPurgePass + * @details Inputs: air trap levels, purgeAirTimeOutStartTime + * @details Outputs: runs blood pump, control valves to trap air * noAirDetectedStartTime * @return current state *************************************************************************/ @@ -656,9 +662,6 @@ setBloodPumpTargetFlowRate( BLOOD_PUMP_FAST_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - // Once the dialyzer is no longer dry from the first pass of purge air, we can set flow to the fast rate - // until we are in a new priming state. - primeFirstPurgePass = FALSE; noAirDetectedStartTime = getMSTimerCount(); primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_COMPLETE_STATE; state = HD_PRIME_SALINE_CIRC_BLOOD_CIRCUIT_STATE; @@ -686,14 +689,17 @@ { HD_PRE_TREATMENT_PRIME_STATE_T state = HD_PRIME_SALINE_CIRC_BLOOD_CIRCUIT_STATE; - if ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) + if ( ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) && + ( ( BUBBLE_DETECTED == getBubbleStatus( ADV ) ) || ( TRUE == didTimeout( noAirDetectedStartTime, NO_AIR_DETECTED_COUNT ) ) ) ) { - purgeAirValvesBloodPumpControl(); + signalBloodPumpHardStop(); + purgeAirValvesBloodPumpControl( FALSE ); purgeAirTimeOutStartTime = getMSTimerCount(); state = HD_PRIME_SALINE_PURGE_AIR_STATE; } - if ( TRUE == didTimeout( noAirDetectedStartTime, NO_AIR_DETECTED_COUNT ) ) + if ( ( TRUE == didTimeout( noAirDetectedStartTime, NO_AIR_DETECTED_COUNT ) ) && + ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) ) { signalBloodPumpHardStop(); state = HD_PRIME_RESERVOIR_ONE_FILL_COMPLETE_STATE;