Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r5545719a6bde1e93991c25918d975024b44c1b43 -r2254b04e7e2dd959b2778e063eb6e6fedf09781f --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 5545719a6bde1e93991c25918d975024b44c1b43) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 2254b04e7e2dd959b2778e063eb6e6fedf09781f) @@ -67,17 +67,17 @@ #define BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< Maximum difference in speed between motor and rotor (in rotor RPM). #define BP_MAX_MOTOR_SPEED_ERROR_RPM 300.0 ///< Maximum difference in speed between measured and commanded RPM. /// Persist time (task intervals) for flow vs. motor speed error condition. -static const U32 BP_FLOW_VS_SPEED_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +static const U32 BP_FLOW_VS_SPEED_PERSIST = ( 5 * MS_PER_SECOND ); /// Persist time (task intervals) for motor off error condition. -static const U32 BP_OFF_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +static const U32 BP_OFF_ERROR_PERSIST = ( 5 * MS_PER_SECOND ); /// Persist time (task intervals) motor speed error condition. -static const U32 BP_MOTOR_SPEED_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +static const U32 BP_MOTOR_SPEED_ERROR_PERSIST = ( 5 * MS_PER_SECOND ); /// Persist time (task intervals) rotor speed error condition. -static const U32 BP_ROTOR_SPEED_ERROR_PERSIST = ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +static const U32 BP_ROTOR_SPEED_ERROR_PERSIST = ( 12 * MS_PER_SECOND ); /// 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_DIRECTION_ERROR_PERSIST = ( 250 ); +/// Persist time period blood pump rotor speed too fast error condition. +static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ( 1 * MS_PER_SECOND ); #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 @@ -184,13 +184,6 @@ static U32 bpMotorSpeedCalcIdx = 0; ///< Index into 1 second buffer of motor speed hall sensor counts static U32 bpMotorSpeedCalcTimerCtr = 0; ///< Counter determines interval for calculating blood pump motor speed from hall sensor count. -static U32 errorBloodFlowVsMotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for flow vs. motor speed error condition. -static U32 errorBloodMotorOffPersistTimerCtr = 0; ///< Persistence timer counter for motor off check error condition. -static U32 errorBloodMotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for motor speed error condition. -static U32 errorBloodRotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for rotor speed error condition. -static U32 errorBloodPumpDirectionPersistTimerCtr = 0; ///< Persistence timer counter for pump direction error condition. -static U32 errorBloodPumpRotorTooFastPersistTimerCtr = 0; ///< Persistence timer counter for pump rotor too fast error condition. - static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; ///< Holds flow samples for a rolling average static U32 flowReadingsIdx = 0; ///< Index for next sample in rolling average array static F32 flowReadingsTotal = 0.0; ///< Rolling total - used to calc average @@ -253,8 +246,15 @@ BP_P_COEFFICIENT, BP_I_COEFFICIENT, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE ); - // Initialize persistent alarm for flow sensor signal strength too low - initPersistentAlarm( ALARM_ID_BLOOD_FLOW_SIGNAL_STRENGTH_TOO_LOW, FLOW_SIG_STRGTH_ALARM_PERSIST, FLOW_SIG_STRGTH_ALARM_PERSIST ); + // Initialize persistent alarm for flow sensor + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, 0, BP_FLOW_VS_SPEED_PERSIST ); + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_OFF_CHECK, 0, BP_OFF_ERROR_PERSIST ); + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, 0, BP_MOTOR_SPEED_ERROR_PERSIST ); + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK, 0, BP_ROTOR_SPEED_ERROR_PERSIST ); + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, 0, BP_DIRECTION_ERROR_PERSIST ); + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH, 0, BP_MAX_ROTOR_SPEED_ERROR_PERSIST ); + initPersistentAlarm( ALARM_ID_BLOOD_FLOW_SIGNAL_STRENGTH_TOO_LOW, 0, FLOW_SIG_STRGTH_ALARM_PERSIST ); + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, 0, BP_MAX_CURR_ERROR_DURATION_MS ); 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 ); } @@ -1030,17 +1030,10 @@ // TODO - alarm??? } - // Ensure rotor speed below maximum - if ( rotorSpeed > BP_MAX_ROTOR_SPEED_RPM ) - { - if ( ++errorBloodPumpRotorTooFastPersistTimerCtr >= BP_MAX_ROTOR_SPEED_ERROR_PERSIST ) - { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH, rotorSpeed ) - } - } - else + // Ensure rotor speed below maximum + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH, rotorSpeed > BP_MAX_ROTOR_SPEED_RPM ) ) { - errorBloodPumpRotorTooFastPersistTimerCtr = 0; + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH, rotorSpeed ) } // If pump is stopped or running very slowly, set rotor speed to zero @@ -1063,6 +1056,7 @@ if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) { MOTOR_DIR_T bpMCDir, bpDir; + BOOL isDirIncorrect; U08 dirErrorCnt = getFPGABloodPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; // Check pump direction error count @@ -1075,35 +1069,26 @@ bpMCDir = ( getMeasuredBloodPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); bpDir = ( getMeasuredBloodPumpSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); - // Check set direction vs. direction from hall sensors - if ( bloodPumpDirectionSet != bpDir ) - { - if ( ++errorBloodPumpDirectionPersistTimerCtr >= BP_DIRECTION_ERROR_PERSIST ) - { -#ifndef DISABLE_PUMP_DIRECTION_CHECKS - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, (U32)bloodPumpDirectionSet, (U32)bpDir ) -#endif - } - } - // Check set direction vs. direction from sign of motor controller speed - else if ( bloodPumpDirectionSet != bpMCDir ) + // Check set direction vs. direction from hall sensors vs. direction from sign of motor controller speed + isDirIncorrect = ( bloodPumpDirectionSet != bpDir ) || ( bloodPumpDirectionSet != bpMCDir ); + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, isDirIncorrect ) ) { - if ( ++errorBloodPumpDirectionPersistTimerCtr >= BP_DIRECTION_ERROR_PERSIST ) - { #ifndef DISABLE_PUMP_DIRECTION_CHECKS + if ( bloodPumpDirectionSet != bpDir ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, (U32)bloodPumpDirectionSet, (U32)bpDir ) + } + else + { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, (U32)bloodPumpDirectionSet, (U32)bpMCDir ) -#endif } +#endif } - else - { - errorBloodPumpDirectionPersistTimerCtr = 0; - } } else { - errorBloodPumpDirectionPersistTimerCtr = 0; - } + resetPersistentAlarmTimer( ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK ); + } } /*********************************************************************//** @@ -1124,27 +1109,13 @@ S32 cmdRate = targetBloodFlowRate; // Check for pump running while commanded off - if ( 0 == cmdRate ) - { - if ( measMotorSpeed > BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) - { - if ( ++errorBloodMotorOffPersistTimerCtr >= BP_OFF_ERROR_PERSIST ) - { + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_OFF_CHECK, ( 0 == cmdRate ) && ( measMotorSpeed > BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) ) ) + { #ifndef DISABLE_PUMP_SPEED_CHECKS - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_OFF_CHECK, measMotorSpeed ); - activateSafetyShutdown(); + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_OFF_CHECK, measMotorSpeed ); + activateSafetyShutdown(); #endif - } - } - else - { - errorBloodMotorOffPersistTimerCtr = 0; - } } - else - { - errorBloodMotorOffPersistTimerCtr = 0; - } if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) { @@ -1154,41 +1125,27 @@ 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 ( ++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 ); + // Check measured motor speed vs. commanded motor speed while controlling to target + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, deltaMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) ) + { +#ifndef DISABLE_PUMP_SPEED_CHECKS + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, (F32)cmdRate, measMotorSpeed ); #endif - } } - else - { - errorBloodMotorSpeedPersistTimerCtr = 0; - } - // Check measured rotor speed vs. measured motor speed while controlling to target - if ( deltaRotorSpeed > BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM ) - { - if ( ++errorBloodRotorSpeedPersistTimerCtr >= BP_ROTOR_SPEED_ERROR_PERSIST ) - { -#ifndef DISABLE_PUMP_SPEED_CHECKS - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK, measRotorSpeed, measMotorSpeed ); + // Check measured rotor speed vs. measured motor speed while controlling to target + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK, deltaRotorSpeed > BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM ) ) + { +#ifndef DISABLE_PUMP_SPEED_CHECKS + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK, measRotorSpeed, measMotorSpeed ); #endif - } } - else - { - errorBloodRotorSpeedPersistTimerCtr = 0; - } + } + else + { + resetPersistentAlarmTimer( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK ); + resetPersistentAlarmTimer( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK ); } - else - { - errorBloodMotorSpeedPersistTimerCtr = 0; - errorBloodRotorSpeedPersistTimerCtr = 0; - } } /*********************************************************************//** @@ -1197,38 +1154,31 @@ * against the implied flow of the measured pump speed when in treatment mode * and controlling to target flow. If a sufficient difference persists, a * flow vs. motor speed check error is triggered. - * @details Inputs: measuredBloodFlowRate, bloodPumpSpeedRPM, errorBloodFlowVsMotorSpeedPersistTimerCtr + * @details Inputs: measuredBloodFlowRate, bloodPumpSpeedRPM * @details Outputs: alarm may be triggered * @return none *************************************************************************/ static void checkBloodPumpFlowAgainstSpeed( void ) { - // Check only performed while in treatment mode and while we are in control to target state + // 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 ); - - if ( delta > BP_MAX_FLOW_VS_SPEED_DIFF_RPM ) - { - if ( ++errorBloodFlowVsMotorSpeedPersistTimerCtr >= BP_FLOW_VS_SPEED_PERSIST ) - { -#ifndef DISABLE_PUMP_FLOW_CHECKS - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, flow, speed ); -#endif - } + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, delta > BP_MAX_FLOW_VS_SPEED_DIFF_RPM ) ) + { +#ifndef DISABLE_PUMP_SPEED_CHECKS + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, flow, speed ); +#endif } - else - { - errorBloodFlowVsMotorSpeedPersistTimerCtr = 0; - } + } + else + { + resetPersistentAlarmTimer( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK ); } - else - { - errorBloodFlowVsMotorSpeedPersistTimerCtr = 0; - } } /*********************************************************************//** @@ -1241,46 +1191,18 @@ *************************************************************************/ static void checkBloodPumpMCCurrent( void ) { - F32 bpCurr; - - // Blood pump should be off - if ( BLOOD_PUMP_OFF_STATE == bloodPumpState ) - { - bpCurr = fabs( getMeasuredBloodPumpMCCurrent() ); - if ( bpCurr > BP_MAX_CURR_WHEN_STOPPED_MA ) - { - bpCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; - if ( bpCurrErrorDurationCtr > BP_MAX_CURR_ERROR_DURATION_MS ) - { -#ifndef DISABLE_MOTOR_CURRENT_CHECKS - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, getMeasuredBloodPumpMCCurrent() ); -#endif - } - } - else - { - bpCurrErrorDurationCtr = 0; - } + F32 const bpCurr = fabs( getMeasuredBloodPumpMCCurrent() ); + // Check blood pump current during off state + BOOL const isOffMCCurrentBad = ( BLOOD_PUMP_OFF_STATE == bloodPumpState ) && ( bpCurr > BP_MAX_CURR_WHEN_STOPPED_MA ); + // Check blood pump current during running state + BOOL const isRunningMCCurrentBad = ( BLOOD_PUMP_OFF_STATE != bloodPumpState ) && ( bpCurr > BP_MAX_CURR_WHEN_RUNNING_MA ); + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, isOffMCCurrentBad || isRunningMCCurrentBad ) ) + { +#ifndef DISABLE_MOTOR_CURRENT_CHECKS + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, getMeasuredBloodPumpMCCurrent() ); +#endif } - // Blood pump should be running - else - { - bpCurr = fabs( getMeasuredBloodPumpMCCurrent() ); - if ( bpCurr > BP_MAX_CURR_WHEN_RUNNING_MA ) - { - bpCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; - if ( bpCurrErrorDurationCtr > BP_MAX_CURR_ERROR_DURATION_MS ) - { -#ifndef DISABLE_MOTOR_CURRENT_CHECKS - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, getMeasuredBloodPumpMCCurrent() ); -#endif - } - } - else - { - bpCurrErrorDurationCtr = 0; - } - } } /*********************************************************************//**