TWI - 模块使用说明
本章节主要描述 TWI (I2C) 模块的常见功能配置和使用。
环境配置
软件环境
- 使用
V821 SDK
,选择v821-ipc-tina
方案。 - 相关源码路径:
bsp/drivers/twi/twi-sunxi.c
硬件环境
- 使用
v821 ipc开发板
。 - 测试使用的 I2C 设备为
eeprom
,连接到i2c0
,涉及PA10
和PA11
两个 GPIO 引脚。 - 注意外设的供电、GND、I2C 引脚的硬件连接。
驱动配置
- 执行
make kernel_menuconfig
。 - 选择以下配置项:
Allwinner BSP --->
Device Drivers --->
TWI Drivers --->
<*> I2C Support for Allwinner SoCs
DTS 配置
使用对应的 TWI 通道前,需要在 board.dts
文件中配置 TWI 引脚和状态:
-
进入
device/config/chips/v821/configs/ipc/linux-5.4-ansc
目录,编辑board.dts
文件。 -
配置
twi0
引脚:
twi0_pins_default: twi0@0 {
pins = "PA10", "PA11";
function = "twi0";
drive-strength = <10>;
bias-pull-up;
};
twi0_pins_sleep: twi0@1 {
pins = "PA10", "PA11";
function = "gpio_in";
};
- 配置
twi0
设备:
&twi0 {
clock-frequency = <400000>;
pinctrl-0 = <&twi0_pins_default>;
pinctrl-1 = <&twi0_pins_sleep>;
pinctrl-names = "default", "sleep";
twi_drv_used = <1>; /* 推荐设置为 1,以确保稳定性和向后兼容性 */
status = "okay";
};
软件包配置
- 执行
make menuconfig
。 - 选中以下 I2C 测试工具软件包配置:
CONFIG_BUSYBOX_CONFIG_I2CGET=y
CONFIG_BUSYBOX_CONFIG_I2CSET=y
CONFIG_BUSYBOX_CONFIG_I2CDUMP=y
CONFIG_BUSYBOX_CONFIG_I2CDETECT=y
CONFIG_BUSYBOX_CONFIG_I2CTRANSFER=y
模块功能测试
TWI0 基本功能测试
用例名称: TWI0 控制器下对 I2C 设备进行读写功能测试
功能说明: I2C 设备读写功能测试
前置条件:
- 设置 驱动配置;
- 配置 TWI0 控制器的 DTS 节点;
- 开启 I2C 测试工具软件包并编译固件;
- TWI0 控制器引脚连接到 EEPROM 外设。
操作步骤:
- 烧录固件。
- 输入命令查看当前 TWI 通路:
i2cdetect -l
; - 输入命令查看外接设备;
- 使用 i2ctools 工具成功进行读写通信。
预期结果:
- 烧录固件后,系统成功启动;
- 成功获取到 TWI0 通路;
- 成功识别到外接设备;
- 成功与外设进行 TWI 读写通信测试。
关键 LOG 如下:
1.查看当前TWI通路:
root@(none):/# i2cdetect -l
i2c-0 i2c SUNXI TWI(0x0000000042502000) I2C adapter
2.识别当前TWI外设:
root@(none):/# i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
3.读取当前外设寄存器值:
root@(none):/# i2cdump -f -y 0 0x50
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 00 ................
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
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 00 ................
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
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 ................
4.修改外设寄存器值,再读取外设寄存器值:
root@(none):/# i2cset -f -y 0 0x50 0x10 0xff
root@(none):/# i2cget -f -y 0 0x50 0x10
0xff
root@(none):/# i2cdump -f -y 0 0x50
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 00 ................
10: ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
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 00 ................
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
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 ................
400K/200K/100K 频率下 TWI 通信
用例名称: 验证 400K/200K/100K 频率下 TWI 通信
功能说明: 验证在 400K、200K 和 100K 频率下 TWI 通信的稳定性和功能。
前置条件:
- 设置驱动配置;
- 配置 TWI0 控制器的 DTS 节点;
- 开启 I2C 测试工具软件包并编译固件;
- TWI0 控制器引脚连接到地址为
0x50
的 EEPROM 外设。
操作步骤:
- 上电进入 Linux 系统控制台。
- 在 Linux 系统控制台执行命令:
cat /sys/devices/platform/soc@2002000/42502000.twi0/info
,查看 TWI0 控制器时钟频率。 - 在 Linux 系统控制台执行命令:
i2cdetect -y 0
,检测 TWI 总线上连接的外设。 - 在 Linux 系统控制台执行命令:
i2cget -f -y 0 0x50 0x10
,读取 EEPROM 设备0x10
地址处的数据。 - 在 Linux 系统控制台执行命令:
i2cset -f -y 0 0x50 0x10 0xab
,向 EEPROM 设备0x10
地址处写入0xab
。 - 在 Linux 系统控制台执行命令:
i2cget -f -y 0 0x50 0x10
,读取 EEPROM 设备0x10
地址处的数据。 - 在 Linux 系统控制台执行命令:
i2cset -f -y 0 0x50 0x10 0x00
,向 EEPROM 设备0x10
地址处写入0x00
。 - 在 Linux 系统控制台执行命令:
echo 200000 > /sys/devices/platform/soc@3000000/42502000.twi0/freq
,设置 TWI0 控制器的时钟频率为 200K,并重复执行步骤 3 到步骤 8。 - 在 Linux 系统控制台执行命令:
echo 100000 > /sys/devices/platform/soc@3000000/42502000.twi0/freq
,设置 TWI0 控制器的时钟频率为 100K,并重复执行步骤 3 到步骤 8。
预期结果:
- 步骤 2 中获取到的时钟频率应为期望的时钟频率:400K、200K 和 100K。
- 步骤 3 中能够成功检测到地址为
0x50
的 EEPROM 外设。 - 步骤 6 中读取到的数据应为
0xab
,且与步骤 4 读取到的数据值不同。
关键 LOG 如下:
1.分别将TWI频率设置成400K、200K、100K,并查看当前TWI频率:
root@(none):/# cat sys/devices/platform/soc@2002000/42502000.twi0/info
twi->bus_num = 0
twi->name = 42502000.twi0
twi->irq = 39
twi->freqency = 400000
root@(none):/# echo 200000 > /sys/devices/platform/soc@2002000/42502000.twi0/freq
[ 78.357929] sunxi:twi-42502000.twi0:[INFO]: Change clock frequncy from 400000 to 200000.
root@(none):/#
root@(none):/#
root@(none):/# cat sys/devices/platform/soc@2002000/42502000.twi0/info
twi->bus_num = 0
twi->name = 42502000.twi0
twi->irq = 39
twi->freqency = 200000
root@(none):/#
root@(none):/#
root@(none):/# echo 100000 > /sys/devices/platform/soc@2002000/42502000.twi0/freq
[ 86.487084] sunxi:twi-42502000.twi0:[INFO]: Change clock frequncy from 200000 to 100000.
root@(none):/# cat sys/devices/platform/soc@2002000/42502000.twi0/info
twi->bus_num = 0
twi->name = 42502000.twi0
twi->irq = 39
twi->freqency = 100000
root@(none):/#
2.分别在不同频率下,读写TWI外设寄存器值(如下为400K时的测试日志):
root@(none):/# i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
root@(none):/# i2cget -f -y 0 0x50 0x10
0x00
root@(none):/# i2cset -f -y 0 0x50 0x10 0xab
root@(none):/# i2cget -f -y 0 0x50 0x10
0xab
root@(none):/# i2cset -f -y 0 0x50 0x10 0x00
如需要默认开机就设置好频率,可修改 dts
对应 twi
节点修改,或增加配置 clock‑frequency = <400000>;
常见问题
执行 i2cdetect
出现大量报错
在执行前先将内核打印等级调低,使用命令
dmesg -n 1