1. 项目概述与MDIO核心价值
如果你正在基于TI的AM64x或AM243x这类高性能工业处理器设计网络设备,无论是工业交换机、网关还是车载通信单元,那么你迟早要和MDIO(Management Data Input/Output)打交道。这看起来只是一个简单的两线串行总线,但在实际的嵌入式网络开发中,它却是连接主控芯片(MAC)与物理层收发器(PHY)的“神经系统”。没有它,你的设备可能就无法感知网络链路是通是断,无法配置PHY的工作模式,更谈不上进行复杂的网络管理。
MDIO协议,或者说MII管理接口,其本质是一种低速、同步的串行通信协议。它通过一根时钟线(MDC)和一根双向数据线(MDIO),让主设备(比如我们芯片里的PRU)能够访问多达32个从设备(PHY芯片)的内部寄存器。每个PHY芯片内部都有几十甚至上百个寄存器,用来控制从自协商、环回测试到功耗管理的一切。在AM64x/AM243x的PRU_ICSSG(可编程实时单元与工业通信子系统)中,TI将MDIO控制器硬件化,并通过一组精心设计的内存映射寄存器暴露给开发者。这意味着,你不再需要像在早期软件bit-bang模拟MDIO时序那样小心翼翼,而是可以通过直接读写寄存器,以更高的效率和可靠性完成PHY管理任务。
理解这套寄存器,特别是PRU_MDIO模块的寄存器配置,是打通从处理器到物理层“最后一公里”的关键。它直接决定了你的设备能否正确识别网络拓扑、快速响应链路变化,以及是否支持更先进的Clause 45管理功能。接下来,我将结合手册内容和实际调试经验,为你拆解这套寄存器地图,并分享如何在实际驱动中高效、稳定地使用它们。
2. MDIO寄存器框架与寻址机制解析
拿到一份技术参考手册,面对几十个寄存器,第一步不是一头扎进去,而是先理清框架。AM64x/AM243x的PRU_MDIO模块寄存器位于PRU_ICSSG子系统的地址空间内。根据手册,我们看到有两个独立的实例:PRU_ICSSG0_PR1_MDIO_V1P7_MDIO和PRU_ICSSG1_PR1_MDIO_V1P7_MDIO,基地址分别为0x3003_2400和0x300B_2400。这通常对应芯片内两个独立的PRU子系统,每个都可以独立管理一组MDIO总线上的PHY设备。
所有寄存器的访问都是基于这个基地址的偏移量(Offset)。例如,控制寄存器MDIO_CONTROL_REG的偏移是0x4,那么对于ICSSG0实例,它的完整物理地址就是0x3003_2400 + 0x4 = 0x3003_2404。在编写底层驱动时,我们通常会将这些基地址和偏移量定义为宏或常量,或者通过芯片的SOC配置模块动态获取。
注意:手册中明确提到,所有未在表中列出的偏移地址都是保留位置,其内容不应被修改。这是一个非常重要的安全提示。在操作寄存器时,务必严格遵循“读-修改-写”的原则,即先读取整个寄存器的值,只修改目标位域,然后再写回。盲目地向未知或保留位写入数据,轻则导致功能异常,重则可能引发不可预知的硬件行为。
寄存器的位域设计体现了模块的功能划分。整体上,我们可以将这些寄存器分为几大类:
- 全局控制与状态类:如
MDIO_CONTROL_REG(使能、时钟分频)、MDIO_VERSION_REG(版本查询)。 - PHY状态监控类:如
MDIO_ALIVE_REG(PHY在线状态)、MDIO_LINK_REG(链路状态)。 - 中断管理类:一个完整的“RAW-MASKED-SET-CLEAR”四件套,分别用于链路状态变化(
MDIO_LINK_INT_*)和用户命令完成(MDIO_USER_INT_*)。 - 用户访问接口类:核心的
MDIO_USER_ACCESS_REG_j和MDIO_USER_PHY_SEL_REG_j,用于发起具体的PHY读写操作。 - 轮询与模式控制类:如
MDIO_POLL_REG、MDIO_POLL_EN_REG、MDIO_CLAUS45_REG,用于配置后台自动轮询和协议模式。 - 手动调试接口:
MDIO_MANUAL_IF_REG,用于直接操控MDC和MDIO引脚,常用于底层调试和故障排查。
理解这个分类,有助于我们在编程时快速定位需要的寄存器,而不是在列表中盲目搜索。
3. 核心控制寄存器详解与配置实战
3.1 模块使能与时钟配置:MDIO_CONTROL_REG
这是MDIO模块的“总开关”。其位域丰富,我们逐一拆解:
- IDLE (Bit 31):这是一个只读状态位。当MDIO状态机空闲,没有进行任何读写操作时,该位为1。在发起任何用户访问(写
GO位)之前,检查此位是否为1是一个好习惯,可以确保状态机就绪。 - ENABLE (Bit 30):模块使能位。这是需要首先配置的位。向此位写1使能MDIO状态机,写0则禁用。手册特别强调:如果状态机正在执行操作时被禁用,它会完成当前操作后再停止并设置IDLE位。此外,如果使用字节访问(8位)方式写此寄存器,ENABLE位必须是最后写入的位。这是因为某些位(如CLKDIV)的更改可能需要状态机处于稳定状态。
- CLKDIV (Bit 15-0):时钟分频器。这是配置MDC时钟频率的关键。公式为:MDCLK频率 = 输入时钟频率 / (CLKDIV + 1)。输入时钟频率需要查阅芯片数据手册,通常与PRU的子系统时钟相关。例如,如果输入时钟为250MHz,我们需要MDC时钟为2.5MHz(MDC典型频率范围在DC-2.5MHz),那么CLKDIV应设置为 (250 / 2.5) - 1 = 99。特别注意:当CLKDIV设置为0时,MDCLK输出将被禁用。通常复位后默认值为0xFF,即最大分频,需要根据实际需求调整。
配置示例与避坑指南: 假设我们需要在250MHz输入时钟下,产生约1.25MHz的MDC时钟,并启用模块。操作步骤如下:
- 计算CLKDIV:
(250 / 1.25) - 1 = 199。 - 采用“读-修改-写”操作。先读取
MDIO_CONTROL_REG的当前值。 - 清除ENABLE位(确保在配置期间模块禁用是一个安全做法),设置CLKDIV字段为199,并可以根据需要设置其他位(如
FAULT_DETECT_ENABLE)。 - 关键步骤:如果使用32位访问,直接写入新值即可。如果使用8位访问(例如通过某些字节寻址的接口),必须确保最后一个写入的字节包含ENABLE位(且其值为1)。更稳妥的做法是始终使用32位访问来操作此寄存器。
// 假设 reg_base 是 MDIO 模块的基地址 volatile uint32_t *control_reg = (volatile uint32_t *)(reg_base + 0x04); uint32_t ctrl_value = *control_reg; // 读取当前值 // 清除ENABLE,设置CLKDIV=199,使能故障检测 ctrl_value &= ~(1 << 30); // 清除ENABLE (Bit 30) ctrl_value &= ~(0xFFFF); // 清除低16位 (CLKDIV) ctrl_value |= (199 & 0xFFFF); // 设置CLKDIV ctrl_value |= (1 << 18); // 设置 FAULT_DETECT_ENABLE (Bit 18) // 先写入配置(此时ENABLE=0) *control_reg = ctrl_value; // 最后,单独置位ENABLE(或者重新组合一个ENABLE=1的值写入) ctrl_value |= (1 << 30); *control_reg = ctrl_value;3.2 PHY状态获取:ALIVE与LINK寄存器
这两个寄存器是系统监控网络物理连接状态的窗口。
- MDIO_ALIVE_REG:这是一个32位的寄存器,每个位对应一个PHY地址(0-31)。当最近一次对某个PHY地址的访问(无论是用户手动访问还是轮询访问)得到了PHY的确认(ACK),对应的位就会被置1。如果访问失败(无ACK),该位被清零。这是一个“粘性”状态寄存器,位一旦被置1,会保持直到你主动写1清除它(写0无效)。这非常有用,例如在系统启动时,可以快速扫描0-31地址,通过读取此寄存器一次性获取所有在线PHY的地址,而无需逐个进行耗时且可能失败的读操作。
- MDIO_LINK_REG:同样是一个32位寄存器,每个位对应一个PHY地���。该寄存器在MDIO模块对PHY的通用状态寄存器(通常为寄存器1)进行轮询读取后被更新。如果读取成功且PHY报告链路已建立(Link Up),则对应位置1;如果读取失败或PHY报告链路断开(Link Down),则对应位置0。注意:此寄存器的更新依赖于轮询机制或手动读取PHY状态寄存器的操作,它不是实时反映硬件引脚状态的。另一种获取特定PHY链路状态的方式是通过
MDIO_USER_PHY_SEL_REG_j配置,使用MLINK硬件引脚(如果PHY支持并连接了此引脚)。
实操心得: 在驱动初始化时,我通常会先使能MDIO模块,然后利用MDIO_ALIVE_REG进行PHY地址扫描。为了提高效率,可以先将MDIO_POLL_EN_REG全部置位(使能所有地址轮询),等待几十毫秒让模块完成一轮扫描,然后读取MDIO_ALIVE_REG,就能得到一张“PHY在线位图”。之后,可以根据这个位图,有针对性地配置MDIO_POLL_EN_REG,只轮询实际存在的PHY,减少总线负载。MDIO_LINK_REG则更适合在链路状态中断服务程序(ISR)中读取,以快速判断是哪个PHY的链路发生了变化。
4. 用户访问流程与寄存器操作详解
这是MDIO模块最核心的主动操作部分,即由处理器发起对特定PHY特定寄存器的读写。
4.1 访问通道与地址寄存器
AM64x/AM243x的PRU_MDIO提供了两个独立的用户访问通道(j=0和1),对应MDIO_USER_ACCESS_REG_0和MDIO_USER_ACCESS_REG_1。这意味着你可以预先设置好两个访问任务,或者进行简单的流水线操作。每个通道都关联着一个MDIO_USER_PHY_SEL_REG_j和一个MDIO_USER_ADDRx_REG。
MDIO_USER_PHY_SEL_REG_j:主要用于配置该通道所监控的PHY(用于链路中断)。PHYADR_MON字段指定要监控链路状态的PHY地址。LINKINT_ENABLE位用于使能该PHY的链路变化中断。LINKSEL位选择链路状态是通过MDIO读取获取(0)还是通过MLINK硬件引脚获取(1)。MDIO_USER_ADDR0/1_REG:仅在Clause 45模式下有效。在Clause 45协议中,访问一个寄存器需要两步:先发送一个“地址”帧(指定MMD和寄存器地址),再发送“数据”帧进行读写。这个“地址”帧的内容就由USER_ADDRx寄存器指定。在Clause 22模式下,此寄存器无用。
4.2 核心操作寄存器:MDIO_USER_ACCESS_REG_j
这是发起读写操作的命令寄存器。它的位域清晰定义了一次MDIO事务的所有要素:
| 位域 | 名称 | 描述与操作要点 |
|---|---|---|
| 31 | GO | 触发位。写1启动此次MDIO访问。此位会在操作完成后自动清零。关键:当GO位为1时,对该寄存器的其他位进行写操作会被阻塞。因此,标准的操作流程是:先配置好其他所有字段(PHY地址、寄存器地址、数据、读写方向),最后再写GO位。 |
| 30 | WRITE | 方向位。1=写操作,0=读操作。 |
| 29 | ACK | 状态位(只读)。当一次读操作完成后,如果PHY正常应答,此位会被硬件置1;如果超时或无应答,则为0。这是判断操作成功与否的直接标志。 |
| 25-21 | REGADR | 寄存器地址。在Clause 22模式下,这就是PHY芯片内部寄存器的地址(0-31)。在Clause 45模式下,这个字段代表的是MMD(管理数据设备)编号。 |
| 20-16 | PHYADR | PHY地址。总线上目标PHY的5位地址(0-31)。 |
| 15-0 | DATA | 数据字段。对于写操作,这是要写入PHY寄存器的值;对于读操作,当GO位清零且ACK为1后,这里存放着从PHY读回的数据。 |
4.3 完整的PHY寄存器读写流程
下面以一个具体的例子说明如何读取PHY地址为1的芯片的标识符寄存器(Clause 22,寄存器地址2)。
步骤1:配置并等待通道空闲在发起新操作前,最好检查目标通道的GO位是否已清零(即上一次操作已完成)。虽然硬件会串行化请求,但显式等待可以避免状态混乱。
步骤2:填充命令寄存器(除GO位)
volatile uint32_t *user_access_reg = (volatile uint32_t *)(reg_base + 0x80); // 通道0 uint32_t cmd = 0; cmd &= ~(1 << 30); // 确保 WRITE=0, 读操作 cmd &= ~(0x1F << 16); // 清除 PHYADR 字段 cmd |= (1 << 16); // 设置 PHYADR = 1 cmd &= ~(0x1F << 21); // 清除 REGADR 字段 cmd |= (2 << 21); // 设置 REGADR = 2 (PHY ID1) // DATA 字段在读操作发起时无需设置 *user_access_reg = cmd; // 此时GO位为0,写入配置步骤3:启动操作并等待完成
// 设置GO位,启动操作 *user_access_reg = cmd | (1 << 31); // 轮询等待GO位清零 while (*user_access_reg & (1 << 31)) { // 可以加入超时机制,避免死等 } // 操作完成,检查ACK位 if (*user_access_reg & (1 << 29)) { // 读取数据 uint16_t phy_id_high = (*user_access_reg) & 0xFFFF; printf("PHY ID1: 0x%04X\n", phy_id_high); } else { printf("MDIO read failed (No ACK) for PHY 1, REG 2.\n"); }步骤4:Clause 45模式下的操作Clause 45操作需要两步。假设我们要访问MMD 3 下的寄存器 0x400A。
- 设置
MDIO_CLAUS45_REG对应PHY地址的位为1,切换到Clause 45模式。 - 地址帧:配置
MDIO_USER_ADDR0_REG为0x400A,然后发起一次“写”操作(WRITE=1),但此时DATA字段内容无关紧要(通常为0),GO=1。这个操作的目的不是写数据,而是将地址0x400A写入PHY的地址寄存器。 - 数据帧:保持Clause 45模式,使用
MDIO_USER_ACCESS_REG_j进行正常的读写操作。此时REGADR字段应设置为MMD编号(本例为3)。
重要提示:在Clause 45操作中,两次MDIO事务之间需要一定的间隔。硬件状态机或软件驱动需要确保前一次地址帧操作完成(GO位清零)后,再发起后续的数据帧操作。此外,切换PHY的Clause模式(通过
MDIO_CLAUS45_REG)可能需要在PHY复位后进行,具体需参考PHY芯片的数据手册。
5. 中断与轮询机制深度解析
高效的PHY管理离不开异步事件通知。PRU_MDIO模块提供了两套中断系统:链路状态变化中断和用户命令完成中断。
5.1 中断寄存器组结构
每一类中断都遵循相同的“四寄存器”管理模式,这是TI外设中常见且优雅的设计:
- RAW寄存器(
MDIO_*_INT_RAW_REG):这是原始中断状态寄存器。当事件(如链路变化、命令完成)发生时,对应的位会被硬件置1。无论中断是否被屏蔽(Mask),RAW位都会置位。向该位写1可以清除它。 - MASKED寄存器(
MDIO_*_INT_MASKED_REG):这是被屏蔽后的中断状态寄存器。只有当RAW位为1,且对应的中断使能位(在MASK_SET寄存器或相关配置寄存器中)也为1时,MASKED寄存器的对应位才为1。这个寄存器的值直接驱动芯片输出到PRU或主机的中断信号线。同样,写1清除。 - MASK_SET寄存器(
MDIO_*_INT_MASK_SET_REG):向某位写1,使能对应的中断(即允许该中断事件传递到MASKED寄存器)。 - MASK_CLEAR寄存器(
MDIO_*_INT_MASK_CLEAR_REG):向某位写1,禁用对应的中断。
这种设计使得中断管理非常灵活和安全。你可以在任何时候查询RAW寄存器了解所有发生的事件,而通过配置MASK_SET/CLEAR来精确控制哪些事件能触发CPU中断。
5.2 链路变化中断配置
链路中断有两种工作模式,由MDIO_POLL_REG的STATECHANGEMODE位决定:
- 普通模式 (STATECHANGEMODE=0):中断基于
MDIO_USER_PHY_SEL_REG_j的配置。你需要在该寄存器中指定要监控的PHY地址(PHYADR_MON),并使能链路中断(LINKINT_ENABLE=1)。当该PHY��链路状态(存储在MDIO_LINK_REG中)发生变化时,对应通道(j)的链路中断RAW位会置位。这种方式可以精确监控特定PHY。 - 状态改变模式 (STATECHANGEMODE=1):此模式下,任何PHY的
MDIO_ALIVE_REG或MDIO_LINK_REG位发生变化(由于任何MDIO操作引起),都会导致LINKINTRAW[0]置位。你需要通过MDIO_LINK_INT_MASK_SET_REG来使能这个全局中断。这种模式用于需要感知总线上任何PHY状态变化的场景。
配置示例(普通模式,监控PHY地址1的链路变化):
// 1. 配置 PHY_SEL 寄存器,选择PHY 1并使能中断 volatile uint32_t *phy_sel_reg = (volatile uint32_t *)(reg_base + 0x84); // 通道0的PHY_SEL *phy_sel_reg = (1 << 6) | (1 & 0x1F); // LINKINT_ENABLE=1, PHYADR_MON=1, LINKSEL=0 // 2. (可选)清除可能存在的原始中断标志 volatile uint32_t *link_int_raw = (volatile uint32_t *)(reg_base + 0x10); *link_int_raw = 0x3; // 写1清除 bit0 和 bit1 // 3. 确保中断在MASK_SET层面是使能的(通常复位后为0,需要设置) // 注意:在普通模式下,MDIO_LINK_INT_MASK_SET_REG 不使用,中断使能由 PHY_SEL 寄存器的 LINKINT_ENABLE 位控制。 // 但需要确保 MDIO_CONTROL_REG 中的 INT_TEST_ENABLE 为 0(正常模式)。5.3 用户命令完成中断配置
当通过MDIO_USER_ACCESS_REG_j发起的读写操作完成时,会触发用户命令完成中断。这对于实现非阻塞的、异步的PHY管理非常有用。
配置步骤:
- 在发起用户访问命令前,先使能对应通道的中断。例如,要使能通道0的中断:
volatile uint32_t *user_int_mask_set = (volatile uint32_t *)(reg_base + 0x28); *user_int_mask_set = 0x1; // 设置 bit0,使能通道0的中断 - 配置并启动MDIO用户访问(设置
GO位)。 - 在PRU或主机的中断服务程序(ISR)中,读取
MDIO_USER_INT_MASKED_REG来确定是哪个通道的操作完成了(例如,bit0为1表示通道0完成)。 - 在ISR中,向
MDIO_USER_INT_MASKED_REG的对应位写1以清除中断标志,然后读取MDIO_USER_ACCESS_REG_j中的DATA字段(读操作)或检查ACK位。
5.4 自动轮询机制
除了手动访问,MDIO模块还支持后台自动轮询,用于定期检查PHY的链路状态并更新MDIO_LINK_REG。相关寄存器有:
MDIO_POLL_EN_REG:32位,每位对应一个PHY地址。置1则启用对该PHY的轮询。MDIO_POLL_REG:包含IPG字段(位7-0),用于设置两次轮询操作之间的MDCLK时钟间隔数。MANUALMODE位用于切换到手動模式(直接控制引脚)。
轮询配置建议: 在系统初始化并识别出在线PHY(通过MDIO_ALIVE_REG)后,只对在线PHY地址对应的MDIO_POLL_EN_REG位进行置位。根据网络稳定性和响应速度要求设置合理的IPG值。过短的间隔会增加总线负载,过长的间隔则会延迟链路状态变化的检测。同时,可以结合链路变化中断,实现事件驱动的链路状态管理,而不是单纯依赖软件轮询MDIO_LINK_REG。
6. 调试技巧与常见问题排查
在实际开发中,MDIO通信失败是常见问题。以下是一些排查思路和利用PRU_MDIO寄存器进行调试的技巧。
6.1 基础通信检查清单
- 物理连接:确认MDC和MDIO两根线是否正确连接到PHY,上拉电阻是否已安装(通常需要)。用示波器测量MDC是否有时钟输出,MDIO线上是否有数据波形。
- 时钟配置:确认
MDIO_CONTROL_REG中的CLKDIV设置是否正确。MDC频率是否在PHY芯片支持的范围内(通常最高2.5MHz)?频率过高会导致通信失败。 - 模块使能:确认
ENABLE位已置1,并且IDLE位在发起操作前为1。 - PHY地址:确认
PHYADR字段设置是否正确。许多PHY的默认地址是0或1,但也可能通过硬件引脚配置为其他地址。 - Clause模式:确认
MDIO_CLAUS45_REG的设置与目标PHY和要访问的寄存器匹配。访问Clause 45寄存器必须使用Clause 45模式。
6.2 利用寄存器进行诊断
MDIO_ALIVE_REG是“探测仪”:在怀疑通信不通时,尝试读取此寄存器。如果对应PHY地址的位始终为0,说明MDIO模块从未成功与该PHY完成过一次帧交换。问题可能出在物理层、PHY地址或PHY本身未上电/复位。ACK位是“应答指示器”:在用户访问后,检查MDIO_USER_ACCESS_REG_j的ACK位。如果为0,表示PHY没有应答。可能的原因包括:PHY地址错误、PHY处于复位或功耗模式、MDIO总线冲突、时钟速率不兼容。FAULT位是“物理层警报”:如果使能了FAULT_DETECT_ENABLE,当MDIO模块驱动到MDIO线上的电平与读回的电平不一致时,FAULT位会被置1。这强烈暗示物理层问题,如短路、断路或上拉/下拉电阻配置错误。- 手动模式 (
MDIO_MANUAL_IF_REG) 是“终极调试工具”:当自动状态机怎么都不工作时,可以尝试切换到手动模式。设置MDIO_POLL_REG的MANUALMODE=1,然后通过MDIO_MANUAL_IF_REG直接控制MDIO_MDCLK_O和MDIO_PIN,并读取MDIO_PIN的输入值。你可以用软件模拟完整的MDIO读写帧,从而排除硬件状态机的逻辑问题,精确定位是读、写、时钟还是数据线的问题。这是验证MDIO总线物理连接和基本PHY响应能力的有效方法。
6.3 典型问题与解决方案速查表
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 读取任何PHY寄存器都失败,ACK始终为0 | 1. MDIO模块未使能。 2. MDC时钟频率异常或未输出。 3. PHY硬件连接问题或未供电。 4. PHY处于复位状态。 | 1. 检查MDIO_CONTROL_REG的ENABLE和IDLE位。2. 检查 CLKDIV配置,用示波器测MDC。3. 检查电源、复位引脚、MDIO线上拉电阻。 4. 检查PHY的复位引脚时序,确保PHY已脱离复位。 |
| 能读到某些PHY,但读不到另一些 | 1. PHY地址配置错误。 2. 总线上的PHY地址冲突。 3. 个别PHY损坏或配置特殊。 | 1. 使用MDIO_ALIVE_REG扫描所有32个地址,确认在线PHY。2. 检查硬件电路,确保每个PHY的地址设置引脚(如PHYAD[4:0])电平正确且唯一。 |
| Clause 22访问正常,Clause 45访问失败 | 1.MDIO_CLAUS45_REG对应位未设置。2. Clause 45的两步操作时序不对。 3. PHY不支持Clause 45或需要特殊使能。 | 1. 确认已设置目标PHY的CLAUSE45位为1。2. 确保地址帧操作(写 USER_ADDRx_REG)完成(GO位清零)后再发起数据帧操作。3. 查阅PHY数据手册,确认其Clause 45功能是否默认开启。 |
| 链路状态中断不触发 | 1. 中断未使能(LINKINT_ENABLE或MASK_SET)。2. 轮询未开启( POLL_EN)。3. 工作模式设置错误( STATECHANGEMODE)。4. 中断服务程序未正确清除标志。 | 1. 根据模式检查LINKINT_ENABLE或LINK_INT_MASK_SET_REG。2. 确认 MDIO_POLL_EN_REG对应位已置位。3. 确认 STATECHANGEMODE与中断配置匹配。4. 在ISR中读取 MDIO_LINK_INT_MASKED_REG并写1清除对应位。 |
| 用户命令完成中断不触发 | 1.USERINTMASKSET未配置。2. 操作完成后未及时读取数据/清除标志,导致后续中断被淹没。 3. 中断信号线(如PRU中断)未正确映射或使能。 | 1. 操作前确认已通过MDIO_USER_INT_MASK_SET_REG使能中断。2. 在ISR中必须读取 MDIO_USER_ACCESS_REG_j(以获取数据)并清除USERINTMASKED标志。3. 检查PRU的INTC(中断控制器)配置,确保MDIO用户中断已映射到正确的系统事件并已使能。 |
调试MDIO这类低速总线,耐心和系统性很重要。从电源、时钟、复位等基础信号查起,再到软件配置,利用好模块提供的状态寄存器,大部分问题都能被定位和解决。