/************************************************************************** * * 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 ValvesDD.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 ********** #define DEENERGIZED 0 ///< 0 for de-energized valve. #define ENERGIZED 1 ///< 1 for energized valve. #define ALL_VALVES_DEENERGIZED 0x0000 ///< 0 in U16 bit field for all valves. #define MAX_VALVE_STATE_MISMATCH_TIMER_COUNT (100 / TASK_PRIORITY_INTERVAL ) ///< Maximum time commanded valves state can fail to match read back valve states in a row. #define VALVES_STATE_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval ( ms / task time) at which valves states are published on CAN bus. #define DATA_PUBLISH_COUNTER_START_COUNT 50 ///< Data publish counter start count. /// Payload record structure for valve open/close request typedef struct { U32 valveID; ///< ValveID ( valid range 0 to 28 ) U32 valveState; ///< Valve state ( Open : 0, closed :1) } VALVE_CMD_PAYLOAD_T; // ********** private data ********** static U32 valvesStatesPublicationTimerCounter; ///< Timer counter used to schedule valve state publication to CAN bus. static U32 fpValveStatesPublicationTimerCounter; ///< Timer counter used to schedule IOFP valve state publication to CAN bus. static U16 commandedValvesStates; ///< Initialize commanded valves states bit field. static U08 commandedBCValveStates; ///< Initialize balancing chamber commanded valves states bit field. static U16 commandedIOFPValveStates; ///< Initialize commanded IOFP valves states bit field. static U32 valveStateMismatchTimerCounter; ///< Initialize valve state mismatch timer. static U32 pendingValveStateChanges[ DD_NUM_OF_VALVES ]; ///< Delayed (pending) valve state changes. static U32 pendingValveStateChangeCountDowns[ DD_NUM_OF_VALVES ]; ///< Delayed (pending) valve state change count down timers (in task intervals). static OVERRIDE_U32_T valveStates[ DD_NUM_OF_VALVES ]; ///< Currently commanded valves states. static OVERRIDE_U32_T valveSensedStates[ DD_NUM_OF_VALVES ]; ///< Valve sensed states override. static OVERRIDE_U32_T valvesStatesPublishInterval; ///< Interval (in ms/task interval) at which to publish valves state to CAN bus. static OVERRIDE_U32_T fpValveStatesPublishInterval; ///< Interval (in ms/task interval) at which to publish valves state to CAN bus. // ********** private function prototypes ********** static void publishValvesStates( void ); static void readCommandedValveStates( void ); static BOOL checkValveStateName( DD_VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName ); static U32 convertValveStateNameToValveState( VALVE_STATE_NAMES_T valveStateName ); static U32 getValveState( U32 valveID ); /*********************************************************************//** * @brief * The initValves function initializes the Valves unit. * @details \b Inputs: none * @details \b Outputs: Valves unit initialized. * @return none *************************************************************************/ void initValves( void ) { U32 i; // Initialize publish interval overrides valvesStatesPublishInterval.data = VALVES_STATE_PUB_INTERVAL; valvesStatesPublishInterval.ovData = VALVES_STATE_PUB_INTERVAL; valvesStatesPublishInterval.ovInitData = 0; valvesStatesPublishInterval.override = OVERRIDE_RESET; fpValveStatesPublishInterval.data = VALVES_STATE_PUB_INTERVAL; fpValveStatesPublishInterval.ovData = VALVES_STATE_PUB_INTERVAL; fpValveStatesPublishInterval.ovInitData = 0; fpValveStatesPublishInterval.override = OVERRIDE_RESET; // Initialize commanded valve states for ( i = 0; i < DD_NUM_OF_VALVES; i++ ) { valveStates[ i ].data = DEENERGIZED; valveStates[ i ].ovInitData = DEENERGIZED; valveStates[ i ].ovData = DEENERGIZED; valveStates[ i ].override = OVERRIDE_RESET; valveSensedStates[ i ].data = DEENERGIZED; valveSensedStates[ i ].ovInitData = DEENERGIZED; valveSensedStates[ i ].ovData = DEENERGIZED; valveSensedStates[ i ].override = OVERRIDE_RESET; pendingValveStateChanges[ i ] = DEENERGIZED; pendingValveStateChangeCountDowns[ i ] = 0; } // Initialize the commanded valve states commandedValvesStates = ALL_VALVES_DEENERGIZED; commandedBCValveStates = ALL_VALVES_DEENERGIZED; commandedIOFPValveStates = ALL_VALVES_DEENERGIZED; valveStateMismatchTimerCounter = 0; valvesStatesPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; // reset valves states publication timer fpValveStatesPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; // reset valves states publication timer readCommandedValveStates(); // initially set all valves to de-energized state via FPGA setFPGADDValveStates( commandedValvesStates ); setFPGABCValveStates( commandedBCValveStates ); setFPGAIOFPValveStates( commandedIOFPValveStates ); } /*********************************************************************//** * @brief * The execValves function executes the valves driver. * @details \b Inputs: valvesStates, valveStateMismatchCounter * pendingValveStateChangeCountDowns, commandedValvesStates, * commandedBCValveStates , commandedUFValveStates * @details \b Outputs: valvesStates, valveStateMismatchCounter * pendingValveStateChanges, valve controls * @details \b Alarm: ALARM_ID_DD_VALVE_CONTROL_FAILURE when FPGA read back * valve state mismatches with the commanded valve state after defined time (100ms). * @return none *************************************************************************/ void execValves( void ) { U32 i; U16 readValvesStates = getFPGADDValveStates(); U08 readValveBCStates = getFPGAValveBCStates(); U16 readValveIOFPStates = getFPGAIOFPValveStates(); // Verify read back FPGA valve states match last commanded valve states if ( ( readValvesStates != commandedValvesStates ) || ( readValveBCStates != commandedBCValveStates ) || ( readValveIOFPStates != commandedIOFPValveStates ) ) { valveStateMismatchTimerCounter++; // increment valve state mismatch counter by 1 if ( valveStateMismatchTimerCounter > MAX_VALVE_STATE_MISMATCH_TIMER_COUNT ) { activateAlarmNoData( ALARM_ID_DD_VALVE_CONTROL_FAILURE ); } } else { valveStateMismatchTimerCounter = 0; } // Handle pending delayed valve state changes for ( i = 0; i < DD_NUM_OF_VALVES; i++ ) { if ( pendingValveStateChangeCountDowns[ i ] > 0 ) { pendingValveStateChangeCountDowns[ i ]--; if ( 0 == pendingValveStateChangeCountDowns[ i ] ) { valveStates[ i ].data = pendingValveStateChanges[ i ]; pendingValveStateChanges[ i ] = DEENERGIZED; } } } // Set valves states (via FPGA) to currently commanded states readCommandedValveStates(); setFPGADDValveStates( commandedValvesStates ); setFPGABCValveStates( commandedBCValveStates ); setFPGAIOFPValveStates( commandedIOFPValveStates ); // Publish valve states on interval publishValvesStates(); } /*********************************************************************//** * @brief * The readCommandedValveStates function gets the hydraulics, Balancing chamber * and Ultrafiltration valvesStates that can be passed to FPGA for setting valves. * @details \b Inputs: valveStates[] * @details \b Outputs: commandedValvesStates,commandedBCValveStates, * commandedUFValveStates * @return converted U16 and U08 bit field for currently commanded valve states *************************************************************************/ static void readCommandedValveStates( void ) { U32 i; // Initiliaze before updating commanded states commandedValvesStates = ALL_VALVES_DEENERGIZED; commandedBCValveStates = ALL_VALVES_DEENERGIZED; commandedIOFPValveStates = ALL_VALVES_DEENERGIZED; // flag hydraulics valves that are currently commanded to be energized for ( i = FIRST_HYD_VALVE; i <= LAST_HYD_VALVE; i++ ) { commandedValvesStates |= ( getValveState( i ) == ENERGIZED ? 0x0001 << i : 0 ); } // flag Balancing chamber valves that are currently commanded to be energized for ( i = FIRST_BC_VALVE; i <= LAST_BC_VALVE; i++ ) { commandedBCValveStates |= ( getValveState( i ) == ENERGIZED ? 0x01 << ( i - FIRST_BC_VALVE ) : 0 ); } } /*********************************************************************//** * @brief * The checkValveStateName function checks the validity of requested valve * state name for given valve. * @details \b Inputs: none * @details \b Outputs: none * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid valve ID passed. * @param valveID ID of valve to check a valve state name for * @param valveStateName valve state name to check for given valve ID * @return TRUE if given valveStateName is appropriate for given valve ID, FALSE if not. *************************************************************************/ static BOOL checkValveStateName( DD_VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName ) { BOOL result = FALSE; // initialize result flag to FALSE switch ( valveStateName ) { case VALVE_STATE_OPEN: case VALVE_STATE_CLOSED: if ( ( D53_VALV == valveID ) || ( D52_VALV == valveID ) || ( D8_VALV == valveID ) || ( D54_VALV == valveID ) || ( D14_VALV == valveID ) || ( D65_VALV == valveID ) || ( D64_VALV == valveID ) || ( D31_VALV == valveID ) || ( D34_VALV == valveID ) || ( D35_VALV == valveID ) || ( D40_VALV == valveID ) || ( D47_VALV == valveID ) || ( D3_VALV == valveID ) || ( M4_VALV == valveID ) || ( D23_VALV == valveID ) || ( D19_VALV == valveID ) || ( D25_VALV == valveID ) || ( D21_VALV == valveID ) || ( D24_VALV == valveID ) || ( D20_VALV == valveID ) || ( D26_VALV == valveID ) || ( D22_VALV == valveID ) ) { result = TRUE; } break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, valveStateName ) break; } 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_DD_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; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, valveStateName ) 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_DD_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( DD_VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName ) { BOOL result = FALSE; // initialize result flag to FALSE if ( valveID < DD_NUM_OF_VALVES ) { if ( TRUE == checkValveStateName( valveID, valveStateName ) ) { valveStates[ valveID ].data = convertValveStateNameToValveState( valveStateName ); result = TRUE; // If a delayed state change is pending for this valve, cancel it pendingValveStateChanges[ valveID ] = DEENERGIZED; pendingValveStateChangeCountDowns[ valveID ] = 0; } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) } 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_DD_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( DD_VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName, U32 delayMs ) { BOOL result = FALSE; // initialize result flag to FALSE if ( valveID < DD_NUM_OF_VALVES ) { 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 ( pendingValveStateChangeCountDowns[ valveID ] > 0 ) { valveStates[ valveID ].data = pendingValveStateChanges[ valveID ]; } // Set delayed valve state change pendingValveStateChanges[ valveID ] = convertValveStateNameToValveState( valveStateName ); pendingValveStateChangeCountDowns[ valveID ] = delayMs / TASK_PRIORITY_INTERVAL; result = TRUE; } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) } return result; } /*********************************************************************//** * @brief * The getValveStateName function gets the current valve state enum for given valve. * @details \b Inputs: valveStates[] * @details \b Outputs: none * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid valve ID passed. * @param valveID ID of valve to get state for * @return the current valve state for given valve in enum *************************************************************************/ VALVE_STATE_NAMES_T getValveStateName( DD_VALVES_T valveID ) { // Initialized per CppCheck. VALVE_STATE_NAMES_T name = NUM_OF_VALVE_STATES; if ( valveID < DD_NUM_OF_VALVES ) { U32 valveState = getU32OverrideValue( &valveSensedStates[ valveID ] ); name = ( DEENERGIZED == valveState ? VALVE_STATE_CLOSED : VALVE_STATE_OPEN ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) } return name; } /*********************************************************************//** * @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_DD_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 < DD_NUM_OF_VALVES ) { valveState = getU32OverrideValue( &valveStates[ valveID ] ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) } return valveState; } /*********************************************************************//** * @brief * The setHydValvesStatetoClosedState function sets all Hydraulics / DD * valves to close state except balancing chamber, UF and Inlet water control. * @details \b Inputs: none * @details \b Outputs: valve states * @return none. *************************************************************************/ void setHydValvesStatetoClosedState( void ) { DD_VALVES_T valve; // Set all Hydraulics valves to closed state for ( valve = FIRST_HYD_VALVE; valve < LAST_HYD_VALVE; valve++ ) { setValveState( valve, VALVE_STATE_CLOSED ); } } /*********************************************************************//** * @brief * The publishValvesStates function publishes DD valves states at the set interval. * @details \b Inputs: valvesStatesPublicationTimerCounter * @details \b Outputs: valvesStatesPublicationTimerCounter * @details \b Messages: MSG_ID_DD_VALVES_STATES_DATA to publish FPGA read valve states. * @return none *************************************************************************/ static void publishValvesStates( void ) { // publish DD valve states on interval if ( ++valvesStatesPublicationTimerCounter >= getU32OverrideValue( &valvesStatesPublishInterval ) ) { DD_VALVES_DATA_T data; U32 i; data.valvesStatus = commandedValvesStates; data.valvesBCStatus = commandedBCValveStates; for ( i = 0; i < LAST_DD_VALVE; i++ ) { data.valvesSensedState[ i ] = (U08)getValveStateName( (DD_VALVES_T)i ); } broadcastData( MSG_ID_DD_VALVES_STATES_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( DD_VALVES_DATA_T ) ); valvesStatesPublicationTimerCounter = 0; } // publish IOFP valve states on interval if ( ++fpValveStatesPublicationTimerCounter >= getU32OverrideValue( &fpValveStatesPublishInterval ) ) { FP_VALVES_DATA_T data; U32 i; data.valvesCmdState = commandedIOFPValveStates; for ( i = FIRST_IO_VALVE; i < LAST_FP_VALVE; i++ ) { data.valvesSensedState[ i ] = (U08)getValveStateName( (DD_VALVES_T)i ); } broadcastData( MSG_ID_FP_VALVES_STATES_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( FP_VALVES_DATA_T ) ); fpValveStatesPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testValvesStatesPublishIntervalOverride function overrides the * valves states publish interval. * @details \b Inputs: none * @details \b Outputs: valvesStatesPublishInterval * @param message Override message from Dialin which includes the value * that override valves states publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testValvesStatesPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &valvesStatesPublishInterval, TASK_PRIORITY_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testValveStateOverride function overrides the value of the * specified valve with a given value. * @details \b Inputs: none * @details \b Outputs: valveStates[] * @param message Override message from Dialin which includes an ID of * the valve to override and the state to override the valve to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testValveStateOverride( MESSAGE_T *message ) { BOOL result = FALSE; TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &payload ); if ( payload.index <= LAST_DD_VALVE ) { result = u32ArrayOverride( message, &valveStates[0], DD_NUM_OF_VALVES - 1, 0, NUM_OF_VALVE_STATES - 1 ); } return result; } /*********************************************************************//** * @brief * The testBCValveStatesOverride function overrides the state of all * balancing chamber valves with a given bits (corresponding to BC valve * enumeration order). * @details \b Inputs: none * @details \b Outputs: valveStates[] * @param message Override message from Dialin which includes the states * to override the balancing chamber valves to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testBCValveStatesOverride( MESSAGE_T *message ) { DD_BC_VALVE_OVERRIDE_PAYLOAD_T payload; DD_VALVES_T valve; BOOL result = FALSE; memcpy( (U08*)(&payload), message->payload, sizeof( DD_BC_VALVE_OVERRIDE_PAYLOAD_T ) ); for ( valve = FIRST_BC_VALVE; valve <= LAST_BC_VALVE; valve++ ) { U32 mask = 0x1 << (valve - FIRST_BC_VALVE); VALVE_STATE_NAMES_T pos = ( ( ( payload.valveStatesBits & mask ) != 0 ) ? VALVE_STATE_OPEN : VALVE_STATE_CLOSED ); result = setValveState( valve, pos ); } return result; } /*********************************************************************//** * @brief * The testValveSensedStateOverride function overrides the value of the * specified sensed state with a given value. * @details \b Inputs: none * @details \b Outputs: valveSensedStates[] * @param message Override message from Dialin which includes an ID of * the valve to override and the state to override the valve to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testValveSensedStateOverride( MESSAGE_T *message ) { BOOL result = FALSE; TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &payload ); if ( payload.index <= LAST_DD_VALVE ) { result = u32ArrayOverride( message, &valveSensedStates[0], DD_NUM_OF_VALVES - 1, 0, NUM_OF_VALVE_STATES - 1 ); } return result; } /*********************************************************************//** * @brief * The testValveOpenCloseStateOverride function overrides the value of the * specified valve with a given value. * @details \b Inputs: tester logged in * @details \b Outputs: valveStates[] * @param message set message from Dialin which includes the valve Id to set * and the state to set the valves to. * @return TRUE if set request is successful, FALSE if not *************************************************************************/ BOOL testValveOpenCloseStateOverride( MESSAGE_T *message ) { BOOL result = FALSE; // Verify tester has logged in with DD if ( TRUE == isTestingActivated() ) { // Verify payload length is valid if ( sizeof( VALVE_CMD_PAYLOAD_T ) == message->hdr.payloadLen ) { VALVE_CMD_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(VALVE_CMD_PAYLOAD_T) ); if ( ( (DD_VALVES_T)payload.valveID < DD_NUM_OF_VALVES ) && ( (VALVE_STATE_NAMES_T)payload.valveState < NUM_OF_VALVE_STATES ) ) { setValveState( (DD_VALVES_T)payload.valveID, (VALVE_STATE_NAMES_T)payload.valveState ); result = TRUE; } } } return result; } /*********************************************************************//** * @brief * The testIOFPValvesStatesPublishIntervalOverride function overrides the * IOFP valves states publish interval. * @details \b Inputs: none * @details \b Outputs: valvesStatesPublishInterval * @param message Override message from Dialin which includes the value * that override valves states publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testIOFPValvesStatesPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &fpValveStatesPublishInterval, TASK_PRIORITY_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testIOFPValveStateOverride function overrides the value of the * specified IOFP valve with a given value. * @details \b Inputs: none * @details \b Outputs: valveStates[] * @param message Override message from Dialin which includes an ID of * the valve to override and the state to override the valve to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testIOFPValveStateOverride( MESSAGE_T *message ) { BOOL result = FALSE; TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &payload ); if ( ( payload.index >= FIRST_IO_VALVE ) && ( payload.index <= LAST_FP_VALVE ) ) { result = u32ArrayOverride( message, &valveStates[0], DD_NUM_OF_VALVES - 1, 0, NUM_OF_VALVE_STATES - 1 ); } return result; } /*********************************************************************//** * @brief * The testIOFPValveSensedStateOverride function overrides the value of the * specified sensed state of an IOFP valve with a given value. * @details \b Inputs: none * @details \b Outputs: valveSensedStates[] * @param message Override message from Dialin which includes an ID of * the valve to override and the state to override the valve to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testIOFPValveSensedStateOverride( MESSAGE_T *message ) { BOOL result = FALSE; TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &payload ); if ( ( payload.index >= FIRST_IO_VALVE ) && ( payload.index <= LAST_FP_VALVE ) ) { result = u32ArrayOverride( message, &valveSensedStates[0], DD_NUM_OF_VALVES - 1, 0, NUM_OF_VALVE_STATES - 1 ); } return result; } /**@}*/