rk3288 I2C-原理学习

I2C介绍

I2C硬件框架

rk3288 I2C-原理学习

  • 一个Soc一般有多个I2C接口,一条I2C总线上,可以挂载一个或多个I2C设备,I2C设备用地址区分。
  • I2C总线上,有两条线,一条是SCL时钟线,一条是SDA线,这两条线上都有上拉电阻

I2C软件框架

rk3288 I2C-原理学习

  • App:不关心底层实现细节,只需要调用设备驱动程序提供的接口。
  • 芯片驱动:知道芯片要求的地址、数据格式;知道怎么发出信号才能让芯片工作,一些芯片特定的工作状态;构造好数据结构给I2C控制器。
  • I2C控制器驱动:根据I2C协议发出各类信号,I2C设备地址、I2C存储地址、数据;根据I2C协议判断数据

I2C协议学习

I2C协议

I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生。
起始和结束信号产生条件:总线在空闲状态时,SCL和SDA都保持着高电平,当SCL为高电平而SDA由高到低的跳变,表示产生一个起始条件;当SCL为高而SDA由低到高的跳变,表示产生一个停止条件。
rk3288 I2C-原理学习
传输数据流程:数据传输以字节为单位,主设备在SCL线上产生每个时钟脉冲的过程中将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位, 此时才认为一个字节真正的被传输完成
rk3288 I2C-原理学习
主设备在传输有效数据之前需要先指定从设备地址,地址指定过程和上面数据传输过程一样,只不过大多数从设备的地址是7位,协议规定添加一个最低位,用来表示数据传输方向,0表示主设备向从设备写数据1表示主设备向从设备读数据
指定设备发送数据的格式,如下图所示,(每一最小包数据由9bit组成,8bit内容+1bit ACK, 如果是地址数据,则8bit包含1bit方向)
rk3288 I2C-原理学习

主设备往从设备写数据

rk3288 I2C-原理学习

主设备往从设备读数据

rk3288 I2C-原理学习

主设备往从设备写数据,重启起始条件,然后往从设备读取数据

rk3288 I2C-原理学习

SMBUS协议

SMBus最初的目的是为了智能电池、充电电池、其他微控制器之间的通信链路而定义的。
SMBus为系统和电源管理这样的任务提供了一条控制总线,使用SMBus的系统,设备之间发送和接手消息都是通过SMBus,而不是使用单独的控制线,这样可以节省设备管脚数。SMBus是I2C协议的子集。

  • Linux内核文档:Documentation\i2c\smbus-protocol.rst
  • SMBus协议: http://www.smbus.org/specs/
  • 因为很多设备都实现了SMBus,而不是更宽泛的I2C协议,所以优先使用SMBus。 即使I2C控制器没有实现SMBus,软件方面也是可以用I2C协议来模拟SMBus。 所以:Linux建议优先使用SMBus
I2C SMBus
VDD 范围很广,0~12v 1.8V~5V
最小时钟频率 时钟频率最小值无限制 时钟频率最小值是10KHz
最大的Clock Stretching1 没有限制 有限制
地址回应(Address Acknowledge) 没有强制要求必须发出回应信号 强制要求必须发出回应信号2
数据的传输格式 只定义了如何传输数据,格式由设备定义 定义了几种数据格式(后面分析)
重复发出S信号(REPEATED START Condition) 需要发送S信号 可以不发出P信号,而是直接发出S信号3
低功耗版本( Low Power Version)

