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.

AWR2944EVM: Ethernet driver change from DP83867 driver to DP83tc812 driver

Part Number: AWR2944EVM
Other Parts Discussed in Thread: DP83TC812R-Q1

Hi,

    The AWR2944EVM supports two RGMII Ethernet ports to provide the connection to the network.One is a MATEnet port (9-2304372-9 connector) via a DP83TC812R-Q1 PHY ,the other is an RJ45 port via a DP83867ERGZR PHY. By default, the RGMII interfaces is connected to the RJ45 port. In the demo, .syscfg file only supports DP83867ERGZR PHY driver. We want to use MATEnet port via a DP83TC812R-Q1 PHY and we have done smoe work.

  Firstly in software aspect,I have sucessfully added the DP83TC812R drivers (including DP83TC812.c ,DP83TC812_priv.hand DP83TC812.h files ) to the mcu_plus_sdk_awr294x_08_04_00_22 and ti_board_config.c can be autogenerated as belows:

/*
 *  Copyright (C) 2021 Texas Instruments Incorporated
 *
 *  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.
 */
/*
 * Auto generated file 
 */
#include "ti_board_config.h"

/*
 * Auto generated file
 */


#include <stdint.h>
#include <enet.h>
#include <networking/enet/core/include/phy/enetphy.h>
#include <networking/enet/core/include/phy/dp83tc812.h>
#include <networking/enet/utils/include/enet_apputils.h>
#include <drivers/hw_include/cslr_soc.h>
#include <networking/enet/core/src/phy/enetphy_priv.h>

#define CONFIG_ENET_CPSW0_PHY0_ADDR (0U)

/* PHY drivers */
extern EnetPhy_Drv gEnetPhyDrvGeneric;
extern EnetPhy_Drv gEnetPhyDrvDp83822;
extern EnetPhy_Drv gEnetPhyDrvDp83867;
extern EnetPhy_Drv gEnetPhyDrvDp83869;
extern EnetPhy_Drv gEnetPhyDrvVsc8514;
extern EnetPhy_Drv gEnetPhyDrvDp83tc812;

/*! \brief All the registered PHY specific drivers. */
static const EnetPhyDrv_Handle gEnetPhyDrvs[] =
{
    &gEnetPhyDrvDp83tc812,   /* DP83tc812 */
    &gEnetPhyDrvGeneric,   /* Generic PHY - must be last */
};

const EnetPhy_DrvInfoTbl gEnetPhyDrvTbl =
{
    .numHandles = ENET_ARRAYSIZE(gEnetPhyDrvs),
    .hPhyDrvList = gEnetPhyDrvs,
};

/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */

/**
   TPR:MSS_CTRL:CPSW_CONTROL

   Address offset    0x0000016C
   Physical address  0x0212016C
   Instance          MSS_CTRL
   CPSW_CONTROL_RGMII1_ID_MODE     16  Writing 1'b1 would disable the internal clock delays. And those delays need to be handled on board.
   CPSW_CONTROL_RMII_REF_CLK_OE_N  8   To select the rmii_ref_clk from PAD or from MSS_RCM. 0: clock will be from mss_rcm through IO internal loopback 1: will be from
   CPSW_CONTROL_PORT1_MODE_SEL     2:0 Port 1 Interface
                                         00 = GMII/MII
                                         01 = RMII
                                         10 = RGMII
                                         11 = Not Supported
*/

#define MSS_CPSW_CONTROL_PORT_MODE_RMII                                   (0x1U)
#define MSS_CPSW_CONTROL_PORT_MODE_RGMII                                  (0x2U)

/* ========================================================================== */
/*                         Structure Declarations                             */
/* ========================================================================== */

/* None */

/* ========================================================================== */
/*                          Function Declarations                             */
/* ========================================================================== */

static const EnetBoard_PortCfg *EnetBoard_getPortCfg(const EnetBoard_EthPort *ethPort);

static const EnetBoard_PortCfg *EnetBoard_findPortCfg(const EnetBoard_EthPort *ethPort,
                                                      const EnetBoard_PortCfg *ethPortCfgs,
                                                      uint32_t numEthPorts);

/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */

/*!
 * \brief Common Processor Board (CPB) board's DP83867 PHY configuration.
 */
