Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r09e6cf9de34acf18f6e1138bf56ac0edb4821186 -r99ba9313f98289563f96a0972a0a4c11e61406f5 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 09e6cf9de34acf18f6e1138bf56ac0edb4821186) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 99ba9313f98289563f96a0972a0a4c11e61406f5) @@ -40,17 +40,21 @@ #define BLOOD_PUMP_FAST_FLOW_RATE_PURGE_AIR_ML_MIN 400 ///< 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_SALINE_FLOW_RATE_PURGE_AIR_ML_MIN 100 ///< Blood pump very slow flow rate during prime saline dialyzer state #define BLOOD_PUMP_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 300 ///< Blood pump flow rate during prime recirculate blood circuit state. #define DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN 300 ///< Dialysate pump flow rate during priming fluid path. #define LOAD_CELL_VOLUME_NOISE_TOLERANCE 0.05 ///< Allow 5% tolerance on load cell readings. +#define LOAD_CELL_VOLUME_SALINE_READING 10.0 ///< Load cell readings of 10 grams ( 10 mL ) #define NO_AIR_DETECTED_COUNT ( 20 * MS_PER_SECOND ) ///< No air detected time period count. #define PURGE_AIR_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for purge air time out. #define MIN_LOAD_CELL_STEADY_VOLUME_TIME ( 10 * MS_PER_SECOND ) ///< Minimum time load cell reading need to remain steady in ms. #define PRIME_DIALYSATE_DIALYZER_TIME_LIMIT ( 120 * MS_PER_SECOND ) ///< Time limit for priming dialysate dialyzer circuit. #define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 120 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. +#define PRIME_SALINE_DIALYZER_TIME_LIMIT ( 300 * MS_PER_SECOND ) ///< Five minutes time limit for priming saline dialyzer path. + /// States of the treatment reservoir management state machine. typedef enum PrimeReservoirMgmt_States { @@ -81,9 +85,11 @@ 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 primeDialysateDialyzerStartTime; ///< Starting time of priming dialysate dialyzer circuit. static U32 primeDialysateBypassStartTime; ///< Starting time of priming dialysate bypass circuit. static U32 previousLoadCellReading; ///< Previous load cell reading. +static U32 initialLoadCellReading; ///< Initial load cell reading. static U32 loadcellSteadyVolumeStartTime; ///< Load cell steady volume starting time. static BOOL runBloodCircuitPrimeAgain; ///< Flag indicates HD should run blood circuit prime once more time. @@ -92,9 +98,12 @@ static void resetPrimeFlags(); static void setupForPrimePause( void ); static void broadcastPrimingStatus( void ); +static void purgeAirDialyserBloodPumpControl( void ); static void purgeAirValvesBloodPumpControl( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeWaitForUserStartState( void ); +static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineDialyzerSetupState( void ); +static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineDialyzerState( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineSetupState( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimePurgeAirState( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeCircBloodCircuitState( void ); @@ -167,6 +176,14 @@ currentPrimeState = handlePrimeWaitForUserStartState(); break; + case HD_PRIME_SALINE_DIALYZER_SETUP_STATE: + currentPrimeState = handlePrimeSalineDialyzerSetupState(); + break; + + case HD_PRIME_SALINE_DIALYZER_STATE: + currentPrimeState = handlePrimeSalineDialyzerState(); + break; + case HD_PRIME_SALINE_SETUP_STATE: currentPrimeState = handlePrimeSalineSetupState(); break; @@ -326,6 +343,27 @@ /*********************************************************************//** * @brief + * The purgeAirDialyserBloodPumpControl function controls valves and blood pump + * to purge air by priming the saline dialyzer fluid path. + * @details Inputs: none + * @details Outputs: run blood pump, close VDI, VDO, VBA and VBV valves, open VBT valve + * @return current state (sub-mode) + *************************************************************************/ +static void purgeAirDialyserBloodPumpControl( void ) +{ + setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); + setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); + setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); + setValveAirTrap( STATE_OPEN ); + + signalDialOutPumpHardStop(); + signalDialInPumpHardStop(); + setBloodPumpTargetFlowRate( BLOOD_PUMP_SALINE_FLOW_RATE_PURGE_AIR_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); +} + +/*********************************************************************//** + * @brief * The purgeAirValvesBloodPumpControl function controls valves and blood pump * to purge air. * @details Inputs: none @@ -366,9 +404,72 @@ if ( TRUE == primeStartRequested ) { primeStartRequested = FALSE; + state = HD_PRIME_SALINE_DIALYZER_SETUP_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handlePrimeSalineDialyzerSetupState function implements the setup + * prior to transition to the prime the saline dialyzer state. + * @details Inputs: primeStartReqReceived + * @details Outputs: control valves to purge air + * @return current state + *************************************************************************/ +static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineDialyzerSetupState( void ) +{ + HD_PRE_TREATMENT_PRIME_STATE_T state = HD_PRIME_SALINE_DIALYZER_STATE; + + initialLoadCellReading = getLoadCellWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + primeSalineDialyzerStartTime = getMSTimerCount(); + purgeAirDialyserBloodPumpControl(); + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + setupForPrimePause(); + state = HD_PRIME_PAUSE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handlePrimeSalineDialyzerState function handles priming for saline + * dialyzer fluid path. + * @details Inputs: reservoir 2 filtered weight + * @details Outputs: primed saline dialyzer fluid path + * @return current state + *************************************************************************/ +static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineDialyzerState( void ) +{ + HD_PRE_TREATMENT_PRIME_STATE_T state = HD_PRIME_SALINE_DIALYZER_STATE; + + F32 const loadcellWeight = getLoadCellWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + + if ( (loadcellWeight - initialLoadCellReading) > LOAD_CELL_VOLUME_SALINE_READING ) + { state = HD_PRIME_SALINE_SETUP_STATE; } + else + { + primeSalineDialyzerStartTime = getMSTimerCount(); + } + if ( TRUE == didTimeout( primeSalineDialyzerStartTime, PRIME_SALINE_DIALYZER_TIME_LIMIT ) ) + { + // SET_ALARM_WITH_1_U32_DATA( ALARM_ID_PRIME_SALINE_DIALYZER_TIME_OUT, PRIME_SALINE_DIALYZER_TIME_LIMIT ); TODO + // if timeout occurs, what state should we go to? + } + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + setupForPrimePause(); + state = HD_PRIME_PAUSE; + } + return state; } @@ -536,6 +637,7 @@ HD_PRE_TREATMENT_PRIME_STATE_T state = HD_PRIME_DIALYSATE_DIALYZER_STATE; F32 const loadcellWeight = getLoadCellWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); + F32 const weightChange = fabs( 1.0 - ( previousLoadCellReading / loadcellWeight ) ); if ( weightChange < LOAD_CELL_VOLUME_NOISE_TOLERANCE )