Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -r3ebcff44116a7853d2011c7b2f1eb38c1f37ba2a -r60db0506b1a90ed00b0e83159f6e7510ab6e4b7b --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 3ebcff44116a7853d2011c7b2f1eb38c1f37ba2a) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 60db0506b1a90ed00b0e83159f6e7510ab6e4b7b) @@ -7,8 +7,8 @@ * * @file ModeGenDialysate.c * -* @author (last) Vinayakam Mani -* @date (last) 11-Feb-2026 +* @author (last) Jashwant Gantyada +* @date (last) 13-Mar-2026 * * @author (original) Vinayakam Mani * @date (original) 06-Nov-2024 @@ -34,6 +34,7 @@ #include "TaskGeneral.h" #include "TDInterface.h" #include "Temperature.h" +#include "TestSupport.h" #include "Timers.h" #include "Ultrafiltration.h" #include "Valves.h" @@ -72,10 +73,14 @@ #define B3_HEAT_DIS_SEC_COEFF 0.0000085278F ///< Second coefficient for Heat loss dissipation calculation from D28 to Dialyzer. #define B3_HEAT_DIS_THIRD_COEFF 0.0035126F ///< Third coefficient for Heat loss dissipation calculation from D28 to Dialyzer. #define B3_HEAT_DIS_FOURTH_COEFF 0.63893F ///< Fourth coefficient for Heat loss dissipation calculation from D28 to Dialyzer. +#define PUMP_SPEED_SLOPE_FACTOR_DIENER_2000 1.24F ///< D48 Diener 2000 pump speed slope (y = 1.24x + 30). +#define PUMP_SPEED_INTERCEPT_FACTOR_DIENER_2000 30.0F ///< D48 Diener 2000 pump speed intercept. +#define PUMP_SPEED_SLOPE_FACTOR_DIENER_1000 2.869F ///< D48 Diener 1000 pump speed slope (y = 2.869x + 25.956). +#define PUMP_SPEED_INTERCEPT_FACTOR_DIENER_1000 25.956F ///< D48 Diener 1000 pump speed intercept. #define BICARB_CHAMBER_FILL_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Bicarb chamber fill timeout. //Testing -#define DELAY_BC_SWITCHING_AT_START_UP ( 10 * MS_PER_SECOND ) ///< Provide a balancing chamber switching start up delay to stabilize pump speed etc., +#define DELAY_BC_SWITCHING_AT_START_UP ( 10 * MS_PER_SECOND ) ///< Provide a balancing chamber switching start up delay to stabilize pump speed etc., /// Payload record structure for Gen dialysate execution state set request typedef struct { @@ -99,6 +104,7 @@ static U32 bypassStateDelayStartTimeMS; ///< Delay balancing chamber switching for a second to preapre pump steady state. static BOOL delayBypassStateFlag; ///< To indicate change in treatment parameters static F32 dialysateToDialyzerFlowRate; ///< Current dialysate to dialyzer flow rate (ml/min) +static U32 d48PumpSpeed; ///< Initial D48 pump speed based on the Qd. // ********** private function prototypes ********** @@ -118,6 +124,7 @@ static F32 calculateHeatDissipationB3( void ); static F32 calculateInitialTemp( F32 targetTemp, F32 heatDissipation ); static void publishGenDialysateModeData( void ); +static U32 getFreshDialPumpInitialRpm( void ); /*********************************************************************//** * @brief @@ -151,6 +158,7 @@ bicarbFillStartTimeMS = 0; pendingSpentChamberFill = FALSE; pendingBicarbChamberFill = FALSE; + d48PumpSpeed = getDialysatePumpMinRPM( D48_PUMP ); //Testing bypassStateDelayStartTimeMS = 0; delayBypassStateFlag = TRUE; @@ -174,8 +182,13 @@ *************************************************************************/ U32 transitionToGenDialysateMode( void ) { + U32 initialD48PumpSpeed = 0U; + initGenDialysateMode(); setCurrentSubState( NO_SUB_STATE ); + //calculateD48PumpSpeedForBCFill(); + initialD48PumpSpeed = getCalculatedD48PumpSpeedForBCFill(); + setD48PumpSpeedForBCFill( initialD48PumpSpeed ); transitionToUltrafiltration(); return genDialysateState; @@ -208,6 +221,26 @@ /*********************************************************************//** * @brief + * The getFreshDialPumpInitialRpm function returns fresh dialysate pump initial + * rpm based on hardwawre configuration. + * @details Inputs: FRESH_DIAL_PUMP_INITIAL_RPM, FRESH_DIAL_PUMP_INITIAL_RPM_B1_9_B2_0 + * @details Outputs: none + * @return fresh dialysate pump initial RPM for the active hardware variant + *************************************************************************/ +static U32 getFreshDialPumpInitialRpm( void ) +{ + U32 rpm = FRESH_DIAL_PUMP_INITIAL_RPM_B1_9_B2_0; + + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) ) + { + rpm = FRESH_DIAL_PUMP_INITIAL_RPM; + } + + return rpm; +} + +/*********************************************************************//** + * @brief * The setModeGenDStateTransition function sets the actuators and variables * for the state transition in generate dialysis mode. * @details Inputs: Valve states, Pump speed @@ -255,9 +288,9 @@ //Testing : Enable close loop once testing is complete //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); //Rinse pump On setRinsePumpState( RINSE_PUMP_STATE_ON ); @@ -291,9 +324,9 @@ startHeater( D45_HEAT ); //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); //Rinse pump On setRinsePumpState( RINSE_PUMP_STATE_ON ); @@ -343,7 +376,7 @@ // Stop trimmer heater stopHeater( D45_HEAT ); - setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_FILL_RPM, TRUE ); //Rinse pump On @@ -386,11 +419,11 @@ setRinsePumpState( RINSE_PUMP_STATE_ON ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); - setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); break; case DD_GEND_DIALYSATE_DELIVERY_PAUSE: - setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); signalDialysatePumpHardStop( D48_PUMP ); requestConcentratePumpOff( D11_PUMP, FALSE ); requestConcentratePumpOff( D10_PUMP, FALSE ); @@ -558,6 +591,31 @@ /*********************************************************************//** * @brief + * The getD48PumpSpeedForBCFill function returns the calculated D48 pump speed + * @details \b Inputs: d48PumpSpeed + * @details \b Outputs: none + * @return D48 pump speed. + *************************************************************************/ +U32 getD48PumpSpeedForBCFill( void ) +{ + return d48PumpSpeed; +} + +/*********************************************************************//** + * @brief + * The setD48PumpSpeedForBCFill function sets the updated D48 pump speed. + * @details \b Inputs: none + * @details \b Outputs: d48PumpSpeed + * @param pumpSpeed Dialysate pump speed + * @return none. + *************************************************************************/ +void setD48PumpSpeedForBCFill( U32 pumpSpeed ) +{ + d48PumpSpeed = pumpSpeed; +} + +/*********************************************************************//** + * @brief * The monitorChamberLevelStatus function checks the spent chamber and bicarb * chamber level status and updates the corrosponding flags. * @details \b Inputs: Spent and bicarb chamber levels. @@ -602,7 +660,7 @@ #ifndef __REVISED_HEATER_MODEL__ if ( dialFlowrate >= LOW_DIAL_FLOW_RATE ) { - // linear releationship seen against high dialysate flowrate Vs DeltaTemp + // linear relationship seen against high dialysate flowrate Vs DeltaTemp // deltaTemp = (-0.0029 * Qd) + 3.47 deltaTemp = ( LINEAR_SLOPE_FACTOR * dialFlowrate ) + LINEAR_INTERCEPT_FACTOR; } @@ -707,6 +765,47 @@ /*********************************************************************//** * @brief + * The getCalculatedD48PumpSpeedForBCFill function returns the D48 pump speed + * calculated from dialysate flow rate (Qd) for continuous delivery. + * @details \b Inputs: Qd from TD, test config TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP. + * @details \b Outputs: none + * @return Calculated D48 pump speed in RPM (Diener 1000 or 2000 formula per test config). + *************************************************************************/ +U32 getCalculatedD48PumpSpeedForBCFill( void ) +{ + F32 dialFlowrate = getTDDialysateFlowrate(); + F32 slope; + F32 intercept; + F32 calculatedSpeed; + U32 rpm; + + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP ) ) + { + slope = PUMP_SPEED_SLOPE_FACTOR_DIENER_2000; + intercept = PUMP_SPEED_INTERCEPT_FACTOR_DIENER_2000; + } + else + { + slope = PUMP_SPEED_SLOPE_FACTOR_DIENER_1000; + intercept = PUMP_SPEED_INTERCEPT_FACTOR_DIENER_1000; + } + + // Calculate nominal speed from Qd. + calculatedSpeed = ( slope * dialFlowrate ) + intercept; + + // Prevent negative before converting to unsigned and round up using ceilf. + if ( calculatedSpeed < 0.0F ) + { + calculatedSpeed = 0.0F; + } + + rpm = (U32)ceilf( calculatedSpeed ); + + return rpm; +} + +/*********************************************************************//** + * @brief * The handleGenDDialysateIsolatedUFState function performs the * Isolated ultrafiltration operations. * @details \b Inputs: none. @@ -994,6 +1093,8 @@ *************************************************************************/ void updateTreatmentSettings( void ) { + F32 initialPumpSpeed = 0.0F; + // Update any dynamic treatment parameter changes if ( TRUE == isTreatmentParamUpdated ) { @@ -1012,6 +1113,11 @@ //TODO: update others parameters setting as needed. signalUFRateUpdate(); + //Update D48 pump speed + //calculateD48PumpSpeedForBCFill(); + initialPumpSpeed = getCalculatedD48PumpSpeedForBCFill(); + setD48PumpSpeedForBCFill( initialPumpSpeed ); + //reset the flag isTreatmentParamUpdated = FALSE; }