/**********************************************************************************************************************
 *  COPYRIGHT
 *  -------------------------------------------------------------------------------------------------------------------
 *  \verbatim
 *  Copyright (c) 2025 by Vector Informatik GmbH.                                                  All rights reserved.
 *
 *                This software is copyright protected and proprietary to Vector Informatik GmbH.
 *                Vector Informatik GmbH grants to you only those rights as set out in the license conditions.
 *                All other rights remain with Vector Informatik GmbH.
 *  \endverbatim
 *  -------------------------------------------------------------------------------------------------------------------
 *  FILE DESCRIPTION
 *  -----------------------------------------------------------------------------------------------------------------*/
/** \file  File:  BrsHw.c
 *      Project:  Vector Basic Runtime System
 *       Module:  BrsHw for platform TexasInstruments Sitara AM263x
 *     Template:  This file is reviewed according to Brs_Template@Implementation[1.03.14]
 *
 *  \brief Description:  This is the hardware specific code file for Vector Basic Runtime System (BRS).
 *
 *  \attention Please note:
 *    The demo and example programs only show special aspects of the software. With regard to the fact
 *    that these programs are meant for demonstration purposes only, Vector Informatik liability shall be
 *    expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute.
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  REVISION HISTORY
 *  -------------------------------------------------------------------------------------------------------------------
 *  Refer to BrsHw.h.
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  EXAMPLE CODE ONLY
 *  -------------------------------------------------------------------------------------------------------------------
 *  This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration.
 *  The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither
 *  intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or
 *  implementations must be tested with diligent care and must comply with all quality requirements which are necessary
 *  according to the state of the art before their use.
 *********************************************************************************************************************/

#define _BRSHW_C_
#define BRSHW_SOURCE

/**********************************************************************************************************************
 *  INCLUDES
 *********************************************************************************************************************/
#include "BrsHw.h"

#if !defined (BRS_DISABLE_OS_USAGE)
  /*
  * BootManager, FlashBootLoader, HSM-Updater and HypervisorMaster execution instances do not use an OS.
  * Define is set in BrsMain.h
  */
  #include "Os.h"
#endif
#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS)
  #include <kernel/dpl/HwiP.h>
  #include <kernel/dpl/ClockP.h>
  #include <kernel/dpl/DebugP.h>
  #include <kernel/dpl/CacheP.h>
  #include <kernel/dpl/MpuP_armv7.h>
  #include <drivers/soc.h>
  #include <kernel/dpl/AddrTranslateP.h>
  #include <drivers/i2c.h>
  #include <drivers/hw_include/cslr_soc.h>
  #include <drivers/soc.h>

  void Dpl_init(void);
  void Dpl_deinit(void);
#endif

/**********************************************************************************************************************
 *  VERSION CHECK
 *********************************************************************************************************************/
#if (BRSHW_MAJOR_VERSION != 1u) || (BRSHW_MINOR_VERSION != 0u)
  #error "Header and source file are inconsistent!"
#endif
#if (BRSHW_PATCH_VERSION != 3u)
  #error "Different versions of patch in Header and Source used!"
#endif

/**********************************************************************************************************************
 *  CONFIGURATION CHECK
 *********************************************************************************************************************/
#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS)

#else
  #error "Unknown compiler specified!"
#endif

#if !defined (BRSMAIN_VERSION_COMBINED)
/* BRSMAIN_VERSION_COMBINED was introduced in BrsMain 2.24.00 - no check needed */
# if (BRSMAIN_VERSION < 0x0221u)
  /* At least BrsMain 2.21.00 is needed for Hypervisor support and definition of BRS_DISABLE_OS_USAGE */
  #error "BrsMain of at least version 2.21.00 is needed for this BrsHw package!"
# endif
#endif

/**********************************************************************************************************************
 *  DEFINITION + MACROS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  GLOBAL VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  GLOBAL CONST VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  LOCAL VARIABLES AND LOCAL HW REGISTERS
 *********************************************************************************************************************/
/* part of ArmCommon */

/**********************************************************************************************************************
 *  CONTROLLER CONFIGURATION REGISTERS
 *********************************************************************************************************************/
