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.

关于TM4C129 中以太网连接状态的问题?

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

if(ui16Status & EPHY_STS_LINK) 

我发现以网线插入与拔出值分别为0x1116 与(0x1112 \0x1102)

但是EPHY_STS_LINK 判断的是第0位, 于是变成检测到网线都是拔出的状态!  谁能帮忙解释一下吗?

  • 请问您现在使用的是第三方的lwip吗?TivaWare_C_Series的版本是多少?在下面的路径中

    C:\ti\TivaWare_C_Series-2.1.4.178\third_party\lwip-1.4.1\ports\tiva-tm4c129\netif

    的tiva-tm4c129.c内主要是靠EPHY_STS_LINK来call netif_set_link_up 或者 netif_set_link_down 判定的
  • /**
     * Process interrupts from the PHY.
     *
     * should be called from the Stellaris Ethernet Interrupt Handler.  This
     * function will read packets from the Stellaris Ethernet fifo and place them
     * into a pbuf queue.  If the transmitter is idle and there is at least one packet
     * on the transmit queue, it will place it in the transmit fifo and start the
     * transmitter.
     *
     */
    void
    tivaif_process_phy_interrupt(struct netif *psNetif)
    {
        uint16_t ui16Val, ui16Status;
    #if EEE_SUPPORT
        uint16_t ui16EEEStatus;
    #endif
        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);
    
        /* If EEE mode support is requested then read the value of the Link
         * partners status
         */
    #if EEE_SUPPORT
        ui16EEEStatus = EMACPHYMMDRead(EMAC0_BASE, PHY_PHYS_ADDR, 0x703D);
    #endif
    
        /* 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
    
                /* if the link has been advertised as EEE capable then configure
                 * the MAC register for LPI timers and manually set the PHY link
                 * status bit
                 */
    #if EEE_SUPPORT
                if(ui16EEEStatus & 0x2)
                {
                    EMACLPIConfig(EMAC0_BASE, true, 1000, 36);
                    EMACLPILinkSet(EMAC0_BASE);
                    g_bEEELinkActive = true;
                }
    #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
            {
                /* 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
    
                /* if the link has been advertised as EEE capable then clear the
                 * MAC register LPI timers and manually clear the PHY link status
                 * bit
                 */
    #if EEE_SUPPORT
               	g_bEEELinkActive = false;
               	EMACLPILinkClear(EMAC0_BASE);
               	EMACLPIConfig(EMAC0_BASE, false, 1000, 0);
    #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);
        }
    }

  • 下面的补丁是之前一个网友测试过的,您可以试一下

    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);
    }
    }

  • 目前我是一到if(ui16Val & EPHY_MISR1_LINKSTAT)就进行重新连接,而不管是否是连接与非连接了
  • 补丁和原文好像只有以下的差距,况且数据手册上是第二位LINKSTAT判断网线连接状态,而不是第0位exten功能,TI的驱动库是否有错???
    #if EEE_SUPPORT
    ui16EEEStatus = EMACPHYMMDRead(EMAC0_BASE, PHY_PHYS_ADDR, 0x703D);
    #endif
  • #if EEE_SUPPORT
    ui16EEEStatus = EMACPHYMMDRead(EMAC0_BASE, PHY_PHYS_ADDR, 0x703D);
    #endif
    补丁和原来的是否只有上述的区别,况且数据手册上写的是第2位为linkstat,而不是第0位的exten,TI的驱动库是否有错?
  • 这个问题在英文E2E上也有研究,您可以看一下

    e2e.ti.com/.../2359748

    e2e.ti.com/.../1909843