Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r88a641b7b0185e0bad77e21e6d438e1d7283fd28 -rd6c75118f4e5792b40b744a0b29e44c78368a469 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 88a641b7b0185e0bad77e21e6d438e1d7283fd28) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision d6c75118f4e5792b40b744a0b29e44c78368a469) @@ -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_MIN_CURR_WHEN_RUNNING_MA 150.0 ///< Motor controller current should always exceed this when pump should be running @@ -102,7 +104,9 @@ /// Blood flow sensor signal strength low alarm persistence. #define FLOW_SIG_STRGTH_ALARM_PERSIST ( 5 * MS_PER_SECOND ) -#define MIN_FLOW_SIG_STRENGTH 0.9 ///< Minimum flow sensor signal strength (90%). +#define MIN_FLOW_SIG_STRENGTH 0.9 ///< Minimum flow sensor signal strength (90%). + +#define BFM_SENSOR_PARAM_CORRUPT_STATUS 0x7 ///< Blood flow meter NVM parameter status. /// Enumeration of blood pump controller states. typedef enum BloodPump_States @@ -182,9 +186,6 @@ static U32 bpCurrErrorDurationCtr = 0; ///< Used for tracking persistence of bp current errors -static BLOOD_FLOW_SELF_TEST_STATE_T bloodPumpSelfTestState = BLOOD_FLOW_SELF_TEST_STATE_START; ///< Current blood pump self-test state -static U32 bloodPumpSelfTestTimerCount = 0; ///< Timer counter for blood pump self-test - // ********** private function prototypes ********** static BLOOD_PUMP_STATE_T handleBloodPumpOffState( void ); @@ -384,7 +385,7 @@ *************************************************************************/ U32 getBloodPumpMotorCount( void ) { - return bloodPumpMotorEdgeCount / BP_HALL_EDGE_COUNTS_PER_REV; + return bloodPumpMotorEdgeCount; } /*********************************************************************//** @@ -424,8 +425,13 @@ { HD_OP_MODE_T opMode = getCurrentOperationMode(); U16 bpRPM = getIntADCReading( INT_ADC_BLOOD_PUMP_SPEED ); - U16 bpmA = getIntADCReading( INT_ADC_BLOOD_PUMP_MOTOR_CURRENT ); + U16 bpmA = getIntADCReading( INT_ADC_BLOOD_PUMP_MOTOR_CURRENT ); + +#ifndef V1_5_SYSTEM + F32 bpFlow = ( getFPGABloodFlow() * bloodFlowCalGain ) + bloodFlowCalOffset; +#else F32 bpFlow = ( ( getFPGABloodFlow() * -1.0 ) * bloodFlowCalGain ) + bloodFlowCalOffset; // Blood flow sensor installed backwards on HD +#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; @@ -928,25 +934,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; @@ -1258,31 +1267,17 @@ *************************************************************************/ SELF_TEST_STATUS_T execBloodFlowTest( void ) { - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; - CALIBRATION_DATA_T cal; + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; - switch ( bloodPumpSelfTestState ) - { - case BLOOD_FLOW_SELF_TEST_STATE_START: - // Retrieve blood flow sensor calibration data - if ( TRUE == getCalibrationData( &cal ) ) - { - bloodFlowCalGain = cal.bloodFlowGain; - bloodFlowCalOffset = cal.bloodFlowOffset_mL_min; - bloodPumpSelfTestState = BLOOD_FLOW_TEST_STATE_COMPLETE; // TODO - implement rest of self-test(s) - result = SELF_TEST_STATUS_PASSED; - } - break; + // Get the flow sensors calibration record + HD_FLOW_SENSORS_CAL_RECORD_T cal = getHDFlowSensorsCalibrationRecord(); - case BLOOD_FLOW_TEST_STATE_IN_PROGRESS: - break; - - case BLOOD_FLOW_TEST_STATE_COMPLETE: - break; - - default: - // TODO - s/w fault - break; + // Retrieve blood flow sensor calibration data and check for sensor connected status + if ( BFM_SENSOR_PARAM_CORRUPT_STATUS != getFPGABloodFlowMeterStatus() ) + { + 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; } return result; @@ -1292,58 +1287,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