
|
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广播的数据,硬件应该配置成功了吧 |