Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r6a3548084b4c7268dcee35009ab2b0fd6beb9c08 -rdb1cea8cb5ab1a052babf36d242ed90622a014f9 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 6a3548084b4c7268dcee35009ab2b0fd6beb9c08) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision db1cea8cb5ab1a052babf36d242ed90622a014f9) @@ -7,8 +7,8 @@ * * @file Prime.c * -* @author (last) Sean Nash -* @date (last) 03-May-2023 +* @author (last) Michael Garthwaite +* @date (last) 16-May-2023 * * @author (original) Quang Nguyen * @date (original) 08-Dec-2020 @@ -62,7 +62,8 @@ #define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 8 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. #define STEADY_VOLUME_COUNT_SEC ( 10000 / LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ) ///< Counter must be greater than 10 seconds before steady volume is true. #define STEADY_VOLUME_DIALYSATE_PRIME_TIME_LIMIT_MS ( 55 * MS_PER_SECOND ) ///< Time in msec for the reservoir volume to stabilize during dialysate prime state. -#define STEADY_VOLUME_BYPASS_PRIME_TIME_LIMIT_MS ( 25 * MS_PER_SECOND ) ///< Time in msec for the reservoir volume to stabilize during bypass dialysate prime state. +#define STEADY_VOLUME_BYPASS_PRIME_TIME_LIMIT_MS ( 62 * MS_PER_SECOND ) ///< Time in msec for the reservoir volume to stabilize during bypass dialysate prime state. +#define STEADY_VOLUME_BYPASS_PRIME_HISTERESIS_ML ( 0.3F ) ///< mL of histeresis for the steady state check that determines when bypass line is primed. #define VENOUS_PRESSURE_BUBBLE_CLEAR_MAX_MMHG ( 200.0F ) ///< Maximum venous pressure reading (in mmHg) for bubble clear. #define BUBBLE_CLEAR_WAIT_TIME_INITIAL_MS ( 10 * MS_PER_SECOND ) ///< Time in msec to wait for initial bubble clear pressure. @@ -136,14 +137,16 @@ static U32 primeDialysateBypassStartTime; ///< Starting time of priming dialysate bypass circuit. static U32 steadyVolumeSamplingStartTime; ///< Load cell steady volume sampling interval starting time. static F32 minimumReservoirVolume; ///< Minimum reservoir volume in mL. -static U32 steadyVolumeCount; ///< Use to keep track the number of dVolume/dt < Threshold +static U32 steadyVolumeCount; ///< Use to keep track the number of dVolume/dt < Threshold. +static BOOL bubbleClearEnded; ///< Bubble clear ended boolean signal. // ********** private function prototypes ********** static void resetPrimeFlags(); static void setupForPrimePause( void ); static void broadcastPrimingStatus( void ); static void purgeAirValvesBloodPumpControl( void ); +static void handlePrimeBubbleClear( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeWaitForUserStartState( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineDialyzerSetupState( void ); @@ -173,14 +176,17 @@ primeStartTime = 0; primePauseStartTime = 0; primeStatusBroadcastTimerCounter = 0; + bubbleClearEnded = FALSE; } /*********************************************************************//** * @brief * The transitionToPrime function prepares for transition to prime sub-mode. * This function will reset anything required before the start of priming sequence. * @details Inputs: none - * @details Outputs: currentPrimeState, wetSelfTestsResult, primeStartReqReceived, reservoirFilledStatus[] + * @details Outputs: currentPrimeState, wetSelfTestsResult, + * primeStartReqReceived, reservoirFilledStatus[], bubbleClearEnded, + * primeDialyzerBubbleClearState * @return none *************************************************************************/ void transitionToPrime( void ) @@ -192,7 +198,7 @@ setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); - + setCurrentSubState( (U32)currentPrimeState ); doorClosedRequired( TRUE, TRUE ); // Pumps should be off @@ -210,6 +216,14 @@ setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); resetPrimeFlags(); + + if ( TRUE == getTestConfigStatus( TEST_CONFIG_USE_WET_CARTRIDGE ) ) + { + // If the use wet cartridge test configuration has been enabled skip the dialyzer + // bubble clear + bubbleClearEnded = TRUE; + primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_COMPLETE_STATE; + } } /*********************************************************************//** @@ -288,6 +302,7 @@ if ( priorSubState != currentPrimeState ) { + setCurrentSubState( (U32)currentPrimeState ); SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentPrimeState ); } @@ -460,6 +475,75 @@ /*********************************************************************//** * @brief + * The handlePrimeBubbleClear function handles bubble clear pressurizing + * of dialyzer. + * @details Inputs: air trap levels, primeDialyzerBubbleClearState, + * primeSalineDialyzerBubbleClearStartTime + * @details Outputs: control valves to pressurize, primeDialyzerBubbleClearState, + * primeSalineDialyzerBubbleClearStartTime + * @return none + *************************************************************************/ +static void handlePrimeBubbleClear( void ) +{ + U32 timeout; + + switch ( primeDialyzerBubbleClearState ) + { + case PRIME_BUBBLE_CLEAR_READY_STATE: + case PRIME_BUBBLE_CLEAR_FLOW_STATE: + if ( PRIME_BUBBLE_CLEAR_READY_STATE == primeDialyzerBubbleClearState ) + { + timeout = BUBBLE_CLEAR_WAIT_TIME_INITIAL_MS; + } + else + { + timeout = BUBBLE_CLEAR_WAIT_TIME_MS; + } + + if ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, timeout ) ) + { + // Close valve to create pressure to clear Dialyzer bubbles + primeSalineDialyzerBubbleClearStartTime = getMSTimerCount(); + if ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) + { + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValveAirTrap( STATE_CLOSED ); + primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_PRESSURE_STATE; + } + } + break; + + case PRIME_BUBBLE_CLEAR_PRESSURE_STATE: + case PRIME_BUBBLE_CLEAR_VENT_STATE: + if ( ( getMeasuredVenousPressure() > VENOUS_PRESSURE_BUBBLE_CLEAR_MAX_MMHG ) || + ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, BUBBLE_CLEAR_MAX_TIME_MS ) ) ) + { + // Pressure max reached. or timeout, release pressure + setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); + primeSalineDialyzerBubbleClearStartTime = getMSTimerCount(); + bubbleClearEnded = TRUE; + primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_VENT_STATE; + } + else if ( ( TRUE == bubbleClearEnded ) && + ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, BUBBLE_CLEAR_VALVE_WAIT_TIME_MS ) ) ) + { + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValveAirTrap( STATE_OPEN ); + bubbleClearEnded = FALSE; + primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_FLOW_STATE; + } + break; + + case PRIME_BUBBLE_CLEAR_COMPLETE_STATE: + default: + // do nothing + break; + + } // end switch +} + +/*********************************************************************//** + * @brief * The handlePrimeSalineSetupState function checks user's request to start * priming. * @details Inputs: primeStartReqReceived @@ -526,74 +610,7 @@ return state; } -/*********************************************************************//** - * @brief - * The handlePrimeBubbleClear function handles bubble clear pressurizing - * of dialyzer. - * @details Inputs: air trap levels, primeDialyzerBubbleClearState, primeSalineDialyzerBubbleClearStartTime - * @details Outputs: control valves to pressurize, primeDialyzerBubbleClearState, primeSalineDialyzerBubbleClearStartTime - * @return none - *************************************************************************/ -static void handlePrimeBubbleClear( void ) -{ - static BOOL bubble_clear_ended = FALSE; - U32 timeout; - switch ( primeDialyzerBubbleClearState ) - { - case PRIME_BUBBLE_CLEAR_READY_STATE: - case PRIME_BUBBLE_CLEAR_FLOW_STATE: - if ( PRIME_BUBBLE_CLEAR_READY_STATE == primeDialyzerBubbleClearState ) - { - timeout = BUBBLE_CLEAR_WAIT_TIME_INITIAL_MS; - } - else - { - timeout = BUBBLE_CLEAR_WAIT_TIME_MS; - } - - if ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, timeout ) ) - { - // Close valve to create pressure to clear Dialyzer bubbles - primeSalineDialyzerBubbleClearStartTime = getMSTimerCount(); - if ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) - { - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); - setValveAirTrap( STATE_CLOSED ); - primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_PRESSURE_STATE; - } - } - break; - - case PRIME_BUBBLE_CLEAR_PRESSURE_STATE: - case PRIME_BUBBLE_CLEAR_VENT_STATE: - if ( ( getMeasuredVenousPressure() > VENOUS_PRESSURE_BUBBLE_CLEAR_MAX_MMHG ) || - ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, BUBBLE_CLEAR_MAX_TIME_MS ) ) ) - { - // Pressure max reached. or timeout, release pressure - setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); - primeSalineDialyzerBubbleClearStartTime = getMSTimerCount(); - bubble_clear_ended = TRUE; - primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_VENT_STATE; - } - else if ( ( TRUE == bubble_clear_ended ) && - ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, BUBBLE_CLEAR_VALVE_WAIT_TIME_MS ) ) ) - { - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); - setValveAirTrap( STATE_OPEN ); - bubble_clear_ended = FALSE; - primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_FLOW_STATE; - } - break; - - case PRIME_BUBBLE_CLEAR_COMPLETE_STATE: - default: - // do nothing - break; - - } // end switch -} - /*********************************************************************//** * @brief * The handlePrimePurgeAirState function checks for air trap level and moves @@ -917,7 +934,7 @@ { F32 const currentReservoirVolume = getLoadCellWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); - if ( currentReservoirVolume >= minimumReservoirVolume ) + if ( currentReservoirVolume >= ( minimumReservoirVolume - STEADY_VOLUME_BYPASS_PRIME_HISTERESIS_ML ) ) { if ( ++steadyVolumeCount >= STEADY_VOLUME_COUNT_SEC ) { @@ -927,9 +944,12 @@ } else { - minimumReservoirVolume = currentReservoirVolume; steadyVolumeCount = 0; } + if ( currentReservoirVolume < minimumReservoirVolume ) + { + minimumReservoirVolume = currentReservoirVolume; + } steadyVolumeSamplingStartTime = getMSTimerCount(); // re-armed the timer for the next 1 second iteration }