Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r0a4dcd288d4347b85baaa0b07da568b6add5eac7 -r7e9399f3213138f1116ccef1df63d00dc2635531 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 0a4dcd288d4347b85baaa0b07da568b6add5eac7) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 7e9399f3213138f1116ccef1df63d00dc2635531) @@ -7,8 +7,8 @@ * * @file Prime.c * -* @author (last) Dara Navaei -* @date (last) 22-Dec-2022 +* @author (last) Sean Nash +* @date (last) 02-Feb-2023 * * @author (original) Quang Nguyen * @date (original) 08-Dec-2020 @@ -46,6 +46,7 @@ #define BLOOD_PUMP_FAST_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 300 ///< Blood pump fast flow rate during prime recirculate blood circuit state. #define BLOOD_PUMP_FLOW_RATE_SALINE_DIALYZER_ML_MIN 300 ///< Blood pump flow rate during prime the saline dialyzer dialysate state. #define DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN 300 ///< Dialysate pump flow rate during priming fluid path. +#define DIALYSATE_PUMP_FAST_PRIME_FLOW_RATE_ML_MIN 600 ///< Dialysate pump flow rate during priming fluid path. #define DPO_PUMP_PRIME_FLOW_RATE_ML_MIN 225 ///< Dialysate outlet pump flow rate needed to match PWM with dialysate inlet pump @ 300 mL/min in open loop mode. #define DIALYSATE_DIALYZER_TUBE_VOLUME_ML 115 ///< This total tube volume is used to calculate the Dpi & Dpo time out in the dialysate dialyzer state. @@ -57,7 +58,7 @@ #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 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_TIME_DEADLINE_MS ( 55 * MS_PER_SECOND ) ///< Time in msec for the steady volume deadline time out. @@ -165,12 +166,11 @@ *************************************************************************/ void initPrime( void ) { - currentPrimeState = HD_PRIME_START_STATE; + currentPrimeState = HD_PRIME_WAIT_FOR_USER_START_STATE; currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_START_STATE; primeStartTime = 0; primePauseStartTime = 0; primeStatusBroadcastTimerCounter = 0; - } /*********************************************************************//** @@ -198,6 +198,12 @@ signalDialInPumpHardStop(); signalDialOutPumpHardStop(); stopSyringePump(); +#ifndef _RELEASE_ + if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) +#endif + { + setAirPumpState( AIR_PUMP_STATE_OFF ); + } // Set valves to default positions setValveAirTrap( STATE_CLOSED ); @@ -218,22 +224,11 @@ *************************************************************************/ void execPrime( void ) { + HD_PRE_TREATMENT_PRIME_STATE_T priorSubState = currentPrimeState; + // execute prime sub-mode state machine switch ( currentPrimeState ) { - case HD_PRIME_START_STATE: -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) - { - currentPrimeState = HD_PRIME_RESERVOIR_ONE_FILL_COMPLETE_STATE; - } - else -#endif - { - currentPrimeState = HD_PRIME_WAIT_FOR_USER_START_STATE; - } - break; - case HD_PRIME_WAIT_FOR_USER_START_STATE: currentPrimeState = handlePrimeWaitForUserStartState(); break; @@ -278,13 +273,14 @@ currentPrimeState = handlePrimeWetSelfTestsState(); break; - case HD_PRIME_COMPLETE: - break; - case HD_PRIME_PAUSE: currentPrimeState = handlePrimePause(); break; + case HD_PRIME_COMPLETE: + // ok, do nothing here. pre-treatment will move on to recirculate once we get here. + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TREATMENT_PRIME_INVALID_STATE, currentReservoirMgmtState ); break; @@ -293,6 +289,11 @@ // Prime flags should be handled by now resetPrimeFlags(); + if ( priorSubState != currentPrimeState ) + { + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentPrimeState ); + } + // Broadcast priming data broadcastPrimingStatus(); } @@ -397,9 +398,12 @@ *************************************************************************/ static void setupForPrimePause( void ) { + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); signalDialOutPumpHardStop(); signalDialInPumpHardStop(); signalBloodPumpHardStop(); + stopSyringePump(); primePauseStartTime = getMSTimerCount(); previousPrimeState = currentPrimeState; @@ -483,6 +487,14 @@ } #endif +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) + { + state = HD_PRIME_RESERVOIR_ONE_FILL_COMPLETE_STATE; + } + else +#endif + if ( TRUE == primeStartRequested ) { primeStartRequested = FALSE; @@ -562,7 +574,7 @@ 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 ) ) ) + ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, BUBBLE_CLEAR_MAX_TIME_MS ) ) ) { // Pressure max reached. or timeout, release pressure setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); @@ -571,7 +583,7 @@ primeDialyzerBubbleClearState = PRIME_BUBBLE_CLEAR_VENT_STATE; } else if ( ( TRUE == bubble_clear_ended ) && - ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, BUBBLE_CLEAR_VALVE_WAIT_TIME_MS ) ) ) + ( TRUE == didTimeout( primeSalineDialyzerBubbleClearStartTime, BUBBLE_CLEAR_VALVE_WAIT_TIME_MS ) ) ) { setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValveAirTrap( STATE_OPEN ); @@ -684,12 +696,7 @@ if ( TRUE == getReservoirFillStatus( DG_RESERVOIR_1 ) ) { - DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; - - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; - rsrvrCmd.useLastTrimmerHeaterDC = FALSE; - - if ( TRUE == hasDGCompletedReservoirSwitch() ) + if ( ( TRUE == hasDGCompletedReservoirSwitch() ) && ( DG_RESERVOIR_1 == getDGActiveReservoir() ) ) { U32 dialyzerDialysateVolume = getDialyzerDialysateVolume(); @@ -746,9 +753,9 @@ { HD_PRE_TREATMENT_PRIME_STATE_T state = HD_PRIME_DIALYSATE_DIALYZER_STATE; + // Draw dialysate from reservoir for fixed time (calculated in prior state), then start looking for reservoir volume to steady state (indicating we have primed the line) if ( TRUE == didTimeout( primeDialysateDialyzerStartTime, primeDialysateDialyzerTimeLimit ) ) { - // check for volume steady state every second after the DVi and DVo pumps have been on for primeDialysateDialyzerTimeLimit seconds if ( TRUE == didTimeout( steadyVolumeSamplingStartTime, LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ) ) { F32 const currentReservoirVolume = getLoadCellWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); @@ -835,6 +842,7 @@ { HD_PRE_TREATMENT_PRIME_STATE_T state = HD_PRIME_SALINE_DIALYZER_STATE; + // Wait fixed time (based on calc done in prior state) and then move on to 2nd transfer check if ( TRUE == didTimeout( primeSalineDialyzerStartTime, primeSalineDialyzerTimeLimit ) ) { state = HD_PRIME_RESERVOIR_TWO_FILL_COMPLETE_STATE; @@ -858,7 +866,7 @@ * @brief * The handlePrimeReservoirTwoFillCompleteState function waits for DG to finish * filling reservoir 2 before moving to pre-treatment re-circulation. - * @details Inputs: reservoirFilledStatus[] + * @details Inputs: none * @details Outputs: update valves and pumps configuration on state change * @return current state *************************************************************************/ @@ -868,17 +876,10 @@ if ( TRUE == getReservoirFillStatus( DG_RESERVOIR_2 ) ) { - DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; - - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; - rsrvrCmd.useLastTrimmerHeaterDC = FALSE; - - cmdSetDGActiveReservoir( &rsrvrCmd ); - - if ( TRUE == hasDGCompletedReservoirSwitch() ) + if ( ( TRUE == hasDGCompletedReservoirSwitch() ) && ( DG_RESERVOIR_2 == getDGActiveReservoir() ) ) { signalBloodPumpHardStop(); - setDialInPumpTargetFlowRate( DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( DIALYSATE_PUMP_FAST_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); @@ -981,8 +982,7 @@ { state = HD_PRIME_COMPLETE; } - - if ( TRUE == doesAlarmStatusIndicateStop() ) + else if ( TRUE == doesAlarmStatusIndicateStop() ) { setupForPrimePause(); state = HD_PRIME_PAUSE; @@ -1009,6 +1009,10 @@ switch ( previousPrimeState ) { + case HD_PRIME_WAIT_FOR_USER_START_STATE: + state = HD_PRIME_WAIT_FOR_USER_START_STATE; + break; + case HD_PRIME_SALINE_SETUP_STATE: case HD_PRIME_SALINE_PURGE_AIR_STATE: case HD_PRIME_SALINE_CIRC_BLOOD_CIRCUIT_STATE: