SMBus 协议

以下是 SMBus 协议的总结。 它适用于该协议的所有版本(1.0、1.1 和 2.0)。 本软件包不支持的某些协议特性将在本文档末尾简要描述。

有些适配器只理解 SMBus (系统管理总线) 协议,它是 I2C 协议的子集。幸运的是,许多设备只使用相同的子集,这使得将它们放在 SMBus 上成为可能。

如果您为某些 I2C 设备编写驱动程序,请尽可能尝试使用 SMBus 命令(如果设备仅使用 I2C 协议的该子集)。 这使得可以在 SMBus 适配器和 I2C 适配器上使用设备驱动程序(在 I2C 适配器上,SMBus 命令集会自动转换为 I2C,但大多数纯 SMBus 适配器根本无法处理普通的 I2C 命令)。

下面是 SMBus 协议操作的列表以及执行它们的函数。 请注意,SMBus 协议规范中使用的名称通常与这些函数名称不匹配。 对于传递单个数据字节的某些操作,使用 SMBus 协议操作名称的函数会执行完全不同的协议操作。

每种事务类型对应一个功能标志。在调用事务函数之前,设备驱动程序应始终(仅一次)检查相应的功能标志,以确保底层 I2C 适配器支持相关事务。有关详细信息,请参见I2C/SMBus 功能

符号说明

S

起始条件

Sr

重复起始条件,用于从写入模式切换到读取模式。

P

停止条件

Rd/Wr (1 位)

读/写位。Rd 等于 1,Wr 等于 0。

A, NA (1 位)

确认 (ACK) 和不确认 (NACK) 位

Addr (7 位)

I2C 7 位地址。 请注意,可以扩展它以获得 10 位 I2C 地址。

Comm (8 位)

命令字节,通常选择设备上的寄存器的数据字节。

Data (8 位)

纯数据字节。 DataLow 和 DataHigh 表示 16 位字的低字节和高字节。

Count (8 位)

包含块操作长度的数据字节。

[..]

I2C 设备发送的数据,与主机适配器发送的数据相反。

SMBus 快速命令

这会在 Rd/Wr 位的位置向设备发送一个位

S Addr Rd/Wr [A] P

功能标志:I2C_FUNC_SMBUS_QUICK

SMBus 接收字节

i2c_smbus_read_byte() 实现

这从设备读取单个字节,而不指定设备寄存器。 有些设备非常简单,以至于此接口就足够了。 对于其他设备,如果要读取与上一个 SMBus 命令中相同的寄存器,则这是一个简写形式

S Addr Rd [A] [Data] NA P

功能标志:I2C_FUNC_SMBUS_READ_BYTE

SMBus 发送字节

i2c_smbus_write_byte() 实现

此操作与“接收字节”相反:它向设备发送单个字节。 有关更多信息,请参见“接收字节”。

S Addr Wr [A] Data [A] P

功能标志:I2C_FUNC_SMBUS_WRITE_BYTE

SMBus 读取字节

i2c_smbus_read_byte_data() 实现

这从设备的指定寄存器读取单个字节。 寄存器通过 Comm 字节指定

S Addr Wr [A] Comm [A] Sr Addr Rd [A] [Data] NA P

功能标志:I2C_FUNC_SMBUS_READ_BYTE_DATA

SMBus 读取字

i2c_smbus_read_word_data() 实现

此操作与“读取字节”非常相似; 同样,数据是从设备的指定寄存器读取的,该寄存器通过 Comm 字节指定。 但是这次,数据是一个完整的字(16 位)

S Addr Wr [A] Comm [A] Sr Addr Rd [A] [DataLow] A [DataHigh] NA P

功能标志:I2C_FUNC_SMBUS_READ_WORD_DATA

请注意,方便函数 i2c_smbus_read_word_swapped() 可用于读取两个数据字节顺序相反的情况(不符合 SMBus 标准,但非常流行。)

SMBus 写入字节

i2c_smbus_write_byte_data() 实现

这向设备的指定寄存器写入单个字节。 寄存器通过 Comm 字节指定。 这与“读取字节”操作相反。

S Addr Wr [A] Comm [A] Data [A] P

功能标志:I2C_FUNC_SMBUS_WRITE_BYTE_DATA

SMBus 写入字

i2c_smbus_write_word_data() 实现

这与“读取字”操作相反。 16 位数据被写入设备的指定寄存器,该寄存器通过 Comm 字节指定

S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P

功能标志:I2C_FUNC_SMBUS_WRITE_WORD_DATA

请注意,方便函数 i2c_smbus_write_word_swapped() 可用于写入两个数据字节顺序相反的情况(不符合 SMBus 标准,但非常流行。)