static const Dp83tc812_Cfg gEnetCpbBoard_dp83tc812PhyCfg =
{  
    .txClkShiftEn = true,
	.rxClkShiftEn = true,
	.interruptEn = false,
	.sgmiiAutoNegEn = true,
	.MasterSlaveMode = DP83TC812_MASTER_SLAVE_STRAP,
    
};

/*
 * AM64x board configuration.
 *
 * 1 x RGMII PHY connected to AM64x CPSW_2G MAC port.
 */
static const EnetBoard_PortCfg gEnetCpbBoard_awr294xEthPort[] =
{
    {    /* "CPSW3G" */
        .enetType = ENET_CPSW_2G,
        .instId   = 0U,
        .macPort  = ENET_MAC_PORT_1,
        .mii      = { ENET_MAC_LAYER_GMII, ENET_MAC_SUBLAYER_REDUCED },
        .phyCfg   =
        {
            .phyAddr         = 0,
            .isStrapped      = false,
            .skipExtendedCfg = false,
            .extendedCfg     = &gEnetCpbBoard_dp83tc812PhyCfg,
            .extendedCfgSize = sizeof(gEnetCpbBoard_dp83tc812PhyCfg),
        },
        .flags    = 0U,
    },
};

/*
 * J721E virtual board used for MAC loopback setup.
 */
static const EnetBoard_PortCfg gEnetLpbkBoard_awr294xEthPort[] =
{
    {    /* RGMII MAC loopback */
        .enetType = ENET_CPSW_2G,
        .instId   = 0U,
        .macPort  = ENET_MAC_PORT_1,
        .mii      = { ENET_MAC_LAYER_GMII, ENET_MAC_SUBLAYER_REDUCED },
        .phyCfg   =
        {
            .phyAddr = ENETPHY_INVALID_PHYADDR,
        },
        .flags    = 0U,
    },
    {    /* RMII MAC loopback */
        .enetType = ENET_CPSW_2G,
        .instId   = 0U,
        .macPort  = ENET_MAC_PORT_1,
        .mii      = { ENET_MAC_LAYER_MII, ENET_MAC_SUBLAYER_REDUCED },
        .phyCfg   =
        {
            .phyAddr = ENETPHY_INVALID_PHYADDR,
        },
        .flags    = 0U,
    },
};

/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */

const EnetBoard_PhyCfg *EnetBoard_getPhyCfg(const EnetBoard_EthPort *ethPort)
{
    const EnetBoard_PortCfg *portCfg;

    portCfg = EnetBoard_getPortCfg(ethPort);

    return (portCfg != NULL) ? &portCfg->phyCfg : NULL;
}

static const EnetBoard_PortCfg *EnetBoard_getPortCfg(const EnetBoard_EthPort *ethPort)
{
    const EnetBoard_PortCfg *portCfg = NULL;

    if (ENET_NOT_ZERO(ethPort->boardId & ENETBOARD_CPB_ID))
    {
        portCfg = EnetBoard_findPortCfg(ethPort,
                                        gEnetCpbBoard_awr294xEthPort,
                                        ENETPHY_ARRAYSIZE(gEnetCpbBoard_awr294xEthPort));
    }
    if ((portCfg == NULL) &&
        ENET_NOT_ZERO(ethPort->boardId & ENETBOARD_LOOPBACK_ID))
    {
        portCfg = EnetBoard_findPortCfg(ethPort,
                                        gEnetLpbkBoard_awr294xEthPort,
                                        ENETPHY_ARRAYSIZE(gEnetLpbkBoard_awr294xEthPort));
    }

    return portCfg;
}

static const EnetBoard_PortCfg *EnetBoard_findPortCfg(const EnetBoard_EthPort *ethPort,
                                                      const EnetBoard_PortCfg *ethPortCfgs,
                                                      uint32_t numEthPorts)
{
    const EnetBoard_PortCfg *ethPortCfg = NULL;
    bool found = false;
    uint32_t i;

    for (i = 0U; i < numEthPorts; i++)
    {
        ethPortCfg = &ethPortCfgs[i];

        if ((ethPortCfg->enetType == ethPort->enetType) &&
            (ethPortCfg->instId == ethPort->instId) &&
            (ethPortCfg->macPort == ethPort->macPort) &&
            (ethPortCfg->mii.layerType == ethPort->mii.layerType) &&
            (ethPortCfg->mii.sublayerType == ethPort->mii.sublayerType))
        {
            found = true;
            break;
        }
    }

    return found ? ethPortCfg : NULL;
}

