Index: firmware/App/Modes/FPModes/FlushFilterDefeatured.c =================================================================== diff -u --- firmware/App/Modes/FPModes/FlushFilterDefeatured.c (revision 0) +++ firmware/App/Modes/FPModes/FlushFilterDefeatured.c (revision 0cee1110f21bca6bd223f8c94d2171a9f162edb5) @@ -0,0 +1,473 @@ +/************************************************************************** +* +* 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 FlushFilterDefeatured.c +* +* @author (last) Sameer Poyil +* @date (last) 12-Dec-2025 +* +* @author (original) Michael Garthwaite +* @date (original) 08-Sep-2025 +* +***************************************************************************/ + +#include "BoostPump.h" +#include "FlushFilterDefeatured.h" +#include "FPOperationModes.h" +#include "MessageSupport.h" +#include "Messaging.h" +#include "Pressure.h" +#include "TaskGeneral.h" +#include "Timers.h" +#include "Valves.h" +#include "WaterQualityMonitor.h" + +/** + * @addtogroup FPFilterFlush + * @{ + */ + +// ********** private definitions ********** + +#define FILTER_FLUSH_MAX_TIMEOUT ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Max override timeout for 10 minutes +#define FILTER_FLUSH_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the gen water mode data published. +#define FILTER_FLUSH_TIMEOUT ( 5 * MS_PER_SECOND ) ///< Filter flush timeout for 5 seconds (in ms) +#define FILTER_FLUSH_PRESSURE_CHECK_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Filter flush timeout for 5 second (in ms) +#define MAX_INLET_WATER_PRESSURE_DEFEATURED_FAULT_HIGH_PSIG 40 ///< maximum dynamic M3 pressure is within range < 40 +#define MIN_FILTER_FLUSH_PRESSURE_DEFEATURED_LOW_PSIG 5.0F ///< Minimum allowed Input warning low pressure value in psig for RO Defeatured. +#define MAX_FILTER_FLUSH_PRESSURE_DEFEATURED_HIGH_PSIG 10.0F ///< Maximum allowed Input warning high pressure value in psig for RO Defeatured. +#define FILTER_FLUSH_PRES_OUT_OF_RANGE_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< Persistence period for pressure out of range error in milliseconds. +#define FILTER_FLUSH_PRES_OUT_OF_RANGE_CLEAR_MS ( 1 * MS_PER_SECOND ) ///< Persistence period for pressure out of range clear in milliseconds. + + +// ********** private data ********** + +static FP_FILTER_FLUSH_DEF_STATE_T filterFlushDefState; ///< Currently active filter flush de-featured state. +static U32 filterFlushDefDataPublicationTimerCounter; ///< Used to schedule filter flush de-featured data publication to CAN bus. +static OVERRIDE_U32_T filterFlushDefDataPublishInterval; ///< Filter Flush de-featured data publish interval. +static OVERRIDE_U32_T filterFlushDefTimeout; ///< Filter Flush timeout value +static U32 filterFlushDefTimer; ///< Filter Flush timeout timer +static U32 filterFlushDefPressureLowCheckTimer; ///< Filter Flush timeout timer for pressure low check +static U32 filterFlushDefPressureHighCheckTimer; ///< Filter Flush timeout timer for pressure high check +static U32 filterFlushPressureCheckStartTimeMS; ///< Filter Flush pressure check timer +static BOOL pendingStartFilterFlushDefRequest; ///< signal to start flushing. +static BOOL isFlushDefComplete; ///< Filter Flush complete + +// ********** private function prototypes ********** + +static void publishFilterFlushDefData( void ); +static FP_FILTER_FLUSH_DEF_STATE_T handleFilterFlushDefDynamicPressureCheckState( void ); +static FP_FILTER_FLUSH_DEF_STATE_T handleFilterFlushDefStaticPressureCheckState( void ); +static FP_FILTER_FLUSH_DEF_STATE_T handleFilterFlushDefPausedState( void ); +static void setFilterFlushDefTransition( FP_FILTER_FLUSH_DEF_STATE_T state ); +static U32 getFilterFlushDefTimeout( void ); +static U32 getFilterFlushDefPublishInterval( void ); + +/*********************************************************************//** + * @brief + * The initFilterFlushDefeatured function initializes the de-featured filter flush unit. + * @details \b Inputs: none + * @details \b Outputs: de-featured filter flush unit initialized + * @return none + *************************************************************************/ +void initFilterFlushDefeatured( void ) +{ + filterFlushDefState = FILTER_FLUSH_DEF_PAUSED; + filterFlushDefDataPublishInterval.data = FILTER_FLUSH_DATA_PUBLISH_INTERVAL; + filterFlushDefDataPublishInterval.ovData = FILTER_FLUSH_DATA_PUBLISH_INTERVAL; + filterFlushDefDataPublishInterval.ovInitData = 0; + filterFlushDefDataPublishInterval.override = OVERRIDE_RESET; + filterFlushDefTimeout.data = FILTER_FLUSH_TIMEOUT; + filterFlushDefTimeout.ovData = FILTER_FLUSH_TIMEOUT; + filterFlushDefTimeout.ovInitData = 0; + filterFlushDefTimeout.override = OVERRIDE_RESET; + filterFlushDefDataPublicationTimerCounter = 0; + filterFlushDefTimer = 0; + filterFlushDefPressureLowCheckTimer = 0; + filterFlushDefPressureHighCheckTimer = 0; + filterFlushPressureCheckStartTimeMS = 0; + isFlushDefComplete = 0; + pendingStartFilterFlushDefRequest = 0; + + initPersistentAlarm( ALARM_ID_FP_INLET_PRESSURE_CRITICAL_OUT_RANGE, FILTER_FLUSH_PRES_OUT_OF_RANGE_CLEAR_MS, FILTER_FLUSH_PRES_OUT_OF_RANGE_TIMEOUT_MS ); +} + +/*********************************************************************//** + * @brief + * The execFilterFlushDefeatured function executes the de-featured filter flush state machine + * and publishes filter flush data. + * @details \b Inputs: filterFlushDefState + * @details \b Outputs: filterFlushDefState + * @details \b Alarm: ALARM_ID_FP_SOFTWARE_FAULT if in invalid flush state + * @return none + *************************************************************************/ +void execFilterFlushDefeatured( void ) +{ + FP_FILTER_FLUSH_DEF_STATE_T prevState = filterFlushDefState; + + switch ( filterFlushDefState ) + { + case FILTER_FLUSH_DEF_DYNAMIC_PRESSURE_CHECK: + filterFlushDefState = handleFilterFlushDefDynamicPressureCheckState(); + checkInletTemperatures(); + break; + + case FILTER_FLUSH_DEF_STATIC_PRESSURE_CHECK: + filterFlushDefState = handleFilterFlushDefStaticPressureCheckState(); + break; + + case FILTER_FLUSH_DEF_PAUSED: + filterFlushDefState = handleFilterFlushPausedState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_FP_INVALID_FILTER_FLUSH_STATE, (U32)filterFlushDefState ) + filterFlushDefState = FILTER_FLUSH_PAUSED; + break; + } + + if ( prevState != filterFlushDefState ) + { + setFilterFlushTransition( filterFlushDefState ); + } + // publish filter flush data on interval + publishFilterFlushData(); +} + +/*********************************************************************//** + * @brief + * The handleFilterFlushDefDynamicPressureCheckState handles the Dynamic pressure check state of de-featured filter flush + * @details \b Inputs: filterFlushDefTimer + * @details \b Outputs: None + * @return the next state of de-featured filter flush state + *************************************************************************/ +static FP_FILTER_FLUSH_DEF_STATE_T handleFilterFlushDefDynamicPressureCheckState( void ) +{ + FP_FILTER_FLUSH_DEF_STATE_T state = FILTER_FLUSH_DEF_DYNAMIC_PRESSURE_CHECK; + F32 pressureM3 = getFilteredPressure( M3_PRES ); + BOOL isPresOutOfHighRange = FALSE; + +// if ( TRUE == 1 )// TODO Alarm and Stop State Rework +// { +// state = FILTER_FLUSH_PAUSED; +// } + + // check the dynamic pressure + if( TRUE == didTimeout( filterFlushDefTimer, getFilterFlushTimeout() ) ) + { + // check for inlet pressure (M3) within range < 40 + if( pressureM3 < MAX_INLET_WATER_PRESSURE_DEFEATURED_FAULT_HIGH_PSIG ) + { + if ( 0 == filterFlushPressureCheckStartTimeMS ) + { + filterFlushPressureCheckStartTimeMS = getMSTimerCount(); + } + else if ( TRUE == didTimeout( filterFlushPressureCheckStartTimeMS, FILTER_FLUSH_PRESSURE_CHECK_TIMEOUT ) ) + { + filterFlushPressureCheckStartTimeMS = 0; + //isFlushDefComplete = TRUE; + // move to dynamic pressure check state + state = FILTER_FLUSH_DEF_STATIC_PRESSURE_CHECK; + } + } + else + { + // second persistent alarm + state = FILTER_FLUSH_DEF_PAUSED; + isPresOutOfHighRange = ( ( pressureM3 > MAX_INLET_WATER_PRESSURE_DEFEATURED_FAULT_HIGH_PSIG ) ? TRUE : FALSE ); + checkPersistentAlarm( ALARM_ID_FP_INLET_PRESSURE_CRITICAL_OUT_RANGE, isPresOutOfHighRange, pressureM3, MAX_INLET_WATER_PRESSURE_DEFEATURED_FAULT_HIGH_PSIG ); + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleFilterFlushDefStaticPressureCheckState handles the static pressure check of the de-featured filter flush + * @details \b Inputs: filterFlushTimer + * @details \b Outputs: isFlushDefComplete + * @return the next state of de-featured filter flush state + *************************************************************************/ +static FP_FILTER_FLUSH_DEF_STATE_T handleFilterFlushDefStaticPressureCheckState( void ) +{ + FP_FILTER_FLUSH_DEF_STATE_T state = FILTER_FLUSH_DEF_STATIC_PRESSURE_CHECK; + U32 thresholdMin = MIN_FILTER_FLUSH_PRESSURE_DEFEATURED_LOW_PSIG; + U32 thresholdMax = MAX_FILTER_FLUSH_PRESSURE_DEFEATURED_HIGH_PSIG; + F32 pressureM3 = getFilteredPressure( M3_PRES ); + +// if ( TRUE == 1 )// TODO Alarm and Stop State Rework +// { +// state = FILTER_FLUSH_PAUSED; +// } + + // check for inlet pressure (M3) within range 5 -10 + if ( ( pressureM3 >= thresholdMin ) && ( pressureM3 <= thresholdMax ) ) + { + filterFlushDefPressureHighCheckTimer = 0; + filterFlushDefPressureLowCheckTimer = 0; + if ( 0 == filterFlushPressureCheckStartTimeMS ) + { + filterFlushPressureCheckStartTimeMS = getMSTimerCount(); + } + else if ( TRUE == didTimeout( filterFlushPressureCheckStartTimeMS, FILTER_FLUSH_PRESSURE_CHECK_TIMEOUT ) ) + { + filterFlushPressureCheckStartTimeMS = 0; + isFlushDefComplete = TRUE; + state = FILTER_FLUSH_DEF_PAUSED; + } + } + // reset the persistence timer when inlet pressure is < 5 + else if ( pressureM3 <= thresholdMin ) + { + filterFlushPressureCheckStartTimeMS = 0; + filterFlushDefPressureHighCheckTimer = 0; + if ( 0 == filterFlushDefPressureLowCheckTimer ) + { + filterFlushDefPressureLowCheckTimer = getMSTimerCount(); + } + + // Trigger alarm if M3 pressure is not within range + else if ( TRUE == didTimeout( filterFlushDefPressureLowCheckTimer, getFilterFlushTimeout() ) ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_RO_INLET_PRESSURE_OUT_HIGH_RANGE, getFilterFlushTimeout(), pressureM3 ) + state = INLET_PRES_CHECK_PAUSED; + } + } + // reset the persistence timer when inlet pressure is > 10 + else if ( pressureM3 >= thresholdMax ) + { + filterFlushPressureCheckStartTimeMS = 0; + filterFlushDefPressureLowCheckTimer = 0; + if ( 0 == filterFlushDefPressureHighCheckTimer ) + { + filterFlushDefPressureHighCheckTimer = getMSTimerCount(); + } + // Trigger alarm if M3 pressure is not within range + else if ( TRUE == didTimeout( filterFlushDefPressureHighCheckTimer, getFilterFlushTimeout() ) ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_RO_INLET_PRESSURE_OUT_HIGH_RANGE, getFilterFlushTimeout(), pressureM3 ) + state = INLET_PRES_CHECK_PAUSED; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleFilterFlushDefPausedState handles the pause state of filter flush + * @details \b Inputs: pendingStartFilterFlushDefRequest + * @details \b Outputs: pendingStartFilterFlushDefRequest, isFlushDefComplete + * @return the next state of de-featured filter flush state + *************************************************************************/ +static FP_FILTER_FLUSH_DEF_STATE_T handleFilterFlushDefPausedState( void ) +{ + FP_FILTER_FLUSH_DEF_STATE_T state = FILTER_FLUSH_DEF_PAUSED; + + if ( TRUE == pendingStartFilterFlushDefRequest ) + { + isFlushDefComplete = FALSE; + pendingStartFilterFlushDefRequest = FALSE; + state = FILTER_FLUSH_DEF_DYNAMIC_PRESSURE_CHECK; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The setFilterFlushDefTransition function sets the actuators and variables + * for the state transition in filter flush de-featured mode. + * @details Inputs: Valve states, Pump speed + * @details Outputs: Actuate valves, pumps as desired. + * @param state de-featured filter flush state enum + * @return none + *************************************************************************/ +static void setFilterFlushDefTransition( FP_FILTER_FLUSH_DEF_STATE_T state ) +{ + // Execute on running state + switch( state ) + { + case FILTER_FLUSH_DEF_DYNAMIC_PRESSURE_CHECK: + setValveState( M4_VALV, VALVE_STATE_OPEN ); + setValveState( M12_VALV, VALVE_STATE_OPEN ); + setValveState( D52_VALV, VALVE_STATE_OPEN ); + filterFlushDefTimer = getMSTimerCount(); + break; + + case FILTER_FLUSH_DEF_STATIC_PRESSURE_CHECK: + setValveState( M4_VALV, VALVE_STATE_CLOSED ); + setValveState( M12_VALV, VALVE_STATE_CLOSED ); + setValveState( D52_VALV, VALVE_STATE_CLOSED ); + filterFlushDefTimer = getMSTimerCount(); + break; + + case FILTER_FLUSH_DEF_PAUSED: + // close only if we actually pause during flush + if ( FALSE == isFilterFlushComplete() ) + { + setValveState( M4_VALV, VALVE_STATE_CLOSED ); + setValveState( M12_VALV, VALVE_STATE_CLOSED ); + setValveState( D52_VALV, VALVE_STATE_CLOSED ); + } + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_FP_INVALID_FILTER_FLUSH_STATE, state ) + break; + } +} + +/*********************************************************************//** + * @brief + * The signalStartDefFilterFlush function signals the FP to start defeatured filter flush. + * @details \b Inputs: filterFlushState + * @details \b Outputs: pendingStartFilterFlushDefRequest + * @return none + *************************************************************************/ +void signalStartDefFilterFlush( void ) +{ + if ( FILTER_FLUSH_DEF_PAUSED == getCurrentFilterFlushDefSState() ) + { + pendingStartFilterFlushDefRequest = TRUE; + } +} + +/*********************************************************************//** + * @brief + * The resetFilterFlushDefSignals function resets the signal values for + * FP filter flush. + * @details \b Inputs: none + * @details \b Outputs: pendingStartFilterFlushDefRequest, isFlushDefComplete + * @return none + *************************************************************************/ +void resetFilterFlushDefSignals( void ) +{ + pendingStartFilterFlushDefRequest = FALSE; + isFlushDefComplete = FALSE; +} + +/*********************************************************************//** + * @brief + * The getCurrentFilterFlushDefState function returns the current state of + * filter flush. + * @details \b Inputs: none + * @details \b Outputs: none + * @return the current state of filter flush + *************************************************************************/ +FP_FILTER_FLUSH_DEF_STATE_T getCurrentFilterFlushDefState( void ) +{ + return filterFlushDefState; +} + +/*********************************************************************//** + * @brief + * The isFilterFlushDefComplete function returns isFilterFlushDefComplete. + * @details \b Inputs: isFlushComplete + * @details \b Outputs: none + * @return TRUE if filter flush is complete, FALSE if not. + *************************************************************************/ +BOOL isFilterFlushDefComplete( void ) +{ + return isFlushDefComplete; +} + +/*********************************************************************//** + * @brief + * The getFilterFlushDefTimeout function gets the generate water + * mode data publish interval. + * @details \b Inputs: filterFlushDefTimeout + * @details \b Outputs: none + * @return the timeout timer for filter flush. + *************************************************************************/ +static U32 getFilterFlushDefTimeout( void ) +{ + U32 result = getU32OverrideValue( &filterFlushDefTimeout ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getFilterFlushDefPublishInterval function gets the filter flush + * mode data publish interval. + * @details \b Inputs: filterFlushDefDataPublishInterval + * @details \b Outputs: none + * @return the interval at defeatured filter flush mode data being published. + *************************************************************************/ +static U32 getFilterFlushDefPublishInterval( void ) +{ + U32 result = getU32OverrideValue( &filterFlushDefDataPublishInterval ); + + return result; +} + +/*********************************************************************//** + * @brief + * The publishFilterFlushDefData function broadcasts the filter flush + * mode data at defined interval. + * @details \b Inputs: filterFlushDataPublicationTimerCounter + * @details \b Outputs: fp filter flush defeatured data broadcast message sent + * @details \b Message \b Sent: MSG_ID_FP_FILTER_FLUSH_DATA to publish the + * filter flush mode data. + * @return none + *************************************************************************/ +static void publishFilterFlushDefData( void ) +{ + if ( ++filterFlushDefDataPublicationTimerCounter >= getFilterFlushDefPublishInterval() ) + { + FILTER_FLUSH_DATA_T data; + + data.filterFlushExecState = (U32)getCurrentFilterFlushDefState(); + broadcastData( MSG_ID_FP_FILTER_FLUSH_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( FILTER_FLUSH_DATA_T ) ); + + filterFlushDefDataPublicationTimerCounter = 0; + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testFilterFlushDefDataPublishIntervalOverride function overrides the + * FP filter flush defeatured mode data publish interval. + * @details \b Inputs: filterFlushDefDataPublishInterval + * @details \b Outputs: filterFlushDefDataPublishInterval + * @param Override message from Dialin which includes the interval + * (in ms) to override the FP filter flush defeatured data publish interval to. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testFilterFlushDefDataPublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = u32BroadcastIntervalOverride( message, &filterFlushDefDataPublishInterval, TASK_GENERAL_INTERVAL ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testFilterFlushDefTimerOverride function overrides the + * FP filter flush timeout value. + * @details \b Inputs: filterFlushDefTimeout + * @details \b Outputs: filterFlushDefTimeout + * @param Override message from Dialin which includes the interval + * (in ms) to override the FP filter flush timeout to. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testFilterFlushDefTimerOverride( MESSAGE_T *message ) +{ + BOOL result = u32Override( message, &filterFlushDefTimeout, 0, FILTER_FLUSH_MAX_TIMEOUT ); + + return result; +} + +/**@}*/ Index: firmware/App/Modes/FPModes/FlushFilterDefeatured.h =================================================================== diff -u --- firmware/App/Modes/FPModes/FlushFilterDefeatured.h (revision 0) +++ firmware/App/Modes/FPModes/FlushFilterDefeatured.h (revision 0cee1110f21bca6bd223f8c94d2171a9f162edb5) @@ -0,0 +1,57 @@ +/************************************************************************** +* +* 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 FlushFilterDefeatured.h +* +* @author (last) Sameer Poyil +* @date (last) 12-Dec-2025 +* +* @author (original) Michael Garthwaite +* @date (original) 08-Sep-2025 +* +***************************************************************************/ + +#ifndef __FLUSH_FILTER_DEFEATURED_H__ +#define __FLUSH_FILTER_DEFEATURED_H__ + +#include "DDDefs.h" +#include "DDCommon.h" +#include "FPDefs.h" + +/** + * @defgroup FPFilterFlushDefeatured FPFilterFlushDefeatured + * @brief Filter Flush unit. Manages de-featured filter flush functions via a state machine. + * + * @addtogroup FPFilterFlushDefeatured + * @{ + */ + +// ********** public definitions ********** + +/// Filter Flush data structure +typedef struct +{ + U32 filterFlushExecState; ///< Filter Flush execution state +} FILTER_FLUSH_DATA_T; + +// ********** public function prototypes ********** + +void initFilterFlushDefeatured( void ); // Initialize this de-featured Filter Flush unit +//U32 transitionToFilterFlushDefeatured( void ); // Transition to Filter Flush +void execFilterFlushDefeatured( void ); // Execute the de-featured Filter Flush state machine +BOOL isFilterFlushDefComplete( void ); // returns if de-featured flush is complete +void signalStartDefFilterFlush( void ); // signal to start de-featured flush +void resetFilterFlushDefSignals( void ); // reset signals for de-featured flush + +FP_FILTER_FLUSH_STATE_T getCurrentFilterFlushState( void ); // Get the current state of the de-featured Filter Flush + +BOOL testFilterFlushDataPublishIntervalOverride( MESSAGE_T *message ); +BOOL testFilterFlushTimerOverride( MESSAGE_T *message ); + +/**@}*/ + +#endif // __FLUSH_FILTER_DEFEATURED_H__