Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -rccfd15568f1e3d304320c2babb2fd4bcf0413304 -r74be223d47ea7bb0ac7d814e74d3627d830a5fac --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision ccfd15568f1e3d304320c2babb2fd4bcf0413304) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 74be223d47ea7bb0ac7d814e74d3627d830a5fac) @@ -15,7 +15,7 @@ * ***************************************************************************/ -#include +#include // Used for fabs() and pow() functions #include "can.h" #include "etpwm.h" @@ -56,7 +56,8 @@ #define BP_I_COEFFICIENT 0.00075 ///< I term for blood pump control #define BP_HOME_RATE 100 ///< Target pump speed (in estimate mL/min) for homing. -#define BP_HOME_TIMEOUT_MS 10000 ///< Maximum time allowed for homing to complete (in ms). +#define BP_HOME_TIMEOUT_MS 10000 ///< Maximum time (in ms) allowed for homing to complete. +#define BP_MAX_ROTOR_HALL_INTERVAL_MS 20000 ///< Maximum time (in ms) allowed between rotor hall sensor detects (50 mL/min worst case). /// Interval (ms/task time) at which the blood pump speed is calculated (every 40 ms). #define BP_SPEED_CALC_INTERVAL ( 40 / TASK_PRIORITY_INTERVAL ) /// Number of hall sensor counts kept in buffer to hold last 1 second of count data. @@ -65,18 +66,20 @@ #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). #define BP_MAX_MOTOR_SPEED_ERROR_RPM 300.0 ///< Maximum difference in speed between measured and commanded RPM. +#ifdef USE_FMB_FLOW_SENSOR +#define BP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured speed and speed implied by measured flow. /// Persist time (task intervals) for flow vs. motor speed error condition. static const U32 BP_FLOW_VS_SPEED_PERSIST = ( 5 * MS_PER_SECOND ); +#endif /// Persist time (task intervals) for motor off error condition. 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 ); /// Persist time (task intervals) rotor speed error condition. -static const U32 BP_ROTOR_SPEED_ERROR_PERSIST = ( 12 * MS_PER_SECOND ); +static const U32 BP_ROTOR_SPEED_ERROR_PERSIST = ( 22 * MS_PER_SECOND ); /// Persist time (task intervals) pump direction error condition. static const U32 BP_DIRECTION_ERROR_PERSIST = ( 250 ); /// Persist time period blood pump rotor speed too fast error condition. @@ -92,7 +95,7 @@ #define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.000238 ///< ~42 BP motor RPM = 1% PWM duty cycle #define BP_CURRENT_ADC_TO_MA_FACTOR 3.002 ///< Conversion factor from ADC counts to mA for blood pump motor -#define BP_REV_PER_LITER 150.0 ///< Rotor revolutions per liter +#define BP_REV_PER_LITER 144.7 ///< Rotor revolutions per liter #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 @@ -105,7 +108,12 @@ #define BLOODPUMP_ADC_ZERO 1998 ///< Blood pump ADC channel zero offset. /// Macro converts 12 bit ADC value to signed 16-bit value. #define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)BLOODPUMP_ADC_ZERO ) + +#ifndef USE_FMB_FLOW_SENSOR /// Measured blood flow is filtered w/ moving average +#define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 1 ) +#else +/// Measured blood flow is filtered w/ moving average #define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 10 ) /// Blood flow sensor signal strength low alarm persistence. @@ -121,8 +129,23 @@ #define BFM_SENSOR_CONNECTED_STATUS 0x00 ///< Blood flow meter connected status. #define BFM_SENSOR_PARAM_CORRUPT_STATUS 0x07 ///< Blood flow meter NVM parameter status. +#endif #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. + +#ifndef USE_FMB_FLOW_SENSOR +#define BLOOD_PC2 -0.0000090267 ///< Pressure compensation coefficient (2nd order) for blood pump. +#define BLOOD_PC1 -0.00071147 ///< Pressure compensation coefficient (1st order) for blood pump. +#define BLOOD_NSV 3.4555 ///< Nominal stroke (1/2 rotor revolution) volume (in mL) for blood pump. +#define BLOOD_SC2 -0.0000000718 ///< Speed compensation coefficient (2nd order) for blood pump. +#define BLOOD_SC1 0.0000851 ///< Speed compensation coefficient (1st order) for blood pump. +#define BLOOD_SC0 -0.027 ///< Speed compensation coefficient (offset) for blood pump. +#define BLOOD_PSC2 -0.00000382 ///< Additional pressure compensation coefficient (2nd order) for blood pump. +#define BLOOD_PSC1 0.000197 ///< Additional pressure compensation coefficient (1st order) for blood pump. +#define BLOOD_PSC0 0.17 ///< Additional pressure compensation coefficient (offset) for blood pump. +#define BLOOD_TS0 1000.0 ///< Lower boundary of weighted speed transition (in RPM). +#define BLOOD_TS1 1500.0 ///< Upper boundary of weighted speed transition (in RPM). +#endif /// Enumeration of blood pump controller states. typedef enum BloodPump_States @@ -166,14 +189,31 @@ /// Interval (in task intervals) at which to publish blood flow data to CAN bus. static OVERRIDE_U32_T bloodFlowDataPublishInterval = { BLOOD_FLOW_DATA_PUB_INTERVAL, BLOOD_FLOW_DATA_PUB_INTERVAL, BLOOD_FLOW_DATA_PUB_INTERVAL, 0 }; -static S32 targetBloodFlowRate = 0; ///< Requested blood flow rate -static OVERRIDE_F32_T measuredBloodFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow rate -static OVERRIDE_F32_T bloodPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump rotor speed -static OVERRIDE_F32_T bloodPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor speed -static OVERRIDE_F32_T adcBloodPumpMCSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller speed -static OVERRIDE_F32_T adcBloodPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller current -static OVERRIDE_F32_T bloodFlowSignalStrength = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow signal strength (%) +static S32 targetBloodFlowRate = 0; ///< Requested blood flow rate. +static OVERRIDE_F32_T measuredBloodFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow rate. +static OVERRIDE_F32_T bloodPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump rotor speed. +static OVERRIDE_F32_T bloodPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor speed. +static OVERRIDE_F32_T adcBloodPumpMCSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller speed. +static OVERRIDE_F32_T adcBloodPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller current. +#ifdef USE_FMB_FLOW_SENSOR +static OVERRIDE_F32_T bloodFlowSignalStrength = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow signal strength (%). + +static U08 lastBloodFlowFastPacketReadCtr = 0; ///< Previous read counter for the blood flow fast packets. +static U08 lastBloodFlowSlowPacketReadCtr = 0; ///< Previous read counter for the blood flow slow packets. +#ifndef DISABLE_PUMP_FLOW_CHECKS +static U08 lastBloodFlowCommErrorCount = 0; ///< Previous BP flow sensor comm error count. +#endif +static HD_FLOW_SENSORS_CAL_RECORD_T bloodFlowCalRecord; ///< Blood flow sensor calibration record. +#endif + +static U08 lastBloodPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. + +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. +static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer. + static U32 bpControlTimerCounter = 0; ///< Determines when to perform control on blood flow static U32 bpRotorRevStartTime = 0; ///< Blood pump rotor rotation start time (in ms) @@ -186,17 +226,15 @@ 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 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. -static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer. +#ifndef USE_FMB_FLOW_SENSOR +static F32 bloodPCSV; ///< Calculated pressure corrected blood pump stroke volume. +static F32 bloodSCSV; ///< Calculated speed corrected blood pump stroke volume. +static F32 bloodPSCSV; ///< Calculated additional pressure corrected blood pump stroke volume. +static F32 bloodHSWF; ///< High speed weighting factor for blood pump stroke volume calculation. +static F32 bloodLSWF; ///< Low speed weighting factor for blood pump stroke volume calculation. +static F32 bloodPSCSVT; ///< Pressure corrected, speed corrected blood pump stroke volume with weighted transition. +#endif -static U08 lastBloodFlowFastPacketReadCtr = 0; ///< Previous read counter for the blood flow fast packets. -static U08 lastBloodFlowSlowPacketReadCtr = 0; ///< Previous read counter for the blood flow slow packets. -static U08 lastBloodPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. -static U08 lastBloodFlowCommErrorCount = 0; ///< Previous BP flow sensor comm error count. -static HD_FLOW_SENSORS_CAL_RECORD_T bloodFlowCalRecord; ///< Blood flow sensor calibration record. - // ********** private function prototypes ********** static BLOOD_PUMP_STATE_T handleBloodPumpOffState( void ); @@ -214,10 +252,44 @@ static void checkBloodPumpRotor( void ); static void checkBloodPumpDirection( void ); static void checkBloodPumpSpeeds( void ); -static void checkBloodPumpFlowAgainstSpeed( void ); static void checkBloodPumpMCCurrent( void ); +static void checkBloodPumpFlowRate( void ); + +#ifdef USE_FMB_FLOW_SENSOR static void checkBloodFlowSensorSignalStrength( void ); -static BOOL processCalibrationData( void ); +static BOOL processCalibrationData( void ); +#else +static F32 calcBloodFlow( void ); + +/*********************************************************************//** + * @brief + * The calcBloodFlow function calculates an estimated blood flow rate from + * blood pump speed and arterial pressure. + * @details Inputs: BP set speed, arterial pressure + * @details Outputs: calcBloodFlowRate + * @return calculated blood flow rate (mL/min) + *************************************************************************/ +static F32 calcBloodFlow( void ) +{ + F32 artPres = getLongFilteredArterialPressure(); + F32 artPres_2 = pow( artPres, 2.0 ); + F32 motSpd = getMeasuredBloodPumpMCSpeed(); //BP_PWM_TO_MOTOR_SPEED_RPM( bloodPumpPWMDutyCyclePctSet ); + F32 motSpd_2 = pow( motSpd, 2.0 ); + F32 rotSpd = motSpd / BP_GEAR_RATIO; + F32 strokeSpd = rotSpd * 2.0; // 1 rotor revolution = 2 strokes + + // Calculate compensated stroke volume (in mL). + bloodPCSV = BLOOD_PC2 * artPres_2 + BLOOD_PC1 * artPres + BLOOD_NSV; + bloodSCSV = bloodPCSV * ( 1.0 + BLOOD_SC2 * motSpd_2 + BLOOD_SC1 * motSpd + BLOOD_SC0 ); + bloodPSCSV = bloodSCSV * ( 1.0 + BLOOD_PSC2 * artPres_2 + BLOOD_PSC1 * artPres + BLOOD_PSC0 ); + bloodHSWF = ( ( motSpd - BLOOD_TS0 > 0.0 ? motSpd - BLOOD_TS0 : 0.0 ) - ( motSpd - BLOOD_TS1 > 0.0 ? motSpd - BLOOD_TS1 : 0.0 ) ) / ( BLOOD_TS1 - BLOOD_TS0 ); + bloodLSWF = 1.0 - bloodHSWF; + bloodPSCSVT = bloodLSWF * bloodPCSV + bloodHSWF * bloodPSCSV; + + // Blood flow = stroke speed (strokes/min) x stroke volume (mL/stroke) = mL/min + return ( strokeSpd * bloodPSCSVT ); +} +#endif /*********************************************************************//** * @brief @@ -249,17 +321,19 @@ MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE ); // 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_PUMP_MC_CURRENT_CHECK, 0, BP_MAX_CURR_ERROR_DURATION_MS ); - initPersistentAlarm( ALARM_ID_BLOOD_FLOW_SIGNAL_STRENGTH_TOO_LOW, FLOW_SIG_STRGTH_ALARM_PERSIST, FLOW_SIG_STRGTH_ALARM_PERSIST ); +#ifdef USE_FMB_FLOW_SENSOR + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, 0, BP_FLOW_VS_SPEED_PERSIST ); + initPersistentAlarm( ALARM_ID_BLOOD_FLOW_SIGNAL_STRENGTH_TOO_LOW, FLOW_SIG_STRGTH_ALARM_PERSIST, FLOW_SIG_STRGTH_ALARM_PERSIST ); 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 ); +#endif initPersistentAlarm( ALARM_ID_HD_BLOOD_FLOW_OUT_OF_RANGE, 0, BP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST ); } @@ -450,28 +524,23 @@ *************************************************************************/ void execBloodFlowMonitor( void ) { - // Check if a new calibration is available - if ( TRUE == isNewCalibrationRecordAvailable() ) - { - // Get the new calibration data and check its validity - processCalibrationData(); - } - HD_OP_MODE_T opMode = getCurrentOperationMode(); U16 bpRPM = getIntADCReading( INT_ADC_BLOOD_PUMP_SPEED ); U16 bpmA = getIntADCReading( INT_ADC_BLOOD_PUMP_MOTOR_CURRENT ); U08 fpReadCtr = getFPGABloodFlowFastPacketReadCounter(); U08 spReadCtr = getFPGABloodFlowSlowPacketReadCounter(); U08 flowErrorCtr = getFPGABloodFlowErrorCounter(); U08 flowStatus = getFPGABloodFlowMeterStatus(); - + F32 bpFlow; +#ifdef USE_FMB_FLOW_SENSOR F32 fpgaBloodFlow = getFPGABloodFlow(); - F32 bpFlow = pow(fpgaBloodFlow, 4) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].fourthOrderCoeff + - pow(fpgaBloodFlow, 3) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].thirdOrderCoeff + - pow(fpgaBloodFlow, 2) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].secondOrderCoeff + - fpgaBloodFlow * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].gain + - bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].offset; + // Check if a new calibration is available + if ( TRUE == isNewCalibrationRecordAvailable() ) + { + // Get the new calibration data and check its validity + processCalibrationData(); + } #ifndef DISABLE_PUMP_FLOW_CHECKS if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_SENSOR_ERROR, ( flowErrorCtr != lastBloodFlowCommErrorCount ) ) ) { @@ -483,7 +552,6 @@ } lastBloodFlowCommErrorCount = flowErrorCtr; #endif - #ifndef DISABLE_FPGA_COUNTER_CHECKS // Check for stale flow reading if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, ( fpReadCtr == lastBloodFlowFastPacketReadCtr ) ) ) @@ -499,12 +567,22 @@ // Record flow read counters for next time around lastBloodFlowFastPacketReadCtr = fpReadCtr; lastBloodFlowSlowPacketReadCtr = spReadCtr; +#endif adcBloodPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpRPM)) * BP_SPEED_ADC_TO_RPM_FACTOR; adcBloodPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpmA)) * BP_CURRENT_ADC_TO_MA_FACTOR; - bloodFlowSignalStrength.data = getFPGABloodFlowSignalStrength(); - filterBloodFlowReadings( bpFlow ); +#ifndef USE_FMB_FLOW_SENSOR + bpFlow = calcBloodFlow(); +#else + bloodFlowSignalStrength.data = getFPGABloodFlowSignalStrength(); + bpFlow = pow(fpgaBloodFlow, 4) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].fourthOrderCoeff + + pow(fpgaBloodFlow, 3) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].thirdOrderCoeff + + pow(fpgaBloodFlow, 2) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].secondOrderCoeff + + fpgaBloodFlow * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].gain + + bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].offset; +#endif + filterBloodFlowReadings( bpFlow ); // TODO - do we need to filter flow if calculated from filtered pressure? // Calculate blood pump motor speed/direction from hall sensor count updateBloodPumpSpeedAndDirectionFromHallSensors(); @@ -518,11 +596,13 @@ checkBloodPumpMCCurrent(); // Check pump speeds and flow checkBloodPumpSpeeds(); - checkBloodPumpFlowAgainstSpeed(); + checkBloodPumpFlowRate(); // Check for home position, zero/low speed checkBloodPumpRotor(); +#ifdef USE_FMB_FLOW_SENSOR // Check flow sensor signal strength - checkBloodFlowSensorSignalStrength(); + checkBloodFlowSensorSignalStrength(); +#endif } // Publish blood flow data on interval @@ -791,6 +871,7 @@ return result; } +#ifdef USE_FMB_FLOW_SENSOR /*********************************************************************//** * @brief * The getMeasuredBloodFlowSignalStrength function gets the measured blood flow @@ -810,6 +891,7 @@ return result; } +#endif /*********************************************************************//** * @brief @@ -914,8 +996,12 @@ payload.measMCSpd = getMeasuredBloodPumpMCSpeed(); payload.measMCCurr = getMeasuredBloodPumpMCCurrent(); payload.pwmDC = bloodPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; +#ifdef USE_FMB_FLOW_SENSOR payload.flowSigStrength = getMeasuredBloodFlowSignalStrength() * FRACTION_TO_PERCENT_FACTOR; - broadcastBloodFlowData( &payload ); +#else + payload.flowSigStrength = 0.0; +#endif + broadcastData( MSG_ID_BLOOD_FLOW_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&payload, sizeof( BLOOD_PUMP_STATUS_PAYLOAD_T ) ); bloodFlowDataPublicationTimerCounter = 0; } } @@ -996,7 +1082,7 @@ // Keep a running 32-bit edge count used for safety check on volume in some functions delta = u16BiDiffWithWrap( last, bpMotorHallSensorCount ); - bloodPumpMotorEdgeCount += (U16)delta; + bloodPumpMotorEdgeCount += ( delta >= 0 ? (U16)delta : 0 ); // Update last count for next time bpLastMotorHallSensorCounts[ nextIdx ] = bpMotorHallSensorCount; @@ -1033,7 +1119,7 @@ } // If pump is stopped or running very slowly, set rotor speed to zero - if ( TRUE == didTimeout( bpRotorRevStartTime, BP_HOME_TIMEOUT_MS ) ) + if ( TRUE == didTimeout( bpRotorRevStartTime, BP_MAX_ROTOR_HALL_INTERVAL_MS ) ) { bloodPumpRotorSpeedRPM.data = 0.0; } @@ -1059,7 +1145,9 @@ if ( lastBloodPumpDirectionCount != dirErrorCnt ) { lastBloodPumpDirectionCount = dirErrorCnt; +#ifndef DISABLE_PUMP_DIRECTION_CHECKS SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_PUMP_DIRECTION_STATUS_ERROR, (U32)HD_PUMP_BLOOD_PUMP ) +#endif } bpMCDir = ( getMeasuredBloodPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); @@ -1149,16 +1237,38 @@ /*********************************************************************//** * @brief - * The checkBloodPumpFlowAgainstSpeed function checks the measured blood flow - * 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 - * @details Outputs: alarm may be triggered + * The checkBloodPumpMCCurrent function checks the measured MC current vs. + * the set state of the blood pump (stopped or running). + * @details Inputs: + * @details Outputs: * @return none *************************************************************************/ -static void checkBloodPumpFlowAgainstSpeed( void ) +static void checkBloodPumpMCCurrent( void ) { + 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_MC_CURRENT_CHECK, isOffMCCurrentBad || isRunningMCCurrentBad ) ) + { +#ifndef DISABLE_MOTOR_CURRENT_CHECKS + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, bpCurr ); +#endif + } +} + +/*********************************************************************//** + * @brief + * The checkBloodPumpFlowRate function checks the measured blood flow rate + * is in range. + * @details Inputs: measuredBloodFlowRate + * @details Outputs: alarm may be triggered + * @return none + *************************************************************************/ +static void checkBloodPumpFlowRate( void ) +{ F32 flow = getMeasuredBloodFlowRate(); // Range check on measure BP flow rate. @@ -1169,50 +1279,29 @@ } #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 ) ) - { +#ifdef USE_FMB_FLOW_SENSOR + // 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 speed = getMeasuredBloodPumpSpeed(); - F32 impliedSpeed = ( flow / (F32)ML_PER_LITER ) * BP_REV_PER_LITER * BP_GEAR_RATIO; - F32 delta = fabs( speed - impliedSpeed ); + F32 impliedSpeed = ( flow / (F32)ML_PER_LITER ) * BP_REV_PER_LITER * BP_GEAR_RATIO; + F32 delta = fabs( speed - impliedSpeed ); 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 { - resetPersistentAlarmTimer( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK ); - } -} - -/*********************************************************************//** - * @brief - * The checkBloodPumpMCCurrent function checks the measured MC current vs. - * the set state of the blood pump (stopped or running). - * @details Inputs: - * @details Outputs: - * @return none - *************************************************************************/ -static void checkBloodPumpMCCurrent( void ) -{ - 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, bpCurr ); + resetPersistentAlarmTimer( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK ); + } #endif - } } +#ifdef USE_FMB_FLOW_SENSOR /*********************************************************************//** * @brief * The checkBloodFlowSensorSignalStrength function checks the measured blood @@ -1285,6 +1374,7 @@ return status; } +#endif /*********************************************************************//** * @brief @@ -1295,7 +1385,8 @@ * @return the current state of the BloodFlow self-test. *************************************************************************/ SELF_TEST_STATUS_T execBloodFlowTest( void ) -{ +{ +#ifdef USE_FMB_FLOW_SENSOR SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; U08 const bfmStatus = getFPGABloodFlowMeterStatus(); @@ -1317,6 +1408,9 @@ { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BLOOD_FLOW_STATUS_SELF_TEST_FAILURE, (U32)bfmStatus ); } +#else + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; +#endif return result; } @@ -1635,6 +1729,7 @@ return result; } +#ifdef USE_FMB_FLOW_SENSOR /*********************************************************************//** * @brief * The testSetMeasuredBloodFlowSignalStrengthOverride function overrides the measured @@ -1679,5 +1774,6 @@ return result; } +#endif /**@}*/