Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -rf46a432cf62183516e05aae835cc810cfc964caa -r1b1cb4654131c2663e48a3041719fe294bea2a4e --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision f46a432cf62183516e05aae835cc810cfc964caa) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 1b1cb4654131c2663e48a3041719fe294bea2a4e) @@ -52,23 +52,19 @@ #define MAX_ACTIVE_LOAD_CELL_CHANGE_G 50.0F ///< Maximum delta between new and previous measured UF volume. +#ifdef DIALYZER_REPRIME_ENABLED // Dialyzer reprime constants -static const U32 DIALYZER_REPRIME_INTERVAL = ((30 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); +static const U32 DIALYZER_REPRIME_INTERVAL = ((30 * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); /// Dialyzer reprime interval count. Time between reprime attempts. -static const U32 DIALYZER_REPRIME_BEFORE_TREATEMENT_END_INTERVAL = ((5 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); -/// Final dialyzer reprime interval count. Used to determine whether the final dialyzer reprime has been completed. -static const U32 DIALYZER_REPRIME_REPRIME_INTERVAL = ((40 * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); -/// Duration of reprime state interval count. How long to run the pumps to remove air from the dialyzer. -static const U32 DIALYZER_REPRIME_PURGE_PRIOR_1_INTERVAL = ((10 * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); -/// Duration of purge lines prior 1 state interval count. -static const U32 DIALYZER_REPRIME_PURGE_PRIOR_2_INTERVAL = ((6 * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); -/// Duration of purge lines prior 2 interval count. -static const U32 DIALYZER_REPRIME_PURGE_LINES_INTERVAL = ((10 * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); -/// Duration of purge lines state interval count. -#define DIALYZER_REPRIME_BEFORE_TREATEMENT_END_INTERVAL_SEC 300 ///< Time before end of treatment to perform final dialyzer reprime, sec. -#define DP_FAST_PURGE_FLOW_RATE_ML_MIN 500.0F ///< Dialysate pump speed for purging air in dialyzer reprime states, ml/min. -#define DPI_REPRIME_FLOW_RATE_ML_MIN 64.0F ///< Inlet dialysate pump speed for repriming in dialyzer reprime states, ml/min. -#define DPO_REPRIME_FLOW_RATE_ML_MIN 60.0F ///< Outlet dialysate pump speed for repriming in dialyzer reprime states, ml/min. +#define DIALYZER_REPRIME_REPRIME_DURATION_MS ( 40 * MS_PER_SECOND ) ///< Duration of dialyzer reprime reprime state. +#define DIALYZER_REPRIME_PURGE_PRIOR_1_DURATION_MS ( 10 * MS_PER_SECOND ) ///< Duration of dialyzer reprime purge prior 1 state. +#define DIALYZER_REPRIME_PURGE_PRIOR_2_DURATION_MS ( 6 * MS_PER_SECOND ) ///< Duration of dialyzer reprime purge prior 2 state. +#define DIALYZER_REPRIME_PURGE_LINES_DURATION_MS ( 10 * MS_PER_SECOND ) ///< Duration of dialyzer reprime purge prior 2 state. +#define DIALYZER_REPRIME_BEFORE_TREATEMENT_END_INTERVAL_SEC 300 ///< Time before end of treatment to perform final dialyzer reprime, sec. +#define DP_FAST_PURGE_FLOW_RATE_ML_MIN 500.0F ///< Dialysate pump speed for purging air in dialyzer reprime states, ml/min. +#define DPI_REPRIME_FLOW_RATE_ML_MIN 64.0F ///< Inlet dialysate pump speed for repriming in dialyzer reprime states, ml/min. +#define DPO_REPRIME_FLOW_RATE_ML_MIN 60.0F ///< Outlet dialysate pump speed for repriming in dialyzer reprime states, ml/min. +#endif /// Defined states for the Load Cell cycles. typedef enum Reservoir_Steady_Cycle @@ -83,7 +79,9 @@ static DIALYSIS_STATE_T currentDialysisState; ///< Current state of the dialysis sub-mode state machine. static UF_STATE_T currentUFState; ///< Current state of the ultrafiltration state machine. static SALINE_BOLUS_STATE_T currentSalineBolusState; ///< Current state of the saline bolus state machine. +#ifdef DIALYZER_REPRIME_ENABLED static DIALYZER_REPRIME_STATE_T currentDialyzerReprimeState; ///< Current state of the dialyzer reprime state machine. +#endif static F32 refUFVolume; ///< Current reference volume for ultrafiltration (Where should we be w/r/t ultrafiltration). static F32 measUFVolume; ///< Current total measured volume for ultrafiltration (Where are we w/r/t ultrafiltration). @@ -114,15 +112,20 @@ static U32 uFAccuracyCheckTimerCtr; ///< Timer counter to determine when next to check ultrafiltration accuracy. static F32 lastUFVolumeChecked; ///< Starting ultrafiltration volume for accuracy check. +#ifdef DIALYZER_REPRIME_ENABLED static U32 dialyzerReprimeIntervalTimerCtr; ///< Timer counter to determine when the dialyzer reprime should be done. static BOOL dialyzerReprimeInProgress; ///< Flag indicates whether the dialyzer reprime has been interrupted. -static U32 dialyzerReprimeTimerCtr; ///< General timer counter for delays in dialyzer reprime functions. +static BOOL dialyzerReprimeFinalReprimeFinished; ///< Flag indicates whether the final dialyzer reprime has completed. +static U32 dialyzerReprimeStateTimer; ///< General state timer for delays in dialyzer reprime functions. +#endif // ********** private function prototypes ********** static DIALYSIS_STATE_T handleDialysisUltrafiltrationState( void ); static DIALYSIS_STATE_T handleDialysisSalineBolusState( void ); +#ifdef DIALYZER_REPRIME_ENABLED static DIALYSIS_STATE_T handleDialysisDialyzerReprimeState( void ); +#endif static UF_STATE_T handleUFStartState( DIALYSIS_STATE_T *dialysisState ); static UF_STATE_T handleUFPausedState( DIALYSIS_STATE_T *dialysisState ); @@ -133,11 +136,14 @@ static SALINE_BOLUS_STATE_T handleSalineBolusInProgressState( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusMaxDeliveredState( DIALYSIS_STATE_T *dialysisState ); -static DIALYZER_REPRIME_STATE_T handleDialysatePumpsOffState( DIALYSIS_STATE_T *dialysisState ); -static DIALYZER_REPRIME_STATE_T handlePurgePrior1State( DIALYSIS_STATE_T *dialysisState ); -static DIALYZER_REPRIME_STATE_T handlePurgePrior2State( DIALYSIS_STATE_T *dialysisState ); -static DIALYZER_REPRIME_STATE_T handleRePrimeState( DIALYSIS_STATE_T *dialysisState ); -static DIALYZER_REPRIME_STATE_T handlePurgeLinesState( DIALYSIS_STATE_T *dialysisState ); +#ifdef DIALYZER_REPRIME_ENABLED +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimeDialysatePumpsOffState( DIALYSIS_STATE_T *dialysisState ); +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimePurgePrior1State( DIALYSIS_STATE_T *dialysisState ); +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimePurgePrior2State( DIALYSIS_STATE_T *dialysisState ); +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimeRePrimeState( DIALYSIS_STATE_T *dialysisState ); +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimePurgeLinesState( DIALYSIS_STATE_T *dialysisState ); +static void initDialyzerReprime( void ); +#endif static void checkUFAccuracyAndVolume( void ); static void updateUFVolumes( void ); @@ -184,10 +190,11 @@ uFAccuracyCheckTimerCtr = 0; lastUFVolumeChecked = 0.0; +#ifdef DIALYZER_REPRIME_ENABLED dialyzerReprimeIntervalTimerCtr = 0; dialyzerReprimeInProgress = FALSE; - dialyzerReprimeTimerCtr = 0; - currentDialyzerReprimeState = DIALYZER_REPRIME_STATE_DIALYSATE_PUMPS_OFF; + dialyzerReprimeFinalReprimeFinished = FALSE; +#endif for ( i = 0; i < NUM_OF_LOAD_CELLS; i++ ) { @@ -419,6 +426,12 @@ { rejReason = REQUEST_REJECT_REASON_SALINE_BOLUS_IN_PROGRESS; } +#ifdef DIALYZER_REPRIME_ENABLED + else if ( currentDialysisState == DIALYSIS_DIALYZER_REPRIME_STATE ) + { + rejReason = REQUEST_REJECT_REASON_DIALYZER_REPRIME_IN_PROGRESS; + } +#endif else { accept = TRUE; @@ -660,17 +673,6 @@ // Check ultrafiltration max rate and accuracy during dialysis (even when ultrafiltration is paused). checkUFAccuracyAndVolume(); - // Check whether it is time for dialyzer reprime - // Either a fixed interval or some interval before treatment end. - if ( ( ++dialyzerReprimeIntervalTimerCtr >= DIALYZER_REPRIME_INTERVAL) || - ( ( dialyzerReprimeIntervalTimerCtr > DIALYZER_REPRIME_BEFORE_TREATEMENT_END_INTERVAL ) && - ( getTreatmentTimeRemainingSecs() <= DIALYZER_REPRIME_BEFORE_TREATEMENT_END_INTERVAL_SEC) - ) - ) - { - currentDialysisState = DIALYSIS_DIALYZER_REPRIME_STATE; - } - // Dialysis state machine switch ( currentDialysisState ) { @@ -681,11 +683,11 @@ case DIALYSIS_SALINE_BOLUS_STATE: currentDialysisState = handleDialysisSalineBolusState(); break; - +#ifdef DIALYZER_REPRIME_ENABLED case DIALYSIS_DIALYZER_REPRIME_STATE: currentDialysisState = handleDialysisDialyzerReprimeState(); break; - +#endif default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIALYSIS_INVALID_STATE, currentDialysisState ) break; @@ -724,6 +726,20 @@ setHeparinCompleted(); } +#ifdef DIALYZER_REPRIME_ENABLED + // Check whether it is time for dialyzer reprime + // Either a fixed interval or some interval before treatment end. + if ( ( ++dialyzerReprimeIntervalTimerCtr >= DIALYZER_REPRIME_INTERVAL) || + ( ( FALSE == dialyzerReprimeFinalReprimeFinished ) && + ( getTreatmentTimeRemainingSecs() <= DIALYZER_REPRIME_BEFORE_TREATEMENT_END_INTERVAL_SEC) + ) + ) + { + initDialyzerReprime(); + currentDialysisState = DIALYSIS_DIALYZER_REPRIME_STATE; + } +#endif + // Handle current ultrafiltration state switch ( currentUFState ) { @@ -795,6 +811,7 @@ return result; } +#ifdef DIALYZER_REPRIME_ENABLED /*********************************************************************//** * @brief * The handleDialysisDialyzerReprimeState function handles the dialyzer reprime @@ -811,23 +828,23 @@ switch ( currentDialyzerReprimeState ) { case DIALYZER_REPRIME_STATE_DIALYSATE_PUMPS_OFF: - currentDialyzerReprimeState = handleDialysatePumpsOffState( &result ); + currentDialyzerReprimeState = handleDialyzerReprimeDialysatePumpsOffState( &result ); break; case DIALYZER_REPRIME_STATE_PURGE_PRIOR_1: - currentDialyzerReprimeState = handlePurgePrior1State( &result ); + currentDialyzerReprimeState = handleDialyzerReprimePurgePrior1State( &result ); break; case DIALYZER_REPRIME_STATE_PURGE_PRIOR_2: - currentDialyzerReprimeState = handlePurgePrior2State( &result ); + currentDialyzerReprimeState = handleDialyzerReprimePurgePrior2State( &result ); break; case DIALYZER_REPRIME_STATE_REPRIME: - currentDialyzerReprimeState = handleRePrimeState( &result ); + currentDialyzerReprimeState = handleDialyzerReprimeRePrimeState( &result ); break; case DIALYZER_REPRIME_STATE_PURGE_LINES: - currentDialyzerReprimeState = handlePurgeLinesState( &result ); + currentDialyzerReprimeState = handleDialyzerReprimePurgeLinesState( &result ); break; default: @@ -843,6 +860,7 @@ return result; } +#endif /*********************************************************************//** * @brief @@ -1106,19 +1124,35 @@ return result; } +#ifdef DIALYZER_REPRIME_ENABLED /*********************************************************************//** * @brief + * The initDialyzerReprimeState function performs the steps to initiate + * the dialyzer reprime task. + * @details Inputs: + * @details Outputs: currentDialyzerReprimeState + * @return none. + *************************************************************************/ +static void initDialyzerReprime( void ) +{ + // Give commands to stop pumps + setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + currentDialyzerReprimeState = DIALYZER_REPRIME_STATE_DIALYSATE_PUMPS_OFF; +} + +/*********************************************************************//** + * @brief * The handleDialysatePumpsOffState function handles the dialysate pumps off state of the * dialyzer reprime state machine. * @details Inputs: isDialInPumpRunning(), isDialOutPumpRunning(), dialyzerReprimeInProgress flag * @details Outputs: next dialyzer reprime state, dialyzerReprimeTimerCtr, dialyzerReprimeInProgress flag * @param dialysis state * @return next dialyzer reprime state *************************************************************************/ -static DIALYZER_REPRIME_STATE_T handleDialysatePumpsOffState( DIALYSIS_STATE_T *dialysisState ) +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimeDialysatePumpsOffState( DIALYSIS_STATE_T *dialysisState ) { DIALYZER_REPRIME_STATE_T result = DIALYZER_REPRIME_STATE_DIALYSATE_PUMPS_OFF; - static BOOL pumpsCmdOff = FALSE; if ( ( FALSE == isDialInPumpRunning() ) && ( FALSE == isDialOutPumpRunning() ) ) { @@ -1128,7 +1162,6 @@ setDialInPumpTargetFlowRate( DP_FAST_PURGE_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - dialyzerReprimeTimerCtr = 0; result = DIALYZER_REPRIME_STATE_PURGE_PRIOR_1; } else @@ -1138,18 +1171,11 @@ setValvePosition( VDO, VALVE_POSITION_B_OPEN ); setDialInPumpTargetFlowRate ( DPI_REPRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_REVERSE, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialOutPumpTargetRate( DPO_REPRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_REVERSE, PUMP_CONTROL_MODE_OPEN_LOOP ); - dialyzerReprimeTimerCtr = 0; dialyzerReprimeInProgress = TRUE; result = DIALYZER_REPRIME_STATE_REPRIME; } + dialyzerReprimeStateTimer = getMSTimerCount(); } - else if ( FALSE == pumpsCmdOff ) - { - // Give commands to stop pumps - setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - pumpsCmdOff = TRUE; - } return result; } @@ -1163,16 +1189,20 @@ * @param dialysis state * @return next dialyzer reprime state *************************************************************************/ -static DIALYZER_REPRIME_STATE_T handlePurgePrior1State( DIALYSIS_STATE_T *dialysisState ) +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimePurgePrior1State( DIALYSIS_STATE_T *dialysisState ) { DIALYZER_REPRIME_STATE_T result = DIALYZER_REPRIME_STATE_PURGE_PRIOR_1; - if ( ++dialyzerReprimeTimerCtr >= DIALYZER_REPRIME_PURGE_PRIOR_1_INTERVAL ) + if ( ( TRUE == didTimeout( dialyzerReprimeStateTimer, DIALYZER_REPRIME_PURGE_PRIOR_1_DURATION_MS ) ) ) { + // Stop the dialysate in pump before opening valves + signalDialInPumpHardStop(); setValvePosition( VDI, VALVE_POSITION_B_OPEN ); setValvePosition( VDO, VALVE_POSITION_B_OPEN ); + // Start the two dialysate pumps together. + setDialInPumpTargetFlowRate( DP_FAST_PURGE_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialOutPumpTargetRate( DP_FAST_PURGE_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - dialyzerReprimeTimerCtr = 0; + dialyzerReprimeStateTimer = getMSTimerCount(); result = DIALYZER_REPRIME_STATE_PURGE_PRIOR_2; } @@ -1188,15 +1218,21 @@ * @param dialysis state * @return next dialyzer reprime state state *************************************************************************/ -static DIALYZER_REPRIME_STATE_T handlePurgePrior2State( DIALYSIS_STATE_T *dialysisState ) +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimePurgePrior2State( DIALYSIS_STATE_T *dialysisState ) { DIALYZER_REPRIME_STATE_T result = DIALYZER_REPRIME_STATE_PURGE_PRIOR_2; - if ( ++dialyzerReprimeTimerCtr >= DIALYZER_REPRIME_PURGE_PRIOR_2_INTERVAL ) + if ( ( TRUE == didTimeout( dialyzerReprimeStateTimer, DIALYZER_REPRIME_PURGE_PRIOR_2_DURATION_MS ) ) ) { + // ramp down the pumps to zero before turning them on in reverse + setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + } + if ( ( FALSE == isDialInPumpRunning() ) && ( FALSE == isDialOutPumpRunning() ) ) + { setDialInPumpTargetFlowRate( DPI_REPRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_REVERSE, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialOutPumpTargetRate( DPO_REPRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_REVERSE, PUMP_CONTROL_MODE_OPEN_LOOP ); - dialyzerReprimeTimerCtr = 0; + dialyzerReprimeStateTimer = getMSTimerCount(); result = DIALYZER_REPRIME_STATE_REPRIME; } @@ -1212,17 +1248,17 @@ * @param dialysis state * @return next dialyzer reprime state *************************************************************************/ -static DIALYZER_REPRIME_STATE_T handleRePrimeState( DIALYSIS_STATE_T *dialysisState ) +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimeRePrimeState( DIALYSIS_STATE_T *dialysisState ) { DIALYZER_REPRIME_STATE_T result = DIALYZER_REPRIME_STATE_REPRIME; - if ( ++dialyzerReprimeTimerCtr >= DIALYZER_REPRIME_REPRIME_INTERVAL ) + if ( ( TRUE == didTimeout( dialyzerReprimeStateTimer, DIALYZER_REPRIME_REPRIME_DURATION_MS ) ) ) { setDialInPumpTargetFlowRate( DP_FAST_PURGE_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); signalDialOutPumpHardStop(); - dialyzerReprimeTimerCtr = 0; + dialyzerReprimeStateTimer = getMSTimerCount(); result = DIALYZER_REPRIME_STATE_PURGE_LINES; } @@ -1239,20 +1275,21 @@ * @param dialysis state * @return next dialyzer reprime state *************************************************************************/ -static DIALYZER_REPRIME_STATE_T handlePurgeLinesState( DIALYSIS_STATE_T *dialysisState ) +static DIALYZER_REPRIME_STATE_T handleDialyzerReprimePurgeLinesState( DIALYSIS_STATE_T *dialysisState ) { DIALYZER_REPRIME_STATE_T result = DIALYZER_REPRIME_STATE_PURGE_LINES; - if ( ++dialyzerReprimeTimerCtr >= DIALYZER_REPRIME_PURGE_LINES_INTERVAL ) + if ( ( TRUE == didTimeout( dialyzerReprimeStateTimer, DIALYZER_REPRIME_PURGE_LINES_DURATION_MS ) ) ) { setValvePosition( VDI, VALVE_POSITION_B_OPEN ); setValvePosition( VDO, VALVE_POSITION_B_OPEN ); signalDialInPumpHardStop(); // Reset the timer for reprime interval and the reprime in progress flag. dialyzerReprimeInProgress = FALSE; - dialyzerReprimeTimerCtr = 0; - dialyzerReprimeIntervalTimerCtr = 0; - currentDialyzerReprimeState = DIALYZER_REPRIME_STATE_DIALYSATE_PUMPS_OFF; + if ( getTreatmentTimeRemainingSecs() <= DIALYZER_REPRIME_BEFORE_TREATEMENT_END_INTERVAL_SEC) + { + dialyzerReprimeFinalReprimeFinished = TRUE; + } // Dialysis back to UF state *dialysisState = DIALYSIS_UF_STATE; // Resume dialysis @@ -1262,6 +1299,7 @@ return result; } +#endif /*********************************************************************//** * @brief