/* R5FSS Vector Interrupt Manager (VIM) */
#define BRSHW_VIM_BASEADDR  0x50F00000UL
/* IRQ vector address register. */
#define BRSHW_INTC_VIM_IRQVEC            BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x18UL))
/* FIQ vector address register. */
#define BRSHW_INTC_VIM_FIQVEC            BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x1CUL))
/* Raw status/set register. */
#define BRSHW_INTC_VIM_RAW_J(n)          BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0400UL + (n) * 0x20UL))
/* Interrupt enable set register. */
#define BRSHW_INTC_VIM_INTR_EN_SET_J(n)  BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0408UL + (n) * 0x20UL))
/* Interrupt enable clear register. */
#define BRSHW_INTC_VIM_INTR_EN_CLR_J(n)  BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x040CUL + (n) * 0x20UL))
/* IRQ interrupt enable status/clear register. */
#define BRSHW_INTC_VIM_IRQSTS_J(n)       BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0410UL + (n) * 0x20UL))
/* FIQ interrupt enable status/clear register. */
#define BRSHW_INTC_VIM_FIQSTS_J(n)       BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0414UL + (n) * 0x20UL))
/* Interrupt map register. */
#define BRSHW_INTC_VIM_INTMAP_J(n)       BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x0418UL + (n) * 0x20UL))
/* Interrupt priority register. */
#define BRSHW_INTC_VIM_PRI_INT_J(n)      BRSHW_IOS(uint32, (BRSHW_VIM_BASEADDR + 0x1000UL + (n) * 0x04UL))

/* Master subsystem reset, clock management registers */
#define BRSHW_MSS_CTRL_BASEADDR  0x50D00000UL
#define BRSHW_MSS_CTRL_MSS_RTI0_HALTEN        BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x454UL))
//#define BRSHW_MSS_CTRL_MSS_DBG_ACK_CTL1         BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x168UL))/*TODO*/
#define BRSHW_MSS_CTRL_MSS_R5_ROM_ECLIPSE       BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x804UL))/*TODO*/
#define BRSHW_MSS_CTRL_LOCK0_KICK0              BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x1008UL))/*TODO*/
#define BRSHW_MSS_CTRL_LOCK0_KICK1              BRSHW_IOS(uint32, (BRSHW_MSS_CTRL_BASEADDR + 0x100CUL))/*TODO*/

#define BRSHW_MSS_RTIA_BASEADDR                 0x52181000UL
#define BRSHW_MSS_RTIA_RTIGCTRL                 BRSHW_IOS(uint32, (BRSHW_MSS_RTIA_BASEADDR + 0x0UL))

#if defined (BRS_ENABLE_PORT)
  #define BRSHW_CPSW_CONTROL                    BRSHW_IOS(uint32, 0x0212016CUL)

  #define CPSW_CONTROL_PORT1_MODE_SEL_GMII_MII  (0x00000000uL)
  #define CPSW_CONTROL_PORT1_MODE_SEL_RMII      (0x00000001uL)
  #define CPSW_CONTROL_PORT1_MODE_SEL_RGMII     (0x00000002uL)
  #define CPSW_CONTROL_CLK_SEL_PAD              (0x00000100uL)
#endif /*BRS_ENABLE_PORT*/

/* Top-level reset, clock management registers */
#define BRSHW_CSL_MSS_TOPRCM_BASE  0x53208000UL
#define BRSHW_CSL_MSS_TOPRCM_SYS_RST_CAUSE      BRSHW_IOS(uint32, (BRSHW_CSL_MSS_TOPRCM_BASE + 0x10U))
#define BRSHW_CSL_MSS_TOPRCM_SYS_RST_CAUSE_CLR  BRSHW_IOS(uint32, (BRSHW_CSL_MSS_TOPRCM_BASE + 0x14U))
#define BRSHW_CSL_MSS_TOPRCM_WARM_RESET_CONFIG  BRSHW_IOS(uint32, (BRSHW_CSL_MSS_TOPRCM_BASE + 0x100U))/*TODO*/

/**********************************************************************************************************************
 *  LOCAL VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  LOCAL CONST VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  PROTOTYPES OF GLOBAL FUNCTIONS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  PROTOTYPES OF LOCAL FUNCTIONS
 *********************************************************************************************************************/
void PowerClock_init(void);

/**********************************************************************************************************************
 *  GLOBAL CONST DEFINITIONS
 *********************************************************************************************************************/
#define BOOT_DATA __attribute__((retain,section(".startupData")))

/* ----------- HwiP ----------- */
const HwiP_Config gHwiConfig BOOT_DATA = {
    .intcBaseAddr = 0x50F00000u,
};

/* ----------- ClockP ----------- */
#define RTI0_CLOCK_SRC_MUX_ADDR (0x53208118u)
#define RTI0_CLOCK_SRC_WUCPUCLK (0x0u)
#define RTI0_BASE_ADDR     (0x52181000u)

