Bootstrap

Linux I2C 命令

目标:已知设备树中目标I2C设备所在的I2C控制器lpi2c3: i2c@42530000 ,找到对应的I2C设备并进行读写测试操作

i2cdetect -l 查看系统上有机组I2C总线。

evk:~# i2cdetect -l
i2c-2   i2c             42530000.i2c                            I2C adapter
i2c-3   i2c             42540000.i2c                            I2C adapter
i2c-5   i2c             426c0000.i2c                            I2C adapter

可以找到设备树节点i2c@42530000 对应哪个I2C-2总线
i2cdetect -a 2 查看目录/sys/bus/i2c/devices/i2c-2总线上的设备。

evk:~# i2cdetect -a 2
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-2.
I will probe address range 0x00-0x7f.
Continue? [Y/n] Y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: UU UU -- UU -- -- -- -- -- -- -- -- -- -- -- UU
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- UU -- -- -- -- 7c -- -- --

理解上述log:
可见地址0x00, 0x20, 0x21, 0x23, 0x2f, 0x4c, 0x50, 0x68, 0x77, 0x7c上为总线上挂载的I2C设备的地址,以16进制表示。
‘- -’ 表示地址被检测但没有应答
‘UU’表示地址当前由内核驱动程序使用

  • i2cdetect -r -y 2i2cdetect -a 2 命令区别:
    -r:使用读取操作来探测设备。这意味着i2cdetect会尝试读取每个地址来确认设备是否存在。这种方法比默认的写操作更安全,因为它不会意外地写入数据到设备。
    -y:在探测过程中不进行交互确认。这个选项会自动回答“是”以继续探测,而不需要用户输入。
    2:指定要探测的I2C总线编号。
    -a:探测所有可能的I2C地址,包括10位地址。默认情况下,i2cdetect只探测7位地址。这个选项会扩展探测范围,包括那些可能使用10位地址的设备。
    -f:强制模式。这个选项会强制进行I2C传输,即使设备可能不支持某些操作或传输可能失败。使用这个选项时要小心,因为它可能会引起某些设备的异常行为。

【注】:i2cdetect 命令读取到的地址是读地址还是写地址?
:都不是,是7位设备地址。先得知道i2c地址怎么看,第一个字节为器件地址(设备地址),其中设备地址D7 D6 D5 D4 D3 D2 D1 D0的D7-D4 共4位为器件类型,一般是半导体公司生产时固定的。D3-D1一般为用户自定义地址,通常由外部IC的3个引脚所组合电平决定(这就是为什么同一IIC总线上同一型号的IC只能最多共挂8片同种类芯片)。
I2C设备的写地址 = I2C设备地址 << 1(最低位“0”表示写)
I2C设备的读地址 = (I2C设备地址 << 1) + 1(最低位“1”表示写)

然后看原理图,知道设备地址是多少(一般看自定义位)应当与对应总线上的设备地址的name匹配(如cat /sys/bus/i2c/devices/i2c-2/2-0023/name 得到I2c-2总线上地址位0x23的设备的名字)(前面这个方法麻烦死了,其实可以看设备树快速知道I2C子设备在总线上地址的对应关系如下)。

&lpi2c3 {
	clock-frequency = <400000>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_###>;
	status = "okay";
	
	pca9670_i2c3: gpio@23 {//看到没有,这个设备树unit-address就是I2C设备地址
		compatible = "nxp,pca9670";
		reg = <0x23>; //这个好像也算
		gpio-controller;
		#gpio-cells = <2>;
		...
	};
	ptn5110: tcpc@50 {//看到没有,这个设备树unit-address就是I2C设备地址
		compatible = "nxp,ptn5110", "tcpci";
		reg = <0x50>;
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_typec>;
		interrupt-parent = <&gpio3>;
		interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
	};
	...
};

i2cdump命令就可以读取设备寄存器的内容了。

i2cdump -f -y 2 0x20 (在I2C总线2上读取地址为0x20的I2C设备的寄存器内容,并将它们显示出来。)
i2cset -f -y 2 0x20 0x77 0x3f (设置i2c-2上0x20器件的0x77寄存器值为0x3f)
i2cget -f -y 2 0x20 0x77 (读取i2c-2上0x20器件的0x77寄存器值)
i2cdetect -F 2 (显示i2c-2总线上功能和特性)

参考:IIC(I2C)总线上的设备其地址如何定义?通俗易懂

;