Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -rc52bfbc3f41fecde11bbec3eb71dc812154fc760 -rd27dcf1fbbc9651636f211028917a1c0702bb56a --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision c52bfbc3f41fecde11bbec3eb71dc812154fc760) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) @@ -62,7 +62,9 @@ /// Number of hall sensor counts kept in buffer to hold last 1 second of count data. #define BP_SPEED_CALC_BUFFER_LEN ( MS_PER_SECOND / BP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) #define BP_MAX_ROTOR_SPEED_RPM 100.0 ///< Maximum rotor speed allowed for blood pump. - + +#define BP_MAX_FLOW_RATE 1320.0 ///< Maximum measured BP flow rate allowed. +#define BP_MIN_FLOW_RATE -1320.0 ///< Minimum measured BP flow rate allowed. #define BP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured speed and speed implied by measured flow. #define BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0 ///< Maximum motor speed (RPM) while motor is commanded off. #define BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< Maximum difference in speed between motor and rotor (in rotor RPM). @@ -78,7 +80,9 @@ /// Persist time (task intervals) pump direction error condition. static const U32 BP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); /// Persist time (task intervals) blood pump rotor speed too fast error condition. -static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) blood flow rate out of range error condition. +static const U32 BP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); #define BP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped #define BP_MAX_CURR_WHEN_RUNNING_MA 2000.0 ///< Motor controller current should not exceed this when pump should be running @@ -97,8 +101,14 @@ #define BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( BP_REV_PER_LITER / ML_PER_LITER ) ///< Conversion factor from mL/min to motor RPM. #define BP_GEAR_RATIO 32.0 ///< Blood pump motor to blood pump gear ratio #define BP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed -/// Conversion factor from mL/min to estimated PWM duty cycle %. -#define BP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * BP_GEAR_RATIO * BP_MOTOR_RPM_TO_PWM_DC_FACTOR + BP_PWM_ZERO_OFFSET ) +/// Conversion macro from mL/min to estimated PWM duty cycle %. +#define BP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * BP_GEAR_RATIO * BP_MOTOR_RPM_TO_PWM_DC_FACTOR + BP_PWM_ZERO_OFFSET ) +/// Conversion from PWM duty cycle % to commanded pump motor speed. +#ifndef V2_0_SYSTEM + #define BP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - BP_PWM_ZERO_OFFSET) * 4000.0 ) +#else + #define BP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - BP_PWM_ZERO_OFFSET) * 3200.0 ) +#endif #define BLOODPUMP_ADC_FULL_SCALE_V 3.0 ///< BP analog signals are 0-3V (while int. ADC ref may be different) #define BLOODPUMP_ADC_ZERO 1998 ///< Blood pump ADC channel zero offset. @@ -269,6 +279,7 @@ initPersistentAlarm( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, 0, BLOOD_FLOW_FAST_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_BP_FLOW_SLOW_READ_TIMEOUT_ERROR, 0, BLOOD_FLOW_SLOW_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_BP_FLOW_SENSOR_ERROR, 0, BLOOD_FLOW_COMM_ERROR_PERSIST ); + initPersistentAlarm( ALARM_ID_HD_BLOOD_FLOW_OUT_OF_RANGE, 0, BP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST ); } /*********************************************************************//** @@ -291,7 +302,7 @@ { #ifndef NO_PUMP_FLOW_LIMITS // Verify flow rate - if ( flowRate <= MAX_BLOOD_FLOW_RATE ) + if ( flowRate <= MAX_SET_BLOOD_FLOW_RATE ) #endif { resetBloodFlowMovingAverage(); @@ -611,7 +622,7 @@ bloodPumpPWMDutyCyclePctSet = bloodPumpPWMDutyCyclePct; resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); bloodPumpControlModeSet = bloodPumpControlMode; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePct ); + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); bpControlTimerCounter = 0; result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; } @@ -650,7 +661,7 @@ bloodPumpPWMDutyCyclePctSet = bloodPumpPWMDutyCyclePct; resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); bloodPumpControlModeSet = bloodPumpControlMode; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePct ); + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); bpControlTimerCounter = 0; result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; } @@ -719,7 +730,7 @@ static void stopBloodPump( void ) { isBloodPumpOn = FALSE; - bloodPumpPWMDutyCyclePctSet = 0.0; + bloodPumpPWMDutyCyclePctSet = BP_PWM_ZERO_OFFSET; etpwmSetCmpA( etpwmREG1, 0 ); SET_BP_STOP(); } @@ -1131,10 +1142,10 @@ static void checkBloodPumpSpeeds( void ) { F32 measMotorSpeed = fabs( getMeasuredBloodPumpSpeed() ); - S32 cmdRate = targetBloodFlowRate; - - // Check for pump running while commanded off - if ( 0 == cmdRate ) + F32 measMCMotorSpeed = fabs( getMeasuredBloodPumpMCSpeed() ); + + // Check for pump running while commanded off + if ( 0 == targetBloodFlowRate ) { if ( measMotorSpeed > BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) { @@ -1154,23 +1165,25 @@ else { errorBloodMotorOffPersistTimerCtr = 0; - } - + } + + // Checks that only occur when pump is running (and beyond ramp). if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) { - F32 cmdMotorSpeed = ( (F32)cmdRate / (F32)ML_PER_LITER ) * BP_REV_PER_LITER * BP_GEAR_RATIO; - F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); + F32 cmdMotorSpeed = BP_PWM_TO_MOTOR_SPEED_RPM( bloodPumpPWMDutyCyclePctSet ); + F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); + F32 deltaMCMotorSpeed = fabs( measMCMotorSpeed - cmdMotorSpeed ); F32 measRotorSpeed = getMeasuredBloodPumpRotorSpeed(); F32 measMotorSpeedInRotorRPM = measMotorSpeed / BP_GEAR_RATIO; F32 deltaRotorSpeed = fabs( measRotorSpeed - measMotorSpeedInRotorRPM ); // Check measured motor speed vs. commanded motor speed while controlling to target - if ( deltaMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) + if ( ( deltaMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) || ( deltaMCMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) ) { if ( ++errorBloodMotorSpeedPersistTimerCtr >= BP_MOTOR_SPEED_ERROR_PERSIST ) { #ifndef DISABLE_PUMP_SPEED_CHECKS - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, (F32)cmdRate, measMotorSpeed ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, cmdMotorSpeed, measMotorSpeed ); #endif } } @@ -1213,10 +1226,19 @@ *************************************************************************/ static void checkBloodPumpFlowAgainstSpeed( void ) { - // Check only performed while in treatment mode and while we are in control to target state + F32 flow = getMeasuredBloodFlowRate(); + + // Range check on measure BP flow rate. +#ifndef DISABLE_PUMP_FLOW_CHECKS + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BLOOD_FLOW_OUT_OF_RANGE, ( flow > BP_MAX_FLOW_RATE ) || ( flow < BP_MIN_FLOW_RATE ) ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_BLOOD_FLOW_OUT_OF_RANGE, flow ); + } +#endif + + // Flow vs. speed check only performed while in treatment mode and while we are in control to target state if ( ( MODE_TREA == getCurrentOperationMode() ) && ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) ) { - F32 flow = getMeasuredBloodFlowRate(); F32 speed = getMeasuredBloodPumpSpeed(); F32 impliedSpeed = ( flow / (F32)ML_PER_LITER ) * BP_REV_PER_LITER * BP_GEAR_RATIO; F32 delta = fabs( speed - impliedSpeed );