Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r6d19d844800eaaa05d03561c7f6e2d882de2c1ff -rcd5be724d5a3ba7457e761191d82f278654d7f5c --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 6d19d844800eaaa05d03561c7f6e2d882de2c1ff) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision cd5be724d5a3ba7457e761191d82f278654d7f5c) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2024 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 DialInFlow.c * -* @author (last) Sean Nash -* @date (last) 06-Jun-2023 +* @author (last) Dara Navaei +* @date (last) 10-Oct-2023 * * @author (original) Sean * @date (original) 16-Dec-2019 @@ -22,7 +22,7 @@ #include "mibspi.h" #include "reg_het.h" -#include "Battery.h" +#include "CPLD.h" #include "DialInFlow.h" #include "FPGA.h" #include "InternalADC.h" @@ -49,17 +49,17 @@ #define MAX_SETTABLE_DIAL_IN_FLOW_RATE 700 ///< Maximum settable dialysate inlet flow rate (in mL/min). -#define MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE 0.0133F ///< Max duty cycle change when ramping up ~ 200 mL/min/s. -#define MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE 0.02F ///< Max duty cycle change when ramping down ~ 300 mL/min/s. +#define MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE 0.01064F ///< Max duty cycle change when ramping up. +#define MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE 0.016F ///< Max duty cycle change when ramping down. #define MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.90F ///< Controller will error if PWM duty cycle > 90%, so set max to 90%. #define MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.10F ///< Controller will error if PWM duty cycle < 10%, so set min to 10%. #define MIN_DG_DIAL_FLOW_RATE 10.0F ///< Minimum DG Dialysate Flow Rate (mL/Min) #define DIP_CONTROL_INTERVAL_SEC 4 ///< Dialysate inlet pump control interval (in seconds). /// Interval (ms/task time) at which the dialIn pump is controlled. static const U32 DIP_CONTROL_INTERVAL = ( DIP_CONTROL_INTERVAL_SEC * MS_PER_SECOND / TASK_GENERAL_INTERVAL ); -#define DIP_P_COEFFICIENT 0.0001F ///< P term for dialIn pump control. -#define DIP_I_COEFFICIENT 0.00075F ///< I term for dialIn pump control. +#define DIP_P_COEFFICIENT 0.00008F ///< P term for dialIn pump control. +#define DIP_I_COEFFICIENT 0.00060F ///< I term for dialIn pump control. #define DIP_HOME_SPEED 400 ///< Target pump speed (in RPM) for homing. #define DIP_HOME_TIMEOUT_MS 10000 ///< Maximum time allowed for homing to complete (in ms). @@ -72,7 +72,7 @@ #define DIP_MAX_FLOW_RATE 1320.0F ///< Maximum measured BP flow rate allowed. #define DIP_MIN_FLOW_RATE -1320.0F ///< Minimum measured BP flow rate allowed. #define DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0F ///< Maximum motor speed (RPM) while motor is commanded off. -#define DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 2.0F ///< Maximum difference in speed between motor and rotor (in rotor RPM). +#define DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0F ///< Maximum difference in speed between motor and rotor (in rotor RPM). #define DIP_MAX_MOTOR_SPEED_ERROR_RPM 300.0F ///< Maximum difference in speed between measured and commanded RPM. #define DIP_MAX_MOTOR_SPEED_VS_TRGT_DIFF_PCT 0.15F ///< Maximum motor speed vs target difference in percent. @@ -100,16 +100,16 @@ ///< Macro converts a 12-bit ADC reading to a signed 16-bit value. #define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DIAL_IN_PUMP_ADC_ZERO ) -#define DIP_SPEED_ADC_TO_RPM_FACTOR 1.751752F ///< Conversion factor from ADC counts to RPM for dialIn pump motor (3500 RPM/1998 counts). -#define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.000238F ///< ~42 BP motor RPM = 1% PWM duty cycle +#define DIP_SPEED_ADC_TO_RPM_FACTOR 2.152152F ///< Conversion factor from ADC counts to RPM for dialIn pump motor (4300 RPM/1998 counts). +#define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.0002F ///< ~50 BP motor RPM = 1% PWM duty cycle #define DIP_CURRENT_ADC_TO_MA_FACTOR 3.002F ///< Conversion factor from ADC counts to mA for dialIn pump motor. #define DIP_REV_PER_LITER 146.84F ///< Rotor revolutions per liter. /// Macro converts flow rate to motor RPM. #define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) #define DIP_GEAR_RATIO 32.0F ///< DialIn pump motor to dialIn pump gear ratio. #define DIP_PWM_ZERO_OFFSET 0.1F ///< 10% PWM duty cycle = zero speed. -#define DIP_100_PCT_PWM_RPM_RANGE 4000.0F ///< 10-90% PWM range yields 0-3,200 RPM range. Full 100% PWM range would yield 4,000 RPM range. +#define DIP_100_PCT_PWM_RPM_RANGE 5000.0F ///< 10-90% PWM range yields 0-4,000 RPM range. Full 100% PWM range would yield 5,000 RPM range. /// Conversion from PWM duty cycle % to commanded pump motor speed. PWM range is 10% to 90%. RPM range is 0 to 3200. 3200 / 0.8 = 4000. #define DIP_PWM_TO_MOTOR_SPEED_RPM(pwm,dir) ( ( ((pwm) - DIP_PWM_ZERO_OFFSET) * DIP_100_PCT_PWM_RPM_RANGE ) * ( dir == MOTOR_DIR_FORWARD ? 1.0F : -1.0F ) ) @@ -129,14 +129,14 @@ #define DATA_PUBLISH_COUNTER_START_COUNT 30 ///< Data publish counter start count. //Hybrid flow rate algorithm parameters -#define DIAL_IN_FLOW_A_ZERO 1.267F ///< Y intercept used for alpha flow coefficient calculation. -#define DIAL_IN_FLOW_WEAR_A_TERM 0.000000003551F ///< A term used for wear portion of alpha flow coefficient (m'). -#define DIAL_IN_FLOW_WEAR_B_TERM 0.002244F ///< B term used for wear portion of alpha flow coefficient (m0). +#define DIAL_IN_FLOW_A_ZERO 1.033F ///< Y intercept used for alpha flow coefficient calculation. +#define DIAL_IN_FLOW_WEAR_A_TERM 0.000000001478F ///< A term used for wear portion of alpha flow coefficient (m'). +#define DIAL_IN_FLOW_WEAR_B_TERM 0.00006284F ///< B term used for wear portion of alpha flow coefficient (m0). #define DIAL_IN_FLOW_QHIGHTRANSITION 400.0F ///< High flow rate transition for blended algorithm #define DIAL_IN_FLOW_QLOWTRANSITION 300.0F ///< Low flow rate transition for blended algorithm -#define DIAL_IN_FLOW_PEST_A_TERM -0.000491F ///< a (2nd order) term in polynomial fit for pressure estimation -#define DIAL_IN_FLOW_PEST_B_TERM -0.04672F ///< b (first order) term in polynomial fit for pressure estimation -#define DIAL_IN_FLOW_PEST_C_TERM 18.648F ///< c (zero order) term in polynomial fit for pressure estimation +#define DIAL_IN_FLOW_PEST_A_TERM -0.0004538F ///< a (2nd order) term in polynomial fit for pressure estimation +#define DIAL_IN_FLOW_PEST_B_TERM -0.1022F ///< b (first order) term in polynomial fit for pressure estimation +#define DIAL_IN_FLOW_PEST_C_TERM 17.835F ///< c (zero order) term in polynomial fit for pressure estimation #define DIAL_IN_MAX_ROTOR_COUNT_FOR_WEAR 25000 ///< Maximum rotor count for determining wear of the cartridge (negligible affect beyond this threshold). #define DIAL_IN_STROKE_VOLUME 3.405 ///< Stroke volume (SV) used for Flow Estimation ALgorithm #define DIAL_IN_GEAR_RATIO 32 ///< Gear ratio used for Flow Estimation ALgorithm @@ -166,10 +166,10 @@ #define DIR_DI_PUMP_SPI5_PORT_MASK 0x00000100 ///< Pin on unused SPI5 peripheral (ENA) - re-purposed as output GPIO to set dialysate inlet pump direction. #define DIP_ROTOR_HALL_SENSOR_NHET_ID 0x0000001E ///< NHET pin number associated with DPi rotor hall sensor input // DialIn pump stop and direction macros -#define SET_DIP_DIR() {mibspiREG5->PC3 |= DIR_DI_PUMP_SPI5_PORT_MASK;} ///< Macro for setting the dialysate inlet pump direction pin high. -#define CLR_DIP_DIR() {mibspiREG5->PC3 &= ~DIR_DI_PUMP_SPI5_PORT_MASK;} ///< Macro for setting the dialysate inlet pump direction pin low. -#define SET_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) ///< Macro for setting the dialysate inlet pump stop pin low. -#define CLR_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) ///< Macro for setting the dialysate inlet pump stop pin high. +#define SET_DIP_DIR() {mibspiREG5->PC3 |= DIR_DI_PUMP_SPI5_PORT_MASK;} ///< Macro for setting the dialysate inlet pump direction pin high (forward). +#define CLR_DIP_DIR() {mibspiREG5->PC3 &= ~DIR_DI_PUMP_SPI5_PORT_MASK;} ///< Macro for setting the dialysate inlet pump direction pin low (reverse). +#define SET_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) ///< Macro for setting the dialysate inlet pump disable pin low (disable). +#define CLR_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) ///< Macro for setting the dialysate inlet pump disable pin high (enable). // ********** private data ********** @@ -514,7 +514,7 @@ } else { // Alarm if not receiving new dialysate flow readings in timely manner - if ( ( TRUE == isDGCommunicating() ) && ( isACPowerLost() != TRUE ) ) + if ( ( TRUE == isDGCommunicating() ) && ( getCPLDACPowerLossDetected() != TRUE ) ) { if ( ++dialysateFlowDataFreshStatusCounter > DIP_DIALYSATE_FLOW_DATA_ALARM_THRESHOLD ) { @@ -837,7 +837,7 @@ F32 calculatedFlow = ( motorRPM * 2 * DIAL_IN_STROKE_VOLUME/DIAL_IN_GEAR_RATIO ) * alphaTerm; - if ( ( QdTarget < DIAL_IN_FLOW_QHIGHTRANSITION ) && ( QdTarget > DIAL_IN_FLOW_QLOWTRANSITION ) ) + if ( QdTarget > DIAL_IN_FLOW_QLOWTRANSITION ) { // use blended flow rate calculation estimatedFlow = ( ( QdTarget - DIAL_IN_FLOW_QLOWTRANSITION ) / ( DIAL_IN_FLOW_QHIGHTRANSITION - DIAL_IN_FLOW_QLOWTRANSITION ) ) * filteredDialInFlowMeterReading + ( ( DIAL_IN_FLOW_QHIGHTRANSITION - QdTarget ) / ( DIAL_IN_FLOW_QHIGHTRANSITION - DIAL_IN_FLOW_QLOWTRANSITION ) ) * calculatedFlow; @@ -1244,7 +1244,7 @@ MOTOR_DIR_T dipMCDir, dipDir; U08 dirErrorCnt = getFPGADialInPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; F32 measMCSpeed = getMeasuredDialInPumpMCSpeed(); - BOOL minDirSpeed = ( measMCSpeed >= DIP_MIN_DIR_CHECK_SPEED_RPM ? TRUE : FALSE ); + BOOL minDirSpeed = ( fabs( measMCSpeed ) >= DIP_MIN_DIR_CHECK_SPEED_RPM ? TRUE : FALSE ); BOOL isHallSensorFailed = ( TRUE == minDirSpeed && lastDialInPumpDirectionCount != dirErrorCnt ? TRUE : FALSE ); // Check pump direction error count @@ -1448,7 +1448,7 @@ F32 dipCurr; // only check current when we have A/C power - if ( FALSE == isACPowerLost() ) + if ( getCPLDACPowerLossDetected() != TRUE ) { // DialIn pump should be off if ( DIAL_IN_PUMP_OFF_STATE == dialInPumpState )