/************************************************************************** * * Copyright (c) 2025-2025 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 InletPressureCheck.c * * @author (last) “Raghu * @date (last) 14-Oct-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 * ***************************************************************************/ #include "BoostPump.h" #include "FlowSensor.h" #include "InletPressureCheck.h" #include "FPOperationModes.h" #include "MessageSupport.h" #include "Messaging.h" #include "Pressure.h" #include "ROPump.h" #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" /** * @addtogroup InletPressureCheck * @{ */ // ********** private definitions ********** #define INLET_PRES_CHECK_MAX_TIMEOUT ( 600 * MS_PER_SECOND ) ///< Max override timeout for 10 minutes #define INLET_PRES_CHECK_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the gen water mode data published. #define INLET_PRES_CHECK_TIMEOUT ( 60 * MS_PER_SECOND ) ///< Inlet Pressure Check timer (in ms) #define INLET_PRES_CHECK_BOOST_PUMP_TGT_PWM 0.2F ///< target in PWM % for the BOOST pump during inlet pressure check. #define INLET_PRES_CHECK_TGT_PSI 30 ///< Pressure target in PSI for the M3 during inlet pressure check. #define INLET_PRES_CHECK_TOLERANCE_PSI 2 ///< Pressure tolerance in PSI for the M3 during inlet pressure check. #define INLET_PRES_PERSISTENCE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Persistence time for M3 during inlet pressure check. // ********** private data ********** static FP_INLET_PRES_CHECK_STATE_T inletPressureCheckState; ///< Currently active Inlet Pressure check state. static U32 inletPressureCheckDataPublicationTimerCounter; ///< Used to schedule Inlet Pressure Check data publication to CAN bus. static U32 inletPressureCheckTimer; ///< Inlet Pressure check timeout timer static U32 inletPressureCheckPersistanceStartTimeMS; ///< Current time for inlet pressure check persistence time started in milliseconds. static BOOL isPressureCheckComplete; ///< Inlet Pressure Check complete BOOL static OVERRIDE_U32_T inletPressureCheckDataPublishInterval; ///< Inlet Pressure Check mode data publish interval. static OVERRIDE_U32_T inletPressureCheckTimeout; ///< Inlet Pressure check timeout value // ********** private function prototypes ********** static void publishInletPressureCheckData( void ); static FP_INLET_PRES_CHECK_STATE_T handleInletPressureCheckProgressState( void ); static FP_INLET_PRES_CHECK_STATE_T handleInletPressureCheckPausedState( void ); static void setInletPressureCheckTransition( FP_INLET_PRES_CHECK_STATE_T state ); static U32 getInletPressureCheckTimeout( void ); static U32 getInletPressureCheckPublishInterval( void ); /*********************************************************************//** * @brief * The initInletPressureCheck function initializes the Inlet Pressure Check unit. * @details \b Inputs: none * @details \b Outputs: Inlet Pressure Check unit initialized * @return none *************************************************************************/ void initInletPressureCheck( void ) { inletPressureCheckState = INLET_PRES_CHECK_PAUSED; inletPressureCheckDataPublishInterval.data = INLET_PRES_CHECK_DATA_PUBLISH_INTERVAL; inletPressureCheckDataPublishInterval.ovData = INLET_PRES_CHECK_DATA_PUBLISH_INTERVAL; inletPressureCheckDataPublishInterval.ovInitData = 0; inletPressureCheckDataPublishInterval.override = OVERRIDE_RESET; inletPressureCheckTimeout.data = INLET_PRES_CHECK_TIMEOUT; inletPressureCheckTimeout.ovData = INLET_PRES_CHECK_TIMEOUT; inletPressureCheckTimeout.ovInitData = 0; inletPressureCheckTimeout.override = OVERRIDE_RESET; inletPressureCheckDataPublicationTimerCounter = 0; inletPressureCheckTimer = 0; inletPressureCheckPersistanceStartTimeMS = 0; isPressureCheckComplete = FALSE; } /*********************************************************************//** * @brief * The execInletPressureCheck function executes the inlet pressure check * state machine and publishes inlet pressure check data. * @details \b Inputs: inletPressureCheckState * @details \b Outputs: inletPressureCheckState * @details \b Alarm: ALARM_ID_FP_SOFTWARE_FAULT if in invalid flush state * @return none *************************************************************************/ void execInletPressureCheck( void ) { FP_INLET_PRES_CHECK_STATE_T prevState = inletPressureCheckState; switch ( inletPressureCheckState ) { case INLET_PRES_CHECK_IN_PROGRESS: inletPressureCheckState = handleInletPressureCheckProgressState(); break; case INLET_PRES_CHECK_PAUSED: inletPressureCheckState = handleInletPressureCheckPausedState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_FP_INVALID_INLET_PRESSURE_CHECK_STATE, (U32)inletPressureCheckState ) inletPressureCheckState = INLET_PRES_CHECK_PAUSED; break; } if ( prevState != inletPressureCheckState ) { setInletPressureCheckTransition( inletPressureCheckState ); } // publish Inlet Pressure check data on interval publishInletPressureCheckData(); } /*********************************************************************//** * @brief * The handleInletPressureCheckProgressState handles the in progress * state of inlet pressure check * @details \b Inputs: none * @details \b Outputs: none * @return the next state of Inlet Pressure check state *************************************************************************/ static FP_INLET_PRES_CHECK_STATE_T handleInletPressureCheckProgressState( void ) { FP_INLET_PRES_CHECK_STATE_T state = INLET_PRES_CHECK_IN_PROGRESS; F32 inletPressure = 0.0; inletPressure = getFilteredPressure(M3_PRES); // check for inlet pressure (M3) within range if( ( inletPressure >= (INLET_PRES_CHECK_TGT_PSI - INLET_PRES_CHECK_TOLERANCE_PSI) ) && ( inletPressure <= (INLET_PRES_CHECK_TGT_PSI + INLET_PRES_CHECK_TOLERANCE_PSI) ) ) { if ( 0 == inletPressureCheckPersistanceStartTimeMS ) { inletPressureCheckPersistanceStartTimeMS = getMSTimerCount(); } else if ( TRUE == didTimeout( inletPressureCheckPersistanceStartTimeMS, INLET_PRES_PERSISTENCE_TIME_MS ) ) { inletPressureCheckPersistanceStartTimeMS = 0; isPressureCheckComplete = TRUE; state = INLET_PRES_CHECK_PAUSED; } } // reset the persistence timer when inlet pressure out of range else if( ( inletPressure <= (INLET_PRES_CHECK_TGT_PSI - INLET_PRES_CHECK_TOLERANCE_PSI) ) || ( inletPressure >= (INLET_PRES_CHECK_TGT_PSI + INLET_PRES_CHECK_TOLERANCE_PSI) ) ) { inletPressureCheckPersistanceStartTimeMS = 0; } // Trigger alarm if M3 pressure is not within range else if ( TRUE == didTimeout( inletPressureCheckTimer, getInletPressureCheckTimeout() ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_RO_INLET_PRESSURE_OUT_HIGH_RANGE, INLET_PRES_CHECK_TIMEOUT, inletPressure) state = INLET_PRES_CHECK_PAUSED; } return state; } /*********************************************************************//** * @brief * The handleInletPressureCheckPausedState handles the paused state of Inlet Pressure check * @details \b Inputs: none * @details \b Outputs: none * @return the next state of Inlet Pressure check state *************************************************************************/ static FP_INLET_PRES_CHECK_STATE_T handleInletPressureCheckPausedState( void ) { FP_INLET_PRES_CHECK_STATE_T state = INLET_PRES_CHECK_PAUSED; if ( FALSE == isInletPressureCheckCompleted() ) { state = INLET_PRES_CHECK_IN_PROGRESS; } return state; } /*********************************************************************//** * @brief * The setInletPressureCheckTransition function sets the actuators and variables * for the state transition in Inlet Pressure check mode. * @details Inputs: Valve states, Pump speed * @details Outputs: Actuate valves, pumps as desired. * @param state Inlet Pressure check state enum * @return none *************************************************************************/ static void setInletPressureCheckTransition( FP_INLET_PRES_CHECK_STATE_T state ) { // Execute on running state switch( state ) { case INLET_PRES_CHECK_IN_PROGRESS: setValveState( M4_VALV, VALVE_STATE_CLOSED ); setValveState( M12_VALV, VALVE_STATE_CLOSED ); setValveState( P6_VALV, VALVE_STATE_CLOSED ); setValveState( P11_VALV, VALVE_STATE_CLOSED ); setValveState( P33_VALV, VALVE_STATE_CLOSED ); setValveState( P34_VALV, VALVE_STATE_CLOSED ); setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_CLOSED ); if ( TRUE == isBoostPumpInstalled() ) { setBoostPumpTargetDutyCycle( INLET_PRES_CHECK_BOOST_PUMP_TGT_PWM ); } signalROPumpHardStop(); inletPressureCheckTimer = getMSTimerCount(); break; case INLET_PRES_CHECK_PAUSED: // Stop pumps and close only if we alarm ( pause ) during flush. if ( FALSE == isInletPressureCheckCompleted() ) { setValveState( M4_VALV, VALVE_STATE_CLOSED ); setValveState( M12_VALV, VALVE_STATE_CLOSED ); setValveState( P6_VALV, VALVE_STATE_CLOSED ); setValveState( P11_VALV, VALVE_STATE_CLOSED ); setValveState( P33_VALV, VALVE_STATE_CLOSED ); setValveState( P34_VALV, VALVE_STATE_CLOSED ); setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_CLOSED ); if ( TRUE == isBoostPumpInstalled() ) { signalBoostPumpHardStop(); } signalROPumpHardStop(); } break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_FP_INVALID_INLET_PRESSURE_CHECK_STATE, state ) break; } } /*********************************************************************//** * @brief * The getCurrentInletPressureCheckState function returns the current state of * Inlet Pressure Check. * @details \b Inputs: inletPressureCheckState * @details \b Outputs: none * @return the current state of inlet pressure check *************************************************************************/ FP_INLET_PRES_CHECK_STATE_T getCurrentInletPressureCheckState( void ) { return inletPressureCheckState; } /*********************************************************************//** * @brief * The isInletPressureCheckCompleted function returns isPressureCheckComplete. * @details \b Inputs: isPressureCheckComplete * @details \b Outputs: none * @return TRUE if Inlet Pressure check is complete, FALSE if not. *************************************************************************/ BOOL isInletPressureCheckCompleted( void ) { return isPressureCheckComplete; } /*********************************************************************//** * @brief * The getInletPressureCheckTimeout function gets the Inlet Pressure check * mode data publish interval. * @details \b Inputs: inletPressureCheckTimeout * @details \b Outputs: none * @return the Inlet Pressure check timeout period in ms. *************************************************************************/ static U32 getInletPressureCheckTimeout( void ) { U32 result = getU32OverrideValue( &inletPressureCheckTimeout ); return result; } /*********************************************************************//** * @brief * The getInletPressureCheckPublishInterval function gets the Inlet Pressure check * mode data publish interval. * @details \b Inputs: inletPressureCheckDataPublishInterval * @details \b Outputs: none * @return the interval at Inlet Pressure check mode data being published. *************************************************************************/ static U32 getInletPressureCheckPublishInterval( void ) { U32 result = getU32OverrideValue( &inletPressureCheckDataPublishInterval ); return result; } /*********************************************************************//** * @brief * The publishInletPressureCheckData function broadcasts the Inlet Pressure check * mode data at defined interval. * @details \b Inputs: inletPressureCheckDataPublicationTimerCounter * @details \b Outputs: fp Inlet Pressure check data broadcast message sent * @details \b Message \b Sent: MSG_ID_FP_INLET_PRESSURE_CHECK_DATA to publish the * Inlet Pressure check mode data. * @return none *************************************************************************/ static void publishInletPressureCheckData( void ) { if ( ++inletPressureCheckDataPublicationTimerCounter >= getInletPressureCheckPublishInterval() ) { INLET_PRES_CHECK_DATA_T data; data.inletPressureCheckExecState = (U32)getCurrentInletPressureCheckState(); broadcastData( MSG_ID_FP_INLET_PRESSURE_CHECK_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( INLET_PRES_CHECK_DATA_T ) ); inletPressureCheckDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testInletPressureCheckDataPublishIntervalOverride function overrides the * FP Inlet Pressure check mode data publish interval. * @details \b Inputs: inletPressureCheckDataPublishInterval * @details \b Outputs: inletPressureCheckDataPublishInterval * @param Override message from Dialin which includes the interval * (in ms) to override the FP Inlet Pressure check data publish interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testInletPressureCheckDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &inletPressureCheckDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testInletPressureCheckTimerOverride function overrides the * FP Inlet Pressure check timeout value. * @details \b Inputs: inletPressureCheckTimeout * @details \b Outputs: inletPressureCheckTimeout * @param Override message from Dialin which includes the interval * (in ms) to override the FP Inlet Pressure check timeout to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testInletPressureCheckTimerOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &inletPressureCheckTimeout, 0, INLET_PRES_CHECK_MAX_TIMEOUT ); return result; } /**@}*/