Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

Ethernet PHY Status -Link Status bit is not set even if link is established and active.

Other Parts Discussed in Thread: TM4C1294NCPDT, EK-TM4C1294XL

Could anyone confirm that Link status bit (in Ethernet PHY Status - MR16 (EPHYSTS), address 0x010)

is never set again after Ethernet cable unplug-plug sequence?

For me this bit is set only once - after reset and first cable plug-in.

Tried to force restart an auto-negotiation cycle, but this gives nothing.

EMACPHYWrite(EMAC0_BASE, PHY_PHYS_ADDR, EPHY_BMCR, (EPHY_BMCR_ANEN |
EPHY_BMCR_RESTARTAN));

Is there any solution to get correct link status?

I need this info to pass to lwip stack ( netif_set_link_up(psNetif) ).

TM4C1294NCPDT with lwIP1.4.1

Thank you for your time.

  • Hello Aigars

    No it does work after plug-unplug-plug

    Regards
    Amit
  • Strange... what I am missing???
    Did you change something in original tiva-tm4c129.c file?
    Have you any idea why it's not working for me?
  • Hello Aigans

    Did you try a known example like qs_iot on a EK-TM4C1294XL to see if it works for you?

    Regards
    Amit
  • I tried today qs_iot example and it works as expected. Bit is set/cleared on every cable plug/unplug event.

    But my project based on the same code - not.

    What else could cause such behavior?

    I compared result values in tivaif_process_phy_interrupt(struct netif *psNetif)

    /* Read the PHY interrupt status. This clears all interrupt sources.
    * Note that we are only enabling sources in EPHY_MISR1 so we don't
    * read EPHY_MISR2.
    */

    ui16Val = EMACPHYRead(EMAC0_BASE, PHY_PHYS_ADDR, EPHY_MISR1);

    and

    /* Read the current PHY status. */

    ui16Status = EMACPHYRead(EMAC0_BASE, PHY_PHYS_ADDR, EPHY_STS);

    function and they are  the same in all cases except one bit - link status.

    In my project it is set only once per session.

    /////// NON WORKING my project//////
    1. PLUG-IN
    ui16Val = 0x243C
    ui16Status = 0x1115 // <-- Here bit 0 has set correctly

    2. PLUG-OUT
    ui16Val = 0x223C
    ui16Status = 0x1912

    3. PLUG-IN
    ui16Val = 0x243C
    ui16Status = 0x1914 // <-- Here !!! bit 0 has never set again !!!

    4. PLUG-OUT
    ui16Val = 0x223C
    ui16Status = 0x1912

    /////// WORKING qs_iot example //////
    1. PLUG-IN
    ui16Val = 0x243C
    ui16Status = 0x1115

    2. PLUG-OUT
    ui16Val = 0x223C
    ui16Status = 0x1912

    3. PLUG-IN
    ui16Val = 0x243C
    ui16Status = 0x1915

    4. PLUG-OUT
    ui16Val = 0x223C
    ui16Status = 0x1912

     

    Have you any idea why?

  • Hello Aigars

    Is the configuration of EMAC and PHY the same between the two codes?

    Regards
    Amit
  • Did not compare, but both projects use the same files for lwip.
    Fortunately I found workaround for my problem.
    I found that if I force read Ethernet PHY Basic Mode Status - MR1 (EPHYBMSR), address
    0x001 on event when cable is unplugged helps to fix this behavior.
    May be you could explain why, but I am happy just with this fix.


    Here is modified routine that fix this behavior:


    void
    tivaif_process_phy_interrupt(struct netif *psNetif)
    {
    uint16_t ui16Val, ui16Status;
    uint32_t ui32Config, ui32Mode, ui32RxMaxFrameSize;

    /* Read the PHY interrupt status. This clears all interrupt sources.
    * Note that we are only enabling sources in EPHY_MISR1 so we don't
    * read EPHY_MISR2.
    */
    ui16Val = EMACPHYRead(EMAC0_BASE, PHY_PHYS_ADDR, EPHY_MISR1);

    /* Read the current PHY status. */
    ui16Status = EMACPHYRead(EMAC0_BASE, PHY_PHYS_ADDR, EPHY_STS);

    /* Has the link status changed? */
    if(ui16Val & EPHY_MISR1_LINKSTAT)
    {

    /* Is link up or down now? */
    if(ui16Status & EPHY_STS_LINK)
    {

    /* Tell lwIP the link is up. */
    #if NO_SYS
    netif_set_link_up(psNetif);
    #else
    tcpip_callback((tcpip_callback_fn)netif_set_link_up, psNetif);
    #endif

    /* In this case we drop through since we may need to reconfigure
    * the MAC depending upon the speed and half/fui32l-duplex settings.
    */
    }
    else
    {
    // HERE IS MY FIX
    /* fix link status bit error by reading Basic Mode Status register*/
    EMACPHYRead(EMAC0_BASE, PHY_PHYS_ADDR, EPHY_BMSR);
    // END OF MY FIX

    /* Tell lwIP the link is down */
    #if NO_SYS
    netif_set_link_down(psNetif);
    #else
    tcpip_callback((tcpip_callback_fn)netif_set_link_down, psNetif);
    #endif
    }
    }

    /* Has the speed or duplex status changed? */
    if(ui16Val & (EPHY_MISR1_SPEED | EPHY_MISR1_SPEED | EPHY_MISR1_ANC))
    {
    /* Get the current MAC configuration. */
    EMACConfigGet(EMAC0_BASE, &ui32Config, &ui32Mode,
    &ui32RxMaxFrameSize);

    /* What speed is the interface running at now?
    */
    if(ui16Status & EPHY_STS_SPEED)
    {
    /* 10Mbps is selected */
    ui32Config &= ~EMAC_CONFIG_100MBPS;
    }
    else
    {
    /* 100Mbps is selected */
    ui32Config |= EMAC_CONFIG_100MBPS;
    }

    /* Are we in fui32l- or half-duplex mode? */
    if(ui16Status & EPHY_STS_DUPLEX)
    {
    /* Fui32l duplex. */
    ui32Config |= EMAC_CONFIG_FULL_DUPLEX;
    }
    else
    {
    /* Half duplex. */
    ui32Config &= ~EMAC_CONFIG_FULL_DUPLEX;
    }

    /* Reconfigure the MAC */
    EMACConfigSet(EMAC0_BASE, ui32Config, ui32Mode, ui32RxMaxFrameSize);
    }
    }


    BTW the value of EPHY_BMSR when read is 0x7849
  • Hello Aigars,

    They may use the same set of file, but not all function calls may be used as there are if-else conditions. I would have first checked the value of the registers as a comparison point.

    Regards
    Amit