int32_t EnetBoard_setupPorts(EnetBoard_EthPort *ethPorts,
                             uint32_t numEthPorts)
{
    CSL_mss_ctrlRegs *mssCtrlRegs = (CSL_mss_ctrlRegs *)CSL_MSS_CTRL_U_BASE;

    DebugP_assert(numEthPorts == 1);
    DebugP_assert(ethPorts[0].macPort == ENET_MAC_PORT_1);
    DebugP_assert(ethPorts[0].mii.sublayerType == ENET_MAC_SUBLAYER_REDUCED);
    switch(ethPorts[0].mii.layerType)
    {
        case ENET_MAC_LAYER_MII:
            CSL_FINS( mssCtrlRegs->CPSW_CONTROL,MSS_CTRL_CPSW_CONTROL_CPSW_CONTROL_PORT1_MODE_SEL, MSS_CPSW_CONTROL_PORT_MODE_RMII);
            break;
        case ENET_MAC_LAYER_GMII:
            CSL_FINS( mssCtrlRegs->CPSW_CONTROL,MSS_CTRL_CPSW_CONTROL_CPSW_CONTROL_PORT1_MODE_SEL, MSS_CPSW_CONTROL_PORT_MODE_RGMII);
            break;
        default:
            DebugP_assert(false);
    }
    /* Nothing else to do */
    return ENET_SOK;
}


static const uint8_t gMacAddr[6U] = {
                             0x70,
                             0xFF,
                             0x76,
                             0x1D,
                             0xEC,
                             0xF3
                            };

void EnetBoard_getMacAddrList(uint8_t macAddr[][ENET_MAC_ADDR_LEN],
                              uint32_t maxMacEntries,
                              uint32_t *pAvailMacEntries)
{
    EnetAppUtils_assert(pAvailMacEntries != NULL);

    memcpy(macAddr, &gMacAddr, ENET_MAC_ADDR_LEN);
    *pAvailMacEntries = 1U;
}

/*
 * Get ethernet board id
 */
uint32_t EnetBoard_getId(void)
{
    return ENETBOARD_AWR294X_EVM;
}



void Board_init(void)
{
}

void Board_deinit(void)
{
}

Is there any error with the configuration for DP83TC812 ?Such as:

static const Dp83tc812_Cfg gEnetCpbBoard_dp83tc812PhyCfg =
{  
    .txClkShiftEn = true,
    .rxClkShiftEn = true,
    .interruptEn = false,
    .sgmiiAutoNegEn = true,
    .MasterSlaveMode = DP83TC812_MASTER_SLAVE_STRAP,
    
};

 
static const EnetBoard_PortCfg gEnetCpbBoard_awr294xEthPort[] =
{
    {    /* "CPSW3G" */
        .enetType = ENET_CPSW_2G,
        .instId   = 0U,
        .macPort  = ENET_MAC_PORT_1,
        .mii      = { ENET_MAC_LAYER_GMII, ENET_MAC_SUBLAYER_REDUCED },
        .phyCfg   =
        {
            .phyAddr         = 0,
            .isStrapped      = false,
            .skipExtendedCfg = false,
            .extendedCfg     = &gEnetCpbBoard_dp83tc812PhyCfg,
            .extendedCfgSize = sizeof(gEnetCpbBoard_dp83tc812PhyCfg),
        },
        .flags    = 0U,
    },
};
static const EnetBoard_PortCfg gEnetLpbkBoard_awr294xEthPort[] =
{
    {    /* RGMII MAC loopback */
        .enetType = ENET_CPSW_2G,
        .instId   = 0U,
        .macPort  = ENET_MAC_PORT_1,
        .mii      = { ENET_MAC_LAYER_GMII, ENET_MAC_SUBLAYER_REDUCED },
        .phyCfg   =
        {
            .phyAddr = ENETPHY_INVALID_PHYADDR,
        },
        .flags    = 0U,
    },
    {    /* RMII MAC loopback */
        .enetType = ENET_CPSW_2G,
        .instId   = 0U,
        .macPort  = ENET_MAC_PORT_1,
        .mii      = { ENET_MAC_LAYER_MII, ENET_MAC_SUBLAYER_REDUCED },
        .phyCfg   =
        {
            .phyAddr = ENETPHY_INVALID_PHYADDR,
        },
        .flags    = 0U,
    },
};

 The  configurations  are reasonable or not.

