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 内部功能块和外部接口的关系。

PHY 芯片内部结构 + 寄存器空间 MAC (主控) MII / RMII PHY 芯片 (内部功能层) PCS PMA PMD MDIO 管理 MDC/MDIO 基本寄存器 (Reg 0~15) 控制、状态、ID、AN 等 IEEE 802.3 强制定义 扩展寄存器 (Reg 16~31) 厂商自定义,用于特殊功能 如 LED、EEE、环回控制 寄存器映射 注意 基本寄存器前 16 个 是所有 PHY 都必须 支持的“公共接口”

3. 寄存器分类与归纳

PHY 芯片内部控制全靠寄存器。IEEE 802.3 标准规定了前 16 个寄存器的地址和功能,也就是 Reg0 到 Reg15。剩下的 Reg16 到 Reg31 留给芯片厂商自己玩。

我个人觉得,搞懂这前 16 个寄存器,基本就能搞定 90% 的 PHY 调试问题。剩下的扩展寄存器,遇到具体芯片再看数据手册。

下面这张表,是我当年自己总结的,每次写驱动都对照着看:

地址 寄存器名称 主要功能 必读/可选
0控制寄存器复位、环回、速度选择、自动协商使能必读
1状态寄存器链接状态、速度能力、自动协商完成必读
2PHY 标识符 1OUI 高 16 位必读
3PHY 标识符 2OUI 低 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 帧,怎么读寄存器,怎么写寄存器,怎么处理异常。但你得先把这章内容吃透,不然代码调起来会很痛苦。好了,拿起你的万用表和逻辑分析仪,我们准备动手!