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