If it is, can you point them out?

Secondly in hardware aspect,  we have do some changes in the hardware as description in the AWR2944EVM User’s Guide to enable the DP83TC812R PHY.


Besides that,  in order to make DP83TC812R work normally, is there any other change that we should do especially in  software aspect?

BR,

Rata

  • Hi Rata,

    Let me check with the team if there is any reference implementation available and get back to you tomorrow.

    Regards,

    Ajay

  • Hi Rata,

    Please find the porting steps below - 


    1. Under <mcu_plus_sdk_awr294x_xx_xx_xx_xx>\source\networking\enet\core\src\phy

    a. Source files and private header files have been added for the automotive PHY
    b. Added the new phy drivers in makefile.


    2. Under <mcu_plus_sdk_awr294x_xx_xx_xx_xx>\source\networking\enet\core\src\phy\enetphy.c

    a. Added the new(automotive phy driver under "Global variable section"
    b. The following items have been added under the section "Function Definitions"

    - Add "phyCfg->supportRegCaps = true;" to "void EnetPhy_initCfg(EnetPhy_Cfg *phyCfg)"
    - Add if/else statement to "static void EnetPhy_enableState(EnetPhy_Handle hPhy)"


    3. Under <mcu_plus_sdk_awr294x_xx_xx_xx_xx>\source\networking\enet\core\include\phy

    a. The header files for the automotive PHY drivers have been added
    b. in the enetphy.h file, bool supportRegCaps element has been added to the structure EnetPhy_Cfg


    4. Changes made in the makefile <mcu_plus_sdk_awr294x_xx_xx_xx_xx>\source\networking\enet\makefile.cpsw.awr294x.r5f.ti-arm-clang

    a. Adjust the specified PHY driver source files (include necessary PHY drivers)


    5. Changes made in the syscfg file template

    a. In the "<mcu_plus_sdk_awr294x_xx_xx_xx_xx>\source\networking\.meta\enet_cpsw\templates\awr294x\enet_board_cfg.c.xdt" file, configurations for the automotive phy dp83tc812 has been added

    Regards,

    Shruti

  • Hi Shruti,

        Thanks for your detailed reply, it helps us a lot. Now I still have some questions:

        First one,the autogenerated  ti_board_config.c file is as belows:

        

    static const Dp83tc812_Cfg gEnetCpbBoard_dp83tc812PhyCfg =
    {  
        .txClkShiftEn = true,
        .rxClkShiftEn = true,
        .interruptEn = false,
        .sgmiiAutoNegEn = true,
        .MasterSlaveMode = DP83TC812_MASTER_SLAVE_STRAP,
        
    };
    
     
    static const EnetBoard_PortCfg gEnetCpbBoard_awr294xEthPort[] =
    {
        {    /* "CPSW3G" */
            .enetType = ENET_CPSW_2G,
            .instId   = 0U,
            .macPort  = ENET_MAC_PORT_1,
            .mii      = { ENET_MAC_LAYER_GMII, ENET_MAC_SUBLAYER_REDUCED },
            .phyCfg   =
            {
                .phyAddr         = 0,
                .isStrapped      = false,
                .skipExtendedCfg = false,
                .extendedCfg     = &gEnetCpbBoard_dp83tc812PhyCfg,
                .extendedCfgSize = sizeof(gEnetCpbBoard_dp83tc812PhyCfg),
            },
            .flags    = 0U,
        },
    };
    static const EnetBoard_PortCfg gEnetLpbkBoard_awr294xEthPort[] =
    {
        {    /* RGMII MAC loopback */
            .enetType = ENET_CPSW_2G,
            .instId   = 0U,
            .macPort  = ENET_MAC_PORT_1,
            .mii      = { ENET_MAC_LAYER_GMII, ENET_MAC_SUBLAYER_REDUCED },
            .phyCfg   =
            {
                .phyAddr = ENETPHY_INVALID_PHYADDR,
            },
            .flags    = 0U,
        },
        {    /* RMII MAC loopback */
            .enetType = ENET_CPSW_2G,
            .instId   = 0U,
            .macPort  = ENET_MAC_PORT_1,
            .mii      = { ENET_MAC_LAYER_MII, ENET_MAC_SUBLAYER_REDUCED },
            .phyCfg   =
            {
                .phyAddr = ENETPHY_INVALID_PHYADDR,
            },
            .flags    = 0U,
        },
    };

    Is there any question for that?

    Second one,

    2. Under <mcu_plus_sdk_awr294x_xx_xx_xx_xx>\source\networking\enet\core\src\phy\enetphy.c

    a. Added the new(automotive phy driver under "Global variable section"

      What should I do for that? The Global variable section is as belows:

    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */


    extern EnetPhy_DrvInfoTbl gEnetPhyDrvTbl;

    /*! \brief Enet MAC port objects. */
    static EnetPhy_Obj gEnetPhy_phyObjs[ENET_CFG_ENETPHY_PHY_MAX];

    #if ((ENET_CFG_TRACE_LEVEL >= ENET_CFG_TRACE_LEVEL_DEBUG) && ENET_CFG_IS_OFF(TRACE_DISABLE_INFOSTRING))
    /*! \brief Name of the FSM states. */
    static const char *gEnetPhyStateNames[] =
    {
        "INIT",
        "FINDING",
        "RESET_WAIT",
        "ENABLE",
        "FOUND",
        "NWAY_START",
        "NWAY_WAIT",
        "LINK_WAIT",
        "LINKED",
        "LOOPBACK",
    };
    #endif

    #if ((ENET_CFG_TRACE_LEVEL >= ENET_CFG_TRACE_LEVEL_WARN) && ENET_CFG_IS_OFF(TRACE_DISABLE_INFOSTRING))
    /*! \brief Ethernet PHY capabilities string buffer. */
    static char gEnetPhyCapsBuf[ENETPHY_CAPS_BUF_LEN];
    #endif

    #if ((ENET_CFG_TRACE_LEVEL >= ENET_CFG_TRACE_LEVEL_DEBUG) && ENET_CFG_IS_OFF(TRACE_DISABLE_INFOSTRING))
    /*! \brief Ethernet PHY mode string buffer. */
    static char gEnetPhyModeBuf[ENETPHY_MODE_BUF_LEN];
    #endif

     How should I do for  adding  the new automotive phy driver?

    BR

    Rata

  • Hi Rata,

    you can use the following configuration for the Dp83tc812_Cfg gEnetCpbBoard_dp83tc812PhyCfg

        .txClkShiftEn         = false,
        .rxClkShiftEn         = true,
        .interruptEn          = false,
        .sgmiiAutoNegEn       = false,
        .MasterSlaveMode      = DP83TC812_MASTER_MODE,
    for your second query, you just need to declare the phy driver like the following - 
    extern EnetPhy_Drv gEnetPhyDrvDp83tc812.
    also, for teh AUTO phy to work, you have to modify some hardware in your board as well.
    Regards,
    Shruti
  • Hi Shruti

    Thanks for your reply, I got it.

    BR,

    Rata

  • Hi Rata,

    Good to know that your issue is resolved. 

    Regards,

    Shruti

  • Hi Shruti,

        I still have an question, as you said if we configure gEnetCpbBoard_dp83tc812PhyCfg as:

       .txClkShiftEn         = false,
        .rxClkShiftEn         = true,
        .interruptEn          = false,
        .sgmiiAutoNegEn       = false,
        .MasterSlaveMode      = DP83TC812_MASTER_MODE,
    also, for teh AUTO phy to work, you have to modify some hardware in your board as well

      The MAC[2:0]must be [1 1 1], is that right? Besides that, what hardware modifications are still needed?

     The txDelay must be set as 0ns, and rxDelay must be set as 2ns by register 0x430,  is that right?

    BR;

    Rata

  • Hi Rata,

    The MAC mode the user can adjust based on their application, as to which mode they want to use. We have tested with the 110 mode which is internal delay mode for both rx and tx and so we are not setting any delay here.

    In the default EVM's the AUTO PHY IC is disconnected from the main interface, meaning there are many unpopulated registers which you have to populate to use the AUTO PHY on EVM.

    Regards,

    Shruti