跳到主要内容

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 的值