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.

TMS320C6678: Configuring EMAC and using NDK for SYS/BIOS on a COTS board

Part Number: TMS320C6678

Hi all,

I have successfully ran a customized NDK "Helloword" app on a c6678 EVM (no boot mode). I have properly acquired the network config. and I am able to communicate with a Windows application running on my PC. Great.

My final goal is to integrate the NDK into a COTS board equipped with the C6678 DSP. I tried the application on the board and clearly it does not work (I was expecting such a kind of situation): I need to configure manually the PHY layer to work with the eth device. Since I have read many documents without finding a final solution and we do not have enough time to try an experimental approach, it would be really appreciated if any expert could help me replying to the below question:

- On the EVM, according to the NDK basic code example, who is going to setup the EMAC ? I guess that MAC address of EVM is hard-coded. Isn't it? 

- I tried to install in my app the EMAC driver using CCS via the NDK Core Stack GUI. In the device list I cannot find any reference to C6678. Is there any way to configure the EMAC using the CCS support?

- I realized that the NDK Network Support Package (NSP) is not supported for C6678 (TI FORUM LINK) . How I can quickly bring-up the Data Link Layer on this device? Where I can find a detailed procedure (steps description) to setup the EMAC?

-Is there any possibility to run the NDK on the C6678 having a different "boot mode" config from "NO BOOT"? I mean for example ... with boot mode set to 0x00000005 (I2C)... 

Thank you in advance for your support.

BR,

