1. MDIO协议概述:起源、应用场景、与MDC的关系

各位好,欢迎来到《MDIO协议波形抓取与调试技巧》的第一章。

说实话,MDIO这协议,刚接触的人会觉得它很简单——两根线,串行,速率不高。嗯,确实比什么PCIe、DDR简单太多了。但我在项目中见过不少人在它上面栽跟头,尤其是做板级调试的时候,波形抓回来一看,咦,怎么数据老是对不上?

所以咱们先打好基础。这一章,我就带你把MDIO的来龙去脉、它到底干嘛用的、以及跟另一根线MDC是什么关系,彻底理清楚。

1.1 这协议是怎么来的?

MDIO,全称是Management Data Input/Output。它是IEEE 802.3标准里定义的一个串行管理接口。说白了,就是为了让MAC层(比如你的交换机芯片、CPU的以太网控制器)去配置和读取PHY芯片内部寄存器的。

你想想看,PHY芯片就像一个黑盒子,它工作在什么模式?千兆还是百兆?要不要开启自动协商?有没有检测到链路?这些问题,都得通过MDIO接口去问它或者告诉它。

我一直强调,学习一个协议,先要知道它为什么诞生。在早期,没有MDIO的时候,工程师只能靠一堆并行总线和跳线去控制PHY。后来大家发现这样太乱了,占引脚又太多,于是就统一了这套两线制的标准答案——也就是MDIO。它在1999年随IEEE 802.3u正式成为标准,一直沿用至今。

1.2 两根线的分工:MDIO和MDC

MDIO接口只有两根信号线:

信号名 方向 一句话解释
MDC 由MAC驱动给PHY 时钟信号。它给数据流提供节拍。
MDIO 双向(MAC↔PHY) 数据线。地址、控制字和状态数据都走这一根线。

我个人习惯把MDC想象成“心跳”,MDIO则是“说话的内容”。它们共同组成一个同步串行总线。MAC始终是主控方,它来驱动MDC时钟,并且发起所有的读或写操作。PHY芯片在MDC的节奏下,一位一位地往MDIO上读写数据。

小提示: 我建议你记一个要点。MDC最高支持到2.5MHz(某些标准里是12.5MHz,后面会讲)。它并不是高速时钟,但在做示波器抓波形时,采样率反而不能设得太高,否则容易抓到毛刺。我在实践中喜欢把采样深度设置成10倍于时钟周期,这样能完整看到一帧32位的数据。

1.3 它的帧结构是什么样子的?

搞懂MDIO,核心是要看懂它的帧格式。一帧数据在MDIO线上有特定的序列。我直接用一张表帮你拆解标准的32位帧结构(802.3规范里的Clause 22 模式):

字段名 位数 方向 说明
PRE 32 bits MAC→PHY 同步前导码,全部为1。「嘿,PHY,准备接收指令了」
ST 2 bits MAC→PHY 起始帧。Clause 22模式固定为01。
OP 2 bits MAC→PHY 操作码。10代表读,01代表写。
PHYAD 5 bits MAC→PHY PHY芯片地址。一条MDIO总线上最多挂32个设备。
REGAD 5 bits MAC→PHY 寄存器地址。每个PHY内部有32个寄存器可访问。
TA 2 bits 双向 转向时间。在写操作时是10;在读操作时,MAC把总线释放(高阻),PHY先拉Z0再拉0,具体是第一位高阻,第二位0。
DATA 16 bits 双向 数据字段。写操作时由MAC驱动,读操作时由PHY驱动。

重要: 有一种常见的802.3扩展模式叫Clause 45(帧格式不同),它支持更丰富的地址空间和类型。我们在本章先不讲Clause 45,后面调试技巧章节里会做对比。你得先把基础的Clause 22帧读透。

1.4 读与写的操作流程

我刚才说,MAC是总指挥。所有的读写都是它发起的。咱们来看看具体流程。