const ClockP_Config gClockConfig BOOT_DATA = {
    .timerBaseAddr = RTI0_BASE_ADDR, 
    .timerHwiIntNum = 91,
    .timerInputClkHz = 25000000,
    .timerInputPreScaler = 1,
    .usecPerTick = 1000,
};

/**********************************************************************************************************************
 *  FUNCTION DEFINITIONS
 *********************************************************************************************************************/
#if defined (BRS_FIRST_EXECUTION_INSTANCE)
#define BRS_START_SEC_STARTUP_CODE
#include "Brs_MemMap.h"
/*****************************************************************************/
/* @brief      This function can be used to initialize controller specific
 *             stuff that should be handled by the first execution instance,
 *             even before the memory initialization took place (e.g.
 *             everything that is necessary to access the memory or to handle
 *             exceptions). This function is called at the beginning of
 *             BrsMainStartup(), immediately after the stackpointer was
 *             initialized in StartupCode
 *             (if BRSHW_EARLYINIT_AVAILABLE is set in BrsHw.h).
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from Brs_PreMainStartup() at power on
 *             initialization
 *****************************************************************************/
void BrsHwEarlyInitPowerOn(void)
{
  /* Micro Processor Unit initialization from TI SDK */
  __mpu_init();
}
#define BRS_STOP_SEC_STARTUP_CODE
#include "Brs_MemMap.h"
#endif /* BRS_FIRST_EXECUTION_INSTANCE */

/*****************************************************************************/
/* @brief      This function can be used to initialize controller specific
 *             stuff that is not related to one of the other InitPowerOn
 *             functions (e.g. code that is always mandatory, also if MCAL
 *             and/or OS is used). This function is called from BrsMain
 *             immediately after BrsHwDisableInterruptAtPowerOn() during
 *             initialization (if BRSHW_PREINIT_AVAILABLE is set in BrsHw.h) or
 *             from the BrsMain_MemoryInit_StageHardReset_Hook() during
 *             initialization (if BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT is set).
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from BrsMainInit() at power on initialization
 *****************************************************************************/
void BrsHwPreInitPowerOn(void)
{
  /* This code is needed to stop the RTIA counter/timer, whenever a break signal from the debugger occurs.
   * The following fields need to be set to suspend the RTI on halting of the processor.
   * This enables setting of breakpoints, while the OS timer is running.
   */
  BRSHW_MSS_CTRL_LOCK0_KICK0 = 0x01234567;
  BRSHW_MSS_CTRL_LOCK0_KICK1 = 0x0FEDCBA8;
  BRSHW_MSS_CTRL_MSS_RTI0_HALTEN |= (0x7<<4); /*MSS_DBG_ACK_CTL1_RTI*/

  //BRSHW_MSS_RTIA_RTIGCTRL &= ~(0x1<<15); /* Clear COS bit of RTIA timer, to stop the counter in halting debug mode */
}

#if defined (BRS_ENABLE_WATCHDOG)
/*****************************************************************************/
/* @brief      This function must be used to initialize the Watchdog.
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from BrsMainInit() at power on initialization
 *****************************************************************************/
void BrsHwWatchdogInitPowerOn(void)
{
  /* Nothing to be done here, Watchdogs disabled after boot from SBL */
}
#endif /* BRS_ENABLE_WATCHDOG */

#if defined (BRS_ENABLE_PLLCLOCKS)
/*****************************************************************************/
/* @brief      This function must be used to initialize the PLL.
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from BrsMainInit() at power on initialization
 *****************************************************************************/
void BrsHwPllInitPowerOn(void)
{
  /* TI SBL image powers up the timers and clock sources.
     According to TI, the following frequencies are configured:
       XTALCLK:               40MHz
       Cortex-R5 CORE clock: 400MHz
       SYSCLK:               200MHz              
       RTI1:                 25MHz       
       I2C2:                 200MHz
       MCAN0,MCAN2:          80MHz       
       CPSW, CPTS:           200MHz
       LIN1:                 196MHz
   */
   /* Initialize the configured modules and clocks*/
   PowerClock_init();

#if defined (BRS_ENABLE_ETHERNET_SUPPORT)
   #error "There is no PLL/clocks handling for DrvEth supported by vBaseEnv on this platform! It is expected to always use the 3rd-party MCAL DrvEth, togehther with DrvMcu."
#endif
}
#endif /*BRS_ENABLE_PLLCLOCKS*/

