Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -rfd9d9df8dd3c75c8f890a5ada96f83ded1841fd5 -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision fd9d9df8dd3c75c8f890a5ada96f83ded1841fd5) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -14,82 +14,82 @@ * @date (original) 07-Nov-2019 * ***************************************************************************/ - -#include // Used for fabs() and pow() functions - -#include "can.h" -#include "etpwm.h" -#include "Battery.h" +#include // Used for fabs() and pow() functions + +#include "can.h" +#include "etpwm.h" + +#include "Battery.h" #include "BloodFlow.h" -#include "FPGA.h" +#include "FPGA.h" #include "InternalADC.h" -#include "NVDataMgmt.h" -#include "OperationModes.h" +#include "NVDataMgmt.h" +#include "OperationModes.h" #include "PersistentAlarm.h" #include "PIControllers.h" -#include "SafetyShutdown.h" -#include "SystemCommMessages.h" -#include "TaskGeneral.h" -#include "TaskPriority.h" +#include "SafetyShutdown.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" +#include "TaskPriority.h" #include "Timers.h" -#include "Utilities.h" - -/** - * @addtogroup BloodFlow - * @{ - */ - -// ********** private definitions ********** +#include "Utilities.h" -/// Interval (ms/task time) at which the blood flow data is published on the CAN bus. -#define BLOOD_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) - -#define MAX_BLOOD_PUMP_PWM_STEP_UP_CHANGE 0.008F ///< Max duty cycle change when ramping up ~ 100 mL/min/s. -#define MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE 0.016F ///< Max duty cycle change when ramping down ~ 200 mL/min/s. -#define MAX_BLOOD_PUMP_PWM_DUTY_CYCLE 0.89F ///< Controller will error if PWM duty cycle > 90%, so set max to 89% -#define MIN_BLOOD_PUMP_PWM_DUTY_CYCLE 0.10F ///< Controller will error if PWM duty cycle < 10%, so set min to 10% +/** + * @addtogroup BloodFlow + * @{ + */ +// ********** private definitions ********** + +/// Interval (ms/task time) at which the blood flow data is published on the CAN bus. +#define BLOOD_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) + +#define MAX_BLOOD_PUMP_PWM_STEP_UP_CHANGE 0.008F ///< Max duty cycle change when ramping up ~ 100 mL/min/s. +#define MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE 0.016F ///< Max duty cycle change when ramping down ~ 200 mL/min/s. +#define MAX_BLOOD_PUMP_PWM_DUTY_CYCLE 0.89F ///< Controller will error if PWM duty cycle > 90%, so set max to 89% +#define MIN_BLOOD_PUMP_PWM_DUTY_CYCLE 0.10F ///< Controller will error if PWM duty cycle < 10%, so set min to 10% + #define BP_CONTROL_INTERVAL_SEC 10 ///< Blood pump control interval (in seconds). -/// Interval (ms/task time) at which the blood pump is controlled. +/// Interval (ms/task time) at which the blood pump is controlled. static const U32 BP_CONTROL_INTERVAL = ( BP_CONTROL_INTERVAL_SEC * MS_PER_SECOND / TASK_GENERAL_INTERVAL ); - -#define BP_P_COEFFICIENT 0.0001F ///< P term for blood pump control -#define BP_I_COEFFICIENT 0.00075F ///< I term for blood pump control - -#define BP_HOME_SPEED 400 ///< Target pump speed (in RPM) for homing. + +#define BP_P_COEFFICIENT 0.0001F ///< P term for blood pump control +#define BP_I_COEFFICIENT 0.00075F ///< I term for blood pump control + +#define BP_HOME_SPEED 400 ///< Target pump speed (in RPM) for homing. #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. #define BP_SPEED_CALC_BUFFER_LEN ( MS_PER_SECOND / BP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) -#define BP_MAX_ROTOR_SPEED_RPM 100.0F ///< Maximum rotor speed allowed for blood pump. +#define BP_MAX_ROTOR_SPEED_RPM 100.0F ///< Maximum rotor speed allowed for blood pump. #define BP_MAX_FLOW_RATE 1320.0F ///< Maximum measured BP flow rate allowed. -#define BP_MIN_FLOW_RATE -1320.0F ///< Minimum measured BP flow rate allowed. -#define BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0F ///< Maximum motor speed (RPM) while motor is commanded off. -#define BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 2.0F ///< Maximum difference in speed between motor and rotor (in rotor RPM). +#define BP_MIN_FLOW_RATE -1320.0F ///< Minimum measured BP flow rate allowed. +#define BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0F ///< Maximum motor speed (RPM) while motor is commanded off. +#define BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 2.0F ///< Maximum difference in speed between motor and rotor (in rotor RPM). #define BP_MAX_MOTOR_SPEED_ERROR_RPM 300.0F ///< Maximum difference in speed between measured and commanded RPM. #define BP_MAX_MOTOR_SPEED_VS_TRGT_DIFF_PCT 0.15F ///< Maximum motor speed vs target difference in percent. -/// Persist time (in ms) for motor off error condition. +/// Persist time (in ms) for motor off error condition. static const U32 BP_OFF_ERROR_PERSIST = ( 5 * MS_PER_SECOND ); -/// Persist time (in ms) motor speed error condition. +/// Persist time (in ms) motor speed error condition. static const U32 BP_MOTOR_SPEED_ERROR_PERSIST = ( 5 * MS_PER_SECOND ); /// Persist time (in ms) pump direction error condition. static const U32 BP_DIRECTION_ERROR_PERSIST = ( 250 ); /// Persist time period (in ms) blood pump rotor speed too fast error condition. -static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ( 1 * MS_PER_SECOND ); - -#define BP_MAX_CURR_WHEN_STOPPED_MA 150.0F ///< Motor controller current should not exceed this when pump should be stopped. -#define BP_MAX_CURR_WHEN_RUNNING_MA 2000.0F ///< Motor controller current should not exceed this when pump should be running. -#define BP_MAX_CURR_ERROR_DURATION_MS 5000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm. +static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ( 1 * MS_PER_SECOND ); +#define BP_MAX_CURR_WHEN_STOPPED_MA 150.0F ///< Motor controller current should not exceed this when pump should be stopped. +#define BP_MAX_CURR_WHEN_RUNNING_MA 2000.0F ///< Motor controller current should not exceed this when pump should be running. +#define BP_MAX_CURR_ERROR_DURATION_MS 5000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm. + #define BLOODPUMP_ADC_FULL_SCALE_V 3.0F ///< BP analog signals are 0-3V (while int. ADC ref may be different). #define BLOODPUMP_ADC_ZERO 1998 ///< Blood pump ADC channel zero offset. @@ -98,25 +98,25 @@ #define BP_SPEED_ADC_TO_RPM_FACTOR 1.751752F ///< Conversion factor from ADC counts to RPM for blood pump motor (3500 RPM/1998 counts). #define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.000238F ///< ~42 BP motor RPM = 1% PWM duty cycle. -#define BP_CURRENT_ADC_TO_MA_FACTOR 3.002F ///< Conversion factor from ADC counts to mA for blood pump motor. - +#define BP_CURRENT_ADC_TO_MA_FACTOR 3.002F ///< Conversion factor from ADC counts to mA for blood pump motor. + #define BP_REV_PER_LITER 146.84F ///< Rotor revolutions per liter. -#define BP_ML_PER_ROTOR_REV 6.81F ///< Milliliters per rotor revolusion. -#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.0F ///< Blood pump motor to blood pump gear ratio. +#define BP_ML_PER_ROTOR_REV 6.81F ///< Milliliters per rotor revolusion. +#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.0F ///< Blood pump motor to blood pump gear ratio. #define BP_PWM_ZERO_OFFSET 0.1F ///< 10 pct PWM duty cycle = zero speed. #define BP_100_PCT_PWM_RPM_RANGE 4000.0F ///< 10-90% PWM range yields 0-3,200 RPM range. Full 100% PWM range would yield 4,000 RPM range. - + /// 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. -#define BP_PWM_TO_MOTOR_SPEED_RPM(pwm,dir) ( ( ((pwm) - BP_PWM_ZERO_OFFSET) * BP_100_PCT_PWM_RPM_RANGE ) * ( dir == MOTOR_DIR_FORWARD ? 1.0F : -1.0F ) ) +#define BP_PWM_TO_MOTOR_SPEED_RPM(pwm,dir) ( ( ((pwm) - BP_PWM_ZERO_OFFSET) * BP_100_PCT_PWM_RPM_RANGE ) * ( dir == MOTOR_DIR_FORWARD ? 1.0F : -1.0F ) ) /// Conversion from RPM to PWM duty cycle %. #define BP_MOTOR_SPEED_RPM_TO_PWM(rpm) ( ( (F32)(rpm) / BP_100_PCT_PWM_RPM_RANGE ) + BP_PWM_ZERO_OFFSET ) /// Conversion macro from mL/min to estimated PWM duty cycle %. #define BP_ML_PER_MIN_FROM_PWM(pwm) ( ( ( pwm - BP_PWM_ZERO_OFFSET ) / ( BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * BP_GEAR_RATIO * BP_MOTOR_RPM_TO_PWM_DC_FACTOR ) ) ) - -/// Measured blood flow is filtered w/ moving average. + +/// Measured blood flow is filtered w/ moving average. #define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 1 ) #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. @@ -129,115 +129,115 @@ #define BP_FLOW_WEAR_B_TERM 0.00055F ///< B term used for wear portion of alpha flow coefficient. #define BP_MAX_ROTOR_COUNT_FOR_WEAR 25000 ///< Maximum rotor count for determining wear of the cartridge (negligible affect beyond this threshold). #define DATA_PUBLISH_COUNTER_START_COUNT 20 ///< Data publish counter start count. - -/// 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_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_T; - -// Pin assignments for pump stop and direction outputs -#define STOP_CAN3_PORT_MASK 0x00000002 // (Tx - re-purposed as output GPIO for blood pump stop signal) -#define DIR_CAN3_PORT_MASK 0x00000002 // (Rx - re-purposed as output GPIO for blood pump direction signal) -// Blood pump stop and direction macros -#define SET_BP_DIR() {canREG3->RIOC |= DIR_CAN3_PORT_MASK;} // Macro to set blood pump direction signal high. -#define CLR_BP_DIR() {canREG3->RIOC &= ~DIR_CAN3_PORT_MASK;} // Macro to set blood pump direction signal low. -#define SET_BP_STOP() {canREG3->TIOC &= ~STOP_CAN3_PORT_MASK;} // Macro to set blood pump stop signal (active low). -#define CLR_BP_STOP() {canREG3->TIOC |= STOP_CAN3_PORT_MASK;} // Macro to clear blood pump stop signal (active low). - -// ********** private data ********** - -static BLOOD_PUMP_STATE_T bloodPumpState = BLOOD_PUMP_OFF_STATE; ///< Current state of blood flow controller state machine -static U32 bloodFlowDataPublicationTimerCounter; ///< Used to schedule blood flow data publication to CAN bus -static BOOL isBloodPumpOn = FALSE; ///< Blood pump is currently running -static F32 bloodPumpPWMDutyCyclePct = 0.0; ///< Initial blood pump PWM duty cycle -static F32 bloodPumpPWMDutyCyclePctSet = 0.0; ///< Currently set blood pump PWM duty cycle -static MOTOR_DIR_T bloodPumpDirection = MOTOR_DIR_FORWARD; ///< Requested blood flow direction -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. + +/// 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_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_T; + +// Pin assignments for pump stop and direction outputs +#define STOP_CAN3_PORT_MASK 0x00000002 // (Tx - re-purposed as output GPIO for blood pump stop signal) +#define DIR_CAN3_PORT_MASK 0x00000002 // (Rx - re-purposed as output GPIO for blood pump direction signal) +// Blood pump stop and direction macros +#define SET_BP_DIR() {canREG3->RIOC |= DIR_CAN3_PORT_MASK;} // Macro to set blood pump direction signal high. +#define CLR_BP_DIR() {canREG3->RIOC &= ~DIR_CAN3_PORT_MASK;} // Macro to set blood pump direction signal low. +#define SET_BP_STOP() {canREG3->TIOC &= ~STOP_CAN3_PORT_MASK;} // Macro to set blood pump stop signal (active low). +#define CLR_BP_STOP() {canREG3->TIOC |= STOP_CAN3_PORT_MASK;} // Macro to clear blood pump stop signal (active low). + +// ********** private data ********** + +static BLOOD_PUMP_STATE_T bloodPumpState = BLOOD_PUMP_OFF_STATE; ///< Current state of blood flow controller state machine +static U32 bloodFlowDataPublicationTimerCounter; ///< Used to schedule blood flow data publication to CAN bus +static BOOL isBloodPumpOn = FALSE; ///< Blood pump is currently running +static F32 bloodPumpPWMDutyCyclePct = 0.0; ///< Initial blood pump PWM duty cycle +static F32 bloodPumpPWMDutyCyclePctSet = 0.0; ///< Currently set blood pump PWM duty cycle +static MOTOR_DIR_T bloodPumpDirection = MOTOR_DIR_FORWARD; ///< Requested blood flow direction +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 U32 errorBloodRotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for rotor speed error condition. - + /// 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 (calculated now) 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_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 (calculated now) 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 U08 lastBloodPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. - + static F32 rpmReadings[ SIZE_OF_ROLLING_AVG ]; ///< Holds RPM samples for a rolling average. static U32 rpmReadingsIdx = 0; ///< Index for next sample in rolling average array. static F32 rpmReadingsTotal = 0.0; ///< Rolling total - used to calc average. static U32 rpmReadingsCount = 0; ///< Number of samples in RPM rolling average buffer. static F32 filteredBloodPumpSpeed = 0.0; ///< Filtered blood pump speed used in blood flow estimation. -static U32 bpControlTimerCounter = 0; ///< Determines when to perform control on blood flow - +static U32 bpControlTimerCounter = 0; ///< Determines when to perform control on blood flow + static U32 bpRotorRevStartTime = 0; ///< Blood pump rotor rotation start time (in ms) -static OVERRIDE_U32_T bloodPumpRotorCounter = { 0, 0, 0, 0 }; ///< Running counter for blood pump rotor revolutions -static BOOL bpStopAtHomePosition = FALSE; ///< Stop blood pump at next home position -static U32 bpHomeStartTime = 0; ///< When did blood pump home command begin? (in ms) - +static OVERRIDE_U32_T bloodPumpRotorCounter = { 0, 0, 0, 0 }; ///< Running counter for blood pump rotor revolutions +static BOOL bpStopAtHomePosition = FALSE; ///< Stop blood pump at next home position +static U32 bpHomeStartTime = 0; ///< When did blood pump home command begin? (in ms) + static U32 bloodPumpMotorEdgeCount = 0; ///< Running counter for blood pump motor revolutions -static U16 bpLastMotorHallSensorCounts[ BP_SPEED_CALC_BUFFER_LEN ]; ///< Last hall sensor readings for the blood pump motor +static U16 bpLastMotorHallSensorCounts[ BP_SPEED_CALC_BUFFER_LEN ]; ///< Last hall sensor readings for the blood pump motor 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 HD_PUMPS_CAL_RECORD_T bloodPumpCalRecord; ///< Blood pump calibration record. - -// ********** private function prototypes ********** - -static BLOOD_PUMP_STATE_T handleBloodPumpOffState( void ); -static BLOOD_PUMP_STATE_T handleBloodPumpRampingUpState( void ); -static BLOOD_PUMP_STATE_T handleBloodPumpRampingDownState( void ); -static BLOOD_PUMP_STATE_T handleBloodPumpControlToTargetState( void ); -static void setBloodPumpControlSignalPWM( F32 newPWM ); -static void stopBloodPump( void ); -static void releaseBloodPumpStop( void ); -static void setBloodPumpDirection( MOTOR_DIR_T dir ); -static void publishBloodFlowData( void ); -static void updateBloodPumpSpeedAndDirectionFromHallSensors( void ); -static void checkBloodPumpRotor( void ); -static void checkBloodPumpDirection( void ); -static void checkBloodPumpSpeeds( void ); + +// ********** private function prototypes ********** + +static BLOOD_PUMP_STATE_T handleBloodPumpOffState( void ); +static BLOOD_PUMP_STATE_T handleBloodPumpRampingUpState( void ); +static BLOOD_PUMP_STATE_T handleBloodPumpRampingDownState( void ); +static BLOOD_PUMP_STATE_T handleBloodPumpControlToTargetState( void ); +static void setBloodPumpControlSignalPWM( F32 newPWM ); +static void stopBloodPump( void ); +static void releaseBloodPumpStop( void ); +static void setBloodPumpDirection( MOTOR_DIR_T dir ); +static void publishBloodFlowData( void ); +static void updateBloodPumpSpeedAndDirectionFromHallSensors( void ); +static void checkBloodPumpRotor( void ); +static void checkBloodPumpDirection( void ); +static void checkBloodPumpSpeeds( void ); static void checkBloodPumpMCCurrent( void ); static F32 calcBloodFlow( void ); static void resetBloodPumpRPMMovingAverage( void ); static void filterBloodPumpRPMReadings( F32 rpm ); -/*********************************************************************//** - * @brief - * The initBloodFlow function initializes the BloodFlow module. - * @details Inputs: none - * @details Outputs: bloodFlowDataPublicationTimerCounter - * @return none - *************************************************************************/ -void initBloodFlow( void ) +/*********************************************************************//** + * @brief + * The initBloodFlow function initializes the BloodFlow module. + * @details Inputs: none + * @details Outputs: bloodFlowDataPublicationTimerCounter + * @return none + *************************************************************************/ +void initBloodFlow( void ) { U32 i; bloodFlowDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - - signalBloodPumpHardStop(); - setBloodPumpDirection( MOTOR_DIR_FORWARD ); - + + signalBloodPumpHardStop(); + setBloodPumpDirection( MOTOR_DIR_FORWARD ); + // Zero rolling pump speed average buffer resetBloodPumpRPMMovingAverage(); @@ -246,12 +246,12 @@ for ( i = 0; i < BP_SPEED_CALC_BUFFER_LEN; i++ ) { bpLastMotorHallSensorCounts[ i ] = getFPGABloodPumpHallSensorCount(); - } + } resetBloodPumpRotorCount(); - // Initialize blood flow PI controller - initializePIController( PI_CONTROLLER_ID_BLOOD_FLOW, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, - BP_P_COEFFICIENT, BP_I_COEFFICIENT, + // Initialize blood flow PI controller + initializePIController( PI_CONTROLLER_ID_BLOOD_FLOW, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, + BP_P_COEFFICIENT, BP_I_COEFFICIENT, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE ); // Initialize persistent alarm for flow sensor @@ -261,25 +261,25 @@ initTimeWindowedCount( TIME_WINDOWED_COUNT_BP_COMMUTATION_ERROR, BP_COMMUTATION_ERROR_MAX_CNT, BP_COMMUTATION_ERROR_TIME_WIN_MS ); initPersistentAlarm( ALARM_ID_HD_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH, 0, BP_MAX_ROTOR_SPEED_ERROR_PERSIST ); initPersistentAlarm( ALARM_ID_HD_BLOOD_PUMP_MC_CURRENT_CHECK, 0, BP_MAX_CURR_ERROR_DURATION_MS ); -} - -/*********************************************************************//** - * @brief - * The setBloodPumpTargetFlowRate function sets a new target flow rate and - * pump direction. - * @details Inputs: isBloodPumpOn, bloodPumpDirectionSet - * @details Outputs: targetBloodFlowRate, bloodPumpdirection, bloodPumpPWMDutyCyclePct - * @param flowRate new target blood flow rate - * @param dir new blood flow direction - * @param mode new control mode - * @return TRUE if new flow rate & dir are set, FALSE if not - *************************************************************************/ -BOOL setBloodPumpTargetFlowRate( U32 flowRate, MOTOR_DIR_T dir, PUMP_CONTROL_MODE_T mode ) -{ - BOOL result = FALSE; - - // Direction change while pump is running is not allowed - if ( ( FALSE == isBloodPumpOn ) || ( 0 == flowRate ) || ( dir == bloodPumpDirectionSet ) ) +} + +/*********************************************************************//** + * @brief + * The setBloodPumpTargetFlowRate function sets a new target flow rate and + * pump direction. + * @details Inputs: isBloodPumpOn, bloodPumpDirectionSet + * @details Outputs: targetBloodFlowRate, bloodPumpdirection, bloodPumpPWMDutyCyclePct + * @param flowRate new target blood flow rate + * @param dir new blood flow direction + * @param mode new control mode + * @return TRUE if new flow rate & dir are set, FALSE if not + *************************************************************************/ +BOOL setBloodPumpTargetFlowRate( U32 flowRate, MOTOR_DIR_T dir, PUMP_CONTROL_MODE_T mode ) +{ + BOOL result = FALSE; + + // Direction change while pump is running is not allowed + if ( ( FALSE == isBloodPumpOn ) || ( 0 == flowRate ) || ( dir == bloodPumpDirectionSet ) ) { S32 dirFlowRate = ( dir == MOTOR_DIR_FORWARD ? (S32)flowRate : (S32)flowRate * -1 ); @@ -293,64 +293,64 @@ { isFlowInrange = TRUE; } -#endif - // Verify flow rate of if the bypass flow limit has been enabled +#endif + // Verify flow rate of if the bypass flow limit has been enabled if ( TRUE == isFlowInrange ) - { + { resetBloodPumpRPMMovingAverage(); - targetBloodFlowRate = dirFlowRate; - bloodPumpDirection = dir; - bloodPumpControlMode = mode; - // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed - bloodPumpPWMDutyCyclePct = BP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) - - switch ( bloodPumpState ) - { - case BLOOD_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp - if ( bloodPumpPWMDutyCyclePct < bloodPumpPWMDutyCyclePctSet ) - { - bloodPumpState = BLOOD_PUMP_RAMPING_DOWN_STATE; - } + targetBloodFlowRate = dirFlowRate; + bloodPumpDirection = dir; + bloodPumpControlMode = mode; + // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed + bloodPumpPWMDutyCyclePct = BP_PWM_FROM_ML_PER_MIN((F32)flowRate); // ~ 8% per 100 mL/min with a 10% zero offset added in (e.g. 100 mL/min = 8+10 = 18%) + + switch ( bloodPumpState ) + { + case BLOOD_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp + if ( bloodPumpPWMDutyCyclePct < bloodPumpPWMDutyCyclePctSet ) + { + bloodPumpState = BLOOD_PUMP_RAMPING_DOWN_STATE; + } break; - - case BLOOD_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp - if ( bloodPumpPWMDutyCyclePct > bloodPumpPWMDutyCyclePctSet ) - { - bloodPumpState = BLOOD_PUMP_RAMPING_UP_STATE; - } + + case BLOOD_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp + if ( bloodPumpPWMDutyCyclePct > bloodPumpPWMDutyCyclePctSet ) + { + bloodPumpState = BLOOD_PUMP_RAMPING_UP_STATE; + } break; - - case BLOOD_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction - if ( bloodPumpPWMDutyCyclePctSet > bloodPumpPWMDutyCyclePct ) - { - bloodPumpState = BLOOD_PUMP_RAMPING_DOWN_STATE; - } - else - { - bloodPumpState = BLOOD_PUMP_RAMPING_UP_STATE; - } + + case BLOOD_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction + if ( bloodPumpPWMDutyCyclePctSet > bloodPumpPWMDutyCyclePct ) + { + bloodPumpState = BLOOD_PUMP_RAMPING_DOWN_STATE; + } + else + { + bloodPumpState = BLOOD_PUMP_RAMPING_UP_STATE; + } break; - - default: - // Ok - not all states need to be handled here - break; - } - result = TRUE; - } - else // Requested flow rate too high + default: + // Ok - not all states need to be handled here + break; + } + result = TRUE; + } + + else // Requested flow rate too high { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMPS_FLOW_LIMITS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { + { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_FLOW_SET_TOO_HIGH, flowRate ) - } + } } - } - } - - return result; + } + } + + return result; } /*********************************************************************//** @@ -371,8 +371,8 @@ result = setBloodPumpTargetFlowRate( (U32)BP_ML_PER_MIN_FROM_PWM( pwm ), dir, PUMP_CONTROL_MODE_OPEN_LOOP ); return result; -} - +} + /*********************************************************************//** * @brief * The calcBloodFlow function calculates an estimated blood flow rate from @@ -395,75 +395,75 @@ return flow; } -/*********************************************************************//** - * @brief - * The signalBloodPumpHardStop function stops the blood pump immediately. - * @details Inputs: none - * @details Outputs: Blood pump stopped, set point reset, state changed to off - * @return none - *************************************************************************/ -void signalBloodPumpHardStop( void ) -{ - targetBloodFlowRate = 0; - stopBloodPump(); - bloodPumpState = BLOOD_PUMP_OFF_STATE; - bloodPumpPWMDutyCyclePct = BP_PWM_ZERO_OFFSET; - bpControlTimerCounter = 0; - resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE ); -} - -/*********************************************************************//** - * @brief - * The signalBloodPumpRotorHallSensor function handles the blood pump rotor - * hall sensor detection. Calculates rotor speed (in RPM). Stops pump if - * there is a pending request to home the pump. - * @details Inputs: bpRotorRevStartTime, bpStopAtHomePosition - * @details Outputs: bpRotorRevStartTime, bloodPumpRotorSpeedRPM, bloodPumpRotorCounter - * @return none - *************************************************************************/ -void signalBloodPumpRotorHallSensor( void ) -{ - U32 rotTime = getMSTimerCount(); +/*********************************************************************//** + * @brief + * The signalBloodPumpHardStop function stops the blood pump immediately. + * @details Inputs: none + * @details Outputs: Blood pump stopped, set point reset, state changed to off + * @return none + *************************************************************************/ +void signalBloodPumpHardStop( void ) +{ + targetBloodFlowRate = 0; + stopBloodPump(); + bloodPumpState = BLOOD_PUMP_OFF_STATE; + bloodPumpPWMDutyCyclePct = BP_PWM_ZERO_OFFSET; + bpControlTimerCounter = 0; + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, MIN_BLOOD_PUMP_PWM_DUTY_CYCLE ); +} + +/*********************************************************************//** + * @brief + * The signalBloodPumpRotorHallSensor function handles the blood pump rotor + * hall sensor detection. Calculates rotor speed (in RPM). Stops pump if + * there is a pending request to home the pump. + * @details Inputs: bpRotorRevStartTime, bpStopAtHomePosition + * @details Outputs: bpRotorRevStartTime, bloodPumpRotorSpeedRPM, bloodPumpRotorCounter + * @return none + *************************************************************************/ +void signalBloodPumpRotorHallSensor( void ) +{ + U32 rotTime = getMSTimerCount(); U32 deltaTime = calcTimeBetween( bpRotorRevStartTime, rotTime ); // Increment rotor counter - bloodPumpRotorCounter.data++; - - // Calculate rotor speed (in RPM) - bloodPumpRotorSpeedRPM.data = ( 1.0F / (F32)deltaTime ) * (F32)MS_PER_SECOND * (F32)SEC_PER_MIN; - bpRotorRevStartTime = rotTime; - - // If we are supposed to stop pump at home position, stop pump now. - if ( TRUE == bpStopAtHomePosition ) - { - signalBloodPumpHardStop(); - bpStopAtHomePosition = FALSE; - } -} - -/*********************************************************************//** - * @brief - * The homeBloodPump function initiates a blood pump home operation. - * @details Inputs: bloodPumpState - * @details Outputs: bpStopAtHomePosition, bpHomeStartTime, blood pump started (slow) - * @return none - *************************************************************************/ -BOOL homeBloodPump( void ) -{ - BOOL result = FALSE; - - if ( BLOOD_PUMP_OFF_STATE == bloodPumpState ) - { - bpStopAtHomePosition = TRUE; - bpHomeStartTime = getMSTimerCount(); - result = setBloodPumpTargetRPM( BP_HOME_SPEED, MOTOR_DIR_FORWARD ); - } - - return result; + bloodPumpRotorCounter.data++; + + // Calculate rotor speed (in RPM) + bloodPumpRotorSpeedRPM.data = ( 1.0F / (F32)deltaTime ) * (F32)MS_PER_SECOND * (F32)SEC_PER_MIN; + bpRotorRevStartTime = rotTime; + + // If we are supposed to stop pump at home position, stop pump now. + if ( TRUE == bpStopAtHomePosition ) + { + signalBloodPumpHardStop(); + bpStopAtHomePosition = FALSE; + } } /*********************************************************************//** * @brief + * The homeBloodPump function initiates a blood pump home operation. + * @details Inputs: bloodPumpState + * @details Outputs: bpStopAtHomePosition, bpHomeStartTime, blood pump started (slow) + * @return none + *************************************************************************/ +BOOL homeBloodPump( void ) +{ + BOOL result = FALSE; + + if ( BLOOD_PUMP_OFF_STATE == bloodPumpState ) + { + bpStopAtHomePosition = TRUE; + bpHomeStartTime = getMSTimerCount(); + result = setBloodPumpTargetRPM( BP_HOME_SPEED, MOTOR_DIR_FORWARD ); + } + + return result; +} + +/*********************************************************************//** + * @brief * The getBloodPumpMotorCount function returns the current count for the * blood pump motor revolution counter. * @details Inputs: bloodPumpMotorCount @@ -544,300 +544,300 @@ { bloodPumpRotorCounter.data = 0; } -} - -/*********************************************************************//** - * @brief - * The execBloodFlowMonitor function executes the blood flow monitor. - * @details Inputs: none +} + +/*********************************************************************//** + * @brief + * The execBloodFlowMonitor function executes the blood flow monitor. + * @details Inputs: none * @details Outputs: measuredBloodFlowRate, adcBloodPumpMCSpeedRPM, - * adcBloodPumpMCCurrentmA - * @return none - *************************************************************************/ -void execBloodFlowMonitor( void ) + * adcBloodPumpMCCurrentmA + * @return none + *************************************************************************/ +void execBloodFlowMonitor( void ) { - HD_OP_MODE_T opMode = getCurrentOperationMode(); - U16 bpRPM = getIntADCReading( INT_ADC_BLOOD_PUMP_SPEED ); + HD_OP_MODE_T opMode = getCurrentOperationMode(); + U16 bpRPM = getIntADCReading( INT_ADC_BLOOD_PUMP_SPEED ); U16 bpmA = getIntADCReading( INT_ADC_BLOOD_PUMP_MOTOR_CURRENT ); - adcBloodPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpRPM)) * BP_SPEED_ADC_TO_RPM_FACTOR; + 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; - + filterBloodPumpRPMReadings( getMeasuredBloodPumpMCSpeed() ); measuredBloodFlowRate.data = calcBloodFlow(); // Pressure and rotor speed already filtered as inputs to calc, so no need to filter flow any further - - // Calculate blood pump motor speed/direction from hall sensor count - updateBloodPumpSpeedAndDirectionFromHallSensors(); - - // Do not start enforcing checks until out of init/POST mode - if ( opMode != MODE_INIT ) - { - // Check pump direction - checkBloodPumpDirection(); - // Check pump controller current - checkBloodPumpMCCurrent(); - // Check pump speeds - checkBloodPumpSpeeds(); - // Check for home position, zero/low speed + + // Calculate blood pump motor speed/direction from hall sensor count + updateBloodPumpSpeedAndDirectionFromHallSensors(); + + // Do not start enforcing checks until out of init/POST mode + if ( opMode != MODE_INIT ) + { + // Check pump direction + checkBloodPumpDirection(); + // Check pump controller current + checkBloodPumpMCCurrent(); + // Check pump speeds + checkBloodPumpSpeeds(); + // Check for home position, zero/low speed checkBloodPumpRotor(); } else { lastBloodPumpDirectionCount = getFPGABloodPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; } - - // Publish blood flow data on interval - publishBloodFlowData(); -} - -/*********************************************************************//** - * @brief - * The execBloodFlowController function executes the blood flow controller. - * @details Inputs: bloodPumpState - * @details Outputs: bloodPumpState - * @return none - *************************************************************************/ -void execBloodFlowController( void ) -{ - switch ( bloodPumpState ) - { - case BLOOD_PUMP_OFF_STATE: - bloodPumpState = handleBloodPumpOffState(); - break; - - case BLOOD_PUMP_RAMPING_UP_STATE: - bloodPumpState = handleBloodPumpRampingUpState(); - break; - - case BLOOD_PUMP_RAMPING_DOWN_STATE: - bloodPumpState = handleBloodPumpRampingDownState(); - break; - - case BLOOD_PUMP_CONTROL_TO_TARGET_STATE: - bloodPumpState = handleBloodPumpControlToTargetState(); - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_FLOW_INVALID_BLOOD_PUMP_STATE, bloodPumpState ) - break; - } -} - -/*********************************************************************//** - * @brief - * The handleBloodPumpOffState function handles the blood pump off state - * of the blood pump controller state machine. - * @details Inputs: targetBloodFlowRate, bloodPumpDirection - * @details Outputs: bloodPumpPWMDutyCyclePctSet, bloodPumpDirectionSet, isBloodPumpOn - * @return next state - *************************************************************************/ -static BLOOD_PUMP_STATE_T handleBloodPumpOffState( void ) -{ - BLOOD_PUMP_STATE_T result = BLOOD_PUMP_OFF_STATE; - - // If we have been given a flow rate, setup ramp up and transition to ramp up state - if ( targetBloodFlowRate != 0 ) - { - // Set initial PWM duty cycle - bloodPumpPWMDutyCyclePctSet = BP_PWM_ZERO_OFFSET + MAX_BLOOD_PUMP_PWM_STEP_UP_CHANGE; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); - // Allow blood pump to run in requested direction - setBloodPumpDirection( bloodPumpDirection ); - releaseBloodPumpStop(); - isBloodPumpOn = TRUE; - result = BLOOD_PUMP_RAMPING_UP_STATE; - } + + // Publish blood flow data on interval + publishBloodFlowData(); +} + +/*********************************************************************//** + * @brief + * The execBloodFlowController function executes the blood flow controller. + * @details Inputs: bloodPumpState + * @details Outputs: bloodPumpState + * @return none + *************************************************************************/ +void execBloodFlowController( void ) +{ + switch ( bloodPumpState ) + { + case BLOOD_PUMP_OFF_STATE: + bloodPumpState = handleBloodPumpOffState(); + break; + + case BLOOD_PUMP_RAMPING_UP_STATE: + bloodPumpState = handleBloodPumpRampingUpState(); + break; + + case BLOOD_PUMP_RAMPING_DOWN_STATE: + bloodPumpState = handleBloodPumpRampingDownState(); + break; + + case BLOOD_PUMP_CONTROL_TO_TARGET_STATE: + bloodPumpState = handleBloodPumpControlToTargetState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_FLOW_INVALID_BLOOD_PUMP_STATE, bloodPumpState ) + break; + } +} + +/*********************************************************************//** + * @brief + * The handleBloodPumpOffState function handles the blood pump off state + * of the blood pump controller state machine. + * @details Inputs: targetBloodFlowRate, bloodPumpDirection + * @details Outputs: bloodPumpPWMDutyCyclePctSet, bloodPumpDirectionSet, isBloodPumpOn + * @return next state + *************************************************************************/ +static BLOOD_PUMP_STATE_T handleBloodPumpOffState( void ) +{ + BLOOD_PUMP_STATE_T result = BLOOD_PUMP_OFF_STATE; + + // If we have been given a flow rate, setup ramp up and transition to ramp up state + if ( targetBloodFlowRate != 0 ) + { + // Set initial PWM duty cycle + bloodPumpPWMDutyCyclePctSet = BP_PWM_ZERO_OFFSET + MAX_BLOOD_PUMP_PWM_STEP_UP_CHANGE; + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); + // Allow blood pump to run in requested direction + setBloodPumpDirection( bloodPumpDirection ); + releaseBloodPumpStop(); + isBloodPumpOn = TRUE; + result = BLOOD_PUMP_RAMPING_UP_STATE; + } else { isBloodPumpOn = FALSE; } - - return result; -} - -/*********************************************************************//** - * @brief - * The handleBloodPumpRampingUpState function handles the ramp up state - * of the blood pump controller state machine. - * @details Inputs: bloodPumpPWMDutyCyclePctSet - * @details Outputs: bloodPumpPWMDutyCyclePctSet - * @return next state - *************************************************************************/ -static BLOOD_PUMP_STATE_T handleBloodPumpRampingUpState( void ) -{ - BLOOD_PUMP_STATE_T result = BLOOD_PUMP_RAMPING_UP_STATE; - - // Have we been asked to stop the blood pump? - if ( 0 == targetBloodFlowRate ) - { - // Start ramp down to stop - bloodPumpPWMDutyCyclePctSet -= MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); - result = BLOOD_PUMP_RAMPING_DOWN_STATE; - } - // Have we reached end of ramp up? - else if ( bloodPumpPWMDutyCyclePctSet >= bloodPumpPWMDutyCyclePct ) - { + + return result; +} + +/*********************************************************************//** + * @brief + * The handleBloodPumpRampingUpState function handles the ramp up state + * of the blood pump controller state machine. + * @details Inputs: bloodPumpPWMDutyCyclePctSet + * @details Outputs: bloodPumpPWMDutyCyclePctSet + * @return next state + *************************************************************************/ +static BLOOD_PUMP_STATE_T handleBloodPumpRampingUpState( void ) +{ + BLOOD_PUMP_STATE_T result = BLOOD_PUMP_RAMPING_UP_STATE; + + // Have we been asked to stop the blood pump? + if ( 0 == targetBloodFlowRate ) + { + // Start ramp down to stop + bloodPumpPWMDutyCyclePctSet -= MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE; + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); + result = BLOOD_PUMP_RAMPING_DOWN_STATE; + } + // Have we reached end of ramp up? + else if ( bloodPumpPWMDutyCyclePctSet >= bloodPumpPWMDutyCyclePct ) + { resetBloodPumpRPMMovingAverage(); bloodPumpPWMDutyCyclePctSet = bloodPumpPWMDutyCyclePct; - resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); - bloodPumpControlModeSet = bloodPumpControlMode; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); + bloodPumpControlModeSet = bloodPumpControlMode; + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); bpControlTimerCounter = 0; - result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; - } - // Continue ramp up - else - { - bloodPumpPWMDutyCyclePctSet += MAX_BLOOD_PUMP_PWM_STEP_UP_CHANGE; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); - } - - return result; -} - -/*********************************************************************//** - * @brief - * The handleBloodPumpRampingDownState function handles the ramp down state - * of the blood pump controller state machine. - * @details Inputs: bloodPumpPWMDutyCyclePctSet - * @details Outputs: bloodPumpPWMDutyCyclePctSet - * @return next state - *************************************************************************/ -static BLOOD_PUMP_STATE_T handleBloodPumpRampingDownState( void ) -{ - BLOOD_PUMP_STATE_T result = BLOOD_PUMP_RAMPING_DOWN_STATE; - - // Have we essentially reached zero speed? - if ( bloodPumpPWMDutyCyclePctSet < (MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE + BP_PWM_ZERO_OFFSET) ) - { - signalBloodPumpHardStop(); - result = BLOOD_PUMP_OFF_STATE; - } - // Have we reached end of ramp down? - else if ( bloodPumpPWMDutyCyclePctSet <= bloodPumpPWMDutyCyclePct ) - { + result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; + } + // Continue ramp up + else + { + bloodPumpPWMDutyCyclePctSet += MAX_BLOOD_PUMP_PWM_STEP_UP_CHANGE; + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleBloodPumpRampingDownState function handles the ramp down state + * of the blood pump controller state machine. + * @details Inputs: bloodPumpPWMDutyCyclePctSet + * @details Outputs: bloodPumpPWMDutyCyclePctSet + * @return next state + *************************************************************************/ +static BLOOD_PUMP_STATE_T handleBloodPumpRampingDownState( void ) +{ + BLOOD_PUMP_STATE_T result = BLOOD_PUMP_RAMPING_DOWN_STATE; + + // Have we essentially reached zero speed? + if ( bloodPumpPWMDutyCyclePctSet < (MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE + BP_PWM_ZERO_OFFSET) ) + { + signalBloodPumpHardStop(); + result = BLOOD_PUMP_OFF_STATE; + } + // Have we reached end of ramp down? + else if ( bloodPumpPWMDutyCyclePctSet <= bloodPumpPWMDutyCyclePct ) + { resetBloodPumpRPMMovingAverage(); bloodPumpPWMDutyCyclePctSet = bloodPumpPWMDutyCyclePct; - resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); - bloodPumpControlModeSet = bloodPumpControlMode; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); - bpControlTimerCounter = 0; - result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; - } - // Continue ramp down - else - { - bloodPumpPWMDutyCyclePctSet -= MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE; - setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); - } - - return result; -} - -/*********************************************************************//** - * @brief - * The handleBloodPumpControlToTargetState function handles the "control to - * target" state of the blood pump controller state machine. - * @details Inputs: none - * @details Outputs: bloodPumpState - * @return next state - *************************************************************************/ -static BLOOD_PUMP_STATE_T handleBloodPumpControlToTargetState( void ) -{ - BLOOD_PUMP_STATE_T result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; - - // Control at set interval - if ( ++bpControlTimerCounter >= BP_CONTROL_INTERVAL ) - { - if ( bloodPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) - { - F32 tgtFlow = (F32)targetBloodFlowRate; - F32 actFlow = getMeasuredBloodFlowRate(); - F32 newPWM; - - newPWM = runPIController( PI_CONTROLLER_ID_BLOOD_FLOW, tgtFlow, actFlow ); - bloodPumpPWMDutyCyclePctSet = newPWM; - setBloodPumpControlSignalPWM( newPWM ); - } - bpControlTimerCounter = 0; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The setBloodPumpControlSignalPWM function sets the PWM duty cycle for - * the blood pump to a given %. - * @details Inputs: none - * @details Outputs: blood pump stop signal activated, PWM duty cycle zeroed - * @param newPWM new duty cycle % to apply to PWM - * @return none - *************************************************************************/ -static void setBloodPumpControlSignalPWM( F32 newPWM ) -{ - etpwmSetCmpA( etpwmREG1, (U32)( (S32)( ( newPWM * (F32)(etpwmREG1->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); -} - -/*********************************************************************//** - * @brief - * The stopBloodPump function sets the blood pump stop signal. - * @details Inputs: none - * @details Outputs: blood pump stop signal activated, PWM duty cycle zeroed - * @return none - *************************************************************************/ -static void stopBloodPump( void ) -{ - isBloodPumpOn = FALSE; - bloodPumpPWMDutyCyclePctSet = BP_PWM_ZERO_OFFSET; - etpwmSetCmpA( etpwmREG1, 0 ); - SET_BP_STOP(); -} - -/*********************************************************************//** - * @brief - * The releaseBloodPumpStop function clears the blood pump stop signal. - * @details Inputs: none - * @details Outputs: blood pump stop signal - * @return none - *************************************************************************/ -static void releaseBloodPumpStop( void ) -{ - CLR_BP_STOP(); -} - -/*********************************************************************//** - * @brief - * The setBloodPumpDirection function sets the set blood pump direction to - * the given direction. - * @details Inputs: bloodPumpState - * @details Outputs: bloodPumpState - * @param dir blood pump direction to set - * @return none - *************************************************************************/ -static void setBloodPumpDirection( MOTOR_DIR_T dir ) -{ - switch ( dir ) - { - case MOTOR_DIR_FORWARD: - bloodPumpDirectionSet = dir; - SET_BP_DIR(); - break; - - case MOTOR_DIR_REVERSE: - bloodPumpDirectionSet = dir; - CLR_BP_DIR(); - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_FLOW_INVALID_BLOOD_PUMP_DIRECTION, dir ) - break; - } + resetPIController( PI_CONTROLLER_ID_BLOOD_FLOW, bloodPumpPWMDutyCyclePctSet ); + bloodPumpControlModeSet = bloodPumpControlMode; + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); + bpControlTimerCounter = 0; + result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; + } + // Continue ramp down + else + { + bloodPumpPWMDutyCyclePctSet -= MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE; + setBloodPumpControlSignalPWM( bloodPumpPWMDutyCyclePctSet ); + } + + return result; } /*********************************************************************//** * @brief + * The handleBloodPumpControlToTargetState function handles the "control to + * target" state of the blood pump controller state machine. + * @details Inputs: none + * @details Outputs: bloodPumpState + * @return next state + *************************************************************************/ +static BLOOD_PUMP_STATE_T handleBloodPumpControlToTargetState( void ) +{ + BLOOD_PUMP_STATE_T result = BLOOD_PUMP_CONTROL_TO_TARGET_STATE; + + // Control at set interval + if ( ++bpControlTimerCounter >= BP_CONTROL_INTERVAL ) + { + if ( bloodPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) + { + F32 tgtFlow = (F32)targetBloodFlowRate; + F32 actFlow = getMeasuredBloodFlowRate(); + F32 newPWM; + + newPWM = runPIController( PI_CONTROLLER_ID_BLOOD_FLOW, tgtFlow, actFlow ); + bloodPumpPWMDutyCyclePctSet = newPWM; + setBloodPumpControlSignalPWM( newPWM ); + } + bpControlTimerCounter = 0; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setBloodPumpControlSignalPWM function sets the PWM duty cycle for + * the blood pump to a given %. + * @details Inputs: none + * @details Outputs: blood pump stop signal activated, PWM duty cycle zeroed + * @param newPWM new duty cycle % to apply to PWM + * @return none + *************************************************************************/ +static void setBloodPumpControlSignalPWM( F32 newPWM ) +{ + etpwmSetCmpA( etpwmREG1, (U32)( (S32)( ( newPWM * (F32)(etpwmREG1->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); +} + +/*********************************************************************//** + * @brief + * The stopBloodPump function sets the blood pump stop signal. + * @details Inputs: none + * @details Outputs: blood pump stop signal activated, PWM duty cycle zeroed + * @return none + *************************************************************************/ +static void stopBloodPump( void ) +{ + isBloodPumpOn = FALSE; + bloodPumpPWMDutyCyclePctSet = BP_PWM_ZERO_OFFSET; + etpwmSetCmpA( etpwmREG1, 0 ); + SET_BP_STOP(); +} + +/*********************************************************************//** + * @brief + * The releaseBloodPumpStop function clears the blood pump stop signal. + * @details Inputs: none + * @details Outputs: blood pump stop signal + * @return none + *************************************************************************/ +static void releaseBloodPumpStop( void ) +{ + CLR_BP_STOP(); +} + +/*********************************************************************//** + * @brief + * The setBloodPumpDirection function sets the set blood pump direction to + * the given direction. + * @details Inputs: bloodPumpState + * @details Outputs: bloodPumpState + * @param dir blood pump direction to set + * @return none + *************************************************************************/ +static void setBloodPumpDirection( MOTOR_DIR_T dir ) +{ + switch ( dir ) + { + case MOTOR_DIR_FORWARD: + bloodPumpDirectionSet = dir; + SET_BP_DIR(); + break; + + case MOTOR_DIR_REVERSE: + bloodPumpDirectionSet = dir; + CLR_BP_DIR(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_FLOW_INVALID_BLOOD_PUMP_DIRECTION, dir ) + break; + } +} + +/*********************************************************************//** + * @brief * The getTargetBloodFlowRate function gets the target blood flow rate. * @details Inputs: targetBloodFlowRate * @details Outputs: none @@ -846,121 +846,121 @@ S32 getTargetBloodFlowRate( void ) { return targetBloodFlowRate; -} - -/*********************************************************************//** - * @brief - * The getMeasuredBloodFlowRate function gets the measured blood flow - * rate. - * @details Inputs: measuredBloodFlowRate - * @details Outputs: none - * @return the current blood flow rate (in mL/min). - *************************************************************************/ -F32 getMeasuredBloodFlowRate( void ) -{ - F32 result = measuredBloodFlowRate.data; - - if ( OVERRIDE_KEY == measuredBloodFlowRate.override ) - { - result = measuredBloodFlowRate.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The getMeasuredBloodPumpRotorSpeed function gets the measured blood flow - * rate. - * @details Inputs: bloodPumpRotorSpeedRPM - * @details Outputs: none - * @return the current blood flow rate (in mL/min). - *************************************************************************/ -F32 getMeasuredBloodPumpRotorSpeed( void ) -{ - F32 result = bloodPumpRotorSpeedRPM.data; - - if ( OVERRIDE_KEY == bloodPumpRotorSpeedRPM.override ) - { - result = bloodPumpRotorSpeedRPM.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The getMeasuredBloodPumpSpeed function gets the measured blood flow - * rate. - * @details Inputs: bloodPumpSpeedRPM - * @details Outputs: none - * @return the current blood flow rate (in mL/min). - *************************************************************************/ -F32 getMeasuredBloodPumpSpeed( void ) -{ - F32 result = bloodPumpSpeedRPM.data; - - if ( OVERRIDE_KEY == bloodPumpSpeedRPM.override ) - { - result = bloodPumpSpeedRPM.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The getMeasuredBloodPumpMCSpeed function gets the measured blood pump - * speed. - * @details Inputs: adcBloodPumpMCSpeedRPM - * @details Outputs: none - * @return the current blood pump speed (in RPM). - *************************************************************************/ -F32 getMeasuredBloodPumpMCSpeed( void ) -{ - F32 result = adcBloodPumpMCSpeedRPM.data; - - if ( OVERRIDE_KEY == adcBloodPumpMCSpeedRPM.override ) - { - result = adcBloodPumpMCSpeedRPM.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The getMeasuredBloodPumpMCCurrent function gets the measured blood pump - * current. - * @details Inputs: adcBloodPumpMCCurrentmA - * @details Outputs: none - * @return the current blood pump current (in mA). - *************************************************************************/ -F32 getMeasuredBloodPumpMCCurrent( void ) -{ - F32 result = adcBloodPumpMCCurrentmA.data; - - if ( OVERRIDE_KEY == adcBloodPumpMCCurrentmA.override ) - { - result = adcBloodPumpMCCurrentmA.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The publishBloodFlowData function publishes blood flow data at the set - * interval. - * @details Inputs: target flow rate, measured flow rate, measured MC speed, - * measured MC current - * @details Outputs: Blood flow data is published to CAN bus. - * @return none - *************************************************************************/ -static void publishBloodFlowData( void ) -{ +} + +/*********************************************************************//** + * @brief + * The getMeasuredBloodFlowRate function gets the measured blood flow + * rate. + * @details Inputs: measuredBloodFlowRate + * @details Outputs: none + * @return the current blood flow rate (in mL/min). + *************************************************************************/ +F32 getMeasuredBloodFlowRate( void ) +{ + F32 result = measuredBloodFlowRate.data; + + if ( OVERRIDE_KEY == measuredBloodFlowRate.override ) + { + result = measuredBloodFlowRate.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getMeasuredBloodPumpRotorSpeed function gets the measured blood flow + * rate. + * @details Inputs: bloodPumpRotorSpeedRPM + * @details Outputs: none + * @return the current blood flow rate (in mL/min). + *************************************************************************/ +F32 getMeasuredBloodPumpRotorSpeed( void ) +{ + F32 result = bloodPumpRotorSpeedRPM.data; + + if ( OVERRIDE_KEY == bloodPumpRotorSpeedRPM.override ) + { + result = bloodPumpRotorSpeedRPM.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getMeasuredBloodPumpSpeed function gets the measured blood flow + * rate. + * @details Inputs: bloodPumpSpeedRPM + * @details Outputs: none + * @return the current blood flow rate (in mL/min). + *************************************************************************/ +F32 getMeasuredBloodPumpSpeed( void ) +{ + F32 result = bloodPumpSpeedRPM.data; + + if ( OVERRIDE_KEY == bloodPumpSpeedRPM.override ) + { + result = bloodPumpSpeedRPM.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getMeasuredBloodPumpMCSpeed function gets the measured blood pump + * speed. + * @details Inputs: adcBloodPumpMCSpeedRPM + * @details Outputs: none + * @return the current blood pump speed (in RPM). + *************************************************************************/ +F32 getMeasuredBloodPumpMCSpeed( void ) +{ + F32 result = adcBloodPumpMCSpeedRPM.data; + + if ( OVERRIDE_KEY == adcBloodPumpMCSpeedRPM.override ) + { + result = adcBloodPumpMCSpeedRPM.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getMeasuredBloodPumpMCCurrent function gets the measured blood pump + * current. + * @details Inputs: adcBloodPumpMCCurrentmA + * @details Outputs: none + * @return the current blood pump current (in mA). + *************************************************************************/ +F32 getMeasuredBloodPumpMCCurrent( void ) +{ + F32 result = adcBloodPumpMCCurrentmA.data; + + if ( OVERRIDE_KEY == adcBloodPumpMCCurrentmA.override ) + { + result = adcBloodPumpMCCurrentmA.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The publishBloodFlowData function publishes blood flow data at the set + * interval. + * @details Inputs: target flow rate, measured flow rate, measured MC speed, + * measured MC current + * @details Outputs: Blood flow data is published to CAN bus. + * @return none + *************************************************************************/ +static void publishBloodFlowData( void ) +{ // Publish blood flow data on interval - if ( ++bloodFlowDataPublicationTimerCounter >= getU32OverrideValue( &bloodFlowDataPublishInterval ) ) + if ( ++bloodFlowDataPublicationTimerCounter >= getU32OverrideValue( &bloodFlowDataPublishInterval ) ) { BLOOD_PUMP_STATUS_PAYLOAD_T payload; HD_OP_MODE_T opMode = getCurrentOperationMode(); @@ -982,10 +982,10 @@ payload.presFlow = 0; } broadcastData( MSG_ID_BLOOD_FLOW_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&payload, sizeof( BLOOD_PUMP_STATUS_PAYLOAD_T ) ); - bloodFlowDataPublicationTimerCounter = 0; - } -} - + bloodFlowDataPublicationTimerCounter = 0; + } +} + /*********************************************************************//** * @brief * The resetBloodPumpRPMMovingAverage function re-initializes the pump speed @@ -1024,96 +1024,96 @@ filteredBloodPumpSpeed = rpmReadingsTotal / (F32)rpmReadingsCount; } -/*********************************************************************//** - * @brief - * The updateBloodPumpSpeedAndDirectionFromHallSensors function calculates - * the blood pump motor speed and direction from hall sensor counter on - * a 1 second interval. - * @details Inputs: bpLastMotorHallSensorCount, bpMotorSpeedCalcTimerCtr, current count from FPGA - * @details Outputs: bpMotorDirectionFromHallSensors, bloodPumpSpeedRPM - * @return none - *************************************************************************/ -static void updateBloodPumpSpeedAndDirectionFromHallSensors( void ) -{ - if ( ++bpMotorSpeedCalcTimerCtr >= BP_SPEED_CALC_INTERVAL ) - { +/*********************************************************************//** + * @brief + * The updateBloodPumpSpeedAndDirectionFromHallSensors function calculates + * the blood pump motor speed and direction from hall sensor counter on + * a 1 second interval. + * @details Inputs: bpLastMotorHallSensorCount, bpMotorSpeedCalcTimerCtr, current count from FPGA + * @details Outputs: bpMotorDirectionFromHallSensors, bloodPumpSpeedRPM + * @return none + *************************************************************************/ +static void updateBloodPumpSpeedAndDirectionFromHallSensors( void ) +{ + if ( ++bpMotorSpeedCalcTimerCtr >= BP_SPEED_CALC_INTERVAL ) + { U16 bpMotorHallSensorCount = getFPGABloodPumpHallSensorCount(); U16 last = bpLastMotorHallSensorCounts[ bpMotorSpeedCalcIdx ]; U32 nextIdx = INC_WRAP( bpMotorSpeedCalcIdx, 0, BP_SPEED_CALC_BUFFER_LEN - 1 ); - U16 incDelta = u16DiffWithWrap( bpLastMotorHallSensorCounts[ nextIdx ], bpMotorHallSensorCount ); - U16 decDelta = ( 0 == incDelta ? 0xFFFF : HEX_64_K - incDelta ); - U16 spdDelta; + U16 incDelta = u16DiffWithWrap( bpLastMotorHallSensorCounts[ nextIdx ], bpMotorHallSensorCount ); + U16 decDelta = ( 0 == incDelta ? 0xFFFF : HEX_64_K - incDelta ); + U16 spdDelta; S16 delta; - // Determine blood pump speed/direction from delta hall sensor count since last interval - if ( incDelta < decDelta ) - { - spdDelta = incDelta; + // Determine blood pump speed/direction from delta hall sensor count since last interval + if ( incDelta < decDelta ) + { + spdDelta = incDelta; bloodPumpSpeedRPM.data = ( (F32)spdDelta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; - } - else - { - spdDelta = decDelta; + } + else + { + spdDelta = decDelta; bloodPumpSpeedRPM.data = ( (F32)spdDelta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; } // Keep a running 32-bit edge count used for safety check on volume in some functions delta = u16BiDiffWithWrap( last, bpMotorHallSensorCount ); bloodPumpMotorEdgeCount += ( delta >= 0 ? (U16)delta : 0 ); - - // Update last count for next time + + // Update last count for next time bpLastMotorHallSensorCounts[ nextIdx ] = bpMotorHallSensorCount; - bpMotorSpeedCalcIdx = nextIdx; - bpMotorSpeedCalcTimerCtr = 0; - } -} - -/*********************************************************************//** - * @brief - * The checkBloodPumpRotor function checks the rotor for the blood - * pump. If homing, this function will stop when hall sensor detected. If pump - * is off or running very slowly, rotor speed will be set to zero. - * @details Inputs: bpStopAtHomePosition, bpHomeStartTime, bpRotorRevStartTime - * @details Outputs: pump may be stopped if homing, bloodPumpRotorSpeedRPM may be set to zero. - * @return none - *************************************************************************/ -static void checkBloodPumpRotor( void ) -{ - F32 rotorSpeed = getMeasuredBloodPumpRotorSpeed(); - - // If homing, check timeout - if ( ( TRUE == bpStopAtHomePosition ) && ( TRUE == didTimeout( bpHomeStartTime, BP_HOME_TIMEOUT_MS ) ) ) - { - signalBloodPumpHardStop(); - bpStopAtHomePosition = FALSE; - // TODO - alarm??? - } - + bpMotorSpeedCalcIdx = nextIdx; + bpMotorSpeedCalcTimerCtr = 0; + } +} + +/*********************************************************************//** + * @brief + * The checkBloodPumpRotor function checks the rotor for the blood + * pump. If homing, this function will stop when hall sensor detected. If pump + * is off or running very slowly, rotor speed will be set to zero. + * @details Inputs: bpStopAtHomePosition, bpHomeStartTime, bpRotorRevStartTime + * @details Outputs: pump may be stopped if homing, bloodPumpRotorSpeedRPM may be set to zero. + * @return none + *************************************************************************/ +static void checkBloodPumpRotor( void ) +{ + F32 rotorSpeed = getMeasuredBloodPumpRotorSpeed(); + + // If homing, check timeout + if ( ( TRUE == bpStopAtHomePosition ) && ( TRUE == didTimeout( bpHomeStartTime, BP_HOME_TIMEOUT_MS ) ) ) + { + signalBloodPumpHardStop(); + bpStopAtHomePosition = FALSE; + // TODO - alarm??? + } + // Ensure rotor speed below maximum if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH, rotorSpeed > BP_MAX_ROTOR_SPEED_RPM ) ) { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH, rotorSpeed ) - } - - // If pump is stopped or running very slowly, set rotor speed to zero - if ( TRUE == didTimeout( bpRotorRevStartTime, BP_MAX_ROTOR_HALL_INTERVAL_MS ) ) - { - bloodPumpRotorSpeedRPM.data = 0.0; - } -} - -/*********************************************************************//** - * @brief - * The checkBloodPumpDirection function checks the set direction vs. - * the direction implied by the sign of the measured MC speed. - * @details Inputs: - * @details Outputs: - * @return none - *************************************************************************/ -static void checkBloodPumpDirection( void ) -{ - if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) - { + } + + // If pump is stopped or running very slowly, set rotor speed to zero + if ( TRUE == didTimeout( bpRotorRevStartTime, BP_MAX_ROTOR_HALL_INTERVAL_MS ) ) + { + bloodPumpRotorSpeedRPM.data = 0.0; + } +} + +/*********************************************************************//** + * @brief + * The checkBloodPumpDirection function checks the set direction vs. + * the direction implied by the sign of the measured MC speed. + * @details Inputs: + * @details Outputs: + * @return none + *************************************************************************/ +static void checkBloodPumpDirection( void ) +{ + if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) + { MOTOR_DIR_T bpMCDir, bpDir; BOOL isDirIncorrect; U08 dirErrorCnt = getFPGABloodPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; @@ -1135,7 +1135,7 @@ 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 vs. direction from sign of motor controller speed isDirIncorrect = ( ( ( bloodPumpDirectionSet != bpDir ) || ( bloodPumpDirectionSet != bpMCDir ) ) && ( TRUE == minDirSpeed ) ); if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BLOOD_PUMP_MC_DIRECTION_CHECK, isDirIncorrect ) ) @@ -1159,26 +1159,26 @@ { resetPersistentAlarmTimer( ALARM_ID_HD_BLOOD_PUMP_MC_DIRECTION_CHECK ); } -} - -/*********************************************************************//** - * @brief - * The checkBloodPumpSpeeds function checks several aspects of the blood pump - * speed. - * 1. while pump is commanded off, measured motor speed should be < limit. - * 2. while pump is controlling, measured motor speed should be within allowed range of commanded speed. - * 3. measured motor speed should be within allowed range of measured rotor speed. - * All 3 checks have a persistence time that must be met before an alarm is triggered. - * @details Inputs: bloodPumpState, targetBloodFlowRate, bloodPumpPWMDutyCyclePctSet, bloodPumpDirectionSet - * @details Outputs: errorBloodRotorSpeedPersistTimerCtr, alarm(s) may be triggered - * @return none - *************************************************************************/ -static void checkBloodPumpSpeeds( void ) -{ +} + +/*********************************************************************//** + * @brief + * The checkBloodPumpSpeeds function checks several aspects of the blood pump + * speed. + * 1. while pump is commanded off, measured motor speed should be < limit. + * 2. while pump is controlling, measured motor speed should be within allowed range of commanded speed. + * 3. measured motor speed should be within allowed range of measured rotor speed. + * All 3 checks have a persistence time that must be met before an alarm is triggered. + * @details Inputs: bloodPumpState, targetBloodFlowRate, bloodPumpPWMDutyCyclePctSet, bloodPumpDirectionSet + * @details Outputs: errorBloodRotorSpeedPersistTimerCtr, alarm(s) may be triggered + * @return none + *************************************************************************/ +static void checkBloodPumpSpeeds( void ) +{ F32 measMotorSpeed = getMeasuredBloodPumpSpeed(); F32 measMCMotorSpeed = getMeasuredBloodPumpMCSpeed(); - - // Check for pump running while commanded off + + // Check for pump running while commanded off if ( ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BLOOD_PUMP_OFF_CHECK, ( 0 == targetBloodFlowRate ) && ( fabs( measMotorSpeed ) > BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) ) ) ) { @@ -1188,20 +1188,20 @@ { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_BLOOD_PUMP_OFF_CHECK, measMotorSpeed ); activateSafetyShutdown(); - } - } - + } + } + // 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, bloodPumpDirectionSet ); + if ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) + { + F32 cmdMotorSpeed = BP_PWM_TO_MOTOR_SPEED_RPM( bloodPumpPWMDutyCyclePctSet, bloodPumpDirectionSet ); F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); - F32 deltaMCMotorSpeed = fabs( measMCMotorSpeed - cmdMotorSpeed ); - F32 measRotorSpeed = fabs( getMeasuredBloodPumpRotorSpeed() ); - F32 measMotorSpeedInRotorRPM = fabs( measMotorSpeed / BP_GEAR_RATIO ); + F32 deltaMCMotorSpeed = fabs( measMCMotorSpeed - cmdMotorSpeed ); + F32 measRotorSpeed = fabs( getMeasuredBloodPumpRotorSpeed() ); + F32 measMotorSpeedInRotorRPM = fabs( measMotorSpeed / BP_GEAR_RATIO ); F32 deltaRotorSpeed = fabs( measRotorSpeed - measMotorSpeedInRotorRPM ); - F32 measMotorSpeedDeltaPct = fabs( deltaRotorSpeed / measMotorSpeedInRotorRPM ); - + F32 measMotorSpeedDeltaPct = fabs( deltaRotorSpeed / measMotorSpeedInRotorRPM ); + // Check measured motor speed vs. commanded motor speed while controlling to target if ( ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BLOOD_PUMP_MOTOR_SPEED_CHECK, ( deltaMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) || ( deltaMCMotorSpeed > BP_MAX_MOTOR_SPEED_ERROR_RPM ) ) ) ) @@ -1212,8 +1212,8 @@ { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_BLOOD_PUMP_MOTOR_SPEED_CHECK, cmdMotorSpeed, measMotorSpeed ); } - } - + } + // Check measured rotor speed vs. measured motor speed while controlling to target if ( ( deltaRotorSpeed > BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM ) && ( measMotorSpeedDeltaPct > BP_MAX_MOTOR_SPEED_VS_TRGT_DIFF_PCT ) ) { @@ -1230,27 +1230,27 @@ else { errorBloodRotorSpeedPersistTimerCtr = 0; - } + } } else { resetPersistentAlarmTimer( ALARM_ID_HD_BLOOD_PUMP_MOTOR_SPEED_CHECK ); errorBloodRotorSpeedPersistTimerCtr = 0; - - } -} - -/*********************************************************************//** - * @brief - * The checkBloodPumpMCCurrent function checks the measured MC current vs. - * the set state of the blood pump (stopped or running). - * @details Inputs: BP motor controller measured current. - * @details Outputs: Alarm triggered it current too high. - * @return none - *************************************************************************/ -static void checkBloodPumpMCCurrent( void ) -{ - F32 const bpCurr = fabs( getMeasuredBloodPumpMCCurrent() ); + + } +} + +/*********************************************************************//** + * @brief + * The checkBloodPumpMCCurrent function checks the measured MC current vs. + * the set state of the blood pump (stopped or running). + * @details Inputs: BP motor controller measured current. + * @details Outputs: Alarm triggered it current too high. + * @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 ) ? TRUE : FALSE ); // Check blood pump current during running state @@ -1265,18 +1265,18 @@ { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_BLOOD_PUMP_MC_CURRENT_CHECK, bpCurr ); } - } + } } -/*********************************************************************//** - * @brief - * The execBloodFlowTest function executes the state machine for the - * BloodFlow self-test. - * @details Inputs: bloodPumpCalRecord - * @details Outputs: none - * @return the current state of the BloodFlow self-test. - *************************************************************************/ -SELF_TEST_STATUS_T execBloodFlowTest( void ) +/*********************************************************************//** + * @brief + * The execBloodFlowTest function executes the state machine for the + * BloodFlow self-test. + * @details Inputs: bloodPumpCalRecord + * @details Outputs: none + * @return the current state of the BloodFlow self-test. + *************************************************************************/ +SELF_TEST_STATUS_T execBloodFlowTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; @@ -1291,325 +1291,325 @@ { result = SELF_TEST_STATUS_FAILED; } - - return result; -} - - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ + return result; +} -/*********************************************************************//** - * @brief - * The testSetBloodFlowDataPublishIntervalOverride function overrides the - * blood flow data publish interval. - * @details Inputs: none - * @details Outputs: bloodFlowDataPublishInterval - * @param value override blood flow data publish interval with (in ms) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetBloodFlowDataPublishIntervalOverride( U32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - U32 intvl = value / TASK_PRIORITY_INTERVAL; - - result = TRUE; - bloodFlowDataPublishInterval.ovData = intvl; - bloodFlowDataPublishInterval.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetBloodFlowDataPublishIntervalOverride function resets the override - * of the blood flow data publish interval. - * @details Inputs: none - * @details Outputs: bloodFlowDataPublishInterval - * @return TRUE if override reset successful, FALSE if not - *************************************************************************/ -BOOL testResetBloodFlowDataPublishIntervalOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - bloodFlowDataPublishInterval.override = OVERRIDE_RESET; - bloodFlowDataPublishInterval.ovData = bloodFlowDataPublishInterval.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetTargetBloodFlowRateOverride function overrides the target - * blood flow rate. - * @details Inputs: none - * @details Outputs: targetBloodFlowRate + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetBloodFlowDataPublishIntervalOverride function overrides the + * blood flow data publish interval. + * @details Inputs: none + * @details Outputs: bloodFlowDataPublishInterval + * @param value override blood flow data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetBloodFlowDataPublishIntervalOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = value / TASK_PRIORITY_INTERVAL; + + result = TRUE; + bloodFlowDataPublishInterval.ovData = intvl; + bloodFlowDataPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetBloodFlowDataPublishIntervalOverride function resets the override + * of the blood flow data publish interval. + * @details Inputs: none + * @details Outputs: bloodFlowDataPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetBloodFlowDataPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodFlowDataPublishInterval.override = OVERRIDE_RESET; + bloodFlowDataPublishInterval.ovData = bloodFlowDataPublishInterval.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetTargetBloodFlowRateOverride function overrides the target + * blood flow rate. + * @details Inputs: none + * @details Outputs: targetBloodFlowRate * @param value override target blood flow rate (in mL/min) - * @param ctrlMode override pump control mode to this mode (0 = closed loop, 1 = open loop) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetTargetBloodFlowRateOverride( S32 value, U32 ctrlMode ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - MOTOR_DIR_T dir; - - if ( value < 0 ) - { - dir = MOTOR_DIR_REVERSE; - } - else - { - dir = MOTOR_DIR_FORWARD; + * @param ctrlMode override pump control mode to this mode (0 = closed loop, 1 = open loop) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetTargetBloodFlowRateOverride( S32 value, U32 ctrlMode ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + MOTOR_DIR_T dir; + + if ( value < 0 ) + { + dir = MOTOR_DIR_REVERSE; } + else + { + dir = MOTOR_DIR_FORWARD; + } if ( ctrlMode < NUM_OF_PUMP_CONTROL_MODES ) { result = setBloodPumpTargetFlowRate( abs(value), dir, (PUMP_CONTROL_MODE_T)ctrlMode ); - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredBloodFlowRateOverride function overrides the measured - * blood flow rate. - * @details Inputs: none - * @details Outputs: measuredBloodFlowRate - * @param value override measured blood flow rate (in mL/min) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredBloodFlowRateOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - measuredBloodFlowRate.ovData = value; - measuredBloodFlowRate.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredBloodFlowRateOverride function resets the override of the - * measured blood flow rate. - * @details Inputs: none - * @details Outputs: measuredBloodFlowRate - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredBloodFlowRateOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - measuredBloodFlowRate.override = OVERRIDE_RESET; - measuredBloodFlowRate.ovData = measuredBloodFlowRate.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetMeasuredBloodPumpRotorSpeedOverride function overrides the measured - * blood pump rotor speed. - * @details Inputs: none - * @details Outputs: bloodPumpRotorSpeedRPM - * @param value override measured blood pump rotor speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredBloodPumpRotorSpeedOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - bloodPumpRotorSpeedRPM.ovData = value; - bloodPumpRotorSpeedRPM.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredBloodPumpRotorSpeedOverride function resets the override of the - * measured blood pump rotor speed. - * @details Inputs: none - * @details Outputs: bloodPumpRotorSpeedRPM - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredBloodPumpRotorSpeedOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - bloodPumpRotorSpeedRPM.override = OVERRIDE_RESET; - bloodPumpRotorSpeedRPM.ovData = bloodPumpRotorSpeedRPM.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetMeasuredBloodPumpSpeedOverride function overrides the measured - * blood pump motor speed. - * @details Inputs: none - * @details Outputs: bloodPumpSpeedRPM - * @param value override measured blood pump motor speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredBloodPumpSpeedOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - bloodPumpSpeedRPM.ovData = value; - bloodPumpSpeedRPM.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredBloodPumpSpeedOverride function resets the override of the - * measured blood pump motor speed. - * @details Inputs: none - * @details Outputs: bloodPumpSpeedRPM - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredBloodPumpSpeedOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - bloodPumpSpeedRPM.override = OVERRIDE_RESET; - bloodPumpSpeedRPM.ovData = bloodPumpSpeedRPM.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetMeasuredBloodPumpMCSpeedOverride function overrides the measured - * blood pump motor speed. - * @details Inputs: none - * @details Outputs: adcBloodPumpMCSpeedRPM - * @param value override measured blood pump speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredBloodPumpMCSpeedOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - adcBloodPumpMCSpeedRPM.ovData = value; - adcBloodPumpMCSpeedRPM.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredBloodPumpMCSpeedOverride function resets the override of the - * measured blood pump motor speed. - * @details Inputs: none - * @details Outputs: adcBloodPumpMCSpeedRPM - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredBloodPumpMCSpeedOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - adcBloodPumpMCSpeedRPM.override = OVERRIDE_RESET; - adcBloodPumpMCSpeedRPM.ovData = adcBloodPumpMCSpeedRPM.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetMeasuredBloodPumpMCCurrentOverride function overrides the measured - * blood pump motor current. - * @details Inputs: none - * @details Outputs: adcBloodPumpMCCurrentmA - * @param value override measured blood pump current (in mA) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredBloodPumpMCCurrentOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - adcBloodPumpMCCurrentmA.ovData = value; - adcBloodPumpMCCurrentmA.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredBloodPumpMCCurrentOverride function resets the override of the - * measured blood pump motor current. - * @details Inputs: none - * @details Outputs: adcBloodPumpMCCurrentmA - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredBloodPumpMCCurrentOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - adcBloodPumpMCCurrentmA.override = OVERRIDE_RESET; - adcBloodPumpMCCurrentmA.ovData = adcBloodPumpMCCurrentmA.ovInitData; - } - - return result; -} + } + } + return result; +} + /*********************************************************************//** * @brief + * The testResetMeasuredBloodFlowRateOverride function overrides the measured + * blood flow rate. + * @details Inputs: none + * @details Outputs: measuredBloodFlowRate + * @param value override measured blood flow rate (in mL/min) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredBloodFlowRateOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + measuredBloodFlowRate.ovData = value; + measuredBloodFlowRate.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredBloodFlowRateOverride function resets the override of the + * measured blood flow rate. + * @details Inputs: none + * @details Outputs: measuredBloodFlowRate + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredBloodFlowRateOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + measuredBloodFlowRate.override = OVERRIDE_RESET; + measuredBloodFlowRate.ovData = measuredBloodFlowRate.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetMeasuredBloodPumpRotorSpeedOverride function overrides the measured + * blood pump rotor speed. + * @details Inputs: none + * @details Outputs: bloodPumpRotorSpeedRPM + * @param value override measured blood pump rotor speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredBloodPumpRotorSpeedOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodPumpRotorSpeedRPM.ovData = value; + bloodPumpRotorSpeedRPM.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredBloodPumpRotorSpeedOverride function resets the override of the + * measured blood pump rotor speed. + * @details Inputs: none + * @details Outputs: bloodPumpRotorSpeedRPM + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredBloodPumpRotorSpeedOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodPumpRotorSpeedRPM.override = OVERRIDE_RESET; + bloodPumpRotorSpeedRPM.ovData = bloodPumpRotorSpeedRPM.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetMeasuredBloodPumpSpeedOverride function overrides the measured + * blood pump motor speed. + * @details Inputs: none + * @details Outputs: bloodPumpSpeedRPM + * @param value override measured blood pump motor speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredBloodPumpSpeedOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodPumpSpeedRPM.ovData = value; + bloodPumpSpeedRPM.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredBloodPumpSpeedOverride function resets the override of the + * measured blood pump motor speed. + * @details Inputs: none + * @details Outputs: bloodPumpSpeedRPM + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredBloodPumpSpeedOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodPumpSpeedRPM.override = OVERRIDE_RESET; + bloodPumpSpeedRPM.ovData = bloodPumpSpeedRPM.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetMeasuredBloodPumpMCSpeedOverride function overrides the measured + * blood pump motor speed. + * @details Inputs: none + * @details Outputs: adcBloodPumpMCSpeedRPM + * @param value override measured blood pump speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredBloodPumpMCSpeedOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + adcBloodPumpMCSpeedRPM.ovData = value; + adcBloodPumpMCSpeedRPM.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredBloodPumpMCSpeedOverride function resets the override of the + * measured blood pump motor speed. + * @details Inputs: none + * @details Outputs: adcBloodPumpMCSpeedRPM + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredBloodPumpMCSpeedOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + adcBloodPumpMCSpeedRPM.override = OVERRIDE_RESET; + adcBloodPumpMCSpeedRPM.ovData = adcBloodPumpMCSpeedRPM.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetMeasuredBloodPumpMCCurrentOverride function overrides the measured + * blood pump motor current. + * @details Inputs: none + * @details Outputs: adcBloodPumpMCCurrentmA + * @param value override measured blood pump current (in mA) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredBloodPumpMCCurrentOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + adcBloodPumpMCCurrentmA.ovData = value; + adcBloodPumpMCCurrentmA.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredBloodPumpMCCurrentOverride function resets the override of the + * measured blood pump motor current. + * @details Inputs: none + * @details Outputs: adcBloodPumpMCCurrentmA + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredBloodPumpMCCurrentOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + adcBloodPumpMCCurrentmA.override = OVERRIDE_RESET; + adcBloodPumpMCCurrentmA.ovData = adcBloodPumpMCCurrentmA.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief * The testSetBloodPumpRotorCountOverride function overrides the blood pump * rotor counter value. * @details Inputs: none @@ -1674,5 +1674,5 @@ return result; } - -/**@}*/ + +/**@}*/ Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r2c1c34c153a146d659976b3aa499937b88264b1b -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 2c1c34c153a146d659976b3aa499937b88264b1b) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -89,6 +89,7 @@ #define BLOOD_LEAK_EMB_MODE_NUM_OF_INFO_CMDS 3 ///< Blood leak embedded mode number of informative commands. #define BLOOD_LEAK_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Blood leak embedded mode FPGA error timeout in milliseconds. +#define BLOOD_LEAK_RXFIFO_COUNT_MASK 0x03ff ///< Mask high order bits of blood leak sensor rx count /// Defined states for the blood leak detector state machine. typedef enum BloodLeakStates @@ -198,6 +199,7 @@ static BOOL isEmbModeCmdQueueEmpty( void ); static U32 getAvailableEmbModeQueueCount( void ); static void enqueueInfoEmbModeCmds( void ); +static U16 getBloodLeakRxBytesAvailable( void ); /*********************************************************************//** * @brief @@ -368,6 +370,9 @@ enqueueEmbModeCmd( Z_EMB_MODE_CMD ); enqueueEmbModeCmd( Q_EMB_MODE_CMD ); enqueueEmbModeCmd( T_EMB_MODE_CMD ); + + // Since the zero commands have been queued, reset the counter + bloodLeakEmbModeCmdEnqueueCount = 0; } else if ( ++bloodLeakEmbModeCmdEnqueueCount > BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) { @@ -895,7 +900,7 @@ if ( ( bloodLeakEmbModeRqstedCmd != CS_EMB_MODE_CMD ) && ( bloodLeakUARTCmdIndex - 1 > BLOOD_LEAK_EMB_MODE_RESET_INDEX ) && ( bloodLeakUARTCmdIndex - 1 <= BLOOD_LEAK_EMB_MODE_RESET_INDEX + 1 ) ) { - if ( BLOOD_LEAK_EMB_MODE_RX_BUFFER_EMPTY == getFPGABloodLeakRxFIFOCount() ) + if ( 0 == getBloodLeakRxBytesAvailable() ) { // TODO do nothing right now. I case it was decided to use the terminal mode again, make sure the reset went through prior to sending the // reset of the command sequence @@ -941,7 +946,7 @@ static BLOOD_LEAK_EMB_MODE_STATE_T handleBloodLeakEmbModeWaitForCommandResponseState( void ) { BLOOD_LEAK_EMB_MODE_STATE_T state = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMMAND_RESPONSE_STATE; - U08 rxFIFOCount = getFPGABloodLeakRxFIFOCount(); + U16 rxFIFOCount = getBloodLeakRxBytesAvailable(); BOOL hasCharBeenReceived = FALSE; U32 commandTimeoutMS = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].timeoutMS; U32 length = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].length; @@ -1635,4 +1640,9 @@ return result; } +static U16 getBloodLeakRxBytesAvailable( void ) +{ + return getFPGABloodLeakRxFIFOCount() & BLOOD_LEAK_RXFIFO_COUNT_MASK; +} + /**@}*/ Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -rc1b9ac0dbf2196280895d2e440dd7ac288ac8424 -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision c1b9ac0dbf2196280895d2e440dd7ac288ac8424) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -14,96 +14,96 @@ * @date (original) 16-Dec-2019 * ***************************************************************************/ - -#include - -#include "etpwm.h" -#include "gio.h" -#include "mibspi.h" -#include "Battery.h" +#include + +#include "etpwm.h" +#include "gio.h" +#include "mibspi.h" + +#include "Battery.h" #include "DialInFlow.h" -#include "FPGA.h" -#include "InternalADC.h" +#include "FPGA.h" +#include "InternalADC.h" #include "NVDataMgmt.h" -#include "OperationModes.h" +#include "OperationModes.h" #include "PersistentAlarm.h" -#include "PIControllers.h" +#include "PIControllers.h" #include "SafetyShutdown.h" #include "SystemCommMessages.h" -#include "SystemComm.h" -#include "TaskGeneral.h" -#include "TaskPriority.h" -#include "Timers.h" - -/** - * @addtogroup DialysateInletFlow - * @{ - */ - -// ********** private definitions ********** - +#include "SystemComm.h" +#include "TaskGeneral.h" +#include "TaskPriority.h" +#include "Timers.h" + +/** + * @addtogroup DialysateInletFlow + * @{ + */ + +// ********** private definitions ********** + /// Interval (ms/task time) at which the dialIn flow data is published on the CAN bus. -#define DIAL_IN_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) - -#define MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE 0.0133F ///< Max duty cycle change when ramping up ~ 200 mL/min/s. -#define MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE 0.02F ///< Max duty cycle change when ramping down ~ 300 mL/min/s. -#define MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.90F ///< Controller will error if PWM duty cycle > 90%, so set max to 90%. -#define MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.10F ///< Controller will error if PWM duty cycle < 10%, so set min to 10%. +#define DIAL_IN_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) + +#define MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE 0.0133F ///< Max duty cycle change when ramping up ~ 200 mL/min/s. +#define MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE 0.02F ///< Max duty cycle change when ramping down ~ 300 mL/min/s. +#define MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.90F ///< Controller will error if PWM duty cycle > 90%, so set max to 90%. +#define MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.10F ///< Controller will error if PWM duty cycle < 10%, so set min to 10%. #define MIN_DG_DIAL_FLOW_RATE 10.0F ///< Minimum DG Dialysate Flow Rate (mL/Min) #define DIP_CONTROL_INTERVAL_SEC 4 ///< Dialysate inlet pump control interval (in seconds). -/// Interval (ms/task time) at which the dialIn pump is controlled. -static const U32 DIP_CONTROL_INTERVAL = ( DIP_CONTROL_INTERVAL_SEC * MS_PER_SECOND / TASK_GENERAL_INTERVAL ); -#define DIP_P_COEFFICIENT 0.0001F ///< P term for dialIn pump control. -#define DIP_I_COEFFICIENT 0.00075F ///< I term for dialIn pump control. - -#define DIP_HOME_SPEED 400 ///< Target pump speed (in RPM) for homing. -#define DIP_HOME_TIMEOUT_MS 10000 ///< Maximum time allowed for homing to complete (in ms). +/// Interval (ms/task time) at which the dialIn pump is controlled. +static const U32 DIP_CONTROL_INTERVAL = ( DIP_CONTROL_INTERVAL_SEC * MS_PER_SECOND / TASK_GENERAL_INTERVAL ); +#define DIP_P_COEFFICIENT 0.0001F ///< P term for dialIn pump control. +#define DIP_I_COEFFICIENT 0.00075F ///< I term for dialIn pump control. + +#define DIP_HOME_SPEED 400 ///< Target pump speed (in RPM) for homing. +#define DIP_HOME_TIMEOUT_MS 10000 ///< Maximum time allowed for homing to complete (in ms). /// Interval (ms/task time) at which the blood pump speed is calculated (every 40 ms). #define DIP_SPEED_CALC_INTERVAL ( 40 / TASK_PRIORITY_INTERVAL ) /// Number of hall sensor counts kept in buffer to hold last 1 second of count data. #define DIP_SPEED_CALC_BUFFER_LEN ( 1000 / DIP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) -#define DIP_HALL_EDGE_COUNTS_PER_REV 48 ///< Number of hall sensor edge counts per motor revolution. - +#define DIP_HALL_EDGE_COUNTS_PER_REV 48 ///< Number of hall sensor edge counts per motor revolution. + #define DIP_MAX_FLOW_RATE 1320.0F ///< Maximum measured BP flow rate allowed. #define DIP_MIN_FLOW_RATE -1320.0F ///< Minimum measured BP flow rate allowed. -#define DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0F ///< Maximum motor speed (RPM) while motor is commanded off. -#define DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 2.0F ///< Maximum difference in speed between motor and rotor (in rotor RPM). +#define DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0F ///< Maximum motor speed (RPM) while motor is commanded off. +#define DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 2.0F ///< Maximum difference in speed between motor and rotor (in rotor RPM). #define DIP_MAX_MOTOR_SPEED_ERROR_RPM 300.0F ///< Maximum difference in speed between measured and commanded RPM. #define DIP_MAX_MOTOR_SPEED_VS_TRGT_DIFF_PCT 0.15F ///< Maximum motor speed vs target difference in percent. /// Persist time (ms) for unexpected flow check failure condition. static const U32 DIP_NO_FLOW_CHK_PERSIST = (10 * MS_PER_SECOND); -/// Persist time (task intervals) for motor off error condition. +/// Persist time (task intervals) for motor off error condition. static const U32 DIP_OFF_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); -/// Persist time (task intervals) motor speed error condition. +/// Persist time (task intervals) motor speed error condition. static const U32 DIP_MOTOR_SPEED_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); -/// Rotor speed persist time test needs a minimum number of rotations. +/// Rotor speed persist time test needs a minimum number of rotations. static const U32 DIP_ROTOR_ERROR_PERSIST_ROTATION_MIN = 3; -/// Persist time (task intervals) pump direction error condition. +/// Persist time (task intervals) pump direction error condition. static const U32 DIP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); /// Time threshold to trigger an alarm if Dialysate flow data has not arrived within 3 seconds static const U32 DIP_DIALYSATE_FLOW_DATA_ALARM_THRESHOLD = ((3 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); - -#define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0F ///< Motor controller current should not exceed this when pump should be stopped. -#define DIP_MAX_CURR_WHEN_RUNNING_MA 2000.0F ///< Motor controller current should not exceed this when pump should be running. -#define DIP_MAX_CURR_ERROR_DURATION_MS 5000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm. - + +#define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0F ///< Motor controller current should not exceed this when pump should be stopped. +#define DIP_MAX_CURR_WHEN_RUNNING_MA 2000.0F ///< Motor controller current should not exceed this when pump should be running. +#define DIP_MAX_CURR_ERROR_DURATION_MS 5000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm. + #define DIAL_IN_PUMP_ADC_FULL_SCALE_V 3.0F ///< BP analog signals are 0-3V (while int. ADC ref V may be different). #define DIAL_IN_PUMP_ADC_ZERO 1998 ///< Mid-point (zero) for ADC readings. ///< Macro converts a 12-bit ADC reading to a signed 16-bit value. #define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DIAL_IN_PUMP_ADC_ZERO ) -#define DIP_SPEED_ADC_TO_RPM_FACTOR 1.751752F ///< Conversion factor from ADC counts to RPM for dialIn pump motor (3500 RPM/1998 counts). +#define DIP_SPEED_ADC_TO_RPM_FACTOR 1.751752F ///< Conversion factor from ADC counts to RPM for dialIn pump motor (3500 RPM/1998 counts). #define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.000238F ///< ~42 BP motor RPM = 1% PWM duty cycle -#define DIP_CURRENT_ADC_TO_MA_FACTOR 3.002F ///< Conversion factor from ADC counts to mA for dialIn pump motor. - -#define DIP_REV_PER_LITER 146.84F ///< Rotor revolutions per liter. +#define DIP_CURRENT_ADC_TO_MA_FACTOR 3.002F ///< Conversion factor from ADC counts to mA for dialIn pump motor. + +#define DIP_REV_PER_LITER 146.84F ///< Rotor revolutions per liter. /// Macro converts flow rate to motor RPM. -#define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) -#define DIP_GEAR_RATIO 32.0F ///< DialIn pump motor to dialIn pump gear ratio. +#define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) +#define DIP_GEAR_RATIO 32.0F ///< DialIn pump motor to dialIn pump gear ratio. #define DIP_PWM_ZERO_OFFSET 0.1F ///< 10% PWM duty cycle = zero speed. #define DIP_100_PCT_PWM_RPM_RANGE 4000.0F ///< 10-90% PWM range yields 0-3,200 RPM range. Full 100% PWM range would yield 4,000 RPM range. @@ -114,7 +114,7 @@ // Macro converts PWM to estimate flow rate needed to achieve it. TODO - this macro does not reverse the function that estimates PWM from target flow rate - and it should #define DIP_ML_PER_MIN_FROM_PWM(pwm) ( (pwm) - DIP_PWM_ZERO_OFFSET ) / DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR / DIP_GEAR_RATIO / DIP_MOTOR_RPM_TO_PWM_DC_FACTOR -/// Measured dialIn flow is filtered w/ moving average. +/// Measured dialIn flow is filtered w/ moving average. #define SIZE_OF_ROLLING_AVG 4 #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. @@ -138,163 +138,163 @@ #define DIAL_IN_GEAR_RATIO 32 ///< Gear ratio used for Flow Estimation ALgorithm #define FIFTY_PERCENT 0.5 ///< 50% constant -/// Enumeration of dialysate inlet pump states. -typedef enum DialInPump_States -{ - DIAL_IN_PUMP_OFF_STATE = 0, ///< Off state for the dialysate inlet pump. - DIAL_IN_PUMP_RAMPING_UP_STATE, ///< Ramping up state for the dialysate inlet pump. - DIAL_IN_PUMP_RAMPING_DOWN_STATE, ///< Ramping down state for the dialysate inlet pump. - DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE, ///< Control to target state for the dialysate inlet pump. - NUM_OF_DIAL_IN_PUMP_STATES ///< Number of dialysate inlet pump states. -} DIAL_IN_PUMP_STATE_T; - -/// Enumeration of dialysate inlet self-test states. -typedef enum DialInFlow_Self_Test_States -{ - DIAL_IN_FLOW_SELF_TEST_STATE_START = 0, ///< Start state for the dialysate inlet pump self-test. - DIAL_IN_FLOW_TEST_STATE_IN_PROGRESS, ///< Test in progress state for the dialysate inlet pump self-test. - DIAL_IN_FLOW_TEST_STATE_COMPLETE, ///< Test completed state for the dialysate inlet pump self-test. - NUM_OF_DIAL_IN_FLOW_SELF_TEST_STATES ///< Number of dialysate inlet pump self-test states. -} DIAL_IN_FLOW_SELF_TEST_STATE_T; - -// Pin assignments for pump stop and direction outputs -#define STOP_DI_PUMP_GIO_PORT_PIN 2U ///< Pin # on GIO A for stopping the dialysate inlet pump. -#define DIR_DI_PUMP_SPI5_PORT_MASK 0x00000100 ///< Pin on unused SPI5 peripheral (ENA) - re-purposed as output GPIO to set dialysate inlet pump direction. -// DialIn pump stop and direction macros -#define SET_DIP_DIR() {mibspiREG5->PC3 |= DIR_DI_PUMP_SPI5_PORT_MASK;} ///< Macro for setting the dialysate inlet pump direction pin high. -#define CLR_DIP_DIR() {mibspiREG5->PC3 &= ~DIR_DI_PUMP_SPI5_PORT_MASK;} ///< Macro for setting the dialysate inlet pump direction pin low. -#define SET_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) ///< Macro for setting the dialysate inlet pump stop pin low. -#define CLR_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) ///< Macro for setting the dialysate inlet pump stop pin high. - -// ********** private data ********** - -static DIAL_IN_PUMP_STATE_T dialInPumpState = DIAL_IN_PUMP_OFF_STATE; ///< Current state of dialIn flow controller state machine -static U32 dialInFlowDataPublicationTimerCounter; ///< Used to schedule dialIn flow data publication to CAN bus -static BOOL isDialInPumpOn = FALSE; ///< DialIn pump is currently running -static F32 dialInPumpPWMDutyCyclePct = 0.0; ///< Initial dialIn pump PWM duty cycle -static F32 dialInPumpPWMDutyCyclePctSet = 0.0; ///< Currently set dialIn pump PWM duty cycle -static MOTOR_DIR_T dialInPumpDirection = MOTOR_DIR_FORWARD; ///< Requested dialysate flow direction -static MOTOR_DIR_T dialInPumpDirectionSet = MOTOR_DIR_FORWARD; ///< Currently set dialysate flow direction -static PUMP_CONTROL_MODE_T dialInPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Requested dialIn pump control mode. +/// Enumeration of dialysate inlet pump states. +typedef enum DialInPump_States +{ + DIAL_IN_PUMP_OFF_STATE = 0, ///< Off state for the dialysate inlet pump. + DIAL_IN_PUMP_RAMPING_UP_STATE, ///< Ramping up state for the dialysate inlet pump. + DIAL_IN_PUMP_RAMPING_DOWN_STATE, ///< Ramping down state for the dialysate inlet pump. + DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE, ///< Control to target state for the dialysate inlet pump. + NUM_OF_DIAL_IN_PUMP_STATES ///< Number of dialysate inlet pump states. +} DIAL_IN_PUMP_STATE_T; + +/// Enumeration of dialysate inlet self-test states. +typedef enum DialInFlow_Self_Test_States +{ + DIAL_IN_FLOW_SELF_TEST_STATE_START = 0, ///< Start state for the dialysate inlet pump self-test. + DIAL_IN_FLOW_TEST_STATE_IN_PROGRESS, ///< Test in progress state for the dialysate inlet pump self-test. + DIAL_IN_FLOW_TEST_STATE_COMPLETE, ///< Test completed state for the dialysate inlet pump self-test. + NUM_OF_DIAL_IN_FLOW_SELF_TEST_STATES ///< Number of dialysate inlet pump self-test states. +} DIAL_IN_FLOW_SELF_TEST_STATE_T; + +// Pin assignments for pump stop and direction outputs +#define STOP_DI_PUMP_GIO_PORT_PIN 2U ///< Pin # on GIO A for stopping the dialysate inlet pump. +#define DIR_DI_PUMP_SPI5_PORT_MASK 0x00000100 ///< Pin on unused SPI5 peripheral (ENA) - re-purposed as output GPIO to set dialysate inlet pump direction. +// DialIn pump stop and direction macros +#define SET_DIP_DIR() {mibspiREG5->PC3 |= DIR_DI_PUMP_SPI5_PORT_MASK;} ///< Macro for setting the dialysate inlet pump direction pin high. +#define CLR_DIP_DIR() {mibspiREG5->PC3 &= ~DIR_DI_PUMP_SPI5_PORT_MASK;} ///< Macro for setting the dialysate inlet pump direction pin low. +#define SET_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) ///< Macro for setting the dialysate inlet pump stop pin low. +#define CLR_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) ///< Macro for setting the dialysate inlet pump stop pin high. + +// ********** private data ********** + +static DIAL_IN_PUMP_STATE_T dialInPumpState = DIAL_IN_PUMP_OFF_STATE; ///< Current state of dialIn flow controller state machine +static U32 dialInFlowDataPublicationTimerCounter; ///< Used to schedule dialIn flow data publication to CAN bus +static BOOL isDialInPumpOn = FALSE; ///< DialIn pump is currently running +static F32 dialInPumpPWMDutyCyclePct = 0.0; ///< Initial dialIn pump PWM duty cycle +static F32 dialInPumpPWMDutyCyclePctSet = 0.0; ///< Currently set dialIn pump PWM duty cycle +static MOTOR_DIR_T dialInPumpDirection = MOTOR_DIR_FORWARD; ///< Requested dialysate flow direction +static MOTOR_DIR_T dialInPumpDirectionSet = MOTOR_DIR_FORWARD; ///< Currently set dialysate flow direction +static PUMP_CONTROL_MODE_T dialInPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Requested dialIn pump control mode. static PUMP_CONTROL_MODE_T dialInPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Currently set dialIn pump control mode. - + /// Interval (in ms) at which to publish dialIn flow data to CAN bus static OVERRIDE_U32_T dialInFlowDataPublishInterval = { DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL, 0 }; -static U32 dialysateFlowDataFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh dialysate flow data is received -static S32 targetDialInFlowRate = 0; ///< Requested dialIn flow rate -static OVERRIDE_F32_T measuredDialInFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet flow rate -static OVERRIDE_F32_T dialInPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump rotor speed -static OVERRIDE_F32_T dialInPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor speed -static OVERRIDE_F32_T adcDialInPumpMCSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor controller speed -static OVERRIDE_F32_T adcDialInPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor controller current +static U32 dialysateFlowDataFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh dialysate flow data is received +static S32 targetDialInFlowRate = 0; ///< Requested dialIn flow rate +static OVERRIDE_F32_T measuredDialInFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet flow rate +static OVERRIDE_F32_T dialInPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump rotor speed +static OVERRIDE_F32_T dialInPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor speed +static OVERRIDE_F32_T adcDialInPumpMCSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor controller speed +static OVERRIDE_F32_T adcDialInPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor controller current static U08 lastDialInPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. - -static U32 dipControlTimerCounter = 0; ///< Determines when to perform control on dialIn flow - -static U32 dipRotorRevStartTime = 0; ///< Dialysate inlet pump rotor rotation start time (in ms) -static BOOL dipStopAtHomePosition = FALSE; ///< Stop dialysate inlet pump at next home position -static U32 dipHomeStartTime = 0; ///< When did dialysate inlet pump home command begin? (in ms) - + +static U32 dipControlTimerCounter = 0; ///< Determines when to perform control on dialIn flow + +static U32 dipRotorRevStartTime = 0; ///< Dialysate inlet pump rotor rotation start time (in ms) +static BOOL dipStopAtHomePosition = FALSE; ///< Stop dialysate inlet pump at next home position +static U32 dipHomeStartTime = 0; ///< When did dialysate inlet pump home command begin? (in ms) + static U16 dipLastMotorHallSensorCounts[ DIP_SPEED_CALC_BUFFER_LEN ]; ///< Last hall sensor count for the dialysate inlet pump motor static U32 dipMotorSpeedCalcIdx = 0; ///< Index into 1 second buffer of motor speed hall sensor counts -static U32 dipMotorSpeedCalcTimerCtr = 0; ///< Counter determines interval for calculating dialysate inlet pump motor speed from hall sensor count. - -static U32 errorDialInMotorOffPersistTimerCtr = 0; ///< Persistence timer counter for motor off check error condition. -static U32 errorDialInMotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for motor speed error condition. -static U32 errorDialInRotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for rotor speed error condition. +static U32 dipMotorSpeedCalcTimerCtr = 0; ///< Counter determines interval for calculating dialysate inlet pump motor speed from hall sensor count. + +static U32 errorDialInMotorOffPersistTimerCtr = 0; ///< Persistence timer counter for motor off check error condition. +static U32 errorDialInMotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for motor speed error condition. +static U32 errorDialInRotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for rotor speed error condition. static U32 errorDialInPumpDirectionPersistTimerCtr = 0; ///< Persistence timer counter for pump direction error condition. - -static F64 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 F64 flowReadingsTotal = 0.0; ///< Rolling total - used to calc average. -static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer. - + +static F64 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 F64 flowReadingsTotal = 0.0; ///< Rolling total - used to calc average. +static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer. + static U32 dipCurrErrorDurationCtr = 0; ///< Used for tracking persistence of dip current errors. static HD_PUMPS_CAL_RECORD_T dialInPumpCalRecord; ///< Dialysate inlet calibration record. static OVERRIDE_U32_T dialysateInPumpRotorCounter = { 0, 0, 0, 0 }; ///< Running counter for dialin pump rotor revolutions static F32 filteredDialInFlowMeterReading = 0.0; ///< Storage for current filtered flow meter reading -// ********** private function prototypes ********** - -static DIAL_IN_PUMP_STATE_T handleDialInPumpOffState( void ); -static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingUpState( void ); -static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingDownState( void ); -static DIAL_IN_PUMP_STATE_T handleDialInPumpControlToTargetState( void ); -static void setDialInPumpControlSignalPWM( F32 newPWM ); -static void stopDialInPump( void ); -static void releaseDialInPumpStop( void ); -static void setDialInPumpDirection( MOTOR_DIR_T dir ); -static void publishDialInFlowData( void ); +// ********** private function prototypes ********** + +static DIAL_IN_PUMP_STATE_T handleDialInPumpOffState( void ); +static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingUpState( void ); +static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingDownState( void ); +static DIAL_IN_PUMP_STATE_T handleDialInPumpControlToTargetState( void ); +static void setDialInPumpControlSignalPWM( F32 newPWM ); +static void stopDialInPump( void ); +static void releaseDialInPumpStop( void ); +static void setDialInPumpDirection( MOTOR_DIR_T dir ); +static void publishDialInFlowData( void ); static void resetDialInFlowMovingAverage( void ); -static void filterDialInFlowReadings( F64 flow ); -static void updateDialInPumpSpeedAndDirectionFromHallSensors( void ); -static void checkDialInPumpRotor( void ); -static void checkDialInPumpDirection( void ); +static void filterDialInFlowReadings( F64 flow ); +static void updateDialInPumpSpeedAndDirectionFromHallSensors( void ); +static void checkDialInPumpRotor( void ); +static void checkDialInPumpDirection( void ); static void checkDialInPumpSpeeds( void ); -static void checkDialInPumpFlowRate( void ); -static void checkDialInPumpMCCurrent( void ); +static void checkDialInPumpFlowRate( void ); +static void checkDialInPumpMCCurrent( void ); static F32 calcDialInFlow( void ); static F32 dialysateInPumpRPMFromTargetFlowRate( F32 QdTarget ); static F32 dialysateInPumpPWMFromTargetFlowRate( F32 QdTarget ); static BOOL setDialInPumpToFixedPWM( F32 pwm ); - -/*********************************************************************//** - * @brief - * The initDialInFlow function initializes the DialInFlow module. - * @details Inputs: none - * @details Outputs: DialInFlow module initialized. - * @return none - *************************************************************************/ -void initDialInFlow( void ) + +/*********************************************************************//** + * @brief + * The initDialInFlow function initializes the DialInFlow module. + * @details Inputs: none + * @details Outputs: DialInFlow module initialized. + * @return none + *************************************************************************/ +void initDialInFlow( void ) { U32 i; dialInFlowDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - signalDialInPumpHardStop(); - setDialInPumpDirection( MOTOR_DIR_FORWARD ); - - // Zero rolling flow average buffer + signalDialInPumpHardStop(); + setDialInPumpDirection( MOTOR_DIR_FORWARD ); + + // Zero rolling flow average buffer resetDialInFlowMovingAverage(); - // Zero pump rotor count + // Zero pump rotor count resetDialInPumpRotorCount(); - + // Zero motor hall sensors counts buffer dipMotorSpeedCalcIdx = 0; for ( i = 0; i < DIP_SPEED_CALC_BUFFER_LEN; i++ ) { dipLastMotorHallSensorCounts[ i ] = getFPGADialInPumpHallSensorCount(); } - // Initialize dialysate inlet flow PI controller - initializePIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, - DIP_P_COEFFICIENT, DIP_I_COEFFICIENT, - MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); + // Initialize dialysate inlet flow PI controller + initializePIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, + DIP_P_COEFFICIENT, DIP_I_COEFFICIENT, + MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); // Initialize persistent alarms initPersistentAlarm( ALARM_ID_HD_DIAL_IN_FLOW_CHECK_FAILURE, 0, DIP_NO_FLOW_CHK_PERSIST ); initTimeWindowedCount( TIME_WINDOWED_COUNT_DIP_COMMUTATION_ERROR, DIP_COMMUTATION_ERROR_MAX_CNT, DIP_COMMUTATION_ERROR_TIME_WIN_MS ); -} - -/*********************************************************************//** - * @brief - * The setDialInPumpTargetFlowRate function sets a new target flow rate and - * pump direction. - * @details Inputs: isDialInPumpOn, dialInPumpDirectionSet - * @details Outputs: targetDialInFlowRate, dialInPumpdirection, dialInPumpPWMDutyCyclePct - * @param flowRate new target dialIn flow rate - * @param dir new dialIn flow direction - * @param mode new control mode - * @return TRUE if new flow rate & dir are set, FALSE if not - *************************************************************************/ -BOOL setDialInPumpTargetFlowRate( U32 flowRate, MOTOR_DIR_T dir, PUMP_CONTROL_MODE_T mode ) -{ - BOOL result = FALSE; - - // Direction change while pump is running is not allowed - if ( ( FALSE == isDialInPumpOn ) || ( 0 == flowRate ) || ( dir == dialInPumpDirectionSet ) ) - { +} + +/*********************************************************************//** + * @brief + * The setDialInPumpTargetFlowRate function sets a new target flow rate and + * pump direction. + * @details Inputs: isDialInPumpOn, dialInPumpDirectionSet + * @details Outputs: targetDialInFlowRate, dialInPumpdirection, dialInPumpPWMDutyCyclePct + * @param flowRate new target dialIn flow rate + * @param dir new dialIn flow direction + * @param mode new control mode + * @return TRUE if new flow rate & dir are set, FALSE if not + *************************************************************************/ +BOOL setDialInPumpTargetFlowRate( U32 flowRate, MOTOR_DIR_T dir, PUMP_CONTROL_MODE_T mode ) +{ + BOOL result = FALSE; + + // Direction change while pump is running is not allowed + if ( ( FALSE == isDialInPumpOn ) || ( 0 == flowRate ) || ( dir == dialInPumpDirectionSet ) ) + { S32 dirFlowRate = ( dir == MOTOR_DIR_FORWARD ? (S32)flowRate : (S32)flowRate * -1 ); // Don't interrupt pump control unless rate or mode is changing @@ -309,67 +309,67 @@ } #endif - // Verify flow rate - if ( TRUE == isFlowRateInRange ) - { - resetDialInFlowMovingAverage(); - targetDialInFlowRate = dirFlowRate; - dialInPumpDirection = dir; - dialInPumpControlMode = mode; + // Verify flow rate + if ( TRUE == isFlowRateInRange ) + { + resetDialInFlowMovingAverage(); + targetDialInFlowRate = dirFlowRate; + dialInPumpDirection = dir; + dialInPumpControlMode = mode; // Set PWM duty cycle target to an estimated initial target to ramp to based on target flow rate - then we will control to flow when ramp completed dialInPumpPWMDutyCyclePct = ( 0 == flowRate ? DIP_PWM_ZERO_OFFSET : dialysateInPumpPWMFromTargetFlowRate( (F32)flowRate ) ); - dialInPumpPWMDutyCyclePct = RANGE( dialInPumpPWMDutyCyclePct, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); - - switch ( dialInPumpState ) - { - case DIAL_IN_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp - if ( dialInPumpPWMDutyCyclePct < dialInPumpPWMDutyCyclePctSet ) - { - dialInPumpState = DIAL_IN_PUMP_RAMPING_DOWN_STATE; - } + dialInPumpPWMDutyCyclePct = RANGE( dialInPumpPWMDutyCyclePct, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); + + switch ( dialInPumpState ) + { + case DIAL_IN_PUMP_RAMPING_UP_STATE: // See if we need to reverse direction of ramp + if ( dialInPumpPWMDutyCyclePct < dialInPumpPWMDutyCyclePctSet ) + { + dialInPumpState = DIAL_IN_PUMP_RAMPING_DOWN_STATE; + } break; - - case DIAL_IN_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp - if ( dialInPumpPWMDutyCyclePct > dialInPumpPWMDutyCyclePctSet ) - { - dialInPumpState = DIAL_IN_PUMP_RAMPING_UP_STATE; - } + + case DIAL_IN_PUMP_RAMPING_DOWN_STATE: // See if we need to reverse direction of ramp + if ( dialInPumpPWMDutyCyclePct > dialInPumpPWMDutyCyclePctSet ) + { + dialInPumpState = DIAL_IN_PUMP_RAMPING_UP_STATE; + } break; - - case DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction - if ( dialInPumpPWMDutyCyclePctSet > dialInPumpPWMDutyCyclePct ) - { - dialInPumpState = DIAL_IN_PUMP_RAMPING_DOWN_STATE; - } - else - { - dialInPumpState = DIAL_IN_PUMP_RAMPING_UP_STATE; - } + + case DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE: // Start ramp to new target in appropriate direction + if ( dialInPumpPWMDutyCyclePctSet > dialInPumpPWMDutyCyclePct ) + { + dialInPumpState = DIAL_IN_PUMP_RAMPING_DOWN_STATE; + } + else + { + dialInPumpState = DIAL_IN_PUMP_RAMPING_UP_STATE; + } break; - - default: - // Ok - not all states need to be handled here - break; - } - result = TRUE; - } - else // Requested flow rate too high + default: + // Ok - not all states need to be handled here + break; + } + result = TRUE; + } + + else // Requested flow rate too high { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMPS_FLOW_LIMITS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { + { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_IN_FLOW_SET_TOO_HIGH, flowRate ) - } + } } - } - } - - return result; -} - + } + } + + return result; +} + /*********************************************************************//** * @brief * The setDialInPumpTargetRPM function sets a new target pump speed and pump @@ -392,73 +392,73 @@ return result; } -/*********************************************************************//** - * @brief - * The signalDialInPumpHardStop function stops the dialIn pump immediately. - * @details Inputs: none - * @details Outputs: DialIn pump stopped, set point reset, state changed to off - * @return none - *************************************************************************/ -void signalDialInPumpHardStop( void ) -{ - targetDialInFlowRate = 0; - stopDialInPump(); - dialInPumpState = DIAL_IN_PUMP_OFF_STATE; - dialInPumpPWMDutyCyclePct = DIP_PWM_ZERO_OFFSET; - dipControlTimerCounter = 0; - resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); -} - -/*********************************************************************//** - * @brief - * The signalDialInPumpRotorHallSensor function handles the dialysate inlet pump rotor - * hall sensor detection. Calculates rotor speed (in RPM). Stops pump if - * there is a pending request to home the pump. - * @details Inputs: dipRotorRevStartTime, dipStopAtHomePosition - * @details Outputs: dipRotorRevStartTime, dialInPumpRotorSpeedRPM, dialysateInPumpRotorCounter, dipStopAtHomePosition - * @return none - *************************************************************************/ -void signalDialInPumpRotorHallSensor( void ) -{ - U32 rotTime = getMSTimerCount(); - U32 deltaTime = calcTimeBetween( dipRotorRevStartTime, rotTime ); - - // Calculate rotor speed (in RPM) - dialInPumpRotorSpeedRPM.data = ( 1.0F / (F32)deltaTime ) * (F32)MS_PER_SECOND * (F32)SEC_PER_MIN; - dipRotorRevStartTime = rotTime; +/*********************************************************************//** + * @brief + * The signalDialInPumpHardStop function stops the dialIn pump immediately. + * @details Inputs: none + * @details Outputs: DialIn pump stopped, set point reset, state changed to off + * @return none + *************************************************************************/ +void signalDialInPumpHardStop( void ) +{ + targetDialInFlowRate = 0; + stopDialInPump(); + dialInPumpState = DIAL_IN_PUMP_OFF_STATE; + dialInPumpPWMDutyCyclePct = DIP_PWM_ZERO_OFFSET; + dipControlTimerCounter = 0; + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); +} + +/*********************************************************************//** + * @brief + * The signalDialInPumpRotorHallSensor function handles the dialysate inlet pump rotor + * hall sensor detection. Calculates rotor speed (in RPM). Stops pump if + * there is a pending request to home the pump. + * @details Inputs: dipRotorRevStartTime, dipStopAtHomePosition + * @details Outputs: dipRotorRevStartTime, dialInPumpRotorSpeedRPM, dialysateInPumpRotorCounter, dipStopAtHomePosition + * @return none + *************************************************************************/ +void signalDialInPumpRotorHallSensor( void ) +{ + U32 rotTime = getMSTimerCount(); + U32 deltaTime = calcTimeBetween( dipRotorRevStartTime, rotTime ); + + // Calculate rotor speed (in RPM) + dialInPumpRotorSpeedRPM.data = ( 1.0F / (F32)deltaTime ) * (F32)MS_PER_SECOND * (F32)SEC_PER_MIN; + dipRotorRevStartTime = rotTime; dialysateInPumpRotorCounter.data++; - - // If we are supposed to stop pump at home position, stop pump now. - if ( TRUE == dipStopAtHomePosition ) - { - signalDialInPumpHardStop(); - dipStopAtHomePosition = FALSE; - } -} - -/*********************************************************************//** - * @brief - * The homeDialInPump function initiates a dialysate inlet pump home operation. - * @details Inputs: dialInPumpState - * @details Outputs: dipStopAtHomePosition, dipHomeStartTime, dialysate inlet pump started (slow) - * @return none - *************************************************************************/ -BOOL homeDialInPump( void ) -{ - BOOL result = FALSE; - - if ( DIAL_IN_PUMP_OFF_STATE == dialInPumpState ) - { - dipStopAtHomePosition = TRUE; - dipHomeStartTime = getMSTimerCount(); - result = setDialInPumpTargetRPM( DIP_HOME_SPEED, MOTOR_DIR_FORWARD ); - } - - return result; -} - + + // If we are supposed to stop pump at home position, stop pump now. + if ( TRUE == dipStopAtHomePosition ) + { + signalDialInPumpHardStop(); + dipStopAtHomePosition = FALSE; + } +} + /*********************************************************************//** * @brief + * The homeDialInPump function initiates a dialysate inlet pump home operation. + * @details Inputs: dialInPumpState + * @details Outputs: dipStopAtHomePosition, dipHomeStartTime, dialysate inlet pump started (slow) + * @return none + *************************************************************************/ +BOOL homeDialInPump( void ) +{ + BOOL result = FALSE; + + if ( DIAL_IN_PUMP_OFF_STATE == dialInPumpState ) + { + dipStopAtHomePosition = TRUE; + dipHomeStartTime = getMSTimerCount(); + result = setDialInPumpTargetRPM( DIP_HOME_SPEED, MOTOR_DIR_FORWARD ); + } + + return result; +} + +/*********************************************************************//** + * @brief * The isDialInPumpRunning function returns whether the dialysate inlet pump * is currently running or not. * @details Inputs: isDialInPumpOn @@ -485,18 +485,18 @@ return result; } -/*********************************************************************//** - * @brief - * The execDialInFlowMonitor function executes the dialIn flow monitor. - * @details Inputs: none - * @details Outputs: measuredDialInFlowRate, adcDialInPumpMCSpeedRPM, adcDialInPumpMCCurrentmA - * @return none - *************************************************************************/ -void execDialInFlowMonitor( void ) +/*********************************************************************//** + * @brief + * The execDialInFlowMonitor function executes the dialIn flow monitor. + * @details Inputs: none + * @details Outputs: measuredDialInFlowRate, adcDialInPumpMCSpeedRPM, adcDialInPumpMCCurrentmA + * @return none + *************************************************************************/ +void execDialInFlowMonitor( void ) { HD_OP_MODE_T opMode = getCurrentOperationMode(); - U16 dipRPM = getIntADCReading( INT_ADC_DIAL_IN_PUMP_SPEED ); - U16 dipmA = getIntADCReading( INT_ADC_DIAL_IN_PUMP_MOTOR_CURRENT ); + U16 dipRPM = getIntADCReading( INT_ADC_DIAL_IN_PUMP_SPEED ); + U16 dipmA = getIntADCReading( INT_ADC_DIAL_IN_PUMP_MOTOR_CURRENT ); F64 dipFlow; // Process new dialysate flow readings @@ -523,287 +523,287 @@ } } - // Get latest pump speed and current from motor controller - adcDialInPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipRPM)) * DIP_SPEED_ADC_TO_RPM_FACTOR; - adcDialInPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipmA)) * DIP_CURRENT_ADC_TO_MA_FACTOR; + // Get latest pump speed and current from motor controller + adcDialInPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipRPM)) * DIP_SPEED_ADC_TO_RPM_FACTOR; + adcDialInPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipmA)) * DIP_CURRENT_ADC_TO_MA_FACTOR; - // Calculate dialysate inlet pump motor speed/direction from hall sensor count - updateDialInPumpSpeedAndDirectionFromHallSensors(); - - // Do not start enforcing checks until out of init/POST mode - if ( opMode != MODE_INIT ) - { - // Check pump direction - checkDialInPumpDirection(); - // Check pump controller current - checkDialInPumpMCCurrent(); - // Check pump speeds and flow - checkDialInPumpSpeeds(); + // Calculate dialysate inlet pump motor speed/direction from hall sensor count + updateDialInPumpSpeedAndDirectionFromHallSensors(); + + // Do not start enforcing checks until out of init/POST mode + if ( opMode != MODE_INIT ) + { + // Check pump direction + checkDialInPumpDirection(); + // Check pump controller current + checkDialInPumpMCCurrent(); + // Check pump speeds and flow + checkDialInPumpSpeeds(); checkDialInPumpFlowRate(); - // Check for home position, zero/low speed + // Check for home position, zero/low speed checkDialInPumpRotor(); } else { lastDialInPumpDirectionCount = getFPGADialInPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; } - // Publish dialIn flow data on interval - publishDialInFlowData(); -} - -/*********************************************************************//** - * @brief - * The execDialInFlowController function executes the dialIn flow controller. - * @details Inputs: dialInPumpState - * @details Outputs: dialInPumpState - * @return none - *************************************************************************/ -void execDialInFlowController( void ) -{ - switch ( dialInPumpState ) - { - case DIAL_IN_PUMP_OFF_STATE: - dialInPumpState = handleDialInPumpOffState(); - break; - - case DIAL_IN_PUMP_RAMPING_UP_STATE: - dialInPumpState = handleDialInPumpRampingUpState(); - break; - - case DIAL_IN_PUMP_RAMPING_DOWN_STATE: - dialInPumpState = handleDialInPumpRampingDownState(); - break; - - case DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE: - dialInPumpState = handleDialInPumpControlToTargetState(); - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_IN_FLOW_INVALID_DIAL_IN_PUMP_STATE, dialInPumpState ) - break; - } -} - -/*********************************************************************//** - * @brief - * The handleDialInPumpOffState function handles the dialIn pump off state - * of the dialIn pump controller state machine. - * @details Inputs: targetDialInFlowRate, dialInPumpDirection - * @details Outputs: dialInPumpPWMDutyCyclePctSet, dialInPumpDirectionSet, isDialInPumpOn - * @return next state - *************************************************************************/ -static DIAL_IN_PUMP_STATE_T handleDialInPumpOffState( void ) -{ - DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_OFF_STATE; - - // If we have been given a flow rate, setup ramp up and transition to ramp up state + // Publish dialIn flow data on interval + publishDialInFlowData(); +} + +/*********************************************************************//** + * @brief + * The execDialInFlowController function executes the dialIn flow controller. + * @details Inputs: dialInPumpState + * @details Outputs: dialInPumpState + * @return none + *************************************************************************/ +void execDialInFlowController( void ) +{ + switch ( dialInPumpState ) + { + case DIAL_IN_PUMP_OFF_STATE: + dialInPumpState = handleDialInPumpOffState(); + break; + + case DIAL_IN_PUMP_RAMPING_UP_STATE: + dialInPumpState = handleDialInPumpRampingUpState(); + break; + + case DIAL_IN_PUMP_RAMPING_DOWN_STATE: + dialInPumpState = handleDialInPumpRampingDownState(); + break; + + case DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE: + dialInPumpState = handleDialInPumpControlToTargetState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_IN_FLOW_INVALID_DIAL_IN_PUMP_STATE, dialInPumpState ) + break; + } +} + +/*********************************************************************//** + * @brief + * The handleDialInPumpOffState function handles the dialIn pump off state + * of the dialIn pump controller state machine. + * @details Inputs: targetDialInFlowRate, dialInPumpDirection + * @details Outputs: dialInPumpPWMDutyCyclePctSet, dialInPumpDirectionSet, isDialInPumpOn + * @return next state + *************************************************************************/ +static DIAL_IN_PUMP_STATE_T handleDialInPumpOffState( void ) +{ + DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_OFF_STATE; + + // If we have been given a flow rate, setup ramp up and transition to ramp up state if ( targetDialInFlowRate != 0 ) - { - // Set initial PWM duty cycle - dialInPumpPWMDutyCyclePctSet = DIP_PWM_ZERO_OFFSET + MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE; - setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); - // Allow dialIn pump to run in requested direction - setDialInPumpDirection( dialInPumpDirection ); - releaseDialInPumpStop(); - isDialInPumpOn = TRUE; - result = DIAL_IN_PUMP_RAMPING_UP_STATE; + { + // Set initial PWM duty cycle + dialInPumpPWMDutyCyclePctSet = DIP_PWM_ZERO_OFFSET + MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE; + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); + // Allow dialIn pump to run in requested direction + setDialInPumpDirection( dialInPumpDirection ); + releaseDialInPumpStop(); + isDialInPumpOn = TRUE; + result = DIAL_IN_PUMP_RAMPING_UP_STATE; } else { isDialInPumpOn = FALSE; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The handleDialInPumpRampingUpState function handles the ramp up state - * of the dialIn pump controller state machine. + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleDialInPumpRampingUpState function handles the ramp up state + * of the dialIn pump controller state machine. * @details Inputs: dialInPumpPWMDutyCyclePctSet, dialInPumpPWMDutyCyclePct, - * targetDialInFlowRate + * targetDialInFlowRate * @details Outputs: dialInPumpPWMDutyCyclePctSet, dipControlTimerCounter, - * dialInPumpControlModeSet - * @return next state - *************************************************************************/ -static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingUpState( void ) -{ - DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_RAMPING_UP_STATE; - - // Have we been asked to stop the dialIn pump? + * dialInPumpControlModeSet + * @return next state + *************************************************************************/ +static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingUpState( void ) +{ + DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_RAMPING_UP_STATE; + + // Have we been asked to stop the dialIn pump? if ( 0 == targetDialInFlowRate ) - { - // Start ramp down to stop - dialInPumpPWMDutyCyclePctSet -= MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE; - setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); - result = DIAL_IN_PUMP_RAMPING_DOWN_STATE; - } - // Have we reached end of ramp up? - else if ( dialInPumpPWMDutyCyclePctSet >= dialInPumpPWMDutyCyclePct ) - { - resetDialInFlowMovingAverage(); + { + // Start ramp down to stop + dialInPumpPWMDutyCyclePctSet -= MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE; + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); + result = DIAL_IN_PUMP_RAMPING_DOWN_STATE; + } + // Have we reached end of ramp up? + else if ( dialInPumpPWMDutyCyclePctSet >= dialInPumpPWMDutyCyclePct ) + { + resetDialInFlowMovingAverage(); dialInPumpPWMDutyCyclePctSet = dialInPumpPWMDutyCyclePct; - resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, dialInPumpPWMDutyCyclePctSet ); - dialInPumpControlModeSet = dialInPumpControlMode; + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, dialInPumpPWMDutyCyclePctSet ); + dialInPumpControlModeSet = dialInPumpControlMode; setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); - dipControlTimerCounter = 0; - result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; - } - // Continue ramp up - else - { - dialInPumpPWMDutyCyclePctSet += MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE; - setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); - } - - return result; -} - -/*********************************************************************//** - * @brief - * The handleDialInPumpRampingDownState function handles the ramp down state - * of the dialIn pump controller state machine. - * @details Inputs: dialInPumpPWMDutyCyclePctSet + dipControlTimerCounter = 0; + result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; + } + // Continue ramp up + else + { + dialInPumpPWMDutyCyclePctSet += MAX_DIAL_IN_PUMP_PWM_STEP_UP_CHANGE; + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleDialInPumpRampingDownState function handles the ramp down state + * of the dialIn pump controller state machine. + * @details Inputs: dialInPumpPWMDutyCyclePctSet * @details Outputs: dialInPumpPWMDutyCyclePctSet, dialInPumpControlModeSet, - * dipControlTimerCounter - * @return next state - *************************************************************************/ -static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingDownState( void ) -{ - DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_RAMPING_DOWN_STATE; - - // Have we essentially reached zero speed - if ( dialInPumpPWMDutyCyclePctSet < (MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE + DIP_PWM_ZERO_OFFSET) ) - { - signalDialInPumpHardStop(); - result = DIAL_IN_PUMP_OFF_STATE; - } - // Have we reached end of ramp down? - else if ( dialInPumpPWMDutyCyclePctSet <= dialInPumpPWMDutyCyclePct ) - { - resetDialInFlowMovingAverage(); + * dipControlTimerCounter + * @return next state + *************************************************************************/ +static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingDownState( void ) +{ + DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_RAMPING_DOWN_STATE; + + // Have we essentially reached zero speed + if ( dialInPumpPWMDutyCyclePctSet < (MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE + DIP_PWM_ZERO_OFFSET) ) + { + signalDialInPumpHardStop(); + result = DIAL_IN_PUMP_OFF_STATE; + } + // Have we reached end of ramp down? + else if ( dialInPumpPWMDutyCyclePctSet <= dialInPumpPWMDutyCyclePct ) + { + resetDialInFlowMovingAverage(); dialInPumpPWMDutyCyclePctSet = dialInPumpPWMDutyCyclePct; - resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, dialInPumpPWMDutyCyclePctSet ); - dialInPumpControlModeSet = dialInPumpControlMode; - setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); + resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, dialInPumpPWMDutyCyclePctSet ); + dialInPumpControlModeSet = dialInPumpControlMode; + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); dipControlTimerCounter = 0; - result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; - } - // Continue ramp down - else - { - dialInPumpPWMDutyCyclePctSet -= MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE; - setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); - } - - return result; -} - -/*********************************************************************//** - * @brief - * The handleDialInPumpControlToTargetState function handles the "control to - * target" state of the dialIn pump controller state machine. - * @details Inputs: none - * @details Outputs: dialInPumpState - * @return next state - *************************************************************************/ -static DIAL_IN_PUMP_STATE_T handleDialInPumpControlToTargetState( void ) -{ - DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; - - // Control at set interval - if ( ++dipControlTimerCounter >= DIP_CONTROL_INTERVAL ) - { - if ( dialInPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) - { - F32 tgtFlow = (F32)targetDialInFlowRate; - F32 actFlow = getMeasuredDialInFlowRate(); - F32 newPWM; - - newPWM = runPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, tgtFlow, actFlow ); - dialInPumpPWMDutyCyclePctSet = newPWM; + result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; + } + // Continue ramp down + else + { + dialInPumpPWMDutyCyclePctSet -= MAX_DIAL_IN_PUMP_PWM_STEP_DN_CHANGE; + setDialInPumpControlSignalPWM( dialInPumpPWMDutyCyclePctSet ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleDialInPumpControlToTargetState function handles the "control to + * target" state of the dialIn pump controller state machine. + * @details Inputs: none + * @details Outputs: dialInPumpState + * @return next state + *************************************************************************/ +static DIAL_IN_PUMP_STATE_T handleDialInPumpControlToTargetState( void ) +{ + DIAL_IN_PUMP_STATE_T result = DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE; + + // Control at set interval + if ( ++dipControlTimerCounter >= DIP_CONTROL_INTERVAL ) + { + if ( dialInPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) + { + F32 tgtFlow = (F32)targetDialInFlowRate; + F32 actFlow = getMeasuredDialInFlowRate(); + F32 newPWM; + + newPWM = runPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, tgtFlow, actFlow ); + dialInPumpPWMDutyCyclePctSet = newPWM; setDialInPumpControlSignalPWM( newPWM ); - } + } signalDialOutControl(); - dipControlTimerCounter = 0; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The setDialInPumpControlSignalPWM function sets the PWM duty cycle for - * the dialysate inlet pump to a given %. - * @details Inputs: none - * @details Outputs: dialIn pump stop signal activated, PWM duty cycle zeroed - * @param newPWM new duty cycle % to apply to PWM - * @return none - *************************************************************************/ -static void setDialInPumpControlSignalPWM( F32 newPWM ) -{ - etpwmSetCmpA( etpwmREG2, (U32)( (S32)( ( newPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); -} - -/*********************************************************************//** - * @brief - * The stopDialInPump function sets the dialIn pump stop signal. - * @details Inputs: none - * @details Outputs: dialIn pump stop signal activated, PWM duty cycle zeroed - * @return none - *************************************************************************/ -static void stopDialInPump( void ) -{ - isDialInPumpOn = FALSE; - dialInPumpPWMDutyCyclePctSet = DIP_PWM_ZERO_OFFSET; - etpwmSetCmpA( etpwmREG2, 0 ); - SET_DIP_STOP(); -} - -/*********************************************************************//** - * @brief - * The releaseDialInPumpStop function clears the dialIn pump stop signal. - * @details Inputs: none - * @details Outputs: dialIn pump stop signal - * @return none - *************************************************************************/ -static void releaseDialInPumpStop( void ) -{ - CLR_DIP_STOP(); -} - -/*********************************************************************//** - * @brief - * The setDialInPumpDirection function sets the set dialIn pump direction to - * the given direction. - * @details Inputs: dialInPumpState - * @details Outputs: dialInPumpState - * @param dir dialIn pump direction to set - * @return none - *************************************************************************/ -static void setDialInPumpDirection( MOTOR_DIR_T dir ) -{ - switch ( dir ) - { - case MOTOR_DIR_FORWARD: - dialInPumpDirectionSet = dir; - SET_DIP_DIR(); - break; - - case MOTOR_DIR_REVERSE: - dialInPumpDirectionSet = dir; - CLR_DIP_DIR(); - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_IN_FLOW_INVALID_DIAL_IN_PUMP_DIRECTION, dir ) - break; - } -} + dipControlTimerCounter = 0; + } + return result; +} + /*********************************************************************//** * @brief + * The setDialInPumpControlSignalPWM function sets the PWM duty cycle for + * the dialysate inlet pump to a given %. + * @details Inputs: none + * @details Outputs: dialIn pump stop signal activated, PWM duty cycle zeroed + * @param newPWM new duty cycle % to apply to PWM + * @return none + *************************************************************************/ +static void setDialInPumpControlSignalPWM( F32 newPWM ) +{ + etpwmSetCmpA( etpwmREG2, (U32)( (S32)( ( newPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); +} + +/*********************************************************************//** + * @brief + * The stopDialInPump function sets the dialIn pump stop signal. + * @details Inputs: none + * @details Outputs: dialIn pump stop signal activated, PWM duty cycle zeroed + * @return none + *************************************************************************/ +static void stopDialInPump( void ) +{ + isDialInPumpOn = FALSE; + dialInPumpPWMDutyCyclePctSet = DIP_PWM_ZERO_OFFSET; + etpwmSetCmpA( etpwmREG2, 0 ); + SET_DIP_STOP(); +} + +/*********************************************************************//** + * @brief + * The releaseDialInPumpStop function clears the dialIn pump stop signal. + * @details Inputs: none + * @details Outputs: dialIn pump stop signal + * @return none + *************************************************************************/ +static void releaseDialInPumpStop( void ) +{ + CLR_DIP_STOP(); +} + +/*********************************************************************//** + * @brief + * The setDialInPumpDirection function sets the set dialIn pump direction to + * the given direction. + * @details Inputs: dialInPumpState + * @details Outputs: dialInPumpState + * @param dir dialIn pump direction to set + * @return none + *************************************************************************/ +static void setDialInPumpDirection( MOTOR_DIR_T dir ) +{ + switch ( dir ) + { + case MOTOR_DIR_FORWARD: + dialInPumpDirectionSet = dir; + SET_DIP_DIR(); + break; + + case MOTOR_DIR_REVERSE: + dialInPumpDirectionSet = dir; + CLR_DIP_DIR(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_IN_FLOW_INVALID_DIAL_IN_PUMP_DIRECTION, dir ) + break; + } +} + +/*********************************************************************//** + * @brief * The calcDialInFlow function calculates an estimated dialysate flow rate from * a blended algorithm based on flow meter data and dialin pump speed and tubing wear * (measured from count of rotor revolutions since cartridge install). @@ -906,28 +906,28 @@ dialysateInPumpRotorCounter.data = 0.0F; } } - -/*********************************************************************//** - * @brief - * The getTargetDialInFlowRate function gets the current target dialIn flow - * rate. - * @details Inputs: targetDialInFlowRate - * @details Outputs: none - * @return the current target dialIn flow rate (in mL/min). - *************************************************************************/ + +/*********************************************************************//** + * @brief + * The getTargetDialInFlowRate function gets the current target dialIn flow + * rate. + * @details Inputs: targetDialInFlowRate + * @details Outputs: none + * @return the current target dialIn flow rate (in mL/min). + *************************************************************************/ S32 getTargetDialInFlowRate( void ) { return targetDialInFlowRate; } - -/*********************************************************************//** - * @brief - * The getMeasuredDialInFlowRate function gets the measured dialIn flow - * rate. - * @details Inputs: measuredDialInFlowRate - * @details Outputs: none - * @return the current dialIn flow rate (in mL/min). - *************************************************************************/ + +/*********************************************************************//** + * @brief + * The getMeasuredDialInFlowRate function gets the measured dialIn flow + * rate. + * @details Inputs: measuredDialInFlowRate + * @details Outputs: none + * @return the current dialIn flow rate (in mL/min). + *************************************************************************/ F32 getMeasuredDialInFlowRate( void ) { F32 result = measuredDialInFlowRate.data; @@ -940,14 +940,14 @@ return result; } -/*********************************************************************//** - * @brief - * The getMeasuredDialInPumpRotorSpeed function gets the measured dialIn flow - * rate. - * @details Inputs: dialInPumpRotorSpeedRPM - * @details Outputs: none - * @return the current dialIn flow rate (in mL/min). - *************************************************************************/ +/*********************************************************************//** + * @brief + * The getMeasuredDialInPumpRotorSpeed function gets the measured dialIn flow + * rate. + * @details Inputs: dialInPumpRotorSpeedRPM + * @details Outputs: none + * @return the current dialIn flow rate (in mL/min). + *************************************************************************/ F32 getMeasuredDialInPumpRotorSpeed( void ) { F32 result = dialInPumpRotorSpeedRPM.data; @@ -958,16 +958,16 @@ } return result; -} - -/*********************************************************************//** - * @brief - * The getMeasuredDialInPumpSpeed function gets the measured dialIn flow - * rate. - * @details Inputs: dialInPumpSpeedRPM - * @details Outputs: none - * @return the current dialIn flow rate (in mL/min). - *************************************************************************/ +} + +/*********************************************************************//** + * @brief + * The getMeasuredDialInPumpSpeed function gets the measured dialIn flow + * rate. + * @details Inputs: dialInPumpSpeedRPM + * @details Outputs: none + * @return the current dialIn flow rate (in mL/min). + *************************************************************************/ F32 getMeasuredDialInPumpSpeed( void ) { F32 result = dialInPumpSpeedRPM.data; @@ -978,16 +978,16 @@ } return result; -} - -/*********************************************************************//** - * @brief - * The getMeasuredDialInPumpMCSpeed function gets the measured dialIn pump - * speed. - * @details Inputs: adcDialInPumpMCSpeedRPM - * @details Outputs: none - * @return the current dialIn pump speed (in RPM). - *************************************************************************/ +} + +/*********************************************************************//** + * @brief + * The getMeasuredDialInPumpMCSpeed function gets the measured dialIn pump + * speed. + * @details Inputs: adcDialInPumpMCSpeedRPM + * @details Outputs: none + * @return the current dialIn pump speed (in RPM). + *************************************************************************/ F32 getMeasuredDialInPumpMCSpeed( void ) { F32 result = adcDialInPumpMCSpeedRPM.data; @@ -998,16 +998,16 @@ } return result; -} - -/*********************************************************************//** - * @brief - * The getMeasuredDialInPumpMCCurrent function gets the measured dialIn pump - * current. - * @details Inputs: adcDialInPumpMCCurrentmA - * @details Outputs: none - * @return the current dialIn pump current (in mA). - *************************************************************************/ +} + +/*********************************************************************//** + * @brief + * The getMeasuredDialInPumpMCCurrent function gets the measured dialIn pump + * current. + * @details Inputs: adcDialInPumpMCCurrentmA + * @details Outputs: none + * @return the current dialIn pump current (in mA). + *************************************************************************/ F32 getMeasuredDialInPumpMCCurrent( void ) { F32 result = adcDialInPumpMCCurrentmA.data; @@ -1039,7 +1039,7 @@ } return result; -} +} /*********************************************************************//** * @brief @@ -1060,7 +1060,7 @@ return result; } - + /*********************************************************************//** * @brief * The getPumpRotorErrorPersistTime function calculates the Rotor error persist time. @@ -1083,20 +1083,20 @@ return err_persist_time; } -/*********************************************************************//** - * @brief - * The publishDialInFlowData function publishes dialIn flow data at the set - * interval. - * @details Inputs: target flow rate, measured flow rate, measured MC speed, - * measured MC current - * @details Outputs: DialIn flow data is published to CAN bus. - * @return none - *************************************************************************/ -static void publishDialInFlowData( void ) -{ - // Publish dialIn flow data on interval - if ( ++dialInFlowDataPublicationTimerCounter >= getU32OverrideValue( &dialInFlowDataPublishInterval ) ) - { +/*********************************************************************//** + * @brief + * The publishDialInFlowData function publishes dialIn flow data at the set + * interval. + * @details Inputs: target flow rate, measured flow rate, measured MC speed, + * measured MC current + * @details Outputs: DialIn flow data is published to CAN bus. + * @return none + *************************************************************************/ +static void publishDialInFlowData( void ) +{ + // Publish dialIn flow data on interval + if ( ++dialInFlowDataPublicationTimerCounter >= getU32OverrideValue( &dialInFlowDataPublishInterval ) ) + { DIALIN_PUMP_STATUS_PAYLOAD_T payload; HD_OP_MODE_T opMode = getCurrentOperationMode(); @@ -1117,124 +1117,124 @@ payload.presFlow = 0; } broadcastData( MSG_ID_DIALYSATE_FLOW_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&payload, sizeof( DIALIN_PUMP_STATUS_PAYLOAD_T ) ); - dialInFlowDataPublicationTimerCounter = 0; - } -} - -/*********************************************************************//** - * @brief - * The resetDialInFlowMovingAverage function resets the properties of the - * dialIn flow moving average sample buffer. - * @details Inputs: none - * @details Outputs: flowReadingsTotal, flowReadingsIdx, flowReadingsCount all set to zero. + dialInFlowDataPublicationTimerCounter = 0; + } +} + +/*********************************************************************//** + * @brief + * The resetDialInFlowMovingAverage function resets the properties of the + * dialIn flow moving average sample buffer. + * @details Inputs: none + * @details Outputs: flowReadingsTotal, flowReadingsIdx, flowReadingsCount all set to zero. * @return none - *************************************************************************/ -static void resetDialInFlowMovingAverage( void ) -{ - flowReadingsIdx = 0; - flowReadingsCount = 0; - flowReadingsTotal = 0.0; - dipControlTimerCounter = 0; -} - -/*********************************************************************//** - * @brief - * The filterDialInFlowReadings function adds a new flow sample to the filter. - * @details Inputs: none - * @details Outputs: flowReadings[], flowReadingsIdx, flowReadingsCount, flowReadingsTotal - * @return none - *************************************************************************/ -void filterDialInFlowReadings( F64 flow ) -{ - if ( flowReadingsCount >= SIZE_OF_ROLLING_AVG ) - { - flowReadingsTotal -= flowReadings[ flowReadingsIdx ]; - } - flowReadings[ flowReadingsIdx ] = flow; - flowReadingsTotal += flow; - flowReadingsIdx = INC_WRAP( flowReadingsIdx, 0, SIZE_OF_ROLLING_AVG - 1 ); + *************************************************************************/ +static void resetDialInFlowMovingAverage( void ) +{ + flowReadingsIdx = 0; + flowReadingsCount = 0; + flowReadingsTotal = 0.0; + dipControlTimerCounter = 0; +} + +/*********************************************************************//** + * @brief + * The filterDialInFlowReadings function adds a new flow sample to the filter. + * @details Inputs: none + * @details Outputs: flowReadings[], flowReadingsIdx, flowReadingsCount, flowReadingsTotal + * @return none + *************************************************************************/ +void filterDialInFlowReadings( F64 flow ) +{ + if ( flowReadingsCount >= SIZE_OF_ROLLING_AVG ) + { + flowReadingsTotal -= flowReadings[ flowReadingsIdx ]; + } + flowReadings[ flowReadingsIdx ] = flow; + flowReadingsTotal += flow; + flowReadingsIdx = INC_WRAP( flowReadingsIdx, 0, SIZE_OF_ROLLING_AVG - 1 ); flowReadingsCount = INC_CAP( flowReadingsCount, SIZE_OF_ROLLING_AVG ); - filteredDialInFlowMeterReading = (F32)( flowReadingsTotal / (F64)flowReadingsCount ); -} - -/*********************************************************************//** - * @brief - * The updateDialInPumpSpeedAndDirectionFromHallSensors function calculates - * the dialysate inlet pump motor speed and direction from hall sensor counter on - * a 1 second interval. - * @details Inputs: dipLastMotorHallSensorCount, dipMotorSpeedCalcTimerCtr, current count from FPGA - * @details Outputs: dipMotorDirectionFromHallSensors, dialInPumpSpeedRPM - * @return none - *************************************************************************/ -static void updateDialInPumpSpeedAndDirectionFromHallSensors( void ) -{ - if ( ++dipMotorSpeedCalcTimerCtr >= DIP_SPEED_CALC_INTERVAL ) - { - U16 dipMotorHallSensorCount = getFPGADialInPumpHallSensorCount(); + filteredDialInFlowMeterReading = (F32)( flowReadingsTotal / (F64)flowReadingsCount ); +} + +/*********************************************************************//** + * @brief + * The updateDialInPumpSpeedAndDirectionFromHallSensors function calculates + * the dialysate inlet pump motor speed and direction from hall sensor counter on + * a 1 second interval. + * @details Inputs: dipLastMotorHallSensorCount, dipMotorSpeedCalcTimerCtr, current count from FPGA + * @details Outputs: dipMotorDirectionFromHallSensors, dialInPumpSpeedRPM + * @return none + *************************************************************************/ +static void updateDialInPumpSpeedAndDirectionFromHallSensors( void ) +{ + if ( ++dipMotorSpeedCalcTimerCtr >= DIP_SPEED_CALC_INTERVAL ) + { + U16 dipMotorHallSensorCount = getFPGADialInPumpHallSensorCount(); U32 nextIdx = INC_WRAP( dipMotorSpeedCalcIdx, 0, DIP_SPEED_CALC_BUFFER_LEN - 1 ); U16 incDelta = ( dipMotorHallSensorCount >= dipLastMotorHallSensorCounts[ nextIdx ] ? \ dipMotorHallSensorCount - dipLastMotorHallSensorCounts[ nextIdx ] : \ ( HEX_64_K - dipLastMotorHallSensorCounts[ nextIdx ] ) + dipMotorHallSensorCount ); - U16 decDelta = ( 0 == incDelta ? 0xFFFF : HEX_64_K - incDelta ); - U16 delta; - - // Determine dialysate inlet pump speed/direction from delta hall sensor count since last interval - if ( incDelta < decDelta ) - { - delta = incDelta; - dialInPumpSpeedRPM.data = ( (F32)delta / (F32)DIP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; - } - else - { - delta = decDelta; - dialInPumpSpeedRPM.data = ( (F32)delta / (F32)DIP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; - } - - // Update last count for next time + U16 decDelta = ( 0 == incDelta ? 0xFFFF : HEX_64_K - incDelta ); + U16 delta; + + // Determine dialysate inlet pump speed/direction from delta hall sensor count since last interval + if ( incDelta < decDelta ) + { + delta = incDelta; + dialInPumpSpeedRPM.data = ( (F32)delta / (F32)DIP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; + } + else + { + delta = decDelta; + dialInPumpSpeedRPM.data = ( (F32)delta / (F32)DIP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; + } + + // Update last count for next time dipLastMotorHallSensorCounts[ nextIdx ] = dipMotorHallSensorCount; dipMotorSpeedCalcIdx = nextIdx; - dipMotorSpeedCalcTimerCtr = 0; - } -} - -/*********************************************************************//** - * @brief - * The checkDialInPumpRotor function checks the rotor for the dialysate inlet - * pump. If homing, this function will stop when hall sensor detected. If pump - * is off or running very slowly, rotor speed will be set to zero. - * @details Inputs: dipStopAtHomePosition, dipHomeStartTime, dipRotorRevStartTime - * @details Outputs: pump may be stopped if homing, dialInPumpRotorSpeedRPM may be set to zero. - * @return none - *************************************************************************/ -static void checkDialInPumpRotor( void ) -{ - // If homing, check timeout - if ( ( TRUE == dipStopAtHomePosition ) && ( TRUE == didTimeout( dipHomeStartTime, DIP_HOME_TIMEOUT_MS ) ) ) - { - signalDialInPumpHardStop(); - dipStopAtHomePosition = FALSE; - // TODO - alarm??? - } - - // If pump is stopped or running very slowly, set rotor speed to zero - if ( TRUE == didTimeout( dipRotorRevStartTime, DIP_HOME_TIMEOUT_MS ) ) - { - dialInPumpRotorSpeedRPM.data = 0.0; - } -} - -/*********************************************************************//** - * @brief - * The checkDialInPumpDirection function checks the set direction vs. - * the direction implied by the sign of the measured MC speed. - * @details Inputs: adcDialInPumpMCSpeedRPM, dialInPumpDirectionSet, dialInPumpState - * @details Outputs: none - * @return none - *************************************************************************/ -static void checkDialInPumpDirection( void ) -{ - if ( DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE == dialInPumpState ) - { + dipMotorSpeedCalcTimerCtr = 0; + } +} + +/*********************************************************************//** + * @brief + * The checkDialInPumpRotor function checks the rotor for the dialysate inlet + * pump. If homing, this function will stop when hall sensor detected. If pump + * is off or running very slowly, rotor speed will be set to zero. + * @details Inputs: dipStopAtHomePosition, dipHomeStartTime, dipRotorRevStartTime + * @details Outputs: pump may be stopped if homing, dialInPumpRotorSpeedRPM may be set to zero. + * @return none + *************************************************************************/ +static void checkDialInPumpRotor( void ) +{ + // If homing, check timeout + if ( ( TRUE == dipStopAtHomePosition ) && ( TRUE == didTimeout( dipHomeStartTime, DIP_HOME_TIMEOUT_MS ) ) ) + { + signalDialInPumpHardStop(); + dipStopAtHomePosition = FALSE; + // TODO - alarm??? + } + + // If pump is stopped or running very slowly, set rotor speed to zero + if ( TRUE == didTimeout( dipRotorRevStartTime, DIP_HOME_TIMEOUT_MS ) ) + { + dialInPumpRotorSpeedRPM.data = 0.0; + } +} + +/*********************************************************************//** + * @brief + * The checkDialInPumpDirection function checks the set direction vs. + * the direction implied by the sign of the measured MC speed. + * @details Inputs: adcDialInPumpMCSpeedRPM, dialInPumpDirectionSet, dialInPumpState + * @details Outputs: none + * @return none + *************************************************************************/ +static void checkDialInPumpDirection( void ) +{ + if ( DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE == dialInPumpState ) + { MOTOR_DIR_T dipMCDir, dipDir; U08 dirErrorCnt = getFPGADialInPumpHallSensorStatus() & PUMP_DIR_ERROR_COUNT_MASK; F32 measMCSpeed = getMeasuredDialInPumpMCSpeed(); @@ -1255,20 +1255,20 @@ dipMCDir = ( getMeasuredDialInPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); dipDir = ( getMeasuredDialInPumpSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); - + // Check set direction vs. direction from hall sensors - if ( ( dialInPumpDirectionSet != dipDir ) && ( TRUE == minDirSpeed ) ) - { + if ( ( dialInPumpDirectionSet != dipDir ) && ( TRUE == minDirSpeed ) ) + { if ( ++errorDialInPumpDirectionPersistTimerCtr >= DIP_DIRECTION_ERROR_PERSIST ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_DIRECTION_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_DIAL_IN_PUMP_MC_DIRECTION_CHECK, (U32)dialInPumpDirectionSet, (U32)dipDir ) - } - } - } + } + } + } // Check set direction vs. direction from sign of motor controller speed else if ( ( dialInPumpDirectionSet != dipMCDir ) && ( TRUE == minDirSpeed ) ) { @@ -1290,117 +1290,117 @@ else { errorDialInPumpDirectionPersistTimerCtr = 0; - } -} - -/*********************************************************************//** - * @brief - * The checkDialInPumpSpeeds function checks several aspects of the dialysate - * inlet pump speed. - * 1. while pump is commanded off, measured motor speed should be < limit. - * 2. while pump is controlling, measured motor speed should be within allowed range of commanded speed. - * 3. measured motor speed should be within allowed range of measured rotor speed. - * All 3 checks have a persistence time that must be met before an alarm is triggered. - * @details Inputs: targetDialInFlowRate, dialInPumpState, dialInPumpPWMDutyCyclePctSet, dialInPumpDirectionSet - * @details Outputs: errorDialInMotorOffPersistTimerCtr, alarm(s) may be triggered - * @return none - *************************************************************************/ -static void checkDialInPumpSpeeds( void ) -{ - F32 measMotorSpeed = getMeasuredDialInPumpSpeed(); + } +} + +/*********************************************************************//** + * @brief + * The checkDialInPumpSpeeds function checks several aspects of the dialysate + * inlet pump speed. + * 1. while pump is commanded off, measured motor speed should be < limit. + * 2. while pump is controlling, measured motor speed should be within allowed range of commanded speed. + * 3. measured motor speed should be within allowed range of measured rotor speed. + * All 3 checks have a persistence time that must be met before an alarm is triggered. + * @details Inputs: targetDialInFlowRate, dialInPumpState, dialInPumpPWMDutyCyclePctSet, dialInPumpDirectionSet + * @details Outputs: errorDialInMotorOffPersistTimerCtr, alarm(s) may be triggered + * @return none + *************************************************************************/ +static void checkDialInPumpSpeeds( void ) +{ + F32 measMotorSpeed = getMeasuredDialInPumpSpeed(); F32 measMCMotorSpeed = getMeasuredDialInPumpMCSpeed(); - - // Check for pump running while commanded off - if ( 0 == targetDialInFlowRate ) - { - if ( measMotorSpeed > DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) - { - if ( ++errorDialInMotorOffPersistTimerCtr >= DIP_OFF_ERROR_PERSIST ) + + // Check for pump running while commanded off + if ( 0 == targetDialInFlowRate ) + { + if ( measMotorSpeed > DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM ) + { + if ( ++errorDialInMotorOffPersistTimerCtr >= DIP_OFF_ERROR_PERSIST ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_SPEED_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_DIAL_IN_PUMP_OFF_CHECK, measMotorSpeed ); + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_DIAL_IN_PUMP_OFF_CHECK, measMotorSpeed ); activateSafetyShutdown(); } - } - } - else - { - errorDialInMotorOffPersistTimerCtr = 0; - } - } - else - { - errorDialInMotorOffPersistTimerCtr = 0; - } - + } + } + else + { + errorDialInMotorOffPersistTimerCtr = 0; + } + } + else + { + errorDialInMotorOffPersistTimerCtr = 0; + } + // Checks that only occur when pump is running (and beyond ramp). - if ( DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE == dialInPumpState ) - { - F32 cmdMotorSpeed = DIP_PWM_TO_MOTOR_SPEED_RPM( dialInPumpPWMDutyCyclePctSet, dialInPumpDirectionSet ); - F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); + if ( DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE == dialInPumpState ) + { + F32 cmdMotorSpeed = DIP_PWM_TO_MOTOR_SPEED_RPM( dialInPumpPWMDutyCyclePctSet, dialInPumpDirectionSet ); + F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); F32 deltaMCMotorSpeed = fabs( measMCMotorSpeed - cmdMotorSpeed ); - F32 measRotorSpeed = fabs( getMeasuredDialInPumpRotorSpeed() ); - F32 measMotorSpeedInRotorRPM = fabs( measMotorSpeed / DIP_GEAR_RATIO ); + F32 measRotorSpeed = fabs( getMeasuredDialInPumpRotorSpeed() ); + F32 measMotorSpeedInRotorRPM = fabs( measMotorSpeed / DIP_GEAR_RATIO ); F32 deltaRotorSpeed = fabs( measRotorSpeed - measMotorSpeedInRotorRPM ); - F32 measMotorSpeedDeltaPct = fabs( deltaRotorSpeed / measMotorSpeedInRotorRPM ); - - // Check measured motor speed vs. commanded motor speed while controlling to target - if ( ( deltaMotorSpeed > DIP_MAX_MOTOR_SPEED_ERROR_RPM ) || ( deltaMCMotorSpeed > DIP_MAX_MOTOR_SPEED_ERROR_RPM ) ) - { - if ( ++errorDialInMotorSpeedPersistTimerCtr >= DIP_MOTOR_SPEED_ERROR_PERSIST ) + F32 measMotorSpeedDeltaPct = fabs( deltaRotorSpeed / measMotorSpeedInRotorRPM ); + + // Check measured motor speed vs. commanded motor speed while controlling to target + if ( ( deltaMotorSpeed > DIP_MAX_MOTOR_SPEED_ERROR_RPM ) || ( deltaMCMotorSpeed > DIP_MAX_MOTOR_SPEED_ERROR_RPM ) ) + { + if ( ++errorDialInMotorSpeedPersistTimerCtr >= DIP_MOTOR_SPEED_ERROR_PERSIST ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_SPEED_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { + { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_DIAL_IN_PUMP_MOTOR_SPEED_CHECK, cmdMotorSpeed, measMotorSpeed ); - } - } - } - else - { - errorDialInMotorSpeedPersistTimerCtr = 0; - } - - // Check measured rotor speed vs. measured motor speed while controlling to target - if ( ( deltaRotorSpeed > DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM ) && ( measMotorSpeedDeltaPct > DIP_MAX_MOTOR_SPEED_VS_TRGT_DIFF_PCT ) ) - { + } + } + } + else + { + errorDialInMotorSpeedPersistTimerCtr = 0; + } + + // Check measured rotor speed vs. measured motor speed while controlling to target + if ( ( deltaRotorSpeed > DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM ) && ( measMotorSpeedDeltaPct > DIP_MAX_MOTOR_SPEED_VS_TRGT_DIFF_PCT ) ) + { if ( ++errorDialInRotorSpeedPersistTimerCtr >= ( getPumpRotorErrorPersistTime( measMotorSpeed, DIP_GEAR_RATIO ) / TASK_PRIORITY_INTERVAL ) ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_SPEED_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { + { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_DIAL_IN_PUMP_ROTOR_SPEED_CHECK, measRotorSpeed, measMotorSpeed ); - } - } - } - else - { - errorDialInRotorSpeedPersistTimerCtr = 0; - } - - } - else - { - errorDialInMotorSpeedPersistTimerCtr = 0; - errorDialInRotorSpeedPersistTimerCtr = 0; - } -} - -/*********************************************************************//** - * @brief - * The checkDialInPumpFlowRate function checks the measured dialysate flow - * rate is in range. - * @details Inputs: measuredDialInFlowRate - * @details Outputs: alarm may be triggered - * @return none - *************************************************************************/ -static void checkDialInPumpFlowRate( void ) -{ + } + } + } + else + { + errorDialInRotorSpeedPersistTimerCtr = 0; + } + + } + else + { + errorDialInMotorSpeedPersistTimerCtr = 0; + errorDialInRotorSpeedPersistTimerCtr = 0; + } +} + +/*********************************************************************//** + * @brief + * The checkDialInPumpFlowRate function checks the measured dialysate flow + * rate is in range. + * @details Inputs: measuredDialInFlowRate + * @details Outputs: alarm may be triggered + * @return none + *************************************************************************/ +static void checkDialInPumpFlowRate( void ) +{ // Check DG Dialysate flow rate if ( ( TRUE == isDialInPumpRunning() ) && ( dialInPumpControlMode != PUMP_CONTROL_MODE_OPEN_LOOP ) ) { @@ -1427,80 +1427,80 @@ { isPersistentAlarmTriggered( ALARM_ID_HD_DIAL_IN_FLOW_CHECK_FAILURE, FALSE ); } -} - -/*********************************************************************//** - * @brief - * The checkDialInPumpMCCurrent function checks the measured MC current vs. - * the set state of the dialIn pump (stopped or running). - * @details Inputs: dialInPumpState, dipCurrErrorDurationCtr, adcDialInPumpMCCurrentmA - * @details Outputs: none - * @return none - *************************************************************************/ -static void checkDialInPumpMCCurrent( void ) -{ - F32 dipCurr; +} +/*********************************************************************//** + * @brief + * The checkDialInPumpMCCurrent function checks the measured MC current vs. + * the set state of the dialIn pump (stopped or running). + * @details Inputs: dialInPumpState, dipCurrErrorDurationCtr, adcDialInPumpMCCurrentmA + * @details Outputs: none + * @return none + *************************************************************************/ +static void checkDialInPumpMCCurrent( void ) +{ + F32 dipCurr; + // only check current when we have A/C power if ( FALSE == isACPowerLost() ) - { - // DialIn pump should be off - if ( DIAL_IN_PUMP_OFF_STATE == dialInPumpState ) - { - dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); - if ( dipCurr > DIP_MAX_CURR_WHEN_STOPPED_MA ) - { - dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; - if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) + { + // DialIn pump should be off + if ( DIAL_IN_PUMP_OFF_STATE == dialInPumpState ) + { + dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); + if ( dipCurr > DIP_MAX_CURR_WHEN_STOPPED_MA ) + { + dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; + if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MOTOR_CURRNT_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { + { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_DIAL_IN_PUMP_MC_CURRENT_CHECK, getMeasuredDialInPumpMCCurrent() ); - } - } - } - else - { - dipCurrErrorDurationCtr = 0; - } - } - // DialIn pump should be running - else - { - dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); - if ( dipCurr > DIP_MAX_CURR_WHEN_RUNNING_MA ) - { - dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; - if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) + } + } + } + else + { + dipCurrErrorDurationCtr = 0; + } + } + // DialIn pump should be running + else + { + dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); + if ( dipCurr > DIP_MAX_CURR_WHEN_RUNNING_MA ) + { + dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; + if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MOTOR_CURRNT_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { + { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_DIAL_IN_PUMP_MC_CURRENT_CHECK, getMeasuredDialInPumpMCCurrent() ); - } - } - } - else - { - dipCurrErrorDurationCtr = 0; - } + } + } + } + else + { + dipCurrErrorDurationCtr = 0; + } } - } + } } -/*********************************************************************//** - * @brief - * The execDialInFlowTest function executes the state machine for the - * DialInFlow self-test. - * @details Inputs: none - * @details Outputs: dialInPumpCalRecord - * @return the current state of the DialInFlow self-test. - *************************************************************************/ -SELF_TEST_STATUS_T execDialInFlowTest( void ) -{ +/*********************************************************************//** + * @brief + * The execDialInFlowTest function executes the state machine for the + * DialInFlow self-test. + * @details Inputs: none + * @details Outputs: dialInPumpCalRecord + * @return the current state of the DialInFlow self-test. + *************************************************************************/ +SELF_TEST_STATUS_T execDialInFlowTest( void ) +{ SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; BOOL calStatus = getNVRecord2Driver( GET_CAL_PUMPS, (U08*)&dialInPumpCalRecord, sizeof( HD_PUMPS_CAL_RECORD_T ), @@ -1515,15 +1515,15 @@ result = SELF_TEST_STATUS_FAILED; } - return result; -} - - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ + return result; +} +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + /*********************************************************************//** * @brief * The setDialInPumpToFixedPWM function sets a new pwm value and pump direction. @@ -1593,80 +1593,80 @@ return result; } - -/*********************************************************************//** - * @brief - * The testSetDialInFlowDataPublishIntervalOverride function overrides the - * dialIn flow data publish interval. - * @details Inputs: none - * @details Outputs: dialInFlowDataPublishInterval - * @param value override dialIn flow data publish interval with (in ms) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetDialInFlowDataPublishIntervalOverride( U32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - U32 intvl = value / TASK_PRIORITY_INTERVAL; - - result = TRUE; - dialInFlowDataPublishInterval.ovData = intvl; - dialInFlowDataPublishInterval.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetDialInFlowDataPublishIntervalOverride function resets the override - * of the dialIn flow data publish interval. - * @details Inputs: none - * @details Outputs: dialInFlowDataPublishInterval - * @return TRUE if override reset successful, FALSE if not - *************************************************************************/ -BOOL testResetDialInFlowDataPublishIntervalOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - dialInFlowDataPublishInterval.override = OVERRIDE_RESET; - dialInFlowDataPublishInterval.ovData = dialInFlowDataPublishInterval.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetTargetDialInFlowRateOverride function overrides the target - * dialysate inlet flow rate.n - * @details Inputs: none - * @details Outputs: targetDialInFlowRate - * @param value override target dialysate inlet flow rate (in mL/min) + +/*********************************************************************//** + * @brief + * The testSetDialInFlowDataPublishIntervalOverride function overrides the + * dialIn flow data publish interval. + * @details Inputs: none + * @details Outputs: dialInFlowDataPublishInterval + * @param value override dialIn flow data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetDialInFlowDataPublishIntervalOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = value / TASK_PRIORITY_INTERVAL; + + result = TRUE; + dialInFlowDataPublishInterval.ovData = intvl; + dialInFlowDataPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetDialInFlowDataPublishIntervalOverride function resets the override + * of the dialIn flow data publish interval. + * @details Inputs: none + * @details Outputs: dialInFlowDataPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetDialInFlowDataPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dialInFlowDataPublishInterval.override = OVERRIDE_RESET; + dialInFlowDataPublishInterval.ovData = dialInFlowDataPublishInterval.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetTargetDialInFlowRateOverride function overrides the target + * dialysate inlet flow rate.n + * @details Inputs: none + * @details Outputs: targetDialInFlowRate + * @param value override target dialysate inlet flow rate (in mL/min) * @param ctrlMode override pump control mode to this mode (0 = closed loop, 1 = open loop) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetTargetDialInFlowRateOverride( S32 value, U32 ctrlMode ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - MOTOR_DIR_T dir; - - if ( value < 0 ) - { - dir = MOTOR_DIR_REVERSE; - } - else - { - dir = MOTOR_DIR_FORWARD; - } + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetTargetDialInFlowRateOverride( S32 value, U32 ctrlMode ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + MOTOR_DIR_T dir; + + if ( value < 0 ) + { + dir = MOTOR_DIR_REVERSE; + } + else + { + dir = MOTOR_DIR_FORWARD; + } if ( ctrlMode < NUM_OF_PUMP_CONTROL_MODES ) { if ( 0 == value ) @@ -1677,239 +1677,239 @@ { result = setDialInPumpTargetFlowRate( abs(value), dir, (PUMP_CONTROL_MODE_T)ctrlMode ); } - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredDialInFlowRateOverride function overrides the measured - * dialIn flow rate. - * @details Inputs: none - * @details Outputs: measuredDialInFlowRate - * @param value override measured dialIn flow rate (in mL/min) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredDialInFlowRateOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - measuredDialInFlowRate.ovData = value; - measuredDialInFlowRate.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredDialInFlowRateOverride function resets the override of the - * measured dialIn flow rate. - * @details Inputs: none - * @details Outputs: measuredDialInFlowRate - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredDialInFlowRateOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - measuredDialInFlowRate.override = OVERRIDE_RESET; - measuredDialInFlowRate.ovData = measuredDialInFlowRate.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetMeasuredDialInPumpRotorSpeedOverride function overrides the measured - * dialIn pump rotor speed. - * @details Inputs: none - * @details Outputs: dialInPumpRotorSpeedRPM - * @param value override measured dialIn pump rotor speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredDialInPumpRotorSpeedOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - dialInPumpRotorSpeedRPM.ovData = value; - dialInPumpRotorSpeedRPM.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredDialInPumpRotorSpeedOverride function resets the override of the - * measured dialIn pump rotor speed. - * @details Inputs: none - * @details Outputs: dialInPumpRotorSpeedRPM - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredDialInPumpRotorSpeedOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - dialInPumpRotorSpeedRPM.override = OVERRIDE_RESET; - dialInPumpRotorSpeedRPM.ovData = dialInPumpRotorSpeedRPM.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetMeasuredDialInPumpSpeedOverride function overrides the measured - * dialIn pump motor speed. - * @details Inputs: none - * @details Outputs: dialInPumpSpeedRPM - * @param value override measured dialIn pump motor speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredDialInPumpSpeedOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - dialInPumpSpeedRPM.ovData = value; - dialInPumpSpeedRPM.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredDialInPumpSpeedOverride function resets the override of the - * measured dialIn pump motor speed. - * @details Inputs: none - * @details Outputs: dialInPumpSpeedRPM - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredDialInPumpSpeedOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - dialInPumpSpeedRPM.override = OVERRIDE_RESET; - dialInPumpSpeedRPM.ovData = dialInPumpSpeedRPM.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetMeasuredDialInPumpMCSpeedOverride function overrides the measured - * dialIn pump motor speed. - * @details Inputs: none - * @details Outputs: adcDialInPumpMCSpeedRPM - * @param value override measured dialIn pump speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredDialInPumpMCSpeedOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - adcDialInPumpMCSpeedRPM.ovData = value; - adcDialInPumpMCSpeedRPM.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredDialInPumpMCSpeedOverride function resets the override of the - * measured dialIn pump motor speed. - * @details Inputs: none - * @details Outputs: adcDialInPumpMCSpeedRPM - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredDialInPumpMCSpeedOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - adcDialInPumpMCSpeedRPM.override = OVERRIDE_RESET; - adcDialInPumpMCSpeedRPM.ovData = adcDialInPumpMCSpeedRPM.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetMeasuredDialInPumpMCCurrentOverride function overrides the measured - * dialIn pump motor current. - * @details Inputs: none - * @details Outputs: adcDialInPumpMCCurrentmA - * @param value override measured dialIn pump current (in mA) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetMeasuredDialInPumpMCCurrentOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - adcDialInPumpMCCurrentmA.ovData = value; - adcDialInPumpMCCurrentmA.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetMeasuredDialInPumpMCCurrentOverride function resets the override of the - * measured dialIn pump motor current. - * @details Inputs: none - * @details Outputs: adcDialInPumpMCCurrentmA - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetMeasuredDialInPumpMCCurrentOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - adcDialInPumpMCCurrentmA.override = OVERRIDE_RESET; - adcDialInPumpMCCurrentmA.ovData = adcDialInPumpMCCurrentmA.ovInitData; - } - - return result; + } + } + + return result; } /*********************************************************************//** * @brief + * The testResetMeasuredDialInFlowRateOverride function overrides the measured + * dialIn flow rate. + * @details Inputs: none + * @details Outputs: measuredDialInFlowRate + * @param value override measured dialIn flow rate (in mL/min) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredDialInFlowRateOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + measuredDialInFlowRate.ovData = value; + measuredDialInFlowRate.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredDialInFlowRateOverride function resets the override of the + * measured dialIn flow rate. + * @details Inputs: none + * @details Outputs: measuredDialInFlowRate + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredDialInFlowRateOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + measuredDialInFlowRate.override = OVERRIDE_RESET; + measuredDialInFlowRate.ovData = measuredDialInFlowRate.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetMeasuredDialInPumpRotorSpeedOverride function overrides the measured + * dialIn pump rotor speed. + * @details Inputs: none + * @details Outputs: dialInPumpRotorSpeedRPM + * @param value override measured dialIn pump rotor speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredDialInPumpRotorSpeedOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dialInPumpRotorSpeedRPM.ovData = value; + dialInPumpRotorSpeedRPM.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredDialInPumpRotorSpeedOverride function resets the override of the + * measured dialIn pump rotor speed. + * @details Inputs: none + * @details Outputs: dialInPumpRotorSpeedRPM + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredDialInPumpRotorSpeedOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dialInPumpRotorSpeedRPM.override = OVERRIDE_RESET; + dialInPumpRotorSpeedRPM.ovData = dialInPumpRotorSpeedRPM.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetMeasuredDialInPumpSpeedOverride function overrides the measured + * dialIn pump motor speed. + * @details Inputs: none + * @details Outputs: dialInPumpSpeedRPM + * @param value override measured dialIn pump motor speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredDialInPumpSpeedOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dialInPumpSpeedRPM.ovData = value; + dialInPumpSpeedRPM.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredDialInPumpSpeedOverride function resets the override of the + * measured dialIn pump motor speed. + * @details Inputs: none + * @details Outputs: dialInPumpSpeedRPM + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredDialInPumpSpeedOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dialInPumpSpeedRPM.override = OVERRIDE_RESET; + dialInPumpSpeedRPM.ovData = dialInPumpSpeedRPM.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetMeasuredDialInPumpMCSpeedOverride function overrides the measured + * dialIn pump motor speed. + * @details Inputs: none + * @details Outputs: adcDialInPumpMCSpeedRPM + * @param value override measured dialIn pump speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredDialInPumpMCSpeedOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + adcDialInPumpMCSpeedRPM.ovData = value; + adcDialInPumpMCSpeedRPM.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredDialInPumpMCSpeedOverride function resets the override of the + * measured dialIn pump motor speed. + * @details Inputs: none + * @details Outputs: adcDialInPumpMCSpeedRPM + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredDialInPumpMCSpeedOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + adcDialInPumpMCSpeedRPM.override = OVERRIDE_RESET; + adcDialInPumpMCSpeedRPM.ovData = adcDialInPumpMCSpeedRPM.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetMeasuredDialInPumpMCCurrentOverride function overrides the measured + * dialIn pump motor current. + * @details Inputs: none + * @details Outputs: adcDialInPumpMCCurrentmA + * @param value override measured dialIn pump current (in mA) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetMeasuredDialInPumpMCCurrentOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + adcDialInPumpMCCurrentmA.ovData = value; + adcDialInPumpMCCurrentmA.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetMeasuredDialInPumpMCCurrentOverride function resets the override of the + * measured dialIn pump motor current. + * @details Inputs: none + * @details Outputs: adcDialInPumpMCCurrentmA + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetMeasuredDialInPumpMCCurrentOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + adcDialInPumpMCCurrentmA.override = OVERRIDE_RESET; + adcDialInPumpMCCurrentmA.ovData = adcDialInPumpMCCurrentmA.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief * The testSetDialInPumpTargetDutyCycle function sets the duty cycle of the * dialysate inlet pump by calling setDialInPumpTargetFlowRate. * @details Inputs: none @@ -1976,4 +1976,4 @@ return result; } -/**@}*/ +/**@}*/ Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r2c1c34c153a146d659976b3aa499937b88264b1b -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 2c1c34c153a146d659976b3aa499937b88264b1b) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -418,7 +418,7 @@ U08 artPresStatus = (U08)( fpgaArtPres >> SHIFT_14_BITS ); checkFPGAPersistentAlarms( FPGA_PERS_ERROR_ARTERIAL_PRESSURE_SENSOR, artReadCtr ); - checkFPGAPersistentAlarms( FPGA_PERS_ERROR_VENOUS_PRESSURE_SESNOR, venReadCtr ); // TODO investigate this with Noe + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_VENOUS_PRESSURE_SESNOR, venReadCtr ); if ( ARTERIAL_PRESSURE_NORMAL_OP == artPresStatus ) { Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r8ed20540782ec6b81fc870c33c7a7e6f589a6ff3 -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 8ed20540782ec6b81fc870c33c7a7e6f589a6ff3) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -40,7 +40,7 @@ // Valve dialyzer inlet defines #define VDI_SET_PID_BIT_MASK 0x0010 ///< VDI enable PID bit mask #define VDI_SET_BYPASS_BIT_MASK 0x0020 ///< VDI enable bypass bit mask -#define VDI_RESET_CONTROL_BIT_MASK 0x03CF ///< VDI reset control bit mask +#define VDI_RESET_CONTROL_BIT_MASK 0x0FCF ///< VDI reset control bit mask #define VDI_INIT_STATUS_BIT_MASK 0x0040 ///< VDI init status bit mask #define VDI_ENABLE_PID_STATUS_BIT_MASK 0x0080 ///< VDI PID status bit mask @@ -49,7 +49,7 @@ // Valve dialyzer outlet defines #define VDO_SET_PID_BIT_MASK 0x0040 ///< VDO enable PID interface #define VDO_SET_BYPASS_BIT_MASK 0x0080 ///< VDO enable bypass bit mask -#define VDO_RESET_CONTROL_BIT_MASK 0x033F ///< VDO reset control bit mask +#define VDO_RESET_CONTROL_BIT_MASK 0x09FF ///< VDO reset control bit mask #define VDO_INIT_STATUS_BIT_MASK 0x0200 ///< VDO init status bit mask #define VDO_ENABLE_PID_STATUS_BIT_MASK 0x0400 ///< VDO enable PID status bit mask @@ -58,7 +58,7 @@ // Valve blood arterial defines #define VBA_SET_PID_BIT_MASK 0x0001 ///< VBA enable PID interface #define VBA_SET_BYPASS_BIT_MASK 0x0002 ///< VBA enable bypass interface -#define VBA_RESET_CONTROL_BIT_MASK 0x03FC ///< VBA reset control bit mask +#define VBA_RESET_CONTROL_BIT_MASK 0x0FFC ///< VBA reset control bit mask #define VBA_INIT_STATUS_BIT_MASK 0x0001 ///< VBA init status bit mask #define VBA_ENABLE_PID_STATUS_BIT_MASK 0x0002 ///< VBA PID status bit mask @@ -67,7 +67,7 @@ // Valve blood venous defines #define VBV_SET_PID_BIT_MASK 0x0004 ///< VBV enable PID interface bit mask #define VBV_SET_BYPASS_BIT_MASK 0x0008 ///< VBV enable bypass interface bit mask -#define VBV_RESET_CONTROL_BIT_MASK 0x03F3 ///< VBV reset control bit mask +#define VBV_RESET_CONTROL_BIT_MASK 0x0FF3 ///< VBV reset control bit mask #define VBV_INIT_STATUS_BIT_MASK 0x0008 ///< VBV init status bit mask #define VBV_ENABLE_PID_STATUS_BIT_MASK 0x0010 ///< VBV PID status bit mask @@ -219,12 +219,44 @@ static const U16 VALVE_CONTROL_MODES_RESET_BITS[ NUM_OF_VALVES ] = { VDI_RESET_CONTROL_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK, VBA_RESET_CONTROL_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK }; ///< Valves control modes rest bits -static const U16 VALVE_CONTROL_STATUS_BITS[ NUM_OF_VALVES ][ NUM_OF_VALVE_CONTROL_STATUS ] = - { { VDI_INIT_STATUS_BIT_MASK, VDI_ENABLE_PID_STATUS_BIT_MASK, VDI_ENABLE_BYPASS_STATUS_BIT_MASK, VDI_RESET_CONTROL_BIT_MASK }, - { VDO_INIT_STATUS_BIT_MASK, VDO_ENABLE_PID_STATUS_BIT_MASK, VDO_ENABLE_BYPASS_STATUS_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK }, - { VBA_INIT_STATUS_BIT_MASK, VBA_ENABLE_PID_STATUS_BIT_MASK, VBA_ENABLE_BYPASS_STATUS_BIT_MASK, VBA_RESET_CONTROL_BIT_MASK }, - { VBV_INIT_STATUS_BIT_MASK, VBV_ENABLE_PID_STATUS_BIT_MASK, VBV_ENABLE_BYPASS_STATUS_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK } }; ///< Valves control status bits +/// Valve check entries +enum valve_check_entries +{ + VALVE_CHECK_EXPECTED_CONTROL = 0, ///< Valve check expected control values + VALVE_CHECK_BIT_MASK, ///< Valve check bit mask + NUM_OF_VALVE_CHECK_ENTRIES, ///< Number of valve check entries +}; +#define VALVE_INIT_STATUS_BIT 0x0001 ///< valve init +#define VALVE_ENABLE_PID_STATUS_BIT 0x0002 ///< valve PID enabled +#define VALVE_ENABLE_BYPASS_STATUS_BIT 0x0004 ///< valve bypass + +#define VALVE_PID_CHECK ( VALVE_INIT_STATUS_BIT | VALVE_ENABLE_PID_STATUS_BIT ) +#define VALVE_CHECK_MASK ( VALVE_INIT_STATUS_BIT | VALVE_ENABLE_PID_STATUS_BIT | VALVE_ENABLE_BYPASS_STATUS_BIT ) +#define VALVE_CHECK_BITS_PER_VALVE ( 3 ) + +#define VDI_POS ( 2 ) +#define VDO_POS ( 3 ) +#define VBA_POS ( 0 ) +#define VBV_POS ( 1 ) +#define VDI_VALVE_CHECK ( VALVE_PID_CHECK << ( VDI_POS * VALVE_CHECK_BITS_PER_VALVE ) ) +#define VDO_VALVE_CHECK ( VALVE_PID_CHECK << ( VDO_POS * VALVE_CHECK_BITS_PER_VALVE ) ) +#define VBA_VALVE_CHECK ( VALVE_PID_CHECK << ( VBA_POS * VALVE_CHECK_BITS_PER_VALVE ) ) +#define VBV_VALVE_CHECK ( VALVE_PID_CHECK << ( VBV_POS * VALVE_CHECK_BITS_PER_VALVE ) ) + +#define VDI_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( 2 * VALVE_CHECK_BITS_PER_VALVE ) ) ) +#define VDO_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( 3 * VALVE_CHECK_BITS_PER_VALVE ) ) ) +#define VBA_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( 0 * VALVE_CHECK_BITS_PER_VALVE ) ) ) +#define VBV_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( 1 * VALVE_CHECK_BITS_PER_VALVE ) ) ) + +static const U16 VALVE_CHECK[ NUM_OF_VALVES ][ NUM_OF_VALVE_CHECK_ENTRIES ] = +{ { VDI_VALVE_CHECK, VDI_VALVE_CHECK_MASK }, + { VDO_VALVE_CHECK, VDO_VALVE_CHECK_MASK }, + { VBA_VALVE_CHECK, VBA_VALVE_CHECK_MASK }, + { VBV_VALVE_CHECK, VBV_VALVE_CHECK_MASK } +}; ///< Valve check entries + + static U16 valvesControlSetBits; ///< Valves control set bit static OPN_CLS_STATE_T valveAirTrapStatus; ///< Air trap valve status (open/close) static HD_VALVES_CAL_RECORD_T valvesCalibrationRecord; ///< Valves calibration record. @@ -1004,65 +1036,30 @@ * The areValvesEnabled function checks the current valves status from FPGA * to the enable bit mask of each valve. If any of the valves is not enabled * the function raises an alarm. - * @details Inputs: valvesStatus + * @details Inputs: valvesStatus, VALVE_CHECK * @details Outputs: none - * @return Returns TRUE if all the valves are enabled properly + * @return Returns TRUE if all the valves status bits are correct *************************************************************************/ static BOOL areValvesFunctional( void ) { BOOL result = TRUE; VALVE_T valve; - VALVE_MODE_T mode; // Get the status of the valves from FPGA - U16 status = getFPGAValvesStatus(); + U16 status = getFPGAValvesStatus(); for ( valve = VDI; valve < NUM_OF_VALVES; valve++ ) { - mode = valvesStatus[ valve ].controlMode; - - // Depending on the control mode of the valve, different bit masks will be checked - if ( mode == VALVE_CONTROL_MODE_ENABLE_PID ) + U16 statusCheck = status & VALVE_CHECK[ valve ][ VALVE_CHECK_BIT_MASK ]; + if ( VALVE_CHECK[ valve ][ VALVE_CHECK_EXPECTED_CONTROL ] != statusCheck ) { - if ( FALSE == ( status & VALVE_CONTROL_STATUS_BITS[ valve ][ VALVE_CONTROL_STATUS_INITIALIZED ] ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)mode ); - result = FALSE; - } - if ( FALSE == ( status & VALVE_CONTROL_STATUS_BITS[ valve ][ VALVE_CONTROL_STATUS_PID_ENABLED ] ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)mode ); - result = FALSE; - } - } - else if ( mode == VALVE_CONTROL_MODE_ENABLE_BYPASS ) - { - if ( FALSE == ( status & VALVE_CONTROL_STATUS_BITS[ valve ][ VALVE_CONTROL_STATUS_BYPASS_ENABLED ] ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)mode ); - result = FALSE; - } - } - else if ( mode == VALVE_CONTROL_MODE_DISABLE_ALL ) - { - if ( FALSE == ( status & ( ~VALVE_CONTROL_STATUS_BITS[ valve ][ VALVE_CONTROL_STATUS_DISABLED ] ) ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)mode ); - result = FALSE; - } - } -#ifndef _VECTORCAST_ - // The default cannot be reached in VectorCAST since the cases are run in a for loop - // Invalid mode was selected - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_VALVES_INVALID_CONTROL_MODE_SELECTED, (U32)valve ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)status); result = FALSE; - } -#endif + } } return result; + } /*********************************************************************//** Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -rc1b9ac0dbf2196280895d2e440dd7ac288ac8424 -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision c1b9ac0dbf2196280895d2e440dd7ac288ac8424) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -93,8 +93,8 @@ SW_FAULT_ID_CAN_PARITY_ERROR, SW_FAULT_ID_CAN_PASSIVE_WARNING, SW_FAULT_ID_CAN_OFF_ERROR, - SW_FAULT_ID_FPGA_UART_FRAME_ERROR, // 65 - SW_FAULT_ID_FPGA_UART_OVERRUN_ERROR, + SW_FAULT_ID_____AVAILABLE_2, // 65 + SW_FAULT_ID_____AVAILABLE_3, SW_FAULT_ID_UTIL_TIME_WINDOWED_COUNT_ERROR, SW_FAULT_ID_ACCEL_INVALID_STATE, SW_FAULT_ID_ACCEL_GET_INVALID_AXIS, Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r8e366c26b98be701b93f6d224955fae41b96b0aa -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 8e366c26b98be701b93f6d224955fae41b96b0aa) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -320,6 +320,7 @@ static void consumeUnexpectedData( void ); static void monitorFPGAPowerStatus( void ); static BOOL checkFPGACommFailure( void ); +static BOOL checkFPGAFEOEFailure( void ); /*********************************************************************//** * @brief @@ -519,6 +520,9 @@ { fpgaReadByteSize = sizeof( FPGA_SENSORS_T ); + // Check if FE or OE error has occurred + checkFPGAFEOEFailure(); + // FPGA incoming state machine switch ( fpgaState ) { @@ -568,6 +572,9 @@ { fpgaReadByteSize = sizeof( FPGA_SENSORS_T ); + // Check if FE or OE error has occurred + checkFPGAFEOEFailure(); + // FPGA outgoing state machine switch ( fpgaState ) { @@ -2353,4 +2360,35 @@ } +/*********************************************************************//** + * @brief + * The checkFPGACommFailure function increments the FPGA comm failure + * windowed timer if an FE or OE error has occurred and returns whether + * or not the number of failures in + * the window have been reached. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if windowed count exceeded, else false. + *************************************************************************/ +static BOOL checkFPGAFEOEFailure( void ) +{ + BOOL status = false; + BOOL FPGAFEOEError = getSci2FEOEError(); + + if ( TRUE == FPGAFEOEError) + { + if ( getMSTimerCount() > MIN_POWER_ON_TIME_FOR_COMM_FAILS ) + { + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_COMM_FAILURES ) ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_COMM_TIMEOUT, MAX_FPGA_COMM_FAILURES, (U32)fpgaSensorReadings.errorCountProcessor ) + status = TRUE; + } + } + } + + return status; + +} + /**@}*/ Index: firmware/App/Services/Interrupts.c =================================================================== diff -u -r2c1c34c153a146d659976b3aa499937b88264b1b -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Services/Interrupts.c (.../Interrupts.c) (revision 2c1c34c153a146d659976b3aa499937b88264b1b) +++ firmware/App/Services/Interrupts.c (.../Interrupts.c) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -53,8 +53,7 @@ // ********** private data ********** -static U32 sci2FrameErrorCnt = 0; ///< FPGA serial frame error counter. -static U32 sci2OverrunErrorCnt = 0; ///< FPGA serial overrun error counter. +static BOOL sci2FEOEError = FALSE; ///< FPGA serial frame or overrun flag; static U32 can1WarningCnt = 0; ///< CAN warning mode counter. static U32 can1BusOffCnt = 0; ///< CAN buss off mode counter. @@ -74,8 +73,6 @@ // Initialize various time windowed counts for monitoring CAN & UART errors and warnings initTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_OFF, MAX_COMM_ERRORS, COMM_ERROR_TIME_WINDOW_MS ); initTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_PARITY, MAX_COMM_ERRORS, COMM_ERROR_TIME_WINDOW_MS ); - initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_UART_FRAME_ERROR, MAX_FPGA_HDW_COMM_ERRORS, FPGA_HDW_COMM_ERROR_TIME_WINDOW_MS ); - initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_UART_OVERRUN, MAX_FPGA_HDW_COMM_ERRORS, FPGA_HDW_COMM_ERROR_TIME_WINDOW_MS ); } /*********************************************************************//** @@ -203,23 +200,14 @@ { if ( ( flags & SCI_FE_INT ) != 0 ) { - sci2FrameErrorCnt++; + sci2FEOEError = TRUE; scilinREG->FLR |= SCI_FE_INT; - if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_UART_FRAME_ERROR ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_COMM_TIMEOUT, MAX_FPGA_HDW_COMM_ERRORS, sci2FrameErrorCnt ) - //SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_UART_OVERRUN_ERROR ) - } } + if ( ( flags & SCI_OE_INT ) != 0 ) { - sci2OverrunErrorCnt++; + sci2FEOEError = TRUE; scilinREG->FLR |= SCI_OE_INT; - if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_UART_OVERRUN ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_COMM_TIMEOUT, MAX_FPGA_HDW_COMM_ERRORS, sci2OverrunErrorCnt ) - //SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_UART_OVERRUN_ERROR ) - } } } } @@ -290,4 +278,24 @@ } } +/*********************************************************************//** + * @brief + * The getSci2FEOEError function returns the sci2FEOEError (OE - Overrun, + * FE - Framing Error) status and resets the status if TRUE + * @details Inputs: sci2FEOEError + * @details Outputs: none + * @return sci2 FE / OE error + *************************************************************************/ +BOOL getSci2FEOEError( void ) +{ + BOOL returnValue = sci2FEOEError; + + if (TRUE == sci2FEOEError ) + { + sci2FEOEError = FALSE; + } + + return returnValue;; +} + /**@}*/ Index: firmware/App/Services/Interrupts.h =================================================================== diff -u -r0a4dcd288d4347b85baaa0b07da568b6add5eac7 -r1145e9197855b4f2cb79eb407d3899059b0ca410 --- firmware/App/Services/Interrupts.h (.../Interrupts.h) (revision 0a4dcd288d4347b85baaa0b07da568b6add5eac7) +++ firmware/App/Services/Interrupts.h (.../Interrupts.h) (revision 1145e9197855b4f2cb79eb407d3899059b0ca410) @@ -34,6 +34,8 @@ void initInterrupts( void ); +BOOL getSci2FEOEError( void ); + /**@}*/ #endif