跳到主要内容

I2C调试指南

前言

X5芯片提供了标准的I2C总线,I2C总线控制器通过串行数据线(SDA)和串行时钟(SCL)线在连接到总线的器件间传递信息。每个器件都有一个唯一的地址(无论是微控制器——MCU、LCD控制器、存储器或键盘接口),而且都可以作为一个发送器和一个接收器(由器件的功能决定)。

I2C控制器支持以下功能:

  • 支持三种速度模式
    • standard mode(0-100Kb/s)
    • fast mode(0-400Kb/s) && fast mode plus(0-1000Kb/s)
    • high-speed mode(0-3.4Mb/s)
  • 支持主从模式配置
  • 支持7位和10位寻址模式

X5的I2C控制器

X5总共提供8个I2C控制器,其中7个(I2C0~6)位于LSIO子系统,1个(I2C7)位于DSP子系统。 所有8个I2C控制器只有I2C4支持high-speed mode。

驱动代码

drivers/i2c/i2c-dev.c 				# I2C字符设备接口代码
drivers/i2c/i2c-core-base.c # I2C框架代码
drivers/i2c/busses/i2c-designware-platdrv.c # I2C驱动代码源文件

内核配置位置

/* arch/arm64/configs/hobot_x5_soc_defconfig */
CONFIG_I2C_CHARDEV=y # I2C驱动应用层配置宏
CONFIG_I2C_DESIGNWARE_PLATFORM=y # DW I2C驱动配置宏

内核DTS节点配置

X5芯片总共支持8路I2C总线。 | X5 I2C控制器的设备树定义位于SDK包的kernel文件夹下的arch/arm64/boot/dts/hobot/x5.dtsi文件内。

备注:x5.dtsi中的节点主要声明SoC共有特性,和具体电路板无关,一般情况下不用修改。

I2C使用

对于I2C的使用说明在Linux Kernel的Documentation/i2c下有详细的说明,本文主要列出X3J3 I2C驱动接口特殊的部分。

Kernel Space

X3J3 I2C驱动在Kernel Space下提供了可以设置I2C传输频率的接口,使用方法如下:

I2C速度配置

默认的I2C速率为100K,支持100k/200k/400k/1M/3.4M四种速率,可通过修改DTS中相应I2C节点的clock-frequency等字段完成速率修改。 以修改i2c4控制器的运行速率为例:

  • 如果需要使用3.4MHz,需要在对应板卡对应的dts的i2c4的节点内配置以下参数:
...
&i2c4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
clock-frequency = <3400000>;
i2c-scl-falling-time-ns = <78>;
i2c-sda-falling-time-ns = <78>;
}
...
  • 如果需要使用1MHz,需要在对应板卡对应的dts的i2c4的节点内配置以下参数:
...
&i2c4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
clock-frequency = <1000000>;
i2c-scl-falling-time-ns = <60>;
i2c-sda-falling-time-ns = <60>;
}
...
  • 如果需要使用400kHz,需要在对应板卡对应的dts的i2c4的节点内配置以下参数:
...
&i2c4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
clock-frequency = <400000>;
i2c-scl-falling-time-ns = <190>;
}
...

备注:“i2c-scl-falling-time-ns”及“i2c-sda-falling-time-ns”两个参数在不同的PCB设计上可能需要通过示波器来调整。上述配置基于I2C IO使能上拉并且板端配置1k上拉电阻的硬件条件。

I2C DMA配置

如果需要配置I2C使用dma,可以参考以下dts配置:

&i2c4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
dma-names = "tx", "rx";
dmas = <&axi_dmac 19>, <&axi_dmac 18>;
}

注意:I2C7位于DSP子系统,DTS内dma需要绑定DSP子系统的DMA:

&i2c4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
dma-names = "tx", "rx";
dmas = <&dsp_axi_dma 31>, <&dsp_axi_dma 30>;
}

I2C DMA握手列表如下:

RXTX
I2C01011
I2C11213
I2C21415
I2C31617
I2C41819
I2C53940
I2C64142
I2C73031

User Space

通常,I2C设备由内核驱动程序控制,但也可以从用户态访问总线上的所有设备,通过/dev/i2c-%d接口来访问,Kernel下面的Documentation/i2c/dev-interface文档里有详细的介绍。

开源工具:i2c-tools

i2c-tools是一套开源工具,该工具已经被交叉编译并包含在在X3J3 系统软件的rootfs中,客户可以直接使用:

  • i2cdetect — 用来列举I2C bus及该bus上的所有设备
  • i2cdump — 显示i2c设备的所有register值
  • i2cget — 读取i2c设备某个register的值
  • i2cset — 写入i2c设备某个register的值
  • i2ctransfer — 可以读、写i2c设备某个或者多个register的值