PHY控制寄存器(CR):你第一个要掌握的寄存器
控制寄存器,英文叫 Control Register,也就是我们常说的 CR 寄存器。它的地址是 0x0,PHY 上电后的第一件事,往往就是读写它。
说实话,我做过不少 PHY 驱动,每次拿到新芯片,最先翻的就是 CR 寄存器。为什么?因为它管着 PHY 的“开关”和“模式”。你想想看,如果连这个都配不对,后边的眼图优化根本无从谈起。
CR 寄存器到底长什么样?
CR 寄存器是 16 位的,标准定义在 IEEE 802.3 第 22 条里。每个比特都有自己的使命。我整理了一张表,你直接看:
| 比特位 | 名称 | 说明 |
|---|---|---|
| 15 | Reset | 软件复位,写 1 复位 PHY,完成后硬件自动清 0 |
| 14 | Loopback | 环回模式,写 1 使能,用于诊断或调试 |
| 13 | Speed Select (LSB) | 与位 6 配合:00=10M, 01=100M, 10=1000M |
| 12 | Auto-Negotiation Enable | 自动协商使能,写 1 启动 |
| 11 | Power Down | 节电模式,写 1 进入休眠 |
| 10 | Isolate | 隔离模式,写 1 断开 MAC 与 PHY 的数据通路 |
| 9 | Restart Auto-Negotiation | 写 1 重新开始协商 |
| 8 | Duplex Mode | 0=半双工, 1=全双工 |
| 7 | Collision Test | 碰撞测试使能,用于测试 MII 接口 |
| 6 | Speed Select (MSB) | 与位 13 配合使用 |
| 5:0 | Reserved | 保留位,一般读回来为 0 |
你别被这 16 个比特吓到。实际上,日常配置只用其中几个。我个人习惯先记住三个关键位:复位(位 15)、自动协商使能(位 12)和速度双工选择(位 13、6、8)。其他位多数是调试时才碰。
软件复位:你必须等它完成
写 CR 位 15 为 1,就能让 PHY 软复位。但有个坑——我记得第一次做项目时,复位完立马去读另一个寄存器,结果读回来全是 0xFF。查了半天才发现,PHY 复位需要时间。
正确的做法是:
// 伪代码示例:安全软复位
phy_write(addr, 0x8000); // 写 CR 位 15=1
while (phy_read(addr) & 0x8000) {
// 等待位 15 清 0
delay_us(10);
}
嗯,这里要注意,有些 PHY 在复位期间不响应读操作。我曾遇到过一个芯片,复位后第一次读超时,加了重试才搞定。你写驱动时最好留个超时退出,别死等。
自动协商:开还是关?
这是个经典选择题。位 12 控制自动协商,位 9 是重启协商。我遇到的大多数项目,都要求开自动协商。但也不是的。
举个例子。我做某个交换机项目时,上位机要求必须强制 100M 全双工。我一开始开了自动协商,结果 PHY 和对方一直协商不成功,链路反复 UP/DOWN。后来关了自动协商,强制配死,问题就解决了。
配置自动协商,一般需要配合 AN 广告寄存器(寄存器 4)一起设。单独开位 12 不够,你得告诉 PHY 它支持哪些能力。这部分我后面会细讲。
速度与双工:两个比特决定一切
速度由位 13(LSB)和位 6(MSB)编码。双工由位 8 单独控制。组合起来就是:
| 位 13 | 位 6 | 速度 |
|---|---|---|
| 0 | 0 | 10 Mbps |
| 1 | 0 | 100 Mbps |
| 0 | 1 | 1000 Mbps |
| 1 | 1 | 保留 |
说白了,位 13 是速度的低位,位 6 是高位。你看到这个编码方式,可能会问:为什么不直接用一个 2 位字段?只能说,IEEE 标准就是这么定的,咱们只能照做。
我一般写驱动时,会用宏定义把常用组合预置好:
#define PHY_CR_10M_HALF 0x0000
#define PHY_CR_10M_FULL 0x0100
#define PHY_CR_100M_HALF 0x2000
#define PHY_CR_100M_FULL 0x2100
#define PHY_CR_1000M_FULL 0x4140 // 千兆必须全双工
环回与隔离:调试的利器
位 14 是环回。使能后,发送的数据直接 loop 回接收端,不经过网线。这是我最常用的调试手段。眼图不好时,先做个本地环回,能快速判断问题是出在 PHY 内部还是外部链路。
位 10 是隔离。打开后,PHY 和 MAC 之间的数据通路断开。这个模式一般用于多 PHY 系统,或者在测试时想单独看 PHY 的状态。
一张图理清 CR 寄存器配置流程
下面我把 CR 寄存器的核心操作画成一张流程图。你跟着它走一遍,基本就能搞定绝大多数场景了。
这张图基本覆盖了我平时配置 CR 的所有路径。你照着走,不太容易出错。
几个常见的坑
最后,我把我踩过的坑总结一下。你记住这些,能少走弯路:
- 复位后不要马上写。 我遇到过复位后立即写其他寄存器,结果 PHY 根本不响应。等复位位清 0 了再操作。
- 自动协商和手动模式不能混用。 开了 AN 却还去设速度双工位,有些 PHY 可以,有些会冲突。我建议你二选一。
- 读回检查很重要。 写完 CR 后,读回来确认一下。尤其是一些 PHY 的保留位会返回非 0 值,你写的时候要小心。
- 环回模式不能一直开着。 调试完了记得关掉。我曾有一次忘了关环回,上线后一直收不到对端数据,查了半天才发现。