#if defined (BRS_ENABLE_PORT)
/* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */

# if defined (BRS_ENABLE_FBL_SUPPORT)
  #define BRS_START_SEC_RAM_CODE
  #include "Brs_MemMap.h"
# endif
/*****************************************************************************/
/* @brief      This function sets the output level of a port pin.
 * @pre        Port pin configurations available within BrsHw_Ports.h,
 *             no DrvPort used for port pin initialization and
 *             transferred port pin has to be initialized as output pin with
 *             GPIO functionality.
 * @param[in]  p     - brsHw_Port_PortType, to be set,
 *             Level - level, port pin has to be set to
 *                     (BRSHW_PORT_LOGIC_LOW or BRSHW_PORT_LOGIC_HIGH).
 * @param[out] -
 * @return     -
 * @context    Function is called from BrsHwPortInitPowerOn() and
 *             provided to external modules (e.g. BrsMainTogglePin()).
 *****************************************************************************/
#define GPIO_LED_PIN (1)

void BrsHwPort_SetLevel(brsHw_Port_PortType p, uint8 Level)
{
  if(BRSHW_PORT_LOGIC_LOW == Level)
  {
    GPIO_pinWriteLow((uint32_t) AddrTranslateP_getLocalAddr(CSL_GPIO0_U_BASE), GPIO_LED_PIN);
  }
  else
  {
    GPIO_pinWriteHigh((uint32_t) AddrTranslateP_getLocalAddr(CSL_GPIO0_U_BASE), GPIO_LED_PIN);
  }
}

/*****************************************************************************/
/* @brief      This function reads the input level of a port pin.
 * @pre        Port pin configurations available within BrsHw_Ports.h,
 *             no DrvPort used for port pin initialization and
 *             transferred port pin has to be initialized as input pin with
 *             GPIO functionality.
 * @param[in]  p - brsHw_Port_PortType, to be read.
 * @param[out] -
 * @return     Level, read from port pin
 *             (BRSHW_PORT_LOGIC_LOW or BRSHW_PORT_LOGIC_HIGH).
 * @context    Function is provided to external modules.
 *****************************************************************************/
uint8 BrsHwPort_GetLevel(brsHw_Port_PortType p)
{
  uint8 pinVal;
  pinVal = (uint8) GPIO_pinRead(CSL_GPIO0_U_BASE, p.portNumber);
  if(pinVal==0x1U)
  {
    return BRSHW_PORT_LOGIC_HIGH;
  }
  else
  {
    return BRSHW_PORT_LOGIC_LOW;
  }
}
# if defined (BRS_ENABLE_FBL_SUPPORT)
  #define BRS_STOP_SEC_RAM_CODE
  #include "Brs_MemMap.h"
# endif

#define SOC_MODULES_END     (0xFFFFFFFFu)

typedef struct {

    uint32_t moduleId;
    uint32_t clkId;
    uint32_t clkRate;

} SOC_ModuleClockFrequency;

uint32_t gSocModules[] = {
# if defined (BRS_ENABLE_CAN_SUPPORT)
    #if defined (BRS_ENABLE_CAN_CHANNEL_0)
    SOC_RcmPeripheralId_MCAN0,
    #endif
    #if defined (BRS_ENABLE_CAN_CHANNEL_2)
    SOC_RcmPeripheralId_MCAN2,
    #endif  
# endif
# if defined (BRS_ENABLE_I2C_SUPPORT)
    SOC_RcmPeripheralId_I2C,
# endif
# if defined (BRS_ENABLE_LIN_SUPPORT)
    #if defined (BRS_ENABLE_LIN_CHANNEL_1)
    SOC_RcmPeripheralId_LIN1_UART1,
    #endif
# endif
    SOC_MODULES_END,
};

SOC_ModuleClockFrequency gSocModulesClockFrequency[] = {
# if defined (BRS_ENABLE_CAN_SUPPORT)
    #if defined (BRS_ENABLE_CAN_CHANNEL_0)
    { SOC_RcmPeripheralId_MCAN0, SOC_RcmPeripheralClockSource_DPLL_CORE_HSDIV0_CLKOUT0, 80000000 },
    #endif
    #if defined (BRS_ENABLE_CAN_CHANNEL_2)
    { SOC_RcmPeripheralId_MCAN2, SOC_RcmPeripheralClockSource_DPLL_CORE_HSDIV0_CLKOUT0, 80000000 },
    #endif
# endif
# if defined (BRS_ENABLE_I2C_SUPPORT)
    { SOC_RcmPeripheralId_I2C, SOC_RcmPeripheralClockSource_DPLL_PER_HSDIV0_CLKOUT1, 96000000 },
# endif
# if defined (BRS_ENABLE_LIN_SUPPORT)
    #if defined (BRS_ENABLE_LIN_CHANNEL_1)
    { SOC_RcmPeripheralId_LIN1_UART1, SOC_RcmPeripheralClockSource_DPLL_PER_HSDIV0_CLKOUT1, 192000000 },
    #endif
# endif
    { SOC_MODULES_END, SOC_MODULES_END, SOC_MODULES_END },
};

