/************************************************************************** * * 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 ROPump.c * * @author (last) Sean Nash * @date (last) 12-Nov-2024 * * @author (original) Sean Nash * @date (original) 12-Nov-2024 * ***************************************************************************/ //#include //#include "FlowSensors.h" //#include "NVDataMgmt.h" #include "Messaging.h" #include "MessageSupport.h" #include "OperationModes.h" #include "PersistentAlarm.h" //#include "PIControllers.h" //#include "Pressures.h" #include "ROPump.h" #include "SafetyShutdown.h" #include "TaskGeneral.h" #include "Timers.h" #include "Utilities.h" /** * @addtogroup ROPump * @{ */ // ********** 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 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 DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. /// 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_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. // ********** 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 void publishROPumpData( void ); /*********************************************************************//** * @brief * The initROPump function initializes the RO Pump module. * @details \b Inputs: none * @details \b Outputs: RO Pump controller unit initialized * @return none *************************************************************************/ void initROPump( void ) { U32 pump; 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; } /*********************************************************************//** * @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[] * @return none *************************************************************************/ void execROPumpController( void ) { RO_BOOST_PUMP_T pump; // Update RO pump feedback from FPGA readBoostPumps(); // Execute pump control state machine for each boost pump for ( pump = (RO_BOOST_PUMP_T)0; pump < NUM_OF_BOOST_PUMPS; pump++ ) { switch ( roPumpState[ pump ] ) { case RO_PUMP_OFF_STATE: roPumpState[ pump ] = handleROPumpOffState( pump ); break; case RO_PUMP_OPEN_LOOP_STATE: roPumpState[ pump ] = handleROPumpOpenLoopState( pump ); 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; } } // Publish RO pump data on interval publishROPumpData(); } /*********************************************************************//** * @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 * @return next state *************************************************************************/ static RO_PUMP_STATE_T handleROPumpOffState( RO_BOOST_PUMP_T pumpID ) { RO_PUMP_STATE_T state = RO_PUMP_OFF_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 * @return next state *************************************************************************/ static RO_PUMP_STATE_T handleROPumpOpenLoopState( RO_BOOST_PUMP_T pumpID ) { RO_PUMP_STATE_T state = RO_PUMP_OPEN_LOOP_STATE; if ( TRUE == stopPumpRequest[ pumpID ] ) { stopPumpRequest[ pumpID ] = FALSE; roPumpState[ pumpID ] = RO_PUMP_OFF_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 * @return none *************************************************************************/ void signalROPumpStop( RO_BOOST_PUMP_T pumpID ) { if ( pumpID < NUM_OF_BOOST_PUMPS ) { setBoostPumpPWMDutyCycle( pumpID, 0 ); // stop pump immediately if ( roPumpState[ pumpID ] != RO_PUMP_OFF_STATE ) { stopPumpRequest[ pumpID ] = TRUE; // set stop request so state machine goes to off state } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PUMP_ID1, (U32)pumpID ) } } /*********************************************************************//** * @brief * The publishROPumpData function publishes RO pump data at the set interval. * @details \b Message \b Sent: * @details \b Inputs: roPumpDataPublicationTimerCounter * @details \b Outputs: roPumpDataPublicationTimerCounter * @return none *************************************************************************/ static void publishROPumpData( void ) { // publish RO pump data on interval if ( ++roPumpDataPublicationTimerCounter >= getU32OverrideValue( &roPumpDataPublishInterval ) ) { 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 ); broadcastData( MSG_ID_RO_PUMP_DATA, COMM_BUFFER_OUT_CAN_RO_BROADCAST, (U08*)&pumpData, sizeof( RO_PUMP_DATA_T ) ); roPumpDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @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 testROPumpDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &roPumpDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /**@}*/