SMBus 协议

以下是 SMBus 协议的摘要。它适用于该协议的所有版本(1.0、1.1 和 2.0)。本文档末尾简要描述了此软件包不支持的某些协议功能。

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

如果您为某些 I2C 设备编写驱动程序,请尽可能尝试使用 SMBus 命令(如果该设备仅使用 I2C 协议的该子集)。这使得可以在 SMBus 适配器和 I2C 适配器上使用设备驱动程序(SMBus 命令集会自动转换为 I2C 适配器上的 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 主机通知。

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

目前没有办法从客户端检索数据参数。

数据包错误检查 (PEC)

数据包错误检查是在规范的 1.1 版本中引入的。

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

地址解析协议 (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 规范定义的。

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