Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r126ad9f684cd96bc38d5e1ab5d79f5238681e3e5 -r44a100f8e5210a02c23b8fcc4527d8e96d577381 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 126ad9f684cd96bc38d5e1ab5d79f5238681e3e5) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) @@ -46,8 +46,8 @@ #define MAX_BLOOD_PUMP_PWM_STEP_UP_CHANGE 0.008 ///< Max duty cycle change when ramping up ~ 100 mL/min/s. #define MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE 0.016 ///< Max duty cycle change when ramping down ~ 200 mL/min/s. -#define MAX_BLOOD_PUMP_PWM_DUTY_CYCLE 0.88 ///< Controller will error if PWM duty cycle > 90%, so set max to 88% -#define MIN_BLOOD_PUMP_PWM_DUTY_CYCLE 0.12 ///< Controller will error if PWM duty cycle < 10%, so set min to 12% +#define MAX_BLOOD_PUMP_PWM_DUTY_CYCLE 0.89 ///< Controller will error if PWM duty cycle > 90%, so set max to 89% +#define MIN_BLOOD_PUMP_PWM_DUTY_CYCLE 0.10 ///< Controller will error if PWM duty cycle < 10%, so set min to 10% /// Interval (ms/task time) at which the blood pump is controlled. static const U32 BP_CONTROL_INTERVAL = ( 10000 / TASK_GENERAL_INTERVAL ); @@ -59,7 +59,7 @@ /// 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. -#define BP_SPEED_CALC_BUFFER_LEN ( 1000 / BP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) +#define BP_SPEED_CALC_BUFFER_LEN ( MS_PER_SECOND / BP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) #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. @@ -82,14 +82,19 @@ #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 - -#define BP_SPEED_ADC_TO_RPM_FACTOR 1.280938 ///< Conversion factor from ADC counts to RPM for blood pump motor + +#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.00025 ///< ~40 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_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_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_MOTOR_RPM_TO_PWM_DC_FACTOR 0.00028 ///< ~28 BP motor RPM = 1% PWM duty cycle #define BP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed /// Conversion factor 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 ) @@ -105,25 +110,35 @@ #define FLOW_SIG_STRGTH_ALARM_PERSIST ( 5 * MS_PER_SECOND ) #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. +/// Blood flow fast read timeout alarm persistence. +#define BLOOD_FLOW_FAST_READ_TO_PERSIST 100 +/// Blood flow slow read timeout alarm persistence. +#define BLOOD_FLOW_SLOW_READ_TO_PERSIST ( MS_PER_SECOND * 3 ) +/// Blood flow comm error persistence. +#define BLOOD_FLOW_COMM_ERROR_PERSIST MS_PER_SECOND + +#define BFM_SENSOR_CONNECTED_STATUS 0x00 ///< Blood flow meter connected status. +#define BFM_SENSOR_PARAM_CORRUPT_STATUS 0x07 ///< Blood flow meter NVM parameter status. + +#define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. /// Enumeration of blood pump controller states. typedef enum BloodPump_States { - BLOOD_PUMP_OFF_STATE = 0, ///< Blood pump off state. - BLOOD_PUMP_RAMPING_UP_STATE, ///< Blood pump ramping up state. - BLOOD_PUMP_RAMPING_DOWN_STATE, ///< Blood pump ramping down state. - BLOOD_PUMP_CONTROL_TO_TARGET_STATE, ///< Blood pump controlling to target state. - NUM_OF_BLOOD_PUMP_STATES ///< Number of blood pump states. + BLOOD_PUMP_OFF_STATE = 0, ///< Blood pump off state + BLOOD_PUMP_RAMPING_UP_STATE, ///< Blood pump ramping up state + BLOOD_PUMP_RAMPING_DOWN_STATE, ///< Blood pump ramping down state + BLOOD_PUMP_CONTROL_TO_TARGET_STATE, ///< Blood pump controlling to target state + NUM_OF_BLOOD_PUMP_STATES ///< Number of blood pump states } BLOOD_PUMP_STATE_T; /// Enumeration of blood pump self-test states. typedef enum BloodFlow_Self_Test_States { - BLOOD_FLOW_SELF_TEST_STATE_START = 0, ///< Blood pump self-test start state. - BLOOD_FLOW_TEST_STATE_IN_PROGRESS, ///< Blood pump self-test in progress state. - BLOOD_FLOW_TEST_STATE_COMPLETE, ///< Blood pump self-test completed state. - NUM_OF_BLOOD_FLOW_SELF_TEST_STATES ///< Number of blood pump self-test states. + BLOOD_FLOW_SELF_TEST_STATE_START = 0, ///< Blood pump self-test start state + BLOOD_FLOW_TEST_STATE_IN_PROGRESS, ///< Blood pump self-test in progress state + BLOOD_FLOW_TEST_STATE_COMPLETE, ///< Blood pump self-test completed state + NUM_OF_BLOOD_FLOW_SELF_TEST_STATES ///< Number of blood pump self-test states } BLOOD_FLOW_SELF_TEST_STATE_T; // Pin assignments for pump stop and direction outputs @@ -171,11 +186,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 +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 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 lastBloodFlowCommErrorCount = 0; ///< Previous BP flow sensor comm error count. + // ********** private function prototypes ********** static BLOOD_PUMP_STATE_T handleBloodPumpOffState( void ); @@ -423,13 +442,40 @@ HD_OP_MODE_T opMode = getCurrentOperationMode(); U16 bpRPM = getIntADCReading( INT_ADC_BLOOD_PUMP_SPEED ); 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 + U08 fpReadCtr = getFPGABloodFlowFastPacketReadCounter(); + U08 spReadCtr = getFPGABloodFlowSlowPacketReadCounter(); + U08 flowErrorCtr = getFPGABloodFlowErrorCounter(); + U08 flowStatus = getFPGABloodFlowMeterStatus(); + +#ifndef DISABLE_PUMP_FLOW_CHECKS + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_SENSOR_ERROR, ( flowErrorCtr != lastBloodFlowCommErrorCount ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_BP_FLOW_SENSOR_ERROR ); + } + if ( flowStatus != BFM_SENSOR_CONNECTED_STATUS ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BLOOD_FLOW_STATUS_SELF_TEST_FAILURE, (U32)flowStatus ); + } + 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 ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR ); + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_SLOW_READ_TIMEOUT_ERROR, ( spReadCtr == lastBloodFlowSlowPacketReadCtr ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_BP_FLOW_SLOW_READ_TIMEOUT_ERROR ); + } +#endif + + // Record flow read counters for next time around + lastBloodFlowFastPacketReadCtr = fpReadCtr; + lastBloodFlowSlowPacketReadCtr = spReadCtr; + 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(); @@ -715,7 +761,7 @@ * @details Outputs: none * @return the current blood flow data publication interval (in task intervals). *************************************************************************/ -U32 getPublishBloodFlowDataInterval( void ) +U32 getPublishBloodFlowDataInterval( void ) { U32 result = bloodFlowDataPublishInterval.data; @@ -1193,7 +1239,7 @@ 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 != getFPGABloodFlowMeterStatus() ) + if ( BFM_SENSOR_PARAM_CORRUPT_STATUS != bfmStatus ) { #ifndef DISABLE_CAL_CHECK if ( cal.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].calibrationTime == 0 ) @@ -1330,7 +1376,7 @@ /*********************************************************************//** * @brief - * The testResetOffButtonStateOverride function resets the override of the + * The testResetMeasuredBloodFlowRateOverride function resets the override of the * measured blood flow rate. * @details Inputs: none * @details Outputs: measuredBloodFlowRate