Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r7960836f635257a147fc30524d37fc7dfa38e967 -rb5409fe2cdc66d0ee781d94ce33a33040e2edf41 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 7960836f635257a147fc30524d37fc7dfa38e967) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision b5409fe2cdc66d0ee781d94ce33a33040e2edf41) @@ -7,8 +7,8 @@ * * @file Reservoirs.c * -* @author (last) Sean Nash -* @date (last) 28-Mar-2023 +* @author (last) Dara Navaei +* @date (last) 12-Jul-2023 * * @author (original) Dara Navaei * @date (original) 21-Nov-2021 @@ -51,10 +51,7 @@ #define MAX_RESERVOIR_DEPLETION_TIME_MS ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Maximum allowed depletion time in milliseconds. #define RESERVOIR_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the reservoir data is published on the CAN bus. -#define DIALYSATE_FLOW_RATE_350_ML_PER_MIN 0.35F ///< Dialysate flow rate 350 mL/min. -#define DIALYSATE_FLOW_RATE_550_ML_PER_MIN 0.55F ///< Dialysate flow rate 550 mL/min. -#define TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN 0.5F ///< Target fill flow rate for dialysate flow rates in between 100 to 350 mL/min. -#define TGT_FILL_FLOW_FOR_DIA_FLOW_550_TO_600_ML_PER_MIN 0.8F ///< Target fill flow rate for dialysate flow rates in between 500 to 600 mL/min. +#define TGT_FILL_FLOW_800_ML_PER_MIN 0.8F ///< Target fill flow rate 800 mL/min. #define TGT_FILL_FLOW_ERROR_ALLOWANCE 0.9F ///< Target fill flow rate for dialysate allowed error percentage. #define DIA_FLOW_TO_FILL_FLOW_SECOND_ORDER_COEFF 10.0F ///< Dialysate flow rate to fill flow rate second order coefficient. @@ -109,6 +106,7 @@ static void calculateActiveReservoirCycleTime( void ); static F32 getReservoirRecirculationMaxPercent( void ); static void publishReservoirData( void ); +static BOOL isDialysateTempAlarmActive( void ); static TREATMENT_RESERVOIR_MGMT_STATE_T handleReservoirMgmtStartState( void ); static TREATMENT_RESERVOIR_MGMT_STATE_T handleReservoirMgmtDrainState( void ); @@ -144,7 +142,7 @@ timeReservoirInUF = 0; lastTimeReservoirInUF = 0; volSpentUFML = 0.0F; - activeReservoir = DG_RESERVOIR_1; + activeReservoir = getDGActiveReservoir(); recirculationLevelPct = 0.0F; reservoirSwitchStartTimeMS = 0; timeWaitToFillMS = 0; @@ -194,17 +192,10 @@ // Calculate volume used from active reservoir - do not accumulate if not performing dialysis or saline bolus is in progress if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) { -#ifdef DIALYZER_REPRIME_ENABLED - if ( getDialysisState() != DIALYSIS_DIALYZER_REPRIME_STATE ) - { -#endif - volSpentML += ( flowRateMLPerMS * msSinceLastVolumeCalc ); - timeReservoirInUse++; - // Check the recirculation level - recirculationLevelPct = volSpentML / (F32)FILL_RESERVOIR_TO_VOLUME_ML; -#ifdef DIALYZER_REPRIME_ENABLED - } -#endif + volSpentML += ( flowRateMLPerMS * msSinceLastVolumeCalc ); + timeReservoirInUse++; + // Check the recirculation level + recirculationLevelPct = volSpentML / (F32)FILL_RESERVOIR_TO_VOLUME_ML; } // Update the reservoir start time @@ -247,20 +238,6 @@ /*********************************************************************//** * @brief - * The setDialysateHeatingParams function is an API to call other internal - * functions to set the trimmer's heater target temperature and times that are - * required to calculated the heaters target temperature in DG. - * @details Inputs: none - * @details Outputs: none - * @return none - *************************************************************************/ -void setDialysateHeatingParams( void ) -{ - calculateActiveReservoirCycleTime(); -} - -/*********************************************************************//** - * @brief * The getLastReservoirUFTimeInMs function returns the reservoir ultrafiltration * time (in ms) for the last reservoir used in treatment. * @details Inputs: none @@ -316,27 +293,8 @@ *************************************************************************/ static F32 getTargetFillFlowRateLPM( void ) { - F32 fillFlowRate = 0.0; + F32 fillFlowRate = TGT_FILL_FLOW_800_ML_PER_MIN; - // Get the current dialysate flow rate set by the user and convert it L/min - F32 dialysateFlow = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) / ML_PER_LITER; - - if ( dialysateFlow <= DIALYSATE_FLOW_RATE_350_ML_PER_MIN ) - { - fillFlowRate = TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN; - } - else if ( dialysateFlow >= DIALYSATE_FLOW_RATE_550_ML_PER_MIN ) - { - fillFlowRate = TGT_FILL_FLOW_FOR_DIA_FLOW_550_TO_600_ML_PER_MIN; - } - else - { - // fill flow = linear interpolation between 350 MLP and 550MLP - fillFlowRate = TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN - + ( ( dialysateFlow - DIALYSATE_FLOW_RATE_350_ML_PER_MIN ) / (DIALYSATE_FLOW_RATE_550_ML_PER_MIN - DIALYSATE_FLOW_RATE_350_ML_PER_MIN ) ) - * ( TGT_FILL_FLOW_FOR_DIA_FLOW_550_TO_600_ML_PER_MIN - TGT_FILL_FLOW_FOR_DIA_FLOW_100_TO_350_ML_PER_MIN ); - } - targetFillFlowLPM = fillFlowRate; return fillFlowRate; @@ -442,25 +400,25 @@ static F32 getReservoirRecirculationMaxPercent( void ) { U32 targetDialysateFlowMLP = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); - F32 maxPercent = 0.0F; + F32 maxPercent = 0.0F; - if (RESERVOIR_FLOW_400_MLP >= targetDialysateFlowMLP) + if ( targetDialysateFlowMLP <= RESERVOIR_FLOW_400_MLP ) { maxPercent = MAX_RESERVOIR_RECIRCULATION_400_MLP; } - else if (RESERVOIR_FLOW_450_MLP >= targetDialysateFlowMLP) + else if ( targetDialysateFlowMLP <= RESERVOIR_FLOW_450_MLP ) { maxPercent = MAX_RESERVOIR_RECIRCULATION_450_MLP; } - else if (RESERVOIR_FLOW_500_MLP >= targetDialysateFlowMLP) + else if ( targetDialysateFlowMLP <= RESERVOIR_FLOW_500_MLP ) { maxPercent = MAX_RESERVOIR_RECIRCULATION_500_MLP; } - else if (RESERVOIR_FLOW_550_MLP >= targetDialysateFlowMLP) + else if ( targetDialysateFlowMLP <= RESERVOIR_FLOW_550_MLP ) { maxPercent = MAX_RESERVOIR_RECIRCULATION_550_MLP; } - else // if (RESERVOIR_FLOW_600_MLP >= targetDialysateFlowMLP) + else { maxPercent = MAX_RESERVOIR_RECIRCULATION_600_MLP; } @@ -573,6 +531,14 @@ cmdStartDGFill( FILL_RESERVOIR_TO_VOLUME_ML, targetFillFlowRateLPM ); } } + // If we have active dialysate temp alarms, we want to fill immediately. + else if ( TRUE == isDialysateTempAlarmActive() ) + { + if ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) + { + cmdStartDGFill( FILL_RESERVOIR_TO_VOLUME_ML, targetFillFlowRateLPM ); + } + } else { // Time to wait prior to next fill is depletion time - the whole group of how much time is needed to fill a reservoir + @@ -657,7 +623,7 @@ // Wait for the reservoir to settle and then send the commands to switch the active reservoir if ( ( TRUE == didTimeout( reservoirSwitchStartTimeMS, RESERVOIR_FRESH_SETTLE_TIME_MS ) ) && - ( ( dilutionLevelPct >= MAX_RESERVOIR_DILUTION ) || ( volSpentML >= (F32)FILL_RESERVOIR_TO_VOLUME_ML ) || ( getReservoirWeight( active ) > MAX_RESERVOIR_VOL_BEFORE_SWITCH_ML ) ) ) + ( ( dilutionLevelPct >= MAX_RESERVOIR_DILUTION ) || ( volSpentML >= (F32)FILL_RESERVOIR_TO_VOLUME_ML ) || ( getReservoirWeight( active ) > MAX_RESERVOIR_VOL_BEFORE_SWITCH_ML ) || ( TRUE == isDialysateTempAlarmActive() ) ) ) { DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; @@ -681,6 +647,7 @@ reservoirSwitchStartTimeMS = getMSTimerCount(); state = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_SWITCH_SETTLE_STATE; + } return state; @@ -715,4 +682,26 @@ return state; } +/*********************************************************************//** + * @brief + * The isDialysateTempAlarmActive function checks for active dialysate + * temperature alarms + * @details Inputs: none + * @details Outputs: none + * @return True if dialysate temperature alarm is active. False if not. + *************************************************************************/ +static BOOL isDialysateTempAlarmActive( void ) +{ + BOOL result = FALSE; + if ( ( TREATMENT_STOP_STATE == getTreatmentState() ) && + ( TRUE == isAlarmConditionDetected( ALARM_ID_HD_DIALYSATE_TEMP_BELOW_TARGET_TEMP ) || + TRUE == isAlarmConditionDetected( ALARM_ID_HD_DIALYSATE_TEMP_ABOVE_SAFETY_TEMP ) || + TRUE == isAlarmConditionDetected( ALARM_ID_HD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP ) ) ) + { + result = TRUE; + } + + return result; +} + /**@}*/