I²C总线卡死:先分清SCL拉低、SDA拉低,再谈9个时钟恢复

I²C总线卡死:先分清SCL拉低、SDA拉低,再谈9个时钟恢复

调试FPGA的I²C控制器时,最容易误判的现象是:状态机一直等ACK,于是直接加一段"发送9个时钟"的恢复逻辑。

先看引脚。SCL没有起来、SDA没有释放、控制器内部忙标志没有清除,是三条不同的排查路径。本文讨论单控制器、开漏加上拉的Standard/Fast-mode总线,不覆盖多控制器抢占、Hs/UFm或缓冲器专有恢复流程。

1. 先排除自己把总线拉住

FPGA控制SDA、SCL时,在本文场景下只做两件事:输出0,或者释放为高阻。高电平来自上拉,不能用推挽输出1去"顶开"低电平。

诊断前,停止新事务,让控制器有序退出驱动,并检查管脚复用和输出使能。然后同时观察输出使能与实际引脚输入:

  • SCL低:先追查时钟为什么没有释放,暂不进入9脉冲流程
  • SCL高、SDA低:才是下面重点讨论的数据线卡低
  • 两线均高:继续检查控制器状态、错误标志和驱动层,不能仅凭BUSY认定外部器件拉线

线与连接意味着,只要还有一个参与者拉低,引脚就不会高。内部"已经输出高"的状态位无法代替管脚回读。1

2. SCL低,可能仍在合法拉伸

时钟拉伸是目标器件保持SCL低,要求控制器等待。对于支持拉伸的系统,释放SCL后,应等输入确实为高,再开始计算有效高电平时间;否则分频计数器走完了,总线上却没有一个完整时钟。1

工程上需要有限等待,但超时值应根据器件手册、允许的处理延迟和系统故障策略确定。普通I²C没有一个可直接套到所有器件上的统一拉伸超时,不能把SMBus的规则照搬过来。

超时仅表示"系统不再继续等",还不能证明某颗器件损坏。检查目标器件是否支持拉伸、上拉和电源是否正常,以及电平转换器两侧的状态。SCL被持续拉低时,主控反复释放SCL也不会产生有效上升沿,所谓9次循环并不等于9个时钟。

NXP的Bus clear章节对此优先建议硬件复位;没有对应复位条件时再考虑器件电源复位。1 实际操作必须服从板级复位和供电设计,确认共享电源、掉电反灌和重新初始化的影响,不能把随意断电当通用处理。

3. SDA低:给未完成的传输补上时钟

一种可能是控制器复位了,目标器件仍停在发送数据0的阶段,等待后续时钟。毛刺也可能让两端计数不同步;TI给出的案例中,不同去毛刺滤波宽度使同一个窄脉冲只被一端识别。2

UM10204第3.1.16节针对SDA卡低给出的处理是发送9个时钟,目标器件应在这些时钟内释放SDA;仍未释放则转向硬件复位或电源复位。1 这是一条有失败分支的恢复路径,不保证解决短路、损坏或所有器件内部异常。

实现时先确认当前控制器独占总线,并让SDA保持释放。每个恢复脉冲都必须经历:拉低SCL、满足低电平时间、释放SCL、等待引脚实际变高、满足高电平时间,再拉低。脉冲计数依据实际完成的总线时序,不能只数寄存器写操作。

在9个脉冲的过程中观察SDA;如果任何一次等待SCL变高超时,就退出当前路径,记录为时钟受阻。不同缓冲器可能实现不同的恢复脉冲数,不能把某颗芯片的数据手册算法当作所有I²C设备的规则。3

4. 收尾的STOP也要看真实边沿

完成恢复时钟并确认SDA已经释放后,需要把当前传输收尾。为了明确生成STOP,可以先将SCL拉低,在低电平阶段拉低SDA,满足SCL低电平最小时长及SDA建立要求后,再释放SCL;等实际SCL变高并满足STOP建立时间后,释放SDA,确认它确实上升。

STOP的判据是"SCL高期间,SDA由低变高"。只把两个输出使能同时清零,无法保证出现这个顺序。也不要为了准备STOP,先在SCL高时把SDA拉低,那会先生成START。1

如果SDA仍被外部拉住,就不能宣称STOP成功。收尾后还应确认两线高电平及相应模式的总线空闲时间,再按控制器手册清理内部状态、重新发起事务。总线重新空闲也不代表之前的写操作已经成功,重试前要判断该操作能否安全重复。

5. 验证时至少覆盖这几种情况

下面是待执行的验证清单,不是已经完成的仿真或板测结果:

  1. 短时拉伸后释放SCL:等待期间不能推进位计数
  2. SCL持续低:有限超时退出,不能上报恢复成功
  3. SDA在恢复时钟内释放:随后产生可观察的STOP和空闲间隔
  4. 9个有效时钟后SDA仍低:返回失败,不能无限循环
  5. 生成STOP时SCL再次受阻:等待或超时,不能只按内部状态宣告结束
  6. 两线高但控制器仍忙:区分外部总线状态与内部状态

对于FPGA,输入同步和去毛刺逻辑也应纳入时序预算。仿真若只观察内部SCL信号、没有把外部拉低建模进去,就很容易漏掉拉伸问题;板上还要核对上升沿是否满足器件的电气要求,逻辑分析仪显示为高不等于模拟波形合格。

抓波形时,把引脚回读、开漏输出使能、等待计数、恢复脉冲计数和退出原因放在一起看。真正有用的结论是:哪条线没有释放、是否形成有效时钟、是否观察到STOP,以及失败后由谁接管处理。

基础读写流程可参照《I2C接口通信:从开漏总线到AT24C02读写》,本文的排查与恢复流程适合接在正常事务状态机之后单独设计。

参考资料

1 NXP UM10204 Rev. 7.0:3.1.1、3.1.4、3.1.9、3.1.16、4.2.2及第6节

2 TI:I2C Stuck Bus: Prevention and Workarounds:第2节

3 TI:What is Stuck Bus Recovery?:TCA4307的器件专有恢复示例

相关推荐
鸥梨菌Honevid5 小时前
STA 与 CDC
fpga开发
科恒盛远5 小时前
ZU902 与 FMC200 高速采集示波器实测
fpga开发
NamoAmitabha1286 小时前
日常问答1---deepseek
fpga开发
鸥梨菌Honevid7 小时前
异步FIFO为什么用打两拍的格雷码?
fpga开发
努力搬砖的小H8 小时前
FPGA应用技巧之AXI4-FULL-MASTER IP FDMA(Fast Direct Memory)详细介绍
经验分享·fpga开发·fdma·axi总线·米联客
szxinmai主板定制专家1 天前
电力边缘 AI 落地难点剖析:RK 系列 + FPGA 异构平台在储能监控终端的 EMC 与算力优化
人工智能·fpga开发·arm+fpga·rk3588+fpga
szxinmai主板定制专家1 天前
基于RK3588+FPGA+AI的储能电站边缘网关,实现电力数据采集与智能预警
arm开发·人工智能·fpga开发·rk3576·半导体设备
XMAIPC_Robot1 天前
储能控制器产品化:ARM+FPGA整机高低温、EMC可靠性测试实战总结
arm开发·人工智能·fpga开发·arm+fpga·rk3588+fpga