“I2C i2c-tools”的版本间的差异

来自百问网嵌入式Linux wiki
第108行: 第108行:
  
 
==I2C 传输==
 
==I2C 传输==
 
+
:这是一个用户空间程序,用于发送串联的I2C消息。
 +
:大多数设备在读取之前都需要对寄存器进行写访问。i2ctransfer <ref name="i2ctransfer"/>  提供了一种组合写入和读取过程的方法。它还可以在单​​个命令中处理带有附加后缀的多个字节写入/读取。
 +
:要读取一组字节:
 
  Board $> i2ctransfer -f -y <i2cbus number> r<number of bytes>@<peripheral address>
 
  Board $> i2ctransfer -f -y <i2cbus number> r<number of bytes>@<peripheral address>
 
+
:要写一组字节:
 
  Board $> i2ctransfer -f -y <i2cbus number> w<number of bytes>@<peripheral address> <byte value 1> <byte value 2> ... <byte value n>
 
  Board $> i2ctransfer -f -y <i2cbus number> w<number of bytes>@<peripheral address> <byte value 1> <byte value 2> ... <byte value n>
 
+
:要写入一组字节,然后读取一组字节:
 
  Board $> i2ctransfer -f -y <i2cbus number> w<number of bytes to write>@<peripheral address> <byte value 1> <byte value 2> ... <byte value n> r<number of bytes to read>
 
  Board $> i2ctransfer -f -y <i2cbus number> w<number of bytes to write>@<peripheral address> <byte value 1> <byte value 2> ... <byte value n> r<number of bytes to read>
  
 +
:示例(总线0,在0x50处从EEPROM偏移0x64处读取8个字节)
 +
Board $> i2ctransfer 0 w1@0x50 0x64 r8
 +
::" w1"代表"写入1个字节"(0x64偏移量),"r8"代表“读取8个字节”
  
Example (bus 0, read 8 bytes at offset 0x64 from EEPROM at 0x50)
+
:示例(同一个EEPROM,在偏移量0x42处写入0xff 0xfe ... 0xf0)
 
 
Board $> i2ctransfer 0 w1@0x50 0x64 r8
 
"w1" for "write 1 byte" (the 0x64 offset), "r8" for "read 8 bytes"
 
 
 
Example (same EEPROM, at offset 0x42 write 0xff 0xfe ... 0xf0)
 
  
Board $> i2ctransfer 0 w17@0x50 0x42 0xff-
+
Board $> i2ctransfer 0 w17@0x50 0x42 0xff-
"w17" for "write 17 bytes", first 0x42 byte for the offset, and 0xff- for the 16 subsequent bytes ("-" for auto value decrease starting from 0xff).
+
::“ w17”表示“写入17个字节”,第一个0x42字节表示偏移量,而0xff-表示后16个字节(“-”表示从0xff开始的自动值减小)。
  
See following chapter for 16 bits addressing devices handling.
+
有关16位寻址设备的处理方法,请参见下一章。
  
 
==16位设备处理==
 
==16位设备处理==

2019年12月10日 (二) 18:14的版本

本文旨在提供一些有用的信息,这些信息对于从Linux®工具:I2C工具开始很有用。

简介

i2c-tools是一个完整的用户空间软件包,位于I2C子系统之上。它提供:
Tools:一组I2C程序,无需编写任何代码即可轻松调试I2C外设
libi2c:用于开发应用程序的库。

工具列表

安装

开始使用

设备检测

查看哪些外设连接到特定的I2C总线可能非常有帮助。
检查所有实例化的I2C适配器:
Board $> i2cdetect -l
如果实例化了I2C适配器,将显示以下返回:
i2c-0   i2c             ST I2C(0xAAAAAAA)                       I2C adapter
i2c-1   i2c             ST I2C(0xBBBBBBB)                       I2C adapter
i2c-2   i2c             ST I2C(0xCCCCCCC)                       I2C adapter
i2c-3   i2c             ST I2C(0xDDDDDDD)                       I2C adapter
i2c-4   i2c             ST I2C(0xEEEEEEE)                       I2C adapter
i2c-5   i2c             ST I2C(0xFFFFFFF)                       I2C adapter
获取在特定I2C总线上检测到的外围设备的列表:
Board $> i2cdetect -y <i2cbus number>
Board $> i2cdetect -y 3
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --
UU- >探测被跳过,因为驱动程序当前正在使用该地址。这强烈表明该地址处有一个设备被驱动程序探测到。
有关i2cdetect[1]的更多信息

读寄存器

