/************************************************************************** * * 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 Valves.c * * @author (last) Vinayakam Mani * @date (last) 14-Aug-2024 * * @author (original) Vinayakam Mani * @date (original) 14-Aug-2024 * ***************************************************************************/ #include // For memcpy #include "FPGADD.h" #include "MessageSupport.h" #include "Messaging.h" #include "TaskPriority.h" #include "Timers.h" #include "Valves.h" /** * @addtogroup Valves * @{ */ // ********** private definitions ********** // ********** private data ********** static U32 numberOfValves; ///< Number of valves used in the module static U32 *pendingValveStateChangesPtr; ///< Pointer to delayed (pending) valve state changes. static U32 *pendingValveStateChangeCountDownsPtr; ///< Pointer to delayed (pending) valve state change count down timers (in task intervals). static OVERRIDE_U32_T *valveStatesPtr; ///< Pointer to currently commanded valves states. static OVERRIDE_U32_T *valveSensedStatesPtr; ///< Pointer to valve sensed states override. // ********** private function prototypes ********** static U32 convertValveStateNameToValveState( VALVE_STATE_NAMES_T valveStateName ); static U32 getValveState( U32 valveID ); /*********************************************************************//** * @brief * The initValves function initializes the Valves module common portion. * @details \b Inputs: none * @details \b Outputs: valveStatesPtr, valveSensedStatesPtr, pendingValveStateChangesPtr, * pendingValveStateChangeCountDownsPtr * @param vlveStats currently commended valve state * @param vlveSensStats actual valve state reported by FPGA * @param penVlveStatChngs Delayed (pending) valve state changes * @param penVlveStatChngeCntDns Delayed (pending) valve state change count down timers (in task intervals) * @param numOfValves number of valves * @return none *************************************************************************/ void initValves(OVERRIDE_U32_T vlveStats[], OVERRIDE_U32_T vlveSensStats[], U32 penVlveStatChngs[], U32 penVlveStatChngeCntDns[],U32 numOfValves ) { U32 i; numberOfValves = numOfValves; valveStatesPtr = vlveStats; valveSensedStatesPtr = vlveSensStats; pendingValveStateChangesPtr = penVlveStatChngs; pendingValveStateChangeCountDownsPtr = penVlveStatChngeCntDns; // initialize commanded valve states for ( i = 0; i < numOfValves; i++ ) { valveStatesPtr[i].data = DEENERGIZED; valveStatesPtr[i].ovInitData = DEENERGIZED; valveStatesPtr[i].ovData = DEENERGIZED; valveStatesPtr[i].override = OVERRIDE_RESET; pendingValveStateChangesPtr[i] = DEENERGIZED; pendingValveStateChangeCountDownsPtr[i] = 0; valveSensedStatesPtr[i].data = DEENERGIZED; valveSensedStatesPtr[i].ovInitData = DEENERGIZED; valveSensedStatesPtr[i].ovData = DEENERGIZED; valveSensedStatesPtr[i].override = OVERRIDE_RESET; } } /*********************************************************************//** * @brief * The fromU32ArrayToU16 function converts an array of U32 valve states * to U16 valvesStates that can be passed to FPGA for setting valves. * @details \b Inputs: valveStates[] * @details \b Outputs: none * @return converted U16 bit field for currently commanded valve states *************************************************************************/ U16 fromU32ArrayToU16( void ) { U16 result = ALL_VALVES_DEENERGIZED; // start result flag as all valves de-energized U32 i; // flag valves that are currently commanded to be energized for ( i = 0; i < numberOfValves; i++ ) { result |= ( getValveState( i ) == ENERGIZED ? 0x0001 << i : 0 ); } return result; } /*********************************************************************//** * @brief * The convertValveStateNameToValveState function converts valve state \n * name to its corresponding de-energized (0) or energized (1) valve state. * @details \b Inputs: none * @details \b Outputs: none * @details \b Alarm : ALARM_ID_XX_SOFTWARE_FAULT when invalid valve state name passed * @param valveStateName valve state name enumeration to convert to energized/de-energized * @return converted valve state for given valve state name *************************************************************************/ static U32 convertValveStateNameToValveState( VALVE_STATE_NAMES_T valveStateName ) { U32 vState = DEENERGIZED; // initialize valve state to de-energized switch ( valveStateName ) { case VALVE_STATE_OPEN: vState = ENERGIZED; break; case VALVE_STATE_CLOSED: vState = DEENERGIZED; break; // case VALVE_STATE_OPEN_C_TO_NC: // vState = ENERGIZED; // break; // // case VALVE_STATE_NOFILL_C_TO_NO: // vState = DEENERGIZED; // break; // // case VALVE_STATE_FILL_C_TO_NC: // vState = ENERGIZED; // break; // // case VALVE_STATE_DRAIN_C_TO_NO: // vState = DEENERGIZED; // break; // // case VALVE_STATE_RECIRC_C_TO_NC: // vState = ENERGIZED; // break; // // case VALVE_STATE_R1_C_TO_NO: // vState = DEENERGIZED; // break; // // case VALVE_STATE_R1_C_TO_NC: // vState = ENERGIZED; // break; // // case VALVE_STATE_R2_C_TO_NO: // vState = DEENERGIZED; // break; // // case VALVE_STATE_R2_C_TO_NC: // vState = ENERGIZED; // break; default: #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, valveStateName ) #endif #ifdef _RO_ // define RO alarm #endif break; } return vState; } /*********************************************************************//** * @brief * The setValveState function sets the valve state for given valve. * @details \b Inputs: none * @details \b Outputs: valveStates[], pendingValveStateChanges[], pendingValveStateChangeCountDowns[] * @details \b Alarm: ALARM_ID_XX_SOFTWARE_FAULT when invalid valve ID passed * @param valveID ID of valve to set state for * @param valveStateName name of valve state to set given valve to * @return TRUE if new valve state is set for given valve ID, FALSE if not. *************************************************************************/ BOOL setValveState( VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName ) { BOOL result = FALSE; // initialize result flag to FALSE if ( valveID < numberOfValves ) { if ( TRUE == checkValveStateName( valveID, valveStateName ) ) { valveStatesPtr[ valveID ].data = convertValveStateNameToValveState( valveStateName ); result = TRUE; // If a delayed state change is pending for this valve, cancel it pendingValveStateChangesPtr[ valveID ] = DEENERGIZED; pendingValveStateChangeCountDownsPtr[ valveID ] = 0; } } else { #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) #endif #ifdef _RO_ // define RO alarm #endif } return result; } /*********************************************************************//** * @brief * The setValveStateDelayed function sets the valve state for given valve * after a given delay. * @details \b Inputs: pendingValveStateChangeCountDowns[] * @details \b Outputs: pendingValveStateChangeCountDowns[], pendingValveStateChangeCountDowns[] * @details \b Alarm: ALARM_ID_XX_SOFTWARE_FAULT when invalid valve ID passed * @param valveID ID of valve to set state for * @param valveStateName name of valve state to set given valve to * @param delayMs delay duration (in ms) before actuation * @return TRUE if new valve state is set for given valve ID, FALSE if not. *************************************************************************/ BOOL setValveStateDelayed( VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName, U32 delayMs ) { BOOL result = FALSE; // initialize result flag to FALSE if ( valveID < numberOfValves ) { if ( TRUE == checkValveStateName( valveID, valveStateName ) ) { // If a delayed state change is already pending for this valve, execute it now before setting a new delayed state change if ( pendingValveStateChangeCountDownsPtr[ valveID ] > 0 ) { valveStatesPtr[ valveID ].data = pendingValveStateChangesPtr[ valveID ]; } // Set delayed valve state change pendingValveStateChangesPtr[ valveID ] = convertValveStateNameToValveState( valveStateName ); pendingValveStateChangeCountDownsPtr[ valveID ] = delayMs / TASK_PRIORITY_INTERVAL; result = TRUE; } } else { #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) #endif #ifdef _RO_ // define RO alarm #endif } return result; } /*********************************************************************//** * @brief * The getValveState function gets the current valve state for given valve. * @details \b Inputs: valveStates[] * @details \b Outputs: none * @details \b Alarm : ALARM_ID_XX_SOFTWARE_FAULT when invalid valve ID passed * @param valveID ID of valve to get state for * @return the current valve state for given valve *************************************************************************/ static U32 getValveState( U32 valveID ) { U32 valveState = DEENERGIZED; if ( valveID < numberOfValves ) { valveState = getU32OverrideValue( &valveStatesPtr[ valveID ] ); } else { #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) #endif #ifdef _RO_ // define RO alarm #endif } return valveState; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetValveStateOverride function overrides the value of the * specified valve with a given value. * @details \b Inputs: none * @details \b Outputs: valves[] * @param valveID ID of valve to override for * @param value override value for the given valve ID * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetValveStateOverride( U32 valveID, U32 value ) { BOOL result = FALSE; if ( valveID < numberOfValves ) { if ( TRUE == isTestingActivated() ) { valveStatesPtr[ valveID ].ovData = value; valveStatesPtr[ valveID ].override = OVERRIDE_KEY; result = TRUE; } } return result; } /*********************************************************************//** * @brief * The testResetValveStateOverride function resets the override of the specified valve. * @details \b Inputs: none * @details \b Outputs: valves[] * @param valveID ID of valve to reset override state for * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetValveStateOverride( U32 valveID ) { BOOL result = FALSE; if ( valveID < numberOfValves ) { if ( TRUE == isTestingActivated() ) { result = TRUE; valveStatesPtr[ valveID ].override = OVERRIDE_RESET; valveStatesPtr[ valveID ].ovData = valveStatesPtr[ valveID ].ovInitData; } } return result; } /*********************************************************************//** * @brief * The testSetValveSensedStateOverride function overrides the value of the * specified sensed state with a given value. * @details \b Inputs: none * @details \b Outputs: valveSensedStates * @param valve ID of valve to override for * @param value override value for the given valve ID * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetValveSensedStateOverride( U32 valve, U32 status ) { BOOL result = FALSE; if ( valve < numberOfValves ) { if ( TRUE == isTestingActivated() ) { valveSensedStatesPtr[ valve ].ovData = status; valveSensedStatesPtr[ valve ].override = OVERRIDE_KEY; result = TRUE; } } return result; } /*********************************************************************//** * @brief * The testResetValveSensedStateOverride function resets the override of * the specified valve's sensed state. * @details \b Inputs: none * @details \b Outputs: valveSensedStates * @param valve ID of valve to reset override state for * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetValveSensedStateOverride( U32 valve ) { BOOL result = FALSE; if ( valve < numberOfValves ) { if ( TRUE == isTestingActivated() ) { valveSensedStatesPtr[ valve ].override = OVERRIDE_RESET; valveSensedStatesPtr[ valve ].ovData = valveSensedStatesPtr[ valve ].ovInitData; result = TRUE; } } return result; } /**@}*/