Index: firmware/App/Controllers/DialysatePumps.c =================================================================== diff -u -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff -r164caef29ce2882549068277843aae33298d6ef2 --- firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) +++ firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 164caef29ce2882549068277843aae33298d6ef2) @@ -74,7 +74,7 @@ #define D12_PUMP_I_COEFFICIENT 60.0F ///< I term for fresh dialysate pump delta pressure control (Diener 2000). #define D48_PUMP_P_COEFFICIENT 20.0F ///< P term for spent dialysate pump delta pressure control (Diener 2000). #define D48_PUMP_I_COEFFICIENT 60.0F ///< I term for spent dialysate pump delta pressure control (Diener 2000). -/** Diener 1000 pump gains for D48 when TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP is set. Tune as needed. */ +/** Diener 1000 pump gains for D48 when __NEW_D48_PUMP__ is defined (or TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP set). Tune as needed. */ #define D48_PUMP_P_COEFFICIENT_1000 20.0F ///< P term for D48 when Diener 1000 enabled. #define D48_PUMP_I_COEFFICIENT_1000 60.0F ///< I term for D48 when Diener 1000 enabled. #define DIAL_PUMP_NO_FEED_FORWARD 0.0F ///< Feedforward term for dialysate pump control @@ -160,22 +160,28 @@ /*********************************************************************//** * @brief - * Returns maximum dialysate pump RPM for D48 (Diener 1000: 1300 when - * TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP set, else Diener 2000: 2650). + * Returns maximum dialysate pump RPM for D48. When __NEW_D48_PUMP__ is defined this + * build is for the new pump and always returns MAX_DIALYSATE_PUMP_RPM (2800). + * Otherwise uses runtime test config (Diener 1000 vs 2000). * Used by ModeGenDialysate/BalancingChamber for D48 speed limits. * @return MAX RPM for D48 pump. *************************************************************************/ U32 getMaxDialysatePumpRpm( void ) { +#ifdef __NEW_D48_PUMP__ + /* New D48 pump build: always use 2800 RPM max; no runtime test config needed. */ + return (U32)MAX_DIALYSATE_PUMP_RPM; +#else return ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) ? (U32)DIENER_1000_MAX_RPM : (U32)DIENER_2000_MAX_RPM; +#endif } /*********************************************************************//** * @brief - * Returns maximum dialysate pump RPM for the given pump. D12 always 2650; - * D48 uses TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP (1300 vs 2650). + * Returns maximum dialysate pump RPM for the given pump. D12 always DIENER_2000_MAX_RPM (2650); + * D48 uses getMaxDialysatePumpRpm() (MAX_DIALYSATE_PUMP_RPM when new pump, else 2650). * @param pumpId D12_PUMP or D48_PUMP. * @return MAX RPM for that pump. *************************************************************************/ @@ -185,6 +191,7 @@ { return getMaxDialysatePumpRpm(); } + /* D12 always uses Diener 2000 limit (2650); do not use MAX_DIALYSATE_PUMP_RPM here. */ return (U32)DIENER_2000_MAX_RPM; } @@ -256,13 +263,20 @@ MIN_DIALYSATE_PUMP_RPM, (U32)DIENER_2000_MAX_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); - // Initialize spent dialysate pump PI controller (D48: Diener 1000 when TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP, else 2000) + // Initialize spent dialysate pump PI controller (D48: when __NEW_D48_PUMP__ use new pump gains + MAX_DIALYSATE_PUMP_RPM, no test config) { +#ifdef __NEW_D48_PUMP__ + F32 d48Kp = D48_PUMP_P_COEFFICIENT_1000; + F32 d48Ki = D48_PUMP_I_COEFFICIENT_1000; + U32 d48MaxRpm = (U32)MAX_DIALYSATE_PUMP_RPM; /* New pump build: always 2800 for D48. */ +#else F32 d48Kp = ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) ? D48_PUMP_P_COEFFICIENT_1000 : D48_PUMP_P_COEFFICIENT; F32 d48Ki = ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) ? D48_PUMP_I_COEFFICIENT_1000 : D48_PUMP_I_COEFFICIENT; + U32 d48MaxRpm = getMaxDialysatePumpRpm(); +#endif initializePIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, d48Kp, d48Ki, MIN_DIALYSATE_PUMP_RPM, - getMaxDialysatePumpRpm(), FALSE, DIAL_PUMP_NO_FEED_FORWARD ); + d48MaxRpm, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); } // Init the dialysate pump with valid PWM while motor is disabled. @@ -1218,7 +1232,8 @@ { // Handle start command if ( ( TRUE == payload.startStop ) && - ( ( payload.rpm >= MIN_DIALYSATE_PUMP_RPM ) && ( payload.rpm <= getMaxDialysatePumpRpmForPump( (DIALYSATE_PUMPS_T)payload.pumpID ) ) ) ) + ( ( payload.rpm >= MIN_DIALYSATE_PUMP_RPM ) && + ( payload.rpm <= getMaxDialysatePumpRpmForPump( (DIALYSATE_PUMPS_T)payload.pumpID ) ) ) ) { setDialysatePumpTargetRPM( (DIALYSATE_PUMPS_T)payload.pumpID, payload.rpm, (BOOL)payload.pumpControl ); result = TRUE; Index: firmware/App/Controllers/DialysatePumps.h =================================================================== diff -u -r23526b5432e8c1cae32bd9b65454ca7ee3c16710 -r164caef29ce2882549068277843aae33298d6ef2 --- firmware/App/Controllers/DialysatePumps.h (.../DialysatePumps.h) (revision 23526b5432e8c1cae32bd9b65454ca7ee3c16710) +++ firmware/App/Controllers/DialysatePumps.h (.../DialysatePumps.h) (revision 164caef29ce2882549068277843aae33298d6ef2) @@ -39,9 +39,6 @@ #define DIENER_2000_MAX_RPM 2650 ///< Diener 2000 maximum RPM. /** Diener 1000 pump limits (when TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP is set, or __NEW_D48_PUMP__ defined). */ -#define DIENER_1000_MIN_RPM 120 ///< Diener 1000 minimum RPM (10% duty target). -#define DIENER_1000_MAX_RPM 2800 ///< Diener 1000 maximum RPM (90% duty target). - #ifdef __NEW_D48_PUMP__ #define MIN_DIALYSATE_PUMP_RPM 134 ///< Minimum RPM target for dialysate pump (10% duty; zero allowed when turning pump off). Index: firmware/App/DDCommon.h =================================================================== diff -u -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff -r164caef29ce2882549068277843aae33298d6ef2 --- firmware/App/DDCommon.h (.../DDCommon.h) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) +++ firmware/App/DDCommon.h (.../DDCommon.h) (revision 164caef29ce2882549068277843aae33298d6ef2) @@ -55,7 +55,7 @@ #define __NEW_D48_PUMP__ 1 //Uncomment below for Maxon controller speed change -//#define __MAXON_SPEED_UPDATE__ 1 +#define __MAXON_SPEED_UPDATE__ 1 //Uncomment below to disable heaters debug message #define __HEATERS_DEBUG__ 1 Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff -r164caef29ce2882549068277843aae33298d6ef2 --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 164caef29ce2882549068277843aae33298d6ef2) @@ -239,7 +239,7 @@ //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); + //setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); // Disabled for Dialin manual D48 control tests //Rinse pump On setRinsePumpState( RINSE_PUMP_STATE_ON ); @@ -267,7 +267,7 @@ //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); - setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); + //setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); // Disabled for Dialin manual D48 control tests //Rinse pump On setRinsePumpState( RINSE_PUMP_STATE_ON ); @@ -300,7 +300,7 @@ startHeater( D5_HEAT ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); - setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_FILL_RPM, TRUE ); + //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_FILL_RPM, TRUE ); // Disabled for Dialin manual D48 control tests //Rinse pump On setRinsePumpState( RINSE_PUMP_STATE_ON ); @@ -337,7 +337,7 @@ setRinsePumpState( RINSE_PUMP_STATE_ON ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); - setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); + //setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); // Disabled for Dialin manual D48 control tests break; case DD_GEND_DIALYSATE_DELIVERY_PAUSE: @@ -608,7 +608,7 @@ { F32 dialFlowrate = getTDDialysateFlowrate(); F32 calculatedRpm = ( PUMP_SPEED_SLOPE_FACTOR * dialFlowrate ) + PUMP_SPEED_INTERCEPT_FACTOR; - U32 maxD48Rpm = getMaxDialysatePumpRpm(); + U32 maxD48Rpm = getMaxDialysatePumpRpm(); /* D48: 1300 when Diener 1000, else 2650 */ if ( calculatedRpm < (F32)MIN_DIALYSATE_PUMP_RPM ) { Index: firmware/App/Services/FpgaDD.c =================================================================== diff -u -r5ce558e3f4df026c6a28bc03220d4c2641c4b5ff -r164caef29ce2882549068277843aae33298d6ef2 --- firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision 5ce558e3f4df026c6a28bc03220d4c2641c4b5ff) +++ firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision 164caef29ce2882549068277843aae33298d6ef2) @@ -17,6 +17,7 @@ ***************************************************************************/ #include "string.h" // for memset(), memcpy() +#include "math.h" #include "gio.h" // hal headers #include "sci.h" @@ -769,24 +770,22 @@ void setFPGAD48PumpSpeed( U16 speed ) { #ifdef __MAXON_SPEED_UPDATE__ - { + #ifdef __NEW_D48_PUMP__ /* Diener Silencer 1000 pump (D48): map commanded RPM to FPGA PWM counts * using characterization: PWM(FPGA) = (D48_NEW_PUMP_PWM_SLOPE * RPM + D48_NEW_PUMP_PWM_INTERCEPT) * * D48_NEW_PUMP_PWM_FULL_SCALE. * This yields ~10% duty (≈120 RPM) at the low end and ~90% duty (≈2800 RPM) at the high end. */ F32 rpm = (F32)speed; - F32 pwmRatio = (D48_NEW_PUMP_PWM_SLOPE * rpm) + D48_NEW_PUMP_PWM_INTERCEPT; /* duty fraction (0.0–1.0) */ - F32 countsF = pwmRatio * D48_NEW_PUMP_PWM_FULL_SCALE; /* 0–full-scale counts */ - U16 currentSpeed = (U16)CLAMP( countsF, 0.0F, D48_NEW_PUMP_PWM_FULL_SCALE ); + F32 pwmRatio = (D48_NEW_PUMP_PWM_SLOPE * rpm) + D48_NEW_PUMP_PWM_INTERCEPT; + F32 currentSpeed = pwmRatio * D48_NEW_PUMP_PWM_FULL_SCALE; #else - /* Legacy mapping for Diener 2000 pump: keep existing scaling. */ + // for Diener 2000 pump U16 currentSpeed = (U16)( ( ( (F32)speed + PUMP_SPEED_OFFSET ) / PUMP_SPEED_FULL_SCALE ) * MAX_PUMP_SPEED ); #endif - fpgaActuatorSetPoints.fpgaD48PumpSpeed = currentSpeed; } + fpgaActuatorSetPoints.fpgaD48PumpSpeed = currentSpeed; #else - { - fpgaActuatorSetPoints.fpgaD48PumpSpeed = speed; } + fpgaActuatorSetPoints.fpgaD48PumpSpeed = speed; #endif }