1. symbol符号

  • S (1 bit) : Start bit(开始位)
  • Sr (1 bit) : 重复的开始位
  • P (1 bit) : Stop bit(停止位)
  • R/W# (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.(读写位)
  • A, N (1 bit) : Accept and reverse accept bit.(回应位)
  • Address(7 bits): I2C 7 bit address. Note that this can be expanded as usual to get a 10 bit I2C address.(地址位,7位地址)
  • Command Code (8 bits): Command byte, a data byte which often selects a register on the device.(命令字节,一般用来选择芯片内部的寄存器)
  • Data Byte (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh for 16 bit data.(数据字节,8位;如果是16位数据的话,用2个字节来表示:DataLow、DataHigh)
  • Count (8 bits): A data byte containing the length of a block operation.(在block操作中,表示数据长度)
    adapter.
    (中括号表示I2C设备发送的数据,没有中括号表示host adapter发送的数据)

2. SMBus Quick Command Protocal

rk3288 I2C-原理学习
只是用来发送一位数据:R/W#本意是用来表示读或写,但是在SMBus里可以用来表示其他含义。 比如某些开关设备,可以根据这一来决定是打开还是关闭。

Functionality flag4: I2C_FUNC_SMBUS_QUICK

3. SMBus Receive Byte

rk3288 I2C-原理学习
I2C-tools中的函数:i2c_smbus_read_byte(),读取一个字节,Host adapter接收到一个字节后不需要发出回应信号(上图中N表示不回应)。
Functionality flag4: I2C_FUNC_SMBUS_READ_BYTE

4. SMBus Send Byte

rk3288 I2C-原理学习
I2C-tools中的函数:i2c_smbus_write_byte(), 发送一个字节
Functionality flag4: I2C_FUNC_SMBUS_WRITE_BYTE

5. SMBus Read Byte

rk3288 I2C-原理学习I2C-tools中的函数:i2c_smbus_read_byte_data()。 先发出Command Code(它一般表示芯片内部的寄存器地址),再读取1个字节的数据。 上面介绍的SMBus Receive Byte是不发Comand,直接读取数据。
Functionality flag4: I2C_FUNC_SMBUS_READ_BYTE_DATA

6. SMBus Read Word

rk3288 I2C-原理学习I2C-tools中的函数:i2c_smbus_read_word_data()。先发出Command Code(它一般表示芯片内部的寄存器地址),再读取2个字节的数据。
Functionality flag4: I2C_FUNC_SMBUS_READ_WORD_DATA

7. SMBus Write Byte

rk3288 I2C-原理学习
I2C-tools中的函数:i2c_smbus_write_byte_data()。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出1个字节的数据。
Functionality flag4: I2C_FUNC_SMBUS_WRITE_BYTE_DATA

8. SMBus Write Word

rk3288 I2C-原理学习
I2C-tools中的函数:i2c_smbus_write_word_data()。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出1个字节的数据。
Functionality flag4: I2C_FUNC_SMBUS_WRITE_WORD_DATA

9. SMBus Block Read

rk3288 I2C-原理学习I2C-tools中的函数:i2c_smbus_read_block_data()。
发出Command Code(它一般表示芯片内部的寄存器地址),再发起度操作:

  • 读到一个字节(Block Count),表示后续要读的字节数
  • 然后读取全部数据
    Functionality flag4: I2C_FUNC_SMBUS_READ_BLOCK_DATA

10. SMBus Block Write

rk3288 I2C-原理学习
I2C-tools中的函数:i2c_smbus_write_block_data()。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出1个字节的Byte Conut(表示后续要发出的数据字节数),最后发全部数据
Functionality flag4: I2C_FUNC_SMBUS_WRITE_BLOCK_DATA

11. I2C Block Read

在一般的I2C协议中,也可以连续读出多个字节。 它跟SMBus Block Read的差别在于设备发出的第1个数据不是长度N,如下图
示:
rk3288 I2C-原理学习
I2C-tools中的函数:i2c_smbus_read_i2c_block_data()。
先发出Command Code(它一般表示芯片内部的寄存器地址),再接收所有数据
Functionality flag4: I2C_FUNC_SMBUS_READ_I2C_BLOCK

12. I2C Block Write

在一般的I2C协议中,也可以连续发出多个字节。 它跟SMBus Block Write的差别在于发出的第1个数据不是长度N,如下图所示:
rk3288 I2C-原理学习
I2C-tools中的函数:i2c_smbus_write_i2c_block_data()。
先发出Command Code(它一般表示芯片内部的寄存器地址),再发全部数据
Functionality flag4: I2C_FUNC_SMBUS_WRITE_I2C_BLOCK

13. SMBus Block Write - Block Read Process Call

rk3288 I2C-原理学习先写一块数据,再读一块数据。
Functionality flag4: I2C_FUNC_SMBUS_BLOCK_PROC_CALL

14. Packet Error Checking (PEC)

PEC是一种错误校验码,如果使用PEC,那么在P信号之前,数据发送方要发送一个字节的PEC码(它是CRC-8码)。
以SMBus Send Byte为例,下图中,一个未使用PEC,另一个使用PEC:
rk3288 I2C-原理学习
rk3288 I2C-原理学习


  1. 某个设备需要更多时间进行内部的处理时,它可以把SCL拉低占住I2C总线 ↩︎

  2. 这样对方才知道该设备的状态:busy,failed,或是被移除了 ↩︎

  3. 这个S信号就是REPEATED START ↩︎

  4. Functionality flag是Linux的某个I2C控制器驱动所支持的功能,比如I2C_FUNC_SMBUS_QUICK,表示需要I2C控制器支持SMBus Quick Command。 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

上一篇:电源管理总线 (PMBus)


下一篇:STM32F767--LTC4015--SMBUS通信