驱动之路#40:I2C通信机制分析(RK3576视角)

描述

 在嵌入式开发中,I2C 应该算是出场率非常高的一种通信接口。像触摸芯片、PMIC、电源管理芯片、摄像头 sensor、RTC、EEPROM 等外设,很多都是通过 I2C 挂到主控上的。

调触摸驱动时,我们经常会看到类似这样的信息:

I2C通信

这里的 i2c2reg = <0x5d> 到底是什么意思?主控又是怎么通过两根线找到对应外设的?这篇就以 RK3576 为例,简单捋一捋 I2C 的通信机制。


1. I2C 是什么?

I2C,全称是 Inter-Integrated Circuit,直译过来就是“内部集成电路总线”。

不用纠结这个名字,简单理解就是:

I2C 是一种两线制串行通信协议,只需要两根线,就能实现主控和多个外设之间通信。

这两根线分别是:

  •  
  •  
SDA:Serial Data,串行数据线,用来传输数据;SCL:Serial Clock,串行时钟线,用来同步通信节奏。

也就是说,I2C 通信至少需要两根线:一根负责“说话”,一根负责“打节拍”。

I2C通信

在 RK3576 这类 SoC 中,I2C 控制器一般由主控内部提供,比如 I2C0、I2C1、I2C2 等。外部设备则挂在对应的 I2C 总线上。


2. I2C 通信像什么?

为了好理解,可以把 I2C 通信理解成 RK3576 发起的一次“点名对话”。

假设:

  •  
  •  
  •  
主机:RK3576从设备:GT911 触摸芯片设备地址:0x5d

整个过程大概是:

  •  
  •  
  •  
  •  
  •  
  •  
RK3576:大家注意,我要开始通信了!RK3576:地址是 0x5d 的设备在不在?GT911:在!RK3576:我要给你写数据 / 我要从你这里读数据。GT911:收到。RK3576:通信结束,总线释放。

I2C 协议看起来有点绕,但核心流程就是这么回事。


 

3. 起始信号:准备通信

I2C 通信开始前,主机会先发送一个起始信号,也就是 Start Condition

条件是:SCL 保持高电平期间,SDA 从高电平跳变为低电平。

这个动作的意思就是:总线上的外设注意,我要开始通信了。

此时挂在这条 I2C 总线上的所有从设备都会“听着”,等待后面的地址匹配。

这里有个关键点:
I2C 总线上,SDA 的变化不是随便什么时候都算有效。一般来说,只有在 SCL 为高电平时,SDA 的跳变才有特殊意义。

比如:

  •  
  •  
SCL 高电平时,SDA 高 -> 低:起始信号SCL 高电平时,SDA 低 -> 高:停止信号

而在数据传输过程中,SDA 通常会在 SCL 低电平期间准备数据,在 SCL 高电平期间保持稳定,供接收方采样。

这些时序一般由 RK3576 的 I2C 控制器自动处理,我们写驱动时通常不用手动去拉高拉低 SDA/SCL。


4. 从设备地址:喊谁谁应答

起始信号之后,RK3576 会发送从设备地址。

I2C 常见地址是 7bit,再加 1bit 读写控制位,组成 8bit 数据。

格式如下:

  •  
  •  
  •  
  •  
前 7 位:从设备地址最后 1 位:读写位0:写1:读

比如 GT911 的设备地址是 0x5d,那么 RK3576 会在总线上发出这个地址。

总线上所有从设备都会收到这个地址,但只有地址匹配的设备才会应答。这个应答信号叫 ACK

ACK 的表现是:接收方在第 9 个时钟周期,将 SDA 拉低。

也就是说,I2C 发送 1 个字节并不是只需要 8 个时钟,而是需要 9 个时钟:

  •  
  •  
前 8 个时钟:传输 8bit 数据第 9 个时钟:传输 ACK 应答

如果主机没有检测到 ACK,通常说明:

  •  
  •  
  •  
  •  
  •  
设备地址不对;设备没有上电;I2C 引脚配置不对;外设没有正常工作;总线硬件异常。

所以调 I2C 设备时,如果设备一直不应答,第一反应就应该去查地址、供电、复位、pinctrl、上拉电阻这些基础条件。


5. 数据传输:一个字节一个字节来

地址匹配成功后,就进入真正的数据传输阶段。

I2C 数据传输的单位是字节,也就是 8bit。

并且传输时遵循:高位在前,MSB first。

比如一个字节 0xA5,会从最高位 bit7 开始传。

根据读写位不同,通信方向也不同。

写操作

写操作是:RK3576 -> 从设备。比如主控给 GT911 写配置、写寄存器地址等。

