This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

D3-3P-TDA3X-SK: Issues with Ethernet initialization

Part Number: D3-3P-TDA3X-SK
Other Parts Discussed in Thread: TDA2

Hi,

We have a couple of D3 TDA3 Starter Kit board on which we're trying to enable Ethernet, both using the Vision SDK (v03.07.00.00) and using a smaller stand-alone program based on the Sys/BIOS and NSP/NDK version shipped in the SDK. We're having some issues getting this to work.

Using the GMACSW_getConfig from the SDK (removing the TDA2 parts) to map port 2 (RGMII1?) to PHY address 12 does not seem to work, and GMACSW/NSP never finds a working interface (even though the PHY on the board should be on address 12). Mapping it to PHY address 0 allows GMACSW/NSP to find it, and when it has done so it also correctly responds to pulling the Ethernet cable out by calling the link status callback we register. However, no packets are sent or received if we try to observe the Ethernet traffic using Wireshark on a connected PC. The interface is configured with a static IP address, and the PC has a correctly configured address in the same subnet. Additionally, when trying to send packets directly to the IP address of the PC, ICMP "host unreachable" packets are returned by the GMACSW (but again, we cannot observe these using Wireshark).

Is there some configuration we are missing? What could cause the PHY to appear to work (on the wrong address) yet not send any packets?