SMBus 进程调用

此命令选择一个设备寄存器(通过 Comm 字节),向其发送 16 位数据,并返回读取 16 位数据

S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
                            Sr Addr Rd [A] [DataLow] A [DataHigh] NA P

功能标志:I2C_FUNC_SMBUS_PROC_CALL

SMBus 块读取

i2c_smbus_read_block_data() 实现

此命令从设备的指定寄存器读取最多 32 个字节的块,该寄存器通过 Comm 字节指定。 数据量由设备在 Count 字节中指定。

S Addr Wr [A] Comm [A]
          Sr Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P

功能标志:I2C_FUNC_SMBUS_READ_BLOCK_DATA

SMBus 块写入

i2c_smbus_write_block_data() 实现

与“块读取”命令相反,这会将最多 32 个字节写入设备的指定寄存器,该寄存器通过 Comm 字节指定。 数据量在 Count 字节中指定。

S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P

功能标志:I2C_FUNC_SMBUS_WRITE_BLOCK_DATA

SMBus 块写入 - 块读取进程调用

SMBus 块写入 - 块读取进程调用是在规范的修订版 2.0 中引入的。

此命令选择一个设备寄存器(通过 Comm 字节),向其发送 1 到 31 个字节的数据,并返回读取 1 到 31 个字节的数据

S Addr Wr [A] Comm [A] Count [A] Data [A] ...
                            Sr Addr Rd [A] [Count] A [Data] ... A P

功能标志:I2C_FUNC_SMBUS_BLOCK_PROC_CALL

SMBus 主机通知

此命令从充当主设备的 SMBus 设备发送到充当从设备的 SMBus 主机。 它与“写入字”的形式相同,只是命令代码替换为警报设备的地址。

[S] [HostAddr] [Wr] A [DevAddr] A [DataLow] A [DataHigh] A [P]

这在 Linux 内核中以下列方式实现

  • 支持 SMBus 主机通知的 I2C 总线驱动程序应报告 I2C_FUNC_SMBUS_HOST_NOTIFY。

  • I2C 总线驱动程序通过调用 i2c_handle_smbus_host_notify() 触发 SMBus 主机通知。

  • 如果其他人没有指定另一个主机,则可以触发 SMBus 主机通知的设备的 I2C 驱动程序会将 client->irq 分配给主机通知 IRQ。

目前无法从客户端检索数据参数。

数据包错误校验 (PEC)

数据包错误校验是在规范的修订版 1.1 中引入的。

PEC 在使用它的传输中添加一个 CRC-8 错误校验字节,紧接在终止 STOP 之前。

地址解析协议 (ARP)

地址解析协议是在规范的修订版 2.0 中引入的。 它是使用上述消息的更高层协议。

ARP 将设备枚举和动态地址分配添加到协议。 所有 ARP 通信都使用从设备地址 0x61 并需要 PEC 校验和。

SMBus 警报

SMBus 警报是在规范的修订版 1.0 中引入的。

SMBus 警报协议允许多个 SMBus 从设备共享 SMBus 主设备上的单个中断引脚,同时仍允许主设备知道哪个从设备触发了中断。

这在 Linux 内核中以下列方式实现

  • 支持 SMBus 警报的 I2C 总线驱动程序应调用 i2c_new_smbus_alert_device() 以安装 SMBus 警报支持。

  • 可以触发 SMBus 警报的设备的 I2C 驱动程序应实现可选的 alert() 回调。

I2C 块事务

以下 I2C 块事务与 SMBus 块读取和写入操作类似,只是它们没有 Count 字节。 SMBus 层支持它们,并且此处为了完整起见进行了描述,但 SMBus 规范 NOT 定义了它们。

I2C 块事务不限制传输的字节数,但 SMBus 层限制为 32 个字节。

I2C 块读取

由 i2c_smbus_read_i2c_block_data() 实现

此命令从设备的指定寄存器读取一个字节块,该寄存器通过 Comm 字节指定

S Addr Wr [A] Comm [A]
          Sr Addr Rd [A] [Data] A [Data] A ... A [Data] NA P

功能标志:I2C_FUNC_SMBUS_READ_I2C_BLOCK

I2C 块写入

由 i2c_smbus_write_i2c_block_data() 实现

与“块读取”命令相反,这会将字节写入设备的指定寄存器,该寄存器通过 Comm 字节指定。 请注意,支持 0、2 或更多字节的命令长度,因为它们与数据无法区分。

S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P

功能标志:I2C_FUNC_SMBUS_WRITE_I2C_BLOCK