Index: firmware/.settings/com.googlecode.cppcheclipse.core.prefs =================================================================== diff -u --- firmware/.settings/com.googlecode.cppcheclipse.core.prefs (revision 0) +++ firmware/.settings/com.googlecode.cppcheclipse.core.prefs (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) @@ -0,0 +1,7 @@ +checkAllIssues=true +checkForce=true +checkInconclusive=true +checkVerbose=true +com.googlecode.cppcheclipse.ui.SettingsPreferencePage_useParentScope=false +eclipse.preferences.version=1 +languageStandardPosix=true Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r6463655c18b173e335b6d475ac7289336f1bf092 -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 6463655c18b173e335b6d475ac7289336f1bf092) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) @@ -32,105 +32,119 @@ #include "Timers.h" #include "DialInFlow.h" +/** + * @addtogroup DialysateInletFlow + * @{ + */ + // ********** private definitions ********** -#define DIAL_IN_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) // 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 ) ///> interval (ms/task time) at which the dialIn flow data is published on the CAN bus -#define MAX_DIAL_IN_PUMP_PWM_STEP_CHANGE 0.01 // duty cycle TODO - fixed or parameterized or set in motor controller? -#define MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.88 // controller will error if PWM duty cycle > 90%, so set max to 88% -#define MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.12 // controller will error if PWM duty cycle < 10%, so set min to 12% +#define MAX_DIAL_IN_PUMP_PWM_STEP_CHANGE 0.01 ///> duty cycle TODO - fixed or parameterized or set in motor controller? +#define MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.88 ///> controller will error if PWM duty cycle > 90%, so set max to 88% +#define MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE 0.12 ///> controller will error if PWM duty cycle < 10%, so set min to 12% -#define DIP_CONTROL_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) // interval (ms/task time) at which the dialIn pump is controlled -#define DIP_P_COEFFICIENT 0.00005 // P term for dialIn pump control -#define DIP_I_COEFFICIENT 0.00015 // I term for dialIn pump control +#define DIP_CONTROL_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///> interval (ms/task time) at which the dialIn pump is controlled +#define DIP_P_COEFFICIENT 0.00005 ///> P term for dialIn pump control +#define DIP_I_COEFFICIENT 0.00015 ///> I term for dialIn pump control -#define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0 // motor controller current should not exceed this when pump should be stopped -#define DIP_MIN_CURR_WHEN_RUNNING_MA 150.0 // motor controller current should always exceed this when pump should be running -#define DIP_MAX_CURR_WHEN_RUNNING_MA 1000.0 // motor controller current should not exceed this when pump should be running -#define DIP_MAX_CURR_ERROR_DURATION_MS 2000 // motor controller current errors persisting beyond this duration will trigger an alarm +#define DIP_HOME_RATE 50 ///< target pump speed (in estimate mL/min) for homing. +#define DIP_HOME_TIMEOUT_MS 10000 ///< maximum time allowed for homing to complete (in ms). -#define DIP_SPEED_ADC_TO_RPM_FACTOR 1.280938 // conversion factor from ADC counts to RPM for dialIn pump motor -#define DIP_CURRENT_ADC_TO_MA_FACTOR 3.002 // conversion factor from ADC counts to mA for dialIn pump motor +#define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///> motor controller current should not exceed this when pump should be stopped +#define DIP_MIN_CURR_WHEN_RUNNING_MA 150.0 ///> motor controller current should always exceed this when pump should be running +#define DIP_MAX_CURR_WHEN_RUNNING_MA 1000.0 ///> motor controller current should not exceed this when pump should be running +#define DIP_MAX_CURR_ERROR_DURATION_MS 2000 ///> motor controller current errors persisting beyond this duration will trigger an alarm -#define DIP_REV_PER_LITER 150.24 // rotor revolutions per liter -#define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) -#define DIP_GEAR_RATIO 32.0 // dialIn pump motor to dialIn pump gear ratio -#define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.00035 // ~28 BP motor RPM = 1% PWM duty cycle -#define DIP_PWM_ZERO_OFFSET 0.1 // 10% PWM duty cycle = zero speed -#define DIP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DIP_GEAR_RATIO * DIP_MOTOR_RPM_TO_PWM_DC_FACTOR + DIP_PWM_ZERO_OFFSET ) +#define DIP_SPEED_ADC_TO_RPM_FACTOR 1.280938 ///> conversion factor from ADC counts to RPM for dialIn pump motor +#define DIP_CURRENT_ADC_TO_MA_FACTOR 3.002 ///> conversion factor from ADC counts to mA for dialIn pump motor -#define DIAL_IN_PUMP_ADC_FULL_SCALE_V 3.0 // BP analog signals are 0-3V (while int. ADC ref V may be different) -#define DIAL_IN_PUMP_ADC_ZERO ( (F32)( INT_ADC_ZERO ) * ( DIAL_IN_PUMP_ADC_FULL_SCALE_V / INT_ADC_REF_V ) ) -#define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DIAL_IN_PUMP_ADC_ZERO ) +#define DIP_REV_PER_LITER 150.24 ///> rotor revolutions per liter +#define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) ///> +#define DIP_GEAR_RATIO 32.0 ///> dialIn pump motor to dialIn pump gear ratio +#define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.00035 ///> ~28 BP motor RPM = 1% PWM duty cycle +#define DIP_PWM_ZERO_OFFSET 0.1 ///> 10% PWM duty cycle = zero speed +#define DIP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DIP_GEAR_RATIO * DIP_MOTOR_RPM_TO_PWM_DC_FACTOR + DIP_PWM_ZERO_OFFSET ) ///> -#define DIAL_IN_FLOW_SAMPLE_FREQ ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) -#define SIZE_OF_ROLLING_AVG ( DIAL_IN_FLOW_SAMPLE_FREQ * 2 ) // measured dialIn flow is filtered w/ moving average -#define MAX_FLOW_FILTER_INTERVAL 5 // slowest sample interval for filter is every 5th sample +#define DIAL_IN_PUMP_ADC_FULL_SCALE_V 3.0 ///> BP analog signals are 0-3V (while int. ADC ref V may be different) +#define DIAL_IN_PUMP_ADC_ZERO ( (F32)( INT_ADC_ZERO ) * ( DIAL_IN_PUMP_ADC_FULL_SCALE_V / INT_ADC_REF_V ) ) ///> +#define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DIAL_IN_PUMP_ADC_ZERO ) ///> +#define DIAL_IN_FLOW_SAMPLE_FREQ ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///> +#define SIZE_OF_ROLLING_AVG ( DIAL_IN_FLOW_SAMPLE_FREQ * 2 ) ///> measured dialIn flow is filtered w/ moving average +#define MAX_FLOW_FILTER_INTERVAL 5 ///> slowest sample interval for filter is every 5th sample + +/// Enumeration of dialysate inlet pump states. typedef enum DialInPump_States { - DIAL_IN_PUMP_OFF_STATE = 0, - DIAL_IN_PUMP_RAMPING_UP_STATE, - DIAL_IN_PUMP_RAMPING_DOWN_STATE, - DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE, - NUM_OF_DIAL_IN_PUMP_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, - DIAL_IN_FLOW_TEST_STATE_IN_PROGRESS, - DIAL_IN_FLOW_TEST_STATE_COMPLETE, - NUM_OF_DIAL_IN_FLOW_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 -#define DIR_DI_PUMP_SPI5_PORT_MASK 0x00000100 // (ENA - re-purposed as output GPIO) +#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;} -#define CLR_DIP_DIR() {mibspiREG5->PC3 &= ~DIR_DI_PUMP_SPI5_PORT_MASK;} +#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. #ifndef BREADBOARD_TARGET - #define SET_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) - #define CLR_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) + #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. #else #define SET_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) #define CLR_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) #endif // ********** 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 = 5; // 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 dialIn flow direction -static MOTOR_DIR_T dialInPumpDirectionSet = MOTOR_DIR_FORWARD; // currently set dialIn flow direction +static DIAL_IN_PUMP_STATE_T dialInPumpState = DIAL_IN_PUMP_OFF_STATE; ///< current state of dialIn flow controller state machine +static U32 dialInFlowDataPublicationTimerCounter = 5; ///< 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 dialIn flow direction +static MOTOR_DIR_T dialInPumpDirectionSet = MOTOR_DIR_FORWARD; ///< currently set dialIn 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. -DATA_DECL( U32, DialInFlowDataPub, dialInFlowDataPublishInterval, DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL ); // interval (in ms) at which to publish dialIn flow data to CAN bus -DATA_DECL( S32, TargetDialInFlowRate, targetDialInFlowRate, 0, 0 ); // requested dialIn flow rate -DATA_DECL( F32, MeasuredDialInFlowRate, measuredDialInFlowRate, 0.0, 0.0 ); // measured dialIn flow rate -DATA_DECL( F32, MeasuredDialInPumpRotorSpeed, dialInPumpRotorSpeedRPM, 0.0, 0.0 );// measured dialIn pump rotor speed -DATA_DECL( F32, MeasuredDialInPumpSpeed, dialInPumpSpeedRPM, 0.0, 0.0 ); // measured dialIn pump motor speed -DATA_DECL( F32, MeasuredDialInPumpMCSpeed, adcDialInPumpMCSpeedRPM, 0.0, 0.0 ); // measured dialIn pump motor controller speed -DATA_DECL( F32, MeasuredDialInPumpMCCurrent, adcDialInPumpMCCurrentmA, 0.0, 0.0 );// measured dialIn pump motor controller current +DATA_DECL( U32, DialInFlowDataPub, dialInFlowDataPublishInterval, DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL ); ///< interval (in ms) at which to publish dialIn flow data to CAN bus +DATA_DECL( S32, TargetDialInFlowRate, targetDialInFlowRate, 0, 0 ); ///< requested dialIn flow rate +DATA_DECL( F32, MeasuredDialInFlowRate, measuredDialInFlowRate, 0.0, 0.0 ); ///< measured dialIn flow rate +DATA_DECL( F32, MeasuredDialInPumpRotorSpeed, dialInPumpRotorSpeedRPM, 0.0, 0.0 ); ///< measured dialIn pump rotor speed +DATA_DECL( F32, MeasuredDialInPumpSpeed, dialInPumpSpeedRPM, 0.0, 0.0 ); ///< measured dialIn pump motor speed +DATA_DECL( F32, MeasuredDialInPumpMCSpeed, adcDialInPumpMCSpeedRPM, 0.0, 0.0 ); ///< measured dialIn pump motor controller speed +DATA_DECL( F32, MeasuredDialInPumpMCCurrent, adcDialInPumpMCCurrentmA, 0.0, 0.0 ); ///< measured dialIn pump motor controller current -static U32 dipControlTimerCounter = 0; // determines when to perform control on dialIn flow +static U32 dipControlTimerCounter = 0; ///< determines when to perform control on dialIn flow -static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; // holds flow samples for a rolling average -static U32 flowReadingsIdx = 0; // index for next sample in rolling average array -static F32 flowReadingsTotal = 0.0; // rolling total - used to calc average -static U32 flowReadingsCount = 0; // # of samples in flow rolling average buffer -static U32 flowReadingsTmrCtr = 0; // determines when to add samples to filter +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 dipCurrErrorDurationCtr = 0; // used for tracking persistence of dip current errors +static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; ///< holds flow samples for a rolling average +static U32 flowReadingsIdx = 0; ///< index for next sample in rolling average array +static F32 flowReadingsTotal = 0.0; ///< rolling total - used to calc average +static U32 flowReadingsCount = 0; ///< # of samples in flow rolling average buffer +static U32 flowReadingsTmrCtr = 0; ///< determines when to add samples to filter -static DIAL_IN_FLOW_SELF_TEST_STATE_T dialInPumpSelfTestState = DIAL_IN_FLOW_SELF_TEST_STATE_START; // current dialIn pump self test state -static U32 dialInPumpSelfTestTimerCount = 0; // timer counter for dialIn pump self test +static U32 dipCurrErrorDurationCtr = 0; ///< used for tracking persistence of dip current errors +static DIAL_IN_FLOW_SELF_TEST_STATE_T dialInPumpSelfTestState = DIAL_IN_FLOW_SELF_TEST_STATE_START; ///< current dialIn pump self test state +static U32 dialInPumpSelfTestTimerCount = 0; ///< timer counter for dialIn pump self test + // ********** private function prototypes ********** static DIAL_IN_PUMP_STATE_T handleDialInPumpOffState( void ); @@ -148,13 +162,12 @@ static void checkDialInPumpMCCurrent( void ); static DATA_GET_PROTOTYPE( U32, getPublishDialInFlowDataInterval ); -/************************************************************************* - * @brief initDialInFlow +/*********************************************************************//** + * @brief * The initDialInFlow function initializes the DialInFlow module. * @details * Inputs : none * Outputs : DialInFlow module initialized. - * @param none * @return none *************************************************************************/ void initDialInFlow( void ) @@ -171,8 +184,8 @@ MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); } -/************************************************************************* - * @brief setDialInPumpTargetFlowRate +/*********************************************************************//** + * @brief * The setDialInPumpTargetFlowRate function sets a new target flow rate and * pump direction. * @details @@ -239,13 +252,12 @@ return result; } -/************************************************************************* - * @brief signalDialInPumpHardStop +/*********************************************************************//** + * @brief * The signalDialInPumpHardStop function stops the dialIn pump immediately. * @details * Inputs : none * Outputs : DialIn pump stopped, set point reset, state changed to off - * @param none * @return none *************************************************************************/ void signalDialInPumpHardStop( void ) @@ -258,13 +270,61 @@ resetPIController( PI_CONTROLLER_ID_DIALYSATE_FLOW, MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); } -/************************************************************************* - * @brief execDialInFlowMonitor +/*********************************************************************//** + * @brief + * The signalDialInPumpRotorHallSensor function handles the dialysate inlet pump rotor \n + * hall sensor detection. Calculates rotor speed (in RPM). Stops pump if \n + * there is a pending request to home the pump. + * @details + * Inputs : dipRotorRevStartTime, dipStopAtHomePosition + * Outputs : dipRotorRevStartTime, dialInPumpRotorSpeedRPM + * @return none + *************************************************************************/ +void signalDialInPumpRotorHallSensor( void ) +{ + U32 rotTime = getMSTimerCount(); + U32 deltaTime = calcTimeBetween( dipRotorRevStartTime, rotTime ); + + // calculate rotor speed (in RPM) + dialInPumpRotorSpeedRPM.data = ( 1.0 / (F32)deltaTime ) * (F32)MS_PER_SECOND * (F32)SEC_PER_MIN; + dipRotorRevStartTime = rotTime; + + // if we're 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 + * 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 = setDialInPumpTargetFlowRate( DIP_HOME_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + + return result; +} + +/*********************************************************************//** + * @brief * The execDialInFlowMonitor function executes the dialIn flow monitor. * @details * Inputs : none * Outputs : measuredDialInFlowRate, adcDialInPumpMCSpeedRPM, adcDialInPumpMCCurrentmA - * @param none * @return none *************************************************************************/ void execDialInFlowMonitor( void ) @@ -285,17 +345,24 @@ checkDialInPumpMCCurrent(); } + // if homing, check timeout + if ( ( TRUE == dipStopAtHomePosition ) && ( TRUE == didTimeout( dipHomeStartTime, DIP_HOME_TIMEOUT_MS ) ) ) + { + signalDialInPumpHardStop(); + dipStopAtHomePosition = FALSE; + // TODO - alarm??? + } + // publish dialIn flow data on interval publishDialInFlowData(); } -/************************************************************************* - * @brief execDialInFlowController +/*********************************************************************//** + * @brief * The execDialInFlowController function executes the dialIn flow controller. * @details * Inputs : dialInPumpState * Outputs : dialInPumpState - * @param none * @return none *************************************************************************/ void execDialInFlowController( void ) @@ -324,14 +391,13 @@ } } -/************************************************************************* - * @brief handleDialInPumpOffState +/*********************************************************************//** + * @brief * The handleDialInPumpOffState function handles the dialIn pump off state \n * of the dialIn pump controller state machine. * @details * Inputs : targetDialInFlowRate, dialInPumpDirection * Outputs : dialInPumpPWMDutyCyclePctSet, dialInPumpDirectionSet, isDialInPumpOn - * @param none * @return next state *************************************************************************/ static DIAL_IN_PUMP_STATE_T handleDialInPumpOffState( void ) @@ -354,14 +420,13 @@ return result; } -/************************************************************************* - * @brief handleDialInPumpRampingUpState +/*********************************************************************//** + * @brief * The handleDialInPumpRampingUpState function handles the ramp up state \n * of the dialIn pump controller state machine. * @details * Inputs : dialInPumpPWMDutyCyclePctSet * Outputs : dialInPumpPWMDutyCyclePctSet - * @param none * @return next state *************************************************************************/ static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingUpState( void ) @@ -400,14 +465,13 @@ return result; } -/************************************************************************* - * @brief handleDialInPumpRampingDownState +/*********************************************************************//** + * @brief * The handleDialInPumpRampingDownState function handles the ramp down state \n * of the dialIn pump controller state machine. * @details * Inputs : dialInPumpPWMDutyCyclePctSet * Outputs : dialInPumpPWMDutyCyclePctSet - * @param none * @return next state *************************************************************************/ static DIAL_IN_PUMP_STATE_T handleDialInPumpRampingDownState( void ) @@ -444,14 +508,13 @@ return result; } -/************************************************************************* - * @brief handleDialInPumpControlToTargetState +/*********************************************************************//** + * @brief * The handleDialInPumpControlToTargetState function handles the "control to \n * target" state of the dialIn pump controller state machine. * @details * Inputs : none * Outputs : dialInPumpState - * @param none * @return next state *************************************************************************/ static DIAL_IN_PUMP_STATE_T handleDialInPumpControlToTargetState( void ) @@ -477,8 +540,8 @@ return result; } -/************************************************************************* - * @brief setDialInPumpControlSignalPWM +/*********************************************************************//** + * @brief * The setDialInPumpControlSignalPWM function sets the PWM duty cycle for \n * the dialysate inlet pump to a given %. * @details @@ -492,13 +555,12 @@ etpwmSetCmpA( etpwmREG2, (U32)( (S32)( ( newPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); } -/************************************************************************* - * @brief stopDialInPump +/*********************************************************************//** + * @brief * The stopDialInPump function sets the dialIn pump stop signal. * @details * Inputs : none * Outputs : dialIn pump stop signal activated, PWM duty cycle zeroed - * @param none * @return none *************************************************************************/ static void stopDialInPump( void ) @@ -509,22 +571,21 @@ SET_DIP_STOP(); } -/************************************************************************* - * @brief releaseDialInPumpStop +/*********************************************************************//** + * @brief * The releaseDialInPumpStop function clears the dialIn pump stop signal. * @details * Inputs : none * Outputs : dialIn pump stop signal - * @param none * @return none *************************************************************************/ static void releaseDialInPumpStop( void ) { CLR_DIP_STOP(); } -/************************************************************************* - * @brief setDialInPumpDirection +/*********************************************************************//** + * @brief * The setDialInPumpDirection function sets the set dialIn pump direction to \n * the given direction. * @details @@ -553,99 +614,91 @@ } } -/************************************************************************* - * @brief getPublishDialInFlowDataInterval +/*********************************************************************//** + * @brief * The getPublishDialInFlowDataInterval function gets the dialIn flow data \n * publication interval. * @details * Inputs : dialInFlowDataPublishInterval * Outputs : none - * @param none * @return the current dialIn flow data publication interval (in ms). *************************************************************************/ DATA_GET( U32, getPublishDialInFlowDataInterval, dialInFlowDataPublishInterval ) -/************************************************************************* - * @brief getTargetDialInFlowRate +/*********************************************************************//** + * @brief * The getTargetDialInFlowRate function gets the current target dialIn flow \n * rate. * @details * Inputs : targetDialInFlowRate * Outputs : none - * @param none * @return the current target dialIn flow rate (in mL/min). *************************************************************************/ DATA_GET( S32, getTargetDialInFlowRate, targetDialInFlowRate ) -/************************************************************************* - * @brief getMeasuredDialInFlowRate +/*********************************************************************//** + * @brief * The getMeasuredDialInFlowRate function gets the measured dialIn flow \n * rate. * @details * Inputs : measuredDialInFlowRate * Outputs : none - * @param none - * @return the current dialIn flow rate (in mL/min). +/ * @return the current dialIn flow rate (in mL/min). *************************************************************************/ DATA_GET( F32, getMeasuredDialInFlowRate, measuredDialInFlowRate ) -/************************************************************************* - * @brief getMeasuredDialInPumpRotorSpeed +/*********************************************************************//** + * @brief * The getMeasuredDialInPumpRotorSpeed function gets the measured dialIn flow \n * rate. * @details * Inputs : dialInPumpRotorSpeedRPM * Outputs : none - * @param none * @return the current dialIn flow rate (in mL/min). *************************************************************************/ DATA_GET( F32, getMeasuredDialInPumpRotorSpeed, dialInPumpRotorSpeedRPM ) -/************************************************************************* - * @brief getMeasuredDialInPumpSpeed +/*********************************************************************//** + * @brief * The getMeasuredDialInPumpSpeed function gets the measured dialIn flow \n * rate. * @details * Inputs : dialInPumpSpeedRPM * Outputs : none - * @param none * @return the current dialIn flow rate (in mL/min). *************************************************************************/ DATA_GET( F32, getMeasuredDialInPumpSpeed, dialInPumpSpeedRPM ) -/************************************************************************* - * @brief getMeasuredDialInPumpMCSpeed +/*********************************************************************//** + * @brief * The getMeasuredDialInPumpMCSpeed function gets the measured dialIn pump \n * speed. * @details * Inputs : adcDialInPumpMCSpeedRPM * Outputs : none - * @param none * @return the current dialIn pump speed (in RPM). *************************************************************************/ DATA_GET( F32, getMeasuredDialInPumpMCSpeed, adcDialInPumpMCSpeedRPM ) -/************************************************************************* - * @brief getMeasuredDialInPumpMCCurrent +/*********************************************************************//** + * @brief * The getMeasuredDialInPumpMCCurrent function gets the measured dialIn pump \n * current. * @details * Inputs : adcDialInPumpMCCurrentmA * Outputs : none - * @param none - * @return the current dialIn pump current (in mA). +/ * @return the current dialIn pump current (in mA). *************************************************************************/ DATA_GET( F32, getMeasuredDialInPumpMCCurrent, adcDialInPumpMCCurrentmA ) -/************************************************************************* - * @brief publishDialInFlowData +/*********************************************************************//** + * @brief * The publishDialInFlowData function publishes dialIn flow data at the set \n * interval. * @details * Inputs : target flow rate, measured flow rate, measured MC speed, \n * measured MC current * Outputs : DialIn flow data is published to CAN bus. - * @param none * @return none *************************************************************************/ static void publishDialInFlowData( void ) @@ -664,27 +717,18 @@ F32 measMCSpd = getMeasuredDialInPumpMCSpeed(); F32 measMCCurr = getMeasuredDialInPumpMCCurrent(); F32 pumpPWMPctDutyCycle = dialInPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; -#ifdef DEBUG_ENABLED -// // TODO - temporary debug code - remove later -// char debugFlowStr[ 256 ]; -// -// sprintf( debugFlowStr, "Dial. Set Pt:%5d, Meas. Flow:%5d, Speed:%5d RPM, Current:%5d mA, PWM:%5d \n", flowStPt, (S32)measFlow, (S32)measMCSpd, (S32)measMCCurr, (S32)pumpPWMPctDutyCycle ); -// sendDebugData( (U08*)debugFlowStr, strlen(debugFlowStr) ); -#endif broadcastDialInFlowData( flowStPt, measFlow, measRotSpd, measSpd, measMCSpd, measMCCurr, pumpPWMPctDutyCycle ); dialInFlowDataPublicationTimerCounter = 0; } } -/************************************************************************* - * @brief resetDialInFlowMovingAverage +/*********************************************************************//** + * @brief * The resetDialInFlowMovingAverage function resets the properties of the \n * dialIn flow moving average sample buffer. * @details * Inputs : none * Outputs : flowReadingsTotal, flowReadingsIdx, flowReadingsCount all set to zero. - * @param none - * @return none *************************************************************************/ static void resetDialInFlowMovingAverage( void ) { @@ -695,8 +739,8 @@ dipControlTimerCounter = 0; } -/************************************************************************* - * @brief filterDialInFlowReadings +/*********************************************************************//** + * @brief * The filterDialInFlowReadings function adds a new flow sample to the filter \n * if decimation rate for current set point calls for it. * @details @@ -752,6 +796,7 @@ } } + // if it's time to add sample to filter, add it. if ( TRUE == addSampleToFilter ) { if ( flowReadingsCount >= SIZE_OF_ROLLING_AVG ) @@ -764,18 +809,16 @@ flowReadingsCount = INC_CAP( flowReadingsCount, SIZE_OF_ROLLING_AVG ); measuredDialInFlowRate.data = flowReadingsTotal / (F32)flowReadingsCount; } - flowReadingsTmrCtr = INC_WRAP( flowReadingsTmrCtr, 0, MAX_FLOW_FILTER_INTERVAL - 1 ); } -/************************************************************************* - * @brief checkDialInPumpDirection +/*********************************************************************//** + * @brief * The checkDialInPumpDirection function checks the set direction vs. \n * the direction implied by the sign of the measured MC speed. * @details * Inputs : adcDialInPumpMCSpeedRPM, dialInPumpDirectionSet, dialInPumpState * Outputs : none - * @param none * @return none *************************************************************************/ static void checkDialInPumpDirection( void ) @@ -793,14 +836,13 @@ } } -/************************************************************************* - * @brief checkDialInPumpMCCurrent +/*********************************************************************//** + * @brief * The checkDialInPumpMCCurrent function checks the measured MC current vs. \n * the set state of the dialIn pump (stopped or running). * @details * Inputs : dialInPumpState, dipCurrErrorDurationCtr, adcDialInPumpMCCurrentmA * Outputs : none - * @param none * @return none *************************************************************************/ static void checkDialInPumpMCCurrent( void ) @@ -847,14 +889,13 @@ } } -/************************************************************************* - * @brief execDialInFlowTest +/*********************************************************************//** + * @brief * The execDialInFlowTest function executes the state machine for the \n * DialInFlow self test. * @details * Inputs : none * Outputs : none - * @param none * @return the current state of the DialInFlow self test. *************************************************************************/ SELF_TEST_STATUS_T execDialInFlowTest( void ) @@ -872,8 +913,8 @@ *************************************************************************/ -/************************************************************************* - * @brief testSetDialInFlowDataPublishIntervalOverride +/*********************************************************************//** + * @brief * The testSetDialInFlowDataPublishIntervalOverride function overrides the \n * dialIn flow data publish interval. * @details @@ -898,8 +939,8 @@ return result; } -/************************************************************************* - * @brief testResetDialInFlowDataPublishIntervalOverride +/*********************************************************************//** + * @brief * The testResetDialInFlowDataPublishIntervalOverride function resets the override \n * of the dialIn flow data publish interval. * @details @@ -921,7 +962,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testSetTargetDialInFlowRateOverride function overrides the target \n * dialysate inlet flow rate. \n @@ -956,14 +997,13 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetTargetDialInFlowRateOverride function resets the override of the \n * target dialysate inlet flow rate. * @details * Inputs : none * Outputs : targetDialInFlowRate - * @param none * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetTargetDialInFlowRateOverride( void ) @@ -982,7 +1022,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetMeasuredDialInFlowRateOverride function overrides the measured \n * dialIn flow rate. @@ -1006,7 +1046,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetMeasuredDialInFlowRateOverride function resets the override of the \n * measured dialIn flow rate. @@ -1029,7 +1069,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testSetMeasuredDialInPumpRotorSpeedOverride function overrides the measured \n * dialIn pump rotor speed. @@ -1053,7 +1093,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetMeasuredDialInPumpRotorSpeedOverride function resets the override of the \n * measured dialIn pump rotor speed. @@ -1076,7 +1116,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testSetMeasuredDialInPumpSpeedOverride function overrides the measured \n * dialIn pump motor speed. @@ -1100,7 +1140,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetMeasuredDialInPumpSpeedOverride function resets the override of the \n * measured dialIn pump motor speed. @@ -1123,7 +1163,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testSetMeasuredDialInPumpMCSpeedOverride function overrides the measured \n * dialIn pump motor speed. @@ -1147,7 +1187,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetMeasuredDialInPumpMCSpeedOverride function resets the override of the \n * measured dialIn pump motor speed. @@ -1170,7 +1210,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testSetMeasuredDialInPumpMCCurrentOverride function overrides the measured \n * dialIn pump motor current. @@ -1194,7 +1234,7 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetMeasuredDialInPumpMCCurrentOverride function resets the override of the \n * measured dialIn pump motor current. @@ -1217,4 +1257,4 @@ return result; } - +/**@}*/ Index: firmware/App/Controllers/DialInFlow.h =================================================================== diff -u -r054fa08b67ed2a31f7848b179fbcd1b4da501b0f -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a --- firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision 054fa08b67ed2a31f7848b179fbcd1b4da501b0f) +++ firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) @@ -1,4 +1,4 @@ -/************************************************************************** +/**********************************************************************//** * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * @@ -19,10 +19,19 @@ #include "HDCommon.h" +/** + * @defgroup DialysateInletFlow DialysateInletFlow + * @brief Dialysate Inlet Pump & Dialysate Flow controller/monitor module. + * Monitors the dialysate flow rate and controls the dialysate inlet pump. + * + * @addtogroup DialysateInletFlow + * @{ + */ + // ********** public definitions ********** -#define MAX_DIAL_IN_FLOW_RATE 600 // mL/min -#define MIN_DIAL_IN_FLOW_RATE 100 // mL/min +#define MAX_DIAL_IN_FLOW_RATE 600 ///< Maximum dialysate inlet flow rate (in mL/min). +#define MIN_DIAL_IN_FLOW_RATE 100 ///< Minimum dialysate inlet flow rate (in mL/min). // ********** public function prototypes ********** @@ -32,6 +41,8 @@ BOOL setDialInPumpTargetFlowRate( U32 flowRate, MOTOR_DIR_T dir, PUMP_CONTROL_MODE_T mode ); void signalDialInPumpHardStop( void ); +void signalDialInPumpRotorHallSensor( void ); +BOOL homeDialInPump( void ); SELF_TEST_STATUS_T execDialInFlowTest( void ); @@ -57,4 +68,6 @@ BOOL testSetMeasuredDialInPumpMCCurrentOverride( F32 value ); BOOL testResetMeasuredDialInPumpMCCurrentOverride( void ); +/**@}*/ + #endif Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -r6463655c18b173e335b6d475ac7289336f1bf092 -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 6463655c18b173e335b6d475ac7289336f1bf092) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) @@ -52,6 +52,9 @@ #define DOP_P_COEFFICIENT 0.0050 ///< P term for dialysate outlet pump control. #define DOP_I_COEFFICIENT 0.0001 ///< I term for dialysate outlet pump control. +#define DOP_HOME_RATE 50 ///< target pump speed (in estimate mL/min) for homing. +#define DOP_HOME_TIMEOUT_MS 10000 ///< maximum time allowed for homing to complete (in ms). + #define DOP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped. #define DOP_MIN_CURR_WHEN_RUNNING_MA 150.0 ///< Motor controller current should always exceed this when pump should be running. #define DOP_MAX_CURR_WHEN_RUNNING_MA 1000.0 ///< Motor controller current should not exceed this when pump should be running. @@ -94,15 +97,15 @@ // pin assignments and macros for pump stop and direction outputs #define STOP_DO_PUMP_MIBSPI1_PORT_MASK 0x00000400 ///< MIBSPI1 SIMO[0] - re-purposed as GPIOoutput for pump controller run/stop pin. #ifndef BREADBOARD_TARGET - #define SET_DOP_STOP() {mibspiREG1->PC3 &= ~STOP_DO_PUMP_MIBSPI1_PORT_MASK;} ///< Macro sets pump controller run/stop signal to stop. - #define CLR_DOP_STOP() {mibspiREG1->PC3 |= STOP_DO_PUMP_MIBSPI1_PORT_MASK;} ///< Macro sets pump controller run/stop signal to run. + #define SET_DOP_STOP() {mibspiREG1->PC3 &= ~STOP_DO_PUMP_MIBSPI1_PORT_MASK;} ///< Macro sets pump controller run/stop signal to stop. + #define CLR_DOP_STOP() {mibspiREG1->PC3 |= STOP_DO_PUMP_MIBSPI1_PORT_MASK;} ///< Macro sets pump controller run/stop signal to run. #else - #define SET_DOP_STOP() {mibspiREG1->PC3 |= STOP_DO_PUMP_MIBSPI1_PORT_MASK;} ///< Macro sets pump controller run/stop signal to stop. - #define CLR_DOP_STOP() {mibspiREG1->PC3 &= ~STOP_DO_PUMP_MIBSPI1_PORT_MASK;} ///< Macro sets pump controller run/stop signal to run. + #define SET_DOP_STOP() {mibspiREG1->PC3 |= STOP_DO_PUMP_MIBSPI1_PORT_MASK;} ///< Macro sets pump controller run/stop signal to stop. + #define CLR_DOP_STOP() {mibspiREG1->PC3 &= ~STOP_DO_PUMP_MIBSPI1_PORT_MASK;} ///< Macro sets pump controller run/stop signal to run. #endif -#define STOP_DO_PUMP_GIO_PORT_PIN 6U ///< GIO port A pin used for pump controller direction pin. -#define SET_DOP_DIR() gioSetBit( gioPORTA, STOP_DO_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) ///< Macro sets pump controller direction to forward direction. -#define CLR_DOP_DIR() gioSetBit( gioPORTA, STOP_DO_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) ///< Macro sets pump controller direction to reverse direction. +#define STOP_DO_PUMP_GIO_PORT_PIN 6U ///< GIO port A pin used for pump controller direction pin. +#define SET_DOP_DIR() gioSetBit( gioPORTA, STOP_DO_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) ///< Macro sets pump controller direction to forward direction. +#define CLR_DOP_DIR() gioSetBit( gioPORTA, STOP_DO_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) ///< Macro sets pump controller direction to reverse direction. // ********** private data ********** @@ -129,6 +132,10 @@ static U32 dopControlTimerCounter = 0; ///< Timer counter to determine when to control dialysate outlet pump. static U32 dopCurrErrorDurationCtr = 0; ///< Timer counter for motor current error persistence. +static U32 dopRotorRevStartTime = 0; ///< dialysate outlet pump rotor rotation start time (in ms) +static BOOL dopStopAtHomePosition = FALSE; ///< stop dialysate outlet pump at next home position +static U32 dopHomeStartTime = 0; ///< when did dialysate outlet pump home command begin? (in ms) + static DIAL_OUT_PUMP_SELF_TEST_STATE_T dialOutPumpSelfTestState = DIAL_OUT_PUMP_SELF_TEST_STATE_START; ///< Current state of the dialysate outlet pump self test state machine. static U32 dialOutPumpSelfTestTimerCount = 0; ///< Timer counter for time reference during self test. @@ -295,6 +302,55 @@ /*********************************************************************//** * @brief + * The signalDialOutPumpRotorHallSensor function handles the dialysate outlet \n + * pump rotor hall sensor detection. Calculates rotor speed (in RPM). \n + * Stops pump if there is a pending request to home the pump. + * @details + * Inputs : dopRotorRevStartTime, dopStopAtHomePosition + * Outputs : dopRotorRevStartTime, dialOutPumpRotorSpeedRPM + * @return none + *************************************************************************/ +void signalDialOutPumpRotorHallSensor( void ) +{ + U32 rotTime = getMSTimerCount(); + U32 deltaTime = calcTimeBetween( dopRotorRevStartTime, rotTime ); + + // calculate rotor speed (in RPM) + dialOutPumpRotorSpeedRPM.data = ( 1.0 / (F32)deltaTime ) * (F32)MS_PER_SECOND * (F32)SEC_PER_MIN; + dopRotorRevStartTime = rotTime; + + // if we're supposed to stop pump at home position, stop pump now. + if ( TRUE == dopStopAtHomePosition ) + { + signalDialOutPumpHardStop(); + dopStopAtHomePosition = FALSE; + } +} + +/*********************************************************************//** + * @brief + * The homeDialOutPump function initiates a dialysate outlet pump home operation. + * @details + * Inputs : dialOutPumpState + * Outputs : dopStopAtHomePosition, dopHomeStartTime, dialysate outlet pump started (slow) + * @return none + *************************************************************************/ +BOOL homeDialOutPump( void ) +{ + BOOL result = FALSE; + + if ( DIAL_OUT_PUMP_OFF_STATE == dialOutPumpState ) + { + dopStopAtHomePosition = TRUE; + dopHomeStartTime = getMSTimerCount(); + result = setDialOutPumpTargetRate( DOP_HOME_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + + return result; +} + +/*********************************************************************//** + * @brief * The setDialOutUFVolumes function sets the ultrafiltration reference and \n * measured total volumes (in mL). * @details @@ -343,6 +399,14 @@ checkDialOutPumpMCCurrent(); } + // if homing, check timeout + if ( ( TRUE == dopStopAtHomePosition ) && ( TRUE == didTimeout( dopHomeStartTime, DOP_HOME_TIMEOUT_MS ) ) ) + { + signalDialOutPumpHardStop(); + dopStopAtHomePosition = FALSE; + // TODO - alarm??? + } + publishDialOutFlowData(); } @@ -558,7 +622,7 @@ /*********************************************************************//** * @brief stopDialOutPump - * The stopDialOutPump function sets the dialout flow stop signal and PWM + * The stopDialOutPump function sets the dialout flow stop signal and PWM \n * duty cycle to 0.0. * @details * Inputs : none @@ -587,7 +651,7 @@ } /*********************************************************************//** - * @brief setDialOutPumpDirection + * @brief * The setDialOutPumpDirection function sets the set dialOut pump direction to \n * the given direction. * @details @@ -617,7 +681,7 @@ } /*********************************************************************//** - * @brief publishDialOutFlowData + * @brief * The publishDialOutFlowData function publishes dialysate outlet data at \n * the set interval. * @details @@ -654,7 +718,6 @@ * @details * Inputs : adcDialOutPumpMCSpeedRPM, dialOutPumpDirectionSet, dialOutPumpState * Outputs : none - * @param none * @return none *************************************************************************/ static void checkDialOutPumpDirection( void ) @@ -679,7 +742,6 @@ * @details * Inputs : dialOutPumpState, dopCurrErrorDurationCtr, adcDialOutPumpMCCurrentmA * Outputs : none - * @param none * @return none *************************************************************************/ static void checkDialOutPumpMCCurrent( void ) @@ -863,7 +925,6 @@ * @details * Inputs : dialOutPumpMCSpeedRPM * Outputs : none -* @param none * @return the current dialOut pump speed (in RPM). *************************************************************************/ F32 getMeasuredDialOutPumpMCSpeed( void ) Index: firmware/App/Controllers/DialOutFlow.h =================================================================== diff -u -r04334ed8d1e927939718b1d62fb01afef0a2b9a9 -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a --- firmware/App/Controllers/DialOutFlow.h (.../DialOutFlow.h) (revision 04334ed8d1e927939718b1d62fb01afef0a2b9a9) +++ firmware/App/Controllers/DialOutFlow.h (.../DialOutFlow.h) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) @@ -65,6 +65,8 @@ void setDialOutUFVolumes( F32 refVol, F32 totVol ); void signalDialOutPumpHardStop( void ); +void signalDialOutPumpRotorHallSensor( void ); +BOOL homeDialOutPump( void ); BOOL setNewLoadCellReadings( F32 res1Primary, F32 res1Backup, F32 res2Primary, F32 res2Backup ); Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r9d4666bf3064df18a6d935125d7a69e4e8234e84 -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 9d4666bf3064df18a6d935125d7a69e4e8234e84) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) @@ -1,4 +1,4 @@ -/************************************************************************** +/**********************************************************************//** * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * @@ -26,145 +26,154 @@ #include "SystemCommMessages.h" #include "Utilities.h" +/** + * @addtogroup FPGA + * @{ + */ + // ********** private definitions ********** +/// Enumeration of FPGA states. typedef enum FPGA_States { - FPGA_STATE_START = 0, - FPGA_STATE_READ_HEADER, - FPGA_STATE_RCV_HEADER, - FPGA_STATE_WRITE_ALL_ACTUATORS, - FPGA_STATE_RCV_ALL_SENSORS, - FPGA_STATE_FAILED, - NUM_OF_FPGA_STATES + FPGA_STATE_START = 0, ///< Start state for the FPGA. + FPGA_STATE_READ_HEADER, ///< Read header command state for the FPGA. + FPGA_STATE_RCV_HEADER, ///< Receive header state for the FPGA. + FPGA_STATE_WRITE_ALL_ACTUATORS, ///< Write actuators command state for the FPGA. + FPGA_STATE_RCV_ALL_SENSORS, ///< Receive sensors state for the FPGA. + FPGA_STATE_FAILED, ///< Failed state for the FPGA. + NUM_OF_FPGA_STATES ///< Number of FPGA states. } FPGA_STATE_T; -#define FPGA_PAGE_SIZE 256 -#define FPGA_EXPECTED_ID 0x59 +#define FPGA_PAGE_SIZE 256 ///< FPGA register pages are 256 bytes. +#define FPGA_EXPECTED_ID 0x59 ///< Expected ID for HD FPGA. -#define FPGA_HEADER_START_ADDR 256 // update these after re-arranging w/ Randy -#define FPGA_BULK_READ_START_ADDR 262 -#define FPGA_BULK_WRITE_START_ADDR 2 +#define FPGA_HEADER_START_ADDR 0x0000 ///< Start address for FPGA header data. +#define FPGA_BULK_READ_START_ADDR 0x0100 ///< Start address for FPGA continuous priority reads. +#define FPGA_BULK_WRITE_START_ADDR 0x0008 ///< Start address for FPGA continuous priority writes. -#define FPGA_WRITE_CMD_BUFFER_LEN (FPGA_PAGE_SIZE+8) -#define FPGA_READ_CMD_BUFFER_LEN 8 -#define FPGA_WRITE_RSP_BUFFER_LEN 8 -#define FPGA_READ_RSP_BUFFER_LEN (FPGA_PAGE_SIZE+8) +#define FPGA_WRITE_CMD_BUFFER_LEN (FPGA_PAGE_SIZE+8) ///< FPGA write command buffer byte length. +#define FPGA_READ_CMD_BUFFER_LEN 8 ///< FPGA read command buffer byte length. +#define FPGA_WRITE_RSP_BUFFER_LEN 8 ///< FPGA write command response buffer byte length. +#define FPGA_READ_RSP_BUFFER_LEN (FPGA_PAGE_SIZE+8) ///< FPGA read command response buffer byte length. -#define FPGA_WRITE_CMD_CODE 0x55 -#define FPGA_READ_CMD_CODE 0x5A -#define FPGA_WRITE_CMD_ACK 0xA5 -#define FPGA_READ_CMD_ACK 0xAA -#define FPGA_CMD_NAK 0xEE +#define FPGA_WRITE_CMD_CODE 0x55 ///< FPGA write command code. +#define FPGA_READ_CMD_CODE 0x5A ///< FPGA read command code. +#define FPGA_WRITE_CMD_ACK 0xA5 ///< FPGA write command ACK code. +#define FPGA_READ_CMD_ACK 0xAA ///< FPGA read command ACK code. +#define FPGA_CMD_NAK 0xEE ///< FPGA command NAK code. -#define FPGA_CRC_LEN 2 -#define FPGA_WRITE_CMD_HDR_LEN 4 -#define FPGA_READ_CMD_HDR_LEN 4 -#define FPGA_WRITE_RSP_HDR_LEN 3 -#define FPGA_READ_RSP_HDR_LEN 3 +#define FPGA_CRC_LEN 2 ///< FPGA CRC byte length. +#define FPGA_WRITE_CMD_HDR_LEN 4 ///< FPGA write command header byte length. +#define FPGA_READ_CMD_HDR_LEN 4 ///< FPGA read command header byte length. +#define FPGA_WRITE_RSP_HDR_LEN 3 ///< FPGA write command response header byte length. +#define FPGA_READ_RSP_HDR_LEN 3 ///< FPGA read command response header byte length. -#define SCI2_RECEIVE_DMA_REQUEST 28 -#define SCI2_TRANSMIT_DMA_REQUEST 29 +#define SCI2_RECEIVE_DMA_REQUEST 28 ///< Serial port 2 receive DMA request line. +#define SCI2_TRANSMIT_DMA_REQUEST 29 ///< Serial port 2 transmit DMA request line. -#define MAX_COMM_ERROR_RETRIES 5 +#define MAX_COMM_ERROR_RETRIES 5 ///< Maximum consecutive FPGA communication error retries. // FPGA Sensors Record #pragma pack(push,1) +/// Record structure for FPGA header read. typedef struct { - U08 fpgaId; - U08 fpgaRev; - U16 fpgaControl; - U16 fpgaStatus; + U08 fpgaId; ///< Reg 0. FPGA ID code. Checked against expected value at power up to verify basic FPGA communication and operation. + U08 fpgaRev; ///< Reg 1. FPGA revision being reported. + U16 fpgaControl; ///< Reg 2,3. TBD. + U16 fpgaStatus; ///< Reg 4,5. TBD. } FPGA_HEADER_T; // read only on FPGA +/// Record structure for FPGA continuous priority reads. typedef struct // TODO - add all sensor readings to this structure per FPGA register map { - U08 errorCountProcessor; // 256 - U08 errorCountPC; - U08 bloodFlowMeterDataPktCount; - U08 bloodFlowMeterSlowPktCounts; - F32 bloodFlowLast; // 260 - U08 bloodFlowMeterDeviceStatus; // 264 - U08 bloodFlowMeterResponse; - U08 dialysateFlowMeterDataPktCount; - U08 dialysateFlowMeterSlowPckCounts; - F32 dialysateFlowLast; // 268 - U08 dialysateFlowMeterDeviceStatus; // 272 - U08 dialysateFlowMeterResponse; - U08 bloodFlowMeterErrorCount; - U08 dialysateFlowMeterErrorCount; - U16 bloodOcclusionData; // 276 - U08 bloodOcclusionReadCount; - U08 bloodOcclusionErrorCount; - U16 dialysateInOcclusionData; // 280 - U08 dialysateInOcclusionReadCount; - U08 dialysateInOcclusionErrorCount; - U16 dialysateOutOcclusionData; // 284 - U08 dialysateOutOcclusionReadCount; - U08 dialysateOutOcclusionErrorCount; - U16 bloodPumpHallSensorCount; // 288 - U08 bloodPumpHallSensorStatus; - U08 dialInPumpHallSensorStatus; - U32 adc1Channel0; // 292 - U32 adc1Channel1; // 296 - U32 adc1Channel2; // 300 - U32 adc1Channel3; // 304 - U32 adc1channel4; // 308 - U08 adc1SequenceCount; // 312 - U08 adc1ErrorCount; - U16 accelX; - U16 accelY; // 316 - U16 accelZ; - U16 accelXMax; // 320 - U16 accelYMax; - U16 accelZMax; // 324 - U16 accelFaultRegister; - U16 accelSampleCounter; // 328 - U16 venousPressure; - U16 venousTemperature; // 332 - U08 venousReadCounter; - U08 dialOutPumpSensorStatus; - U16 dialInPumpHallSensorCount; // 336 - U16 dialOutPumpHallSensorCount; + U08 errorCountProcessor; ///< Reg 256. TBD. + U08 errorCountPC; ///< Reg 257. TBD. + U08 bloodFlowMeterDataPktCount; ///< Reg 258. Blood flow sensor data packet count. + U08 bloodFlowMeterSlowPktCounts; ///< Reg 259. Blood flow sensor slow data packet count. + F32 bloodFlowLast; ///< Reg 260. Blood flow rate data. + U08 bloodFlowMeterDeviceStatus; ///< Reg 264. Blood flow sensor status. + U08 bloodFlowMeterResponse; ///< Reg 265. TBD. + U08 dialysateFlowMeterDataPktCount; ///< Reg 266. Dialysate flow sensor data packet count. + U08 dialysateFlowMeterSlowPckCounts; ///< Reg 267. Dialysate flow sensor slow data packet count. + F32 dialysateFlowLast; ///< Reg 268. Dialysate flow rate data. + U08 dialysateFlowMeterDeviceStatus; ///< Reg 272. Dialysate flow sensor status. + U08 dialysateFlowMeterResponse; ///< Reg 273. TBD. + U08 bloodFlowMeterErrorCount; ///< Reg 274. Blood flow sensor error count. + U08 dialysateFlowMeterErrorCount; ///< Reg 275. Dialysate flow sensor error count. + U16 bloodOcclusionData; ///< Reg 276. Blood pump occlusion sensor data. + U08 bloodOcclusionReadCount; ///< Reg 278. Blood pump occlusion sensor read count. + U08 bloodOcclusionErrorCount; ///< Reg 279. Blood pump occlusion sensor error count. + U16 dialysateInOcclusionData; ///< Reg 280. Dialysate inlet pump occlusion sensor data. + U08 dialysateInOcclusionReadCount; ///< Reg 282. Dialysate inlet pump occlusion sensor read count. + U08 dialysateInOcclusionErrorCount; ///< Reg 283. Dialysate inlet pump occlusion sensor error count. + U16 dialysateOutOcclusionData; ///< Reg 284. Dialysate outlet pump occlusion sensor data. + U08 dialysateOutOcclusionReadCount; ///< Reg 286. Dialysate outlet pump occlusion sensor read count. + U08 dialysateOutOcclusionErrorCount; ///< Reg 287. Dialysate outlet pump occlusion sensor error count. + U16 bloodPumpHallSensorCount; ///< Reg 288. Blood pump hall sensor count. + U08 bloodPumpHallSensorStatus; ///< Reg 290. Blood pump hall sensor status. + U08 dialInPumpHallSensorStatus; ///< Reg 291. Dialysate inlet pump hall sensor status. + U32 adc1Channel0; ///< Reg 292. ADC1 channel 0 data. + U32 adc1Channel1; ///< Reg 296. ADC1 channel 1 data. + U32 adc1Channel2; ///< Reg 300. ADC1 channel 2 data. + U32 adc1Channel3; ///< Reg 304. ADC1 channel 3 data. + U32 adc1channel4; ///< Reg 308. ADC1 channel 4 data. + U08 adc1SequenceCount; ///< Reg 312. ADC1 round robin channel sequence count. + U08 adc1ErrorCount; ///< Reg 313. ADC1 error count. + U16 accelX; ///< Reg 314. Accelerometer X axis data. + U16 accelY; ///< Reg 316. Accelerometer Y axis data. + U16 accelZ; ///< Reg 318. Accelerometer Z axis data. + U16 accelXMax; ///< Reg 320. Accelerometer X axis max data (since last read). + U16 accelYMax; ///< Reg 322. Accelerometer Y axis max data (since last read). + U16 accelZMax; ///< Reg 324. Accelerometer Z axis max data (since last read). + U16 accelFaultRegister; ///< Reg 326. Accelerometer fault register. + U16 accelSampleCounter; ///< Reg 328. Accelerometer sample count. + U16 venousPressure; ///< Reg 330. Venous pressure sensor data. + U16 venousTemperature; ///< Reg 332. Venous pressure sensor temperature. + U08 venousReadCounter; ///< Reg 334. Venous pressure sensor read count. + U08 dialOutPumpSensorStatus; ///< Reg 335. Dialysate outlet pump hall sensor status. + U16 dialInPumpHallSensorCount; ///< Reg 336. Dialysate inlet pump hall sensor count. + U16 dialOutPumpHallSensorCount; ///< Reg 338. Dialysate outlet pump hall sensor count. } FPGA_SENSORS_T; +/// Record structure for FPGA continuous priority writes. typedef struct // TODO - add all actuator set points to this structure per FPGA register map { - U08 bloodValveSetState; + U08 bloodValveSetState; ///< Reg 8. Set valve actuator states. } FPGA_ACTUATORS_T; #pragma pack(pop) // ********** private data ********** // FPGA state -static FPGA_STATE_T fpgaState = FPGA_STATE_START; +static FPGA_STATE_T fpgaState = FPGA_STATE_START; ///< Current FPGA state. -static U32 fpgaCommRetryCount = 0; -static U32 fpgaReceiptCounter = 0; -static U32 fpgaTransmitCounter = 0; -static BOOL fpgaWriteCommandInProgress = FALSE; -static BOOL fpgaReadCommandInProgress = FALSE; -static BOOL fpgaBulkWriteAndReadInProgress = FALSE; -static BOOL fpgaWriteCommandResponseReceived = FALSE; -static BOOL fpgaReadCommandResponseReceived = FALSE; +static U32 fpgaCommRetryCount = 0; ///< FPGA communication retry counter. +static U32 fpgaReceiptCounter = 0; ///< FPGA response receipt counter. +static U32 fpgaTransmitCounter = 0; ///< FPGA command transmit counter. +static BOOL fpgaWriteCommandInProgress = FALSE; ///< Flag indicating an FPGA write command is in progress. +static BOOL fpgaReadCommandInProgress = FALSE; ///< Flag indicating an FPGA read command is in progress. +static BOOL fpgaBulkWriteAndReadInProgress = FALSE; ///< Flag indicating an FPGA bulk write and read command are in progress. +static BOOL fpgaWriteCommandResponseReceived = FALSE; ///< Flag indicating a response to an FPGA write command has been received. +static BOOL fpgaReadCommandResponseReceived = FALSE; ///< Flag indicating a response to an FPGA read command has been received. // FPGA comm buffers -static U08 fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_BUFFER_LEN ]; -static U08 fpgaReadCmdBuffer[ FPGA_READ_CMD_BUFFER_LEN ]; -static U08 fpgaWriteResponseBuffer[ FPGA_WRITE_RSP_BUFFER_LEN ]; -static U08 fpgaReadResponseBuffer[ FPGA_READ_RSP_BUFFER_LEN ]; +static U08 fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_BUFFER_LEN ]; ///< FPGA write command buffer. Holds the next FPGA write command to be transmitted. +static U08 fpgaReadCmdBuffer[ FPGA_READ_CMD_BUFFER_LEN ]; ///< FPGA read command buffer. Holds the next FPGA read command to be transmitted. +static U08 fpgaWriteResponseBuffer[ FPGA_WRITE_RSP_BUFFER_LEN ]; ///< FPGA write command response buffer. Memory reserved to capture the response to the last FPGA write command. +static U08 fpgaReadResponseBuffer[ FPGA_READ_RSP_BUFFER_LEN ]; ///< FPGA read command response buffer. Memory reserved to capture the response to the last FPGA read command. // DMA control records -static g_dmaCTRL fpgaDMAWriteControlRecord; -static g_dmaCTRL fpgaDMAWriteRespControlRecord; -static g_dmaCTRL fpgaDMAReadControlRecord; -static g_dmaCTRL fpgaDMAReadRespControlRecord; +static g_dmaCTRL fpgaDMAWriteControlRecord; ///< DMA record for controlling a DMA write command transmission from buffer. +static g_dmaCTRL fpgaDMAWriteRespControlRecord; ///< DMA record for controlling a DMA write command reception to buffer. +static g_dmaCTRL fpgaDMAReadControlRecord; ///< DMA record for controlling a DMA read command transmission from buffer. +static g_dmaCTRL fpgaDMAReadRespControlRecord; ///< DMA record for controlling a DMA read command reception to buffer. // FPGA data -static FPGA_HEADER_T fpgaHeader; -static FPGA_SENSORS_T fpgaSensorReadings; -static FPGA_ACTUATORS_T fpgaActuatorSetPoints; +static FPGA_HEADER_T fpgaHeader; ///< Record of last received FPGA header data. +static FPGA_SENSORS_T fpgaSensorReadings; ///< Record of last received FPGA sensor data. +static FPGA_ACTUATORS_T fpgaActuatorSetPoints; ///< Record of next transmitted FPGA actuator data. // ********** private function prototypes ********** @@ -185,13 +194,12 @@ static void consumeUnexpectedData( void ); -/************************************************************************* - * @brief initFPGA +/*********************************************************************//** + * @brief * The initFPGA function initializes the FPGA module. * @details * Inputs : none * Outputs : FPGA module initialized. - * @param none * @return none *************************************************************************/ void initFPGA( void ) @@ -296,14 +304,13 @@ consumeUnexpectedData(); } -/************************************************************************* - * @brief resetFPGACommFlags +/*********************************************************************//** + * @brief * The resetFPGACommFlags function resets the various fpga comm flags and \n * counters. * @details * Inputs : none * Outputs : fpga comm flags & counters reset - * @param none * @return none *************************************************************************/ static void resetFPGACommFlags( void ) @@ -317,14 +324,13 @@ fpgaReceiptCounter = 0; } -/************************************************************************* - * @brief signalFPGAReceiptCompleted +/*********************************************************************//** + * @brief * The signalFPGAReceiptCompleted function increments a counter to indicate \n * that another DMA receipt from the FPGA has completed. * @details * Inputs : none * Outputs : fpgaReceiptCounter - * @param none * @return none *************************************************************************/ void signalFPGAReceiptCompleted( void ) @@ -353,28 +359,26 @@ } } -/************************************************************************* - * @brief signalFPGATransmitCompleted +/*********************************************************************//** + * @brief * The signalFPGATransmitCompleted function increments a counter to indicate \n * that another DMA transmit to the FPGA has completed. * @details * Inputs : none * Outputs : fpgaReceiptCounter - * @param none * @return none *************************************************************************/ void signalFPGATransmitCompleted( void ) { fpgaTransmitCounter++; } -/************************************************************************* - * @brief execFPGAIn +/*********************************************************************//** + * @brief * The execFPGA function manages incoming data exchanges with the FPGA. * @details * Inputs : fpgaState * Outputs : fpgaState - * @param none * @return none *************************************************************************/ void execFPGAIn( void ) @@ -422,13 +426,12 @@ resetFPGACommFlags(); } -/************************************************************************* - * @brief execFPGAOut +/*********************************************************************//** + * @brief * The execFPGAOut function manages outgoing data exchanges with the FPGA. * @details * Inputs : fpgaState * Outputs : fpgaState - * @param none * @return none *************************************************************************/ void execFPGAOut( void ) @@ -463,14 +466,13 @@ } } -/************************************************************************* - * @brief handleFPGAReadHeaderState +/*********************************************************************//** + * @brief * The handleFPGAReadHeaderState function handles the FPGA state where \n * the read header registers command is sent to the FPGA. * @details * Inputs : none * Outputs : read command sent to FPGA - * @param none * @return next FPGA state *************************************************************************/ static FPGA_STATE_T handleFPGAReadHeaderState( void ) @@ -480,8 +482,8 @@ // construct read command to read 3 registers starting at address 0 fpgaReadCmdBuffer[ 0 ] = FPGA_READ_CMD_CODE; - fpgaReadCmdBuffer[ 1 ] = 0x00; // start at FPGA address 0 - fpgaReadCmdBuffer[ 2 ] = 0x00; + fpgaReadCmdBuffer[ 1 ] = GET_LSB_OF_WORD( FPGA_HEADER_START_ADDR ); + fpgaReadCmdBuffer[ 2 ] = GET_MSB_OF_WORD( FPGA_HEADER_START_ADDR ); fpgaReadCmdBuffer[ 3 ] = sizeof(FPGA_HEADER_T); crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( crc ); @@ -496,14 +498,13 @@ return result; } -/************************************************************************* - * @brief handleFPGAReceiveHeaderState +/*********************************************************************//** + * @brief * The handleFPGAReceiveHeaderState function handles the FPGA state \n * where the header registers read response should be ready to take in. * @details * Inputs : none * Outputs : header register values updated - * @param none * @return next FPGA state *************************************************************************/ static FPGA_STATE_T handleFPGAReceiveHeaderState( void ) @@ -549,14 +550,13 @@ return result; } -/************************************************************************* - * @brief handleFPGAWriteAllActuatorsState +/*********************************************************************//** + * @brief * The handleFPGAWriteAllActuatorsState function handles the FPGA state \n * where the bulk write command is sent to the FPGA. * @details * Inputs : actuator set points * Outputs : actuator set points sent to FPGA - * @param none * @return next FPGA state *************************************************************************/ static FPGA_STATE_T handleFPGAWriteAllActuatorsState( void ) @@ -566,21 +566,23 @@ // construct bulk write command to write actuator data registers starting at address 3 (TODO - change address later) fpgaWriteCmdBuffer[ 0 ] = FPGA_WRITE_CMD_CODE; - fpgaWriteCmdBuffer[ 1 ] = 0x08; // start at FPGA address 8 - fpgaWriteCmdBuffer[ 2 ] = 0x00; + fpgaWriteCmdBuffer[ 1 ] = GET_LSB_OF_WORD( FPGA_BULK_WRITE_START_ADDR ); + fpgaWriteCmdBuffer[ 2 ] = GET_MSB_OF_WORD( FPGA_BULK_WRITE_START_ADDR ); fpgaWriteCmdBuffer[ 3 ] = sizeof(FPGA_ACTUATORS_T); memcpy( &( fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN ] ), &fpgaActuatorSetPoints, sizeof( FPGA_ACTUATORS_T ) ); crc = crc16( fpgaWriteCmdBuffer, FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) ); fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) ] = GET_MSB_OF_WORD( crc ); fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) + 1 ] = GET_LSB_OF_WORD( crc ); + // construct bulk read command to read sensor data registers starting at address 8 fpgaReadCmdBuffer[ 0 ] = FPGA_READ_CMD_CODE; - fpgaReadCmdBuffer[ 1 ] = 0x00; // start at FPGA address 0x100 (256) - fpgaReadCmdBuffer[ 2 ] = 0x01; + fpgaReadCmdBuffer[ 1 ] = GET_LSB_OF_WORD( FPGA_BULK_READ_START_ADDR ); + fpgaReadCmdBuffer[ 2 ] = GET_MSB_OF_WORD( FPGA_BULK_READ_START_ADDR ); fpgaReadCmdBuffer[ 3 ] = sizeof(FPGA_SENSORS_T); crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( crc ); fpgaReadCmdBuffer[ 5 ] = GET_LSB_OF_WORD( crc ); + // prep DMA for sending the bulk write cmd and receiving its response setupDMAForWriteCmd( FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) + FPGA_CRC_LEN ); setupDMAForWriteResp( FPGA_WRITE_RSP_HDR_LEN + FPGA_CRC_LEN ); @@ -597,14 +599,13 @@ return result; } -/************************************************************************* - * @brief handleFPGAReceiveAllSensorsState +/*********************************************************************//** + * @brief * The handleFPGAReceiveAllSensorsState function handles the FPGA state \n * where the bulk read response should be ready to parse. * @details * Inputs : none * Outputs : sensor values updated - * @param none * @return next FPGA state *************************************************************************/ static FPGA_STATE_T handleFPGAReceiveAllSensorsState( void ) @@ -656,13 +657,12 @@ return result; } -/************************************************************************* - * @brief execFPGATest +/*********************************************************************//** + * @brief * The execFPGATest function executes the FPGA self-test. \n * @details * Inputs : fpgaHeader * Outputs : none - * @param none * @return passed, or failed *************************************************************************/ SELF_TEST_STATUS_T execFPGATest( void ) @@ -687,8 +687,8 @@ return result; } -/************************************************************************* - * @brief setupDMAForWriteCmd +/*********************************************************************//** + * @brief * The setupDMAForWriteCmd function sets the byte count for the next DMA \n * write command to the FPGA. * @details @@ -710,14 +710,13 @@ } } -/************************************************************************* - * @brief startDMAWriteCmd +/*********************************************************************//** + * @brief * The startDMAWriteCmd function initiates the DMA transmit for the next \n * DMA write command to the FPGA. * @details * Inputs : none * Outputs : DMA write command to FPGA is initiated - * @param none * @return none *************************************************************************/ static void startDMAWriteCmd( void ) @@ -727,8 +726,8 @@ setSCI2DMATransmitInterrupt(); } -/************************************************************************* - * @brief setupDMAForWriteResp +/*********************************************************************//** + * @brief * The setupDMAForWriteResp function sets the expected byte count for the \n * next DMA write command response from the FPGA. * @details @@ -750,14 +749,13 @@ } } -/************************************************************************* - * @brief startDMAReceiptOfWriteResp +/*********************************************************************//** + * @brief * The startDMAReceiptOfWriteResp function initiates readiness of the DMA \n * receiver for the next DMA write command response from the FPGA. * @details * Inputs : none * Outputs : DMA write command response is ready to be received from the FPGA - * @param none * @return none *************************************************************************/ static void startDMAReceiptOfWriteResp( void ) @@ -767,8 +765,8 @@ setSCI2DMAReceiveInterrupt(); } -/************************************************************************* - * @brief setupDMAForReadCmd +/*********************************************************************//** + * @brief * The setupDMAForReadCmd function sets the byte count for the next DMA \n * read command to the FPGA. * @details @@ -790,14 +788,13 @@ } } -/************************************************************************* - * @brief startDMAReadCmd +/*********************************************************************//** + * @brief * The startDMAReadCmd function initiates the DMA transmit for the next \n * DMA read command to the FPGA. * @details * Inputs : none * Outputs : DMA read command to FPGA is initiated - * @param none * @return none *************************************************************************/ static void startDMAReadCmd( void ) @@ -807,8 +804,8 @@ setSCI2DMATransmitInterrupt(); } -/************************************************************************* - * @brief setupDMAForReadResp +/*********************************************************************//** + * @brief * The setupDMAForReadResp function sets the expected byte count for the \n * next DMA read command response from the FPGA. * @details @@ -830,14 +827,13 @@ } } -/************************************************************************* - * @brief startDMAReceiptOfReadResp +/*********************************************************************//** + * @brief * The startDMAReceiptOfReadResp function initiates readiness of the DMA \n * receiver for the next DMA read command response from the FPGA. * @details * Inputs : none * Outputs : DMA read command response is ready to be received from the FPGA - * @param none * @return none *************************************************************************/ static void startDMAReceiptOfReadResp( void ) @@ -847,23 +843,22 @@ setSCI2DMAReceiveInterrupt(); } -/************************************************************************* - * @brief getFPGAStatus +/*********************************************************************//** + * @brief * The getFPGAStatus function gets the version read from the diagnostic register \n * of the FPGA. * @details * Inputs : fpgaHeader * Outputs : none - * @param none * @return fpgaHeader.fpgaStatus *************************************************************************/ U16 getFPGAStatus( void ) { return fpgaHeader.fpgaStatus; } -/************************************************************************* - * @brief getFPGADiag +/*********************************************************************//** + * @brief * The getFPGADiag function sets the diagnostic register of the FPGA. * @details * Inputs : fpgaHeader @@ -876,114 +871,208 @@ fpgaHeader.fpgaControl = ctrl; } -/************************************************************************* - * @brief getFPGABloodFlow +/*********************************************************************//** + * @brief * The getFPGABloodFlow function gets the latest blood flow reading. * @details * Inputs : fpgaSensorReadings * Outputs : none - * @param none * @return last blood flow reading *************************************************************************/ F32 getFPGABloodFlow( void ) { return fpgaSensorReadings.bloodFlowLast; } -/************************************************************************* - * @brief getFPGADialysateFlow +/*********************************************************************//** + * @brief * The getFPGADialysateFlow function gets the latest dialysate flow reading. * @details * Inputs : fpgaSensorReadings * Outputs : none - * @param none * @return last dialysate flow reading *************************************************************************/ F32 getFPGADialysateFlow( void ) { return fpgaSensorReadings.dialysateFlowLast; } -/************************************************************************* - * @brief getFPGABloodPumpOcclusion +/*********************************************************************//** + * @brief + * The getFPGABloodPumpHallSensorCount function gets the latest blood pump \n + * hall sensor count. Count is a 16 bit free running counter. If counter is \n + * counting up, indicates motor is running in forward direction. If counter is \n + * counting down, indicates motor is running in reverse direction. Counter will \n + * wrap at 0/65535. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @return last blood pump hall sensor count reading. + *************************************************************************/ +U16 getFPGABloodPumpHallSensorCount( void ) +{ + return fpgaSensorReadings.bloodPumpHallSensorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGABloodPumpHallSensorStatus function gets the latest blood pump \n + * hall sensor status. \n + * Bit 0 - Derived direction of the blood pump motor (0=Fwd, 1=Rev) \n + * Bit 1 - A direction error was detected in the current hall sensor phase \n + * Bit 2 - A direction error was detected since the last read of this register + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @return last blood pump hall sensor status reading. + *************************************************************************/ +U08 getFPGABloodPumpHallSensorStatus( void ) +{ + return fpgaSensorReadings.bloodPumpHallSensorStatus; +} + +/*********************************************************************//** + * @brief + * The getFPGADialInPumpHallSensorCount function gets the latest dialysate inlet pump \n + * hall sensor count. Count is a 16 bit free running counter. If counter is \n + * counting up, indicates motor is running in forward direction. If counter is \n + * counting down, indicates motor is running in reverse direction. Counter will \n + * wrap at 0/65535. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @return last dialysate inlet pump hall sensor count reading. + *************************************************************************/ +U16 getFPGADialInPumpHallSensorCount( void ) +{ + return fpgaSensorReadings.dialInPumpHallSensorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialInPumpHallSensorStatus function gets the latest dialysate inlet pump \n + * hall sensor status. \n + * Bit 0 - Derived direction of the dialyste inlet pump motor (0=Fwd, 1=Rev) \n + * Bit 1 - A direction error was detected in the current hall sensor phase \n + * Bit 2 - A direction error was detected since the last read of this register + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @return last dialysate inlet pump hall sensor status reading. + *************************************************************************/ +U08 getFPGADialInPumpHallSensorStatus( void ) +{ + return fpgaSensorReadings.dialInPumpHallSensorStatus; +} + +/*********************************************************************//** + * @brief + * The getFPGADialOutPumpHallSensorCount function gets the latest dialysate outlet pump \n + * hall sensor count. Count is a 16 bit free running counter. If counter is \n + * counting up, indicates motor is running in forward direction. If counter is \n + * counting down, indicates motor is running in reverse direction. Counter will \n + * wrap at 0/65535. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @return last dialysate outlet pump hall sensor count reading. + *************************************************************************/ +U16 getFPGADialOutPumpHallSensorCount( void ) +{ + return fpgaSensorReadings.dialOutPumpHallSensorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialOutPumpHallSensorStatus function gets the latest dialysate outlet pump \n + * hall sensor status. \n + * Bit 0 - Derived direction of the dialysate outlet pump motor (0=Fwd, 1=Rev) \n + * Bit 1 - A direction error was detected in the current hall sensor phase \n + * Bit 2 - A direction error was detected since the last read of this register + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @return last dialysate outlet pump hall sensor status reading. + *************************************************************************/ +U08 getFPGADialOutPumpHallSensorStatus( void ) +{ + return fpgaSensorReadings.dialOutPumpSensorStatus; +} + +/*********************************************************************//** + * @brief * The getFPGABloodPumpOcclusion function gets the latest blood occlusion reading. * @details * Inputs : fpgaSensorReadings * Outputs : none - * @param none * @return last blood occlusion reading *************************************************************************/ U16 getFPGABloodPumpOcclusion( void ) { return fpgaSensorReadings.bloodOcclusionData; } -/************************************************************************* - * @brief getFPGADialInPumpOcclusion +/*********************************************************************//** + * @brief * The getFPGADialInPumpOcclusion function gets the latest dialysate \n * inlet occlusion reading. * @details * Inputs : fpgaSensorReadings * Outputs : none - * @param none * @return last dialysate inlet occlusion reading *************************************************************************/ U16 getFPGADialInPumpOcclusion( void ) { return fpgaSensorReadings.dialysateInOcclusionData; } -/************************************************************************* - * @brief getFPGADialOutPumpOcclusion +/*********************************************************************//** + * @brief * The getFPGADialOutPumpOcclusion function gets the latest dialysate \n * outlet occlusion reading. * @details * Inputs : fpgaSensorReadings * Outputs : none - * @param none * @return last dialysate outlet occlusion reading *************************************************************************/ U16 getFPGADialOutPumpOcclusion( void ) { return fpgaSensorReadings.dialysateOutOcclusionData; } -/************************************************************************* - * @brief getFPGAArterialPressure +/*********************************************************************//** + * @brief * The getFPGAArterialPressure function gets the latest arterial pressure reading. * @details * Inputs : fpgaSensorReadings * Outputs : none - * @param none * @return last arterial pressure reading *************************************************************************/ U16 getFPGAArterialPressure( void ) { return 0; // TODO - return reading when available } -/************************************************************************* - * @brief getFPGAVenousPressure +/*********************************************************************//** + * @brief * The getFPGAVenousPressure function gets the venous arterial pressure reading. * @details * Inputs : fpgaSensorReadings * Outputs : none - * @param none * @return last venous pressure reading *************************************************************************/ U16 getFPGAVenousPressure( void ) { return 0; // TODO - return reading when available } -/************************************************************************* - * @brief consumeUnexpectedData +/*********************************************************************//** + * @brief * The consumeUnexpectedData function checks to see if a byte is sitting in \n * the SCI2 received data register. * @details * Inputs : fpgaHeader * Outputs : none - * @param none * @return fpgaDiag *************************************************************************/ static void consumeUnexpectedData( void ) @@ -997,3 +1086,4 @@ } } +/**@}*/ Index: firmware/App/Services/FPGA.h =================================================================== diff -u -r9b262ba08e3180f121c3cf19d8d25e565183f87d -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision 9b262ba08e3180f121c3cf19d8d25e565183f87d) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) @@ -20,6 +20,16 @@ #include "HDCommon.h" #include "Interrupts.h" +/** + * @defgroup FPGA FPGA + * @brief FPGA service module. + * Maintains latest sensor readings at priority task interval. Updates actuator + * states at priority task interval. + * + * @addtogroup FPGA + * @{ + */ + // ********** public definitions ********** // ********** public function prototypes ********** @@ -34,12 +44,23 @@ U16 getFPGAStatus( void ); void setFPGAControl( U16 ctrl ); + F32 getFPGABloodFlow( void ); F32 getFPGADialysateFlow( void ); + +U16 getFPGABloodPumpHallSensorCount( void ); +U08 getFPGABloodPumpHallSensorStatus( void ); +U16 getFPGADialInPumpHallSensorCount( void ); +U08 getFPGADialInPumpHallSensorStatus( void ); +U16 getFPGADialOutPumpHallSensorCount( void ); +U08 getFPGADialOutPumpHallSensorStatus( void ); + U16 getFPGAArterialPressure( void ); U16 getFPGAVenousPressure( void ); U16 getFPGABloodPumpOcclusion( void ); U16 getFPGADialInPumpOcclusion( void ); U16 getFPGADialOutPumpOcclusion( void ); +/**@}*/ + #endif Index: firmware/App/Services/Interrupts.c =================================================================== diff -u -r9d4666bf3064df18a6d935125d7a69e4e8234e84 -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a --- firmware/App/Services/Interrupts.c (.../Interrupts.c) (revision 9d4666bf3064df18a6d935125d7a69e4e8234e84) +++ firmware/App/Services/Interrupts.c (.../Interrupts.c) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) @@ -329,11 +329,11 @@ break; case HET1_EDGE_DPI_ROTOR_HALL_SENSOR: - //signalDialInPumpRotorHallSensor(); + signalDialInPumpRotorHallSensor(); break; case HET1_EDGE_DPO_ROTOR_HALL_SENSOR: - //signalDialOutPumpRotorHallSensor(); + signalDialOutPumpRotorHallSensor(); break; default: