Tool/software:
Hello,
I'm working with the following schematic:

The two boards are identical, and I believe the SGMII configuration is correct. I'm using the official RTOS driver; however, a link is never established between the two physical devices.
Since the driver does not provide an initialization function, I created one myself, though I'm not sure if it's implemented correctly.
According to the logs, the PHY in use is a DP83TG720_CS1_1. Naturally, I have configured one side as master and the other as slave.
I'm attaching my code below for additional context.
/*
* Copyright (c) Texas Instruments Incorporated 2020
*
* 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 dp83tg720.c
*
* \brief This file contains the implementation of the DP83TG720 PHY.
*/
/* ========================================================================== */
/* Include Files */
/* ========================================================================== */
#include "hal_stdtypes.h"
#include "dp83tg720.h"
#include "dp83tg720_priv.h"
#include "mdio.h"
/* ========================================================================== */
/* Macros & Typedefs */
/* ========================================================================== */
#define DP83TG720_OUI (0x080028U)
#define DP83TG720_MODEL (0x28U)
#define DP83TG721_MODEL (0x29U)
#define DP83TG721_REV_CS1 (0U)
#define DP83TG720_REV_CS1 (3U)
#define DP83TG720_REV_CS1_1 (4U)
/* ========================================================================== */
/* Structure Declarations */
/* ========================================================================== */
enum dp83tg720_chip_type {
DP83TG720_CS1 = 3,
DP83TG720_CS1_1 = 4,
DP83TG721_CS1 = 5,
};
struct dp83tg720_privParams {
int chip;
bool is_master;
};
/* ========================================================================== */
/* Function Declarations */
/* ========================================================================== */
static void Dp83tg720_setLoopbackCfg(EthPhyDrv_Handle hPhy,
bool enable);
static void Dp83tg720_resetHw(EthPhyDrv_Handle hPhy);
static int32_t Dp83tg720_readMmd(EthPhyDrv_Handle hPhy, uint16_t devad, uint32_t reg, uint16_t *val);
static void Dp83tg720_writeMmd(EthPhyDrv_Handle hPhy, uint16_t devad, uint32_t reg, uint16_t val);
static void Dp83tg720_setBitsMmd(EthPhyDrv_Handle hPhy, uint16_t devad, uint32_t reg, uint16_t val);
static void Dp83tg720_readStraps(EthPhyDrv_Handle hPhy, Dp83tg720_MasterSlaveMode msMode);
static void Dp83tg720_writeSeq(EthPhyDrv_Handle hPhy, const struct dp83tg720_init_reg *init_data, int size);
static void Dp83tg720_chipInit(EthPhyDrv_Handle hPhy);
static void Dp83tg720_setMiiMode(EthPhyDrv_Handle hPhy, Phy_Mii mii);
static void Dp83tg720_configAutoNeg(EthPhyDrv_Handle hPhy, bool sgmiiAutoNegEn);
static void Dp83tg720_configClkShift(EthPhyDrv_Handle hPhy, bool txClkShiftEn, bool rxClkShiftEn);
static void Dp83tg720_configIntr(EthPhyDrv_Handle hPhy, bool intrEn);
static int32_t mi_readReg(void* args, uint32_t reg, uint16_t* val);
static int32_t mi_writeReg(void* args, uint32_t reg, uint16_t val);
/* ========================================================================== */
/* Global Variables */
/* ========================================================================== */
Phy_DrvObj_t gEnetPhyDrvDp83tg720 =
{
.fxn =
{
.name = "Dp83tg720",
.bind = Dp83tg720_bind,
.isPhyDevSupported = Dp83tg720_isPhyDevSupported,
.isMacModeSupported = Dp83tg720_isMacModeSupported,
.config = Dp83tg720_config,
.reset = Dp83tg720_reset,
.isResetComplete = Dp83tg720_isResetComplete,
.readExtReg = mi_readReg,
.writeExtReg = mi_writeReg,
.printRegs = NULL,
.adjPtpFreq = NULL,
.adjPtpPhase = NULL,
.getPtpTime = NULL,
.setPtpTime = NULL,
.getPtpTxTime = NULL,
.getPtpRxTime = NULL,
.waitPtpTxTime = NULL,
.procStatusFrame = NULL,
.getStatusFrameEthHeader = NULL,
.enablePtp = NULL,
.tickDriver = NULL,
.enableEventCapture = NULL,
.enableTriggerOutput = NULL,
.getEventTs = NULL,
}
};
/* PHY Device Attributes */
static struct dp83tg720_privParams dp83tg720_params = {
.chip = 4,
.is_master = false,
};
/* ========================================================================== */
/* Function Definitions */
/* ========================================================================== */
void Dp83tg720_initCfg(Dp83tg720_Cfg *cfg)
{
cfg->txClkShiftEn = true;
cfg->rxClkShiftEn = true;
cfg->interruptEn = false;
cfg->sgmiiAutoNegEn = false;
cfg->MasterSlaveMode = DP83TG720_MASTER_SLAVE_STRAP;
}
void Dp83tg720_bind(EthPhyDrv_Handle* hPhy,
uint8_t phyAddr,
Phy_RegAccessCb_t* pRegAccessCb)
{
Phy_Obj_t* pObj = (Phy_Obj_t*) hPhy;
pObj->phyAddr = phyAddr;
pObj->regAccessApi = *pRegAccessCb;
}
bool Dp83tg720_isPhyDevSupported(EthPhyDrv_Handle hPhy,
const void *pVersion)
{
const Phy_Version *version = (Phy_Version *)pVersion;
bool supported = false;
if ((version->oui == DP83TG720_OUI) && (
(version->model == DP83TG720_MODEL) || (version->model == DP83TG721_MODEL) ))
{
supported = true;
}
//Determine phy version
if (version->revision == DP83TG720_REV_CS1)
dp83tg720_params.chip = DP83TG720_CS1;
else if (version->revision == DP83TG720_REV_CS1_1)
dp83tg720_params.chip = DP83TG720_CS1_1;
else if (version->revision == DP83TG721_REV_CS1)
dp83tg720_params.chip = DP83TG721_CS1;
return supported;
}
bool Dp83tg720_isMacModeSupported(EthPhyDrv_Handle hPhy,
Phy_Mii mii)
{
bool supported = false;
switch (mii)
{
case PHY_MAC_MII_MII:
break;
case PHY_MAC_MII_GMII:
break;
case PHY_MAC_MII_RGMII:
supported = true;
break;
case PHY_MAC_MII_SGMII:
supported = true;
break;
default:
supported = false;
break;
}
return supported;
}
int32_t Dp83tg720_config(EthPhyDrv_Handle hPhy,
const void *pExtCfg,
const uint32_t extCfgSize,
Phy_Mii mii,
bool loopbackEn)
{
uint8_t phyAddr = PhyPriv_getPhyAddr(hPhy);
const Dp83tg720_Cfg *extendedCfg = (const Dp83tg720_Cfg *)pExtCfg;
uint32_t extendedCfgSize = extCfgSize;
int32_t status = PHY_SOK;
if ((extendedCfg == NULL) ||
(extendedCfgSize != sizeof(*extendedCfg)))
{
//PHYTRACE_ERR("PHY %u: invalid config params (cfg=%p, size=%u)\n",phyAddr, extendedCfg, extendedCfgSize);
status = PHY_EINVALIDPARAMS;
}
/* Read strap register */
if (status == PHY_SOK)
{
Dp83tg720_readStraps(hPhy, extendedCfg->MasterSlaveMode);
}
/* Set Master/Slave mode - through PHY config */
if(extendedCfg->MasterSlaveMode == DP83TG720_MASTER_MODE)
{
dp83tg720_params.is_master = true;
//PHYTRACE_DBG("PHY %u: Master Mode enabled\n",phyAddr);
}
else if(extendedCfg->MasterSlaveMode == DP83TG720_SLAVE_MODE)
{
dp83tg720_params.is_master = false;
////PHYTRACE_DBG("PHY %u: Slave Mode enabled\n",phyAddr);
}
/* Init specific chip */
if (status == PHY_SOK)
{
Dp83tg720_chipInit(hPhy);
}
/* Configure MII interface */
if (status == PHY_SOK)
{
Dp83tg720_setMiiMode(hPhy, mii);
}
/* Configure SGMII auto negotiation */
if (status == PHY_SOK &&
mii == PHY_MAC_MII_SGMII)
{
Dp83tg720_configAutoNeg(hPhy, extendedCfg->sgmiiAutoNegEn);
}
/* Configure RGMII clock shift */
if (status == PHY_SOK &&
mii == PHY_MAC_MII_RGMII)
{
Dp83tg720_configClkShift(hPhy,
extendedCfg->txClkShiftEn,
extendedCfg->rxClkShiftEn);
}
/* Configure interrupts */
if (status == PHY_SOK)
{
Dp83tg720_configIntr(hPhy, extendedCfg->interruptEn);
}
/* Set loopback configuration: enable or disable */
if (status == PHY_SOK)
{
Dp83tg720_setLoopbackCfg(hPhy, loopbackEn);
}
return status;
}
static void Dp83tg720_setLoopbackCfg(EthPhyDrv_Handle hPhy,
bool enable)
{
bool complete;
int32_t status;
uint16_t val;
const uint8_t phyAddr = PhyPriv_getPhyAddr(hPhy);
Phy_RegAccessCb_t* pRegAccessApi = PhyPriv_getRegAccessApi(hPhy);
//PHYTRACE_DBG("PHY %u: %s loopback\n",enable ? "enable" : "disable");
status = pRegAccessApi->EnetPhy_readReg(pRegAccessApi->pArgs, PHY_BMCR, &val);
if(status != PHY_SOK && enable)
{
//PHYTRACE_ERR_IF(status != PHY_SOK,"PHY %u: failed to set loopback mode: could not read reg %u\n",phyAddr, PHY_BMCR);
return;
}
if (enable)
{
//xMII Loopback Mode
val |= PHY_BMCR_LOOPBACK;
}
else
{
//Normal Mode
val &= ~PHY_BMCR_LOOPBACK;
}
/* Specific predefined loopback configuration values are required for
* normal mode or loopback mode */
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, PHY_BMCR, val);
/* Software restart is required after changing LOOPCR register */
Dp83tg720_reset(hPhy);
do
{
complete = Dp83tg720_isResetComplete(hPhy);
}
while (!complete);
}
void Dp83tg720_reset(EthPhyDrv_Handle hPhy)
{
Phy_RegAccessCb_t* pRegAccessApi = PhyPriv_getRegAccessApi(hPhy);
/* Global software reset */
//PHYTRACE_DBG("PHY %u: global soft-reset\n", 0x0F);
pRegAccessApi->EnetPhy_rmwReg(pRegAccessApi->pArgs, MII_DP83TG720_RESET_CTRL, DP83TG720_SW_RESET, DP83TG720_SW_RESET);
}
static void Dp83tg720_resetHw(EthPhyDrv_Handle hPhy)
{
/* Global hardware reset */
Phy_RegAccessCb_t* pRegAccessApi = PhyPriv_getRegAccessApi(hPhy);
//PHYTRACE_DBG("PHY %u: global hard-reset\n", 0x0F);
pRegAccessApi->EnetPhy_rmwReg(pRegAccessApi->pArgs, MII_DP83TG720_RESET_CTRL, DP83TG720_HW_RESET, DP83TG720_HW_RESET);
}
bool Dp83tg720_isResetComplete(EthPhyDrv_Handle hPhy)
{
int32_t status;
uint16_t val;
bool complete = false;
Phy_RegAccessCb_t* pRegAccessApi = PhyPriv_getRegAccessApi(hPhy);
/* Reset is complete when RESET bits have self-cleared */
status = pRegAccessApi->EnetPhy_readReg(pRegAccessApi->pArgs, MII_DP83TG720_RESET_CTRL, &val);
if (status == PHY_SOK)
{
complete = ((val & (DP83TG720_SW_RESET | DP83TG720_HW_RESET)) == 0U);
}
//PHYTRACE_DBG("PHY %u: global reset is %s complete\n", 0x0F, complete ? "" : "not");
return complete;
}
static int32_t Dp83tg720_readMmd(EthPhyDrv_Handle hPhy, uint16_t devad, uint32_t reg, uint16_t *val)
{
int32_t status;
Phy_RegAccessCb_t* pRegAccessApi = PhyPriv_getRegAccessApi(hPhy);
status = pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, PHY_MMD_CR, devad | MMD_CR_ADDR);
if (status == PHY_SOK)
{
status = pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, PHY_MMD_DR, reg);
}
if (status == PHY_SOK)
{
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, PHY_MMD_CR, devad | MMD_CR_DATA_NOPOSTINC);
}
if (status == PHY_SOK)
{
status = pRegAccessApi->EnetPhy_readReg(pRegAccessApi->pArgs, PHY_MMD_DR, val);
}
//PHYTRACE_VERBOSE_IF(status == PHY_SOK, "PHY %u: read reg %u val 0x%04x\n", 0x0F, reg, *val);
//PHYTRACE_ERR_IF(status != PHY_SOK,"PHY %u: failed to read reg %u\n", 0x0F, reg);
return 0;
}
static void Dp83tg720_writeMmd(EthPhyDrv_Handle hPhy, uint16_t devad, uint32_t reg, uint16_t val)
{
int32_t status;
Phy_RegAccessCb_t* pRegAccessApi = PhyPriv_getRegAccessApi(hPhy);
//PHYTRACE_VERBOSE("PHY %u: write %u val 0x%04x\n", 0x0F, reg, val);
status = pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, PHY_MMD_CR, devad | MMD_CR_ADDR);
if (status == PHY_SOK)
{
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, PHY_MMD_DR, reg);
}
if (status == PHY_SOK)
{
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, PHY_MMD_CR, devad | MMD_CR_DATA_NOPOSTINC);
}
if (status == PHY_SOK)
{
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, PHY_MMD_DR, val);
}
//PHYTRACE_ERR_IF(status != PHY_SOK,"PHY %u: failed to write reg %u val 0x%04x\n", 0x0F, reg, val);
}
static void Dp83tg720_setBitsMmd(EthPhyDrv_Handle hPhy, uint16_t devad, uint32_t reg, uint16_t val)
{
uint16_t value;
int32_t status;
status = Dp83tg720_readMmd(hPhy, devad, reg, &value);
if (status == PHY_SOK)
{
value = value | val;
Dp83tg720_writeMmd(hPhy, devad, reg, value);
}
}
static void Dp83tg720_readStraps(EthPhyDrv_Handle hPhy, Dp83tg720_MasterSlaveMode msMode)
{
uint16_t strap;
int32_t status;
status = Dp83tg720_readMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_STRAP, &strap);
if (status != PHY_SOK)
return;
//PHYTRACE_DBG("PHY %u: Strap register is 0x%X\n",0x0F, strap);
if(msMode == DP83TG720_MASTER_SLAVE_STRAP)
{
if (strap & DP83TG720_MASTER_MODE_EN)
{
dp83tg720_params.is_master = true;
//PHYTRACE_DBG("PHY %u: Strap: Master Mode enabled\n",0x0F);
}
else
{
dp83tg720_params.is_master = false;
//PHYTRACE_DBG("PHY %u: Strap: Slave Mode enabled\n",0x0F);
}
}
if (strap & DP83TG720_RGMII_IS_EN)
{
/* //PHYTRACE_DBG("PHY %u: Strap: RGMII Mode enabled\n",0x0F);
if (strap & DP83TG720_TX_SHIFT_EN)
//PHYTRACE_DBG("PHY %u: Strap: TX Clock Shift enabled\n",0x0F);
if (strap & DP83TG720_RX_SHIFT_EN)
//PHYTRACE_DBG("PHY %u: Strap: RX Clock Shift enabled\n",0x0F); */
}
else if (strap & DP83TG720_SGMII_IS_EN)
{
//PHYTRACE_DBG("PHY %u: Strap: SGMII Mode enabled\n",0x0F);
}
};
static void Dp83tg720_writeSeq(EthPhyDrv_Handle hPhy, const struct dp83tg720_init_reg *init_data, int size)
{
int i;
for (i = 0; i < size; i++) {
Dp83tg720_writeMmd(hPhy, init_data[i].mmd, init_data[i].reg, init_data[i].val);
}
}
static void Dp83tg720_chipInit(EthPhyDrv_Handle hPhy)
{
bool complete = false;
/* Perform a hardware reset prior to configuration */
Dp83tg720_resetHw(hPhy);
do
{
complete = Dp83tg720_isResetComplete(hPhy);
}
while (!complete);
/* Apply chip-specific configuration */
switch (dp83tg720_params.chip) {
case DP83TG720_CS1:
if (dp83tg720_params.is_master){
Dp83tg720_writeSeq(hPhy, dp83tg720_cs1_master_init,
sizeof(dp83tg720_cs1_master_init)/sizeof(dp83tg720_cs1_master_init[0]));
//PHYTRACE_DBG("PHY %u: Applying configuration for DP83TG720 CS1.0 Master\n",0x0F);
}
else{
Dp83tg720_writeSeq(hPhy, dp83tg720_cs1_slave_init,
sizeof(dp83tg720_cs1_slave_init)/sizeof(dp83tg720_cs1_slave_init[0]));
//PHYTRACE_DBG("PHY %u: Applying configuration for DP83TG720 CS1.0 Slave\n",0x0F);
}
break;
case DP83TG720_CS1_1:
if (dp83tg720_params.is_master){
Dp83tg720_writeSeq(hPhy, dp83tg720_cs1_1_master_init,
sizeof(dp83tg720_cs1_1_master_init)/sizeof(dp83tg720_cs1_1_master_init[0]));
//PHYTRACE_DBG("PHY %u: Applying configuration for DP83TG720 CS1.1 Master\n",0x0F);
}
else{
Dp83tg720_writeSeq(hPhy, dp83tg720_cs1_1_slave_init,
sizeof(dp83tg720_cs1_1_slave_init)/sizeof(dp83tg720_cs1_1_slave_init[0]));
//PHYTRACE_DBG("PHY %u: Applying configuration for DP83TG720 CS1.1 Slave\n",0x0F);
}
break;
case DP83TG721_CS1:
if (dp83tg720_params.is_master){
Dp83tg720_writeSeq(hPhy, dp83tg721_cs1_master_init,
sizeof(dp83tg721_cs1_master_init)/sizeof(dp83tg721_cs1_master_init[0]));
//PHYTRACE_DBG("PHY %u: Applying configuration for DP83TG721 CS1 Master\n",0x0F);
}
else{
Dp83tg720_writeSeq(hPhy, dp83tg721_cs1_slave_init,
sizeof(dp83tg721_cs1_slave_init)/sizeof(dp83tg721_cs1_slave_init[0]));
//PHYTRACE_DBG("PHY %u: Applying configuration for DP83TG721 CS1 Slave\n",0x0F);
}
break;
default:
//PHYTRACE_DBG("PHY %u: No supported DP83TG720 Chip. Skipping chip-specific configuration!\n",0x0F);
break;
};
/* Perform a software reset to restart the PHY with the updated configuration */
Dp83tg720_reset(hPhy);
do
{
complete = Dp83tg720_isResetComplete(hPhy);
}
while (!complete);
/* Let the PHY start link-up procedure */
Dp83tg720_writeMmd(hPhy, DP83TG720_DEVADDR, 0x0573U, 0x0001U);
/* Start send-s detection during link-up sequence */
Dp83tg720_writeMmd(hPhy, DP83TG720_DEVADDR, 0x056AU, 0x5F41U);
}
static void Dp83tg720_setMiiMode(EthPhyDrv_Handle hPhy, Phy_Mii mii)
{
uint16_t rgmii_val = 0U;
uint16_t sgmii_val = 0U;
int32_t status = PHY_SOK;
status = Dp83tg720_readMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_RGMII_CTRL, &rgmii_val);
if(status != PHY_SOK)
return;
status = Dp83tg720_readMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_SGMII_CTRL, &sgmii_val);
if(status != PHY_SOK)
return;
if (mii == PHY_MAC_MII_RGMII)
{
rgmii_val |= DP83TG720_RGMII_EN;
sgmii_val &= ~DP83TG720_SGMII_EN;
//PHYTRACE_DBG("PHY %u: RGMII Mode enabled\n",0x0F);
}
else if (mii == PHY_MAC_MII_SGMII)
{
rgmii_val &= ~DP83TG720_RGMII_EN;
sgmii_val |= DP83TG720_SGMII_EN;
//PHYTRACE_DBG("PHY %u: SGMII Mode enabled\n",0x0F);
}
Dp83tg720_writeMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_RGMII_CTRL, rgmii_val);
Dp83tg720_writeMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_SGMII_CTRL, sgmii_val);
}
static void Dp83tg720_configAutoNeg(EthPhyDrv_Handle hPhy, bool sgmiiAutoNegEn)
{
uint16_t val = 0U;
int32_t status = PHY_SOK;
status = Dp83tg720_readMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_SGMII_CTRL, &val);
if(status != PHY_SOK)
return;
if(sgmiiAutoNegEn)
{
val |= DP83TG720_SGMII_AUTO_NEG_EN;
//PHYTRACE_DBG("PHY %u: SGMII Auto Negotiation enabled\n",0x0F);
}
else
{
val &= ~DP83TG720_SGMII_AUTO_NEG_EN;
//PHYTRACE_DBG("PHY %u: SGMII Auto Negotiation disabled\n",0x0F);
}
Dp83tg720_writeMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_SGMII_CTRL, val);
}
static void Dp83tg720_configClkShift(EthPhyDrv_Handle hPhy, bool txClkShiftEn, bool rxClkShiftEn)
{
uint16_t val = 0U;
int32_t status = PHY_SOK;
status = Dp83tg720_readMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_RGMII_ID_CTRL, &val);
if(status != PHY_SOK)
return;
if (!txClkShiftEn)
val &= ~DP83TG720_TX_CLK_SHIFT;
else
val |= DP83TG720_TX_CLK_SHIFT;
if (!rxClkShiftEn)
val &= ~DP83TG720_RX_CLK_SHIFT;
else
val |= DP83TG720_RX_CLK_SHIFT;
Dp83tg720_writeMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_RGMII_ID_CTRL, val);
//PHYTRACE_DBG("PHY %u: RGMII TX Clock Shift %s\n",0x0F, txClkShiftEn ? "enabled" : "disabled");
//PHYTRACE_DBG("PHY %u: RGMII RX Clock Shift %s\n",0x0F, rxClkShiftEn ? "enabled" : "disabled");
}
static void Dp83tg720_configIntr(EthPhyDrv_Handle hPhy, bool intrEn)
{
uint16_t reg_val;
int32_t status;
Phy_RegAccessCb_t* pRegAccessApi = PhyPriv_getRegAccessApi(hPhy);
if (intrEn) {
//PHYTRACE_DBG("PHY %u: Enable interrupts\n", 0x0F);
status = pRegAccessApi->EnetPhy_readReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT1, ®_val);
if (status != PHY_SOK)
return;
reg_val |= (DP83TG720_ANEG_COMPLETE_INT_EN |
DP83TG720_ESD_EVENT_INT_EN |
DP83TG720_LINK_STAT_INT_EN |
DP83TG720_ENERGY_DET_INT_EN |
DP83TG720_LINK_QUAL_INT_EN);
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT1, reg_val);
status = pRegAccessApi->EnetPhy_readReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT2, ®_val);
if (status != PHY_SOK)
return;
reg_val |= (DP83TG720_SLEEP_MODE_INT_EN |
DP83TG720_OVERTEMP_INT_EN |
DP83TG720_OVERVOLTAGE_INT_EN |
DP83TG720_UNDERVOLTAGE_INT_EN);
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT2, reg_val);
status = pRegAccessApi->EnetPhy_readReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT3, ®_val);
if (status != PHY_SOK)
return;
reg_val |= (DP83TG720_LPS_INT_EN |
DP83TG720_WAKE_REQ_EN |
DP83TG720_NO_FRAME_INT_EN |
DP83TG720_POR_DONE_INT_EN);
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT3, reg_val);
}
else {
//PHYTRACE_DBG("PHY %u: Disable interrupts\n",0x0F);
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT1, 0U);
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT2, 0U);
pRegAccessApi->EnetPhy_writeReg(pRegAccessApi->pArgs, MII_DP83TG720_INT_STAT3, 0U);
}
}
static volatile uint16_t regVals[20];
void Dp83tg720_readRegsToArray()
{
uint16_t val;
const uint8_t phyAddr = 0x0F;
EthPhyDrv_Handle hPhy = &gEnetPhyDrvDp83tg720; // sin cast
Phy_RegAccessCb_t* pRegAccessApi = PhyPriv_getRegAccessApi(hPhy);
uint8_t i = 0;
// Registers via Clause 22
mi_readReg(phyAddr, PHY_BMCR, &val);
regVals[i++] = val; // 0 - BMCRphyAddr
mi_readReg(phyAddr, PHY_BMSR, &val);
regVals[i++] = val; // 1 - BMSRphyAddr
mi_readReg(phyAddr, PHY_PHYIDR1, &val);
regVals[i++] = val; // 2 - PHYIphyAddr
mi_readReg(phyAddr, PHY_PHYIDR2, &val);
regVals[i++] = val; // 3 - PHYIphyAddr
mi_readReg(phyAddr, DP83TG720_PHYSTS, &val);
regVals[i++] = val; // 4 - PHYSphyAddr
mi_readReg(phyAddr, DP83TG720_PHYCR, &val);
regVals[i++] = val; // 5 - PHYCphyAddr
mi_readReg(phyAddr, DP83TG720_MISR1, &val);
regVals[i++] = val; // 6 - MISRphyAddr
mi_readReg(phyAddr, DP83TG720_MISR2, &val);
regVals[i++] = val; // 7 - MISRphyAddr
mi_readReg(phyAddr, DP83TG720_RECR, &val);
regVals[i++] = val; // 8 - RECRphyAddr
mi_readReg(phyAddr, DP83TG720_BISCR, &val);
regVals[i++] = val; // 9 - BISCphyAddr
mi_readReg(phyAddr, DP83TG720_MISR3, &val);
regVals[i++] = val; // 10 - MISphyAddr
mi_readReg(phyAddr, DP83TG720_REG19, &val);
regVals[i++] = val; // 11 - REGphyAddr
mi_readReg(phyAddr, DP83TG720_CDCR, &val);
regVals[i++] = val; // 12 - CDCphyAddr
mi_readReg(phyAddr, DP83TG720_PHYRCR, &val);
regVals[i++] = val; // 13 - PHYRCR
/* // MMD registers
Dp83tg720_readMmd(0xFCF78900U, DP83TG720_DEVADDR, DP83TG720_SGMII_CTRL, &val);
regVals[i++] = val; // 14 - SGMII_CTRL
Dp83tg720_readMmd(0xFCF78900U, DP83TG720_DEVADDR, DP83TG720_RGMII_CTRL, &val);
regVals[i++] = val; // 15 - RGMII_CTRL
Dp83tg720_readMmd(0xFCF78900U, DP83TG720_DEVADDR, DP83TG720_RGMII_ID_CTRL, &val);
regVals[i++] = val; // 16 - RGMII_DELAY_CTRL
Dp83tg720_readMmd(0xFCF78900U, DP83TG720_DEVADDR_MMD1, DP83TG720_MMD1_PMA_PMD_CONTROL, &val);
regVals[i++] = val; // 17 - MMD1_PMA_PMD_CONTROL */
}
int32_t mi_readReg(void* args, uint32_t reg, uint16_t* val) {
uint32 mdioHandle = 0xFCF78900U;
MDIOPhyRegRead(mdioHandle, 0x0F, reg, val);
return 0;
}
int32_t mi_writeReg(void* args, uint32_t reg, uint16_t val) {
uint32 mdioHandle = 0xFCF78900U;
MDIOPhyRegWrite(mdioHandle, 0x0F, reg, val);
return 0;
}
int32_t mi_rmwReg(void* args, uint32_t reg, uint16_t mask, uint16_t val) {
uint32 mdioHandle = 0xFCF78900U;
uint16_t oldVal;
MDIOPhyRegRead((void*)mdioHandle, 0x0F, reg, &oldVal);
oldVal = (oldVal & ~mask) | (val & mask);
MDIOPhyRegWrite((void*)mdioHandle, 0x0F, reg, oldVal);
return 0;
}
static volatile uint16 dp83tg720_reg_value3;
static volatile uint16 dp83tg720_reg_value4;
void dp83tg720_init()
{
EthPhyDrv_Handle hPhy = &gEnetPhyDrvDp83tg720;
uintptr_t mdioHandle = 0xFCF78900U;
Phy_RegAccessCb_t regAccessCb = {
.EnetPhy_readReg = mi_readReg,
.EnetPhy_writeReg = mi_writeReg,
.EnetPhy_rmwReg = mi_rmwReg,
.EnetPhy_readExtReg = Dp83tg720_readMmd,
.EnetPhy_writeExtReg = Dp83tg720_writeMmd,
.pArgs = (void*)mdioHandle, // directo sin estructura
};
Dp83tg720_bind(&hPhy, 0x0F, ®AccessCb);
//MDIOPhyRegRead(MDIO_BASE, 0x0F, 0x03, ®_value3);
Dp83tg720_Cfg phyCfg;
Dp83tg720_initCfg(&phyCfg);
phyCfg.MasterSlaveMode = DP83TG720_SLAVE_MODE;
phyCfg.txClkShiftEn = true;
phyCfg.rxClkShiftEn = true;
phyCfg.interruptEn = false;
phyCfg.sgmiiAutoNegEn = true;
Phy_Mii phyMiiMode = PHY_MAC_MII_SGMII;
bool loopback = false;
//Dp83tg720_readMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_STRAP, &dp83tg720_reg_value3);
int32_t status = Dp83tg720_config(hPhy, &phyCfg, sizeof(phyCfg), phyMiiMode, loopback);
Dp83tg720_readMmd(hPhy, DP83TG720_DEVADDR, DP83TG720_SGMII_CTRL, &dp83tg720_reg_value3);
Dp83tg720_readMmd(hPhy, DP83TG720_DEVADDR, 0x60AU, &dp83tg720_reg_value4);
}
Could you help me identify what might be missing or incorrect in the setup that prevents the link from being established?
Regards,
Daniel


