Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r335c721d795f22c6dc4a24f5180dee3ba095a2b2 -r0772fa437a0f4bcbb58fbad9d6e1f0054efd0e28 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 335c721d795f22c6dc4a24f5180dee3ba095a2b2) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 0772fa437a0f4bcbb58fbad9d6e1f0054efd0e28) @@ -7,8 +7,8 @@ * * @file DialInFlow.c * -* @author (last) Dara Navaei -* @date (last) 21-May-2023 +* @author (last) Sean Nash +* @date (last) 17-Jul-2023 * * @author (original) Sean * @date (original) 16-Dec-2019 @@ -20,8 +20,9 @@ #include "etpwm.h" #include "gio.h" #include "mibspi.h" +#include "reg_het.h" -#include "Battery.h" +#include "CPLD.h" #include "DialInFlow.h" #include "FPGA.h" #include "InternalADC.h" @@ -46,6 +47,8 @@ /// Interval (ms/task time) at which the dialIn flow data is published on the CAN bus. #define DIAL_IN_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) +#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_DUTY_CYCLE 0.90F ///< Controller will error if PWM duty cycle > 90%, so set max to 90%. @@ -69,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. @@ -79,8 +82,9 @@ static const U32 DIP_OFF_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); /// Persist time (task intervals) motor speed error condition. static const U32 DIP_MOTOR_SPEED_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); -/// Rotor speed persist time test needs a minimum number of rotations. -static const U32 DIP_ROTOR_ERROR_PERSIST_ROTATION_MIN = 3; +/// Rotor speed persist time test needs a minimum number of rotations or time. +static const U32 DIP_ROTOR_ERROR_PERSIST_ROTATION_MIN = 10; +static const U32 DIP_ROTOR_ERROR_PERSIST_TIME_MIN = (10 * MS_PER_SECOND); /// Persist time (task intervals) pump direction error condition. static const U32 DIP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); /// Time threshold to trigger an alarm if Dialysate flow data has not arrived within 3 seconds @@ -125,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 @@ -157,9 +161,10 @@ NUM_OF_DIAL_IN_FLOW_SELF_TEST_STATES ///< Number of dialysate inlet pump self-test states. } DIAL_IN_FLOW_SELF_TEST_STATE_T; -// Pin assignments for pump stop and direction outputs +// Pin assignments for pump stop and direction outputs and DPi rotor hall sensor input #define STOP_DI_PUMP_GIO_PORT_PIN 2U ///< Pin # on GIO A for stopping the dialysate inlet pump. #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. @@ -300,7 +305,7 @@ // Don't interrupt pump control unless rate or mode is changing if ( ( dirFlowRate != targetDialInFlowRate ) || ( mode != dialInPumpControlMode ) ) { - BOOL isFlowRateInRange = ( flowRate <= MAX_DIAL_IN_FLOW_RATE ? TRUE : FALSE ); + BOOL isFlowRateInRange = ( flowRate <= MAX_SETTABLE_DIAL_IN_FLOW_RATE ? TRUE : FALSE ); #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMPS_FLOW_LIMITS ) ) @@ -509,7 +514,7 @@ } else { // Alarm if not receiving new dialysate flow readings in timely manner - if ( ( TRUE == isDGCommunicating() ) && ( FALSE == isACPowerLost() ) ) + if ( ( TRUE == isDGCommunicating() ) && ( getCPLDACPowerLossDetected() != TRUE ) ) { if ( ++dialysateFlowDataFreshStatusCounter > DIP_DIALYSATE_FLOW_DATA_ALARM_THRESHOLD ) { @@ -1069,15 +1074,17 @@ U32 getPumpRotorErrorPersistTime( F32 mtr_rpm, F32 gear_ratio ) { U32 err_persist_time = HEX_32_BIT_FULL_SCALE; // 49 days - U32 temporaryPersistentTimeout = 10 * MS_PER_SECOND; + F32 absMotRPM = fabs( mtr_rpm ); - if ( mtr_rpm > 0 ) + if ( absMotRPM > NEARLY_ZERO ) { /// Calculate persist time for rotor speed error condition. - err_persist_time = ( ( DIP_ROTOR_ERROR_PERSIST_ROTATION_MIN / ( mtr_rpm / gear_ratio / SEC_PER_MIN ) ) * MS_PER_SECOND ); + err_persist_time = ( ( (F32)DIP_ROTOR_ERROR_PERSIST_ROTATION_MIN / ( absMotRPM / gear_ratio / (F32)SEC_PER_MIN ) ) * (F32)MS_PER_SECOND ); + // Choose bigger value of MinTime or calculated persist time + err_persist_time = MAX(DIP_ROTOR_ERROR_PERSIST_TIME_MIN, err_persist_time); } - return err_persist_time + temporaryPersistentTimeout; + return err_persist_time; } /*********************************************************************//** @@ -1096,6 +1103,7 @@ { DIALIN_PUMP_STATUS_PAYLOAD_T payload; HD_OP_MODE_T opMode = getCurrentOperationMode(); + U32 hallSensor = gioGetBit( hetPORT1, DIP_ROTOR_HALL_SENSOR_NHET_ID ); payload.setPoint = targetDialInFlowRate; payload.measFlow = getMeasuredDialInFlowRate(); @@ -1113,6 +1121,7 @@ { payload.presFlow = 0; } + payload.rotorHall = ( hallSensor > 0 ? 0 : 1 ); // 1=home, 0=not home broadcastData( MSG_ID_DIALYSATE_FLOW_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&payload, sizeof( DIALIN_PUMP_STATUS_PAYLOAD_T ) ); dialInFlowDataPublicationTimerCounter = 0; } @@ -1235,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 @@ -1439,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 )