/* 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位, 于是变成检测到网线都是拔出的状态! 谁能帮忙解释一下吗?
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.
/* 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位, 于是变成检测到网线都是拔出的状态! 谁能帮忙解释一下吗?
/** * 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); } }