过程大概是:

  •  
  •  
  •  
  •  
  •  
RK3576 发送 8bit 数据从设备回复 ACKRK3576 再发送下一个 8bit 数据从设备继续 ACK直到数据发送完成

读操作

读操作是:从设备 -> RK3576。比如主控读取触摸坐标、读取芯片 ID、读取状态寄存器等。

过程大概是:

  •  
  •  
  •  
  •  
  •  
从设备发送 8bit 数据RK3576 回复 ACK从设备继续发送下一个 8bit 数据RK3576 继续 ACK直到读取完成

以上这些通信细节,大部分由 I2C 控制器和 Linux I2C 子系统帮我们处理好了。我们写驱动时,更多是调用类似 i2c_transfer()i2c_smbus_read_byte_data() 这类接口,而不是手动模拟时序。


6. 停止信号:通信结束

数据传输完成后,主机会发送停止信号,也就是 Stop Condition

条件是:SCL 保持高电平期间,SDA 从低电平跳变为高电平。

这个动作表示:本次通信结束,总线释放。

停止信号发出后,从设备回到等待状态,RK3576 的 I2C 控制器也可以继续和其他外设通信。


 

7. I2C 的三个关键信号

通过前面的“点名对话”,可以总结出 I2C 通信里几个最关键的信号。

I2C通信

起始信号 S:SCL 为高电平期间,SDA 由高变低。表示开始通信。

应答信号 ACK:接收方收到 8bit 数据后,在第 9 个时钟周期拉低 SDA。表示数据已收到。

停止信号 P:SCL 为高电平期间,SDA 由低变高。表示通信结束。

理解这三个信号,基本就能看懂 I2C 通信的大致过程了。


8. I2C 地址冲突怎么办?

I2C 是一条总线上挂多个设备,因此每个从设备都需要有自己的地址。

但实际项目中,可能会遇到两个外设地址一样的情况。比如两个相同型号的触摸芯片,默认地址都一样,那就会冲突。

因为主机一喊 0x5d,两个设备都应答,总线就乱套了。针对这种情况,一般有两种解决办法。

方案一:挂到不同 I2C 控制器

RK3576 有多个通用 I2C 控制器,比如 I2C0、I2C1、I2C2 等。如果两个设备地址一样,可以把它们分别挂到不同的 I2C 总线上。

比如:

  •  
  •  
设备 A -> I2C2设备 B -> I2C3

这样虽然地址一样,但它们不在同一条总线上,就不会冲突。

方案二:修改从设备地址

有些外设支持通过硬件引脚配置地址。比如某些芯片可以通过拉高或拉低地址选择引脚,切换不同的 I2C 地址。这种情况下,只要硬件设计时把地址区分开,就能避免冲突。

所以画原理图时,I2C 地址一定要提前确认,不然后期调试会很难受。


9. 调试 I2C 时重点看什么?

实际调 I2C 外设时,不要一上来就怀疑驱动。

可以先按下面几个点查:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
[ ] 外设供电是否正常?[ ] reset / enable 引脚是否拉到正确电平?[ ] SDA / SCL 是否配置了正确 pinctrl?[ ] I2C 控制器节点 status 是否为 okay?[ ] 从设备 reg 地址是否正确?[ ] SDA / SCL 是否有上拉电阻?[ ] 是否存在地址冲突?[ ] i2cdetect 能否扫到设备?

很多 I2C 问题,最后都不是协议本身有多复杂,而是供电、复位、地址、pinctrl 这些基础条件没对上。


10. 总结

I2C 通信总结起来其实就是几个关键词:

  •  
  •  
  •  
  •  
  •  
两根线:SDA + SCL一个主机:RK3576多个从设备:触摸、PMIC、RTC、EEPROM 等三个信号:Start、ACK、Stop一个地址:通过从设备地址找到目标外设

整个过程就像主控在总线上点名:

  •  
开始通信 -> 发送地址 -> 等待应答 -> 读写数据 -> 停止通信

对于驱动开发来说,理解到这一层基本就够用了。再往下深挖,就是更底层的时序、电气特性、模拟电路和数字电路内容了。

I2C通信

那些当然也重要,但对大多数基于 SDK 做外设适配的开发者来说,先搞懂通信流程、地址匹配和 ACK 应答,已经足够解决大部分 I2C 调试问题。

(完)

下期继续聊:为什么 I2C需要上拉?


本人专注 Linux 嵌入式全栈开发,可提供从硬件方案评估与设计、Linux/Android BSP 适配、驱动开发、外设调试、系统移植到产品交付的全流程技术支持。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分