Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r0a61f7fa5ff6945ebc2e507d8ecb71a652c38eaa -r6b9c66e070fe7cdab2c368c611fdc6b09b9fbf06 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 0a61f7fa5ff6945ebc2e507d8ecb71a652c38eaa) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 6b9c66e070fe7cdab2c368c611fdc6b09b9fbf06) @@ -222,6 +222,7 @@ signalBloodPumpHardStop(); signalDialInPumpHardStop(); signalDialOutPumpHardStop(); + cmdStopDGTrimmerHeater(); if ( TRUE == isAlarmActive( ALARM_ID_HD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM ) ) { @@ -1811,6 +1812,7 @@ if ( DG_CMD_REQUEST_REJECT_REASON_NONE == cmdResp.rejectCode ) { setDialInPumpTargetFlowRate( DIP_FLOW_RATE_FIRST_DISPLACEMENT_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + cmdStartDGTrimmerHeater(); settleStartTime = getMSTimerCount(); state = WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE; } @@ -1845,6 +1847,7 @@ if ( TRUE == didTimeout( displacementStartTime, WET_SELF_TEST_FIRST_DISPLACEMENT_TIME_MS ) ) { signalDialInPumpHardStop(); + cmdStopDGTrimmerHeater(); settleStartTime = getMSTimerCount(); state = WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE; } @@ -1954,6 +1957,7 @@ if ( DG_CMD_REQUEST_REJECT_REASON_NONE == cmdResp.rejectCode ) { setDialInPumpTargetFlowRate( DIP_FLOW_RATE_SECOND_DISPLACEMENT_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + cmdStartDGTrimmerHeater(); settleStartTime = getMSTimerCount(); state = WET_SELF_TESTS_SECOND_DISPLACEMENT_STATE; } @@ -1996,6 +2000,7 @@ if ( TRUE == didTimeout( displacementStartTime, WET_SELF_TEST_SECOND_DISPLACEMENT_TIME_MS ) ) { signalDialInPumpHardStop(); + cmdStopDGTrimmerHeater(); settleStartTime = getMSTimerCount(); state = WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE; } Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r0035cfb9a3fa89a8f9c3e0b589a327ed9c1d9470 -r6b9c66e070fe7cdab2c368c611fdc6b09b9fbf06 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 0035cfb9a3fa89a8f9c3e0b589a327ed9c1d9470) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 6b9c66e070fe7cdab2c368c611fdc6b09b9fbf06) @@ -36,7 +36,14 @@ #define MAX_RESERVOIR_VOLUME_ML 1900.0F ///< Maximum allowed fluid in a reservoir in milliliters. #define MAX_RESERVOIR_DILUTION 0.15F ///< Maximum reservoir dilution limit. -#define MAX_RESERVOIR_RECIRCULATION 1.1F ///< Maximum reservoir recirculation limit. +#define MAX_RESERVOIR_RECIRCULATION_450_MLP 1.1F ///< Maximum reservoir recirculation limit <= 450mL/m. +#define MAX_RESERVOIR_RECIRCULATION_500_MLP 1.2F ///< Maximum reservoir recirculation limit <= 500mL/m. +#define MAX_RESERVOIR_RECIRCULATION_550_MLP 1.3F ///< Maximum reservoir recirculation limit <= 550mL/m. +#define MAX_RESERVOIR_RECIRCULATION_600_MLP 1.4F ///< Maximum reservoir recirculation limit <= 600mL/m. +#define RESERVOIR_FLOW_450_MLP 450.0F ///< Reservoir flow rate 450mL/m. +#define RESERVOIR_FLOW_500_MLP 500.0F ///< Reservoir flow rate 500mL/m. +#define RESERVOIR_FLOW_550_MLP 550.0F ///< Reservoir flow rate 550mL/m. +#define RESERVOIR_FLOW_600_MLP 600.0F ///< Reservoir flow rate 600mL/m. #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. @@ -96,6 +103,7 @@ static F32 getTargetFillFlowRateLPM( void ); static U32 getFillTimeMS( void ); static void calculateActiveReservoirCycleTime( void ); +static F32 getReservoirRecirculationMaxPercent( void ); static void publishReservoirData( void ); static TREATMENT_RESERVOIR_MGMT_STATE_T handleReservoirMgmtStartState( void ); @@ -309,9 +317,10 @@ } else { - // fill flow = 10 x dialysate_flow ^ 2 - 7.5 x dialysate_flow + 2.0 - fillFlowRate = pow( dialysateFlow, 2 ) * DIA_FLOW_TO_FILL_FLOW_SECOND_ORDER_COEFF - - dialysateFlow * DIA_FLOW_TO_FILL_FLOW_FIRST_ORDER_COEFF + DIA_FLOW_TO_FILL_FLOW_CONSTANT; + // 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 - dialysateFlow ) ) + * ( 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; @@ -394,6 +403,39 @@ /*********************************************************************//** * @brief + * The getReservoirRecirculationMaxPercent function returns the reservoir management + * maximum recirculation percentage. + * @details Inputs: TREATMENT_PARAM_DIALYSATE_FLOW + * @details Outputs: none + * @return reservoir management max recirculation percent + *************************************************************************/ +static F32 getReservoirRecirculationMaxPercent( void ) +{ + U32 targetDialysateFlowMLP = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + F32 maxPercent = 0.0F; + + if (RESERVOIR_FLOW_450_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_450_MLP; + } + else if (RESERVOIR_FLOW_500_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_500_MLP; + } + else if (RESERVOIR_FLOW_550_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_550_MLP; + } + else // if (RESERVOIR_FLOW_600_MLP >= targetDialysateFlowMLP) + { + maxPercent = MAX_RESERVOIR_RECIRCULATION_600_MLP; + } + + return maxPercent; +} + +/*********************************************************************//** + * @brief * The publishReservoirData function publishes reservoirs data during treatment. * @details Inputs: reservoirsPublicationCounter * @details Outputs: reservoirsPublicationCounter @@ -528,7 +570,14 @@ // Time to wait prior to next fill is depletion time - the whole group of how much time is needed to fill a reservoir + // the time it takes to wait for a reservoir to settle and the extra margin time for ramp up of the RO and drain pumps and // any other extra times. - timeWaitToFillMS = timeDepleteMS - ( getFillTimeMS() + RESERVOIR_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS ); + if ( targetDialysateFlowMLP < RESERVOIR_FLOW_500_MLP ) + { + timeWaitToFillMS = timeDepleteMS - ( getFillTimeMS() + RESERVOIR_SETTLE_TIME_MS + RESERVOIR_CYCLE_EXTRA_MARGIN_TIME_MS ); + } + else + { + timeWaitToFillMS = 0; + } // If the wait time has elapsed, trigger a fill command if ( timeWaitToFillMS <= 0 ) @@ -566,7 +615,7 @@ // If the recirculation level has exceeded the max allowed, raise the alarm to stop using the active reservoir as it has been // diluted to much - if ( recirculationLevelPct >= MAX_RESERVOIR_RECIRCULATION ) + if ( recirculationLevelPct >= getReservoirRecirculationMaxPercent() ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_RESERVOIRS_ALARMS ) != SW_CONFIG_ENABLE_VALUE )