Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r9aa7ae70106b8c96224cb541d24125215d85237e -r25466a692dfcc7c43413940268f69583614513c3 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 9aa7ae70106b8c96224cb541d24125215d85237e) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 25466a692dfcc7c43413940268f69583614513c3) @@ -94,7 +94,7 @@ static U32 previousDialysateFlowMLP; ///< Previous dialysate flow rate in mL/min. static F32 previousUFFlowMLP; ///< Previous ultrafiltration flow rate in mL/min. static DG_MIXING_RATIOS_T ratios; ///< Mixing ratios and fill prep time in milliseconds structure. -static U32 prevTargetFillVolumeML; ///< Previous target fill volume in milliliters. +static U32 prevTargetFillVolumeML[ NUM_OF_DG_RESERVOIRS ]; ///< Previous target fill volume in milliliters. static const F32 RESERVOIR_DILUTION_RATIO = MAX_RESERVOIR_DILUTION / ( 1.0 - MAX_RESERVOIR_DILUTION ); ///< Reservoir dilution ratio. @@ -154,7 +154,9 @@ ratios.acidMixingRatio = 0.0F; ratios.bicarbMixingRatio = 0.0F; ratios.timeFillPrepMS = 0; - prevTargetFillVolumeML = 0; + + // set the previous target fill volume array + memset( prevTargetFillVolumeML, 0x0, NUM_OF_DG_RESERVOIRS ); } /*********************************************************************//** @@ -174,8 +176,9 @@ * @brief * The execReservoirs function executes the state machine for the treatment * reservoir management during treatment mode. - * @details Inputs: reservoirsState - * @details Outputs: reservoirsState, timeReservoirInUse, volSpentML, recirculationLevelPct + * @details Inputs: reservoirsState, prevTargetFillVolumeML + * @details Outputs: reservoirsState, timeReservoirInUse, volSpentML, + * recirculationLevelPct * @return none *************************************************************************/ void execReservoirs( void ) @@ -198,7 +201,7 @@ volSpentML += ( flowRateMLPerMS * msSinceLastVolumeCalc ); timeReservoirInUse++; // Check the recirculation level - recirculationLevelPct = volSpentML / (F32)prevTargetFillVolumeML; + recirculationLevelPct = volSpentML / (F32)prevTargetFillVolumeML[ getDGActiveReservoir() ]; } // Update the reservoir start time @@ -306,7 +309,7 @@ /*********************************************************************//** * @brief * The getFillTimeMS function calculates the fill time in milliseconds. - * @details Inputs: ratios + * @details Inputs: targetFillFlowRate, prevTargetFillVolumeML * @details Outputs: none * @return target maximum fill time *************************************************************************/ @@ -318,7 +321,7 @@ F32 totalTargetFillFlow = targetFillFlowRate + ( targetFillFlowRate * ratios.acidMixingRatio ) + ( targetFillFlowRate * ratios.bicarbMixingRatio ); // Time fill = Fill volume / Qfill. Qfill is converted from L/min to mL/min and the time is converted from minutes to milliseconds - U32 timeFillMS = ( prevTargetFillVolumeML / ( ML_PER_LITER * totalTargetFillFlow ) ) * SEC_PER_MIN * MS_PER_SECOND; + U32 timeFillMS = ( prevTargetFillVolumeML[ getDGActiveReservoir() ] / ( ML_PER_LITER * totalTargetFillFlow ) ) * SEC_PER_MIN * MS_PER_SECOND; // Add the prepare time in the DG mode fill to the calculated fill time in milliseconds U32 timeTotalFillMS = timeFillMS + ratios.timeFillPrepMS; @@ -332,27 +335,29 @@ * flow has changed the function sends the new active reservoir cycle time * to the DG. * @details Inputs: previousDialysateFlowMLP, previousUFFlowMLP - * @details Outputs: previousDialysateFlowMLP, previousUFFlowMLP, volSpentUFML, timeDepleteMS + * @details Outputs: previousDialysateFlowMLP, previousUFFlowMLP, volSpentUFML, + * timeDepleteMS, prevTargetFillVolumeML * @return none *************************************************************************/ static void calculateActiveReservoirCycleTime( void ) { + U32 activeRsrvrTgtVolML = prevTargetFillVolumeML[ getDGActiveReservoir() ]; U32 dialysateFlowMLP = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); - F32 fillTimeMS = ( (F32)prevTargetFillVolumeML / ( getTargetFillFlowRateLPM() * ML_PER_LITER ) ) * SEC_PER_MIN * MS_PER_SECOND; + F32 fillTimeMS = ( (F32)activeRsrvrTgtVolML / ( getTargetFillFlowRateLPM() * ML_PER_LITER ) ) * SEC_PER_MIN * MS_PER_SECOND; F32 targetUFFlowMLP = getCurrentUFSetRate(); - F32 timeDepletionMS = ( (F32)prevTargetFillVolumeML / dialysateFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; + F32 timeDepletionMS = ( (F32)activeRsrvrTgtVolML / dialysateFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; F32 timeTotalCycleMS = fillTimeMS + RESERVOIR_FRESH_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS + ratios.timeFillPrepMS; F32 timeReservoirCycleMS = 0.0F; F32 timeUFDepletionMS = NEARLY_INFINITY; - F32 volFreshML = prevTargetFillVolumeML - volSpentML; + F32 volFreshML = activeRsrvrTgtVolML - volSpentML; F32 timeFreshRemainingMS = ( volFreshML / (F32)dialysateFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; - F32 volMaxUFML = prevTargetFillVolumeML * MAX_RESERVOIR_DILUTION; + F32 volMaxUFML = activeRsrvrTgtVolML * MAX_RESERVOIR_DILUTION; // Check if target UF flow is not zero to consider it in the calculations too if ( targetUFFlowMLP > NEARLY_ZERO ) { // If UF is not 0, the active reservoir cycle time is minimum of UF depletion and fill time - timeUFDepletionMS = ( ( (F32)prevTargetFillVolumeML * RESERVOIR_DILUTION_RATIO ) / targetUFFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; + timeUFDepletionMS = ( ( (F32)activeRsrvrTgtVolML * RESERVOIR_DILUTION_RATIO ) / targetUFFlowMLP ) * SEC_PER_MIN * MS_PER_SECOND; // Calculate the ultra-filtration remaining volume // Using the ultra-filtration remaining volume and the ultra-filtration target flow rate calculate the time // The depletion time in milliseconds is the minimum time of the fresh remaining time and the depletion remaining time @@ -517,7 +522,8 @@ TREATMENT_RESERVOIR_MGMT_STATE_T state = TREATMENT_RESERVOIR_MGMT_WAIT_TO_FILL_STATE; // Get the target fill flow rate in L/min - F32 targetFillFlowRateLPM = getTargetFillFlowRateLPM(); + F32 targetFillFlowRateLPM = getTargetFillFlowRateLPM(); + DG_RESERVOIR_ID_T inactiveRsrvr = getDGInactiveReservoir(); // Get the ultra-filtration volume milliliters // Get the dilution level in percent = spent ultra-filtration volume / target fill volume in milliliters @@ -531,17 +537,17 @@ { if ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) { - prevTargetFillVolumeML = getTargetFillVolumeBasedOnDialysateFlowML(); - cmdStartDGFill( prevTargetFillVolumeML, targetFillFlowRateLPM ); + prevTargetFillVolumeML[ inactiveRsrvr ] = getTargetFillVolumeBasedOnDialysateFlowML(); + cmdStartDGFill( prevTargetFillVolumeML[ inactiveRsrvr ], 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 ) { - prevTargetFillVolumeML = getTargetFillVolumeBasedOnDialysateFlowML(); - cmdStartDGFill( prevTargetFillVolumeML, targetFillFlowRateLPM ); + prevTargetFillVolumeML[ inactiveRsrvr ] = getTargetFillVolumeBasedOnDialysateFlowML(); + cmdStartDGFill( prevTargetFillVolumeML[ inactiveRsrvr ], targetFillFlowRateLPM ); } } else @@ -554,8 +560,8 @@ // If the wait time has elapsed, trigger a fill command if ( timeWaitToFillMS <= 0 ) { - prevTargetFillVolumeML = getTargetFillVolumeBasedOnDialysateFlowML(); - cmdStartDGFill( prevTargetFillVolumeML, targetFillFlowRateLPM ); + prevTargetFillVolumeML[ inactiveRsrvr ] = getTargetFillVolumeBasedOnDialysateFlowML(); + cmdStartDGFill( prevTargetFillVolumeML[ inactiveRsrvr ], targetFillFlowRateLPM ); } } @@ -620,12 +626,13 @@ static TREATMENT_RESERVOIR_MGMT_STATE_T handleReservoirMgmtWaitForFillSettleState( void ) { TREATMENT_RESERVOIR_MGMT_STATE_T state = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_FILL_SETTLE_STATE; - DG_RESERVOIR_ID_T active = getDGActiveReservoir(); + DG_RESERVOIR_ID_T active = getDGActiveReservoir(); + DG_RESERVOIR_ID_T inactiveRsrvr = getDGInactiveReservoir(); // Get the ultra-filtration volume milliliters // Get the dilution level in percent = spent ultra-filtration volume / target fill volume in milliliters volSpentUFML = getReservoirUltrafiltrationVol( activeReservoir ); - dilutionLevelPct = volSpentUFML / (F32)getTargetFillVolumeBasedOnDialysateFlowML(); + dilutionLevelPct = volSpentUFML / (F32)prevTargetFillVolumeML[ inactiveRsrvr ]; // 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 ) ) && @@ -653,7 +660,6 @@ reservoirSwitchStartTimeMS = getMSTimerCount(); state = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_SWITCH_SETTLE_STATE; - } return state;