从外设读取所有寄存器:
Board $> i2cdump -f -y <i2cbus number> <peripheral address>
Board $> i2cdump -f -y 0 0x5f
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bc    ...............?
10: 3f 00 87 33 96 be ec a1 9e b2 fe 00 e8 01 80 82    ?.?3???????.????
20: 00 00 00 00 00 00 00 00 51 f2 ae 00 10 f3 c6 00    ........Q??.???.
30: 41 92 a0 0e 00 c4 ee ff 32 03 bf d3 ff ff d0 02    A???.??.2???..??
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bc    ...............?
90: 3f 00 87 33 96 be ec a1 9e b2 fe 00 e8 01 80 82    ?.?3???????.????
a0: 00 00 00 00 00 00 00 00 51 f2 ae 00 10 f3 c6 00    ........Q??.???.
b0: 41 92 a0 0e 00 c4 ee ff 32 03 bf d3 ff ff d0 02    A???.??.2???..??
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
有关i2cdump [2]的更多信息。
要直接读取一个寄存器,请使用i2cget[3]
Board $> i2cget -f -y <i2cbus number> <peripheral address>
示例:读取I2c总线0上地址为0x5f的外设寄存器0x0f数据
Board $> i2cset -f -y 0 0x5f 0x0f 0xac

写寄存器

要直接写寄存器,请使用i2cset[4]
Board $> i2cset -f -y <i2cbus number> <peripheral address> <value>
示例:将0xac写入外围设备的寄存器0x0f的总线0的地址0x5f上:
Board $> i2cset -f -y 0 0x5f 0x0f 0xac

注意:如果寄存器处于只读模式,则写入可能会失败

自动增量设备

即使不是I2C标准的一部分,通常也会在I2C设备上找到自动递增功能,尤其是那些处理大量寄存器的设备(通常是I2C RAM或EEPROM)。
此类设备在每次读取或写入操作时自动递增一个内部地址指针,因此,在同一地址发出多个读取命令时,每次读取返回的值可能每次都不同。
以下是STM32MP157C-EV1评估板上的WM8994音频编解码器器件的一些示例:
首先启动音频播放以启动音频编解码器设备(请参阅“ 如何播放音频”)
读取WM8994地址为"0x0000"软件复位寄存器数据。
Board $> i2cget -y 0 0x1b 0x00 w
0x9489
将0x9489读为一个字,了解0x89 0x94,这是设备ID(WM8994),并且实际上是软件复位寄存器的内容。
如果再次重复相同的命令:
Board $> i2cget -y 0 0x1b 0x00 w
0x0000
Board $> i2cget -y 0 0x1b 0x00 w
0x0060
返回不同的值,这些值不再与软件复位寄存器“ 0x0000”相对应,而是与寄存器“ 0x0001”和“ 0x0002”相继对应。
要重置内部地址计数器,只需在目标寄存器地址处写入一个值:
Board $> i2cset -y 0 0x1b 0x00 0x00
然后后续读取将在此地址重新开始:
Board $> i2cget -y 0 0x1b 0x00 w
0x9489

请注意,通常可以通过写入特定于器件的配置寄存器来禁用自动递增模式(有关详细信息,请参见器件数据手册)。

I2C 传输

这是一个用户空间程序,用于发送串联的I2C消息。
大多数设备在读取之前都需要对寄存器进行写访问。i2ctransfer [5] 提供了一种组合写入和读取过程的方法。它还可以在单​​个命令中处理带有附加后缀的多个字节写入/读取。
要读取一组字节:
Board $> i2ctransfer -f -y <i2cbus number> r<number of bytes>@<peripheral address>
要写一组字节:
Board $> i2ctransfer -f -y <i2cbus number> w<number of bytes>@<peripheral address> <byte value 1> <byte value 2> ... <byte value n>
要写入一组字节,然后读取一组字节:
Board $> i2ctransfer -f -y <i2cbus number> w<number of bytes to write>@<peripheral address> <byte value 1> <byte value 2> ... <byte value n> r<number of bytes to read>
示例(总线0,在0x50处从EEPROM偏移0x64处读取8个字节)
Board $> i2ctransfer 0 w1@0x50 0x64 r8 
" w1"代表"写入1个字节"(0x64偏移量),"r8"代表“读取8个字节”
示例(同一个EEPROM,在偏移量0x42处写入0xff 0xfe ... 0xf0)
Board $> i2ctransfer 0 w17@0x50 0x42 0xff-
“ w17”表示“写入17个字节”,第一个0x42字节表示偏移量,而0xff-表示后16个字节(“-”表示从0xff开始的自动值减小)。

有关16位寻址设备的处理方法,请参见下一章。

16位设备处理

The I2C standard protocol supports natively 7 bits of address (or 10 bits of address in extended mode) followed by 8 bits of data.

However some I2C devices embed 16-bit data registers with internal 16-bit address space. Here is how the i2c-tool allows to drive such devices.

To read a 16 bits value, add "w" for "word" at the end of command: Board $> i2cget -f -y <i2cbus number> <peripheral address> <address> w Please note that <address> is 8-bit wide, while the returned data is 16-bit wide. The interpretation of <address> is device dependent (One possible interpretation is that <address> drives the 8 MSB bits of the 16-bit address while the 8 LSB bits are set to 0).

To write a 16 bits value specifying the 16 bits address, send both the address and the data as a set of bytes in a single "I2C block write" by adding "i" at the end of i2cset[4] command: Board $> i2cset -f -y <i2cbus number> <peripheral address> <MSB address> <LSB address> <MSB value> <LSB value> i