Index: firmware/App/Modes/InletPressureCheck.c =================================================================== diff -u --- firmware/App/Modes/InletPressureCheck.c (revision 0) +++ firmware/App/Modes/InletPressureCheck.c (revision d5f58f8014d99822b71bd2844063fb62fe79d8a1) @@ -0,0 +1,368 @@ +/************************************************************************** +* +* Copyright (c) 2024-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 InletPressureCheck.c +* +* @author (last) Raghu Kallala +* @date (last) 12-Aug-2025 +* +* @author (original) Raghu Kallala +* @date (original) 12-Aug-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, SW_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( M7_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 ); + setValveState( P20_VALV, VALVE_STATE_CLOSED ); + setValveState( P43_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( M7_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 ); + setValveState( P20_VALV, VALVE_STATE_CLOSED ); + setValveState( P43_VALV, VALVE_STATE_CLOSED ); + + if ( TRUE == isBoostPumpInstalled() ) + { + signalBoostPumpHardStop(); + } + signalROPumpHardStop(); + } + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_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; +} + +/**@}*/ Index: firmware/App/Services/Messaging.c =================================================================== diff -u -rbdf1e3ac2eef7ec37034127e18aa6308148e894a -rd5f58f8014d99822b71bd2844063fb62fe79d8a1 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision bdf1e3ac2eef7ec37034127e18aa6308148e894a) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision d5f58f8014d99822b71bd2844063fb62fe79d8a1) @@ -115,9 +115,11 @@ { MSG_ID_FP_SAFETY_SHUTDOWN_OVERRIDE_REQUEST, &testSetResetSafetyShutdownOverride }, { MSG_ID_FP_ALARM_STATE_OVERRIDE_REQUEST, &testAlarmStateOverride }, { MSG_ID_FP_ALARM_CLEAR_ALL_ALARMS_REQUEST, &testClearAllAlarms }, -{ MSG_ID_FP_INLET_PRES_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testInletPressureCheckDataPublishIntervalOverride }, -{ MSG_ID_FP_INLET_PRES_CHECK_TIME_OVERRIDE_REQUEST, &testInletPressureCheckTimerOverride }, - +{ MSG_ID_FP_SET_TEST_CONFIGURATION, &testSetTestConfiguration }, +{ MSG_ID_FP_GET_TEST_CONFIGURATION, &testGetTestConfiguration }, +{ MSG_ID_FP_RESET_ALL_TEST_CONFIGURATIONS, &testResetAllTestConfigurations }, +{ MSG_ID_FP_INLET_PRES_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testInletPressureCheckDataPublishIntervalOverride }, +{ MSG_ID_FP_INLET_PRES_CHECK_TIME_OVERRIDE_REQUEST, &testInletPressureCheckTimerOverride } }; #define NUM_OF_FUNCTION_HANDLERS (sizeof(MSG_FUNCTION_HANDLER_LOOKUP) / sizeof(MSG_HANDLER_LOOKUP_T)) @@ -704,4 +706,87 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetTestConfiguration function handles a request to set a + * test configuration. + * @details \b Inputs: none + * @details \b Outputs: message handled + * @param message a pointer to the message to handle + * @return TRUE if command accepted, FALSE if rejected + *************************************************************************/ +BOOL testSetTestConfiguration( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify payload length + if ( sizeof( TEST_CONFIG_PAYLOAD_T ) == message->hdr.payloadLen ) + { + TEST_CONFIG_PAYLOAD_T payload; + + // copy message payload to local variable + memcpy( (U08*)&payload, &message->payload[0], sizeof( TEST_CONFIG_PAYLOAD_T ) ); + + // Verify given test configuration is valid + if ( payload.config < NUM_OF_TEST_CONFIGS ) + { + result = TRUE; + if ( FALSE == payload.reset ) + { + setTestConfig( (TEST_CONFIG_T)payload.config ); + } + else + { + resetTestConfig( (TEST_CONFIG_T)payload.config ); + } + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testGetTestConfiguration function handles a request to get a + * test configuration. + * @details \b Inputs: none + * @details \b Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +BOOL testGetTestConfiguration( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + result = sendTestConfigStatusToDialin(); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetTestConfiguration function handles a request to reset all + * test configurations. + * @details \b Inputs: none + * @details \b Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +BOOL testResetAllTestConfigurations( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + result = resetAllTestConfigs(); + } + + return result; +} + /**@}*/