void Module_clockSetFrequency(void)
{
    int32_t status;
    uint32_t i = 0;

    while(gSocModulesClockFrequency[i].moduleId!=SOC_MODULES_END)
    {
        status = SOC_moduleSetClockFrequency(
                    gSocModulesClockFrequency[i].moduleId,
                    gSocModulesClockFrequency[i].clkId,
                    gSocModulesClockFrequency[i].clkRate
                    );
        DebugP_assertNoLog(status == SystemP_SUCCESS);
        i++;
    }
}

void Module_clockEnable(void)
{
    int32_t status;
    uint32_t i = 0;

    while(gSocModules[i]!=SOC_MODULES_END)
    {
        status = SOC_moduleClockEnable(gSocModules[i], 1);
        DebugP_assertNoLog(status == SystemP_SUCCESS);
        i++;
    }
}

void PowerClock_init(void)
{
    Module_clockEnable();
    Module_clockSetFrequency();
}

# if defined (BRS_ENABLE_ETHERNET_SUPPORT)
  #define SOC_CONTROLSS_CTRL      (0x502F0000U)
  #define MSS_IOCFGKICK0          (0x00001008U)
  #define MSS_IOCFGKICK1          (0x0000100CU)
  
  #define SOC_MSS_CTRL_BASE       (0x50D00000U)
  #define MSS_CPSW_CONTROL_REG             (0x810U)
  
  #define MSS_CPSW_CONTROL_REG_P1_MODE_SEL_SHIFT              (0x0U)
  #define MSS_CPSW_CONTROL_REG_P1_MODE_SEL_MASK               (0x00000003U)
  
  #define MSS_CPSW_CONTROL_REG_P2_MODE_SEL_SHIFT              (0x10U)
  #define MSS_CPSW_CONTROL_REG_P2_MODE_SEL_MASK               (0x00000030U)
  
  #define KICK0_UNLOCK_VAL_MCU             (0x01234567U)
  #define KICK1_UNLOCK_VAL_MCU             (0x0FEDCBA8U)
  
  #define ETH_GMII_SEL_GMII_MODE          (0x0U)
  #define ETH_GMII_SEL_RMII_MODE          (0x1U)
  #define ETH_GMII_SEL_RGMII_MODE         (0x2U)
  
  typedef enum
  {
      ETH_MAC_CONN_TYPE_MII_10 = 0x00U,
      /**< MAC connection type for 10Mbps MII mode */
      ETH_MAC_CONN_TYPE_MII_100 = 0x01U,
      /**< MAC connection type for 100Mbps MII mode */
      ETH_MAC_CONN_TYPE_RMII_10 = 0x02U,
      /**< MAC connection type for 10Mbps RMII mode */
      ETH_MAC_CONN_TYPE_RMII_100 = 0x03U,
      /**< MAC connection type for 100Mbps RMII mode */
      ETH_MAC_CONN_TYPE_RGMII_FORCE_100_HALF = 0x04U,
      /**< MAC connection type for forced half-duplex 100Mbps RGMII mode */
      ETH_MAC_CONN_TYPE_RGMII_FORCE_100_FULL = 0x05U,
      /**< MAC connection type for forced full-duplex 100Mbps RGMII mode */
      ETH_MAC_CONN_TYPE_RGMII_FORCE_1000 = 0x06U,
      /**< MAC connection type for forced 1000Mbps RGMII mode */
      ETH_MAC_CONN_TYPE_RGMII_DETECT_INBAND = 0x07U,
      /**< MAC connection type for RGMII inband detection mode (speed determined
       *   based on received RGMII Rx clock) */
  } Eth_MacConnectionType;
  
  void Eth_EnableTransceiver(Eth_MacConnectionType type)
  {
    uint32 val;
  
    switch (type)
    {
        case ETH_MAC_CONN_TYPE_MII_10:
        case ETH_MAC_CONN_TYPE_MII_100:
            /* MII modes */
            /* Eth mode select */
            val = ETH_GMII_SEL_GMII_MODE;
            break;
        case ETH_MAC_CONN_TYPE_RMII_10:
        case ETH_MAC_CONN_TYPE_RMII_100:
            /* RMII modes */
            val = ETH_GMII_SEL_RMII_MODE;
            break;
        case ETH_MAC_CONN_TYPE_RGMII_FORCE_100_HALF:
        case ETH_MAC_CONN_TYPE_RGMII_FORCE_100_FULL:
        case ETH_MAC_CONN_TYPE_RGMII_FORCE_1000:
        case ETH_MAC_CONN_TYPE_RGMII_DETECT_INBAND:
            /* RGMII modes */
            val = ETH_GMII_SEL_RGMII_MODE;
            break;
        default:
            /* Wrong configuration */
            break;
    }
  
    /* Set MAC port interface in MMR */
    HW_WR_REG32((SOC_CONTROLSS_CTRL +MSS_IOCFGKICK0),KICK0_UNLOCK_VAL_MCU);
    HW_WR_REG32((SOC_CONTROLSS_CTRL +MSS_IOCFGKICK1),KICK1_UNLOCK_VAL_MCU);
    HW_WR_FIELD32(SOC_MSS_CTRL_BASE + MSS_CPSW_CONTROL_REG,
            MSS_CPSW_CONTROL_REG_P1_MODE_SEL,(val));
    HW_WR_FIELD32(SOC_MSS_CTRL_BASE + MSS_CPSW_CONTROL_REG,
            MSS_CPSW_CONTROL_REG_P2_MODE_SEL,(val));
}
# endif /* BRS_ENABLE_ETHERNET_SUPPORT */

