PHY 芯片基础与寄存器分类归纳总结
做嵌入式网络开发,你天天要和 PHY 芯片打交道。很多人一上来就调寄存器,结果调了半天还是不通。为什么会这样?其实是你没搞懂 PHY 到底在干什么。
这章我们把基础补上。我自己的习惯是,拿到一块新板子,先不看原理图,而是先搞清楚 PHY 的型号,找到数据手册,把基本功能理清楚。然后再动手写代码。
1. PHY 芯片到底是个什么东西?
PHY 的全称是 Physical Layer Transceiver,就是物理层收发器。它的任务是把 MAC 发过来的数字信号变成线缆上的模拟信号,反过来也一样。说白了,它是 MAC 和网线之间的“翻译官”。
MAC 通常集成在主控芯片里(比如 STM32、ARM、FPGA),PHY 是独立芯片,通过 MII 或者 RMII 接口连接。嗯,这里要注意:MII 需要 16 根信号线,RMII 只需要 8 根,省引脚但需要 50MHz 时钟。
我在一个项目中遇到过,量产一段时间后,部分板子偶尔 ping 不通。查到最后,发现是 RMII 时钟抖动偏大,导致 PHY 采样出错。从那以后,我对时钟源的选择就特别小心了。
2. PHY 芯片内部长什么样?
别看 PHY 芯片只是个小 QFN,里面分了好几块功能区。我习惯把它分成三层:
- PCS(物理编码子层):负责编解码,比如 100Base-TX 用的 4B/5B 编码。
- PMA(物理介质附着子层):负责串并转换和时钟恢复。
- PMD(物理介质相关子层):直接驱动差分线对,处理信号电平和阻抗匹配。
这些层通过标准接口连在一起。你看下面这张图,基本划清了 PHY 内部功能块和外部接口的关系。
3. 寄存器分类与归纳
PHY 芯片内部控制全靠寄存器。IEEE 802.3 标准规定了前 16 个寄存器的地址和功能,也就是 Reg0 到 Reg15。剩下的 Reg16 到 Reg31 留给芯片厂商自己玩。
我个人觉得,搞懂这前 16 个寄存器,基本就能搞定 90% 的 PHY 调试问题。剩下的扩展寄存器,遇到具体芯片再看数据手册。
下面这张表,是我当年自己总结的,每次写驱动都对照着看:
| 地址 | 寄存器名称 | 主要功能 | 必读/可选 |
|---|---|---|---|
| 0 | 控制寄存器 | 复位、环回、速度选择、自动协商使能 | 必读 |
| 1 | 状态寄存器 | 链接状态、速度能力、自动协商完成 | 必读 |
| 2 | PHY 标识符 1 | OUI 高 16 位 | 必读 |
| 3 | PHY 标识符 2 | OUI 低 8 位 + 型号 + 版本 | 必读 |
| 4 | 自动协商广告能力 | 本端支持的工作模式 | 必读 |
| 5 | 自动协商伙伴能力 | 对端支持的工作模式 | 必读 |
| 6 | 自动协商扩展状态 | 协商结果、页交换 | 可选 |
| 7 | 下一页发送 | 用于自定义协议 | 可选 |
| 8~15 | 扩展状态/保留 | 部分芯片用于 EEE、节能 | 可选 |
我的经验:写初始化代码时,读 Reg2 和 Reg3 可以快速确认 PHY 型号。比如读出来是 0x2000 和 0x5C90,那八成是 IP101G 了。我踩过一个坑,板子上标的是 A 型号,但实际焊的是 B 型号,代码里写死了 ID 判断,结果死活不认。从那以后我都先用 MDIO 读一把确认。
4. 几个容易忽略的关键点
实际操作中,有几点值得特别留意:
- 自动协商(Auto Negotiation):不是每个网口都是固定的 100M 全双工。如果不协商,你没法知道对端支持什么。但如果你板子和交换机直连,也可以写死模式跳过协商,这样更稳定(曾经有客户要求这么做)。
- 链接状态检测:Reg1 的 bit2 是链接状态。我通常会循环读几次,排除抖动。有些芯片在 link down 后会有短暂的假 link up。
- MDIO 时钟频率:标准 MDC 最大 2.5MHz,但很多 PHY 可以跑到 25MHz。不过你想想看,跑快了可能时序不合格,特别是当你用 GPIO 模拟 MDC 时。我习惯用 1MHz 以下,稳。
注意:不要用空循环延时来产生 MDC 时序!不同编译器优化后会变。我建议直接用定时器或者硬件 I/O 翻转来保证时序稳定。
5. 寄存器操作的“潜规则”
不同厂商的 PHY,内部实现细节差异很大。比如 Broadcom 的 PHY 访问扩展寄存器需要先写一个页选择寄存器,而 Microchip 的 PHY 则是直接地址映射。嗯,这里要强调:永远先看数据手册的“寄存器映射”章节。
另外一个我常遇到的问题:写寄存器后读回确认。比如你写 Reg0 的 bit15 复位,不能马上读,PHY 复位需要时间。我一般是等个 100ms 再读状态。不然读回来的还是旧值,容易误判。
6. 小结(但不要期待总结)
这一章我们把 PHY 的底子讲清楚了。你记住了:PHY 就是物理层收发器,内部有 PCS/PMA/PMD,对外通过 MDIO 接口访问寄存器。寄存器分基本和扩展两大类,基本的前 16 个是通用的。调试时先读 ID 确认型号,再读链接状态,最后配置控制寄存器。
后面章节我们会用代码一步步演示:怎么发 MDIO 帧,怎么读寄存器,怎么写寄存器,怎么处理异常。但你得先把这章内容吃透,不然代码调起来会很痛苦。好了,拿起你的万用表和逻辑分析仪,我们准备动手!