###1. i2c tools

在进行i2c总线设备的开发过程中, 经常需要探测i2c总线上是否存在设备, 读/写设备寄存器, dump设备的寄存器, i2c tools可以帮助我们完成这些任务

i2c-tools 工具包由4个tool组成

  • i2cdetect : 用于探测i2c总线及总线上的设备
  • i2cdump : 用于dump i2c设备的寄存器
  • i2cget : 用于读取i2c设备的寄存器
  • i2cset : 用于写i2c设备的寄存器

###2. i2c设备的安装

ubuntu 等linux桌面系统上, 可以直接从软件仓库中安装

android上,可以从 i2c tools 下载地址 来下载i2c tools 源码

然后在andrroid源码中建立 external/i2c-tools 目录

external/i2c-tools
	|
	|- include
	|	|- i2cbusses.h
	|	|- util.h
	|	|- lunux
	|		|- i2c-dev.h
	|
	|- src
	|	|- i2cbusses.c
	|	|- i2cdetect.c
	|	|- i2cdump.c
	| 	|- i2cget.c
	|	|- i2cset.c
	|	|- util.c
	|
	|- version.h
	|
	|- Android.mk

其中的 *.c 和 *.h 文件均从 i2c-tools 源码中的 “include” 和 “tools” 目录表中提取, Android.mk 为自行添加, 内容为

LOCAL_PATH:= $(call my-dir)

##### build static libs for i2c tools ####
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng debug
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SRC_FILES := 	src/i2cbusses.c \
				src/util.c
LOCAL_MODULE := i2c_tools_lib
include $(BUILD_STATIC_LIBRARY)


##### build i2cdetect ####
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng debug
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SRC_FILES := src/i2cdetect.c
LOCAL_SHARED_LIBRARIES:=libc
LOCAL_STA	TIC_LIBRARIES := i2c_tools_lib
LOCAL_MODULE := i2cdetect
include $(BUILD_EXECUTABLE)


##### build i2cget ####
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng debug
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SRC_FILES := src/i2cget.c
LOCAL_SHARED_LIBRARIES:=libc
LOCAL_STATIC_LIBRARIES := i2c_tools_lib
LOCAL_MODULE := i2cget
include $(BUILD_EXECUTABLE)


##### build i2cset ####
include $	(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng debug
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SRC_FILES := src/i2cset.c
LOCAL_SHARED_LIBRARIES:=libc
LOCAL_STATIC_LIBRARIES := i2c_tools_lib
LOCAL_MODULE := i2cset
include $(BUILD_EXECUTABLE)


##### build i2cdump ####
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng debug
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SRC_FILES := src/i2cdump.c
LOCAL_SHARED_LIBRARIES := libc
LOCAL_STATIC_LIBRARIES := i2c_tools_lib
LOCAL_MODULE := i2cdump
include $(BUILD_EXECUTABLE)

执行“source”, “lunch” 步骤后, 在 “external/i2c-tools”目录中执行“mm”即可编译出i2c-tools

###3. i2cdetect

i2cdetect可用于总线扫描, 总线能力探测以及设备扫描

“i2cdetect -V”可用于查看版本号

###3.1 i2c总线扫描

i2c总线扫描即探测系统中存在多少i2c总线, 并且列出它们的编号

$ i2cdetect -l
i2c-0	i2c       	MSM-I2C-v2-adapter              	I2C adapter
i2c-4	i2c       	MSM-I2C-v2-adapter              	I2C adapter
i2c-5	i2c       	MSM-I2C-v2-adapter              	I2C adapter
i2c-6	i2c       	MSM-I2C-v2-adapter              	I2C adapter

可见系统中存在4条总线, 编号分别为 0, 4, 5, 6

###3.2 i2c总线功能扫描

i2c总线功能扫描即探测某一条i2c总线所支持的操作

# i2cdetect  -F 6
I2C                              yes
SMBus Quick Command              no
SMBus Send Byte                  yes
SMBus Receive Byte               yes
SMBus Write Byte                 yes
SMBus Read Byte                  yes
SMBus Write Word                 yes
SMBus Read Word                  yes
SMBus Process Call               yes
SMBus Block Write                yes
SMBus Block Read                 no
SMBus Block Process Call         no
SMBus PEC                        yes
I2C Block Write                  yes
I2C Block Read                   yes

上述命令列出了i2c总线6支持的操作, 可见支持i2c, 不支持 SMBus Quick Command

###3.3 i2c设备扫描

设备扫描可用于检测在某一条i2c总线上, 在哪些地址存在i2c设备, 只要设备上电正常,hardware没有问题就可以扫描出设备, 即使没有设备driver

i2cdetect用于设备扫描时的语法为

i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]

其中参数的意义为:

  • -y : i2cdetet在扫描设备时, 会stop对应的i2c总线, 默认情况下i2cdetect会给出提示, 需要user手动输入“y/n”确定, 加上‘-y’选项时, 会略过提示这一步, 在脚本中使用i2cdetect时比较有用
  • -a :
  • -q : 使用SMBus Quick Command来进行探测,和“-r”互斥, 缺省为-q, 在不支持SMBUSQuick Command的总线上会报error “Error: Can’t use SMBus Quick Write command on this bus”
  • -r : 使用i2c command来进行探测, 在不支持SMBUSQuick Command的i2c总线上(会报error “Error: Can’t use SMBus Quick Write command on this bus”)必须使用此选项

