int32_t EMAC_PhyInit(void)
{
uint32_t u32Reg;
uint32_t u32Delay;
g_EMAC_i32ErrCode = 0;
/* Reset Phy Chip */
EMAC_MdioWrite(PHY_CNTL_REG, EMAC_PHY_ADDR, PHY_CNTL_RESET_PHY);
/* Wait until PHY reset complete.
Report error if the reset status is not cleared for more than 0.1 second */
u32Delay = SystemCoreClock / 10;
while (--u32Delay)
{
u32Reg = EMAC_MdioRead(PHY_CNTL_REG, EMAC_PHY_ADDR) ;
if ((u32Reg & PHY_CNTL_RESET_PHY) == 0UL)
{
break;
}
}
if(u32Delay == 0)
{
goto error;
}
u32Delay = SystemCoreClock; // Wait 1 second. Report error if link valid is not set
while (!(EMAC_MdioRead(PHY_STATUS_REG, EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID))
{
if (--u32Delay == 0) /* Cable not connected */
{
goto error;
}
}
/* Configure auto negotiation capability */
EMAC_MdioWrite(PHY_ANA_REG, EMAC_PHY_ADDR, PHY_ANA_DR100_TX_FULL |
PHY_ANA_DR100_TX_HALF |
PHY_ANA_DR10_TX_FULL |
PHY_ANA_DR10_TX_HALF |
PHY_ANA_IEEE_802_3_CSMA_CD);
/* Restart auto negotiation */
EMAC_MdioWrite(PHY_CNTL_REG, EMAC_PHY_ADDR, EMAC_MdioRead(PHY_CNTL_REG, EMAC_PHY_ADDR) | PHY_CNTL_RESTART_AN);
/* Wait for auto-negotiation complete
Report error if auto-negotiation is not complete in 2 seconds */
u32Delay = SystemCoreClock * 2;
while (!(EMAC_MdioRead(PHY_STATUS_REG, EMAC_PHY_ADDR) & PHY_STATUS_AN_COMPLETE))
{
if (--u32Delay == 0)
{
goto error;
}
}
/* Check link valid again. There're some PHY chips need to re-check link valid
bit set after auto-t-negotiation complete before check partner capability.
Report error if link valid is not set after 1 second */
u32Delay = SystemCoreClock;
while (!(EMAC_MdioRead(PHY_STATUS_REG, EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID))
{
if (--u32Delay == 0)
{
goto error;
}
}
/* Check link partner capability */
u32Reg = EMAC_MdioRead(PHY_ANLPA_REG, EMAC_PHY_ADDR) ;
if (u32Reg & PHY_ANLPA_DR100_TX_FULL)
{
EMAC->CTL |= EMAC_CTL_OPMODE_Msk;
EMAC->CTL |= EMAC_CTL_FUDUP_Msk;
}
else if (u32Reg & PHY_ANLPA_DR100_TX_HALF)
{
EMAC->CTL |= EMAC_CTL_OPMODE_Msk;
EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
}
else if (u32Reg & PHY_ANLPA_DR10_TX_FULL)
{
EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
EMAC->CTL |= EMAC_CTL_FUDUP_Msk;
}
else
{
EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
}
return 0;
error:
EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
return EMAC_TIMEOUT_ERR;
}
EMAC_PhyInit用的是官方例程的EMAC_TxRx
程序是由官方例程修改的,只改了地址EMAC_PHY_ADDR修改为0
还有哪些需要修改的呢?
我试了一下DHCP不行,但是能接收到UDP广播的数据,硬件应该配置成功了吧
|