AnsweredAssumed Answered

PHY device not responding to MDIO

Question asked by Chaitannya Mahatme on Dec 27, 2014
Latest reply on Jan 8, 2015 by Kan_Li

Hello Everyone,

 

I am using the K60DN512 device with 8720A PHY IC. I have written a simple program to communicate with the PHY IC. I have checked it on logic analyser and I am not getting any response from the PHY device. What can be possible causes.

 

Configuration of PHY device straps.

PHYAD[0]: Pulled low.

MODE[2:0] : 011 100Base-TX Full Duplex. Auto-negotiation disabled. CRS is active during Receive.

MDIO : Pulled high.

MDC: 1 Mhz.

 

I am using the processor expert generated code. So in that case there shouldn't be any error. What can be the possible reason for communication failure. The value is either 0 or 0xFFFF.

 

main(){

 

    MAChandler = mac_Init(NULL);

    Bit1_Init(NULL);

   

    uint16_t id = 0;

    uint16_t value = 0;

    uint16_t timeout = 0;

    uint16_t count = 0;

    uint8_t sfr = 0;

    const uint8_t netifLINK_DELAY = 3;

    do {

 

        mii_read(id, PHY_PHYIDR1, &value);

        count++;

    } while (value == 0xffff);

 

    do {

        value = 0xffff;

        mii_read(id, sfr, &value);

        if (value != 0xffff)

            sfr++;

        count++;

    } while (sfr <= 0x1F);

    uint16 config;

    do {

 

        config = 0x2200;

        mii_write(id, PHY_BMCR, config);

        uint16_t i, j;

        for (i = 0; i < 0xFF; i++)

            for (j = 0; j < 0xFFFF; j++)

                ;

        mii_read(id, PHY_BMCR, &value);

        count++;

    } while (value != config);

 

}

 

int mii_write(int phy_addr, int reg_addr, uint16_t data) {

    int timeout;

 

    /* Clear the MII interrupt bit */ENET_EIR /*(ch)*/= ENET_EIR_MII_MASK;

 

    /* Initiatate the MII Management write */ENET_MMFR /*(ch)*/=

            0 | ENET_MMFR_ST(0x01) | ENET_MMFR_OP(0x01) | ENET_MMFR_PA(phy_addr)

                    | ENET_MMFR_RA(reg_addr) | ENET_MMFR_TA(0x02)

                    | ENET_MMFR_DATA(data);

 

    /* Poll for the MII interrupt (interrupt should be masked) */

    for (timeout = 0; timeout < MII_TIMEOUT; timeout++) {

        if (ENET_EIR /*(ch)*/& ENET_EIR_MII_MASK)

            break;

    }

 

    if (timeout == MII_TIMEOUT)

        return 1;

 

    /* Clear the MII interrupt bit */ENET_EIR /*(ch)*/= ENET_EIR_MII_MASK;

 

    return 0;

}

/********************************************************************/

/*!

* \brief   Read a value from a PHY's MII register.

* \param   phy_addr    Address of the PHY

* \param   reg_addr    Address of the register in the PHY

* \param   data        Pointer to location were read data will be stored

* \return  0 if write is successful; 1 if write times out

*

* mii_read() polls for the FEC's MII interrupt event (which should

* be masked from the interrupt handler) and clears it. If after a

* suitable amount of time the event isn't triggered, a non-zero value

* is returned.

*/

int mii_read(int phy_addr, int reg_addr, uint16_t *data) {

    int timeout;

 

    /* Clear the MII interrupt bit */ENET_EIR /*(ch)*/= ENET_EIR_MII_MASK;

    Bit1_SetVal(NULL); // Indication that the MDIO transfer is about to begin.

    /* Initiatate the MII Management read */ENET_MMFR /*(ch)*/= 0

            | ENET_MMFR_ST(0x01) | ENET_MMFR_OP(0x2) | ENET_MMFR_PA(phy_addr)

            | ENET_MMFR_RA(reg_addr) | ENET_MMFR_TA(0x02);

 

    /* Poll for the MII interrupt (interrupt should be masked) */

    for (timeout = 0; timeout < MII_TIMEOUT; timeout++) {

        if (ENET_EIR /*(ch)*/& ENET_EIR_MII_MASK){

            Bit1_ClrVal(NULL); // Indication that the MDIO transfer is complete.

            break;

        }

    }

 

    if (timeout == MII_TIMEOUT)

        return 1;

   

    /* Clear the MII interrupt bit */ENET_EIR /*(ch)*/= ENET_EIR_MII_MASK;

 

    uint16_t test = ENET_MMFR /*(ch)*/& 0x0000FFFF;

    *data = ENET_MMFR /*(ch)*/& 0x0000FFFF;

 

    return 0;

}

Outcomes