Index: firmware/App/Controllers/DialysatePumps.c =================================================================== diff -u -rf6022e86136c821709ce24b61e11e8e2bdf0b11e -rb2e7c9194acd84783d2bbad64c5720410493e199 --- firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision f6022e86136c821709ce24b61e11e8e2bdf0b11e) +++ firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision b2e7c9194acd84783d2bbad64c5720410493e199) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-2026 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file DialysatePumps.c * -* @author (last) Vinayakam Mani -* @date (last) 02-Oct-2024 +* @author (last) Jashwant Gantyada +* @date (last) 12-Mar-2026 * * @author (original) Vinayakam Mani -* @date (original) 02-Oct-2024 +* @date (original) 07-Oct-2024 * ***************************************************************************/ @@ -30,6 +30,7 @@ #include "SafetyShutdown.h" #include "TaskGeneral.h" #include "TaskPriority.h" +#include "TestSupport.h" #include "Timers.h" #include "Utilities.h" @@ -39,14 +40,15 @@ */ // ********** private definitions ********** + #define DIALYSATE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump data is published on the CAN bus. #define DATA_PUBLISH_COUNTER_START_COUNT 60 ///< Data publish counter start count. #define DP_CONTROL_INTERVAL_MS 1000 ///< Dialysate pump control interval in ms #define DP_CONTROL_INTERVAL ( DP_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump is controlled. #define DIALYSATE_PUMP_CONTROL_RUN 0x01 ///< Dialysate pump control run pump. #define DIALYSATE_PUMP_CONTROL_STOP 0x00 ///< Dialysate pump control stop pump. #define DIALYSATE_PUMP_FORWARD_DIR 1 ///< Dialysate pump forward direction. reverse direction is not allowed. -#define DIALYSATE_PUMP_RAMP_SPEED_INCREMENT 10.0F ///< Speed increase when controlling dialysate pump ramp to target step speed. +#define DIALYSATE_PUMP_RAMP_SPEED_INCREMENT 50.0F ///< Speed increase when controlling dialysate pump ramp to target step speed. #define ZERO_SPEED 0.0F ///< Zero speed/RPM value. #define DIALYSATE_PUMP_MAX_CURRENT_WHEN_OFF_A 0.1F ///< Dialysate pump maximum current when the pump is off in amps. @@ -77,7 +79,7 @@ #define DEGAS_PUMP_INTERCEPT_FACTOR 0.1153F ///< Dialysate pump target pressure addition factor ( b factor in 'y = mx + b' equation) #define MAX_ALLOWED_RPM_OUT_OF_RANGE 300 ///< Maximum allowed RPM out of range from target RPM in open loop. -#define PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD 20.0F ///< Speed change that alters the state to ramp during control state. +#define PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD 100.0F ///< Speed change that alters the state to ramp during control state. #define RPM_OUT_OF_RANGE_TIME_OUT ( 10 * MS_PER_SECOND ) ///< Open loop RPM out of range time out in ms. #define SAFETY_SHUTDOWN_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Dialysate pump safety shutdown activation timeout. @@ -124,9 +126,7 @@ // ********** private data ********** static U32 dialysatePumpDataPublicationTimerCounter; ///< Used to schedule dialysate pump data publication to CAN bus. -static OVERRIDE_U32_T dialysatePumpDataPublishInterval = { DIALYSATE_PUMP_DATA_PUB_INTERVAL, - DIALYSATE_PUMP_DATA_PUB_INTERVAL, - 0, 0 }; ///< Interval (in ms) at which to publish dialysate pump data to CAN bus. +static OVERRIDE_U32_T dialysatePumpDataPublishInterval; ///< Interval (in ms) at which to publish dialysate pump data to CAN bus. //static DD_DIALYSATE_PUMP_CAL_RECORD_T dialysatePumpCalRecord; ///< Dialysate pump calibration record. static DIALYSATE_PUMP_DATA_T dialysatePumps[ NUM_OF_DIALYSATE_PUMPS ]; ///< Array of dialysate pumps data structure. @@ -157,6 +157,62 @@ /*********************************************************************//** * @brief + * The getD48MinPumpRPM function returns the minimum RPM limit for the D48 pump + * based on test configuration (Diener 1000 vs Diener 2000). + * @details \b Inputs: Test configuration TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP. + * @details \b Outputs: none + * @param pumpId to set the pump speed accordingly + * @return Minimum RPM for D48 pump (200 when Diener 2000 enabled, 134 otherwise). + *************************************************************************/ +U32 getDialysatePumpMinRPM( DIALYSATE_PUMPS_T pumpId ) +{ + U32 minRpm = MIN_DIALYSATE_PUMP_RPM; + + if ( D48_PUMP == pumpId ) + { + // Default to Diener 1000 min when that test config is active; + // otherwise use the common MIN_DIALYSATE_PUMP_RPM (Diener 2000 / beta systems). + minRpm = D48_DIENER_1000_MIN_RPM; + + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP ) ) + { + minRpm = MIN_DIALYSATE_PUMP_RPM; + } + } + + return minRpm; +} + +/*********************************************************************//** + * @brief + * The getDialysatePumpMaxRPM function returns the maximum RPM limit for a + * given dialysate pump. + * @details \b Inputs: pumpId + * @details \b Outputs: none +* @param pumpId to set the pump speed accordingly + * @return Maximum RPM for the specified pump + *************************************************************************/ +U32 getDialysatePumpMaxRPM( DIALYSATE_PUMPS_T pumpId ) +{ + U32 maxRpm = MAX_DIALYSATE_PUMP_RPM; + + if ( D48_PUMP == pumpId ) + { + // Default to Diener 1000 max when that test config is active; + // otherwise use the common MAX_DIALYSATE_PUMP_RPM (Diener 2000 / beta systems). + maxRpm = D48_DIENER_1000_MAX_RPM; + + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP ) ) + { + maxRpm = MAX_DIALYSATE_PUMP_RPM; + } + } + + return maxRpm; +} + +/*********************************************************************//** + * @brief * The initDialysatePump function initializes the DialysatePumps unit. * @details \b Inputs: none * @details \b Outputs: Dialysate pump unit variables initialized. @@ -193,7 +249,7 @@ dialysatePumpMeasuredCurrentA[ pumpId ].ovInitData = 0.0F; dialysatePumpMeasuredCurrentA[ pumpId ].ovData = 0.0F; dialysatePumpMeasuredCurrentA[ pumpId ].override = OVERRIDE_RESET; - dialysatePumps[ pumpId ].currentPumpSpeed = MIN_DIALYSATE_PUMP_RPM; + dialysatePumps[ pumpId ].currentPumpSpeed = getDialysatePumpMinRPM( pumpId ); dialysatePumps[ pumpId ].prevPumpTargetSpeed = 0.0F; dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; dialysatePumps[ pumpId ].directionErrorCount = 0; @@ -203,6 +259,11 @@ signalDialysatePumpHardStop( pumpId ); } + dialysatePumpDataPublishInterval.data = DIALYSATE_PUMP_DATA_PUB_INTERVAL; + dialysatePumpDataPublishInterval.ovInitData = DIALYSATE_PUMP_DATA_PUB_INTERVAL; + dialysatePumpDataPublishInterval.ovData = 0; + dialysatePumpDataPublishInterval.override = OVERRIDE_RESET; + pumpTargetPressure[D12_PUMP].data = DEFAULT_FRESH_DIALYSATE_TARGET_PRESSURE_PSI; pumpTargetPressure[D12_PUMP].ovInitData = DEFAULT_FRESH_DIALYSATE_TARGET_PRESSURE_PSI; pumpTargetPressure[D12_PUMP].ovData = 0.0F; @@ -217,14 +278,14 @@ initializePIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, D12_PUMP_P_COEFFICIENT, D12_PUMP_I_COEFFICIENT, MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); - // Initialize spent dialysate pump PI controller + // Initialize spent dialysate pump PI controller (use Diener 1000 range to support both pump types) initializePIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, D48_PUMP_P_COEFFICIENT, D48_PUMP_I_COEFFICIENT, - MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM,FALSE, DIAL_PUMP_NO_FEED_FORWARD ); + D48_DIENER_1000_MIN_RPM, D48_DIENER_1000_MAX_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); // Init the dialysate pump with valid PWM while motor is disabled. // when enable triggers, we dont want invlid RPM set that triggers alarm in motor controller. - setFPGAD12PumpSpeed( MIN_DIALYSATE_PUMP_RPM ); - setFPGAD48PumpSpeed( MIN_DIALYSATE_PUMP_RPM ); + setFPGAD12PumpSpeed( getDialysatePumpMinRPM( D12_PUMP ) ); + setFPGAD48PumpSpeed( getDialysatePumpMinRPM( D48_PUMP ) ); #ifdef __PITEST__ for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) @@ -261,10 +322,11 @@ *************************************************************************/ static void calculateDegasPumpTargetPressure( void ) { - F32 pressureInmmHg = getFilteredPressure( BARO_PRES ); + //TODO: Uncomment below once baro reading available from TD. + //F32 pressureInmmHg = getFilteredPressure( BARO_PRES ); //Get the degassing target pressure - pumpTargetPressure[D12_PUMP].data = ( ( DEGAS_PUMP_SLOPE_FACTOR * pressureInmmHg ) + DEGAS_PUMP_INTERCEPT_FACTOR ) + DEGAS_PUMP_TARGET_PRES_ADJ_THRESHOLD; + //pumpTargetPressure[D12_PUMP].data = ( ( DEGAS_PUMP_SLOPE_FACTOR * pressureInmmHg ) + DEGAS_PUMP_INTERCEPT_FACTOR ) + DEGAS_PUMP_TARGET_PRES_ADJ_THRESHOLD; } /*********************************************************************//** @@ -282,37 +344,42 @@ BOOL setDialysatePumpTargetRPM( DIALYSATE_PUMPS_T pumpId, U32 rpm, BOOL isOpenLoopControlEnabled ) { BOOL result = FALSE; + U32 minRPM; + U32 maxRPM; + minRPM = getDialysatePumpMinRPM( pumpId ); + maxRPM = getDialysatePumpMaxRPM( pumpId ); + if ( pumpId < NUM_OF_DIALYSATE_PUMPS ) { - if ( ( MIN_DIALYSATE_PUMP_RPM <= rpm ) && ( rpm <= MAX_DIALYSATE_PUMP_RPM ) ) + if ( ( minRPM <= rpm ) && ( rpm <= maxRPM ) ) { pumpTargetSpeed[ pumpId ].data = rpm; } - else if ( rpm < MIN_DIALYSATE_PUMP_RPM ) + else if ( rpm < minRPM ) { - // Lets assign minimum speed to make sure, driver is not getting into fault mode - pumpTargetSpeed[ pumpId ].data = MIN_DIALYSATE_PUMP_RPM; + // Assign minimum speed so driver does not enter fault mode. + pumpTargetSpeed[ pumpId ].data = minRPM; } else { - pumpTargetSpeed[ pumpId ].data = MAX_DIALYSATE_PUMP_RPM; + pumpTargetSpeed[ pumpId ].data = maxRPM; } // Assign Open loop or close loop control isDialPumpOpenLoopEnabled[ pumpId ] = isOpenLoopControlEnabled; #ifdef __BARO_PRES_SENSOR__ - //Update Degas pump target speed + // Update degas pump target speed. calculateDegasPumpTargetPressure(); #endif - //handle target speed update when pump is running + // Handle target speed update when pump is running. if ( DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE == dialysatePumps[ pumpId ].dialysatePumpState ) { F32 diffSpeed = fabs( getDialysatePumpTargetSpeed( pumpId ) - dialysatePumps[ pumpId ].prevPumpTargetSpeed ); if ( diffSpeed > PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD ) { - // change to ramp state + // Change to ramp state. dialysatePumps[ pumpId ].dialysatePumpState = DIALYSATE_PUMP_RAMP_UP_STATE; } } @@ -339,30 +406,29 @@ *************************************************************************/ void signalDialysatePumpHardStop( DIALYSATE_PUMPS_T pumpId ) { - //Update control to stop the dialysate pump + // Update control to stop the dialysate pump. if ( D12_PUMP == pumpId ) { - // dialysate pump control run enable dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; setFPGAD12PumpControl( dialysatePumps[ pumpId ].control ); - setFPGAD12PumpSpeed( MIN_DIALYSATE_PUMP_RPM ); + setFPGAD12PumpSpeed( getDialysatePumpMinRPM( D12_PUMP ) ); } else { dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; setFPGAD48PumpControl( dialysatePumps[ pumpId ].control ); - setFPGAD48PumpSpeed( MIN_DIALYSATE_PUMP_RPM ); + setFPGAD48PumpSpeed( getDialysatePumpMinRPM( D48_PUMP ) ); } - // Reset all the variables to stop mode - dialysatePumps[ pumpId ].currentPumpSpeed = MIN_DIALYSATE_PUMP_RPM; + // Reset all the variables to stop mode. + dialysatePumps[ pumpId ].currentPumpSpeed = getDialysatePumpMinRPM( pumpId ); pumpTargetSpeed[ pumpId ].data = 0.0F; dialysatePumps[ pumpId ].dialysatePumpState = DIALYSATE_PUMP_OFF_STATE; dialysatePumps[ pumpId ].controlTimerCounter = 0; dialysatePumps[ pumpId ].isDialPumpOn = FALSE; isDialPumpOpenLoopEnabled[ pumpId ] = FALSE; - //Reset PI Controller + // Reset PI controller. if ( D12_PUMP == pumpId ) { resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); @@ -655,12 +721,13 @@ { DIALYSATE_PUMP_STATE_T result = DIALYSATE_PUMP_OFF_STATE; F32 targetSpeed = getDialysatePumpTargetSpeed( pumpId ); + U32 minRPM = getDialysatePumpMinRPM( pumpId ); - if ( targetSpeed >= MIN_DIALYSATE_PUMP_RPM ) + if ( targetSpeed >= minRPM ) { if ( D12_PUMP == pumpId ) { - // dialysate pump control run enable, forward run only. + // Dialysate pump control run enable, forward run only. dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_RUN; setFPGAD12PumpControl( dialysatePumps[ pumpId ].control ); } @@ -724,6 +791,7 @@ F32 speedIncrease = 0.0F; BOOL hasTgtBeenReached = FALSE; F32 currentToTargetDiff = fabs( getDialysatePumpTargetSpeed( pumpId ) - dialysatePumps[ pumpId ].currentPumpSpeed ); + U32 minRPM = getDialysatePumpMinRPM( pumpId ); if ( currentToTargetDiff > ZERO_SPEED ) { @@ -737,7 +805,7 @@ hasTgtBeenReached = TRUE; } - // Subtract current speed when target speed is smaller + // Subtract current speed when target speed is smaller. if ( getDialysatePumpTargetSpeed( pumpId ) < dialysatePumps[ pumpId ].currentPumpSpeed ) { speedIncrease *= -1.0F; @@ -752,16 +820,16 @@ // } } - if ( dialysatePumps[ pumpId ].currentPumpSpeed >= MIN_DIALYSATE_PUMP_RPM ) + if ( dialysatePumps[ pumpId ].currentPumpSpeed >= minRPM ) { if ( D12_PUMP == pumpId ) { - // Set fresh dialyate pump speed + // Set fresh dialysate pump speed. setFPGAD12PumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); } else { - // Set spent dialyate pump speed + // Set spent dialysate pump speed. setFPGAD48PumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); } } @@ -832,7 +900,23 @@ } } } + else if ( TRUE == isDialPumpOpenLoopEnabled[ pumpId ] ) + { + // Get current pump speed + dialysatePumps[ pumpId ].currentPumpSpeed = getDialysatePumpTargetSpeed( pumpId ); + if ( D12_PUMP == pumpId ) + { + //Set fresh dialyate pump speed + setFPGAD12PumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); + } + else + { + //Set spent dialyate pump speed + setFPGAD48PumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); + } + } + return state; } @@ -1157,15 +1241,18 @@ if ( (DIALYSATE_PUMPS_T)payload.pumpID < NUM_OF_DIALYSATE_PUMPS ) { - // Handle start command + U32 minRPM = getDialysatePumpMinRPM( (DIALYSATE_PUMPS_T)payload.pumpID ); + U32 maxRPM = getDialysatePumpMaxRPM( (DIALYSATE_PUMPS_T)payload.pumpID ); + + // Handle start command. if ( ( TRUE == payload.startStop ) && - ( ( payload.rpm >= MIN_DIALYSATE_PUMP_RPM ) && ( payload.rpm <= MAX_DIALYSATE_PUMP_RPM ) ) ) + ( ( payload.rpm >= minRPM ) && ( payload.rpm <= maxRPM ) ) ) { setDialysatePumpTargetRPM( (DIALYSATE_PUMPS_T)payload.pumpID, payload.rpm, (BOOL)payload.pumpControl ); result = TRUE; } - //Handle stop command + // Handle stop command. if ( FALSE == payload.startStop ) { signalDialysatePumpHardStop( (DIALYSATE_PUMPS_T)payload.pumpID );