Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r2eacb97f43f15f317779635681ed81051828af4f -r2593d24ad372b16af13b5e7022a86498a4010ada --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 2eacb97f43f15f317779635681ed81051828af4f) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 2593d24ad372b16af13b5e7022a86498a4010ada) @@ -275,58 +275,64 @@ // Direction change while pump is running is not allowed if ( ( FALSE == isBloodPumpOn ) || ( 0 == flowRate ) || ( dir == bloodPumpDirectionSet ) ) - { + { + U32 dirFlowRate = ( dir == MOTOR_DIR_FORWARD ? (S32)flowRate : (S32)flowRate * -1 ); + + // Don't interrupt pump control unless rate or mode is changing + if ( ( dirFlowRate != targetBloodFlowRate ) || ( mode != bloodPumpControlMode ) ) + { #ifndef NO_PUMP_FLOW_LIMITS - // Verify flow rate - if ( flowRate <= MAX_SET_BLOOD_FLOW_RATE ) + // Verify flow rate + if ( flowRate <= MAX_SET_BLOOD_FLOW_RATE ) #endif - { - resetBloodPumpRPMMovingAverage(); - targetBloodFlowRate = ( dir == MOTOR_DIR_FORWARD ? (S32)flowRate : (S32)flowRate * -1 ); - bloodPumpDirection = dir; - bloodPumpControlMode = mode; - // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed - bloodPumpPWMDutyCyclePct = BP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) - - switch ( bloodPumpState ) { - case BLOOD_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp - if ( bloodPumpPWMDutyCyclePct < bloodPumpPWMDutyCyclePctSet ) - { - bloodPumpState = BLOOD_PUMP_RAMPING_DOWN_STATE; - } - break; + resetBloodPumpRPMMovingAverage(); + targetBloodFlowRate = dirFlowRate; + bloodPumpDirection = dir; + bloodPumpControlMode = mode; + // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed + bloodPumpPWMDutyCyclePct = BP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) - case BLOOD_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp - if ( bloodPumpPWMDutyCyclePct > bloodPumpPWMDutyCyclePctSet ) - { - bloodPumpState = BLOOD_PUMP_RAMPING_UP_STATE; - } - break; + switch ( bloodPumpState ) + { + case BLOOD_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp + if ( bloodPumpPWMDutyCyclePct < bloodPumpPWMDutyCyclePctSet ) + { + bloodPumpState = BLOOD_PUMP_RAMPING_DOWN_STATE; + } + break; - case BLOOD_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction - if ( bloodPumpPWMDutyCyclePctSet > bloodPumpPWMDutyCyclePct ) - { - bloodPumpState = BLOOD_PUMP_RAMPING_DOWN_STATE; - } - else - { - bloodPumpState = BLOOD_PUMP_RAMPING_UP_STATE; - } - break; + case BLOOD_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp + if ( bloodPumpPWMDutyCyclePct > bloodPumpPWMDutyCyclePctSet ) + { + bloodPumpState = BLOOD_PUMP_RAMPING_UP_STATE; + } + break; - default: - // Ok - not all states need to be handled here - break; + case BLOOD_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction + if ( bloodPumpPWMDutyCyclePctSet > bloodPumpPWMDutyCyclePct ) + { + bloodPumpState = BLOOD_PUMP_RAMPING_DOWN_STATE; + } + else + { + bloodPumpState = BLOOD_PUMP_RAMPING_UP_STATE; + } + break; + + default: + // Ok - not all states need to be handled here + break; + } + result = TRUE; } - result = TRUE; - } #ifndef NO_PUMP_FLOW_LIMITS - else // Requested flow rate too high - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_FLOW_SET_TOO_HIGH, flowRate ) - } -#endif + else // Requested flow rate too high + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_FLOW_SET_TOO_HIGH, flowRate ) + } +#endif + } } return result; Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -rc7890e8beda1708d2dea0762dcc40ca5a12222e3 -r2593d24ad372b16af13b5e7022a86498a4010ada --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision c7890e8beda1708d2dea0762dcc40ca5a12222e3) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 2593d24ad372b16af13b5e7022a86498a4010ada) @@ -262,54 +262,60 @@ // Direction change while pump is running is not allowed if ( ( FALSE == isDialInPumpOn ) || ( 0 == flowRate ) || ( dir == dialInPumpDirectionSet ) ) { + U32 dirFlowRate = ( dir == MOTOR_DIR_FORWARD ? (S32)flowRate : (S32)flowRate * -1 ); + + // Don't interrupt pump control unless rate or mode is changing + if ( ( dirFlowRate != targetDialInFlowRate ) || ( mode != dialInPumpControlMode ) ) + { #ifndef NO_PUMP_FLOW_LIMITS - // Verify flow rate - if ( flowRate <= MAX_DIAL_IN_FLOW_RATE ) + // Verify flow rate + if ( flowRate <= MAX_DIAL_IN_FLOW_RATE ) #endif - { - resetDialInFlowMovingAverage(); - targetDialInFlowRate = ( dir == MOTOR_DIR_FORWARD ? (S32)flowRate : (S32)flowRate * -1 ); - dialInPumpDirection = dir; - dialInPumpControlMode = mode; - // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed - dialInPumpPWMDutyCyclePct = DIP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) - - switch ( dialInPumpState ) { - case DIAL_IN_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp - if ( dialInPumpPWMDutyCyclePct < dialInPumpPWMDutyCyclePctSet ) - { - dialInPumpState = DIAL_IN_PUMP_RAMPING_DOWN_STATE; - } - break; - case DIAL_IN_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp - if ( dialInPumpPWMDutyCyclePct > dialInPumpPWMDutyCyclePctSet ) - { - dialInPumpState = DIAL_IN_PUMP_RAMPING_UP_STATE; - } - break; - case DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction - if ( dialInPumpPWMDutyCyclePctSet > dialInPumpPWMDutyCyclePct ) - { - dialInPumpState = DIAL_IN_PUMP_RAMPING_DOWN_STATE; - } - else - { - dialInPumpState = DIAL_IN_PUMP_RAMPING_UP_STATE; - } - break; - default: - // Ok - not all states need to be handled here - break; + resetDialInFlowMovingAverage(); + targetDialInFlowRate = dirFlowRate; + dialInPumpDirection = dir; + dialInPumpControlMode = mode; + // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed + dialInPumpPWMDutyCyclePct = DIP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) + + switch ( dialInPumpState ) + { + case DIAL_IN_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp + if ( dialInPumpPWMDutyCyclePct < dialInPumpPWMDutyCyclePctSet ) + { + dialInPumpState = DIAL_IN_PUMP_RAMPING_DOWN_STATE; + } + break; + case DIAL_IN_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp + if ( dialInPumpPWMDutyCyclePct > dialInPumpPWMDutyCyclePctSet ) + { + dialInPumpState = DIAL_IN_PUMP_RAMPING_UP_STATE; + } + break; + case DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction + if ( dialInPumpPWMDutyCyclePctSet > dialInPumpPWMDutyCyclePct ) + { + dialInPumpState = DIAL_IN_PUMP_RAMPING_DOWN_STATE; + } + else + { + dialInPumpState = DIAL_IN_PUMP_RAMPING_UP_STATE; + } + break; + default: + // Ok - not all states need to be handled here + break; + } + result = TRUE; } - result = TRUE; - } #ifndef NO_PUMP_FLOW_LIMITS - else // Requested flow rate too high - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_IN_FLOW_SET_TOO_HIGH, flowRate ) - } -#endif + else // Requested flow rate too high + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_IN_FLOW_SET_TOO_HIGH, flowRate ) + } +#endif + } } return result; Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -r3d8d8451d10aaf2ea9fc9d83857699ef1ae1a0be -r2593d24ad372b16af13b5e7022a86498a4010ada --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 3d8d8451d10aaf2ea9fc9d83857699ef1ae1a0be) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 2593d24ad372b16af13b5e7022a86498a4010ada) @@ -255,58 +255,62 @@ // Direction change while pump is running is not allowed if ( ( FALSE == isDialOutPumpOn ) || ( 0 == flowRate ) || ( dir == dialOutPumpDirectionSet ) ) { + F32 pwmDC = DOP_PWM_FROM_ML_PER_MIN( (F32)flowRate ); + + // Don't interrupt pump control unless rate or mode is changing + if ( ( fabs( pwmDC - dialOutPumpPWMDutyCyclePct ) > NEARLY_ZERO ) || ( mode != dialOutPumpControlMode ) ) + { #ifndef NO_PUMP_FLOW_LIMITS - // Verify flow rate - if ( flowRate <= MAX_DIAL_OUT_FLOW_RATE ) + // Verify flow rate + if ( flowRate <= MAX_DIAL_OUT_FLOW_RATE ) #endif - { - F32 adjFlow = (F32)flowRate; - - resetDialOutFlowMovingAverage(); - dopControlSignal = FALSE; - lastGivenRate = flowRate; - dialOutPumpDirection = dir; - dialOutPumpControlMode = mode; - // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed - dialOutPumpPWMDutyCyclePct = DOP_PWM_FROM_ML_PER_MIN(adjFlow); - dialOutPumpPWMDutyCyclePct = MIN( dialOutPumpPWMDutyCyclePct, MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE ); - - switch ( dialOutPumpState ) { - case DIAL_OUT_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp - if ( dialOutPumpPWMDutyCyclePct < dialOutPumpPWMDutyCyclePctSet ) - { - dialOutPumpState = DIAL_OUT_PUMP_RAMPING_DOWN_STATE; - } - break; - case DIAL_OUT_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp - if ( dialOutPumpPWMDutyCyclePct > dialOutPumpPWMDutyCyclePctSet ) - { - dialOutPumpState = DIAL_OUT_PUMP_RAMPING_UP_STATE; - } - break; - case DIAL_OUT_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction - if ( dialOutPumpPWMDutyCyclePctSet > dialOutPumpPWMDutyCyclePct ) - { - dialOutPumpState = DIAL_OUT_PUMP_RAMPING_DOWN_STATE; - } - else - { - dialOutPumpState = DIAL_OUT_PUMP_RAMPING_UP_STATE; - } - break; - default: - // Ok - not all states need to be handled here - break; + resetDialOutFlowMovingAverage(); + dopControlSignal = FALSE; + lastGivenRate = flowRate; + dialOutPumpDirection = dir; + dialOutPumpControlMode = mode; + // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed + dialOutPumpPWMDutyCyclePct = pwmDC; + dialOutPumpPWMDutyCyclePct = MIN( dialOutPumpPWMDutyCyclePct, MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE ); + + switch ( dialOutPumpState ) + { + case DIAL_OUT_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp + if ( dialOutPumpPWMDutyCyclePct < dialOutPumpPWMDutyCyclePctSet ) + { + dialOutPumpState = DIAL_OUT_PUMP_RAMPING_DOWN_STATE; + } + break; + case DIAL_OUT_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp + if ( dialOutPumpPWMDutyCyclePct > dialOutPumpPWMDutyCyclePctSet ) + { + dialOutPumpState = DIAL_OUT_PUMP_RAMPING_UP_STATE; + } + break; + case DIAL_OUT_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction + if ( dialOutPumpPWMDutyCyclePctSet > dialOutPumpPWMDutyCyclePct ) + { + dialOutPumpState = DIAL_OUT_PUMP_RAMPING_DOWN_STATE; + } + else + { + dialOutPumpState = DIAL_OUT_PUMP_RAMPING_UP_STATE; + } + break; + default: + // Ok - not all states need to be handled here + break; + } + result = TRUE; } - result = TRUE; - } #ifndef NO_PUMP_FLOW_LIMITS - else // Requested flow rate too high - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_OUT_FLOW_SET_TOO_HIGH, flowRate ) - } + else // Requested flow rate too high + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_OUT_FLOW_SET_TOO_HIGH, flowRate ) + } #endif + } } return result;