Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r5ce2656c662525e10acd1e55f16f7aca5ce9b4d6 -r3e0d27b2607ac2ec6cead5360af682e40ec6e80f --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 5ce2656c662525e10acd1e55f16f7aca5ce9b4d6) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 3e0d27b2607ac2ec6cead5360af682e40ec6e80f) @@ -54,13 +54,19 @@ #define DIALYZER_VOLUME_SCALE_FACTOR 0.5F ///< Half of the dialyzer total volume. #define NO_AIR_DETECTED_COUNT ( 40 * MS_PER_SECOND ) ///< No air detected time period count. -#define PURGE_AIR_TIME_OUT_COUNT ( 120 * MS_PER_SECOND ) ///< Time period count for purge air time out. +#define PURGE_AIR_TIME_OUT_COUNT ( 240 * MS_PER_SECOND ) ///< Time period count for purge air time out. #define PRIME_SALINE_DIALYZER_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for prime saline dialyzer time out. #define LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ( 1 * MS_PER_SECOND ) ///< Time load cell reading steady state detection sampling time in seconds. #define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 15 * 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_TIME_DEADLINE_MS ( 55 * MS_PER_SECOND ) ///< Time in msec for the steady volume deadline time out. +#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. +#define BUBBLE_CLEAR_WAIT_TIME_MS ( 2 * MS_PER_SECOND ) ///< Time in msec to wait for bubble clear pressure. +#define BUBBLE_CLEAR_MAX_TIME_MS ( 10 * MS_PER_SECOND ) ///< Time in msec maximum for bubble clear pressure. +#define BUBBLE_CLEAR_VALVE_WAIT_TIME_MS ( 90 ) ///< Time in msec between VDi and VBT valve open + /// States of the treatment reservoir management state machine. typedef enum PrimeReservoirMgmt_States { @@ -76,6 +82,17 @@ NUM_OF_PRIME_RESERVOIR_MGMT_STATES ///< Number of prime reservoir mgmt. states. } PRIME_RESERVOIR_MGMT_STATE_T; +/// States of the prime dialyzer bubble clear state machine. +typedef enum PrimeSalineDialyzerBubbleClear_States +{ + PRIME_BUBBLE_CLEAR_READY_STATE = 0, ///< Bubble clear initial / ready state. + PRIME_BUBBLE_CLEAR_PRESSURE_STATE, ///< Bubble clear pressurized / active state. + PRIME_BUBBLE_CLEAR_VENT_STATE, ///< BUbble clear vent to reservoir state. + PRIME_BUBBLE_CLEAR_FLOW_STATE, ///< Bubble clear flow state. + PRIME_BUBBLE_CLEAR_COMPLETE_STATE, ///< Bubble clear complete. + NUM_OF_PRIME_BUBBLE_CLEAR_STATES ///< Number of bubble clear states. +} PRIME_BUBBLE_CLEAR_STATE_T; + typedef struct { U32 bloodVolume; ///< Blood volume of the dialyzer in mL. U32 dialysateVolume; ///< Dialysate volume of the dialyzer in mL. @@ -98,6 +115,7 @@ static HD_PRE_TREATMENT_PRIME_STATE_T currentPrimeState; ///< Current state of the prime sub-mode state machine. static HD_PRE_TREATMENT_PRIME_STATE_T previousPrimeState; ///< Previous state of the prime sub-mode, to use when resuming from pause. static PRIME_RESERVOIR_MGMT_STATE_T currentReservoirMgmtState; ///< Current reservoir management state. +static PRIME_BUBBLE_CLEAR_STATE_T primeDialyzerBubbleClearState;///< Priming saline dialyzer bubble clear state. static U32 primeStartTime; ///< Starting time of priming (in ms). static U32 primePauseStartTime; ///< Priming pause start time (in ms). @@ -110,6 +128,7 @@ static U32 noAirDetectedStartTime; ///< starting time when detecting no air. static U32 purgeAirTimeOutStartTime; ///< Starting time for purge air state time out. static U32 primeSalineDialyzerStartTime; ///< Starting time of priming saline dialyzer circuit. +static U32 primeSalineDialyzerBubbleClearStartTime; ///< Starting time of priming saline dialyzer bubble clear. static U32 primeDialysateDialyzerStartTime; ///< Starting time of priming dialysate dialyzer circuit. static U32 primeDialysateBypassStartTime; ///< Starting time of priming dialysate bypass circuit. static U32 steadyVolumeSamplingStartTime; ///< Load cell steady volume sampling interval starting time. @@ -166,6 +185,7 @@ { primeStartTime = getMSTimerCount(); primeFirstPurgePass = TRUE; + primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_READY_STATE; setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); @@ -478,7 +498,8 @@ * before start priming the saline dialyzer fluid path. * priming. * @details Inputs: primeStartReqReceived - * @details Outputs: control valves to purge air + * @details Outputs: control valves to purge air, primeDialyzerBubbleClearState, + * primeSalineDialyzerBubbleClearStartTime, purgeAirTimeOutStartTime * @return current state *************************************************************************/ static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineSetupState( void ) @@ -487,6 +508,8 @@ purgeAirValvesBloodPumpControl(); purgeAirTimeOutStartTime = getMSTimerCount(); + primeSalineDialyzerBubbleClearStartTime = getMSTimerCount(); + primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_READY_STATE; if ( TRUE == doesAlarmStatusIndicateStop() ) { @@ -499,6 +522,74 @@ /*********************************************************************//** * @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 * to blood circuit circulation state if fluid is detected at upper sensor. * @details Inputs: air trap levels, primeFirstPurgePass, purgeAirTimeOutStartTime @@ -515,6 +606,8 @@ SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_PRIME_SALINE_PURGE_AIR_TIME_OUT, PURGE_AIR_TIME_OUT_COUNT ); } + handlePrimeBubbleClear(); + if ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) { setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); @@ -529,6 +622,7 @@ // 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; }