写操作流程:MAC先输出PRE(32个1),然后依次输出ST、OP(01表示写)、PHYAD、REGAD,然后是TA字段(此时MAC输出10),最后把16位数据放在MDIO线上。整个过程中,PHY一直处于监听状态,只在最后的DATA阶段被动收数据。

读操作流程:MAC一样先输出PRE、ST、OP(10表示读)、PHYAD、REGAD。关键点来了——TA字段。MAC在发完REGAD的最后一位后,把MDIO线释放掉(变成高阻),然后把控制权交给PHY。PHY会在下一个时钟周期主动拉低MDIO(驱动0),再在下一个周期输出16位数据。这中间如果时序不对或者TA不对,读回来的全是垃圾。

避坑指南: 我曾经遇到过一个项目,PHY芯片在REGAD地址之后,需要MAC额外增加一个空闲时钟周期才能切换驱动方向。结果呢?读回来的16位数据全部左移了1位。如果你在调试时发现读到的寄存器值看起来像是某个数值的两倍左右,优先检查TA区和GPIO/IO方向切换是否给了足够的延时。

1.5 电气特性与典型应用

这个接口的电气特性和电平逻辑,其实相当灵活。MDC和MDIO通常使用普通的GPIO引脚直接相连。电平由VDD决定,常见的是1.8V、2.5V或3.3V。我在实验室里也见过用OD门加上拉电阻的方式,这其实是为了支持多主设备(虽然很少用),标准里允许MDIO通过开漏输出多设备共享。

它主要用在什么地方?

  • 以太网交换机、路由器:CPU通过MDIO配置PHY芯片的速率、双工、EEE节能等。
  • 光模块:虽然现在光模块主流是I2C,但早期一些模块内部PHY仍使用MDIO。
  • FPGA开发板:你经常需要用软核或者硬核去控制PHY芯片,而MDIO正是那个唯一的配置通道。

1.6 本章知识核心关系图

为了让整体的知识结构更直观,我用一张SVG图把MDIO的物理层、帧结构、以及读写流程串起来。图上标了关键字段和方向。你留意一下TA字段的细节,那是整个读操作最容易被误解的地方。

MDIO协议核心要素架构图 物理层基础 • 两根线:MDC(时钟) • 两根线:MDIO(数据) • MAC主控,PHY从属 • 电平:1.8V / 2.5V / 3.3V • 最高时钟:2.5MHz • 支持OD门互联 *(Clause 22模式)* 帧结构(32位) PRE: 32'b全1(前导) ST: 2'b01(起始码) OP: 2'b10/01(操作码) PHYAD: 5 bits(设备地址) REGAD: 5 bits(寄存器地址) TA: 2 bits(总线转向) DATA: 16 bits(数据) ⬆ 最多32个PHY & 32个寄存器 读/写流程 写操作 MAC全程驱动MDIO TA = 10 输出16位数据 读操作 MAC释放MDIO (TA第一位) PHY驱动TA第二位=0 PHY输出16位数据 定义帧格式 驱动时序

1.7 为什么你需要学会看MDIO波形?

说到底,MDIO协议虽然简单,但它在板级调试中却是最快确认PHY芯片是否正常工作的手段。直接读一个寄存器,比如寄存器0(基本控制寄存器),如果ID读取正确,那说明硬件连接和时序基本没问题。反之,一旦读出来全是0xFF或者乱码,通常意味着MDC/MDIO的驱动电压不匹配、线序有误、或者是PHY地址设置错了。

练习思路: 我建议你尝试用逻辑分析仪抓一个MDIO读操作波形。先找到PRE前导码(一串连续的1),然后从那里数32个时钟,对照刚才的表看位顺序。不要只看整体,逐个字段核对。我记得第一次独立抓MDIO波形时,光确认TA字段就花了半天,后来发现是示波器的触发沿选反了。这些坑,咱们在调试章节里会细讲。