Giorgio

  • The team is notified. They will post their feedback directly here.

    BR
    Tsvetolin Shulev
  • Hi,

    Assuming you ran NIMU_emacExample_EVMC6678C66BiosExampleProject under Processor SDK RTOS or similar, the NDK calls into the NIMU driver pdk_c667x_2_0_x\packages\ti\transport\ndk\nimu\src\v1\nimu_eth.c, function EMACInit_Core(). This is the top level where the EMAC is initialized.

    Looking into Init_Cpsw() function, the MAC address is read from SOC efuse and programmed here with Init_MAC(). The Init_MDIO() is empty. On your own board, if you use a PHY, you need to program it via MDIO interface, see processors.wiki.ti.com/.../Processor_SDK_RTOS_FAQ

    The Init_Cpsw() setup the L2 switch and PHY function. If you changed the nimu_eth.c function, then you need to rebuild the NIMU library, which is linked with your NDK hello world project.

    For I2C boot mode, do you mean you want to flash the NDK hello world into a device connect to I2C bus and want to boot from there? I think that probably will not work. When using the no-boot mode, there is a GEL file to initialize the SOC: Those functions needs to be done in no-boot mode as well.

    Set_PSC_State(PD2, LPSC_PKTPROC, PSC_ENABLE);
    Set_PSC_State(PD2, LPSC_CPGMAC, PSC_ENABLE);
    Set_PSC_State(PD2, LPSC_Crypto, PSC_ENABLE);

    // Setup Pll3 pass clk @ 1050 MHz
    Init_Pll3(PLLM_PASS, PLLD_PASS);

    // Configure SGMII SERDES
    configSGMIISerdes();

    setCpSwConfig(); ====> this is not needed

    Regards, Eric
  • Hi Eric,
    the boot mode for my board is 0x00000005 (I2C) and I cannot use the .gel file. Nevertheless I can port the functions you mentioned before, from the GEL into my application. Supposing that I know how to configure the MDIO interface, do you think that it could work? If yes, which is the configuration sequence to apply before to properly get the final ip address (NetworkIPAddr)?

    Thank you in advance.

    BR,
    Giorgio
  • Hi,

    When you run the example in the no-boot mode, the GEL run first, you need follow the same sequence, the GEL is ccsv7\ccs_base\emulation\boards\evmc6678l\gel\evmc6678l.gel, Global_Default_Setup_Silent() with those functions I mentioned. Then the hello world application.

    In the I2C boot mode, you need add the same functions in GEL to the beginning of the main(). Then in the Init_MDIO(), add you own code. This should work.

    Regards, Eric
  • Hi Eric,

    could you please confirm that @0x02090030 is the register to configure SGMII_TXCFG_REG port 0?

    Thank you in advance.

    BR,

    Giorgio

  • Do you mean SGMII_SERDES_CFGTX0 in the configSGMIISerdes() in the GEL?

    #define SGMII_SERDES_CFGPLL (*(unsigned int*)(CHIP_LEVEL_REG + 0x340))
    #define SGMII_SERDES_CFGRX0 (*(unsigned int*)(CHIP_LEVEL_REG + 0x344))
    #define SGMII_SERDES_CFGTX0 (*(unsigned int*)(CHIP_LEVEL_REG + 0x348))
    #define SGMII_SERDES_CFGRX1 (*(unsigned int*)(CHIP_LEVEL_REG + 0x34C))
    #define SGMII_SERDES_CFGTX1 (*(unsigned int*)(CHIP_LEVEL_REG + 0x350))

    #define CHIP_LEVEL_REG 0x02620000

    Regards, Eric
  • Hi Eric,
    so, in my understanding the @0x02090030 address is not in the range of sgmii configuration. Am I right?

    BR,
    Giorgio
  • Hi,

    If you look at the KeyStone Architecture Gigabit Ethernet (GbE) Switch Subsystem UG Literature Number: SPRUGV9D www.ti.com/.../sprugv9d.pdf

    Table 3-3 KeyStone I Gigabit Ethernet Switch Subsystem Complete Register Listing (Part 1 of 6)

    000h GbE Switch Subsystem ES_SS_IDVER Ethernet switch subsystem Identification and Version Register ===> This starts from 0x209_0000. offset 0x30 is reserved.

    If you look at 6678 data sheet:
    Table 3-2 Device State Control Registers (Sheet 4 of 4), you can see the SGMII CFG address:
    0x02620340 0x02620343 4B SGMII_SERDES_CFGPLL See ‘‘Related Documentation from Texas Instruments’’ on page 72
    0x02620344 0x02620347 4B SGMII_SERDES_CFGRX0
    0x02620348 0x0262034B 4B SGMII_SERDES_CFGTX0
    0x0262034C 0x0262034F 4B SGMII_SERDES_CFGRX1
    0x02620350 0x02620353 4B SGMII_SERDES_CFGTX1

    Regards, Eric
  • Hi Eric,

    I work in the same project with Giorgio. Here is a little update:

    We managed to make the example work on in I2C boot mode integrating the gel file in our code.

    Now the next step is to make it work on the COTS board we work on.

    We applied the fixes needed on the COTS board gel file and tried to set correctly the 3-Port Ethernet Switch.

    Unfortunately this is probably where we are doing something wrong.

    We tried to do some kind of merge in between what Linux does on this COTS board (of course the net works using Linux) and what is needed in the gel file.

    The NDK is correctly set up but still we are not able to ping the board, so we think this may be because of some switch/SGMII/MDIO/SerDes setting error we are making.

    Please have a look at the code we used for initialization and please let me know if there is something missing or wrong.

    Consider that this COTS board should be using SGMII 1.

    int sgmii_init(void)
    {
        struct sgmii_config sgmiic0, sgmiic1;
    
        /* SGMII to SGMII forced (AMC) */
        sgmiic0.master = 1;
        sgmiic0.loopback = 0;
        sgmiic0.autoneg = 1;
    
        sgmiic0.txconfig = 0x000108a1;
        sgmiic0.rxconfig = 0x00700621;
    
        sgmiic0.auxconfig = 0x00000081; /* PLL multiplier */
    
        keystone_sgmii_config(0, &sgmiic0);
    
        /* SGMII to PHY (RJ45) */
        sgmiic1.master = 1;
        sgmiic1.loopback = 0;
    
        sgmiic1.autoneg = 0;
        sgmiic1.txconfig = 0x000108a1;
        sgmiic1.rxconfig = 0x00700621;
    
        sgmiic1.auxconfig = 0x00000081; /* PLL multiplier */
    
        keystone_sgmii_config(1, &sgmiic1);
    
        return 0;
    }
    
    
    
    static int serdes_init(void)
    {
        // Turn PLL off first, this ensures network starts up on reboot
        SGMII_SERDES_CFGPLL = 0x00000080;
    
        udelay(200);
    
        SGMII_SERDES_CFGPLL = 0x00000081;
    
        udelay(2000);
    
        SGMII_SERDES_CFGRX0 = 0x00700621;
        SGMII_SERDES_CFGRX1 = 0x00700621;
    
        SGMII_SERDES_CFGTX0 = 0x000108A1;
        SGMII_SERDES_CFGTX1 = 0x000108A1;
    
        udelay(2000);
    
        return 0;
    }
    
    /* Initialize switch configuration */
    void setCpSwConfig()
    {
        /* Enable Port 0 */
        CPSW3G_CONTROL_REG = 0x4;
        CPSW3G_STAT_PORT_REG = 0xF;
    
        /* disable flow control */
        CPSW_REG_FLOW_CTL = 0;
    
        /* Enable ALE. */
        CPSW3G_ALE_CONTROL_REG = 0x00000050;
    
        CPSW3G_ALE_CONTROL_REG |= 0x80000000;
        /* Enable ALE port state to Forward */
        CPSW3G_ALE_PORT_0_CTL_REG = 0x3;
    
    
        /* now configure ports */
    
       CPSW_REG_MAC_SA_HI(0)= 0x04C2B5D0;
       CPSW_REG_MAC_SA_LO(0)= 0x0000E426;
    
       CPSW_REG_MAC_SA_HI(1)=0x04C2B5D0;
       CPSW_REG_MAC_SA_LO(1)=0x0000E426;
    
       CPSW3G_ALE_PORT_1_CTL_REG = 0x3;
       CPSW3G_ALE_PORT_2_CTL_REG = 0x3;
    
    }
    
    int keystone_sgmii_reset(int port)
    {
        sgmii_write_reg(SGMII_CTL_REG(port), 0);
    
        /* Soft reset */
        sgmii_write_reg_bit(SGMII_SRESET_REG(port), 0x1);
        while (sgmii_read_reg(SGMII_SRESET_REG(port)) != 0x0)
            ;
    
        return 0;
    }
    
    void Global_Default_Setup_Silent() // This has some little tweaks regarding PLL freq because DSP runs at 1.25GHz but everything else is default gel file
    {
    int count;
    
    /* DDR PLL settings for 1333 MHz */
    unsigned int PLLM_DDR = 19;
    unsigned int PLLD_DDR = 0;
    /* DDR PLL settings for 1066 MHz */
    //unsigned int PLLM_DDR = 31;
    //unsigned int PLLD_DDR = 1;
    /* PASS PLL settings for 1050 MHz */
    unsigned int PLLM_PASS = 20;
    unsigned int PLLD_PASS = 0;
    int status;
    
    // Set DSP cache to pre defined values...
    Set_DSP_Cache();
    
    // Only core 0 can set these
    if (DNUM == 0)
    {
        for (count = 0; count < PLL_REINIT_MAX_COUNT; count++)
        {
            // Setup Pll1 DSP @ TARGET_FREQ
    
            status = Init_PLL(PLL1_M, PLL1_D, PLL1_O);
    
            if (status == -1)
            {
                bl_write_uart(
                        "Error in Setting up main PLL, please power cycle the board and re-run Global Default Setup...\n");
                while (1)
                    ;
            }
    
            if (!count)
            {
    
                // Setup all Power Domains on
                Set_Psc_All_On();
            }
            // Setup Pll3 pass clk @ 1050 MHz
            Init_Pll3(PLLM_PASS, PLLD_PASS);
    
            // Setup Pll2 DDR3 PLL @ 667 MHz
            Init_Pll2(PLLM_DDR, PLLD_DDR);
    
            bl_write_uart("\n DDR begin (1333 auto)\n");
            xmc_setup();
            ddr3_setup_auto_lvl_1333();
            bl_write_uart("\n DDR done\n");
    
            break;
    
        }
    
        if (count == PLL_REINIT_MAX_COUNT)
        {
            bl_write_uart("\n PLL and DDR Initialization failed ...\n");
        }
        else
        {
            bl_write_uart("\n PLL and DDR Initialization completed ...\n");
        }
    
        // Configure SGMII SERDES
        configSGMIISerdes();
    
        bl_write_uart("\n Enabling EDC ...\n");
        EnableEDC_OneforAll();
        bl_write_uart("\n Enabling EDC ...Done \n");
    
        bl_write_uart("\n Configuring CPSW ...\n");
        setCpSwConfig();
        bl_write_uart("\n Configuring CPSW ...Done \n");
    }
    bl_write_uart("\n Global Default Setup... Done.\n");
    
    }
    
    
    int phy_init(void)
    {
        TSCL = 0;
    
    
        Global_Default_Setup_Silent();
    
        /* Unlock Chip Level Registers */
        KICK0 = KICK0_UNLOCK;
        KICK1 = KICK1_UNLOCK;
    
        /* Reset SGMII for all ports*/
        keystone_sgmii_reset(0);
        keystone_sgmii_reset(1);
    
    
        setCpSwConfig();
    
        /* SERDES init */
        serdes_init();
        /* Configure the SGMII */
        sgmii_init();
    
        mdio_set_reg(MDIO_CONTROL, MDIO_B_ENABLE | (VBUSCLK & MDIO_M_CLKDIV));
    
        mdio_set_reg(MDIO_CONTROL, 0x4000001f); /* enable MII interface */
        udelay(145844);
    
        mdio_phy_write(24, 1, 0x109);
        mdio_phy_wait();
        mdio_phy_write(24, 2, 0x109);
        mdio_phy_wait();
    
        /* Lock Chip Level Registers */
      KICK0 = KICK_LOCK;
      KICK1 = KICK_LOCK;
    
        return 0;
    }

    Edit:

    It looks like the SGMII 1 link is set to 1 (SGMII_MR_ADV_ABILITY) register, but is not up in SGMII_STATUS register.

    Thank you in advance.

    Best Regards,

    Fabrizio

  • Hi,

    We managed to make the example work on in I2C boot mode integrating the gel file in our code. =====> do you mean this is TI 6678 EVM?

    We tried to do some kind of merge in between what Linux does on this COTS board ====> Do you mean you have a Linux driver for the CPSW switch of C6678? Where the code came from? If the Linux code worked before, why not directly porting the Linux code into RTOS?

    Meanwhile, I am looking at your code.

    Regards, Eric
  • Hi,

    In the code:
    /* SGMII to PHY (RJ45) */
    sgmiic1.master = 1;
    sgmiic1.loopback = 0;

    sgmiic1.autoneg = 0;
    sgmiic1.txconfig = 0x000108a1;
    sgmiic1.rxconfig = 0x00700621;

    sgmiic1.auxconfig = 0x00000081; /* PLL multiplier */

    keystone_sgmii_config(1, &sgmiic1);

    Is this from Linux code? When SGMII 1 is connected to PHY (RJ-45), PHY is the master and SGMII is the slave, so you need
    sgmiic1.master = 0;
    sgmiic1.autoneg = 1;

    Can you have the SGMII port up, check 0x2090214 (Status Register (STATUS)) in Table 3-3 KeyStone I Gigabit Ethernet Switch Subsystem Complete Register Listing (Part 1 of 6), www.ti.com/.../sprugv9d.pdf

    Regards, Eric
  • Hello Eric,
    the Linux is a TI version adapted by the board's vendor to work with the specific platform.
    According to our project requirements, we cannot run an instance of Linux onto our DSP.
    A part from this, I have checked some registers in both cases (Linux and our benchmark).

    LINUX:
    (110h) Port 1 SGMII SGMII_CONTROL Control Register 0x21
    (114h) Port 1 SGMII SGMII_STATUS Status Register (read only) 0x3D
    (118h) Port 1 SGMII SGMII_MR_ADV_ABILITY Advertised Ability Register 0x9801

    (210h) Port 2 SGMII SGMII_CONTROL Control Register 0x21
    (214h) Port 2 SGMII SGMII_STATUS Status Register (read only) 0x3D
    (218h) Port 2 SGMII SGMII_MR_ADV_ABILITY Advertised Ability Register 0x9801

    NDK Benchmark:
    (110h) Port 1 SGMII SGMII_CONTROL Control Register 0x21
    (114h) Port 1 SGMII SGMII_STATUS Status Register (read only) 0x3D
    (118h) Port 1 SGMII SGMII_MR_ADV_ABILITY Advertised Ability Register 0x9801

    (210h) Port 2 SGMII SGMII_CONTROL Control Register 0x21
    (214h) Port 2 SGMII SGMII_STATUS Status Register (read only) 0x30 HERE THE DIFFERENCE (Link is no UP)
    (218h) Port 2 SGMII SGMII_MR_ADV_ABILITY Advertised Ability Register 0x9801


    Any idea about the link port 2 cannot be properly linked up?

    Thank in advance.

    BR,
    Giorgio
  • Hi,

    If you have a Linux version and port 2 came up, do you have u-boot initialize the both SGMII ports without Linux kernel? That is, after u-boot, can you check the above registers to see if both ports came up? If yes, it maybe easier to see what was done in the U-boot code for this. Are both SGMII ports connected to a PHY? If the setup is the same, I would expect the code is the same for SGMII 0 and SGMII 1.

    Also, in the NDK version of the code, do you run our TI NIMU example for this? Do you use the TI nimu_eth.c, modify inside and rebuild the NIMU library? It looks not but I want to confirm.

    Regards, Eric
  • Hi Eric,

    thank you for your support. Very appreciated.

    I have contacted the board provider for a double check about the PHY connections and I am still waiting for more details.

    Regarding the NDK benchmark, I am using the source code provided in ...\ti\pdk_c667x_2_0_8\packages\ti\transport\ndk\nimu\example\helloWorld\src folder.

    Basically I have configured manually the CCS project according to the following statements 

    -ccs.linkFile "PDK_INSTALL_PATH/ti/transport/ndk/nimu/example/HelloWorld/src/helloWorld.c"
    -ccs.linkFile "PDK_INSTALL_PATH/ti/transport/ndk/nimu/example/HelloWorld/src/nimu_osal.c"
    -ccs.linkFile "PDK_INSTALL_PATH/ti/transport/ndk/nimu/example/HelloWorld/src/nimu_cppi_qmss_iface.c"
    -ccs.linkFile "PDK_INSTALL_PATH/ti/transport/ndk/nimu/example/HelloWorld/src/nimu_pa_iface.c"
    -ccs.linkFile "PDK_INSTALL_PATH/ti/transport/ndk/nimu/example/HelloWorld/src/udpHello.c"
    -ccs.linkFile "PDK_INSTALL_PATH/ti/transport/ndk/nimu/example/HelloWorld/src/setuprm.c"
    -ccs.linkFile "PDK_INSTALL_PATH/ti/drv/rm/device/c6678/policy_dsp-only.c"
    -ccs.linkFile "PDK_INSTALL_PATH/ti/drv/rm/device/c6678/global-resource-list.c"
    -ccs.linkFile "PDK_INSTALL_PATH/ti/transport/ndk/nimu/example/helloWorld/c6678/c66/bios/helloWorld.cfg"
    -ccs.setCompilerOptions "-D -mv64+ -g -DSOC_C6678 -DDEVICE_C6678 -DUSE_BIOS --diag_warning=225 --diag_warning=994 --diag_warning=262 --diag_suppress=1111 --diag_suppress=827 --diag_suppress=824 --diag_suppress=837 --diag_suppress=1037 --diag_suppress=195 --diag_suppress=77 --diag_suppress=232 -I${PDK_INSTALL_PATH}/ti/transport/ndk/nimu -I${PDK_INSTALL_PATH} -I{NDK_INSTALL_DIR}/packages " -rtsc.enableRtsc

    Then I have adapted the benchmark to work with the EVM or the Platform Board. In addition, as you suggested also in the past, all the gel routines (platform depending) are launched at the beginning of software execution.

    Thanks.

    BR,

    Giorgio

  • In addition > the board IBL will only touch the SGMII if configured for network booting.
    If booting from NAND like normal, the IBL does not configure the SGMII in any way (consider that for my test I install it in the NAND as well)

    On our board both SGMII ports are routed to the VPX backplane and there are no PHYs.
    The SGMII will be connected to whatever connects on that backplane pins...

    Thanks
  • Hi Eric,

    I tried to set master to 0 and autoneg to 1 but still port is down, Status reg is 0x30.

    As Giorgio explained, there is no nimu_eth.c file in our project. is this a problem?

    BR,

    Fabrizio

  • Hi,

    Any news here?

    Thank you in advance,

    VR

    Fabrizio

  • Hi,

    Also another question:

    I saw there are 7 versions of the file nimu_eth.c
    we are now working with v1 but is it the correct one?

    Thank you,

    BR

    Fabrizio

  • Hi all,
    we were able to run our code on the CoT board editing properly the nimu_eth.c file. Thank you Eric for the support.

    BR,
    Giorgio