嵌入式 PHY 驱动移植
嵌入式 PHY 驱动移植
PHY是IEEE 802.3规定的一个标准模块, PHY芯片寄存器空间为5位, 地址 0~31 共32个寄存器
其中0~15 (0x00~0x0F) 为标准寄存器, 16~31 (0x10~0x1F) 为标准扩展寄存器
32~255 (0x20~0xFF) 为厂商扩展寄存器
标准寄存器 BMCR (0x00)
| Bit | Symbol | Name | 描述 |
|---|---|---|---|
15 | Reset | 软复位 | 1 = 触发全局硬复位,复位后自动清零 |
14 | Loopback | 环回 | 1 = 启用环回模式 |
13 | Speed_Selection(LSB) | 速度选择(最低位) | 需要禁用自动协商, 0 = 10Mbps, 1 = 100Mbps, 2 = 1000Mbps |
12 | Autoneg_En | 自动协商使能 | 1 = 启用自动协商, 0 = 禁用自动协商 |
11 | Power_down | 低功耗模式 | 进入节能转台, 物理链接中断 |
9 | Re_Autoneg | 重启自动协商 | 些1后触发自动协商, 完成后自动清零 |
8 | Duplex_Mode | 双工模式 | 0 = 半双工, 1 = 全双工, 自动协商启用时, 该位反应结果 |
6 | Speed_ Selection(MSB) | 速度选择(最高位) | 见13位 |
标准状态寄存器 BMSR (0x01)
| Bit | Symbol | 描述 |
|---|---|---|
14 | 100BASE-X_Fd | 100M全双工 |
13 | 100BASE-X_Hd | 100M半双工 |
12 | 10Mbps_Fd | 10M全双工 |
11 | 10Mbps_Hd | 10M半双工 |
8 | Extended_Status | 扩展状态可用指示 |
5 | Autoneg_Complete | 自动协商完成标志 |
4 | Remote_Fault | 远端故障指示 |
3 | Autoneg_Ability | 是否支持自动协商功能 |
2 | Link_Status | 链接状态 1 = 链接, 0 = 未链接 |
0 | Extended_Capability | 是否存在扩展能力 |
PHY初始化
复位PHY
Cvoid yt8531_reset(ENET_Type *ptr, uint32_t phy_addr) { uint16_t data; /* PHY reset */ enet_write_phy(ptr, phy_addr, yt8531_BMCR, yt8531_BMCR_RESET_SET(1)); /* wait until the reset is completed */ do { data = enet_read_phy(ptr, phy_addr, yt8531_BMCR); } while (yt8531_BMCR_RESET_GET(data)); }配置自动协商 (或手动配置)
Cbool yt8531_basic_mode_init(ENET_Type *ptr, uint32_t phy_addr, yt8531_config_t *config) { uint16_t data = 0; data |= yt8531_BMCR_RESET_SET(0) /* Normal operation */ | yt8531_BMCR_LOOPBACK_SET(config->loopback) /* configure PCS loopback mode */ | yt8531_BMCR_ANE_SET(config->auto_negotiation) /* configure Auto-Negotiation */ | yt8531_BMCR_PWD_SET(0) /* Normal operation */ | yt8531_BMCR_ISOLATE_SET(0) /* Normal operation */ | yt8531_BMCR_RESTART_AN_SET(0) /* Normal operation (ignored when Auto-Negotiation is disabled) */ | yt8531_BMCR_COLLISION_TEST_SET(0); /* Normal operation */ if (config->auto_negotiation == 0) { data |= yt8531_BMCR_SPEED0_SET(config->speed) | yt8531_BMCR_SPEED1_SET(config->speed >> 1); /* Set port speed */ data |= yt8531_BMCR_DUPLEX_SET(config->duplex); /* Set duplex mode */ } /* check the id of yt8531 */ if (yt8531_check_id(ptr) == false) { return false; } enet_write_phy(ptr, phy_addr, yt8531_BMCR, data); return true; }确认接口模式
Cvoid yt8531_get_phy_status(ENET_Type *ptr, uint32_t phy_addr, enet_phy_status_t *status) { uint16_t data; data = enet_read_phy(ptr, phy_addr, yt8531_PHYSR); status->enet_phy_link = yt8531_PHYSR_LINK_REAL_TIME_GET(data); status->enet_phy_speed = yt8531_PHYSR_SPEED_GET(data) == 0 ? enet_phy_port_speed_10mbps : yt8531_PHYSR_SPEED_GET(data) == 1 ? enet_phy_port_speed_100mbps : enet_phy_port_speed_1000mbps; status->enet_phy_duplex = yt8531_PHYSR_DUPLEX_GET(data); }
嵌入式 PHY 驱动移植
https://simonkimi.githubio.io/2026/03/16/嵌入式-PHY-驱动移植/