常用的是“-y”和“-r”选项, 示例:

# i2cdetect -y -r 4
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- 10 -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

可见 在i2c 4-0x0c 和 4-0x6a 这两个地址上存在i2c设备

需要注意的是, 上述扫描结果中列出的“UU”, 只要有某一个 i2c_client 占用了这一地址, i2cdetect就会返回”UU”, 因此在出现UU时, 有可能是该地址没有i2c设备, 但是该地址被某一个i2c_client占用, 也有可能是 有可能是该地址没有i2c设备且已经绑定driver, 因此在返回“UU”时, 还需要进行确认

###4. i2cdump

i2cdump可用于dump i2c设备的寄存器的值, 其语法为

i2cdump [-f] [-y] [-r first-last] I2CBUS ADDRESS [MODE [BANK [BANKREG]]]

其中 :

  • -f : 强制访问i2c设备, 通常情况下, 当driver在访问该i2c设备时, i2cdump会拒绝访问该设备, 可用“-f”选项强制访问, 有一定的危险性
  • -y : i2cdump时, 会stop对应的i2c总线, 默认情况下i2cdump会给出提示, 需要user手动输入“y/n”确定, 加上‘-y’选项时, 会略过提示这一步, 在脚本中使用i2cdetect时比较有用
  • -r : 指定要dump的寄存器的起始编号, 缺省为所有寄存器
  • ADDRESS : 可选 0x03 ~ 0x77
  • MODE : 读取的单位, 即从i2c设备的每一个寄存器中读取多大的数据,可选的参数如下
    • b (byte, default)
    • w (word)
    • W (word on even register addresses)
    • s (SMBus block)
    • i (I2C block)
    • c (consecutive byte)
  • BANK BANKRANG : 很少使用, 针对一些特殊的chip, 类似于W83781D

通常在使用时, 常用的参数是“-y”, “-r”

示例

# i2cdump -f -y -r 0x01-0x1a 4 0x6a                        
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:    18 d5 ed 04 1e 71 e0 18 65 b0 71 00 00 d4 03     ?????q??e?q..??
10: a1 20 20 2f 98 30 5c 03 20 00 31                   ?  /?0\? .1     

即读取 i2c设备 4-0xa 的寄存器 0x01 ~ 0x1a 的值

“i2cdump -V”可用于查看版本号

###5. i2cget

i2cget 用于读取i2c设备的一个寄存器, 其语法为

i2cget [-f] [-y] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]

其中

  • -f : 强制访问i2c设备, 通常情况下, 当driver在访问该i2c设备时, i2cdump会拒绝访问该设备, 可用“-f”选项强制访问, 有一定的危险性
  • -y : i2cget时, 会stop对应的i2c总线, 默认情况下i2cget会给出提示, 需要user手动输入“y/n”确定, 加上‘-y’选项时, 会略过提示这一步, 在脚本中使用i2cget时比较有用
  • I2CBUS : 总线号
  • CHIP-ADDRESS : 设备地址, 0x03 ~ 0x77
  • DATA-ADDRESS : 要读取的寄存器的编号, 可选 0x00 ~ 0xFF
  • MODE : 读取的单位, 即从i2c设备的每一个寄存器中读取多大的数据,可选的参数如下
    • b (byte, default)
    • w (word)
    • c (consecutive byte) write byte/ read byte

示例

# i2cget -f -y 4 0x6a 0x01                               
0x18

即强制读取 i2c 设备 4-0xa的寄存器 0x01的值

“i2cget -V”可用于查看版本号

###6. i2cset

i2cset用于设置i2c设备的寄存器, 其语法为

i2cset [-f] [-y] [-m MASK] [-r] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]

其中

  • -f : 强制访问i2c设备, 通常情况下, 当driver在访问该i2c设备时, i2cdump会拒绝访问该设备, 可用“-f”选项强制访问, 有一定的危险性
  • -y : i2cget时, 会stop对应的i2c总线, 默认情况下i2cget会给出提示, 需要user手动输入“y/n”确定, 加上‘-y’选项时, 会略过提示这一步, 在脚本中使用i2cget时比较有用
  • -m : 指定掩码, 要写入的VALUE和MASK做与运算, MASK中为1的bit对应的bit才会写入, 为0的bit使用寄存器中的原始值, 在只修改寄存器中某一位时比较有用
  • -r : 写入后, 会读取该寄存器的值, 和写入的值比较
  • I2CBUS : 总线号
  • CHIP-ADDRESS : 设备地址, 0x03 ~ 0x77
  • DATA-ADDRESS : 要写入的寄存器的编号, 可选 0x00 ~ 0xFF
  • VALUE : 要写入的值
  • MODE : 读取的单位, 即要向i2c设备的寄存器写入多大的数据,可选的参数如下
    • c (byte, no value)
    • b (byte, default)
    • w (word)
    • s (SMBus block)
    • i (I2C block)

示例

# i2cset -f -y 1 0x49 0x23 5

“i2cset -V”可用于查看版本号