ZYNQ RTL8211F 网口调试
网口调试报错:
-----lwIP Socket Mode Echo server Demo Application ------
Board IP: 192.168.1.10
Netmask : 255.255.255.0
Gateway : 192.168.1.1
Start PHY autonegotiation
Waiting for PHY to complete autonegotiation.
[10:23:38.828]收←◆autonegotiation complete
Phy setup error
Assert due to phy setup failure
在代码get_IEEE_phy_speed里添加如下:
u16 phy_id1, phy_id2; /* 添加PHY ID读取和打印 */ XEmacPs_PhyRead(xemacpsp, phy_addr, 2, &phy_id1); XEmacPs_PhyRead(xemacpsp, phy_addr, 3, &phy_id2); xil_printf("[DEBUG] PHY ID1: 0x%04X, ID2: 0x%04X, Addr: %d\r\n", phy_id1, phy_id2, phy_addr);打印ID结果为:
[DEBUG] PHY ID1: 0x001C, ID2: 0xC916, Addr: 0
证实网口phy芯片为Realtek工业级,和工业级的寄存器地址不一样,所以需要更改驱动,详细信息可以参考如下博客:https://blog.csdn.net/weixin_43260537/article/details/144540367
使用代码如下后,工作正常:
static u32_t get_Realtek_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr) { u16_t control; u16_t status; u16_t status_speed; u32_t timeout_counter = 0; u32_t temp_speed; u16_t phy_identity; u32_t RetStatus; u32_t RTL_SPECIFIC_STATUS_REG; u32_t RTL_LINK_STATUS_MASK; u32_t RTL_SPEED_MASK; u32_t RTL_SPEED_1000; u32_t RTL_SPEED_100; //此处判断是RTL8211F或RTL8211E,根据型号重定义寄存器地址和掩码 XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_IDENTIFIER_2_REG, &phy_identity); if (phy_identity == 0XC916) { xil_printf("Start PHY:RTL8211F autonegotiation\r\n"); RTL_SPECIFIC_STATUS_REG = 0X1A; RTL_LINK_STATUS_MASK = 0x04; RTL_SPEED_MASK = 0x30; RTL_SPEED_1000 = 0x20; RTL_SPEED_100 = 0x10; } else if (phy_identity == 0XC915) { xil_printf("Start PHY:RTL8211E autonegotiation\r\n"); RTL_SPECIFIC_STATUS_REG = 0X0011; RTL_LINK_STATUS_MASK = 0x0400; RTL_SPEED_MASK = 0xC000; RTL_SPEED_1000 = 0x8000; RTL_SPEED_100 = 0x4000; } XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control); control |= IEEE_ASYMMETRIC_PAUSE_MASK; control |= IEEE_PAUSE_MASK; control |= ADVERTISE_100; control |= ADVERTISE_10; XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control); XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, &control); control |= ADVERTISE_1000; XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, control); XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control); control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE; control |= IEEE_STAT_AUTONEGOTIATE_RESTART; XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control); XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control); control |= IEEE_CTRL_RESET_MASK; XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control); while (1) { XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control); if (control & IEEE_CTRL_RESET_MASK) continue; else break; } XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status); xil_printf("Waiting for PHY to complete autonegotiation.\r\n"); while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) { sleep(1); timeout_counter++; if (timeout_counter == 5) { xil_printf("Auto negotiation error \r\n"); return XST_FAILURE; } XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status); } xil_printf("autonegotiation complete \r\n"); //此处使用重定义的寄存器地址和掩码 XEmacPs_PhyRead(xemacpsp, phy_addr,RTL_SPECIFIC_STATUS_REG, &status_speed); if (status_speed & RTL_LINK_STATUS_MASK) { temp_speed = status_speed & RTL_SPEED_MASK; if (temp_speed == RTL_SPEED_1000) return 1000; else if(temp_speed == RTL_SPEED_100) return 100; else return 10; } return XST_FAILURE; }