/*****************************************************************************/
/* @brief      This function must be used to initialize the used ports.
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from BrsMainInit() at power on initialization
 *****************************************************************************/
void BrsHwPortInitPowerOn(void)
{
 /* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */

  /* GPIO initialization */
  /* Initialize USER_LED1 and USER_LED0 JWADD */

Pinmux_PerCfg_t gGpioPinCfg[] =
{
#  if defined (BRS_ENABLE_SUPPORT_LEDS)
    /* GPIO1 -> QSPI_CSn1 (R3) */
    {
        PIN_QSPI_CSN1,
        ( PIN_MODE(7) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW | PIN_QUAL_SYNC | PIN_GPIO_R5SS0_0 )
    },
#  endif
#  if defined (BRS_ENABLE_CAN_SUPPORT)
            /* MCAN0 pin config */
    /* MCAN0_RX -> MCAN0_RX (M1) */
    {
        PIN_MCAN0_RX,
        ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW )
    },
    /* MCAN0_TX -> MCAN0_TX (L1) */
    {
        PIN_MCAN0_TX,
        ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW )
    },
            /* MCAN2 pin config */
    /* MCAN2_RX -> MCAN2_RX (A12) */
    {
        PIN_MCAN2_RX,
        ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW )
    },
    /* MCAN2_TX -> MCAN2_TX (B12) */
    {
        PIN_MCAN2_TX,
        ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW )
    },
#  endif
#  if defined (BRS_ENABLE_I2C_SUPPORT)
   /* I2C2 pin config */
    /* I2C2_SCL -> UART0_RTSn (C7) */
    {
    PIN_UART0_RTSN,
    ( PIN_MODE(1) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW )
    },
    /* I2C2_SDA -> UART0_CTSn (B7) */
    {
    PIN_UART0_CTSN,
    ( PIN_MODE(1) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW )
    },
#  endif
#  if defined (BRS_ENABLE_LIN_SUPPORT)
    {
         PIN_LIN1_RXD,
        ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW )
    },
    /* LIN1_TXD -> LIN_TXD (B9) */
    {
         PIN_LIN1_TXD,
        ( PIN_MODE(0) | PIN_PULL_DISABLE | PIN_SLEW_RATE_LOW )
    },

#  endif
    {PINMUX_END, PINMUX_END}
};

  Pinmux_config(gGpioPinCfg, PINMUX_DOMAIN_ID_MAIN);
  
  uint32_t    gpioBaseAddr, pinNum;

  #define GPIO_LED_PIN (1)
  
  gpioBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CSL_GPIO0_U_BASE);
  pinNum       = GPIO_LED_PIN;

  GPIO_setDirMode(gpioBaseAddr, pinNum, GPIO_DIRECTION_OUTPUT);

