/************************************************************************** * * 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 FlushFilter.c * * @author (last) Michael Garthwaite * @date (last) 28-Feb-2025 * * @author (original) Michael Garthwaite * @date (original) 28-Feb-2025 * ***************************************************************************/ #include "FlushFilter.h" #include "FPOperationModes.h" #include "MessageSupport.h" #include "Messaging.h" #include "Pressure.h" #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" /** * @addtogroup FPFilterFlush * @{ */ // ********** private definitions ********** #define FILTER_FLUSH_MAX_TIMEOUT ( 600 * 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 ( 30 * MS_PER_SECOND ) ///< Filter flush timer (in ms) #define FILTER_HEALTH_PRESSURE_DIFF 15 ///< Filter flush pressure difference threshold for alarm // ********** private data ********** static FP_FILTER_FLUSH_STATE_T filterFlushState; ///< Currently active filter flush state. static U32 filterFlushDataPublicationTimerCounter; ///< Used to schedule filter flush data publication to CAN bus. static OVERRIDE_U32_T filterFlushDataPublishInterval; ///< Filter Flush mode data publish interval. static OVERRIDE_U32_T filterFlushTimeout; ///< Filter Flush timeout value static U32 filterFlushTimer; ///< Filter Flush timeout timer static BOOL pendingStartFilterFlushRequest; ///< signal to start flushing. static BOOL isFlushComplete; ///< Filter Flush complete BOOL // ********** private function prototypes ********** static void publishFilterFlushData( void ); static FP_FILTER_FLUSH_STATE_T handleFilterFlushProgressState( void ); static FP_FILTER_FLUSH_STATE_T handleFilterFlushPausedState( void ); static void setFilterFlushTransition( FP_FILTER_FLUSH_STATE_T state ); static U32 getFilterFlushTimeout( void ); static U32 getFilterFlushPublishInterval( void ); /*********************************************************************//** * @brief * The initFilterFlush function initializes the filter flush unit. * @details \b Inputs: none * @details \b Outputs: filter flush unit initialized * @return none *************************************************************************/ void initFilterFlush( void ) { filterFlushState = FILTER_FLUSH_PAUSED; filterFlushDataPublishInterval.data = FILTER_FLUSH_DATA_PUBLISH_INTERVAL; filterFlushDataPublishInterval.ovData = FILTER_FLUSH_DATA_PUBLISH_INTERVAL; filterFlushDataPublishInterval.ovInitData = 0; filterFlushDataPublishInterval.override = OVERRIDE_RESET; filterFlushTimeout.data = FILTER_FLUSH_TIMEOUT; filterFlushTimeout.ovData = FILTER_FLUSH_TIMEOUT; filterFlushTimeout.ovInitData = 0; filterFlushTimeout.override = OVERRIDE_RESET; filterFlushDataPublicationTimerCounter = 0; filterFlushTimer = 0; isFlushComplete = FALSE; pendingStartFilterFlushRequest = FALSE; } /*********************************************************************//** * @brief * The execFilterFlush function executes the filter flush state machine * and publishes filter flush data. * @details \b Inputs: filterFlushState * @details \b Outputs: filterFlushState * @details \b Alarm: ALARM_ID_FP_SOFTWARE_FAULT if in invalid flush state * @return none *************************************************************************/ void execFilterFlush( void ) { FP_FILTER_FLUSH_STATE_T prevState = filterFlushState; switch ( filterFlushState ) { case FILTER_FLUSH_IN_PROGRESS: filterFlushState = handleFilterFlushProgressState(); break; case FILTER_FLUSH_PAUSED: filterFlushState = handleFilterFlushPausedState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_FP_INVALID_FILTER_FLUSH_STATE, (U32)filterFlushState ) filterFlushState = FILTER_FLUSH_PAUSED; break; } if ( prevState != filterFlushState ) { setFilterFlushTransition( filterFlushState ); } // publish filter flush data on interval publishFilterFlushData(); } /*********************************************************************//** * @brief * The handleFilterFlushProgressState handles the in progress state of filter flush * @details \b Inputs: filterFlushTimer * @details \b Outputs: none * @return the next state of filter flush state *************************************************************************/ static FP_FILTER_FLUSH_STATE_T handleFilterFlushProgressState( void ) { FP_FILTER_FLUSH_STATE_T state = FILTER_FLUSH_IN_PROGRESS; BOOL isPressureOutOfRange = FALSE; F32 pressureDif = 0.0; // if ( TRUE == 1 )// TODO Alarm and Stop State Rework // { // state = FILTER_FLUSH_PAUSED; // } if( TRUE == didTimeout( filterFlushTimer, getFilterFlushTimeout() ) ) { pressureDif = fabs( getFilteredPressure(M3_PRES) - getFilteredPressure(P8_PRES) ); isPressureOutOfRange = ( pressureDif > FILTER_HEALTH_PRESSURE_DIFF ? TRUE : FALSE ); if( TRUE == isPressureOutOfRange ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_FILTER_HEALTH_PRESSURE_OUT_OF_RANGE, pressureDif, FILTER_HEALTH_PRESSURE_DIFF ); state = FILTER_FLUSH_PAUSED; } else { isFlushComplete = TRUE; state = FILTER_FLUSH_PAUSED; } } return state; } /*********************************************************************//** * @brief * The handleFilterFlushProgressState handles the in progress state of filter flush * @details \b Inputs: pendingStartFilterFlushRequest * @details \b Outputs: pendingStartFilterFlushRequest, isFlushComplete * @return the next state of filter flush state *************************************************************************/ static FP_FILTER_FLUSH_STATE_T handleFilterFlushPausedState( void ) { FP_FILTER_FLUSH_STATE_T state = FILTER_FLUSH_PAUSED; if ( TRUE == pendingStartFilterFlushRequest ) { isFlushComplete = FALSE; pendingStartFilterFlushRequest = FALSE; state = FILTER_FLUSH_IN_PROGRESS; } return state; } /*********************************************************************//** * @brief * The setFilterFlushTransition function sets the actuators and variables * for the state transition in filter flush mode. * @details Inputs: Valve states, Pump speed * @details Outputs: Actuate valves, pumps as desired. * @param state filter flush state enum * @return none *************************************************************************/ static void setFilterFlushTransition( FP_FILTER_FLUSH_STATE_T state ) { // Execute on running state switch( state ) { case FILTER_FLUSH_IN_PROGRESS: setValveState( M4_VALV, VALVE_STATE_OPEN ); setValveState( M7_VALV, VALVE_STATE_CLOSED ); setValveState( P6_VALV, VALVE_STATE_OPEN ); 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_OPEN ); setValveState( P20_VALV, VALVE_STATE_CLOSED ); setValveState( P43_VALV, VALVE_STATE_CLOSED ); filterFlushTimer = getMSTimerCount(); break; case FILTER_FLUSH_PAUSED: // close only if we actually pause during flush if ( FALSE == isFilterFlushComplete() ) { 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 ); } break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_FP_INVALID_FILTER_FLUSH_STATE, state ) break; } } /*********************************************************************//** * @brief * The signalStartFilterFlush function signals the FP to start filter flush. * @details \b Inputs: filterFlushState * @details \b Outputs: pendingStartFilterFlushRequest * @return none *************************************************************************/ void signalStartFilterFlush( void ) { if ( FILTER_FLUSH_PAUSED == getCurrentFilterFlushState() ) { pendingStartFilterFlushRequest = TRUE; } } /*********************************************************************//** * @brief * The resetFilterFlushSignals function resets the signal values for * FP filter flush. * @details \b Inputs: none * @details \b Outputs: pendingStartFilterFlushRequest, isFlushComplete * @return none *************************************************************************/ void resetFilterFlushSignals( void ) { pendingStartFilterFlushRequest = FALSE; isFlushComplete = FALSE; } /*********************************************************************//** * @brief * The getCurrentFilterFlushState 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_STATE_T getCurrentFilterFlushState( void ) { return filterFlushState; } /*********************************************************************//** * @brief * The isFilterFlushComplete function returns isFilterFlushComplete. * @details \b Inputs: isFlushComplete * @details \b Outputs: none * @return TRUE if filter flush is complete, FALSE if not. *************************************************************************/ BOOL isFilterFlushComplete( void ) { return isFlushComplete; } /*********************************************************************//** * @brief * The getFilterFlushTimeout function gets the generate water * mode data publish interval. * @details \b Inputs: filterFlushTimeOut * @details \b Outputs: none * @return the timeout timer for filter flush. *************************************************************************/ static U32 getFilterFlushTimeout( void ) { U32 result = getU32OverrideValue( &filterFlushTimeout ); return result; } /*********************************************************************//** * @brief * The getFilterFlushPublishInterval function gets the filter flush * mode data publish interval. * @details \b Inputs: filterFlushDataPublishInterval * @details \b Outputs: none * @return the interval at filter flush mode data being published. *************************************************************************/ static U32 getFilterFlushPublishInterval( void ) { U32 result = getU32OverrideValue( &filterFlushDataPublishInterval ); return result; } /*********************************************************************//** * @brief * The publishFilterFlushData function broadcasts the filter flush * mode data at defined interval. * @details \b Inputs: filterFlushDataPublicationTimerCounter * @details \b Outputs: fp filter flush 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 publishFilterFlushData( void ) { if ( ++filterFlushDataPublicationTimerCounter >= getFilterFlushPublishInterval() ) { FILTER_FLUSH_DATA_T data; data.filterFlushExecState = (U32)getCurrentFilterFlushState(); broadcastData( MSG_ID_FP_FILTER_FLUSH_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( FILTER_FLUSH_DATA_T ) ); filterFlushDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testFilterFlushDataPublishIntervalOverride function overrides the * FP filter flush mode data publish interval. * @details \b Inputs: filterFlushDataPublishInterval * @details \b Outputs: filterFlushDataPublishInterval * @param Override message from Dialin which includes the interval * (in ms) to override the FP filter flush data publish interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testFilterFlushDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &filterFlushDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testFilterFlushTimerOverride function overrides the * FP filter flush timeout value. * @details \b Inputs: filterFlushTimeout * @details \b Outputs: filterFlushTimeout * @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 testFilterFlushTimerOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &filterFlushTimeout, 0, FILTER_FLUSH_MAX_TIMEOUT ); return result; } /**@}*/