Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -rfa41b85cf47fb01cd905b2ed53d472a9cb0c1706 -r6419179374edcd65da462de84e8aeaefb7e20320 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision fa41b85cf47fb01cd905b2ed53d472a9cb0c1706) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 6419179374edcd65da462de84e8aeaefb7e20320) @@ -20,10 +20,6 @@ #include "can.h" #include "etpwm.h" -// TODO - Test includes - remove later -#include "DialInFlow.h" -#include "PresOccl.h" - #include "BloodFlow.h" #include "FPGA.h" #include "InternalADC.h" @@ -35,7 +31,8 @@ #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" -#include "Timers.h" +#include "Timers.h" +#include "Utilities.h" /** * @addtogroup BloodFlow @@ -53,7 +50,7 @@ #define MIN_BLOOD_PUMP_PWM_DUTY_CYCLE 0.12 ///< Controller will error if PWM duty cycle < 10%, so set min to 12% /// Interval (ms/task time) at which the blood pump is controlled. -#define BP_CONTROL_INTERVAL ( 10000 / TASK_GENERAL_INTERVAL ) +static const U32 BP_CONTROL_INTERVAL = ( 10000 / TASK_GENERAL_INTERVAL ); #define BP_P_COEFFICIENT 0.00035 ///< P term for blood pump control #define BP_I_COEFFICIENT 0.00035 ///< I term for blood pump control @@ -63,19 +60,24 @@ #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. #define BP_SPEED_CALC_BUFFER_LEN ( 1000 / BP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) -#define BP_HALL_EDGE_COUNTS_PER_REV 48 ///< Number of hall sensor edge counts per motor revolution. #define BP_MAX_ROTOR_SPEED_RPM 100.0 ///< Maximum rotor speed allowed for blood pump. #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. -#define BP_FLOW_VS_SPEED_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) for flow vs. motor speed error condition. -#define BP_OFF_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) for motor off error condition. -#define BP_MOTOR_SPEED_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) motor speed error condition. -#define BP_ROTOR_SPEED_ERROR_PERSIST ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) rotor speed error condition. -#define BP_DIRECTION_ERROR_PERSIST (250 / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) pump direction error condition. -#define BP_MAX_ROTOR_SPEED_ERROR_PERSIST ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) blood pump rotor speed too fast error condition. +#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); +/// Persist time (task intervals) for motor off error condition. +static const U32 BP_OFF_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) motor speed error condition. +static const U32 BP_MOTOR_SPEED_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) rotor speed error condition. +static const U32 BP_ROTOR_SPEED_ERROR_PERSIST = ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// 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); #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 @@ -382,7 +384,7 @@ *************************************************************************/ U32 getBloodPumpMotorCount( void ) { - return bloodPumpMotorEdgeCount / BP_HALL_EDGE_COUNTS_PER_REV; + return bloodPumpMotorEdgeCount; } /*********************************************************************//** @@ -931,25 +933,28 @@ if ( ++bpMotorSpeedCalcTimerCtr >= BP_SPEED_CALC_INTERVAL ) { U16 bpMotorHallSensorCount = getFPGABloodPumpHallSensorCount(); - U32 nextIdx = INC_WRAP( bpMotorSpeedCalcIdx, 0, BP_SPEED_CALC_BUFFER_LEN - 1 ); - U16 incDelta = ( bpMotorHallSensorCount >= bpLastMotorHallSensorCounts[ nextIdx ] ? \ - bpMotorHallSensorCount - bpLastMotorHallSensorCounts[ nextIdx ] : \ - ( HEX_64_K - bpLastMotorHallSensorCounts[ nextIdx ] ) + bpMotorHallSensorCount ); + U16 last = bpLastMotorHallSensorCounts[ bpMotorSpeedCalcIdx ]; + U32 nextIdx = INC_WRAP( bpMotorSpeedCalcIdx, 0, BP_SPEED_CALC_BUFFER_LEN - 1 ); + U16 incDelta = u16DiffWithWrap( bpLastMotorHallSensorCounts[ nextIdx ], bpMotorHallSensorCount ); U16 decDelta = HEX_64_K - incDelta; - U16 delta; - + U16 spdDelta; + S16 delta; + // Determine blood pump speed/direction from delta hall sensor count since last interval if ( incDelta < decDelta ) { - delta = incDelta; - bloodPumpSpeedRPM.data = ( (F32)delta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; + spdDelta = incDelta; + bloodPumpSpeedRPM.data = ( (F32)spdDelta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; } else { - delta = decDelta; - bloodPumpSpeedRPM.data = ( (F32)delta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; + spdDelta = decDelta; + bloodPumpSpeedRPM.data = ( (F32)spdDelta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; } - bloodPumpMotorEdgeCount += delta; + + // Keep a running 32-bit edge count used for safety check on volume in some functions + delta = u16BiDiffWithWrap( last, bpMotorHallSensorCount ); + bloodPumpMotorEdgeCount += (U16)delta; // Update last count for next time bpLastMotorHallSensorCounts[ nextIdx ] = bpMotorHallSensorCount; @@ -1261,25 +1266,18 @@ *************************************************************************/ SELF_TEST_STATUS_T execBloodFlowTest( void ) { - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; 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 ) + if ( BFM_SENSOR_PARAM_CORRUPT_STATUS != getFPGABloodFlowMeterStatus() ) { -#ifndef SKIP_CALIBRATION_TESTS - CALIBRATION_DATA_T cal; - - if ( TRUE == getCalibrationData( &cal ) ) - { - bloodFlowCalGain = cal.bloodFlowGain; - bloodFlowCalOffset = cal.bloodFlowOffset_mL_min; - } - else - { - result = SELF_TEST_STATUS_FAILED; - } -#endif + 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; } else { @@ -1294,58 +1292,7 @@ /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ - - -/*********************************************************************//** - * @brief - * The setBloodFlowCalibration function sets the blood flow calibration - * factors and has them stored in non-volatile memory. - * @details Inputs: none - * @details Outputs: bloodFlowCalGain, bloodFlowCalOffset - * @param gain gain calibration factor for blood flow sensor - * @param offset offset calibration factor for blood flow sensor - * @return TRUE if calibration factors successfully set/stored, FALSE if not - *************************************************************************/ -BOOL setBloodFlowCalibration( F32 gain, F32 offset ) -{ - BOOL result = FALSE; - if ( TRUE == isTestingActivated() ) - { - CALIBRATION_DATA_T cal; - - getCalibrationData( &cal ); - // Keep locally and apply immediately - bloodFlowCalGain = gain; - bloodFlowCalOffset = offset; - // Also update calibration record in non-volatile memory - cal.bloodFlowGain = gain; - cal.bloodFlowOffset_mL_min = offset; - if ( TRUE == setCalibrationData( cal ) ) - { - result = TRUE; - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The getBloodFlowCalibration function retrieves the current blood flow - * calibration factors. - * @details Inputs: bloodFlowCalGain, bloodFlowCalOffset - * @details Outputs: none - * @param gain value to populate with gain calibration factor for blood flow sensor - * @param offset value to populate with offset calibration factor for blood flow sensor - * @return none - *************************************************************************/ -void getBloodFlowCalibration( F32 *gain, F32 *offset ) -{ - *gain = bloodFlowCalGain; - *offset = bloodFlowCalOffset; -} - /*********************************************************************//** * @brief * The testSetBloodFlowDataPublishIntervalOverride function overrides the