“I2C i2c-tools”的版本间的差异
来自百问网嵌入式Linux wiki
(→写寄存器) |
Zhouyuebiao(讨论 | 贡献) |
||
(未显示1个用户的4个中间版本) | |||
第1行: | 第1行: | ||
+ | {{DISPLAYTITLE:i2c-tools}} | ||
+ | |||
本文旨在提供一些有用的信息,这些信息对于从Linux®工具:I2C工具开始很有用。 | 本文旨在提供一些有用的信息,这些信息对于从Linux®工具:I2C工具开始很有用。 | ||
=简介= | =简介= | ||
第88行: | 第90行: | ||
:以下是STM32MP157C-EV1评估板上的WM8994音频编解码器器件的一些示例: | :以下是STM32MP157C-EV1评估板上的WM8994音频编解码器器件的一些示例: | ||
:{{Redtext |首先启动音频播放以启动音频编解码器设备(请参阅“ 如何播放音频”) }} | :{{Redtext |首先启动音频播放以启动音频编解码器设备(请参阅“ 如何播放音频”) }} | ||
− | : | + | :读取WM8994地址为"0x0000"软件复位寄存器数据。 |
Board $> i2cget -y 0 0x1b 0x00 w | Board $> i2cget -y 0 0x1b 0x00 w | ||
0x9489 | 0x9489 | ||
− | + | :将0x9489读为一个字,了解0x89 0x94,这是设备ID(WM8994),并且实际上是软件复位寄存器的内容。 | |
− | + | :如果再次重复相同的命令: | |
Board $> i2cget -y 0 0x1b 0x00 w | Board $> i2cget -y 0 0x1b 0x00 w | ||
0x0000 | 0x0000 | ||
Board $> i2cget -y 0 0x1b 0x00 w | Board $> i2cget -y 0 0x1b 0x00 w | ||
0x0060 | 0x0060 | ||
− | + | :返回不同的值,这些值不再与软件复位寄存器“ 0x0000”相对应,而是与寄存器“ 0x0001”和“ 0x0002”相继对应。 | |
+ | :要重置内部地址计数器,只需在目标寄存器地址处写入一个值: | ||
Board $> i2cset -y 0 0x1b 0x00 0x00 | Board $> i2cset -y 0 0x1b 0x00 0x00 | ||
− | + | :然后后续读取将在此地址重新开始: | |
− | |||
− | |||
Board $> i2cget -y 0 0x1b 0x00 w | Board $> i2cget -y 0 0x1b 0x00 w | ||
0x9489 | 0x9489 | ||
+ | |||
+ | '''请注意,通常可以通过写入特定于器件的配置寄存器来禁用自动递增模式(有关详细信息,请参见器件数据手册)。''' | ||
==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 to write>@<peripheral address> <byte value 1> <byte value 2> ... <byte value n> r<number of bytes to read> | ||
− | Board $> i2ctransfer | + | :示例(总线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位设备处理== | |
− | " | + | :I2C标准协议本身支持7位地址(或在扩展模式下为10位地址),其后是8位数据。 |
+ | :但是,某些I2C器件将16位数据寄存器嵌入内部16位地址空间。这是i2c工具允许驱动此类设备的方式。 | ||
+ | *要读取16位值,请在命令末尾添加" w "作为" word": | ||
+ | Board $> i2cget -f -y <i2cbus number> <peripheral address> <address> w | ||
− | + | '''请注意,<地址>为8位宽,而返回的数据为16位宽。<address>的解释取决于设备(一种可能的解释是<address>驱动16位地址的8个MSB位,而8个LSB位设置为0)。''' | |
+ | *要写入指定16位地址的16位值,请通过在i2cset<ref name="i2cset"/>命令的末尾添加 "i ",在单个“ I2C块写入”中以字节的形式发送地址和数据。 | ||
− | Board $> | + | Board $> i2cset -f -y <i2cbus number> <peripheral address> <MSB address> <LSB address> <MSB value> <LSB value> i |
− | |||
− | + | :以下是STM32MP157C-EV1评估板上的WM8994音频编解码器器件的一些示例: | |
+ | ::'''首先启动音频播放以启动音频编解码器设备(请参阅“ 如何播放音频”)''' | ||
+ | *从地址“ 0x0000”的“软件重置”寄存器中读取设备ID: | ||
+ | Board $> i2cget -y 0 0x1b 0x0 w | ||
+ | 0x9489 | ||
− | + | :“ w”代表“单词”访问。由于单词是在Little Endian中读取的,而设备是Big Endian,因此我们必须反转Endianness。 | |
− | + | :返回的字0x9489应该解释为0x89 0x94,这实际上是(WM8994)设备ID。 | |
+ | *地址“ 0x0300”处寄存器“ AIF1控制”的更新值: | ||
+ | Board $> i2cget -y 0 0x1b 0x3 w | ||
+ | 0x5040 | ||
+ | :当前值为0x4050。 | ||
+ | :假设需要将AIF1ADC_TDM引脚置于三态,这是通过设置位13来完成的,因此需要写入0x6050: | ||
+ | Board $> i2cset -y 0 0x1b 0x03 0x00 0x60 0x50 i | ||
+ | Board $> i2cget -y 0 0x1b 0x3 w | ||
+ | 0x5060 | ||
+ | :" AIF1控制"寄存器值已按预期更新为0x6050。 | ||
+ | :对I2C传输执行相同的操作要简单得多: | ||
+ | Board $> i2ctransfer -f -y 0 w4@0x1b 0x03 0x00 0x60 0x50 -r2 | ||
+ | Board $> 0x60 0x50 | ||
+ | :“ w4”表示“写入4个字节”:地址(0x0300)的前2个字节,寄存器地址(0x6050)的后2个字节 | ||
+ | :“ r2”表示“读取2个字节”:字寄存器值 | ||
− | + | =参考= | |
− | + | :所有这些工具(i2cset,i2cget,i2cdump,i2cdectect和i2ctransfer)在此GIT中可用: | |
− | + | git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git或 | |
− | + | git clone https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git | |
− | + | :浏览I2C工具代码的源代码 https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/tree/ | |
− | |||
− | |||
<references /> | <references /> | ||
[[Category:Linux_Operating_System]][[Category:Low_speed_interface]][[Category:I2C]] | [[Category:Linux_Operating_System]][[Category:Low_speed_interface]][[Category:I2C]] |
2020年1月6日 (一) 15:45的最新版本
本文旨在提供一些有用的信息,这些信息对于从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 ................
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位设备处理
- I2C标准协议本身支持7位地址(或在扩展模式下为10位地址),其后是8位数据。
- 但是,某些I2C器件将16位数据寄存器嵌入内部16位地址空间。这是i2c工具允许驱动此类设备的方式。
- 要读取16位值,请在命令末尾添加" w "作为" word":
Board $> i2cget -f -y <i2cbus number> <peripheral address> <address> w
请注意,<地址>为8位宽,而返回的数据为16位宽。<address>的解释取决于设备(一种可能的解释是<address>驱动16位地址的8个MSB位,而8个LSB位设置为0)。
- 要写入指定16位地址的16位值,请通过在i2cset[4]命令的末尾添加 "i ",在单个“ I2C块写入”中以字节的形式发送地址和数据。
Board $> i2cset -f -y <i2cbus number> <peripheral address> <MSB address> <LSB address> <MSB value> <LSB value> i
- 以下是STM32MP157C-EV1评估板上的WM8994音频编解码器器件的一些示例:
- 首先启动音频播放以启动音频编解码器设备(请参阅“ 如何播放音频”)
- 从地址“ 0x0000”的“软件重置”寄存器中读取设备ID:
Board $> i2cget -y 0 0x1b 0x0 w 0x9489
- “ w”代表“单词”访问。由于单词是在Little Endian中读取的,而设备是Big Endian,因此我们必须反转Endianness。
- 返回的字0x9489应该解释为0x89 0x94,这实际上是(WM8994)设备ID。
- 地址“ 0x0300”处寄存器“ AIF1控制”的更新值:
Board $> i2cget -y 0 0x1b 0x3 w 0x5040
- 当前值为0x4050。
- 假设需要将AIF1ADC_TDM引脚置于三态,这是通过设置位13来完成的,因此需要写入0x6050:
Board $> i2cset -y 0 0x1b 0x03 0x00 0x60 0x50 i Board $> i2cget -y 0 0x1b 0x3 w 0x5060
- " AIF1控制"寄存器值已按预期更新为0x6050。
- 对I2C传输执行相同的操作要简单得多:
Board $> i2ctransfer -f -y 0 w4@0x1b 0x03 0x00 0x60 0x50 -r2 Board $> 0x60 0x50
- “ w4”表示“写入4个字节”:地址(0x0300)的前2个字节,寄存器地址(0x6050)的后2个字节
- “ r2”表示“读取2个字节”:字寄存器值
参考
- 所有这些工具(i2cset,i2cget,i2cdump,i2cdectect和i2ctransfer)在此GIT中可用:
git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git或 git clone https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git