Regards,
Simon

  • Hi Simon,

    Can you attach the ndk_nsp_hooks.c file with your modifications?

    Regards,
    Anand

  • Hi,

    See attached file below. We're building with MAKECONFIG=tda3xx_rvp_bios_all and NDK_PROC_TO_USE=ipu1_0.

    Also attached is the smaller stand-alone program I mentioned above. Both exhibit the same issue.

    Regards,
    Simon

    • ndk_nsp_hooks.c:
      /*
      Copyright (c) [2012 - 2017] Texas Instruments Incorporated
      
      All rights reserved not granted herein.
      
      Limited License.
      
       Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
       license under copyrights and patents it now or hereafter owns or controls to
       make,  have made, use, import, offer to sell and sell ("Utilize") this software
       subject to the terms herein.  With respect to the foregoing patent license,
       such license is granted  solely to the extent that any such patent is necessary
       to Utilize the software alone.  The patent license shall not apply to any
       combinations which include this software, other than combinations with devices
       manufactured by or for TI ("TI Devices").  No hardware patent is licensed
       hereunder.
      
       Redistributions must preserve existing copyright notices and reproduce this
       license (including the above copyright notice and the disclaimer and
       (if applicable) source code license limitations below) in the documentation
       and/or other materials provided with the distribution
      
       Redistribution and use in binary form, without modification, are permitted
       provided that the following conditions are met:
      
       * No reverse engineering, decompilation, or disassembly of this software
         is permitted with respect to any software provided in binary form.
      
       * Any redistribution and use are licensed by TI for use only with TI Devices.
      
       * Nothing shall obligate TI to provide you with source code for the software
         licensed and provided to you in object code.
      
       If software source code is provided to you, modification and redistribution of
       the source code are permitted provided that the following conditions are met:
      
       * Any redistribution and use of the source code, including any resulting
         derivative works, are licensed by TI for use only with TI Devices.
      
       * Any redistribution and use of any object code compiled from the source code
         and any resulting derivative works, are licensed by TI for use only with TI
         Devices.
      
       Neither the name of Texas Instruments Incorporated nor the names of its
       suppliers may be used to endorse or promote products derived from this software
       without specific prior written permission.
      
       DISCLAIMER.
      
       THIS SOFTWARE IS PROVIDED BY TI AND TI�S LICENSORS "AS IS" AND ANY EXPRESS OR
       IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
       MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
       IN NO EVENT SHALL TI AND TI�S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT,
       INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
       OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      */
      
      /**
       *******************************************************************************
       *   \file  ndk_nsp_hooks.c
       *
       *   \brief Do all necessary board level initialization for NDK.
       *
       *******************************************************************************
       */
      
      
      /*******************************************************************************
       *  INCLUDE FILES
       *******************************************************************************
       */
      
      /* Standard language headers */
      #include <stddef.h>
      #include <stdio.h>
      #include <inttypes.h>
      #include <string.h>
      
      /* OS/Posix headers */
      
      /* NDK Dependencies */
      #include <ti/ndk/inc/netmain.h>
      #include <ti/ndk/inc/_stack.h>
      #include <ti/ndk/inc/tools/servers.h>
      #include <ti/ndk/inc/tools/console.h>
      
      /* NSP Dependencies */
      #include <ti/nsp/drv/inc/gmacsw.h>
      #include <ti/nsp/drv/inc/gmacsw_config.h>
      
      /* Project dependency headers */
      #include <src/rtos/utils_common/include/utils.h>
      #include <include/link_api/systemLink_common.h>
      #include <include/link_api/networkCtrl_api.h>
      
      #include <ti/csl/soc.h>
      #include <ti/drv/stw_lld/platform/platform.h>
      
      /*******************************************************************************
       *  Defines
       *******************************************************************************
       */
      
      /* Ethernet MAC ID registers(Devcice configuration) from EFuse */
      #define MAC_ID0_LO              (*(volatile uint32_t*)0x4A002514)
      #define MAC_ID0_HI              (*(volatile uint32_t*)0x4A002518)
      #define MAC_ID1_LO              (*(volatile uint32_t*)0x4A00251C)
      #define MAC_ID1_HI              (*(volatile uint32_t*)0x4A002520)
      
      /* I/O Delay related registers */
      #define CFG_IO_DELAY_UNLOCK_KEY     (0x0000AAAA)
      #define CFG_IO_DELAY_LOCK_KEY       (0x0000AAAB)
      
      #define CFG_IO_DELAY_ACCESS_PATTERN (0x00029000)
      #define CFG_IO_DELAY_LOCK_MASK      (0x400)
      
      #define CFG_IO_DELAY_BASE           (0x4844A000)
      #define CFG_IO_DELAY_LOCK           (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0x02C))
      #define CFG_RGMII0_TXCTL_OUT        (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0x74C))
      #define CFG_RGMII0_TXD0_OUT         (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0x758))
      #define CFG_RGMII0_TXD1_OUT         (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0x764))
      #define CFG_RGMII0_TXD2_OUT         (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0x770))
      #define CFG_RGMII0_TXD3_OUT         (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0x77C))
      #define CFG_VIN2A_D13_OUT           (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0xA7C))
      #define CFG_VIN2A_D17_OUT           (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0xAAC))
      #define CFG_VIN2A_D16_OUT           (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0xAA0))
      #define CFG_VIN2A_D15_OUT           (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0xA94))
      #define CFG_VIN2A_D14_OUT           (*(volatile uint32_t*)(CFG_IO_DELAY_BASE + 0xA88))
      
      /* PAD Configuration Registers */
      #define SYSCFG_PAD_RGMII0_TXCTL     (*(volatile uint32_t*)(0x4A003654))
      #define SYSCFG_PAD_RGMII0_TXD3      (*(volatile uint32_t*)(0x4A003658))
      #define SYSCFG_PAD_RGMII0_TXD2      (*(volatile uint32_t*)(0x4A00365C))
      #define SYSCFG_PAD_RGMII0_TXD1      (*(volatile uint32_t*)(0x4A003660))
      #define SYSCFG_PAD_RGMII0_TXD0      (*(volatile uint32_t*)(0x4A003664))
      #define SYSCFG_PAD_VIN2A_D13        (*(volatile uint32_t*)(0x4A00359C))
      #define SYSCFG_PAD_VIN2A_D14        (*(volatile uint32_t*)(0x4A0035A0))
      #define SYSCFG_PAD_VIN2A_D15        (*(volatile uint32_t*)(0x4A0035A4))
      #define SYSCFG_PAD_VIN2A_D16        (*(volatile uint32_t*)(0x4A0035A8))
      #define SYSCFG_PAD_VIN2A_D17        (*(volatile uint32_t*)(0x4A0035AC))
      
      #define CTRL_MODULE_CTRL_CORE_SMA_SW_1 (*(volatile uint32_t*) (0x4A002534))
      
      #if defined(BOARD_TYPE_TDA3XX_RVP)
      /* DP83867IR Register details for delay configuration */
      #define DP83867_CTRL         (0x1FU)
      #define DP83867_RGMIICTL     (0x0032U)
      #define DP83867_RGMIIDCTL    (0x0086U)
      #define DP83867_IO_MUX_CTRL  (0x0170U)
      /* PHY CTRL bits */
      #define DP83867_SW_RESET    (15)
      #define DP83867_SW_RESTART  (14)
      #define DP83867_PHYCR_FIFO_DEPTH_3_B_NIB    (0x00U)
      #define DP83867_PHYCR_FIFO_DEPTH_4_B_NIB    (0x01U)
      #define DP83867_PHYCR_FIFO_DEPTH_6_B_NIB    (0x02U)
      #define DP83867_PHYCR_FIFO_DEPTH_8_B_NIB    (0x03U)
      /* RGMIIDCTL internal delay for rx and tx */
      #define DP83867_RGMIIDCTL_250_PS     (0x0U)
      #define DP83867_RGMIIDCTL_500_PS     (0x1U)
      #define DP83867_RGMIIDCTL_750_PS     (0x2U)
      #define DP83867_RGMIIDCTL_1_NS       (0x3U)
      #define DP83867_RGMIIDCTL_1_25_NS    (0x4U)
      #define DP83867_RGMIIDCTL_1_50_NS    (0x5U)
      #define DP83867_RGMIIDCTL_1_75_NS    (0x6U)
      #define DP83867_RGMIIDCTL_2_00_NS    (0x7U)
      #define DP83867_RGMIIDCTL_2_25_NS    (0x8U)
      #define DP83867_RGMIIDCTL_2_50_NS    (0x9U)
      #define DP83867_RGMIIDCTL_2_75_NS    (0xaU)
      #define DP83867_RGMIIDCTL_3_00_NS    (0xbU)
      #define DP83867_RGMIIDCTL_3_25_NS    (0xcU)
      #define DP83867_RGMIIDCTL_3_50_NS    (0xdU)
      #define DP83867_RGMIIDCTL_3_75_NS    (0xeU)
      #define DP83867_RGMIIDCTL_4_00_NS    (0xfU)
      #endif
      
      
      /*******************************************************************************
       *  Function's
       *******************************************************************************
       */
      static void LOCAL_linkStatus( uint32_t phy, uint32_t linkStatus );
      static void LOCAL_phyFoundCb(uint32_t portNum, uint32_t phy);
      void stackInitHookStaticEth1(void *hCfg);
      void stackInitHookDynEth1(void *hCfg);
      
      /*******************************************************************************
       *  Global's
       *******************************************************************************
       */
      
      /* This string array corresponds to link state */
      static char *LinkStr[] = { "No Link",
                                 "None",
                                 "10Mb/s Half Duplex",
                                 "10Mb/s Full Duplex",
                                 "100Mb/s Half Duplex",
                                 "100Mb/s Full Duplex",
                                 "1000Mb/s Half Duplex", /*not suported*/
                                 "1000Mb/s Full Duplex"};
      
      
      /**
       *******************************************************************************
       *
       * \brief HW specific initialization
       *
       *        We changed our CFG file to point call this private init
       *        function. Here we initialize our board and read in our
       *        MAC address.
       *
       *******************************************************************************
       */
      
      void NDK_NSP_Init( void )
      {
      }
      
      /**
       *******************************************************************************
       *
       * \brief Callback to get GMAC HW config
       *
       *        This is a callback from the Ethernet driver. This function
       *        is used by the driver to an application-specific config structure
       *        for the GMACSW driver. Typically it will be used to provide the
       *        MAC address(es) and the link status update callback function.
       *
       *******************************************************************************
       */
      GMACSW_Config* GMACSW_getConfig(void)
      {
      #if (defined(NDK_PROC_TO_USE_IPU1_0) && defined(BUILD_M4_0)) && \
          (defined(BOARD_TYPE_TDA3XX_EVM) || defined(BOARD_TYPE_TDA3XX_RVP))
          /* Get default starting config */
          GMACSW_Config *pGMACSWConfig = GMACSW_CONFIG_getDefaultConfig();
      #else
          GMACSW_Config *pGMACSWConfig = NULL;
      #endif
      
          if (pGMACSWConfig != NULL)
          {
              /* Set callbacks */
              pGMACSWConfig->mdioCfg.phyFoundCallback = &LOCAL_phyFoundCb;
              pGMACSWConfig->linkStatusCallback       = &LOCAL_linkStatus;
      
      #if defined(BOARD_TYPE_TDA3XX_EVM)
              /* TDA3XX-EVM: Map MAC port 1 to PHY address 0 */
              pGMACSWConfig->activeMACPortMask = PORT_MASK_MAC_1;
              pGMACSWConfig->macInitCfg[0].phyMask = (1u << 0u);
      
              pGMACSWConfig->macInitCfg[0].macConnectionType = MAC_CONNECTION_TYPE_RGMII_DETECT_INBAND;
              pGMACSWConfig->macInitCfg[0].macAddr[5] = (uint8_t)((MAC_ID0_LO & 0x000000FFu) >> 0u );
              pGMACSWConfig->macInitCfg[0].macAddr[4] = (uint8_t)((MAC_ID0_LO & 0x0000FF00u) >> 8u );
              pGMACSWConfig->macInitCfg[0].macAddr[3] = (uint8_t)((MAC_ID0_LO & 0x00FF0000u) >> 16u);
              pGMACSWConfig->macInitCfg[0].macAddr[2] = (uint8_t)((MAC_ID0_HI & 0x000000FFu) >> 0u );
              pGMACSWConfig->macInitCfg[0].macAddr[1] = (uint8_t)((MAC_ID0_HI & 0x0000FF00u) >> 8u );
              pGMACSWConfig->macInitCfg[0].macAddr[0] = (uint8_t)((MAC_ID0_HI & 0x00FF0000u) >> 16u);
      #elif defined(BOARD_TYPE_TDA3XX_RVP)
              /* TDA3XX-RVP: Map MAC port 2 to PHY address 12 */
              pGMACSWConfig->activeMACPortMask = PORT_MASK_MAC_2;
              pGMACSWConfig->macInitCfg[1].phyMask = (1u << 12u);
      
              pGMACSWConfig->macInitCfg[1].macConnectionType = MAC_CONNECTION_TYPE_RGMII_DETECT_INBAND;
              pGMACSWConfig->macInitCfg[1].macAddr[5] = (uint8_t)((MAC_ID1_LO & 0x000000FFu) >> 0u );
              pGMACSWConfig->macInitCfg[1].macAddr[4] = (uint8_t)((MAC_ID1_LO & 0x0000FF00u) >> 8u );
              pGMACSWConfig->macInitCfg[1].macAddr[3] = (uint8_t)((MAC_ID1_LO & 0x00FF0000u) >> 16u);
              pGMACSWConfig->macInitCfg[1].macAddr[2] = (uint8_t)((MAC_ID1_HI & 0x000000FFu) >> 0u );
              pGMACSWConfig->macInitCfg[1].macAddr[1] = (uint8_t)((MAC_ID1_HI & 0x0000FF00u) >> 8u );
              pGMACSWConfig->macInitCfg[1].macAddr[0] = (uint8_t)((MAC_ID1_HI & 0x00FF0000u) >> 16u);
      #endif
          }
      
          /* Return the config */
          return pGMACSWConfig;
      }
      
      #if defined(BOARD_TYPE_TDA3XX_RVP)
      /**
       *******************************************************************************
       *
       * \brief PHY DP83867IR delay config function
       *
       *        This function is used for configuring the receive and transmit delays
       *        for DP83867IR PHY on TDA2EX PG 2.0 EVM (RevC).
       *        For PHY configuration, need to configure DP83867’s RGMII Control
       *        Register (RGMIICTL) for RGMII mode and RGMII Delay Control Register
       *        (RGMIIDCTL) for 0ns TX delay, 2.25ns RX delay. Set IO Drive Strength
       *        Register (IO_IMPEDANCE_CTRL) to maximum drive.
       *        NOTE: Call this function after NSP initialization as it requires GMAC
       *        handle to call GMAC IOCTL.
       *
       *******************************************************************************
       */
      void DP83867_configurePhyDelays(GMACSW_DeviceHandle hGMACSW, uint32_t portNum)
      {
              MDIO_rdWrphyRegIoctlCmd cmd;
              uint32_t regVal;
              cmd.portNum = portNum;
      
              /* PHY software reset */
              regVal = (1U << DP83867_SW_RESET);
              cmd.regAddr = DP83867_CTRL;
              cmd.regVal = &regVal;
              GMACSW_ioctl( hGMACSW,
                            GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                           (void *)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
      
              /* Set RGMII Delay values: Tx delay 0 and Rx delay 2.25ns */
              regVal = 0x08;
              cmd.regAddr = DP83867_RGMIIDCTL;
              cmd.regVal = &regVal;
              GMACSW_ioctl( hGMACSW,
                            GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                           (void *)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
      
              /* Enable RGMII and CLK delay bits */
              regVal = 0x0D1;
              cmd.regAddr = DP83867_RGMIICTL;
              cmd.regVal = &regVal;
              GMACSW_ioctl( hGMACSW,
                            GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                           (void *)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
      
              /* Set Drive Strength bits */
              regVal = 0x61F;
              cmd.regAddr = DP83867_IO_MUX_CTRL;
              cmd.regVal = &regVal;
              GMACSW_ioctl( hGMACSW,
                            GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                           (void *)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
      
              /* software restart */
              regVal = (1U << DP83867_SW_RESTART);
              cmd.regAddr = DP83867_CTRL;
              cmd.regVal = &regVal;
              GMACSW_ioctl( hGMACSW,
                            GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                           (void *)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
      }
      #endif
      
      /**
       *******************************************************************************
       * \brief String to displayed on telnet terminal
       *******************************************************************************
       */
      char *VerStr = "\n\n **** Vision SDK **** \n\n";
      
      #if (defined(NDK_PROC_TO_USE_IPU1_0) && defined(BUILD_M4_0))
          static HANDLE hEcho = 0;
          static HANDLE hEchoUdp = 0;
          static HANDLE hData = 0;
          static HANDLE hNull = 0;
          static HANDLE hOob = 0;
      #endif
      
      #if (defined(NDK_PROC_TO_USE_IPU1_0) && defined(BUILD_M4_0))
      /**
       *******************************************************************************
       *
       * \brief IPv6 initialization callback function
       *
       *******************************************************************************
       */
      
      #if defined(NDK_ENABLE_IPV6)
      static void IPv6DADStatus(IP6N Address, unsigned short dev_index,
              unsigned char Status)
      {
          char strIPAddress[40];
      
          /* Convert the IP Address to String Format. */
          inet_ntop(AF_INET6, &Address, strIPAddress, 40);
      
          /* Print the status of the address. */
          Vps_printf("  Network :Address %s on device %d is %s\n", strIPAddress, dev_index,
                  (Status == 1) ? "UNIQUE" : "DUPLICATE");
      
          System_flush();
      
          return;
      }
      #endif
      #endif
      
      /**
       *******************************************************************************
       *
       * \brief Stack init hook function to configure the second mac port
       *
       *******************************************************************************
       */
      void stackInitHookStaticEth1(void *config)
      {
          /* Set up static IP for interface 2 */
          {
              CI_ROUTE route;
              memset(&route, 0, sizeof(route));
              route.IPDestAddr = 0;
              route.IPDestMask = 0;
              route.IPGateAddr = inet_addr("192.168.2.1");
              CfgAddEntry(config, CFGTAG_ROUTE, 0U, 0U, sizeof(CI_ROUTE), (void *)&route,  0);
      
              CI_IPNET ip_net;
              ip_net.IPAddr = inet_addr("192.168.2.100");
              ip_net.IPMask = inet_addr("255.255.255.0");
              CfgAddEntry(config, CFGTAG_IPNET, 2U, 0U, sizeof(CI_IPNET), (void *)&ip_net, 0);
          }
      
          /* Set up static IP for interface 1 */
          {
              CI_ROUTE route;
              memset(&route, 0, sizeof(route));
              route.IPDestAddr = 0;
              route.IPDestMask = 0;
              route.IPGateAddr = inet_addr("192.168.1.1");
              CfgAddEntry(config, CFGTAG_ROUTE, 0U, 0U, sizeof(CI_ROUTE), (void *)&route,  0);
      
              CI_IPNET ip_net;
              ip_net.IPAddr = inet_addr("192.168.1.100");
              ip_net.IPMask = inet_addr("255.255.255.0");
              CfgAddEntry(config, CFGTAG_IPNET, 1U, 0U, sizeof(CI_IPNET), (void *)&ip_net, 0);
          }
      }
      
      void stackInitHookDynEth1(void *config)
      {
          static const UINT8 options[] = { DHCPOPT_SUBNET_MASK };
          CI_SERVICE_DHCPC dhcpc;
          memset(&dhcpc, 0, sizeof(dhcpc));
          dhcpc.cisargs.Mode   = 1U;
          dhcpc.param.pOptions = (UINT8*)&options[0];
          dhcpc.param.len      = 1;
      
          /* Set up DHCP for interface 2 */
          dhcpc.cisargs.IfIdx  = 2U;
          CfgAddEntry(config, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0U, sizeof(dhcpc), (void *)&dhcpc, 0);
      
          /* Set up DHCP for interface 1 */
          dhcpc.cisargs.IfIdx  = 1U;
          CfgAddEntry(config, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0U, sizeof(dhcpc), (void *)&dhcpc, 0);
      }
      
      /**
       *******************************************************************************
       *
       * \brief NDK callback to start DEAMON services
       *
       *******************************************************************************
       */
      void netOpenHook(void)
      {
      #if (defined(NDK_PROC_TO_USE_IPU1_0) && defined(BUILD_M4_0))
          /* Create our local servers */
          hEcho = DaemonNew( SOCK_STREAMNC, 0, 7, dtask_tcp_echo,
                             OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
          hEchoUdp = DaemonNew( SOCK_DGRAM, 0, 7, dtask_udp_echo,
                                OS_TASKPRINORM, OS_TASKSTKNORM, 0, 1 );
          hData = DaemonNew( SOCK_STREAM, 0, 1000, dtask_tcp_datasrv,
                             OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
          hNull = DaemonNew( SOCK_STREAMNC, 0, 1001, dtask_tcp_nullsrv,
                             OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
          hOob  = DaemonNew( SOCK_STREAMNC, 0, 999, dtask_tcp_oobsrv,
                             OS_TASKPRINORM, OS_TASKSTKNORM, 0, 3 );
      
      #if defined (NDK_ENABLE_IPV6)
          IPv6InterfaceInit(1, IPv6DADStatus);
          IPv6InterfaceInit(2, IPv6DADStatus);
      #endif
      #endif
      }
      
      /**
       *******************************************************************************
       *
       * \brief NDK callback to stop DEAMON services
       *
       *******************************************************************************
       */
      void netCloseHook(void)
      {
      #if (defined(NDK_PROC_TO_USE_IPU1_0) && defined(BUILD_M4_0))
      #if defined (NDK_ENABLE_IPV6)
          /* Enter the kernel Mode. */
          llEnter ();
          IPv6InterfaceDeInit(1);
          IPv6InterfaceDeInit(2);
          llExit ();
      #endif
      
          DaemonFree(hOob);
          DaemonFree(hNull);
          DaemonFree(hData);
          DaemonFree(hEchoUdp);
          DaemonFree(hEcho);
      #endif
      }
      
      /**
       *******************************************************************************
       *
       * \brief Print link status
       *
       *        This is a callback from the Ethernet driver. This function
       *        is called whenever there is a change in link state. The
       *        current PHY and current link state are passed as parameters.
       *
       *******************************************************************************
       */
      static void LOCAL_linkStatus( uint32_t phy, uint32_t linkStatus )
      {
          Vps_printf(" NDK: Link Status: %s on PHY %" PRIu32 "\n",LinkStr[linkStatus],phy);
      }
      
      /**
       *******************************************************************************
       *
       * \brief PHY Found callback
       *
       *        This is a callback from the Ethernet driver. This function
       *        is called when PHY is found at PHY mask. This can be used for PHY
       *        specific configuration.
       *
       *******************************************************************************
       */
      static void LOCAL_phyFoundCb(uint32_t portNum, uint32_t phy)
      {
          Vps_printf(" NSP GMAC: PHY %d Found on MAC Port %" PRIu32 "\n",phy, portNum);
      
      #if defined (BOARD_TYPE_TDA3XX_RVP)
          GMACSW_DeviceHandle handle = GMACSW_open(NULL);
          DP83867_configurePhyDelays(handle, portNum);
          GMACSW_close(handle);
      #endif
      }
      
      /**
       * \brief Return ID of processor on which networking runs
       */
      UInt32 Utils_netGetProcId(void)
      {
          UInt32 procId = SYSTEM_PROC_INVALID;
      
          #ifdef NDK_PROC_TO_USE_IPU1_0
          procId = SYSTEM_PROC_IPU1_0;
          #endif
      
          return procId;
      }
      
      /**
       *******************************************************************************
       * \brief Retrun IP address as a string
       *
       *        If network stack is not initialized correctly 0.0.0.0 IP address
       *        is returned
       *
       * \param ipAddrStr [OUT] Assigned IP address as a string
       *
       *******************************************************************************
       */
      void Utils_ndkGetIpAddrStr(char *ipAddrStr, UInt32 ifIdx)
      {
          IPN ipAddr;
      
          memset(&ipAddr, 0, sizeof(ipAddr));
      
          strcpy(ipAddrStr,"none");
      
      #if (defined(NDK_PROC_TO_USE_IPU1_0) && defined(BUILD_M4_0))
      
          NtIfIdx2Ip(ifIdx, &ipAddr);
          NtIPN2Str(ipAddr, ipAddrStr);
      
      #endif
      
      }
      
      Int32 Utils_netGetIpAddrStr(char *ipAddr, UInt32 ifIdx)
      {
          UInt32 linkId, procId;
          Int32 status;
          SystemCommon_IpAddr prm;
      
          prm.ifIdx = ifIdx;
      
          strcpy(ipAddr, "none" );
      
          procId = Utils_netGetProcId();
      
          if(procId==SYSTEM_PROC_INVALID)
          {
              status = SYSTEM_LINK_STATUS_EFAIL;
          }
          else
          {
              linkId = SYSTEM_MAKE_LINK_ID(procId, SYSTEM_LINK_ID_PROCK_LINK_ID);
      
              status = System_linkControl(
                  linkId,
                  SYSTEM_COMMON_CMD_GET_IP_ADDR,
                  &prm,
                  sizeof(prm),
                  TRUE
              );
      
              if(status==SYSTEM_LINK_STATUS_SOK)
              {
                  strcpy(ipAddr, prm.ipAddr);
              }
          }
      
          return status;
      }
      
      Bool Utils_netIsNetworkEnabled(void)
      {
          Bool status = (Bool)FALSE;
      
      #if defined(NDK_PROC_TO_USE_IPU1_0)
          status = (Bool)TRUE;
      #endif
      
          return status;
      }
      
      
    • ndk-testing.zip:
      ndk-testing.zip
  • Hi Simon,

    I'll take a look at this and get back to you ASAP. Most probably it should be a small error in the hooks file. 

    Regards,
    Anand

  • Hi Simon,

    The file looks fine to me, in the current configuration you are assigning PHY 0 to interface 0 and PHY 12 to interface 1. Did you try assigning PHY 0 to interface 1 when it didn't work? I need to check the pinmux to see if there is something more we need to do to determine which interface is enabled.

    Regards,
    Anand

  • Hi,

    Assigning PHY 0 to interface 1 does not work either. It does cause the program to print "Link Status: 1000Mb/s Full Duplex on PHY 0" on the console (and the link status changes when the ethernet cable is unplugged), but no packets can be observed using Wireshark on the PC side.

    Regards,
    Simon

  • Hi Simon,

    Are you using a static or dynamic IP address?

    Regards,
    Anand

  • Hi,

    The example uses a static IP address, but we've also tried using a dynamic IP address. In either case, there are no Ethernet packets being sent from the board.

    Regards,
    Simon

  • Hi Simon,

    Did you try using the pre-built binary for D3 starter kit and see if the network is working?

    If it doesn't work with 1Gbps switch, please try again with 100Mbps switch.

    If that doesn't work, you can ask D3 for RMA.

    Regards,
    Stanley

  • Hi,

    The pre-built binary for the D3 starter kit seems to be working fine, I can receive DHCP requests from the board on the PC side. We noticed that the pre-built image is running an older Vision SDK (v03.02.00.00) than the one we're building with. Has there been any changes to the PDK, NDK/NSP, or networking setup in the Vision SDK between these versions that may have caused it to stop working?

    Regards,
    Simon

  • The issue you are facing is most likely related to IO delay setting for ethernet phy or pin mux.

    We need to check with D3 to see if there is any change missing in 3.7 release.

    Just to confirm...

    You did the build with 3.7 release using tda3xx_rvp_bios_all config for both SBL and AppImage without any change?

  • Hi,

    I've been building the sample_app for tda3xx_rvp_bios_all without code changes (other than adding the RVP config in the sample_app and enabling the NDK). I've been using CCS to flash the firmware, and haven't touched anything SBL-related. I have a colleague in another team that has built the apps/ (configured for SBL, IIRC) with similar results regarding Ethernet, though.

    Regards,
    Simon

  • Hi Simon,

    D3 has found a workaround for the ethernet issue.

    Please apply the attached patch to Vision SDK 3.6 release and use 3.6 release for now. Network should be working on D3 board with the patched 3.6 release. However, Vision SDK 3.7 is still not working yet and we are debugging it.

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/791/0001_2D00_tda3x_2D00_eth_2D00_Fixed_2D00_bug_2D00_for_2D00_TDA3x_2D00_RVP_2D00_Ethernet.patch

    Regards,
    Stanley

  • Hello,

    I have a work around for this issue. 

    First, apply the attached patch to vision sdk (extension changed to a .txt for upload)

     

    From e0f9ab6f43d7d649d3893e160000434c327e194d Mon Sep 17 00:00:00 2001
    From: Ben McGee <benmcgee@d3engineering.com>
    Date: Wed, 20 Nov 2019 09:49:01 -0500
    Subject: [PATCH] tda3x:eth: Fixed bug for TDA3x RVP Ethernet
    
    ---
     links_fw/src/rtos/utils_common/src/ndk/ndk_nsp_hooks.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/links_fw/src/rtos/utils_common/src/ndk/ndk_nsp_hooks.c b/links_fw/src/rtos/utils_common/src/ndk/ndk_nsp_hooks.c
    index 23ffff1..b71a973 100644
    --- a/links_fw/src/rtos/utils_common/src/ndk/ndk_nsp_hooks.c
    +++ b/links_fw/src/rtos/utils_common/src/ndk/ndk_nsp_hooks.c
    @@ -578,7 +578,7 @@ GMACSW_Config *GMACSW_getConfig(void)
                              * port is connected to a PHY with address = 12, the second MAC
                              * port is connected to a PHY with address = 11.
                              */
    -                        pGMACSWConfig->macInitCfg[i].phyMask = (uint32_t)((uint32_t)0x1 << (uint32_t)(12U - i));
    +                        pGMACSWConfig->macInitCfg[i].phyMask = (uint32_t)((uint32_t)0x1 << (uint32_t)(13U - i));
                         #else
                             /*
                              * Adjust the PHY mask numbers for TDA3xx EVM. The first MAC
    -- 
    2.7.4
    
    

    Second, Copy the ti_components/network/nsp_gmacsw from vision sdk 3.06 (version 4.16.00.00) to overwrite the 4.16.01.01 version in Vision SDK 3.07

    Cheers,

    Ben

  • Hi,

    I've applied the patch and down-graded NSP to 4.16.00.00, but unfortunately still can't see any Ethernet packets being sent from the board. The MDIO_ALIVE register looks correct (indicating PHY 12 is alive) now, and the link status callback also reacts to the correct PHY, but unfortunately no packets are being sent. This applies to both Vision SDK 3.06 and 3.07.

    Regards,
    Simon

  • Hi Simon,

    Did you do a clean rebuild?

    Are you using DHCP?

    Thanks,

    Ben

  • Hi,

    Yes; a clean rebuild of 3.7 and a completely clean install of 3.6; both with and without DHCP (does not seem to make any difference).

    Regards,
    Simon

  • Hi All,

    Please try this attached AppImage and let me know if it works on your systems. It uses DHCP. Please note it take about 10 seconds after boot for the IP address to be acquired.

    Thanks,

    BenAppImage.zip

  • Hi,

    The attached AppImage seems to work; I can see DHCP Discover messages from the D3 board.

    Is there any specific initialization performed by the applications in apps/ that is not performed by the sample_app/ shipped with the Vision SDK?

    Regards,
    Simon

  • Hi Simon,

    Any initialisation required is done for all the apps in SDK. Did you rebuild vision_sdk after applying the patch in ndk_nsp_hooks.c? Are you not able to see an IP address when you build with a DHCP IP address? Can you provide a UART log of the non-working case? Because the patch BenM provided should fix your issue with PHY

  • Hi,

    Yes, I've done a clean rebuild after applying the patch and downgrading NSP to 4.16.00.00; I can see no Ethernet packages being sent from the board, and consequently the board does not get an IP address using DHCP. I have attached an UART log of the non-working case: UART-log.txt.

    Here's also a copy of the AppImage, if that helps: AppImage.zip.

    Regards,
    Simon

  • Hi Simon,

    I get a broken link when I open the UART log. Can you attach is once more?

  • Hi,

    Here's the contents of the UART log:

    AL!
     TDA3xx SBL Boot
    
     Identified 15X15 Silicon
    
     DPLL Configuration Completed
    
     Clock Domain Configuration Completed
    
     Module Enable Configuration Completed
    
     TI EVM PAD Configuration Completed
    
     DDR Configuration Completed
    
     TDA3xx SOC Init Completed
    
     App Image Download Begins
    
     SD Boot - file open completed successfully
    
     IPU1 CPU0 Image Load Completed
    
     App Image Download Completed
    
     EVE MMU configuration completed
    
    *****************************************************************
    
     32K Timer is used to measure cycles, divide by 32K to get time in seconds
    
     Reset to SBL Init Cycles - 650  (19.83 ms)
    
     SBL Initial Config Cycles - 334  (10.19 ms)
    
     SOC Init Cycles - 493  (15.04 ms)
    
     DDR Config Clock Cycles - 230  (7.01 ms)
    
     App Image Load Cycles - 19942  (608.58 ms)
    
     Slave Core Bootup Cycles - 710  (21.66 ms)
    
     SBL Boot-up Cycles - 21710  (662.53 ms)
    
    *****************************************************************
    
     No IPU1 CPU1 App Found, Switching to while Loop
    
     Jumping to IPU1 CPU0 App
    [IPU1-0]      0.739156 s:  ***** IPU1_0 Firmware build time 10:49:42 Nov 29 2019
    [IPU1-0]      0.739309 s:  *** SYSTEM: CPU Frequency <ORG = 212800000 Hz>, <NEW = 212800000 Hz>
    [IPU1-0]      0.748886 s:  SYSTEM: System Common Init in progress !!!
    [IPU1-0]      0.755932 s:  SYSTEM: IPC init in progress !!!
    [IPU1-0]      0.755993 s:  SYSTEM: Notify init done !!!
    [IPU1-0]      0.756145 s:  SYSTEM: MsgQ init done !!!
    [IPU1-0]      0.756206 s:  SYSTEM: IPC init DONE !!!
    [IPU1-0]      0.758219 s:  SYSTEM: System Common Init Done !!!
    [IPU1-0]      0.758280 s:  SYSTEM: System Init in progress !!!
    [IPU1-0]      0.758341 s:  SYSTEM: BSP Common Init in progress !!!
    [IPU1-0]      0.758402 s:  SYSTEM: BSP Common Init Done !!!
    [IPU1-0]      0.758463 s:  SYSTEM: BSP Platform Init in progress !!!
    [IPU1-0]      0.758555 s:  SYSTEM: BSP Platform Init Done !!!
    [IPU1-0]      0.758616 s:  SYSTEM: FVID2 Init in progress !!!
    [IPU1-0]      0.758738 s:  SYSTEM: FVID2 Init Done !!!
    [IPU1-0]      0.758799 s:  SYSTEM: VPS Init in progress !!!
    [IPU1-0]      0.758860 s:  SYSTEM: VPDMA Descriptor Memory Address translation ENABLED [0xa0000000 -> 0x80000000]
    [IPU1-0]      0.761087 s: *** VPDMA Firmware Loading... ***
    [IPU1-0]      0.761209 s: VPDMA Firmware Address = 0x9ffc7800
    [IPU1-0]      0.761270 s: VPDMA Load Address     = 0x4897d004
    [IPU1-0]      0.761361 s: VPDMA Firmware Version = 0x4d0001b8
    [IPU1-0]      0.761453 s: VPDMA List Busy Status = 0x00000000
    [IPU1-0]      0.761514 s: *** VPDMA Firmware Load Success ***
    [IPU1-0]      0.796864 s:  SYSTEM: VPS Init Done !!!
    [IPU1-0]      0.797566 s:  UTILS: DMA: HWI Create for INT34 !!!
    [IPU1-0]      0.797810 s:  SYSTEM: SW Message Box Msg Pool, Free Msg Count = 1024
    [IPU1-0]      0.797932 s:  SYSTEM: Heap = LOCAL_DDR            @ 0x00000000, Total size = 262144 B (256 KB), Free size = 247736 B (241 KB)
    [IPU1-0]      0.798084 s:  SYSTEM: Heap = SR_OCMC              @ 0x00000000, Total size = 0 B (0 KB), Free size = 0 B (0 KB)
    [IPU1-0]      0.798206 s:  SYSTEM: Heap = SR_DDR_CACHED        @ 0x86103000, Total size = 369086464 B (351 MB), Free size = 369086464 B (351 MB)
    [IPU1-0]      0.798359 s:  SYSTEM: Heap = SR_DDR_NON_CACHED    @ 0xbfe00000, Total size = 916224 B (0 MB), Free size = 916224 B (0 MB)
    [IPU1-0]      0.798511 s:  SYSTEM: Initializing Links !!!
    [IPU1-0]      0.871896 s:  SYSTEM: Initializing Links ... DONE !!!
    [IPU1-0]      0.872872 s:  BOARD: Board Init in progress !!!
    [IPU1-0]      0.873848 s:  BOARD: Board Init Done !!!
    [IPU1-0]      0.877874 s:
    [IPU1-0]      0.877935 s:  Vision SDK Version    : [REL_VISION_SDK_03_07_00_00]
    [IPU1-0]      0.877996 s:  FVID2 Version         : [FVID_02_01_00_01]
    [IPU1-0]      0.878057 s:  BSP Version           : [PDK_01_10_03_xx]
    [IPU1-0]      0.878118 s:  Platform              : [EVM]
    [IPU1-0]      0.878179 s:  SOC                   : [TDA3XX]
    [IPU1-0]      0.878240 s:  SOC Revision          : [ES2.0]
    [IPU1-0]      0.878667 s:  Board Detected        : [TDA3XX D3 Starter Kit]
    [IPU1-0]      0.878911 s:  Base Board Revision   : [REV - SK DASH]
    [IPU1-0]      0.878972 s:  Daughter Card Revision: [REV A]
    [IPU1-0]      0.879033 s:
    [IPU1-0]      1.040108 s:  NSP GMAC: PHY 12 Found on MAC Port 1
    [IPU1-0]      1.740498 s:   Network :Address fe80::5a7a:62ff:febf:ee9c on device 1 is UNIQUE
    [IPU1-0]      1.878850 s:  QSPI Init Started
    [IPU1-0]      1.879033 s:  MID - 20
    [IPU1-0]      1.879064 s:  DID - ba
    [IPU1-0]      1.879125 s:  QSPI Init Completed Sucessfully
    [IPU1-0]      1.879186 s:  UTILS: DMM: API NOT supported in TDA3xx !!!
    [IPU1-0]      1.879247 s:  UTILS: DMM: API NOT supported in TDA3xx !!!
    [IPU1-0]      3.840663 s:  NDK: Link Status: 1000Mb/s Full Duplex on PHY 12
    

    Regards,
    Simon

  • Hi Simon,

    Thanks a lot for the log. So I take it that you don't see anything after this, as in the IP address is not getting printed (Not even "0.0.0.0" as the default?). You have to wait for a while for the IP address to be assigned by DHCP. But you are not seeing any DHCP requests on wireshark as well, right. Do you see something like "My IP Address : x.x.x.x" when you hit enter?

  • Hi,

    Correct; no IP address is getting printed (not after waiting at least a few minutes), not even after hitting enter. There are no DHCP requests visible in Wireshark.

    Regards,
    Simon

  • Hi Simon,

    In additional to applying the previously provided patch for phy Id, a change has to be made to the nsp:

    ----------------------- packages/ti/nsp/drv/config.bld ------------------------

    index 45eb349..9061511 100755
    @@ -81,9 +81,9 @@ var gccInc   = " -I\"" + gccRoot + "/include\" ";
     //gccCommonCopts   += " -DNSP_DYNAMIC_ALLOCATION";
     
     /* Uncomment below to enable Dual MAC mode */
    -// tiDspCommonCopts += " -DDUAL_MAC_MODE ";
    -// tiArmCommonCopts += " -DDUAL_MAC_MODE ";
    -// gccCommonCopts   += " -DDUAL_MAC_MODE ";
    +tiDspCommonCopts += " -DDUAL_MAC_MODE ";
    +tiArmCommonCopts += " -DDUAL_MAC_MODE ";
    +gccCommonCopts   += " -DDUAL_MAC_MODE ";
     
     /* TI C674x DSP Target compiler options */

     var tiC674DSPTarget = xdc.useModule('ti.targets.elf.C674');

    And then nsp has to be rebuilt. The easiest way to rebuild nsp is to update paths in packages/ti/nsp/drv/.xdcenv.mak and then make the component

    Cheers,

    Ben

  • Hi,

    I applied the patch and rebuilt the NSP, then did a clean rebuild of the sample_app, but unfortunately I still cannot see any DHCP requests in Wireshark.

    Regards,
    Simon

  • Hi Simon,

    I follow the same instructions from Ben and now I can get IP address on my D3 board.

    Did you do a clean build of NSP? First "gmake clean" and then "gmake all".

    Regards,
    Stanley

  • Hi,

    After doing a clean rebuild of everything again, Ethernet seems to be working when building both apps and sample_app. However, I still cannot get a freestanding (non-Vision SDK) application to work with Ethernet.

    Regards.
    Simon

  • Simon,

    There are configuration/initialization steps required for NSP/NDK, which are taken care by Vision SDK framework when building/running with Vision SDK applications.

    If you are creating your own application outside of Vision SDK framework, you should follow the example from NSP to config/initialize NSP/NDK.

    You can find those examples under ~\ti_components\networking\nsp_gmacsw_4_16_00_00\packages\ti\ndk\tda3xx\examples_ipu1

    Regards,
    Stanley

  • In NSP example, you have to update the configuration for PHY address, similar to the patch provided by Ben.

    The example is based on EVM, not RVP.

  • Hi,

    I have been following the example from the NSP (with the updated PHY config and patched NSP, and also added the DP83867_configurePhyDelays function which the Vision SDK includes when building for the RVP), but I cannot get any Ethernet working.

    I have attached two applications in which Ethernet is not working for me; both are more or less based on the examples from the NSP.

    Regards,
    Simon

  • Hi Simon,

    One problem I have observed when running NSP example is the pin mux for RGMII1 port.

    In CCS, the default GEL file pad config enables RGMII0 port based on EVM, not RGMII1 port used by RVP.

    When running with Vision SDK app, there is an initialization routine which will take care of this.

    Please refer to RvpInitEthernet() function in ~ti_components/drivers/pdk_xx_xx_xx_xx/packages/ti/drv/vps/src/boards/src/bsp_boardTda3xx.c.

    You need to port this function to tda3xx_init() function in NSP example.

    This should be called before PHY delays are configured by DP83867_configurePhyDelays() since the above function will reset PHY.

    Regards,
    Stanley

  • Hi Stanley,

    I have tried including the RGMII1 pinmux settings from the PDK in both of the examples I attached in my previous message (although they are commented-out in the external-loopback-tda3xx-ipu1.zip sources), but unfortunately I still cannot get any Ethernet packets from the board.

    Regards,
    Simon

  • Could you share your latest changes?

  • Hi Simon,

    Even after adding the pinmux, the PHY is still not being detected by the example.

    My guess is there are more RVP board related configurations which are taken care by SDK.

    I don't think it is worth the effort to port all the missing pieces to NSP example.

    Could you add your application under Vision SDK?

    You don't have to use Link framework in your application but you can rely on SDK framework to initialize the board properly.

    Regards,
    Stanley

  • Hi,

    When you say we can "rely on SDK framework to initialize the board", do you mean we should use the BSP platform initialization from the VPS/PDK? In order to integrate this code in our existing build system, we would like to depend on as few components (preferably self-contained) as possible; depending on the PDK should be fine but having to build our application in the Vision SDK build system is not an option for us.

    I tried adding the PDK (build for TDA3xx-RVP) to the NSP example, running the BSP board/platform initialization routines in the main task of the application, but unfortunately this did not seem to help in getting Ethernet working.

    Regards,
    Simon

  • Hi Simon,

    I have taken a closer look at the problem. The issue turns out to be pinmux still.

    The pin VOUT1_FLD is configured as GPIO2_22 and control the IO buffer OE input.

    Pinmux for this pin was configured as GPIO2_22 correctly but it is not set to drive the line HIGH.

    This somehow creates some bus contention on the line even though there is external pullup.

    So, the IO buffer didn't get OE as HIGH and disconnected all the RX pin between TDA and PHY.

    After this, PHY is up. However, for DHCP to work for Port 1, there is also some configuration file change required.

    I have attached the changes required here.

    4442.helloWorld.cfg

    /*
     * Copyright (C) 2014, Texas Instruments Incorporated  - http://www.ti.com/
     *
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /**
     *   @file  tda3xx_init.c
     *
     *   @brief
     *       Do all necessary board level initialization for NDK example.
     *
     */
    
    
    /*---------------------------------------------------------------------------*\
    |                                Header Files                                 |
    \*---------------------------------------------------------------------------*/
    
    /* Standard language headers */
    #include <stddef.h>
    #include <stdio.h>
    #include <inttypes.h>
    #include <string.h>
    
    /* OS/Posix headers */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* NDK Dependencies */
    #include <ti/ndk/inc/netmain.h>
    
    /* NSP Dependencies */
    #include <ti/nsp/drv/inc/gmacsw.h>
    #include <ti/nsp/drv/inc/gmacsw_config.h>
    
    /* Project dependency headers */
    
    
    /*---------------------------------------------------------------------------*\
    |                             Extern Declarations                             |
    \*---------------------------------------------------------------------------*/
    
    void DP83867_configurePhyDelays(GMACSW_DeviceHandle, uint32_t);
    void configureRGMII1(void);
    
    /*---------------------------------------------------------------------------*\
    |                            Local Macros/Defines                             |
    \*---------------------------------------------------------------------------*/
    
    /* Ethernet MAC ID registers(Devcice configuration) from EFuse */
    #define MAC_ID0_LO                (*(volatile uint32_t*)0x4A002514)
    #define MAC_ID0_HI                (*(volatile uint32_t*)0x4A002518)
    #define MAC_ID1_LO                (*(volatile uint32_t*)0x4A00251C)
    #define MAC_ID1_HI                (*(volatile uint32_t*)0x4A002520)
    
    #define DP83867_PHYADRESS_TDA3_RVP   (0xCU)
    
    /*---------------------------------------------------------------------------*\
    |                            Local Typedefs/Enums                             |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                         Local Function Declarations                         |
    \*---------------------------------------------------------------------------*/
    
    static void LOCAL_linkStatus(uint32_t phy, uint32_t linkStatus);
    static void LOCAL_phyFound(uint32_t portNum, uint32_t phy);
    static uint32_t log2(uint32_t v);
    
    /*---------------------------------------------------------------------------*\
    |                         Local Variable Declarations                         |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                         Global Variable Declarations                        |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                           Local Function Definitions                        |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                          Global Function Definitions                        |
    \*---------------------------------------------------------------------------*/
    
    /*
     * We changed our CFG file to point call this private init
     * function. Here we initialize our some particulars for
     * our board/device.
     */
    void tda3xx_init( void )
    {
        /* Nothing to do for this platform */
        configureRGMII1();
    }
    
    /*
     * GMACSW_getConfig()
     *
     * This is a callback from the Ethernet driver. This function
     * is used by the driver to an application-specific config structure
     * for the GMACSW driver. Typically it will be used to provide the
     * MAC address(es) and the link status update callback function.
     */
    GMACSW_Config *GMACSW_getConfig(void)
    {
        static const char* ConnTypeStr[] = {
            "MII 10Mb/s", "MII 100Mb/s",
            "RMII 10Mb/s", "RMII 100Mb/s",
            "RGMII 100Mb/s Half Duplex",
            "RGMII 100Mb/s Full Duplex",
            "RGMII 1000Mb/s Full Duplex",
            "RGMII Inband Detection Mode"
        };
    
        int i = 0;
        uint8_t macAddr[6];
    
        /* Get default starting config */
        GMACSW_Config *pGMACSWConfig = GMACSW_CONFIG_getDefaultConfig();
    
        /* Set count of active MAC ports */
        /*pGMACSWConfig->activeMACPortMask = PORT_MASK_MAC_BOTH;*/
        pGMACSWConfig->activeMACPortMask = PORT_MASK_MAC_2;
    
        /* Update default config with the correct MAC addresses */
        for(i=0; i<MAC_NUM_PORTS; i++)
        {
            if ( (1U << i) & pGMACSWConfig->activeMACPortMask )
            {
                if (0==i)
                {
                    /* Get the MAC Address from control module register space */
                    macAddr[5] = (uint8_t)((MAC_ID0_LO & 0x000000FFu) >> 0u );
                    macAddr[4] = (uint8_t)((MAC_ID0_LO & 0x0000FF00u) >> 8u );
                    macAddr[3] = (uint8_t)((MAC_ID0_LO & 0x00FF0000u) >> 16u);
    
                    macAddr[2] = (uint8_t)((MAC_ID0_HI & 0x000000FFu) >> 0u );
                    macAddr[1] = (uint8_t)((MAC_ID0_HI & 0x0000FF00u) >> 8u );
                    macAddr[0] = (uint8_t)((MAC_ID0_HI & 0x00FF0000u) >> 16u);
                }
                else
                {
                    /* Get the MAC Address from control module register space */
                    macAddr[5] = (uint8_t)((MAC_ID1_LO & 0x000000FFu) >> 0u );
                    macAddr[4] = (uint8_t)((MAC_ID1_LO & 0x0000FF00u) >> 8u );
                    macAddr[3] = (uint8_t)((MAC_ID1_LO & 0x00FF0000u) >> 16u);
    
                    macAddr[2] = (uint8_t)((MAC_ID1_HI & 0x000000FFu) >> 0u );
                    macAddr[1] = (uint8_t)((MAC_ID1_HI & 0x0000FF00u) >> 8u );
                    macAddr[0] = (uint8_t)((MAC_ID1_HI & 0x00FF0000u) >> 16u);
                }
    
                printf("\nMAC Port %d Address:\n\t%02x-%02x-%02x-%02x-%02x-%02x\n", i,
                        macAddr[0], macAddr[1], macAddr[2],
                        macAddr[3], macAddr[4], macAddr[5]);
    
                /* Copy the correct MAC address into the driver config */
                memcpy( (void *)&(pGMACSWConfig->macInitCfg[i].macAddr[0]), (void *)&macAddr[0], 6 );
    
                /*
                * Adjust the PHY mask numbers for the Vayu EVM. The first MAC
                * port is connected to a PHY with address = 2, the second MAC
                * port is connected to a PHY with address = 3.
                */
                /*GMACSWConfig->macInitCfg[i].phyMask = 0x1 << i;*/
                pGMACSWConfig->macInitCfg[i].phyMask = (uint32_t)((uint32_t)0x1 << (uint32_t) DP83867_PHYADRESS_TDA3_RVP);
                pGMACSWConfig->macInitCfg[i].macConnectionType =
                        MAC_CONNECTION_TYPE_RGMII_DETECT_INBAND;
            }
        }
    
        /* Print MAC configurations */
        const int NUM_MACS = (sizeof(pGMACSWConfig->macInitCfg) / sizeof(pGMACSWConfig->macInitCfg[0]));
        for (i = 0; i < NUM_MACS; ++i)
        {
            const MAC_Config* cfg = &pGMACSWConfig->macInitCfg[i];
    
            printf("MAC port %d, PHY %u\n", i, log2(cfg->phyMask));
            printf("  address: %02x:%02x:%02x:%02x:%02x:%02x\n",
                   cfg->macAddr[0], cfg->macAddr[1], cfg->macAddr[2],
                   cfg->macAddr[3], cfg->macAddr[4], cfg->macAddr[5]);
            printf("  MTU: %u, PRI: %u, CFI: %u, VID: %u\n",
                   cfg->PktMTU, cfg->portPri, cfg->portCfi, cfg->portVID);
            printf("  Flags: MAC [%08x] MDIO  [%08x]\n", cfg->macModeFlags, cfg->mdioModeFlags);
            printf("  Masks: PHY [%08x] Mlink [%08x]\n", cfg->phyMask, cfg->MLinkMask);
            printf("  Connection type: %s\n", ConnTypeStr[cfg->macConnectionType]);
        }
    
        /* Set callbacks */
        pGMACSWConfig->mdioCfg.phyFoundCallback = &LOCAL_phyFound;
        pGMACSWConfig->linkStatusCallback       = &LOCAL_linkStatus;
    
        /* Return the config */
        return pGMACSWConfig;
    }
    
    void stackInitHookDynEth1(void *hCfg)
    {
        /*Add the setup for DHCP for interface 2*/
        CI_SERVICE_DHCPC dhcpc;
        static UINT8 DHCP_OPTIONS[] = { DHCPOPT_SUBNET_MASK };
    
        bzero(&dhcpc, sizeof(dhcpc));
        dhcpc.cisargs.Mode = 1U;
        dhcpc.cisargs.IfIdx = 2U;
        dhcpc.param.pOptions = DHCP_OPTIONS;
        dhcpc.param.len = 1;
    
        CfgAddEntry(hCfg, (uint32_t)CFGTAG_SERVICE, (uint32_t)CFGITEM_SERVICE_DHCPCLIENT, 0U, (int32_t)sizeof(dhcpc), (UINT8 *)(void *)&dhcpc, 0);
    }
    
    /*---------------------------------------------------------------------------*\
    |                           Local Function Definitions                        |
    \*---------------------------------------------------------------------------*/
    
    /*
     * LOCAL_linkStatus()
     *
     * This is a callback from the Ethernet driver. This function
     * is called whenever there is a change in link state. The
     * current PHY and current link state are passed as parameters.
     */
    static void LOCAL_linkStatus( uint32_t phy, uint32_t linkStatus )
    {
        static const char* LinkStr[] = {
            "No Link",              "None",
            "10Mb/s Half Duplex",   "10Mb/s Full Duplex",
            "100Mb/s Half Duplex",  "100Mb/s Full Duplex",
            "1000Mb/s Half Duplex", "1000Mb/s Full Duplex",
        };
        printf("Link Status: %s on PHY %d\n", LinkStr[linkStatus], phy);
    }
    
    /*
     * LOCAL_phyFound()
     */
    static void LOCAL_phyFound(uint32_t portNum, uint32_t phy)
    {
        printf("GMAC: PHY %u found on MAC port %u\n", phy, portNum);
    
        GMACSW_DeviceHandle handle = GMACSW_open(NULL);
        DP83867_configurePhyDelays(handle, portNum);
        GMACSW_close(handle);
    }
    
    /*
     * log2()
     */
    static uint32_t log2(uint32_t v)
    {
        uint32_t r = 0;
        while (v >>= 1u)
        {
          r++;
        }
        return r;
    }
    
    /*---------------------------------------------------------------------------*\
    |                                 End of File                                 |
    \*---------------------------------------------------------------------------*/
    

    /*
     * Copyright (C) 2014, Texas Instruments Incorporated  - http://www.ti.com/
     *
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /**
     *   @file  tda3xx_init.c
     *
     *   @brief
     *       Do all necessary board level initialization for NDK example.
     *
     */
    
    
    /*---------------------------------------------------------------------------*\
    |                                Header Files                                 |
    \*---------------------------------------------------------------------------*/
    
    /* Standard language headers */
    #include <stddef.h>
    #include <stdio.h>
    #include <inttypes.h>
    #include <string.h>
    
    /* OS/Posix headers */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* NDK Dependencies */
    
    /* NSP Dependencies */
    #include <ti/nsp/drv/inc/gmacsw.h>
    #include <ti/nsp/drv/inc/gmacsw_config.h>
    
    /* Project dependency headers */
    #include "hw_ctrl_core_pad_io.h"
    
    
    /*---------------------------------------------------------------------------*\
    |                             Extern Declarations                             |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                            Local Macros/Defines                             |
    \*---------------------------------------------------------------------------*/
    
    /* From PDK CSL (soc.h and hw_types.h) */
    #define SOC_CORE_PAD_IO_REGISTERS_BASE                                          (0x4a003400U)
    #define SOC_GPIO2_BASE                                                          (0x48055000U)
    
    #define HW_RD_REG32(addr)        (HW_RD_REG32_RAW((uint32_t) (addr)))
    #define HW_WR_REG32(addr, value) (HW_WR_REG32_RAW((uint32_t) (addr), (uint32_t) (value)))
    
    static inline uint32_t HW_RD_REG32_RAW(uint32_t addr)
    {
        uint32_t regVal = *(volatile uint32_t *) addr;
        asm("    dsb");
        return (regVal);
    }
    
    static inline void HW_WR_REG32_RAW(uint32_t addr, uint32_t value)
    {
        *(volatile uint32_t *) addr = value;
        asm("    dsb");
        return;
    }
    
    /* From PDK headers (bsp_platform.h) */
    #define BSP_PLATFORM_IOPAD_CFG_DEFAULT                  ((uint32_t) 0xFFU)
    #define BSP_PLATFORM_IOPAD_CFG_PULLUDENABLE_ENABLE      ((uint32_t) 0x00U)
    #define BSP_PLATFORM_IOPAD_CFG_PULLUDENABLE_DISABLE     ((uint32_t) 0x01U)
    #define BSP_PLATFORM_IOPAD_CFG_PULLTYPESELECT_DOWN      ((uint32_t) 0x00U)
    #define BSP_PLATFORM_IOPAD_CFG_PULLTYPESELECT_UP        ((uint32_t) 0x02U)
    #define BSP_PLATFORM_IOPAD_CFG_INPUTENABLE_OUT          ((uint32_t) 0x00U)
    #define BSP_PLATFORM_IOPAD_CFG_INPUTENABLE_BI           ((uint32_t) 0x04U)
    
    /* From PDK internal headers (gpio_v2.h) */
    #define GPIO_DIR_INPUT                   (uint32_t) (0x1U)
    #define GPIO_DIR_OUTPUT                  (uint32_t) (0x0U)
    #define GPIO_PIN_LOW                     (uint32_t) (0x0U)
    #define GPIO_PIN_HIGH                    (uint32_t) (0x1U)
    
    /* From PDK headers (hw_gpio.h) */
    #define GPIO_OE                            (0x134U)
    #define GPIO_CLEARDATAOUT                  (0x190U)
    #define GPIO_SETDATAOUT                    (0x194U)
    
    /* DP83867IR register details */
    #define DP83867_CTRL         (0x1FU)
    #define DP83867_RGMIICTL     (0x0032U)
    #define DP83867_RGMIIDCTL    (0x0086U)
    #define DP83867_IO_MUX_CTRL  (0x0170U)
    #define DP83867_SW_RESET    (15)
    #define DP83867_SW_RESTART  (14)
    
    /*---------------------------------------------------------------------------*\
    |                            Local Typedefs/Enums                             |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                         Local Function Declarations                         |
    \*---------------------------------------------------------------------------*/
    
    static void setPinMuxRegs(uint32_t mode_index, uint32_t offset, uint32_t pupd_info);
    static void GPIODirModeSet(uint32_t baseAdd, uint32_t pinNumber, uint32_t pinDirection);
    static void GPIOPinWrite(uint32_t baseAdd, uint32_t pinNumber, uint32_t pinValue);
    
    /*---------------------------------------------------------------------------*\
    |                         Local Variable Declarations                         |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                         Global Variable Declarations                        |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                           Local Function Definitions                        |
    \*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*\
    |                          Global Function Definitions                        |
    \*---------------------------------------------------------------------------*/
    
    void DP83867_configurePhyDelays(GMACSW_DeviceHandle hGMACSW, uint32_t portNum)
    {
        printf("Configuring DP83867 PHY delays...\n");
    
        MDIO_rdWrphyRegIoctlCmd cmd;
        uint32_t regVal;
        cmd.portNum = portNum;
    
        /* PHY software reset */
        regVal = (1U << DP83867_SW_RESET);
        cmd.regAddr = DP83867_CTRL;
        cmd.regVal  = &regVal;
        GMACSW_ioctl(hGMACSW,
                     GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                     (void*)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
    
        /* Set RGMII Delay values: Tx delay 0 and Rx delay 2.25ns */
        regVal = 0x08;
        cmd.regAddr = DP83867_RGMIIDCTL;
        cmd.regVal  = &regVal;
        GMACSW_ioctl(hGMACSW,
                     GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                     (void*)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
    
        /* Enable RGMII and CLK delay bits */
        regVal = 0x0D1;
        cmd.regAddr = DP83867_RGMIICTL;
        cmd.regVal  = &regVal;
        GMACSW_ioctl(hGMACSW,
                     GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                     (void*)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
    
        /* Set Drive Strength bits */
        regVal = 0x61F;
        cmd.regAddr = DP83867_IO_MUX_CTRL;
        cmd.regVal  = &regVal;
        GMACSW_ioctl(hGMACSW,
                     GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                     (void*)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
    
        /* software restart */
        regVal = (1U << DP83867_SW_RESTART);
        cmd.regAddr = DP83867_CTRL;
        cmd.regVal  = &regVal;
        GMACSW_ioctl(hGMACSW,
                     GMACSW_IOCTL_MDIO_WRITE_DP83867_PHY_INDIRECT_REGISTER,
                     (void*)&cmd, sizeof(MDIO_rdWrphyRegIoctlCmd));
    }
    
    void configureRGMII1(void)
    {
        System_printf("Configuring RGMII1 pin mux...\n");
    
        /* RGMII1 mux */
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_CLK_MUXMODE_RGMII1_TXC_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_CLK,
            BSP_PLATFORM_IOPAD_CFG_PULLUDENABLE_ENABLE);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_BEN0_MUXMODE_RGMII1_TXCTL_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_BEN0,
            BSP_PLATFORM_IOPAD_CFG_PULLUDENABLE_ENABLE);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_BEN1_MUXMODE_RGMII1_TXD3_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_BEN1,
            BSP_PLATFORM_IOPAD_CFG_PULLUDENABLE_ENABLE);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_ADVN_ALE_MUXMODE_RGMII1_TXD2_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_ADVN_ALE,
            BSP_PLATFORM_IOPAD_CFG_PULLUDENABLE_ENABLE);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_OEN_REN_MUXMODE_RGMII1_TXD1_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_OEN_REN,
            BSP_PLATFORM_IOPAD_CFG_PULLUDENABLE_ENABLE);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_WEN_MUXMODE_RGMII1_TXD0_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_WEN,
            BSP_PLATFORM_IOPAD_CFG_PULLUDENABLE_ENABLE);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_CS0_MUXMODE_RGMII1_RXCTL_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_CS0,
            BSP_PLATFORM_IOPAD_CFG_INPUTENABLE_BI);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_WAIT0_MUXMODE_RGMII1_RXD3_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_WAIT0,
            BSP_PLATFORM_IOPAD_CFG_INPUTENABLE_BI);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_AD0_MUXMODE_RGMII1_RXD2_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_AD0,
            BSP_PLATFORM_IOPAD_CFG_INPUTENABLE_BI);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_AD1_MUXMODE_RGMII1_RXD1_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_AD1,
            BSP_PLATFORM_IOPAD_CFG_INPUTENABLE_BI);
        setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_AD2_MUXMODE_RGMII1_RXD0_1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_AD2,
            BSP_PLATFORM_IOPAD_CFG_INPUTENABLE_BI);
        setPinMuxRegs(
            (uint32_t) 1,
            (uint32_t) CTRL_CORE_PAD_IO_GPMC_AD13,
            BSP_PLATFORM_IOPAD_CFG_INPUTENABLE_BI);
        setPinMuxRegs(
            (uint32_t) 0,
            (uint32_t) CTRL_CORE_PAD_IO_MDIO_MCLK,
            BSP_PLATFORM_IOPAD_CFG_PULLTYPESELECT_UP);
        setPinMuxRegs(
            (uint32_t) 0,
            (uint32_t) CTRL_CORE_PAD_IO_MDIO_D,
            0x06);
    
        /* GPIO2_19 */
        /* Active low reset line on PHY */
        setPinMuxRegs(
            (uint32_t) 14,
            (uint32_t) CTRL_CORE_PAD_IO_VIN2A_CLK0,
            BSP_PLATFORM_IOPAD_CFG_DEFAULT);
    
        /* GPIO2_22 */
        /* Controls bus switch on the RGMII1 receive pins
         *  Low  - disconnected from PHY
         *  High - connected to PHY
         */
         setPinMuxRegs(
            (uint32_t) CTRL_CORE_PAD_IO_VOUT1_FLD_MUXMODE_GPIO2_22_14,
            (uint32_t) CTRL_CORE_PAD_IO_VOUT1_FLD,
             BSP_PLATFORM_IOPAD_CFG_DEFAULT);
         GPIODirModeSet(SOC_GPIO2_BASE, 22, GPIO_DIR_OUTPUT);
         GPIOPinWrite(SOC_GPIO2_BASE, 19, GPIO_PIN_HIGH);
    
        /* toggle phy reset_n */
        GPIODirModeSet(SOC_GPIO2_BASE, 19, GPIO_DIR_OUTPUT);
        GPIOPinWrite(SOC_GPIO2_BASE, 19, GPIO_PIN_LOW);
        {
            volatile uint32_t dummy = 100000U;
            while (--dummy);
        }
        GPIOPinWrite(SOC_GPIO2_BASE, 19, GPIO_PIN_HIGH);
    }
    
    /*---------------------------------------------------------------------------*\
    |                           Local Function Definitions                        |
    \*---------------------------------------------------------------------------*/
    
    static void setPinMuxRegs(uint32_t mode_index, uint32_t offset, uint32_t pupd_info)
    {
        /* Unlock MMR_5 for pin muxing*/
        //HW_WR_REG32(0x4A002550U, 0x143F832CU);
    
        /* IO input glitches may occur when switching pull type and
         * mux mode simultaneously. To avoid such glitches it is expected
         * two separate register writes to transition to the desired state */
        if (offset != 0xffffu)
        {
            uint32_t muxVal = HW_RD_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE + offset);
            if (pupd_info != 0xFFu)
            {
                muxVal &= ~(0x70000U);
                muxVal |= ((pupd_info & 0x07U) << 16U);
                HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE + offset, muxVal);
            }
            muxVal &= ~((uint32_t) 0x0FU);
            muxVal |= (mode_index & 0x0000000FU);
            HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE + offset, muxVal);
        }
    
        /* Lock MMR_5 for pin muxing*/
        //HW_WR_REG32(0x4A002550U, 0x6F361E05U);
    }
    
    static void GPIODirModeSet(uint32_t baseAdd,
                               uint32_t pinNumber,
                               uint32_t pinDirection)
    {
        uint32_t gpioOeValue = HW_RD_REG32(baseAdd + GPIO_OE);
        /* Checking if pin is required to be an output pin. */
        if (GPIO_DIR_OUTPUT == pinDirection)
        {
            gpioOeValue &= ~((uint32_t) 1 << pinNumber);
        }
        else
        {
            gpioOeValue |= (uint32_t) 1 << pinNumber;
        }
        HW_WR_REG32(baseAdd + GPIO_OE, gpioOeValue);
    }
    
    static void GPIOPinWrite(uint32_t baseAdd,
                             uint32_t pinNumber,
                             uint32_t pinValue)
    {
        if (GPIO_PIN_HIGH == pinValue)
        {
            HW_WR_REG32(baseAdd + GPIO_SETDATAOUT, (uint32_t) 1 << pinNumber);
        }
        else
        {
            HW_WR_REG32(baseAdd + GPIO_CLEARDATAOUT, (uint32_t) 1 << pinNumber);
        }
    }
    
    /*---------------------------------------------------------------------------*\
    |                                 End of File                                 |
    \*---------------------------------------------------------------------------*/
    

    I tested "HelloWorld" example and was able to get IP address. I was also able to ping the RVP with the IP address.

    You can apply the same changes to other examples.

    Regards,
    Stanley

  • Hi,

    That seems to be the final missing piece of the puzzle! I can confirm that with the changes suggested we have both Ethernet and DHCP working on our board as well.

    Thank you very much for your assistance with this issue.

    Regards,
    Simon