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适配器支持所涉及的事务。

符号注解

S

Start 条件

P

Stop 条件

Rd/Wr (1 bit)

读/写位。Read等于1, Write等于0。

A, NA (1 bit)

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

Addr (7 bits)

I2C 7位地址。注意,这可以像往常一样进行扩展,以获得10位I2C地址。

Comm (8 bits)

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

Data (8 bits)

一个普通数据字节。有时,对于16位数据写DataLow, DataHigh。

Count (8 bits)

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

[..]

由I2C设备发送的数据,而不是由主机适配器(adapter)发送的数据。

SMBus快速命令

这将在Rd/Wr位的位置发送一个位到设备:

S Addr Rd/Wr [A] P

功能flag: I2C_FUNC_SMBUS_QUICK

SMBus接收字节

由 i2c_smbus_read_byte() 实现。

它从设备中读取单个字节,而不指定设备寄存器。有些设备非常简单,这个接口就足够了;对于其他人来说,如果您想读取与前一个SMBus命令中相同的寄存器,则它是一种简写:

S Addr Rd [A] [Data] NA P

功能flag: I2C_FUNC_SMBUS_READ_BYTE

API分析:

s32 i2c_smbus_read_byte(const struct i2c_client *client)

SMBus“接收字节”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。

描述

  这将执行SMBus“接收字节”协议,返回负errno 或者 从设备接收的字节。

SMBus发送字节

由 i2c_smbus_write_byte() 实现。

此操作与接收字节相反:它向设备发送单个字节。

S Addr Wr [A] Data [A] P

功能flag:I2C_FUNC_SMBUS_WRITE_BYTE

API分析:

s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value);

SMBus“发送字节”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 value:要发送的字节

描述

  这将执行SMBus的“发送字节”协议,返回负errno 或者 成功时返回0。

 SMBus读取字节

由 i2c_smbus_read_byte_data() 实现。

它从一个设备,从一个指定的寄存器中读取一个字节。寄存器是通过Comm字节指定的:

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

功能flag:I2C_FUNC_SMBUS_READ_BYTE_DATA

API分析:

s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)

SMBus“读字节”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 command从机字节解释(一般为slave的寄存器地址)。

描述

  这将执行SMBus“读字节”协议,出错时返回负errno,否则返回从设备接收的数据字节。

SMBus读字

由 i2c_smbus_read_word_data() 实现。

这个操作很像读字节;同样,数据从设备中读取,从通过Comm字节指定的指定寄存器中读取。但这一次,数据是一个完整的字(16位):

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

功能flag:I2C_FUNC_SMBUS_READ_WORD_DATA

注意,函数i2c_smbus_read_word_swap()可用于读取两个数据字节相反的情况(不符合SMBus,但非常流行)。

API分析:

s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command)

SMBus“读字”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 command从机字节解释(一般为slave的寄存器地址)。

描述

  这执行SMBus“read word”协议,返回负errno 或 设备接收到的16位无符号“word”。

SMBus写字节

由 i2c_smbus_write_byte_data() 实现。

这将一个字节写入一个设备,一个指定的寄存器。寄存器是通过Comm字节指定的。这与读字节操作相反。

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

功能flag:I2C_FUNC_SMBUS_WRITE_BYTE_DATA

API分析:

s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value)

SMBus“写字节”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 command从机字节解释(一般为slave的寄存器地址)。
  • u8 value:将要被写入的字节数据

描述

  这将执行SMBus的“写字节”协议,出错时返回负errno, 或者成功时返回0。

SMBus写字

由 i2c_smbus_write_word_data() 实现。

这与Read Word操作相反。16位的数据被写入设备,通过Comm字节指定的指定寄存器:

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

功能flag:I2C_FUNC_SMBUS_WRITE_WORD_DATA

注意,函数i2c_smbus_write_word_swap()可用于两个数据字节相反方向的写操作(不符合SMBus,但非常流行)。

API分析:

s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, u16 value)

SMBus“写字”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 command从机字节解释(一般为slave的寄存器地址)。
  • u16 value:将要被写入的16位的"word"

描述

  这将执行SMBus“write word”协议,出错时返回负errno,成功时返回0.

SMBus进程调用

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

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

功能flag: I2C_FUNC_SMBUS_PROC_CALL

SMBus块读取

由 i2c_smbus_read_block_data() 实现。

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

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

功能flag: I2C_FUNC_SMBUS_READ_BLOCK_DATA

API分析:

s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values)

SMBus“块读”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 command从机字节解释(一般为slave的寄存器地址)。
  • u8 *values数据将被读入的字节数组;大到足以容纳从slave返回的数据。SMBus最多允许32个字节。

