Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -r36db8974c2a0242e0c8c59d6f3131b975b34d06b -r3d69f9a417c8473a16cc32f37db9b2c96faf7f6a --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 36db8974c2a0242e0c8c59d6f3131b975b34d06b) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 3d69f9a417c8473a16cc32f37db9b2c96faf7f6a) @@ -22,8 +22,8 @@ #include "DryBiCart.h" #include "FpgaDD.h" #include "Heaters.h" -#include "ModeStandby.h" #include "ModeGenDialysate.h" +#include "ModeStandby.h" #include "Messaging.h" #include "OperationModes.h" #include "Pressure.h" @@ -454,7 +454,7 @@ balChamberSWState = BAL_CHAMBER_SW_STATE1; currentBalChamberFillCounter = 0; isBalChamberFillInProgress = FALSE; - isPressureStabilizedDuringFill = FALSE; + isPressureStabilizedDuringFill = FALSE; isPressureDroppedDuringFill = FALSE; isSpentFillComplete = FALSE; lastPrevSpentDialPressure = 0.0F; @@ -465,7 +465,7 @@ freshDialPressure = getFilteredPressure( D18_PRES ); spentDialPressure = getFilteredPressure( D51_PRES ); - // Check fresh and spent dialysate pressure in range or BC switch only flag set + // Check fresh dialysate pressure in range or BC switch only flag set or BC pressure alarms are disabled if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) || ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) ) ) { @@ -682,7 +682,6 @@ // Check fresh dialysate pressure in range if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) || - // ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) || ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) ) ) { // Valve control for state 2 fill @@ -730,7 +729,7 @@ freshDialPressure = getFilteredPressure( D18_PRES ); spentDialPressure = getFilteredPressure( D51_PRES ); - // Check fresh and spent dialysate pressure back in range to indicate fill complete. + // Check fresh dialysate pressure back in range to indicate fill complete. if ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) { if ( ++balChamberFillCompleteStablePressureCounter >= BAL_CHAMBER_FILL_COMPLETE_MS ) @@ -829,6 +828,7 @@ * fill timing close to the switching period time. * @details \b Inputs: balChamberExecState * @details \b Outputs: none + * @param spentDialPressure to check the switching time for BC and set D48 speed based on it. * @return the current state of balancing chamber states. *************************************************************************/ static void checkSpentFillComplete( F32 spentDialPressure ) @@ -842,11 +842,16 @@ U32 maxD48Speed = initialD48PumpSpeed + ( initialD48PumpSpeed * D48_SPEED_RANGE_LIMIT ); U32 d48SpeedPostRangeCheck = 0; F32 qdMlpm = getTDDialysateFlowrate(); + BOOL result = FALSE; F32 spentFillCompletePresPsig; - // Diener 1000 pump: spent fill complete pressure depends on Qd (7/15/20 PSI). Other pump: use legacy 25 PSI. - if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) + // Diener 2000 pump: spent fill complete pressure use legacy 25 PSI. Other pump: depends on Qd. + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP ) ) { + spentFillCompletePresPsig = SPENT_FILL_COMPLETE_PRES; + } + else + { if ( qdMlpm <= QD_THRESHOLD_LOW_MLPM ) { spentFillCompletePresPsig = SPENT_FILL_COMPLETE_PRES_QD_LOW_PSIG; @@ -860,10 +865,6 @@ spentFillCompletePresPsig = SPENT_FILL_COMPLETE_PRES_QD_HIGH_PSIG; } } - else - { - spentFillCompletePresPsig = SPENT_FILL_COMPLETE_PRES; - } // Collect the next sample of spent pressure lastPrevSpentDialPressure = prevSpentDialPressure; @@ -878,9 +879,9 @@ absDiffSpentFillCount = abs(diffSpentFillCompleteCount); adjustedSpeed = ( ( (F32)absDiffSpentFillCount / (F32)balChamberValveClosePeriod ) * spentDialPumpSpeed ) * D48_SPEED_ADJUST_FACTOR; - //Not adjust the D48 pump speed if the fill counter is just 50ms difference from the closing period. - if ( 0 == ( ( diffSpentFillCompleteCount <= 0 ) && ( diffSpentFillCompleteCount >= -2 ) ) ) - //if ( absDiffSpentFillCount > SPENT_DIFF_COUNT_DEADBAND ) + result = ( ( diffSpentFillCompleteCount <= 0 ) && ( diffSpentFillCompleteCount >= -2 ) ) ? TRUE : FALSE; + //Not adjust the D48 pump speed if the fill counter is just 50ms difference from the closing period(considering only positive DEADBAND as negative deadband might indicate under fill of BC). + if ( 0 == result ) { if ( diffSpentFillCompleteCount < SPENT_DIFF_COUNT_ZERO ) { @@ -956,6 +957,7 @@ * switching only On/Off status. * @details \b Inputs: balanceChamberSwitchingOnly * @details \b Outputs: none + * @param OnOff to set the BC switch status * @return none *************************************************************************/ void setBalChamberSwitchingOnlyStatus( BOOL OnOff ) Index: firmware/App/Controllers/DialysatePumps.c =================================================================== diff -u -r7b8aea653f9a89d97dcec76fe0368664d26907d0 -r3d69f9a417c8473a16cc32f37db9b2c96faf7f6a --- firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 7b8aea653f9a89d97dcec76fe0368664d26907d0) +++ firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision 3d69f9a417c8473a16cc32f37db9b2c96faf7f6a) @@ -74,7 +74,6 @@ #define D12_PUMP_I_COEFFICIENT 60.0F ///< I term for fresh dialysate pump delta pressure control. #define D48_PUMP_P_COEFFICIENT 20.0F ///< P term for spent dialysate pump delta pressure control. #define D48_PUMP_I_COEFFICIENT 60.0F ///< I term for spent dialysate pump delta pressure control. -#define D48_PUMP_CLOSED_LOOP_DEADBAND_RPM 50.0F ///< Deadband on PI output so pump speed does not fluctuate frequently. #define DIAL_PUMP_NO_FEED_FORWARD 0.0F ///< Feedforward term for dialysate pump control #define DEGAS_PUMP_SLOPE_FACTOR -0.0156F ///< Dialysate pump target pressure multiply factor ( m factor in 'y = mx + b' equation) #define DEGAS_PUMP_INTERCEPT_FACTOR 0.1153F ///< Dialysate pump target pressure addition factor ( b factor in 'y = mx + b' equation) @@ -160,37 +159,53 @@ * @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_1000_PUMP. + * @details \b Inputs: Test configuration TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP. * @details \b Outputs: none - * @return Minimum RPM for D48 pump (134 when Diener 1000 enabled, 200 otherwise). + * @param pumpId to set the pump speed accordingly + * @return Minimum RPM for D48 pump (200 when Diener 2000 enabled, 134 otherwise). *************************************************************************/ -U32 getD48MinPumpRPM( void ) +U32 getDialysatePumpMinRPM( DIALYSATE_PUMPS_T pumpId ) { U32 minRpm = MIN_DIALYSATE_PUMP_RPM; - if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) + 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 getD48MaxPumpRPM function returns the maximum 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_1000_PUMP. + * The getDialysatePumpMaxRPM function returns the maximum RPM limit for a + * given dialysate pump. + * @details \b Inputs: pumpId * @details \b Outputs: none - * @return Maximum RPM for D48 pump (2770 when Diener 1000 enabled, 2650 otherwise). +* @param pumpId to set the pump speed accordingly + * @return Maximum RPM for the specified pump *************************************************************************/ -U32 getD48MaxPumpRPM( void ) +U32 getDialysatePumpMaxRPM( DIALYSATE_PUMPS_T pumpId ) { U32 maxRpm = MAX_DIALYSATE_PUMP_RPM; - if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) + 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; @@ -234,14 +249,7 @@ dialysatePumpMeasuredCurrentA[ pumpId ].ovInitData = 0.0F; dialysatePumpMeasuredCurrentA[ pumpId ].ovData = 0.0F; dialysatePumpMeasuredCurrentA[ pumpId ].override = OVERRIDE_RESET; - if ( D48_PUMP == pumpId ) - { - dialysatePumps[ pumpId ].currentPumpSpeed = getD48MinPumpRPM(); - } - else - { - 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; @@ -276,8 +284,8 @@ // 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( getD48MinPumpRPM() ); + setFPGAD12PumpSpeed( getDialysatePumpMinRPM( D12_PUMP ) ); + setFPGAD48PumpSpeed( getDialysatePumpMinRPM( D48_PUMP ) ); #ifdef __PITEST__ for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) @@ -339,16 +347,8 @@ U32 minRPM; U32 maxRPM; - if ( D48_PUMP == pumpId ) - { - minRPM = getD48MinPumpRPM(); - maxRPM = getD48MaxPumpRPM(); - } - else - { - minRPM = MIN_DIALYSATE_PUMP_RPM; - maxRPM = MAX_DIALYSATE_PUMP_RPM; - } + minRPM = getDialysatePumpMinRPM( pumpId ); + maxRPM = getDialysatePumpMaxRPM( pumpId ); if ( pumpId < NUM_OF_DIALYSATE_PUMPS ) { @@ -411,24 +411,17 @@ { 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( getD48MinPumpRPM() ); + setFPGAD48PumpSpeed( getDialysatePumpMinRPM( D48_PUMP ) ); } // Reset all the variables to stop mode. - if ( D48_PUMP == pumpId ) - { - dialysatePumps[ pumpId ].currentPumpSpeed = getD48MinPumpRPM(); - } - else - { - dialysatePumps[ pumpId ].currentPumpSpeed = MIN_DIALYSATE_PUMP_RPM; - } + dialysatePumps[ pumpId ].currentPumpSpeed = getDialysatePumpMinRPM( pumpId ); pumpTargetSpeed[ pumpId ].data = 0.0F; dialysatePumps[ pumpId ].dialysatePumpState = DIALYSATE_PUMP_OFF_STATE; dialysatePumps[ pumpId ].controlTimerCounter = 0; @@ -728,17 +721,8 @@ { DIALYSATE_PUMP_STATE_T result = DIALYSATE_PUMP_OFF_STATE; F32 targetSpeed = getDialysatePumpTargetSpeed( pumpId ); - U32 minRPM; + U32 minRPM = getDialysatePumpMinRPM( pumpId ); - if ( D48_PUMP == pumpId ) - { - minRPM = getD48MinPumpRPM(); - } - else - { - minRPM = MIN_DIALYSATE_PUMP_RPM; - } - if ( targetSpeed >= minRPM ) { if ( D12_PUMP == pumpId ) @@ -807,7 +791,7 @@ F32 speedIncrease = 0.0F; BOOL hasTgtBeenReached = FALSE; F32 currentToTargetDiff = fabs( getDialysatePumpTargetSpeed( pumpId ) - dialysatePumps[ pumpId ].currentPumpSpeed ); - U32 minRPM; + U32 minRPM = getDialysatePumpMinRPM( pumpId ); if ( currentToTargetDiff > ZERO_SPEED ) { @@ -836,15 +820,6 @@ // } } - if ( D48_PUMP == pumpId ) - { - minRPM = getD48MinPumpRPM(); - } - else - { - minRPM = MIN_DIALYSATE_PUMP_RPM; - } - if ( dialysatePumps[ pumpId ].currentPumpSpeed >= minRPM ) { if ( D12_PUMP == pumpId ) @@ -1266,20 +1241,9 @@ if ( (DIALYSATE_PUMPS_T)payload.pumpID < NUM_OF_DIALYSATE_PUMPS ) { - U32 minRPM; - U32 maxRPM; + U32 minRPM = getDialysatePumpMinRPM( (DIALYSATE_PUMPS_T)payload.pumpID ); + U32 maxRPM = getDialysatePumpMaxRPM( (DIALYSATE_PUMPS_T)payload.pumpID ); - if ( D48_PUMP == (DIALYSATE_PUMPS_T)payload.pumpID ) - { - minRPM = getD48MinPumpRPM(); - maxRPM = getD48MaxPumpRPM(); - } - else - { - minRPM = MIN_DIALYSATE_PUMP_RPM; - maxRPM = MAX_DIALYSATE_PUMP_RPM; - } - // Handle start command. if ( ( TRUE == payload.startStop ) && ( ( payload.rpm >= minRPM ) && ( payload.rpm <= maxRPM ) ) ) Index: firmware/App/Controllers/DialysatePumps.h =================================================================== diff -u -rff8dde1e0c78936fc2db1aa496c9dce2e498e03b -r3d69f9a417c8473a16cc32f37db9b2c96faf7f6a --- firmware/App/Controllers/DialysatePumps.h (.../DialysatePumps.h) (revision ff8dde1e0c78936fc2db1aa496c9dce2e498e03b) +++ firmware/App/Controllers/DialysatePumps.h (.../DialysatePumps.h) (revision 3d69f9a417c8473a16cc32f37db9b2c96faf7f6a) @@ -84,8 +84,8 @@ void execDialysatePumpController( void ); SELF_TEST_STATUS_T execDialysatePumpSelfTest( void ); -U32 getD48MinPumpRPM( void ); -U32 getD48MaxPumpRPM( void ); +U32 getDialysatePumpMinRPM( DIALYSATE_PUMPS_T pumpId ); +U32 getDialysatePumpMaxRPM( DIALYSATE_PUMPS_T pumpId ); F32 getDialysatePumpTargetSpeed( DIALYSATE_PUMPS_T pumpId ); F32 getDialysatePumpMeasuredSpeed( DIALYSATE_PUMPS_T pumpId ); F32 getDialysatePumpTargetPressure( DIALYSATE_PUMPS_T pumpId ); Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -rb8888f36d5e2972edbf6931627859aa06bd128a6 -r3d69f9a417c8473a16cc32f37db9b2c96faf7f6a --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision b8888f36d5e2972edbf6931627859aa06bd128a6) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 3d69f9a417c8473a16cc32f37db9b2c96faf7f6a) @@ -145,7 +145,7 @@ bicarbFillStartTimeMS = 0; pendingSpentChamberFill = FALSE; pendingBicarbChamberFill = FALSE; - d48PumpSpeed = getD48MinPumpRPM(); + d48PumpSpeed = getDialysatePumpMinRPM( D48_PUMP ); //Testing bypassStateDelayStartTimeMS = 0; delayBypassStateFlag = TRUE; @@ -649,8 +649,10 @@ F32 dialFlowrate = getTDDialysateFlowrate(); F32 slope; F32 intercept; + F32 calculatedSpeed; + U32 rpm; - if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP ) ) + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP ) ) { slope = PUMP_SPEED_SLOPE_FACTOR_DIENER_1000; intercept = PUMP_SPEED_INTERCEPT_FACTOR_DIENER_1000; @@ -661,7 +663,18 @@ intercept = PUMP_SPEED_INTERCEPT_FACTOR_DIENER_2000; } - return (U32)( ( slope * dialFlowrate ) + intercept ); + // 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; } /*********************************************************************//** Index: firmware/App/Services/FpgaDD.c =================================================================== diff -u -r5b1c1736fdb7e6b6ac83687bbb8de2c2321cb1ff -r3d69f9a417c8473a16cc32f37db9b2c96faf7f6a --- firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision 5b1c1736fdb7e6b6ac83687bbb8de2c2321cb1ff) +++ firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision 3d69f9a417c8473a16cc32f37db9b2c96faf7f6a) @@ -1091,14 +1091,14 @@ *************************************************************************/ void setFPGAD48PumpSpeed( U16 speed ) { - if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP )) + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP )) { - U16 currentSpeed = (U16)( ( ( DIENER_1000_PUMP_SLOPE * speed ) + DIENER_1000_PUMP_INTERCEPT) * DIENER_1000_PUMP_SPEED_FULL_SCALE ); + U16 currentSpeed =(U16)( ( ( speed + PUMP_SPEED_OFFSET ) / PUMP_SPEED_FULL_SCALE ) * MAX_PUMP_SPEED ); SET_FPGA_ACTUATOR_FIELD( fpgaD48PumpSpeed, currentSpeed ); } else { - U16 currentSpeed =(U16)( ( ( speed + PUMP_SPEED_OFFSET ) / PUMP_SPEED_FULL_SCALE ) * MAX_PUMP_SPEED ); + U16 currentSpeed = (U16)( ( ( DIENER_1000_PUMP_SLOPE * speed ) + DIENER_1000_PUMP_INTERCEPT) * DIENER_1000_PUMP_SPEED_FULL_SCALE ); SET_FPGA_ACTUATOR_FIELD( fpgaD48PumpSpeed, currentSpeed ); } } @@ -1114,10 +1114,8 @@ *************************************************************************/ void setFPGAD12PumpSpeed( U16 speed ) { - U16 currentSpeed =(U16)( ( ( speed + PUMP_SPEED_OFFSET ) / PUMP_SPEED_FULL_SCALE ) * MAX_PUMP_SPEED ); SET_FPGA_ACTUATOR_FIELD( fpgaD12PumpSpeed, currentSpeed ); - } /*********************************************************************//**