#  if defined (BRS_ENABLE_SUPPORT_LEDS)
  /* Set LED on EVB demo board to show the system is alive */
  BrsMainTogglePin(BRSMAIN_TOGGLEPIN_LED);
#  endif

#  if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN)
  /* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */
  #error "Implementation for initialization of specific pin must be added here. See LED pin as reference."
#  endif

#  if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN)
  /* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */
  #error "Implementation for initialization of specific pin must be added here. See LED pin as reference."
#  endif

/*******************************************************************************
 *  CAN driver
 *******************************************************************************/
#  if defined (BRS_ENABLE_CAN_SUPPORT)
//Can_PlatformInit();
#  endif /*BRS_ENABLE_CAN_SUPPORT*/

/*******************************************************************************
 *  LIN driver
 *******************************************************************************/
#  if defined (BRS_ENABLE_LIN_SUPPORT)
/* Calls of BrsHwInitPortOutput() and BrsHwInitPortInput() replaced by proprietery SBL image, provided by TI */
#  endif /*BRS_ENABLE_LIN_SUPPORT*/

/*******************************************************************************
 *  ETHERNET driver
 *******************************************************************************/
#  if defined (BRS_ENABLE_ETHERNET_SUPPORT)
/* Currently selecting connection RMII 10 by default */
  Eth_EnableTransceiver(ETH_MAC_CONN_TYPE_RMII_10);
  #error "There is no portpin handling for DrvEth supported by vBaseEnv on this platform! It is expected to always use the 3rd-party MCAL DrvEth, togehther with DrvPort."
#  endif /*BRS_ENABLE_ETHERNET_SUPPORT*/
}
#endif /*BRS_ENABLE_PORT*/

/* BrsHwDisableInterruptAtPowerOn() is part of ArmCommon */

/* BrsHw_ExceptionTable_Init() is part of ArmCommon */

/*****************************************************************************/
/* @brief      Restart ECU (issue a software reset or jump to startup code)
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from e.g. ECU state handling
 *****************************************************************************/
void BrsHwSoftwareResetECU(void)
{
  BrsMain_SoftwareResetECU_Hook();

#if !defined (BRS_ENABLE_FBL_SUPPORT) /* FBL is always running in polling mode with interrupts disabled */
 /*DisableAllInterrupts(); call removed by TI */
#endif

  SOC_controlModuleUnlockMMR(SOC_DOMAIN_ID_MAIN, MSS_RCM_PARTITION0);
  /* Clear reset Reason*/
  HW_WR_REG32(0x53208014, 0x7);
  /* R5SS0_RST_WFICHECK */
  HW_WR_REG32(0x53208024, 0x7000707);
  /* R5SS1_RST_WFICHECK */
  HW_WR_REG32(0x53208044, 0x7000707);
  /* R5SS1_CORE0_LRST_CTRL */
  HW_WR_REG32(0x5320851C, 0x7);
  /* R5SS0_CORE0_LRST_CTRL */
  HW_WR_REG32(0x53208518, 0x7);

  while (1)
  {
    /* Wait until reset/watchdog reset occurs */
  }
}

#if defined (BRS_FIRST_EXECUTION_INSTANCE)
/* This code is only needed for the first instance/executable in the system */
#define BRS_START_SEC_STARTUP_CODE
#include "Brs_MemMap.h"
/*****************************************************************************/
/* @brief      Get reset reason
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     Reset reason
 * @context    Function is called from BrsMainStartup to determine if reset
 *             was triggered through software call (BrsHwSoftwareResetECU()).
 *             The result is stored by BrsMainStartup in the global variable
 *             brsMain_ResetReason. It should only be called once, during
 *             startup. The old API name BrsHwGetResetReason() is remapped
 *             to BrsMainGetResetReason.
 *****************************************************************************/
