1.首先我们想要使用工具,肯定是要先下载工具源码,下载路径如下:
https://www.kernel.org/pub/software/utils/i2c-tools/
2.在下载的源码(i2c-tools-4.2)中添加Android.mk编译文件,Android.mk文件中写入以下内容:
LOCAL_PATH:= $(call my-dir)
################### i2c-tools #########################
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := i2c-tools
LOCAL_SRC_FILES := \
tools/i2cbusses.c \
tools/util.c \
lib/smbus.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/include
#LOCAL_CFLAGS := -g -Wall -Werror -Wno-unused-parameter
include $(BUILD_STATIC_LIBRARY)
################### i2cdetect #########################
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE:=i2cdetect
LOCAL_SRC_FILES:= \
tools/i2cdetect.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES:= \
libc
LOCAL_STATIC_LIBRARIES := \
i2c-tools
LOCAL_CPPFLAGS += -DANDROID
include $(BUILD_EXECUTABLE)
#################### i2cget ###########################
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE:=i2cget
LOCAL_SRC_FILES:= \
tools/i2cget.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES:= \
libc
LOCAL_STATIC_LIBRARIES := \
i2c-tools
LOCAL_CPPFLAGS += -DANDROID
include $(BUILD_EXECUTABLE)
##################### i2cset ##########################
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE:=i2cset
LOCAL_SRC_FILES:= \
tools/i2cset.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES:= \
libc
LOCAL_STATIC_LIBRARIES := \
i2c-tools
LOCAL_CPPFLAGS += -DANDROID
include $(BUILD_EXECUTABLE)
##################### i2cdump #########################
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE:=i2cdump
LOCAL_SRC_FILES:= \
tools/i2cdump.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES:= \
libc
LOCAL_STATIC_LIBRARIES := \
i2c-tools
LOCAL_CPPFLAGS += -DANDROID
include $(BUILD_EXECUTABLE)
################### i2ctransfer #######################
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE:=i2ctransfer
LOCAL_SRC_FILES:= \
tools/i2ctransfer.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES:= \
libc
LOCAL_STATIC_LIBRARIES := \
i2c-tools
LOCAL_CPPFLAGS += -DANDROID
include $(BUILD_EXECUTABLE)
注意如果写LOCAL_MODULE_TAGS := eng 报错就写成LOCAL_MODULE_TAGS := optional
3.将源码(i2c-tools-4.2)放入工程中,例如放在和kernel-4.9同一目录下,其他目录也行。
4.编译源码有两种方式:
a.在source build/envsetup.sh 和lunch后 mmm i2c-tools-4.2 对源码进行编译,让后就会在out\target\product\xxx\system\bin 目录下生成5个可执行文件,分别为 i2cdetect 、i2cdump、i2cget、i2cset、i2ctransfer。后还有一步关键的,要对直接的工程进行make -j24 编译后,在烧录。
b.就是直接不进行 mmm i2c-tools-4.2 编译,直接make -j24 编译自动生成 out\target\product\xxx\system\bin 目录下,只需要在device\mediateksample\xxx\device.mk文件中添加以下内容:
PRODUCT_PACKAGES += \
i2cdetect \
i2cget \
i2cdump \
i2cset \
i2ctransfer
5.错误
此时将执行i2cdetect,i2cget,i2cset,i2cdump,i2ctransfer等文件时,可能会提示错误,如执行i2cdetect -y 1
Could not open file `/dev/i2c-1' or `/dev/i2c/1'
需要在kernel-4.9/arch/arm64/configs将对应的xxx_64_bsp_defconfig将如下编译开关打开,重新编译系统
CONFIG_I2C_CHARDEV=y
6.常用命令
<1> i2cdetect --- I2C检测
1> 列出当前的I2C Adapter(或称为I2C Bus、I2C Controller)
# i2cdetect -l
i2c-1 i2c STM32F7 I2C(0x40013000) I2C adapter
i2c-2 i2c STM32F7 I2C(0x5c002000) I2C adapter
i2c-0 i2c STM32F7 I2C(0x40012000) I2C adapter
2> 打印某个I2C Adapter的Functionalities, I2CBUS为0、1、2等整数
# i2cdetect -F 0
Functionalities implemented by /dev/i2c-0:
I2C yes
SMBus Quick Command yes
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 yes
SMBus Block Process Call yes
SMBus PEC yes
I2C Block Write yes
I2C Block Read yes
3> 看看有哪些I2C设备, I2CBUS为0、1、2等整数
// --表示没有该地址对应的设备, UU表示有该设备并且它已经有驱动程序,
// 数值表示有该设备但是没有对应的设备驱动
# i2cdetect -y -a 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
```
<2> i2cget --- I2C读
# i2cget
Usage: i2cget [-f] [-y] [-a] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]
I2CBUS is an integer or an I2C bus name
ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)
MODE is one of:
b (read byte data, default)
w (read word data)
c (write byte/read byte)
Append p for SMBus PEC
1> 读一个字节
I2CBUS为0、1、2等整数, 表示I2C Bus; CHIP-ADDRESS表示设备地址
i2cget -f -y I2CBUS CHIP-ADDRESS
// 读某个地址上的一个字节:
// I2CBUS为0、1、2等整数, 表示I2C Bus
// CHIP-ADDRESS表示设备地址
// DATA-ADDRESS: 芯片上寄存器地址
// MODE:有2个取值, b-使用`SMBus Read Byte`先发出DATA-ADDRESS, 再读一个字节, 中间无P信号
// c-先write byte, 在read byte,中间有P信号
i2cget -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS MODE
2> 读某个地址上的2个字节
// I2CBUS为0、1、2等整数, 表示I2C Bus
// CHIP-ADDRESS表示设备地址
// DATA-ADDRESS: 芯片上寄存器地址
// MODE:w-表示先发出DATA-ADDRESS,再读2个字节
i2cget -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS MODE
```
<3> i2cset --- I2C写
# i2cset
Usage: i2cset [-f] [-y] [-m MASK] [-r] [-a] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]
I2CBUS is an integer or an I2C bus name
ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)
MODE is one of:
c (byte, no value)
b (byte data, default)
w (word data)
i (I2C block data)
s (SMBus block data)
Append p for SMBus PEC
// 写一个字节: I2CBUS为0、1、2等整数, 表示I2C Bus; CHIP-ADDRESS表示设备地址
// DATA-ADDRESS就是要写的数据
i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS
// 给address写1个字节(address, value):
// I2CBUS为0、1、2等整数, 表示I2C Bus; CHIP-ADDRESS表示设备地址
// DATA-ADDRESS: 8位芯片寄存器地址;
// VALUE: 8位数值
// MODE: 可以省略,也可以写为b
i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE [b]
// 给address写2个字节(address, value):
// I2CBUS为0、1、2等整数, 表示I2C Bus; CHIP-ADDRESS表示设备地址
// DATA-ADDRESS: 8位芯片寄存器地址;
// VALUE: 16位数值
// MODE: w
i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE w
// SMBus Block Write:给address写N个字节的数据
// 发送的数据有:address, N, value1, value2, ..., valueN
// 跟`I2C Block Write`相比, 需要发送长度N
// I2CBUS为0、1、2等整数, 表示I2C Bus; CHIP-ADDRESS表示设备地址
// DATA-ADDRESS: 8位芯片寄存器地址;
// VALUE1~N: N个8位数值
// MODE: s
i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE1 ... VALUEN s
// I2C Block Write:给address写N个字节的数据
// 发送的数据有:address, value1, value2, ..., valueN
// 跟`SMBus Block Write`相比, 不需要发送长度N
// I2CBUS为0、1、2等整数, 表示I2C Bus; CHIP-ADDRESS表示设备地址
// DATA-ADDRESS: 8位芯片寄存器地址;
// VALUE1~N: N个8位数值
// MODE: i
i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE1 ... VALUEN i
<4> i2ctransfer --- I2C传输(不是基于SMBus)
# i2ctransfer
Usage: i2ctransfer [-f] [-y] [-v] [-V] [-a] I2CBUS DESC [DATA] [DESC [DATA]]...
I2CBUS is an integer or an I2C bus name
DESC describes the transfer in the form: {r|w}LENGTH[@address]
1) read/write-flag 2) LENGTH (range 0-65535) 3) I2C address (use last one if omitted)
DATA are LENGTH bytes for a write message. They can be shortened by a suffix:
= (keep value constant until LENGTH)
+ (increase value by 1 until LENGTH)
- (decrease value by 1 until LENGTH)
p (use pseudo random generator until LENGTH with value as seed)
Example (bus 0, read 8 byte at offset 0x64 from EEPROM at 0x50):
# i2ctransfer 0 w1@0x50 0x64 r8
Example (same EEPROM, at offset 0x42 write 0xff 0xfe ... 0xf0):
# i2ctransfer 0 w17@0x50 0x42 0xff-
// Example (bus 0, read 8 byte at offset 0x64 from EEPROM at 0x50):
# i2ctransfer -f -y 0 w1@0x50 0x64 r8
// Example (bus 0, write 3 byte at offset 0x64 from EEPROM at 0x50):
# i2ctransfer -f -y 0 w9@0x50 0x64 val1 val2 val3
// Example
// first: (bus 0, write 3 byte at offset 0x64 from EEPROM at 0x50)
// and then: (bus 0, read 3 byte at offset 0x64 from EEPROM at 0x50)
# i2ctransfer -f -y 0 w9@0x50 0x64 val1 val2 val3 r3@0x50
# i2ctransfer -f -y 0 w9@0x50 0x64 val1 val2 val3 r3 //如果设备地址不变,后面的设备地址可省略