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.

RTOS/PROCESSOR-SDK-AM437X: Custom board PHY init fails

Part Number: PROCESSOR-SDK-AM437X
Other Parts Discussed in Thread: TLK105

Tool/software: TI-RTOS

Hi

I am migrating the EtherCAT + EnDAT project from AM437x Industial EVM (version 1.4A) to my custom board.

The custom board is designed following the circuit of AM437x Industrial EVM, reducing peripheral module to EnDat, QSPI(for flash) and ICSS Ethernet port.

Software environment :

SYS/BIOS: ind SDK 02.01.03.02

Compiler: GNU v4.8.4(Linaro)

SYS/BIOS: 6.41.4.54

XDCtool: 3.31.2.38

The  EtherCAT + EnDAT project is developed by extending the FOC with EtherCAT example project.

The custom board will get stuck at while loop in bsp_tlk105_init() function (tiescbsp.c line1409).

void bsp_tlk105_init(PRUICSS_Handle pruIcssHandle, Uint8 phy0addr,
                     Uint8 phy1addr, Uint8 enhancedlink_enable)
{
    if(TIESC_MDIO_RX_LINK_ENABLE == enhancedlink_enable)
    {
        Board_phyMLEDConfig((((PRUICSS_HwAttrs *)(
                                  pruIcssHandle->hwAttrs))->baseAddr + PRU_ICSS_MDIO), phy0addr, PHY_MLED_100,
                            NULL);
        Board_phyMLEDConfig((((PRUICSS_HwAttrs *)(
                                  pruIcssHandle->hwAttrs))->baseAddr + PRU_ICSS_MDIO), phy1addr, PHY_MLED_100,
                            NULL);
    }

    while(!MDIO_getPhyIdentifyStat((((PRUICSS_HwAttrs *)(
                                         pruIcssHandle->hwAttrs))->baseAddr + PRU_ICSS_MDIO), phy0addr, NULL))
    {
    }

The PRUETH circuit is designed following AM437x IDK, only change the Mag RJ-45 Jack.

I found there is something weird when executing HW_WR_REG32() function in MDIOPhyRegRead (mdio.c line90) which called by MDIO_getPhyIdentifyStat() function.


void MDIOPhyRegRead(uint32_t baseAddr,
                    uint32_t phyAddr,
                    uint32_t regNum,
                    uint16_t *pData)
{
    uint32_t regVal = 0U;

    /* Wait till transaction completion if any */
    while(MDIO_USERACCESS_GO_EN_0x1 ==
        HW_RD_FIELD32(baseAddr + MDIO_USERACCESS(0U),
        MDIO_USERACCESS_GO));

    HW_SET_FIELD(regVal, MDIO_USERACCESS_GO, MDIO_USERACCESS_GO_EN_0x1);
    HW_SET_FIELD(regVal, MDIO_USERACCESS_WRITE, MDIO_USERACCESS_READ);
    HW_SET_FIELD(regVal, MDIO_USERACCESS_PHYADR, phyAddr);
    HW_SET_FIELD(regVal, MDIO_USERACCESS_REGADR, regNum);
    HW_WR_REG32(baseAddr + MDIO_USERACCESS(0U), regVal);

    /* wait for command completion */
    while(MDIO_USERACCESS_GO_EN_0x1 ==
        HW_RD_FIELD32(baseAddr + MDIO_USERACCESS(0U),
        MDIO_USERACCESS_GO));

    /* Store the data if the read is acknowledged */
    if(MDIO_USERACCESS_ACK_PASS ==
        HW_RD_FIELD32(baseAddr + MDIO_USERACCESS(0U),
        MDIO_USERACCESS_ACK));
    {
        *pData = (uint16_t)(HW_RD_FIELD32(baseAddr + MDIO_USERACCESS(0U),
            MDIO_USERACCESS_DATA));
    }
}

The value of parameter are

baseAddr: 0x54432400

phyAddr: 0x0

regNum: 0x2

Since the value of parameter "baseAddr" and "regVal" are "0x54432400" and "0x80400000" 

The register value at 0x54432480 should be 0x80400000 but 0x20402000 on AM437x IDK .

And on custom board the value will be 0x0040FFFF, which will not pass the if-statement in MDIO_getPhyIdentifyStat() function (osdrv_mdio.c line509)

uint8_t MDIO_getPhyIdentifyStat(uint32_t mdioBaseAddress, uint32_t phyAddr,
                                MDIOSEM_Handle mdioSemhandle)
{
    uint16_t regStatus;
    MDIO_regRead(mdioBaseAddress, phyAddr, PHY_PHYIDR1_REG, &regStatus,
                 mdioSemhandle);

    if(regStatus == 0x2000)
    {
        return TRUE;
    }

    else
    {
        return FALSE;
    }
}

Is there anyone can help me get through this problem?

Please help...

Yi-Lin