brsMain_ResetReasonType BrsHwGetResetReasonStartup(void)
{
  volatile uint32 rst_cause;
  uint32 sw_reset = 0x00000020U;
  rst_cause = BRSHW_CSL_MSS_TOPRCM_SYS_RST_CAUSE; /*HW_RD_REG32(0x53208010UL);*/
  rst_cause = rst_cause & 0x000000FF;
  if(rst_cause == sw_reset)
    /* 000 0000 0001 - POR;
       000 0000 0010 - WARM RESET
       000 0000 0100 - STC     
       000 0000 1000 - Reset for CORE0 and MSS_CORE00_VIM using MSS_RCM::MSS_CR5SSA0_RST_CTRL
       000 0001 0000 - Reset for CORE1 and MSS_CORE10_VIM using MSS_RCM::MSS_CR5SSB0_RST_CTRL
       000 0010 0000 - Reset for CORE0 only using MSS_RCM::MSS_CORE00_RST_CTRL
       000 0100 0000 - Reset for CORE1 only using using MSS_RCM::MSS_CORE10_RST_CTRL
       000 1000 0000 - Reset for CORE0 and MSS_CORE00_VIM caused because of reset request by debugger in CORE00
       001 0000 0000 - Reset for CORE10 and MSS_CORE10_VIM caused because of reset request by debugger in CORE10
       010 0000 0000 - Reset for CR5SS0 by the RESET FSM using MSS_CTRL::R5SS0_CONTROL_RESET_FSM_TRIGGER
       100 0000 0000 - MSS_RCM.MSS_CR5SS_POR_RST_CTRL0 */
  {
    return BRSMAIN_RESET_SW;
  }
  else
  {
    return BRSMAIN_RESET_OTHER;
  }
}
#define BRS_STOP_SEC_STARTUP_CODE
#include "Brs_MemMap.h"
#endif /* BRS_FIRST_EXECUTION_INSTANCE */

/* BrsHwTime100NOP() is part of ArmCommon */

#if defined (BRS_ENABLE_SAFECTXSUPPORT)
/*****************************************************************************/
/* @brief      This API is used to enable hardware access in untrusted mode
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function must be called after all depending peripheral modules
 *             are supplied by proper clocks AND before the OS is started.
 *****************************************************************************/
void BrsHw_EnableHwAccess(void)
{
  /* nothing to be done for this platform yet (or never tested) */
  #error "Hardware access in UserMode not yet supported for your specific derivative!"
}
#endif /* BRS_ENABLE_SAFECTXSUPPORT */

/* BrsHw_GetCore() is part of ArmCommon */

/*****************************************************************************/
/* @brief      This API is used to enable an interrupt source in the core
 *             interrupt controller.
 * @pre        -
 * @param[in]  Source to be enabled.
 * @param[in]  Priority level to be set.
 * @param[out] -
 * @return     -
 * @context    Function is called from HlpTest and other test environments.
 *****************************************************************************/
void BrsHw_EnableInterrupt(uint32 Source, uint8 Priority)
{
  /* Clear pending interrupt. */
  if(((BRSHW_INTC_VIM_INTMAP_J(Source / 32U)) >> (Source % 32U)) & (uint32)0x01)
  {
    BRSHW_INTC_VIM_FIQSTS_J(Source / 32U)= (uint32)(1UL << (Source % 32U));
    BRSHW_INTC_VIM_FIQVEC = 0x01UL;
  }
  else
  {
    BRSHW_INTC_VIM_IRQSTS_J(Source / 32U)= (uint32)(1UL << (Source % 32U));
    BRSHW_INTC_VIM_IRQVEC = 0x01UL;
  }
  /* Set interrupt priority. */
  BRSHW_INTC_VIM_PRI_INT_J(Source) = Priority;
  /* Enable interrupt handling. */
  BRSHW_INTC_VIM_INTR_EN_SET_J(Source / 32U) |= (uint32)(1UL << (Source % 32U));
}

/*****************************************************************************/
/* @brief      This API is used to disable an interrupt source in the core
 *             interrupt controller.
 * @pre        -
 * @param[in]  Source to be disabled.
 * @param[out] -
 * @return     -
 * @context    Function is called from HlpTest and other test environments.
 *****************************************************************************/
void BrsHw_DisableInterrupt(uint32 Source)
{
  BRSHW_INTC_VIM_INTR_EN_CLR_J(Source / 32U) |= (uint32)(1UL << (Source % 32U));
}

/*****************************************************************************/
/* @brief      This API is used to trigger the given software interrupt source.
 * @pre        -
 * @param[in]  Source to be triggered.
 *             Some derivatives only support few software triggerable sources,
 *             check for their validity.
 * @param[out] -
 * @return     -
 * @context    Function is called from HlpTest and other test environments.
 *****************************************************************************/
void BrsHw_TriggerSoftwareInterrupt(uint32 Source)
{
  BRSHW_INTC_VIM_RAW_J(Source / 32U) |= (uint32)(1UL << (Source % 32U));
}

  #define BOOT_CODE __attribute__((section(".startupCode")))
  
  void Dpl_deinit(void)
  {
  }
  
  void putchar_(char character)
  {
    (void)character;
  }