描述

  这将执行SMBus“block read”协议,返回负errno,否则返回从slave响应中的数据字节数。

注意,使用这个函数需要客户机的适配器支持I2C_FUNC_SMBUS_READ_BLOCK_DATA功能。不是所有的适配器驱动程序都支持这一点;它通过I2C消息传递的仿真依赖于特定的机制(I2C_M_RECV_LEN),可能没有被实现。

SMBus块写入

由 i2c_smbus_write_block_data() 实现。

与Block Read命令相反,该命令将至多32字节写入设备,写入通过Comm字节指定的指定寄存器。数据量在Count字节中指定。

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

功能 flag: I2C_FUNC_SMBUS_WRITE_BLOCK_DATA

API分析:

s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values);

SMBus“块写入”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 command从机字节解释(一般为slave的寄存器地址)。
  • u8 length: 数据块大小,SMBus最多允许32个字节
  • const u8 *values将被写入的字节数组。

描述

  这将执行SMBus的“块写”协议,出错时返回负errno,成功时返回0。

SMBus块写-块读进程调用

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

这个命令选择一个设备寄存器(通过Comm字节),发送1到31字节的数据给它,并返回1到31字节的数据:

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

功能 flag: I2C_FUNC_SMBUS_BLOCK_PROC_CALL

SMBus主机通知

该命令从作为主设备的SMBus设备发送到作为从设备的SMBus主机。它的形式与Write Word相同,只是command代码被发信号设备的地址所代替。

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

在Linux内核中,这是通过以下方式实现的:

  • 支持SMBus Host Notify的I2C总线驱动应该报告I2C_FUNC_SMBUS_HOST_NOTIFY。
  • I2C总线驱动通过调用i2c_handle_smbus_host_notify()来触发SMBus Host Notify。
  • 可以触发SMBus主机通知的设备的I2C驱动程序将有 client->irq 分配给Host Notify IRQ,如果没有其他人指定其他的。

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

包错误检查(PEC)

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

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

地址解析协议(ARP)

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

ARP协议增加了设备枚举和动态地址分配功能。所有ARP通信使用从地址0x61,并需要PEC校验和。

SMBus Alert

SMBus Alert是在规范的1.0版本中引入的。

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

在Linux内核中,是通过以下方式实现的:

  • 支持SMBus告警的I2C总线驱动应该调用i2c_new_smbus_alert_device()来安装SMBus告警支持。
  • 可以触发SMBus警报的设备的I2C驱动程序应该实现可选的alert()回调。

I2C块事务

下面的I2C块事务类似于SMBus块读和写操作,只是它们没有Count(即 S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P 中的Count)字节。它们由SMBus层支持,为了完整起见,这里对它们进行了描述,但它们不是由SMBus规范定义的。

I2C块事务不限制传输的字节数,但SMBus层设置了32字节的限制。

I2C块读取

由 i2c_smbus_read_i2c_block_data() 实现。

这个命令从设备中读取一个字节块,从指定的寄存器(通过Comm字节指定)中读取:

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

功能 flag: I2C_FUNC_SMBUS_READ_I2C_BLOCK

API分析:

s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command,
				  u8 length, u8 *values)

i2c“块读”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 command从机字节解释(一般为slave的寄存器地址)。
  • u8 length: 要读取的字节数。
  • u8 *values:存放读取的数据的字节数组。

描述

  这将执行i2c “block read”协议,返回负errno,否则返回从slave中读取的数据字节数。

I2C块写入

由 i2c_smbus_write_i2c_block_data() 实现。

与Block Read命令相反,该命令将字节写入设备,写入通过Comm字节指定的指定寄存器。注意,命令长度为0、2或更多字节是受支持的,因为它们与数据没有区别。

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

功能 flag: I2C_FUNC_SMBUS_WRITE_I2C_BLOCK

API分析:

s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command,
				   u8 length, const u8 *values)

i2c “块写入”协议。

参数

  • const struct i2c_client *client: 从设备客户端指针。
  • u8 command从机字节解释(一般为slave的寄存器地址)。
  • u8 length: 将要写入的数据块大小
  • const u8 *values:将被写入的字节数组。

描述

   这将执行i2c的“块写”协议,出错时返回负errno,成功时返回0。

本文来自博客园,作者:王楼小子,转载请注明原文链接:https://www.cnblogs.com/wanglouxiaozi/p/15147043.html

原文地址:https://www.cnblogs.com/wanglouxiaozi/p/15147043.html