Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r7a7bf19d0cf16745566956f45cef57f8eb5df445 -r8466e63f95f65a3ffb18c3af85ac99328e41167b --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 7a7bf19d0cf16745566956f45cef57f8eb5df445) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 8466e63f95f65a3ffb18c3af85ac99328e41167b) @@ -70,31 +70,26 @@ #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 ); /// 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); +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 #define BP_MAX_CURR_ERROR_DURATION_MS 2000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm -#ifndef V2_0_SYSTEM - #define BP_SPEED_ADC_TO_RPM_FACTOR 1.751752 ///< Conversion factor from ADC counts to RPM for blood pump motor - #define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.000238 ///< ~42 BP motor RPM = 1% PWM duty cycle -#else - #define BP_SPEED_ADC_TO_RPM_FACTOR 1.280938 ///< Conversion factor from ADC counts to RPM for blood pump motor - #define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.0003125 ///< ~32 BP motor RPM = 1% PWM duty cycle -#endif +#define BP_SPEED_ADC_TO_RPM_FACTOR 1.751752 ///< Conversion factor from ADC counts to RPM for blood pump motor +#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 @@ -104,11 +99,7 @@ /// 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 BP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - BP_PWM_ZERO_OFFSET) * 4000.0 ) #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. @@ -172,8 +163,6 @@ static MOTOR_DIR_T bloodPumpDirectionSet = MOTOR_DIR_FORWARD; ///< Currently set blood flow direction static PUMP_CONTROL_MODE_T bloodPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Requested blood pump control mode. static PUMP_CONTROL_MODE_T bloodPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Currently set blood pump control mode. -static F32 bloodFlowCalGain = 1.0; ///< Blood flow calibration gain. -static F32 bloodFlowCalOffset = 0.0; ///< Blood flow calibration offset. /// 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 }; @@ -197,24 +186,16 @@ 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. static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer. -static U32 bpCurrErrorDurationCtr = 0; ///< Used for tracking persistence of bp current errors. - 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 ********** @@ -235,7 +216,8 @@ static void checkBloodPumpSpeeds( void ); static void checkBloodPumpFlowAgainstSpeed( void ); static void checkBloodPumpMCCurrent( void ); -static void checkBloodFlowSensorSignalStrength( void ); +static void checkBloodFlowSensorSignalStrength( void ); +static BOOL processCalibrationData( void ); /*********************************************************************//** * @brief @@ -266,7 +248,7 @@ 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 + // 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 ); @@ -462,20 +444,34 @@ * @brief * The execBloodFlowMonitor function executes the blood flow monitor. * @details Inputs: none - * @details Outputs: measuredBloodFlowRate, adcBloodPumpMCSpeedRPM, adcBloodPumpMCCurrentmA + * @details Outputs: measuredBloodFlowRate, adcBloodPumpMCSpeedRPM, + * adcBloodPumpMCCurrentmA * @return none *************************************************************************/ 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 ); - F32 bpFlow = ( getFPGABloodFlow() * bloodFlowCalGain ) + bloodFlowCalOffset; U08 fpReadCtr = getFPGABloodFlowFastPacketReadCounter(); U08 spReadCtr = getFPGABloodFlowSlowPacketReadCounter(); U08 flowErrorCtr = getFPGABloodFlowErrorCounter(); U08 flowStatus = getFPGABloodFlowMeterStatus(); + 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; + #ifndef DISABLE_PUMP_FLOW_CHECKS if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_SENSOR_ERROR, ( flowErrorCtr != lastBloodFlowCommErrorCount ) ) ) { @@ -1030,17 +1026,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 +1052,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 +1065,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 ); + } } /*********************************************************************//** @@ -1122,31 +1103,17 @@ { F32 measMotorSpeed = fabs( getMeasuredBloodPumpSpeed() ); F32 measMCMotorSpeed = fabs( getMeasuredBloodPumpMCSpeed() ); - - // Check for pump running while commanded off - if ( 0 == targetBloodFlowRate ) - { - if ( measMotorSpeed > BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) - { - if ( ++errorBloodMotorOffPersistTimerCtr >= BP_OFF_ERROR_PERSIST ) - { + + // Check for pump running while commanded off + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_OFF_CHECK, ( 0 == targetBloodFlowRate ) && ( 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; - } - - // Checks that only occur when pump is running (and beyond ramp). + + // Checks that only occur when pump is running (and beyond ramp). if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) { F32 cmdMotorSpeed = BP_PWM_TO_MOTOR_SPEED_RPM( bloodPumpPWMDutyCyclePctSet ); @@ -1156,41 +1123,28 @@ 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 ) || ( 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, cmdMotorSpeed, 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 ) || ( deltaMCMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) ) ) + { +#ifndef DISABLE_PUMP_SPEED_CHECKS + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, cmdMotorSpeed, 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; - } } /*********************************************************************//** @@ -1199,7 +1153,7 @@ * 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 *************************************************************************/ @@ -1221,25 +1175,18 @@ 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; - } } /*********************************************************************//** @@ -1252,46 +1199,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, bpCurr ); +#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; - } - } } /*********************************************************************//** @@ -1319,6 +1238,52 @@ } } #endif +} + +/*********************************************************************//** + * @brief + * The processCalibrationData function gets the calibration data and makes + * sure it is valid by checking the calibration date. The calibration date + * should not be 0. + * @details Inputs: none + * @details Outputs: bloodFlowCalRecord + * @return TRUE if the calibration record is valid, otherwise FALSE + *************************************************************************/ +static BOOL processCalibrationData( void ) +{ + BOOL status = TRUE; + + // Get the calibration record from NVDataMgmt + HD_FLOW_SENSORS_CAL_RECORD_T calData = getHDFlowSensorsCalibrationRecord(); + + // Check if the calibration data that was received from NVDataMgmt is legitimate + // The calibration date item should not be zero. If the calibration date is 0, + // then the blood flow sensors data is not stored in the NV memory or it was corrupted. + if ( 0 == calData.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].calibrationTime ) + { +#ifndef SKIP_CAL_CHECK + activateAlarmNoData( ALARM_ID_HD_BLOOD_FLOW_INVALID_CAL_RECORD ); + status = FALSE; +#endif + } + + // The calibration data was valid, update the local copy + bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].fourthOrderCoeff = + calData.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].fourthOrderCoeff; + + bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].thirdOrderCoeff = + calData.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].thirdOrderCoeff; + + bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].secondOrderCoeff = + calData.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].secondOrderCoeff; + + bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].gain = + calData.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].gain; + + bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].offset = + calData.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].offset; + + return status; } /*********************************************************************//** @@ -1331,22 +1296,25 @@ *************************************************************************/ SELF_TEST_STATUS_T execBloodFlowTest( void ) { - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; U08 const bfmStatus = getFPGABloodFlowMeterStatus(); - // Get the flow sensors calibration record - HD_FLOW_SENSORS_CAL_RECORD_T cal = getHDFlowSensorsCalibrationRecord(); - // Retrieve blood flow sensor calibration data and check for sensor connected status if ( BFM_SENSOR_PARAM_CORRUPT_STATUS != bfmStatus ) { - bloodFlowCalGain = cal.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].gain; - bloodFlowCalOffset = cal.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].offset; - result = SELF_TEST_STATUS_PASSED; + BOOL calStatus = processCalibrationData(); + + if ( TRUE == calStatus ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + result = SELF_TEST_STATUS_FAILED; + } } else { - result = SELF_TEST_STATUS_FAILED; SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BLOOD_FLOW_STATUS_SELF_TEST_FAILURE, (U32)bfmStatus ); }