/**********************************************************************//** * * Copyright (c) 2020-2020 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 * * @date 21-Apr-2020 * @author P. Montazemi * * @brief Valves source file. * **************************************************************************/ #include "AlarmMgmt.h" #include "FPGA.h" #include #include "OperationModes.h" #include "stdbool.h" #include "SystemCommMessages.h" #include "TaskPriority.h" #include "Timers.h" #include "Valves.h" /** * @addtogroup DGValves * @{ */ // ********** private definitions ********** #define DEENERGIZED 0 /// 0 for de-energized valve #define ENERGIZED 1 /// 1 for energized valve #define INIT_VALVES_STATES 0 /// 0 in U16 initial state of all valves /// Default publication interval for valves states #define VALVES_STATE_PUB_INTERVAL ( 500 / TASK_PRIORITY_INTERVAL ) ///< interval ( ms / task time) at which valves states are published on CAN bus // ********** private data ********** static U16 valvesStates = INIT_VALVES_STATES; ///< initialize valves states for FPGA to set static U32 valvesStatesPublicationTimerCounter = 0; ///< used to schedule valve state publication to CAN bus static int execValvesCounter = 0; ///< initialize execValves counter static OVERRIDE_U32_T valves[ NUM_OF_VALVES ]; ///< Current valves states static OVERRIDE_U32_T valvesStatesPublishInterval = { VALVES_STATE_PUB_INTERVAL, VALVES_STATE_PUB_INTERVAL, 0, 0 }; ///< interval (in ms/task interval) at which to publish valves state to CAN bus // ********** private function prototypes ********** static BOOL checkValves( VALVES_T valve, VALVE_STATES_T valveState ); ///< check validity of requested valve state U16 fromIntArrayToU16( int array[ NUM_OF_VALVES ] ); ///< convert array of Int to U16 for statesValves preparation static void publishValvesStates( void ); static DATA_GET_PROTOTYPE( U32, getPublishValvesStatesInterval ); /**@}*/ /*********************************************************************//** * @brief * The initValves function initializes the Valves module. * @details * Inputs : none * Outputs : Valves module initialized. * @return none *************************************************************************/ void initValves( void ) { setFPGAValveStates( INIT_VALVES_STATES ); // initially set all valves to de-energized state via FPGA valvesStatesPublicationTimerCounter = 0; // reset valves states publication timer } /*********************************************************************//** * @brief * The execValves function executes the valves driver. * @details * Inputs : valvesStates * Outputs : valvesStates * @return none *************************************************************************/ void execValves( void ) { execValvesCounter++; // increment execValves counter by 1 if ( execValvesCounter <= 2 ) { //int i = 0; //for ( valves[ i ]; i <= NUM_OF_VALVES; i++ ) //{ // valvesStates = getFPGAValveStates(); // if ( getValveState( valves [ i ] ) == fromU16ToIntArray( getFPGAValveStates(), i ) // { // setFPGAValveStates( valvesStates ); // set valves states via FPGA // publishValvesStates(); // publish valves states on interval // execValvesCounter = 0; // reset execValves counter // } //} if ( OVERRIDE_KEY == valves[ valve ].override ) { valvesStates = valves[ valve ].ovData; } else { valvesStates = valves[ valve ].data; } setFPGAValveStates( valvesStates ); publishValvesStates(); // publish valves states on interval execValvesCounter = 0; // reset execValves counter } else // if requested valve state does not match FPGA-provided valve state three (3) times in row { activateAlarmNoData( ALARM_ID_VALVE_EXEC_COUNTER_ERROR ); } publishValvesStates(); // publish valves states on interval } /*********************************************************************//** * @brief * The checkValveState function checks the validity of the requested valve \n * state for given valve. * @details * Inputs : valve, valveState * Outputs : none * @return none *************************************************************************/ static BOOL checkValves( VALVES_T valve, VALVE_STATES_T valveState ) { BOOL result = FALSE; // initialize checkValves result flag to FALSE switch ( valveState ) { case VALVE_STATE_OPEN: if ( ( valve == VPI ) || ( valve == VBF ) || ( valve == VSP ) ) { result = TRUE; } break; case VALVE_STATE_CLOSED: if ( ( valve == VPI ) || ( valve == VBF ) || ( valve == VSP ) ) { result = TRUE; } break; case VALVE_STATE_OPEN_C_TO_NO: if ( valve == VPD ) { result = TRUE; } break; case VALVE_STATE_DRAIN_C_TO_NC: if ( valve == VPD ) { result = TRUE; } break; case VALVE_STATE_NOFILL_C_TO_NO: if ( valve == VPO ) { result = TRUE; } break; case VALVE_STATE_FILL_C_TO_NC: if ( valve == VPO ) { result = TRUE; } break; case VALVE_STATE_DRAIN_C_TO_NO: if ( ( valve == VDR ) || ( valve == VRC ) ) { result = TRUE; } break; case VALVE_STATE_RECIRC_C_TO_NC: if ( ( valve == VDR ) || ( valve == VRC ) ) { result = TRUE; } break; case VALVE_STATE_R1_C_TO_NO: if ( ( valve == VRO ) || ( valve == VRI ) ) { result = TRUE; } break; case VALVE_STATE_R1_C_TO_NC: if ( ( valve == VRD ) || ( valve == VRF ) ) { result = TRUE; } break; case VALVE_STATE_R2_C_TO_NO: if ( ( valve == VRD ) || ( valve == VRF ) ) { result = TRUE; } break; case VALVE_STATE_R2_C_TO_NC: if ( ( valve == VRO ) || ( valve == VRI ) ) { result = TRUE; } break; default: activateAlarmNoData( ALARM_ID_VALVE_STATE_CHECK_ERROR ); break; } return result; } /*********************************************************************//** * @brief * The getPublishValveStateInterval function gets the valves states \n * publication interval. * @details * Inputs : valvesStatesPublishInterval * Outputs : none * @return the current valves states publication interval (in task intervals). *************************************************************************/ U32 getPublishValvesStatesInterval( void ) { U32 result = valvesStatesPublishInterval.data; if ( OVERRIDE_KEY == valvesStatesPublishInterval.override ) { result = valvesStatesPublishInterval.ovData; } return result; } /*********************************************************************//** * @brief * The fromIntArrayToU16 function converts an array of Int valve states \n * to U16 valvesStates that can be passed to FPGA for setting valves. * @details * Inputs : none * Outputs : none * @return converted U16 valvesStates *************************************************************************/ U16 fromIntArrayToU16( int array[ NUM_OF_VALVES ] ) { U16 result = 0; // initialize result flag to 0 int i; for ( i = 0; i < NUM_OF_VALVES; i++) { result += array[ i ] * pow( 2, i ); } return result; } /*********************************************************************//** * @brief * The convertToValveState function converts a text-based valve state \n * to its corresponding de-energized (0) or energized (1) valve state. * @details * Inputs : none * Outputs : none * @return converted U32 vState *************************************************************************/ U32 convertToValveState(VALVE_STATES_T valveState) { U32 vState = 0; // initialize state to 0 switch (valveState) { case VALVE_STATE_OPEN: vState = 1; // Energized break; case VALVE_STATE_CLOSED: vState = 0; // De-energized break; case VALVE_STATE_OPEN_C_TO_NO: vState = 0; // De-energized break; case VALVE_STATE_DRAIN_C_TO_NC: vState = 1; // Energized break; case VALVE_STATE_NOFILL_C_TO_NO: vState = 0; // De-energized break; case VALVE_STATE_FILL_C_TO_NC: vState = 1; // Energized break; case VALVE_STATE_DRAIN_C_TO_NO: vState = 0; // De-energized break; case VALVE_STATE_RECIRC_C_TO_NC: vState = 1; // Energized break; case VALVE_STATE_R1_C_TO_NO: vState = 0; // De-energized break; case VALVE_STATE_R1_C_TO_NC: vState = 1; // Energized break; case VALVE_STATE_R2_C_TO_NO: vState = 0; // De-energized break; case VALVE_STATE_R2_C_TO_NC: vState = 1; // Energized break; default: break; } return vState; } /*********************************************************************//** * @brief * The setValveState function sets the valve state for given valve. * @details * Inputs : none * Outputs : none * @return TRUE if new valve state is set for given valve *************************************************************************/ BOOL setValveState( VALVES_T valve, VALVE_STATES_T valveState ) { BOOL result = FALSE; // initialize result flag to FALSE if ( checkValves ( valve, valveState ) ) { if ( OVERRIDE_KEY == valves[ valve ].override ) { valves[ valve ].ovData = convertToValveState( valveState ); } else { valves[ valve ].data = convertToValveState( valveState ); } result = TRUE; } else { activateAlarmNoData( ALARM_ID_VALVE_STATE_ERROR ); } return result; } /*********************************************************************//** * @brief * The getValveState function gets the current valve state for given valve. * @details * Inputs : valveState * Outputs : none * @return the current valve state for given valve. *************************************************************************/ U32 getValveState( U32 valve ) { int valveState = DEENERGIZED; if ( valve < NUM_OF_VALVES ) { if ( OVERRIDE_KEY == valves[ valve ].override ) { valveState = valves[ valve ].ovData; } else { valveState = valves[ valve ].data; } } else { activateAlarmNoData( ALARM_ID_VALVE_ERROR ); } return valveState; } /*********************************************************************//** * * @brief * The publishValvesStates function publishes DG valves states at the \n * set interval. * @details * Inputs : valvesStatesPublicationTimerCounter * Outputs : DG valves states are published to CAN bus * @return none *************************************************************************/ static void publishValvesStates( void ) { // publish valve state on interval if ( ++valvesStatesPublicationTimerCounter >= getPublishValvesStatesInterval() ) { broadcastValvesStates( getFPGAValveStates() ); valvesStatesPublicationTimerCounter = 0; } } /**@}*/ /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetValvesStatesPublishIntervalOverride function overrides the \n * valves states publish interval. * @details * Inputs : none * Outputs : valvesStatesPublishInterval * @param value : override valves states publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetValvesStatesPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_PRIORITY_INTERVAL; result = TRUE; valvesStatesPublishInterval.ovData = intvl; valvesStatesPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetValvesStatesPublishIntervalOverride function resets the override \n * of the valves states publish interval. * @details * Inputs : none * Outputs : valvesStatesPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetValvesStatesPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; valvesStatesPublishInterval.override = OVERRIDE_RESET; valvesStatesPublishInterval.ovData = valvesStatesPublishInterval.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetValveStateOverride function overrides the value of the \n * specified valve with a given value. * Inputs : none * Outputs : valves[] * @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 testSetValveStateOverride( U32 valve, U32 value ) { BOOL result = FALSE; if ( valve < NUM_OF_VALVES ) { if ( TRUE == isTestingActivated() ) { result = TRUE; valves[ valve ].ovData = value; valves[ valve ].override = OVERRIDE_KEY; } } return result; } /*********************************************************************//** * @brief * The testResetValveStateOverride function resets the override of the \n * specified valve. * @details * Inputs : none * Outputs : valves[] * @param value : ID of valve to reset override state for * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetValveStateOverride( U32 valve ) { BOOL result = FALSE; if ( valve < NUM_OF_VALVES ) { if ( TRUE == isTestingActivated() ) { result = TRUE; valves[ valve ].override = OVERRIDE_RESET; valves[ valve ].ovData = valves[ valve ].ovInitData; } } return result; }