Index: firmware/App/Controllers/BoostPump.c =================================================================== diff -u --- firmware/App/Controllers/BoostPump.c (revision 0) +++ firmware/App/Controllers/BoostPump.c (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -0,0 +1,648 @@ +/************************************************************************** +* +* Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPBoostDUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file BoostPump.c +* +* @author (last) Sean Nash +* @date (last) 12-Nov-2024 +* +* @author (original) Sean Nash +* @date (original) 12-Nov-2024 +* +***************************************************************************/ + +//#include + +#include "BoostPump.h" +#include "FlowSensor.h" +//#include "NVDataMgmt.h" +#include "Messaging.h" +#include "MessageSupport.h" +#include "OperationModes.h" +#include "PersistentAlarm.h" +#include "PIControllers.h" +#include "Pressure.h" +#include "SafetyShutdown.h" +#include "TaskGeneral.h" +#include "Timers.h" +#include "Utilities.h" + +/** + * @addtogroup BoostPump + * @{ + */ + +// ********** private definitions ********** + +#define BOOST_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the Boost Pump data is published on the CAN bus. +#define BOOST_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the Boost pump is controlled. + +#define BOOST_FLOW_CONTROL_P_COEFFICIENT 0.15F ///< P term for Boost pump flow control. +#define BOOST_FLOW_CONTROL_I_COEFFICIENT 0.65F ///< I term for Boost pump flow control. +#define BOOST_PRESSURE_CONTROL_P_COEFFICIENT 0.01F ///< P term for Boost pump pressure control. +#define BOOST_PRESSURE_CONTROL_I_COEFFICIENT 0.01F ///< I term for Boost pump pressure control. +#define BOOST_PWM_STEP_LIMIT 0.50F ///< Current maximum PWM step limit used in Boost Profiles. +#define BOOST_RAMP_DOWN_DUTY_CYCLE_RATIO 0.03F ///< Pump ramp down duty cycle ratio when the pressure higher than max defined. + +#define BOOST_FLOW_TO_PWM_SLOPE 0.5F ///< Slope of flow to PWM line equation. +#define BOOST_FLOW_TO_PWM_INTERCEPT 0.0F ///< Intercept of flow to PWM line equation. +#define BOOST_PRESSURE_TO_PWM_SLOPE 0.5F ///< Slope of pressure to PWM line equation. +#define BOOST_PRESSURE_TO_PWM_INTERCEPT 0.0F ///< Intercept of pressure to PWM line equation. + +#define DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. + +#define BOOST_FLOW_TO_PWM(flow) ( BOOST_FLOW_TO_PWM_SLOPE * flow + BOOST_FLOW_TO_PWM_INTERCEPT ) ///< PWM line equation for flow. +#define BOOST_PRESSURE_TO_PWM(pres) ( BOOST_PRESSURE_TO_PWM_SLOPE * pres + BOOST_PRESSURE_TO_PWM_INTERCEPT ) ///< PWM line equation for pressure. + + + +/// Enumeration of Boost pump states. +typedef enum BoostPump_States +{ + BOOST_PUMP_OFF_STATE = 0, ///< Boost pump off state. + BOOST_PUMP_CONTROL_TO_TARGET_FLOW_STATE, ///< Boost pump control to target flow state. + BOOST_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE, ///< Boost pump control to max pressure state. + BOOST_PUMP_OPEN_LOOP_STATE, ///< Boost pump open loop state. + NUM_OF_Boost_PUMP_STATES ///< Number of Boost pump states. +} BOOST_PUMP_STATE_T; + +// ********** private data ********** + +static BOOST_PUMP_STATE_T boostPumpState; ///< Current state of pump controller state machine. +static PUMP_CONTROL_MODE_T boostPumpControlMode; ///< Requested pump control mode. +static BOOL isBoostPumpOn; ///< Flag indicating whether pump is currently running. +static BOOL stopPumpRequest; ///< Flag indicating pump stop is requested. +static U32 boostPumpDataPublicationTimerCounter; ///< Used to schedule Boost pump data publication to CAN bus. +static OVERRIDE_U32_T boostPumpDataPublishInterval; ///< Interval (in ms) at which to publish boost pump data to CAN bus. +static U32 boostControlTimerCounter; ///< Determines when to perform control on Boost pump. +static OVERRIDE_F32_T targetBoostPumpFlowRate; ///< Target Boost flow rate (in L/min). +static OVERRIDE_F32_T targetBoostPumpPressure; ///< Target Boost max allowed pressure (in PSI). +static F32 boostPumpDutyCyclePctSet; ///< Currently set Boost pump PWM duty cycle. +static F32 boostPumpOpenLoopTargetDutyCycle; ///< Target Boost pump open loop PWM. +// ********** private function prototypes ********** + +static BOOST_PUMP_STATE_T handleBoostPumpOffState( void ); +static BOOST_PUMP_STATE_T handleBoostPumpControlToTargetFlowState( void ); +static BOOST_PUMP_STATE_T handleBoostPumpControlToTargetPressureState( void ); +static BOOST_PUMP_STATE_T handleBoostPumpOpenLoopState( void ); + +static F32 boostPumpPresToPWM( F32 targetPressure ); +static F32 boostPumpFlowToPWM( F32 targetFlow ); +static void stopBoostPump( void ); +static void publishBoostPumpData( void ); + + +/*********************************************************************//** + * @brief + * The initBoostPump function initializes the Boost Pump module. + * @details \b Inputs: boostPumpState, boostPumpControlMode, isBoostPumpOn, stopPumpRequest, + * boostControlTimerCounter, boostPumpDutyCyclePctSet, boostPumpOpenLoopTargetDutyCycle, boostPumpDataPublicationTimerCounter, + * boostPumpDataPublishInterval, targetBoostPumpFlowRCLOSEDate, targetBoostPumpPressure + * @details \b Outputs: Boost Pump controller unit initialized + * @return none + *************************************************************************/ +void initBoostPump( void ) +{ + initFluidPump(); + + + // Initialize Boost pump PI controller to flow + initializePIController( PI_CONTROLLER_ID_BOOST_PUMP_FLOW, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, BOOST_FLOW_CONTROL_P_COEFFICIENT, BOOST_FLOW_CONTROL_I_COEFFICIENT, + MIN_FLUID_PUMP_DUTY_CYCLE_PCT, MAX_FLUID_PUMP_DUTY_CYCLE_PCT, FALSE, 0 ); + + // Initialize Boost pump PI controller to target pressure + initializePIController( PI_CONTROLLER_ID_BOOST_PUMP_PRES, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, BOOST_PRESSURE_CONTROL_P_COEFFICIENT, BOOST_PRESSURE_CONTROL_I_COEFFICIENT, + MIN_FLUID_PUMP_DUTY_CYCLE_PCT, MAX_FLUID_PUMP_DUTY_CYCLE_PCT, FALSE, 0 ); + + boostPumpState = BOOST_PUMP_OFF_STATE; + boostPumpControlMode = NUM_OF_PUMP_CONTROL_MODES; + isBoostPumpOn = FALSE; + stopPumpRequest = FALSE; + boostControlTimerCounter = 0; + boostPumpDutyCyclePctSet = 0; + boostPumpOpenLoopTargetDutyCycle = 0; + boostPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + boostPumpDataPublishInterval.data = BOOST_DATA_PUB_INTERVAL; + boostPumpDataPublishInterval.ovData = BOOST_CONTROL_INTERVAL; + boostPumpDataPublishInterval.ovInitData = 0; + boostPumpDataPublishInterval.override = OVERRIDE_RESET; + targetBoostPumpFlowRate.data = 0; + targetBoostPumpFlowRate.ovData = 0; + targetBoostPumpFlowRate.ovInitData = 0; + targetBoostPumpFlowRate.override = OVERRIDE_RESET; + targetBoostPumpPressure.data = 0; + targetBoostPumpPressure.ovData = 0; + targetBoostPumpPressure.ovInitData = 0; + targetBoostPumpPressure.override = OVERRIDE_RESET; + + stopBoostPump(); +} + +/*********************************************************************//** + * @brief + * The execBoostPumpController function executes the Boost pump controller. + * @details \b Alarm: ALARM_ID_FP_SOFTWARE_FAULT if pump is in an invalid state + * @details \b Inputs: boostPumpState + * @details \b Outputs: boostPumpState + * @return none + *************************************************************************/ +void execBoostPumpController( void ) +{ + + // Update Boost pump feedback from FPGA + readFluidPumps(); + + switch ( boostPumpState ) + { + case BOOST_PUMP_OFF_STATE: + boostPumpState = handleBoostPumpOffState(); + break; + + case BOOST_PUMP_CONTROL_TO_TARGET_FLOW_STATE: + boostPumpState = handleBoostPumpControlToTargetFlowState(); + break; + + case BOOST_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE: + boostPumpState = handleBoostPumpControlToTargetPressureState(); + break; + + case BOOST_PUMP_OPEN_LOOP_STATE: + boostPumpState = handleBoostPumpOpenLoopState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_RO_INVALID_PUMP_DUTY_CYCLE_SELECTED, boostPumpState ) + boostPumpState = BOOST_PUMP_OFF_STATE; + break; + } + + // Publish Boost pump data on interval + publishBoostPumpData(); +} + +/*********************************************************************//** + * @brief + * The handleBoostPumpOffState function handles the off state of the Boost pump + * state machine. + * @details \b Inputs: isBoostPumpOn, boostPumpControlMode, boostPumpOpenLoopTargetDutyCycle + * @details \b Outputs: isBoostPumpOn, boostPumpDutyCyclePctSet + * @return next state + *************************************************************************/ +static BOOST_PUMP_STATE_T handleBoostPumpOffState( void ) +{ + BOOST_PUMP_STATE_T state = BOOST_PUMP_OFF_STATE; + isBoostPumpOn = FALSE; + + // If there is a target pressure set, transition to the PI controller and control to pressure. + if ( ( getTargetBoostPumpPressure() > 0.0F ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == boostPumpControlMode ) ) + { + // Set pump to on + isBoostPumpOn = TRUE; + boostPumpDutyCyclePctSet = boostPumpPresToPWM( getTargetBoostPumpPressure() ); + setFluidPumpPctToPWMDutyCycle( P40_PUMP, boostPumpDutyCyclePctSet ); + state = BOOST_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE; + } + + // If there is a target flow set, transition to the PI controller and control to flow + else if ( ( getTargetBoostPumpFlowRateLPM() > 0.0F ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == boostPumpControlMode ) ) + { + // Set pump to on + isBoostPumpOn = TRUE; + boostPumpDutyCyclePctSet = boostPumpFlowToPWM( getTargetBoostPumpFlowRateLPM() ); + setFluidPumpPctToPWMDutyCycle( P40_PUMP, boostPumpDutyCyclePctSet ); + state = BOOST_PUMP_CONTROL_TO_TARGET_FLOW_STATE; + } + // If the target duty cycle is greater than zero (minimum is 10%) and the mode has been set to open + // loop, set the duty cycle + else if ( ( boostPumpOpenLoopTargetDutyCycle > 0.0F ) && ( PUMP_CONTROL_MODE_OPEN_LOOP == boostPumpControlMode ) ) + { + setFluidPumpPctToPWMDutyCycle( P40_PUMP, boostPumpOpenLoopTargetDutyCycle ); + boostPumpDutyCyclePctSet = boostPumpOpenLoopTargetDutyCycle; + isBoostPumpOn = TRUE; + state = BOOST_PUMP_OPEN_LOOP_STATE; + } + return state; +} + +/*********************************************************************//** + * @brief + * The handleBoostPumpOpenLoopState function handles the open loop control + * state of the Boost pump state machine. + * @details \b Inputs: stopPumpRequest, boostPumpControlMode, + * boostPumpDutyCyclePctSet + * @details \b Outputs: boostPumpState, stopPumpRequest + * @return next state + *************************************************************************/ +static BOOST_PUMP_STATE_T handleBoostPumpOpenLoopState( void ) +{ + BOOST_PUMP_STATE_T state = BOOST_PUMP_OPEN_LOOP_STATE; + + if ( TRUE == stopPumpRequest ) + { + stopPumpRequest = FALSE; + state = BOOST_PUMP_OFF_STATE; + } + // If there is a target pressure set, transition to the PI controller and control to pressure. + if ( ( getTargetBoostPumpPressure() > 0.0F ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == boostPumpControlMode ) ) + { + //transition to closed loop + resetPIController( PI_CONTROLLER_ID_BOOST_PUMP_PRES, boostPumpDutyCyclePctSet, 0 ); + state = BOOST_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE; + } + + // If there is a target flow set, transition to the PI controller and control to flow + else if ( ( getTargetBoostPumpFlowRateLPM() > 0.0F ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == boostPumpControlMode ) ) + { + ///transition to closed loop + resetPIController( PI_CONTROLLER_ID_BOOST_PUMP_FLOW, boostPumpDutyCyclePctSet, 0 ); + state = BOOST_PUMP_CONTROL_TO_TARGET_FLOW_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBoostPumpControlToTargetFlowState function handles the control to + * target flow state of the Boost pump controller state machine. + * @details Inputs: boostPumpPWMDutyCyclePctSet, boostControlTimerCounter + * @details Outputs: boostPumpPWMDutyCyclePctSet, boostControlTimerCounter + * @return next state of the controller state machine + *************************************************************************/ +static BOOST_PUMP_STATE_T handleBoostPumpControlToTargetFlowState( void ) +{ + BOOST_PUMP_STATE_T state = BOOST_PUMP_CONTROL_TO_TARGET_FLOW_STATE; + + // Control at set interval + if ( ( ++boostControlTimerCounter >= BOOST_CONTROL_INTERVAL ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == boostPumpControlMode ) ) + { + boostPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_BOOST_PUMP_FLOW, getTargetBoostPumpFlowRateLPM(), getFlowRate( P7_FLOW ) ); + setFluidPumpPctToPWMDutyCycle( P12_PUMP, boostPumpDutyCyclePctSet ); + boostControlTimerCounter = 0; + + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBoostPumpControlToMaxPressureState function handles the control + * to target pressure state of the Boost pump controller state machine. + * @details Inputs: boostPumpPWMDutyCyclePctSet, boostControlTimerCounter + * @details Outputs: boostPumpPWMDutyCyclePctSet, boostControlTimerCounter + * @return next state of the controller state machine + *************************************************************************/ +static BOOST_PUMP_STATE_T handleBoostPumpControlToTargetPressureState( void ) +{ + BOOST_PUMP_STATE_T state = BOOST_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE; + + // Control at set interval + if ( ( ++boostControlTimerCounter >= BOOST_CONTROL_INTERVAL ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == boostPumpControlMode ) ) + { + boostPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_BOOST_PUMP_PRES, getTargetBoostPumpPressure(), getFilteredPressure( M3_PRES ) ); + setFluidPumpPctToPWMDutyCycle( P12_PUMP, boostPumpDutyCyclePctSet ); + boostControlTimerCounter = 0; + + } + + return state; +} + +/*********************************************************************//** + * @brief + * The setBoostPumpTargetFlowRate function sets a new target flow rate for the + * Boost pump. + * @details Inputs: boostPumpOpenLoopTargetDutyCycle + * @details Outputs: targetBoostPumpFlowRate, boostPumpControlMode, boostPumpDutyCyclePctSet, + * boostControlTimerCounter, isBoostPumpOn + * @param boostFlowRate which is target Boost flow rate in mL/min + * @return TRUE if new target flow rate is set successfully, FALSE if not + *************************************************************************/ +BOOL setBoostPumpTargetFlowRateLPM( F32 boostFlowRate ) +{ + BOOL result = FALSE; + + // First of all, the flow rate must be in range + if ( ( boostFlowRate <= MAX_BOOST_FLOWRATE_LPM ) && ( boostFlowRate >= MIN_BOOST_FLOWRATE_LPM ) ) + { + targetBoostPumpFlowRate.data = boostFlowRate; + boostPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; + // Get the initial guess of the duty cycle + boostPumpDutyCyclePctSet = boostPumpFlowToPWM( getTargetBoostPumpFlowRateLPM() ); + boostControlTimerCounter = 0; + isBoostPumpOn = TRUE; + + // Clear previous target data + if ( getTargetBoostPumpPressure() > 0.0F ) + { + targetBoostPumpPressure.data = 0; + } + if ( boostPumpOpenLoopTargetDutyCycle > 0.0F ) + { + boostPumpOpenLoopTargetDutyCycle = 0; + } + result = TRUE; + } + // Requested flow rate is out of range + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, boostFlowRate ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setBoostPumpTargetPressure function sets a new target pressure for the + * Boost pump. + * @details Inputs: boostPumpOpenLoopTargetDutyCycle, targetBoostPumpFlowRate + * @details Outputs: boostPumpOpenLoopTargetDutyCycle, targetBoostPumpFlowRate, isBoostPumpOn, + * boostControlTimerCounter, boostPumpDutyCyclePctSet, boostPumpControlMode, targetBoostPumpPressure + * @param boostPressure which is target Boost pressure + * @return TRUE if new target flow rate is set successfully, FALSE if not + *************************************************************************/ +BOOL setBoostPumpTargetPressure( F32 boostPressure ) +{ + BOOL result = FALSE; + + // First of all, the pressure must be in range + if ( ( boostPressure <= MAX_BOOST_PRESSURE_PSI ) && ( boostPressure >= MIN_BOOST_PRESSURE_PSI ) ) + { + targetBoostPumpPressure.data = boostPressure; + boostPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; + // Get the initial guess of the duty cycle + boostPumpDutyCyclePctSet = boostPumpPresToPWM( getTargetBoostPumpPressure() ); + boostControlTimerCounter = 0; + isBoostPumpOn = TRUE; + // Clear previous target data + if ( getTargetBoostPumpFlowRateLPM() > 0.0F ) + { + targetBoostPumpFlowRate.data = 0; + } + if ( boostPumpOpenLoopTargetDutyCycle > 0.0F ) + { + boostPumpOpenLoopTargetDutyCycle = 0; + } + result = TRUE; + } + // Requested flow rate is out of range + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PRESSURE_SELECTED, boostPressure ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setBoostPumpTargetDutyCycle function sets the duty cycle that the + * pump should run. + * @details Inputs: boostPumpOpenLoopTargetDutyCycle, boostPumpPWMDutyCyclePct, + * targetBoostPumpPressure, targetBoostPumpFlowRate + * @details Outputs: boostPumpOpenLoopTargetDutyCycle + * boostPumpControlMode, targetBoostPumpFlowRate, targetBoostPumpPressure + * @param duty which is the duty cycle + * @return none + *************************************************************************/ +BOOL setBoostPumpTargetDutyCycle( F32 dutyCycle ) +{ + BOOL status = FALSE; + + if ( ( dutyCycle >= MIN_FLUID_PUMP_DUTY_CYCLE_PCT ) && ( dutyCycle <= MAX_FLUID_PUMP_DUTY_CYCLE_PCT ) ) + { + boostPumpOpenLoopTargetDutyCycle = dutyCycle; + boostPumpControlMode = BOOST_PUMP_OPEN_LOOP_STATE; + status = TRUE; + + // Set the new duty cycle of the pump + setFluidPumpPctToPWMDutyCycle( P12_PUMP, boostPumpOpenLoopTargetDutyCycle ); + // Clear previous target data + if ( getTargetBoostPumpFlowRateLPM() > 0.0F ) + { + targetBoostPumpFlowRate.data = 0; + } + if ( getTargetBoostPumpPressure() > 0.0F ) + { + targetBoostPumpPressure.data = 0; + } + } + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_RO_INVALID_PUMP_DUTY_CYCLE_SELECTED, dutyCycle ) + } + + return status; +} + +/*********************************************************************//** + * @brief + * The getTargetBoostPumpPressure function gets the current target Boost pump + * pressure. + * @details Inputs: targetBoostPumpPressure + * @details Outputs: none + * @return the current target Boost pressure in PSI + *************************************************************************/ +F32 getTargetBoostPumpPressure( void ) +{ + F32 pressure = getF32OverrideValue( &targetBoostPumpPressure ); + + return pressure; +} + +/*********************************************************************//** + * @brief + * The getTargetBoostPumpFlowRateLPM function gets the current target Boost pump + * flow rate. + * @details Inputs: targetBoostPumpFlowRate + * @details Outputs: none + * @return the current target Boost flow rate (in L/min). + *************************************************************************/ +F32 getTargetBoostPumpFlowRateLPM( void ) +{ + F32 flowRate = getF32OverrideValue( &targetBoostPumpFlowRate ); + + return flowRate; +} + +/*********************************************************************//** + * @brief + * The boostPumpPresToPWM function calculates the duty cycle for the given target + * pressure. + * @details Inputs: none + * @details Outputs: dutyCyclePct + * @return the current target Boost pump PWM in a percentage. + *************************************************************************/ +static F32 boostPumpPresToPWM( F32 targetPressure ) +{ + F32 dutyCyclePct = BOOST_PRESSURE_TO_PWM( targetPressure ); + + return dutyCyclePct; +} + +/*********************************************************************//** + * @brief + * The boostPumpFlowToPWM function calculates the duty cycle for the given target + * flow rate. + * @details Inputs: none + * @details Outputs: dutyCyclePct + * @return the current target Boost pump PWM in a percentage. + *************************************************************************/ +static F32 boostPumpFlowToPWM( F32 targetFlow ) +{ + F32 dutyCyclePct = BOOST_FLOW_TO_PWM( targetFlow ); + + return dutyCyclePct; +} + +/*********************************************************************//** + * @brief + * The signalBoostPumpStop function stops the P12 pump immediately and + * resets all the variables associated with the P12 pump run. + * @details \b Inputs: boostPumpState[] + * @details \b Outputs: stopPumpRequest[] + * @param pumpID ID of boost pump to stop + * @return none + *************************************************************************/ +void signalBoostPumpHardStop( void ) +{ + + if( targetBoostPumpFlowRate.data > 0.0F ) + { + targetBoostPumpFlowRate.data = 0.0; + resetPIController( PI_CONTROLLER_ID_BOOST_PUMP_FLOW, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, 0 ); + } + + if( targetBoostPumpPressure.data > 0.0F ) + { + targetBoostPumpPressure.data = 0.0; + resetPIController( PI_CONTROLLER_ID_BOOST_PUMP_PRES, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, 0 ); + } + + boostPumpState = BOOST_PUMP_OFF_STATE; + boostPumpDutyCyclePctSet = 0; + boostControlTimerCounter = 0; + boostPumpOpenLoopTargetDutyCycle = 0; + stopBoostPump(); +} + +/*********************************************************************//** + * @brief + * The stopBoostPump function sets the P40 pump duty cycle to zero. + * @details Inputs: isBoostPumpOn, boostPumpPWMDutyCyclePctSet + * @details Outputs: isBoostPumpOn, boostPumpPWMDutyCyclePctSet + * @return none + *************************************************************************/ +static void stopBoostPump( void ) +{ + isBoostPumpOn = FALSE; + boostPumpDutyCyclePctSet = 0.0; + // Set the new duty cycle of the pump + setFluidPumpPWMDutyCycle( P40_PUMP, 0 ); +} + +/*********************************************************************//** + * @brief + * The isBoostPumpRunning function returns the on/off status of P12 pump. + * @details Inputs: isBoostPumpOn + * @details Outputs: none + * @return isBoostPumpOn the boolean flag that is TRUE if the pump is on and + * FALSE if it is off + *************************************************************************/ +BOOL isBoostPumpRunning( void ) +{ + return isBoostPumpOn; +} +/*********************************************************************//** + * @brief + * The publishBoostPumpData function publishes p12 pump data at the set interval. + * @details \b Message \b Sent: + * @details \b Inputs: boostPumpDataPublicationTimerCounter + * @details \b Outputs: boostPumpDataPublicationTimerCounter + * @return none + *************************************************************************/ +static void publishBoostPumpData( void ) +{ + // publish Boost pump data on interval + if ( ++boostPumpDataPublicationTimerCounter >= getU32OverrideValue( &boostPumpDataPublishInterval ) ) + { + BOOST_PUMP_DATA_T pumpData; + + pumpData.p40PumpState = (U32)boostPumpState; + pumpData.p40PumpDutyCycle = (U32)getFluidPumpPWMDutyCycle( P40_PUMP ); + pumpData.p40PumpFBDutyCycle = (U32)getFluidPumpReadPWMDutyCycle( P40_PUMP ); + pumpData.p40PumpSpeed = getFluidPumpRPM( P40_PUMP ); + pumpData.p40TargetPressure = getTargetBoostPumpPressure(); + pumpData.p40TargetFlow = getTargetBoostPumpFlowRateLPM(); + pumpData.p40TargetDutyCycle = boostPumpOpenLoopTargetDutyCycle; + + broadcastData( MSG_ID_FP_BOOST_PUMP_DATA, COMM_BUFFER_OUT_CAN_RO_BROADCAST, (U08*)&pumpData, sizeof( BOOST_PUMP_DATA_T ) ); + boostPumpDataPublicationTimerCounter = 0; + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testBoostPumpDataPublishIntervalOverride function overrides the Boost pump + * data publish interval. + * @details Inputs: boostPumpDataPublishInterval + * @details Outputs: boostPumpDataPublishInterval + * @param message Override message from Dialin which includes the value + * that override boost pump data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testBoostPumpDataPublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = u32BroadcastIntervalOverride( message, &boostPumpDataPublishInterval, TASK_GENERAL_INTERVAL ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testBoostPumpDataPublishIntervalOverride function overrides the Boost pump + * data publish interval. + * @details Inputs: boostPumpDataPublishInterval + * @details Outputs: boostPumpDataPublishInterval + * @param message Override message from Dialin which includes the value + * that override boost pump data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testBoostPumpTargetPressureOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &targetBoostPumpPressure ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testBoostPumpDataPublishIntervalOverride function overrides the Boost pump + * data publish interval. + * @details Inputs: boostPumpDataPublishInterval + * @details Outputs: boostPumpDataPublishInterval + * @param message Override message from Dialin which includes the value + * that override boost pump data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testBoostPumpTargetFlowOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &targetBoostPumpFlowRate ); + + return result; +} + + +/**@}*/ Index: firmware/App/Controllers/BoostPump.h =================================================================== diff -u --- firmware/App/Controllers/BoostPump.h (revision 0) +++ firmware/App/Controllers/BoostPump.h (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -0,0 +1,75 @@ +/************************************************************************** +* +* Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPBoostDUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file BoostPump.h +* +* @author (last) Sean Nash +* @date (last) 12-Nov-2024 +* +* @author (original) Sean Nash +* @date (original) 12-Nov-2024 +* +***************************************************************************/ + +#ifndef __BOOSTPUMP_H__ +#define __BOOSTPUMP_H__ + + +#include "FluidPump.h" +#include "FPCommon.h" + +/** + * @defgroup BoostPump BoostPump + * @brief Boost Pump controller unit. Controls and monitors the Boost pump. + * The diaphragm (Boost) pump is manufactured by Aquatec, PN: 5889-2MM1-V724DY. + * + * @addtogroup BoostPump + * @{ + */ + +// ********** public definitions ********** + +#define MAX_BOOST_FLOWRATE_LPM 1.5F ///< Maximum target Boost flow rate in L/min. +#define MIN_BOOST_FLOWRATE_LPM 0.0F ///< Minimum target Boost flow rate in L/min. +#define MAX_BOOST_PRESSURE_PSI 40.0F ///< Maximum allowed pressure that the Boost pump can go to. +#define MIN_BOOST_PRESSURE_PSI 10.0F ///< Minimum allowed pressure that the Boost pump can go to. + +/// Boost pump data record. +typedef struct +{ + U32 p40PumpState; ///< Boost pump current state. + U32 p40PumpDutyCycle; ///< Boost pump duty cycle. + U32 p40PumpFBDutyCycle; ///< Boost pump feedback duty cycle. + F32 p40PumpSpeed; ///< Boost pump speed (RPM). + F32 p40TargetPressure; ///< Boost pump target pressure for control. + F32 p40TargetFlow; ///< Boost pump target flow ( in L/min ) for control. + F32 p40TargetDutyCycle; ///< Boost pump target duty cycle for open loop control. +} BOOST_PUMP_DATA_T; + +// ********** public function prototypes ********** + +void initBoostPump( void ); +void execBoostPumpController( void ); + +void signalBoostPumpStop( void ); +BOOL isBoostPumpRunning( void ); + +BOOL setBoostPumpTargetFlowRateLPM( F32 roFlowRate ); +BOOL setBoostPumpTargetPressure( F32 roPressure ); +BOOL setBoostPumpTargetDutyCycle( F32 duty ); + +F32 getBoostFeedbackDutyCycle( void ); +F32 getTargetBoostPumpFlowRateLPM( void ); +F32 getTargetBoostPumpPressure( void ); + +BOOL testBoostPumpDataPublishIntervalOverride( MESSAGE_T *message ); + + + +/**@}*/ + +#endif Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r2ac0ed667ccf0d77a65905157af9badbd19007cd -r17a448770daa138ebeb6ce79974966e650828f25 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 2ac0ed667ccf0d77a65905157af9badbd19007cd) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -17,14 +17,14 @@ //#include -//#include "FlowSensors.h" +#include "FlowSensor.h" //#include "NVDataMgmt.h" #include "Messaging.h" #include "MessageSupport.h" #include "OperationModes.h" #include "PersistentAlarm.h" -//#include "PIControllers.h" -//#include "Pressures.h" +#include "PIControllers.h" +#include "Pressure.h" #include "ROPump.h" #include "SafetyShutdown.h" #include "TaskGeneral.h" @@ -38,115 +38,146 @@ // ********** private definitions ********** -#define RO_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO Pump data is published on the CAN bus. -#define ROP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO pump is controlled. +#define RO_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO Pump data is published on the CAN bus. +#define ROP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO pump is controlled. -//#define ROP_FLOW_CONTROL_P_COEFFICIENT 0.15F ///< P term for RO pump flow control. -//#define ROP_FLOW_CONTROL_I_COEFFICIENT 0.65F ///< I term for RO pump flow control. -//#define ROP_MAX_PRESSURE_P_COEFFICIENT 0.01F ///< P term for RO pump max pressure control. -//#define ROP_MAX_PRESSURE_I_COEFFICIENT 0.01F ///< I term for RO pump max pressure control. -//#define ROP_PWM_STEP_LIMIT 0.50F ///< Current maximum PWM step limit used in RO Profiles. +#define ROP_FLOW_CONTROL_P_COEFFICIENT 0.15F ///< P term for RO pump flow control. +#define ROP_FLOW_CONTROL_I_COEFFICIENT 0.65F ///< I term for RO pump flow control. +#define ROP_PRESSURE_CONTROL_P_COEFFICIENT 0.01F ///< P term for RO pump pressure control. +#define ROP_PRESSURE_CONTROL_I_COEFFICIENT 0.01F ///< I term for RO pump pressure control. +#define ROP_PWM_STEP_LIMIT 0.50F ///< Current maximum PWM step limit used in RO Profiles. +#define ROP_RAMP_DOWN_DUTY_CYCLE_RATIO 0.03F ///< Pump ramp down duty cycle ratio when the pressure higher than max defined. -#define DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. +#define ROP_FLOW_TO_PWM_SLOPE 0.5F ///< Slope of flow to PWM line equation. +#define ROP_FLOW_TO_PWM_INTERCEPT 0.0F ///< Intercept of flow to PWM line equation. +#define ROP_PRESSURE_TO_PWM_SLOPE 0.5F ///< Slope of pressure to PWM line equation. +#define ROP_PRESSURE_TO_PWM_INTERCEPT 0.0F ///< Intercept of pressure to PWM line equation. +#define DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. + +#define ROP_FLOW_TO_PWM(flow) ( ROP_FLOW_TO_PWM_SLOPE * flow + ROP_FLOW_TO_PWM_INTERCEPT ) ///< PWM line equation for flow. +#define ROP_PRESSURE_TO_PWM(pres) ( ROP_PRESSURE_TO_PWM_SLOPE * pres + ROP_PRESSURE_TO_PWM_INTERCEPT ) ///< PWM line equation for pressure. + + + /// Enumeration of RO pump states. typedef enum ROPump_States { - RO_PUMP_OFF_STATE = 0, ///< RO pump off state. - RO_PUMP_OPEN_LOOP_STATE, ///< RO pump open loop state. - NUM_OF_RO_PUMP_STATES ///< Number of RO pump states. + RO_PUMP_OFF_STATE = 0, ///< RO pump off state. + RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE, ///< RO pump control to target flow state. + RO_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE, ///< RO pump control to max pressure state. + RO_PUMP_OPEN_LOOP_STATE, ///< RO pump open loop state. + NUM_OF_RO_PUMP_STATES ///< Number of RO pump states. } RO_PUMP_STATE_T; -/// Enumeration of RO pump self-test states. -//typedef enum ROPump_Self_Test_States -//{ -// RO_PUMP_SELF_TEST_STATE_START = 0, ///< RO pump self-test start state. -// RO_PUMP_TEST_STATE_IN_PROGRESS, ///< RO pump self-tests in progress state. -// RO_PUMP_TEST_STATE_COMPLETE, ///< RO pump self-tests completed state. -// NUM_OF_RO_PUMP_SELF_TEST_STATES ///< Number of RO pump self-test states. -//} RO_PUMP_SELF_TEST_STATE_T; - // ********** private data ********** -static RO_PUMP_STATE_T roPumpState[ NUM_OF_BOOST_PUMPS ]; ///< Current state of pump controller state machine. -static PUMP_CONTROL_MODE_T roPumpControlMode[ NUM_OF_BOOST_PUMPS ]; ///< Requested pump control mode. -static BOOL isROPumpOn[ NUM_OF_BOOST_PUMPS ]; ///< Flag indicating whether pump is currently running. -static BOOL stopPumpRequest[ NUM_OF_BOOST_PUMPS ]; ///< Flag indicating pump stop is requested. -static U32 roPumpDataPublicationTimerCounter; ///< Used to schedule RO pump data publication to CAN bus. -static OVERRIDE_U32_T roPumpDataPublishInterval; ///< Interval (in ms) at which to publish boost pump data to CAN bus. -static U32 roControlTimerCounter; ///< Determines when to perform control on RO pump. -static U32 roPumpControlInterval; ///< RO pump Control interval. - +static RO_PUMP_STATE_T roPumpState; ///< Current state of pump controller state machine. +static PUMP_CONTROL_MODE_T roPumpControlMode; ///< Requested pump control mode. +static BOOL isROPumpOn; ///< Flag indicating whether pump is currently running. +static BOOL stopPumpRequest; ///< Flag indicating pump stop is requested. +static U32 roPumpDataPublicationTimerCounter; ///< Used to schedule RO pump data publication to CAN bus. +static OVERRIDE_U32_T roPumpDataPublishInterval; ///< Interval (in ms) at which to publish boost pump data to CAN bus. +static U32 roControlTimerCounter; ///< Determines when to perform control on RO pump. +static OVERRIDE_F32_T targetROPumpFlowRate; ///< Target RO flow rate (in L/min). +static OVERRIDE_F32_T targetROPumpPressure; ///< Target RO max allowed pressure (in PSI). +static F32 roPumpDutyCyclePctSet; ///< Currently set RO pump PWM duty cycle. +static F32 roPumpOpenLoopTargetDutyCycle; ///< Target RO pump open loop PWM. // ********** private function prototypes ********** -static RO_PUMP_STATE_T handleROPumpOffState( RO_BOOST_PUMP_T pumpID ); -static RO_PUMP_STATE_T handleROPumpOpenLoopState( RO_BOOST_PUMP_T pumpID ); +static RO_PUMP_STATE_T handleROPumpOffState( void ); +static RO_PUMP_STATE_T handleROPumpControlToTargetFlowState( void ); +static RO_PUMP_STATE_T handleROPumpControlToTargetPressureState( void ); +static RO_PUMP_STATE_T handleROPumpOpenLoopState( void ); +static F32 roPumpPresToPWM( F32 targetPressure ); +static F32 roPumpFlowToPWM( F32 targetFlow ); +static void stopROPump( void ); static void publishROPumpData( void ); + /*********************************************************************//** * @brief * The initROPump function initializes the RO Pump module. - * @details \b Inputs: none + * @details \b Inputs: roPumpState, roPumpControlMode, isROPumpOn, stopPumpRequest, + * roControlTimerCounter, roPumpDutyCyclePctSet, roPumpOpenLoopTargetDutyCycle, roPumpDataPublicationTimerCounter, + * roPumpDataPublishInterval, targetROPumpFlowRate, targetROPumpPressure * @details \b Outputs: RO Pump controller unit initialized * @return none *************************************************************************/ void initROPump( void ) { - U32 pump; + initFluidPump(); - initBoostPump(); - // Initialize the variables - for ( pump = 0; pump < NUM_OF_BOOST_PUMPS; pump++ ) - { - roPumpState[ pump ] = RO_PUMP_OFF_STATE; - roPumpControlMode[ pump ] = NUM_OF_PUMP_CONTROL_MODES; - isROPumpOn[ pump ] = FALSE; - stopPumpRequest[ pump ] = FALSE; - } - roPumpControlInterval = ROP_CONTROL_INTERVAL; - roControlTimerCounter = 0; - roPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - roPumpDataPublishInterval.data = RO_PUMP_DATA_PUB_INTERVAL; - roPumpDataPublishInterval.ovData = RO_PUMP_DATA_PUB_INTERVAL; - roPumpDataPublishInterval.ovInitData = 0; - roPumpDataPublishInterval.override = OVERRIDE_RESET; + // Initialize RO pump PI controller to flow + initializePIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, ROP_FLOW_CONTROL_P_COEFFICIENT, ROP_FLOW_CONTROL_I_COEFFICIENT, + MIN_FLUID_PUMP_DUTY_CYCLE_PCT, MAX_FLUID_PUMP_DUTY_CYCLE_PCT, FALSE, 0 ); + + // Initialize RO pump PI controller to target pressure + initializePIController( PI_CONTROLLER_ID_RO_PUMP_PRES, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, ROP_PRESSURE_CONTROL_P_COEFFICIENT, ROP_PRESSURE_CONTROL_I_COEFFICIENT, + MIN_FLUID_PUMP_DUTY_CYCLE_PCT, MAX_FLUID_PUMP_DUTY_CYCLE_PCT, FALSE, 0 ); + + roPumpState = RO_PUMP_OFF_STATE; + roPumpControlMode = NUM_OF_PUMP_CONTROL_MODES; + isROPumpOn = FALSE; + stopPumpRequest = FALSE; + roControlTimerCounter = 0; + roPumpDutyCyclePctSet = 0; + roPumpOpenLoopTargetDutyCycle = 0; + roPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + roPumpDataPublishInterval.data = RO_PUMP_DATA_PUB_INTERVAL; + roPumpDataPublishInterval.ovData = RO_PUMP_DATA_PUB_INTERVAL; + roPumpDataPublishInterval.ovInitData = 0; + roPumpDataPublishInterval.override = OVERRIDE_RESET; + targetROPumpFlowRate.data = 0; + targetROPumpFlowRate.ovData = 0; + targetROPumpFlowRate.ovInitData = 0; + targetROPumpFlowRate.override = OVERRIDE_RESET; + targetROPumpPressure.data = 0; + targetROPumpPressure.ovData = 0; + targetROPumpPressure.ovInitData = 0; + targetROPumpPressure.override = OVERRIDE_RESET; + + stopROPump(); } /*********************************************************************//** * @brief * The execROPumpController function executes the RO pump controller. - * @details \b Alarm: ALARM_ID_RO_SOFTWARE_FAULT if pump is in an invalid state - * @details \b Inputs: roPumpState[] - * @details \b Outputs: roPumpState[] + * @details \b Alarm: ALARM_ID_FP_SOFTWARE_FAULT if pump is in an invalid state + * @details \b Inputs: roPumpState + * @details \b Outputs: roPumpState * @return none *************************************************************************/ void execROPumpController( void ) { - RO_BOOST_PUMP_T pump; // Update RO pump feedback from FPGA - readBoostPumps(); + readFluidPumps(); - // Execute pump control state machine for each boost pump - for ( pump = (RO_BOOST_PUMP_T)0; pump < NUM_OF_BOOST_PUMPS; pump++ ) + switch ( roPumpState ) { - switch ( roPumpState[ pump ] ) - { - case RO_PUMP_OFF_STATE: - roPumpState[ pump ] = handleROPumpOffState( pump ); - break; + case RO_PUMP_OFF_STATE: + roPumpState = handleROPumpOffState(); + break; - case RO_PUMP_OPEN_LOOP_STATE: - roPumpState[ pump ] = handleROPumpOpenLoopState( pump ); - break; + case RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE: + roPumpState = handleROPumpControlToTargetFlowState(); + break; - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_EXEC_STATE, roPumpState[ pump ] ) - roPumpState[ pump ] = RO_PUMP_OFF_STATE; - break; - } + case RO_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE: + roPumpState = handleROPumpControlToTargetPressureState(); + break; + + case RO_PUMP_OPEN_LOOP_STATE: + roPumpState = handleROPumpOpenLoopState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_RO_INVALID_PUMP_DUTY_CYCLE_SELECTED, roPumpState ) + roPumpState = RO_PUMP_OFF_STATE; + break; } // Publish RO pump data on interval @@ -157,69 +188,380 @@ * @brief * The handleROPumpOffState function handles the off state of the RO pump * state machine. - * @details \b Inputs: none - * @details \b Outputs: none - * @param pumpID ID of boost pump to handle off state for + * @details \b Inputs: isROPumpOn, roPumpControlMode, roPumpOpenLoopTargetDutyCycle + * @details \b Outputs: isROPumpOn, roPumpDutyCyclePctSet * @return next state *************************************************************************/ -static RO_PUMP_STATE_T handleROPumpOffState( RO_BOOST_PUMP_T pumpID ) +static RO_PUMP_STATE_T handleROPumpOffState( void ) { - RO_PUMP_STATE_T state = RO_PUMP_OFF_STATE; + RO_PUMP_STATE_T state = RO_PUMP_OFF_STATE; + isROPumpOn = FALSE; + // If there is a target pressure set, transition to the PI controller and control to pressure. + if ( ( getTargetROPumpPressure() > 0.0F ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) ) + { + // Set pump to on + isROPumpOn = TRUE; + roPumpDutyCyclePctSet = roPumpPresToPWM( getTargetROPumpPressure() ); + setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); + state = RO_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE; + } + + // If there is a target flow set, transition to the PI controller and control to flow + else if ( ( getTargetROPumpFlowRateLPM() > 0.0F ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) ) + { + // Set pump to on + isROPumpOn = TRUE; + roPumpDutyCyclePctSet = roPumpFlowToPWM( getTargetROPumpFlowRateLPM() ); + setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); + state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; + } + // If the target duty cycle is greater than zero (minimum is 10%) and the mode has been set to open + // loop, set the duty cycle + else if ( ( roPumpOpenLoopTargetDutyCycle > 0.0F ) && ( PUMP_CONTROL_MODE_OPEN_LOOP == roPumpControlMode ) ) + { + setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpOpenLoopTargetDutyCycle ); + roPumpDutyCyclePctSet = roPumpOpenLoopTargetDutyCycle; + isROPumpOn = TRUE; + state = RO_PUMP_OPEN_LOOP_STATE; + } return state; } /*********************************************************************//** * @brief * The handleROPumpOpenLoopState function handles the open loop control * state of the RO pump state machine. - * @details \b Inputs: stopPumpRequest[] - * @details \b Outputs: roPumpState[], stopPumpRequest[] - * @param pumpID ID of boost pump to handle open loop control state for + * @details \b Inputs: stopPumpRequest, roPumpControlMode, + * roPumpDutyCyclePctSet + * @details \b Outputs: roPumpState, stopPumpRequest * @return next state *************************************************************************/ -static RO_PUMP_STATE_T handleROPumpOpenLoopState( RO_BOOST_PUMP_T pumpID ) +static RO_PUMP_STATE_T handleROPumpOpenLoopState( void ) { RO_PUMP_STATE_T state = RO_PUMP_OPEN_LOOP_STATE; - if ( TRUE == stopPumpRequest[ pumpID ] ) + if ( TRUE == stopPumpRequest ) { - stopPumpRequest[ pumpID ] = FALSE; - roPumpState[ pumpID ] = RO_PUMP_OFF_STATE; + stopPumpRequest = FALSE; + state = RO_PUMP_OFF_STATE; } + // If there is a target pressure set, transition to the PI controller and control to pressure. + if ( ( getTargetROPumpPressure() > 0.0F ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) ) + { + //transition to closed loop + resetPIController( PI_CONTROLLER_ID_RO_PUMP_PRES, roPumpDutyCyclePctSet, 0 ); + state = RO_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE; + } + // If there is a target flow set, transition to the PI controller and control to flow + else if ( ( getTargetROPumpFlowRateLPM() > 0.0F ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) ) + { + ///transition to closed loop + resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet, 0 ); + state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; + } + return state; } /*********************************************************************//** * @brief - * The signalROPumpStop function stops the RO pump immediately and - * resets all the variables associated with the RO pump run. - * @details \b Alarm: ALARM_ID_RO_SOFTWARE_FAULT if invalid pump ID given - * @details \b Inputs: roPumpState[] - * @details \b Outputs: stopPumpRequest[] - * @param pumpID ID of boost pump to stop + * The handleROPumpControlToTargetFlowState function handles the control to + * target flow state of the RO pump controller state machine. + * @details Inputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter + * @details Outputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter + * @return next state of the controller state machine + *************************************************************************/ +static RO_PUMP_STATE_T handleROPumpControlToTargetFlowState( void ) +{ + RO_PUMP_STATE_T state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; + + // Control at set interval + if ( ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) ) + { + roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, getTargetROPumpFlowRateLPM(), getFlowRate( P16_FLOW ) ); + setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); + roControlTimerCounter = 0; + + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleROPumpControlToMaxPressureState function handles the control + * to target pressure state of the RO pump controller state machine. + * @details Inputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter + * @details Outputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter + * @return next state of the controller state machine + *************************************************************************/ +static RO_PUMP_STATE_T handleROPumpControlToTargetPressureState( void ) +{ + RO_PUMP_STATE_T state = RO_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE; + + // Control at set interval + if ( ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL ) && ( PUMP_CONTROL_MODE_CLOSED_LOOP == roPumpControlMode ) ) + { + roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_PRES, getTargetROPumpPressure(), getFilteredPressure( P17_PRES ) ); + setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); + roControlTimerCounter = 0; + + } + + return state; +} + +/*********************************************************************//** + * @brief + * The setROPumpTargetFlowRate function sets a new target flow rate for the + * RO pump. + * @details Inputs: roPumpOpenLoopTargetDutyCycle + * @details Outputs: targetROPumpFlowRate, roPumpControlMode, roPumpDutyCyclePctSet, + * roControlTimerCounter, isROPumpOn + * @param roFlowRate which is target RO flow rate in mL/min + * @return TRUE if new target flow rate is set successfully, FALSE if not + *************************************************************************/ +BOOL setROPumpTargetFlowRateLPM( F32 roFlowRate ) +{ + BOOL result = FALSE; + + // First of all, the flow rate must be in range + if ( ( roFlowRate <= MAX_RO_FLOWRATE_LPM ) && ( roFlowRate >= MIN_RO_FLOWRATE_LPM ) ) + { + targetROPumpFlowRate.data = roFlowRate; + roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; + // Get the initial guess of the duty cycle + roPumpDutyCyclePctSet = roPumpFlowToPWM( getTargetROPumpFlowRateLPM() ); + roControlTimerCounter = 0; + isROPumpOn = TRUE; + + // Clear previous target data + if ( getTargetROPumpPressure() > 0.0F ) + { + targetROPumpPressure.data = 0; + } + if ( roPumpOpenLoopTargetDutyCycle > 0.0F ) + { + roPumpOpenLoopTargetDutyCycle = 0; + } + result = TRUE; + } + // Requested flow rate is out of range + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, roFlowRate ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setROPumpTargetPressure function sets a new target pressure for the + * RO pump. + * @details Inputs: roPumpOpenLoopTargetDutyCycle, targetROPumpFlowRate + * @details Outputs: roPumpOpenLoopTargetDutyCycle, targetROPumpFlowRate, isROPumpOn, + * roControlTimerCounter, roPumpDutyCyclePctSet, roPumpControlMode, targetROPumpPressure + * @param roPressure which is target RO pressure + * @return TRUE if new target flow rate is set successfully, FALSE if not + *************************************************************************/ +BOOL setROPumpTargetPressure( F32 roPressure ) +{ + BOOL result = FALSE; + + // First of all, the pressure must be in range + if ( ( roPressure <= MAX_RO_PRESSURE_PSI ) && ( roPressure >= MIN_RO_PRESSURE_PSI ) ) + { + targetROPumpPressure.data = roPressure; + roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; + // Get the initial guess of the duty cycle + roPumpDutyCyclePctSet = roPumpPresToPWM( getTargetROPumpPressure() ); + roControlTimerCounter = 0; + isROPumpOn = TRUE; + // Clear previous target data + if ( getTargetROPumpFlowRateLPM() > 0.0F ) + { + targetROPumpFlowRate.data = 0; + } + if ( roPumpOpenLoopTargetDutyCycle > 0.0F ) + { + roPumpOpenLoopTargetDutyCycle = 0; + } + result = TRUE; + } + // Requested flow rate is out of range + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PRESSURE_SELECTED, roPressure ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setROPumpTargetDutyCycle function sets the duty cycle that the + * pump should run. + * @details Inputs: roPumpOpenLoopTargetDutyCycle, roPumpPWMDutyCyclePct, + * targetROPumpPressure, targetROPumpFlowRate + * @details Outputs: roPumpOpenLoopTargetDutyCycle + * roPumpControlMode, targetROPumpFlowRate, targetROPumpPressure + * @param duty which is the duty cycle * @return none *************************************************************************/ -void signalROPumpStop( RO_BOOST_PUMP_T pumpID ) +BOOL setROPumpTargetDutyCycle( F32 dutyCycle ) { - if ( pumpID < NUM_OF_BOOST_PUMPS ) + BOOL status = FALSE; + + if ( ( dutyCycle >= MIN_FLUID_PUMP_DUTY_CYCLE_PCT ) && ( dutyCycle <= MAX_FLUID_PUMP_DUTY_CYCLE_PCT ) ) { - setBoostPumpPWMDutyCycle( pumpID, 0 ); // stop pump immediately - if ( roPumpState[ pumpID ] != RO_PUMP_OFF_STATE ) + roPumpOpenLoopTargetDutyCycle = dutyCycle; + roPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; + status = TRUE; + + // Set the new duty cycle of the pump + setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpOpenLoopTargetDutyCycle ); + // Clear previous target data + if ( getTargetROPumpFlowRateLPM() > 0.0F ) { - stopPumpRequest[ pumpID ] = TRUE; // set stop request so state machine goes to off state + targetROPumpFlowRate.data = 0; } + if ( getTargetROPumpPressure() > 0.0F ) + { + targetROPumpPressure.data = 0; + } } else { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PUMP_ID1, (U32)pumpID ) + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_RO_INVALID_PUMP_DUTY_CYCLE_SELECTED, dutyCycle ) } + + return status; } /*********************************************************************//** * @brief - * The publishROPumpData function publishes RO pump data at the set interval. + * The getTargetROPumpPressure function gets the current target RO pump + * pressure. + * @details Inputs: targetROPumpPressure + * @details Outputs: none + * @return the current target RO pressure in PSI + *************************************************************************/ +F32 getTargetROPumpPressure( void ) +{ + F32 pressure = getF32OverrideValue( &targetROPumpPressure ); + + return pressure; +} + +/*********************************************************************//** + * @brief + * The getTargetROPumpFlowRateMLPM function gets the current target RO pump + * flow rate. + * @details Inputs: targetROPumpFlowRate + * @details Outputs: none + * @return the current target RO flow rate (in L/min). + *************************************************************************/ +F32 getTargetROPumpFlowRateLPM( void ) +{ + F32 flowRate = getF32OverrideValue( &targetROPumpFlowRate ); + + return flowRate; +} + +/*********************************************************************//** + * @brief + * The roPumpPresToPWM function calculates the duty cycle for the given target + * pressure. + * @details Inputs: none + * @details Outputs: dutyCyclePct + * @return the current target RO pump PWM in a percentage. + *************************************************************************/ +static F32 roPumpPresToPWM( F32 targetPressure ) +{ + F32 dutyCyclePct = ROP_PRESSURE_TO_PWM( targetPressure ); + + return dutyCyclePct; +} + +/*********************************************************************//** + * @brief + * The roPumpFlowToPWM function calculates the duty cycle for the given target + * flow rate. + * @details Inputs: none + * @details Outputs: dutyCyclePct + * @return the current target RO pump PWM in a percentage. + *************************************************************************/ +static F32 roPumpFlowToPWM( F32 targetFlow ) +{ + F32 dutyCyclePct = ROP_FLOW_TO_PWM( targetFlow ); + + return dutyCyclePct; +} + +/*********************************************************************//** + * @brief + * The signalROPumpStop function stops the P12 pump immediately and + * resets all the variables associated with the P12 pump run. + * @details \b Inputs: roPumpState[] + * @details \b Outputs: stopPumpRequest[] + * @param pumpID ID of boost pump to stop + * @return none + *************************************************************************/ +void signalROPumpHardStop( void ) +{ + + if( targetROPumpFlowRate.data > 0.0F ) + { + targetROPumpFlowRate.data = 0.0; + resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, 0 ); + } + + if( targetROPumpPressure.data > 0.0F ) + { + targetROPumpPressure.data = 0.0; + resetPIController( PI_CONTROLLER_ID_RO_PUMP_PRES, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, 0 ); + } + + roPumpState = RO_PUMP_OFF_STATE; + roPumpDutyCyclePctSet = 0; + roControlTimerCounter = 0; + roPumpOpenLoopTargetDutyCycle = 0; + stopROPump(); +} + +/*********************************************************************//** + * @brief + * The stopROPump function sets the P12 pump duty cycle to zero. + * @details Inputs: isROPumpOn, roPumpPWMDutyCyclePctSet + * @details Outputs: isROPumpOn, roPumpPWMDutyCyclePctSet + * @return none + *************************************************************************/ +static void stopROPump( void ) +{ + isROPumpOn = FALSE; + roPumpDutyCyclePctSet = 0.0; + // Set the new duty cycle of the pump + setFluidPumpPWMDutyCycle( P12_PUMP, 0 ); +} + +/*********************************************************************//** + * @brief + * The isROPumpRunning function returns the on/off status of P12 pump. + * @details Inputs: isROPumpOn + * @details Outputs: none + * @return isROPumpOn the boolean flag that is TRUE if the pump is on and + * FALSE if it is off + *************************************************************************/ +BOOL isROPumpRunning( void ) +{ + return isROPumpOn; +} +/*********************************************************************//** + * @brief + * The publishROPumpData function publishes p12 pump data at the set interval. * @details \b Message \b Sent: * @details \b Inputs: roPumpDataPublicationTimerCounter * @details \b Outputs: roPumpDataPublicationTimerCounter @@ -232,16 +574,15 @@ { RO_PUMP_DATA_T pumpData; - pumpData.p12PumpState = (U32)roPumpState[ P12_PUMP ]; - pumpData.p12PumpDutyCycle = (U32)getBoostPumpPWMDutyCycle( P12_PUMP ); - pumpData.p12PumpFBDutyCycle = (U32)getBoostPumpReadPWMDutyCycle( P12_PUMP ); - pumpData.p12PumpSpeed = getBoostPumpRPM( P12_PUMP ); - pumpData.p40PumpState = (U32)roPumpState[ P40_PUMP ]; - pumpData.p40PumpDutyCycle = (U32)getBoostPumpPWMDutyCycle( P40_PUMP ); - pumpData.p40PumpFBDutyCycle = (U32)getBoostPumpReadPWMDutyCycle( P40_PUMP ); - pumpData.p40PumpSpeed = getBoostPumpRPM( P40_PUMP ); + pumpData.p12PumpState = (U32)roPumpState; + pumpData.p12PumpDutyCycle = (U32)getFluidPumpPWMDutyCycle( P12_PUMP ); + pumpData.p12PumpFBDutyCycle = (U32)getFluidPumpReadPWMDutyCycle( P12_PUMP ); + pumpData.p12PumpSpeed = getFluidPumpRPM( P12_PUMP ); + pumpData.p12TargetPressure = getTargetROPumpPressure(); + pumpData.p12TargetFlow = getTargetROPumpFlowRateLPM(); + pumpData.p12TargetDutyCycle = roPumpOpenLoopTargetDutyCycle; - broadcastData( MSG_ID_RO_PUMP_DATA, COMM_BUFFER_OUT_CAN_RO_BROADCAST, (U08*)&pumpData, sizeof( RO_PUMP_DATA_T ) ); + broadcastData( MSG_ID_FP_RO_PUMP_DATA, COMM_BUFFER_OUT_CAN_RO_BROADCAST, (U08*)&pumpData, sizeof( RO_PUMP_DATA_T ) ); roPumpDataPublicationTimerCounter = 0; } } @@ -269,4 +610,39 @@ return result; } +/*********************************************************************//** + * @brief + * The testROPumpDataPublishIntervalOverride function overrides the RO pump + * data publish interval. + * @details Inputs: roPumpDataPublishInterval + * @details Outputs: roPumpDataPublishInterval + * @param message Override message from Dialin which includes the value + * that override ro pump data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testROPumpTargetPressureOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &targetROPumpPressure ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testROPumpDataPublishIntervalOverride function overrides the RO pump + * data publish interval. + * @details Inputs: roPumpDataPublishInterval + * @details Outputs: roPumpDataPublishInterval + * @param message Override message from Dialin which includes the value + * that override ro pump data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testROPumpTargetFlowOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &targetROPumpFlowRate ); + + return result; +} + + /**@}*/ Index: firmware/App/Controllers/ROPump.h =================================================================== diff -u -r2ac0ed667ccf0d77a65905157af9badbd19007cd -r17a448770daa138ebeb6ce79974966e650828f25 --- firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 2ac0ed667ccf0d77a65905157af9badbd19007cd) +++ firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -18,9 +18,10 @@ #ifndef __RO_PUMP_H__ #define __RO_PUMP_H__ -#include "ROCommon.h" -#include "BoostPump.h" +#include "FluidPump.h" +#include "FPCommon.h" + /** * @defgroup ROPump ROPump * @brief RO Pump controller unit. Controls and monitors the RO pump. @@ -32,28 +33,43 @@ // ********** public definitions ********** +#define MAX_RO_FLOWRATE_LPM 1.5F ///< Maximum target RO flow rate in L/min. +#define MIN_RO_FLOWRATE_LPM 0.0F ///< Minimum target RO flow rate in L/min. +#define MAX_RO_PRESSURE_PSI 120.0F ///< Maximum allowed pressure that the RO pump can go to. +#define MIN_RO_PRESSURE_PSI 10.0F ///< Minimum allowed pressure that the RO pump can go to. + /// RO pump data record. typedef struct { U32 p12PumpState; ///< RO pump current state. U32 p12PumpDutyCycle; ///< RO pump duty cycle. U32 p12PumpFBDutyCycle; ///< RO pump feedback duty cycle. F32 p12PumpSpeed; ///< RO pump speed (RPM). - U32 p40PumpState; ///< Boost pump current state. - U32 p40PumpDutyCycle; ///< Boost pump duty cycle. - U32 p40PumpFBDutyCycle; ///< Boost pump feedback duty cycle. - F32 p40PumpSpeed; ///< Boost pump speed (RPM). + F32 p12TargetPressure; ///< RO pump target pressure for control. + F32 p12TargetFlow; ///< RO pump target flow ( in L/min ) for control. + F32 p12TargetDutyCycle; ///< RO pump target duty cycle for open loop control. } RO_PUMP_DATA_T; // ********** public function prototypes ********** void initROPump( void ); void execROPumpController( void ); -void signalROPumpStop( RO_BOOST_PUMP_T pumpID ); +void signalROPumpHardStop( void ); +BOOL isROPumpRunning( void ); +BOOL setROPumpTargetFlowRateLPM( F32 roFlowRate ); +BOOL setROPumpTargetPressure( F32 roPressure ); +BOOL setROPumpTargetDutyCycle( F32 duty ); + +F32 getROFeedbackDutyCycle( void ); +F32 getTargetROPumpFlowRateLPM( void ); +F32 getTargetROPumpPressure( void ); + BOOL testROPumpDataPublishIntervalOverride( MESSAGE_T *message ); + + /**@}*/ #endif Fisheye: Tag 17a448770daa138ebeb6ce79974966e650828f25 refers to a dead (removed) revision in file `firmware/App/Drivers/BoostPump.c'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 17a448770daa138ebeb6ce79974966e650828f25 refers to a dead (removed) revision in file `firmware/App/Drivers/BoostPump.h'. Fisheye: No comparison available. Pass `N' to diff? Index: firmware/App/Drivers/FluidPump.c =================================================================== diff -u --- firmware/App/Drivers/FluidPump.c (revision 0) +++ firmware/App/Drivers/FluidPump.c (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -0,0 +1,363 @@ +/************************************************************************** +* +* Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file FluidPump.c +* +* @author (last) Sean Nash +* @date (last) 12-Nov-2024 +* +* @author (original) Sean Nash +* @date (original) 12-Nov-2024 +* +***************************************************************************/ + +#include "FluidPump.h" +#include "FpgaRO.h" +#include "Messaging.h" +#include "MessageSupport.h" +#include "PersistentAlarm.h" +#include "Timers.h" +#include "Utilities.h" + +/** + * @addtogroup FluidPump + * @{ + */ + +// ********** private definitions ********** + +#define FLUID_PUMP_COUNTS_2_RPM_NUMERATOR 1500000.0F ///< Numerator in counts to RPM conversion. +#define FLUID_PUMP_COUNTS_FOR_STOPPED_PUMP 0xFFFF ///< FPGA will report FFFF counts when pump is stopped. + +/// Payload record structure for fluid pump set PWM request +typedef struct +{ + U32 pumpID; ///< Pump ID + U32 pwm; ///< Pump PWM magnitude (0..500). +} FLUID_PUMP_CMD_PAYLOAD_T; + +// ********** private data ********** + +static U16 fluidPumpCmdDutyCycle[ NUM_OF_PUMPS ]; ///< Commanded duty cycles for fluid pumps. +static OVERRIDE_U32_T fluidPumpReadDutyCycle[ NUM_OF_PUMPS ]; ///< Fluid pump duty cycles read back from FPGA. +static OVERRIDE_F32_T fluidPumpMeasRPM[ NUM_OF_PUMPS ]; ///< Fluid pump measured speeds (RPM). + +// ********** private function prototypes ********** + +/*********************************************************************//** + * @brief + * The initFluidPump function initializes the Fluid Pump driver unit. + * @details \b Inputs: none + * @details \b Outputs: Fluid pump unit initialized. + * @return none + *************************************************************************/ +void initFluidPump( void ) +{ + U32 pump; + + // initialize duty cycles and measured speeds + for ( pump = 0; pump < NUM_OF_PUMPS; pump++ ) + { + fluidPumpCmdDutyCycle[ pump ] = 0; + fluidPumpReadDutyCycle[ pump ].data = 0; + fluidPumpReadDutyCycle[ pump ].ovData = 0; + fluidPumpReadDutyCycle[ pump ].ovInitData = 0; + fluidPumpReadDutyCycle[ pump ].override = OVERRIDE_RESET; + fluidPumpMeasRPM[ pump ].data = 0.0F; + fluidPumpMeasRPM[ pump ].ovData = 0.0F; + fluidPumpMeasRPM[ pump ].ovInitData = 0.0F; + fluidPumpMeasRPM[ pump ].override = OVERRIDE_RESET; + } + + // set RO pump to stop + setFPGAP12PumpPWM( 0 ); + + // TODO set fluid pump to stop +} + +/*********************************************************************//** + * @brief + * The readFluidPumps function reads the PWM and tach counts for each fluid pump. + * @details \b Inputs: none + * @details \b Outputs: fluidPumpReadDutyCycle[], fluidPumpMeasRPM[] + * @return none + *************************************************************************/ +void readFluidPumps( void ) +{ + U32 tach; + + // get latest RO pump duty cycle read back from FPGA + fluidPumpReadDutyCycle[ P12_PUMP ].data = getFPGAP12PumpPWM(); + + // get latest RO pump tachometer count from FPGA and convert to RPM + tach = (U32)getFPGAP12PumpTachCount(); + if ( ( tach != 0 ) && ( tach < FLUID_PUMP_COUNTS_FOR_STOPPED_PUMP ) ) + { + fluidPumpMeasRPM[ P12_PUMP ].data = FLUID_PUMP_COUNTS_2_RPM_NUMERATOR / (F32)tach; + } + else + { + fluidPumpMeasRPM[ P12_PUMP ].data = 0.0F; + } + + // TODO - get latest for fluider pump PWM and tach +} + +/*********************************************************************//** + * @brief + * The setFluidPumpPctToPWMDutyCycle function sets the commanded PWM percentage + * for the given fluid pump. + * @details \b Alarm: ALARM_ID_RO_SOFTWARE_FAULT if invalid fluid pump ID given. + * @details \b Inputs: none + * @details \b Outputs: none + * @param pumpID ID of fluid pump to set commanded PWM magnitude for. + * @param dutyCyclePct Value (0..0.99) indicating magnitude of PWM duty cycle to set + * @return TRUE if duty cycle set successfully, FALSE if not + *************************************************************************/ +BOOL setFluidPumpPctToPWMDutyCycle( FP_FLUID_PUMP_T pumpID, F32 dutyCyclePct) +{ + BOOL result = FALSE; + U16 pwmCnt = 0; + if ( pumpID < NUM_OF_PUMPS ) + { + pwmCnt = convertDutyCyclePctToCnt( dutyCyclePct ); + result = setFluidPumpPWMDutyCycle (pumpID, pwmCnt); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_FLUID_PUMP_ID1, (U32)pumpID ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setFluidPumpPWMDutyCycle function sets the commanded PWM magnitude (0..500) + * for the given fluid pump. + * @details \b Alarm: ALARM_ID_RO_SOFTWARE_FAULT if invalid fluid pump ID given. + * @details \b Inputs: none + * @details \b Outputs: fluidPumpCmdDutyCycle[] + * @param pumpID ID of fluid pump to set commanded PWM magnitude for. + * @param pwm Value (0..500) indicating magnitude of PWM duty cycle to set + * @return TRUE if duty cycle set successfully, FALSE if not + *************************************************************************/ +BOOL setFluidPumpPWMDutyCycle( FP_FLUID_PUMP_T pumpID, U16 pwm ) +{ + BOOL result = FALSE; + + if ( pumpID < NUM_OF_PUMPS ) + { + // enable/disable pump per given PWM + if ( P12_PUMP == pumpID ) + { + if ( 0 == pwm ) + { + setFPGAP12PumpEnable( FALSE ); + } + else + { + setFPGAP12PumpEnable( TRUE ); + } + } + else + { + if ( 0 == pwm ) + { + setFPGAP40PumpEnable( FALSE ); + } + else + { + setFPGAP40PumpEnable( TRUE ); + } + } + + // constrain given pwm magnitude to valid range + pwm = MIN( pwm, MAX_FLUID_PUMP_PWM_DUTY_CYCLE ); + // set commanded duty cycle for given fluid pump to given pwm magnitude + fluidPumpCmdDutyCycle[ pumpID ] = pwm; + if ( P12_PUMP == pumpID ) + { + setFPGAP12PumpPWM( pwm ); + } + else + { + setFPGAP12PumpPWM( pwm ); + } + result = TRUE; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_FLUID_PUMP_ID1, (U32)pumpID ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getFluidPumpPWMDutyCycle function gets the commanded PWM magnitude (0..500) + * for the given fluid pump. + * @details \b Alarm: ALARM_ID_RO_SOFTWARE_FAULT if invalid fluid pump ID given. + * @details \b Inputs: fluidPumpCmdDutyCycle[] + * @details \b Outputs: none + * @param pumpID ID of fluid pump to get commanded PWM magnitude for. + * @return Value (0..500) indicating magnitude of PWM duty cycle + *************************************************************************/ +U16 getFluidPumpPWMDutyCycle( FP_FLUID_PUMP_T pumpID ) +{ + U16 result = 0; + + if ( pumpID < NUM_OF_PUMPS ) + { + result = fluidPumpCmdDutyCycle[ pumpID ]; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_FLUID_PUMP_ID2, (U32)pumpID ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getFluidPumpReadPWMDutyCycle function gets the PWM magnitude (0..500) + * read back from FPGA for the given fluid pump. + * @details \b Alarm: ALARM_ID_RO_SOFTWARE_FAULT if invalid fluid pump ID given. + * @details \b Inputs: fluidPumpReadDutyCycle[] + * @details \b Outputs: none + * @param pumpID ID of fluid pump to get read back PWM magnitude for. + * @return Value (0..500) indicating magnitude of PWM duty cycle + *************************************************************************/ +U16 getFluidPumpReadPWMDutyCycle( FP_FLUID_PUMP_T pumpID ) +{ + U16 result = 0; + + if ( pumpID < NUM_OF_PUMPS ) + { + result = (U16)getU32OverrideValue( &fluidPumpReadDutyCycle[ pumpID ] ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_FLUID_PUMP_ID3, (U32)pumpID ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getFluidPumpRPM function gets the measured speed (RPM) for the given + * fluid pump. + * @details \b Alarm: ALARM_ID_RO_SOFTWARE_FAULT if invalid fluid pump ID given. + * @details \b Inputs: fluidPumpMeasRPM[] + * @details \b Outputs: none + * @param pumpID ID of fluid pump to get measured speed for. + * @return measured pump speed (RPM) for the given pump + *************************************************************************/ +F32 getFluidPumpRPM( FP_FLUID_PUMP_T pumpID ) +{ + F32 result = 0.0F; + + if ( pumpID < NUM_OF_PUMPS ) + { + result = (U16)getF32OverrideValue( &fluidPumpMeasRPM[ pumpID ] ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_FLUID_PUMP_ID4, (U32)pumpID ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The convertDutyCyclePctToCnt function converts a duty cycle percentage + * into counts to set the PWM magnitude. + * @details Inputs: none + * @details Outputs: none + * @param dutyCyclePct duty cycle percentage to be converted. + * @return Value (0..500) indicating magnitude of PWM duty cycle. + *************************************************************************/ +U16 convertDutyCyclePctToCnt( F32 dutyCyclePct ) +{ + U16 pwmCnt = (U16)MAX( (MAX_FLUID_PUMP_PWM_DUTY_CYCLE * dutyCyclePct) , MIN_FLUID_PUMP_PWM_DUTY_CYCLE ); + + return pwmCnt; +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetFluidPumpPWM function sets a given fluid pump to a given PWM + * value. + * @details \b Inputs: none + * @details \b Outputs: fluidPumpCmdDutyCycle[] + * @param message Override message from Dialin which includes an ID of + * the pump to override and the PWM to override the pump to. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetFluidPumpPWM( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + if ( sizeof( FLUID_PUMP_CMD_PAYLOAD_T ) == message->hdr.payloadLen ) + { + FLUID_PUMP_CMD_PAYLOAD_T payload; + + memcpy( &payload, &message->payload[0], sizeof( FLUID_PUMP_CMD_PAYLOAD_T ) ); + result = setFluidPumpPWMDutyCycle( (FP_FLUID_PUMP_T)payload.pumpID, (U16)payload.pwm ); + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testFluidPumpPWMOverride function overrides the measured PWM of the + * given fluid pump. + * @details \b Inputs: none + * @details \b Outputs: fluidPumpReadDutyCycle[] + * @param message Override message from Dialin which includes an ID of + * the fluid pump to override PWM for and the PWM to override the pump to. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testFluidPumpPWMOverride( MESSAGE_T *message ) +{ + BOOL result = u32ArrayOverride( message, &fluidPumpReadDutyCycle[0], NUM_OF_PUMPS - 1, 0, MAX_FLUID_PUMP_PWM_DUTY_CYCLE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testFluidPumpRPMOverride function overrides the measured speed (RPM) + * of the given fluid pump. + * @details \b Inputs: none + * @details \b Outputs: fluidPumpMeasRPM[] + * @param message Override message from Dialin which includes an ID of + * the fluid pump to override speed for and the speed to override the pump to. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testFluidPumpRPMOverride( MESSAGE_T *message ) +{ + BOOL result = f32ArrayOverride( message, &fluidPumpMeasRPM[0], NUM_OF_PUMPS - 1 ); + + return result; +} + +/**@}*/ Index: firmware/App/Drivers/FluidPump.h =================================================================== diff -u --- firmware/App/Drivers/FluidPump.h (revision 0) +++ firmware/App/Drivers/FluidPump.h (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -0,0 +1,69 @@ +/************************************************************************** +* +* Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file BoostPump.h +* +* @author (last) Sean Nash +* @date (last) 12-Nov-2024 +* +* @author (original) Sean Nash +* @date (original) 12-Nov-2024 +* +***************************************************************************/ + +#ifndef __BOOST_PUMP_H__ +#define __BOOST_PUMP_H__ + +#include "FPCommon.h" + +/** + * @defgroup BoostPump BoostPump + * @brief Boost Pump driver unit. Controls the RO and booster pumps. + * The diaphragm (RO) pump is manufactured by TBD. + * The optional booster pump is manufactured by TBD. + * + * @addtogroup BoostPump + * @{ + */ + +// ********** public definitions ********** + +#define MAX_FLUID_PUMP_PWM_DUTY_CYCLE 500 ///< Maximum settable boost pump duty cycle magnitude. +#define MIN_FLUID_PUMP_PWM_DUTY_CYCLE 0 ///< minimum settable boost pump duty cycle magnitude. + +#define MAX_FLUID_PUMP_DUTY_CYCLE_PCT 0.99F ///< Max duty cycle in percentage. +#define MIN_FLUID_PUMP_DUTY_CYCLE_PCT 0.0F ///< Min duty cycle in percentage. +/// Enumerations of RO boost pumps. +typedef enum BoostPumps +{ + P12_PUMP = 0, ///< RO pump + P40_PUMP, ///< Optional inlet boost pump + NUM_OF_PUMPS, ///< Number of boost pumps +} FP_FLUID_PUMP_T; + +// ********** public function prototypes ********** + +void initFluidPump( void ); +void readFluidPumps( void ); + + +BOOL setFluidPumpPWMDutyCycle( FP_FLUID_PUMP_T pumpID, U16 pwm ); +U16 getFluidPumpPWMDutyCycle( FP_FLUID_PUMP_T pumpID ); +U16 getFluidPumpReadPWMDutyCycle( FP_FLUID_PUMP_T pumpID ); +F32 getFluidPumpRPM( FP_FLUID_PUMP_T pumpID ); + +U16 convertDutyCyclePctToCnt( F32 dutyCyclePct ); +BOOL setFluidPumpPctToPWMDutyCycle( FP_FLUID_PUMP_T pumpID, F32 dutyCyclePct); + + +BOOL testSetFluidPumpPWM( MESSAGE_T *message ); +BOOL testFluidPumpPWMOverride( MESSAGE_T *message ); +BOOL testFluidPumpRPMOverride( MESSAGE_T *message ); + +/**@}*/ + +#endif Index: firmware/App/FPCommon.h =================================================================== diff -u --- firmware/App/FPCommon.h (revision 0) +++ firmware/App/FPCommon.h (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -0,0 +1,62 @@ + +#ifndef __RO_COMMON_H__ +#define __RO_COMMON_H__ + +#include "hal_stdtypes.h" + +// ********** version ********** + +#define RO_VERSION_MAJOR 0 +#define RO_VERSION_MINOR 0 +#define RO_VERSION_MICRO 0 +#define RO_VERSION_BUILD 2 + +// ********** development build switches ********** + +#ifndef _RELEASE_ +#ifndef _VECTORCAST_ +// #define TASK_TIMING_OUTPUT_ENABLED 1 // Re-purposes alarm lamp pins for task timing + + #include + #include +#endif +#endif + +#include "Common.h" + +/** + * @addtogroup Main + * @{ + */ + +// **** Common Definitions **** + +#pragma pack(push,1) + +/// Payload record structure for an RO versions message. +typedef struct +{ + U08 major; ///< RO version major revision. + U08 minor; ///< RO version minor revision. + U08 micro; ///< RO version micro revision. + U16 build; ///< RO build version. + U08 fpgaId; ///< RO FPGA ID. + U08 fpgaMajor; ///< RO FPGA major revision. + U08 fpgaMinor; ///< RO FPGA minor revision. + U08 fpgaLab; ///< RO FPGA lab revision. + U32 compatibilityRev; ///< RO compatibility revision. +} RO_VERSIONS_T; + +#pragma pack(pop) + +// **** Common Macros **** + +/**@}*/ + +// **** VectorCAST Definitions **** + +#ifdef _VECTORCAST_ + +#endif + +#endif Fisheye: Tag 17a448770daa138ebeb6ce79974966e650828f25 refers to a dead (removed) revision in file `firmware/App/ROCommon.h'. Fisheye: No comparison available. Pass `N' to diff? Index: firmware/App/Services/FpgaRO.c =================================================================== diff -u -r0126254993a6cc5023632330f59cb05daf485ebe -r17a448770daa138ebeb6ce79974966e650828f25 --- firmware/App/Services/FpgaRO.c (.../FpgaRO.c) (revision 0126254993a6cc5023632330f59cb05daf485ebe) +++ firmware/App/Services/FpgaRO.c (.../FpgaRO.c) (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -468,7 +468,7 @@ *************************************************************************/ void setFPGAP24Enabled( BOOL enable ) { - return 0; + return; } /*********************************************************************//** @@ -484,7 +484,7 @@ *************************************************************************/ void setFPGAP24PWM( U16 pwm ) { - return 0; + return; } /*********************************************************************//** Index: firmware/App/Services/FpgaRO.h =================================================================== diff -u -r0126254993a6cc5023632330f59cb05daf485ebe -r17a448770daa138ebeb6ce79974966e650828f25 --- firmware/App/Services/FpgaRO.h (.../FpgaRO.h) (revision 0126254993a6cc5023632330f59cb05daf485ebe) +++ firmware/App/Services/FpgaRO.h (.../FpgaRO.h) (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -18,7 +18,7 @@ #ifndef __FPGA_RO_H__ #define __FPGA_RO_H__ -#include "ROCommon.h" +#include "FPCommon.h" #include "FPGA.h" /** Index: firmware/source/sys_main.c =================================================================== diff -u -reaadab648c4c1d6d34f3927df6ce5cfb59cdebb6 -r17a448770daa138ebeb6ce79974966e650828f25 --- firmware/source/sys_main.c (.../sys_main.c) (revision eaadab648c4c1d6d34f3927df6ce5cfb59cdebb6) +++ firmware/source/sys_main.c (.../sys_main.c) (revision 17a448770daa138ebeb6ce79974966e650828f25) @@ -64,10 +64,19 @@ #include "AlarmMgmtRO.h" #include "CommBuffers.h" #include "Conductivity.h" +#include "DDInterface.h" +#include "FilterFlush.h" #include "Flow.h" #include "FpgaRO.h" +#include "InternalADC.h" #include "Interrupts.h" #include "Level.h" +#include "MembraneFlush.h" +#include "ModeFault.h" +#include "ModeInitPOST.h" +#include "ModeStandby.h" +#include "ModeWaterGen.h" +#include "ModeWaterPreGen.h" #include "MsgQueues.h" #include "OperationModes.h" #include "Pressure.h" @@ -153,28 +162,50 @@ *************************************************************************/ static void initSoftware( void ) { + + // Tasks and Core initSemaphores(); initTimers(); initSafetyShutdown(); initAlarmMgmtRO(); initWatchdogMgmt(); - initInterrupts(); - initFPGARO(); initCommBuffers(); initMsgQueues(); - initSystemComm(); + initSystemCommRO(); + initTestConfigs(); + // Services + initFPGARO(); + initDDInterface(); + initInterrupts(); + + // Drivers + initConductivitySensors(); + initFlowSensor(); + initFluidPump(); + initInternalADC(); + initPressureSensor(); + initTemperatureSensors(); + + // Controllers + initROPump(); + initValves(); + + // Monitors initConductivity(); + initFlow(); initLevels(); initPressure(); initTemperature(); - initFlow(); - initROPump(); - initValves(); - + // Modes initOperationModes(); - initTestConfigs(); + initGenWaterMode(); + initStandbyMode(); + initInitAndPOSTMode(); + initFaultMode(); + initPreGenWMode(); + } /*************************************************************************