• ArmSom---I2C开发指南


    1. 简介

    • RK3588从入门到精通

    • 本⽂介绍在rockchip平台下如何配置i2c接口的方法并且添加调试验证i2c外设的例子

    • 开发板:ArmSoM-W3

    • Kernel:5.10.160

    • OS:Debian11

    2. i2c接口概述

    i2c 总线控制器通过串行数据(SDA)线和串行时钟 (SCL)线在连接到总线的器件间传递信息。

    i2c总线一些特征:

    1. 只有两根线分别是串行数据线(SDA),串行时钟线(SCL)。

    2. 每个器件都有一个唯一的地址识别

    3. 使用串行8位双向数据传输方式。

    4. 可以使用普通GPIO口模拟I2C,但要需要将GPIO配置成OD模式(开漏模式)

    3. 芯片i2c资源

    RK3588旗舰芯片上可使用的I2C有9组,ArmSoM SOM-3588-LGA核心板采用LGA 506引脚封装方式将I2C资源全部引出,ArmSoM-W3板子上接有部分i2c外设以及40PIN资源如下:

    在这里插入图片描述
    在这里插入图片描述

    4. i2c使用

    RK3588使用I2C 的驱动是i2c-rk3x.c,参考文件 kernel/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt。

    4.1 DTS配置

    i2c资源使用只需要在设备树下进行配置,例如上述RTC芯片的配置如下:

    &i2c6 {
    	status = "okay";
    	//i2c-scl-rising-time-ns = <265>;
    	//i2c-scl-falling-time-ns = <11>;
    	//clock-frequency = <400000>;
    
    	hym8563: hym8563@51 {
    		compatible = "haoyu,hym8563";
    		reg = <0x51>;
    		#clock-cells = <0>;
    		clock-frequency = <32768>;
    		clock-output-names = "hym8563";
    		pinctrl-names = "default";
    		pinctrl-0 = <&rtc_int>;
    		interrupt-parent = <&gpio0>;
    		interrupts = ;
    	};
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    参数说明:

    • clock-frequency: 默认 frequency 为 100k 可不配置,其它 I2C 频率需要配置,最大可配置频率由i2c-scl-rising-time-ns 决定;例如配置 400k,clock-frequency=<400000>。
    • i2c-scl-rising-time-ns:SCL 上升沿时间由硬件决定,例如测得 SCL 上升沿 365ns,i2c-scl-rising-time-ns=<365>。(默认可以不配置)
    • i2c-scl-falling-time-ns: SCL 下降沿时间, 一般不变, 等同于 i2c-sda-falling-time-ns。(默认也可以不配置)

    在使用i2c设备树配置的时候,有些方面需要注意:

    1.上述rtc使用的引脚是I2C6_SDA_M0和I2C6_SCL_M0,硬件接口有些可以使用I2C6_SDA_M1,或者I2C6_SDA_M3,要修改默认配置

     i2c6: i2c@fec80000 {
      compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
      reg = <0x0 0xfec80000 0x0 0x1000>;
      clocks = <&cru 146>, <&cru 138>;
      clock-names = "i2c", "pclk";
      interrupts = <0 323 4>;
      pinctrl-names = "default";
      pinctrl-0 = <&i2c6m0_xfer>;//&i2c6m1_xfer、&i2c6m3_xfer
      #address-cells = <1>;
      #size-cells = <0>;
      status = "disabled";
     };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. i2c地址主要由7bit的二进制数值组成,最低位是读写标志位,0表示写,1表示读

      比如:读,0A3H 写,0A2H
      在linux驱动中要取这个ic设备的从设备地址,就是0xA3或者0xA2右移一位得到

    4.2 GPIO 模拟 I2C

    I2C 用 GPIO 模拟,内核已经有实现,请参考文档:Documentation/devicetree/bindings/i2c/i2c-gpio.txt
    下面是使用的例子,dts 下配置 I2C 节点。

    i2c@4 {
        compatible = "i2c-gpio";
        gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>, /* sda */
        <&gpio5 8 GPIO_ACTIVE_HIGH>; /* scl */
        i2c-gpio,delay-us = <2>; /* ~100 kHz */
        #address-cells = <1>;
        #size-cells = <0>;
        pinctrl-names = "default";
        pinctrl-0 = <&i2c4_gpio>;
        status = "okay";
        
        gt9xx: gt9xx@14 {
            compatible = "goodix,gt9xx";
            reg = <0x14>;
            touch-gpio = <&gpio5 11 IRQ_TYPE_LEVEL_LOW>;
            reset-gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>;
            max-x = <1200>;
            max-y = <1900>;
            tp-size = <911>;
            tp-supply = <&vcc_tp>;
            status = "okay";
          };
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    一般不推荐使用 GPIO,效率不高。

    5. 检查i2c设备

    5.1 IIC 第三方工具

    I2C tool 是一个开源工具,需自行下载进行交叉编译,代码下载地址:
    https://www.kernel.org/pub/software/utils/i2c-tools/或者
    编译后会生成 i2cdetect,i2cdump,i2cset,i2cget 等工具,可以直接在命令行上调试使用,I2C tool 是开源的,编译与使用参考里面的 README 与帮助说明。

    ArmSoM-W3板子对应的出厂固件已经在系统下集成了这个工具,可以直接使用,比如扫描I2C总线上的RTC设备:

    root@linaro-alip:~# i2cdetect -y 6
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:                         -- -- -- -- -- -- -- -- 
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    50: -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    70: -- -- -- -- -- -- -- --                         
    root@linaro-alip:~# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    扫描到对应的RTC芯片的I2C地址为0X51

    常用的命令还有以下几个。

    #检测当前系统有几组i2c总线
    i2cdetect -l
    
    #查看i2c-0接口上的设备
    i2cdetect -a 6
    
    #读取指定设备的全部寄存器的值。
    i2cdump  -f -y 6 0x51
    
    #读取指定IIC设备的某个寄存器的值,如下读取地址为0x51器件中的0x01寄存器值。
    i2cget -f -y 6 0x51 0x01
    
    #写入指定IIC设备的某个寄存器的值,如下设置地址为0x51器件中的0x01寄存器值为0x1a;
    i2cset -f -y 3 0x51 0x01 0x1a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.2 RTC使用

    Linux系统下包含两个时间:系统时间和RTC时间。

    linux命令中的date和time等命令都是用来设置系统时间的,而hwclock命令是用来设置和读写RTC时间的。

    root@linaro-alip:~# hwclock -r
    2018-05-24 16:38:13.115443+00:00 //查看硬件时间
    root@linaro-alip:~# date
    2018年 05月 24日 星期四 16:38:21 UTC //查看系统时间
    root@linaro-alip:~# date -s "2023-10-24 11:45:00" 
    2023年 10月 24日 星期二 11:45:00 UTC //重新设置系统时间
    root@linaro-alip:~# hwclock -w //同步系统时间到rtc上,掉电不丢失时间
    root@linaro-alip:~# hwclock -r
    2023-10-24 11:45:17.694727+00:00
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5.3 I2C 常见问题

    如果调用 I2C 传输接口返回值为 -6(-ENXIO)时候,表示为 NACK 错误,即对方设备无应答响应

    在这里插入图片描述

    这种情况一般为外设的问题,常见的有以下几种情况:

    • I2C 地址错误;

    • I2C slave 设备处于不正常工作状态,比如没有上电,错误的上电时序以及设备异常等;

    • I2C 时序不符合 slave 设备所要求也会产生 NACK 信号,比如 slave 设备需要的是 stop 信号,而不是

      repeat start 信号的时候;

    • I2C 总线受外部干扰导致的,用示波器测量可以看到是一个 ACK 波形。

    当出现 I2C 的 log 类似:"timeout, ipd: 0x80, state: 1"时,看到 ipd 为 0x80 打印,可以说明当前 SCL 被
    slave 拉住,要判断被哪个 slave 拉住:
    一是排除法,适用于外设不多的情况,而且复现概率高;
    二是需要修改硬件,在 SCL 总线上串入电阻,通过电阻两端产生的压差来确定,电压更低的那端
    外设为拉低的 slave,电阻的选取以不影响 I2C 传输且可以看出压差为标准,一般上拉电阻的 1/20
    以上都可以,如果是 host 拉低也可以看出。
    常见的情况是 sda 被拉低,证明是谁拉低的。

    有时候i2c初始化有问题时速率可以降低看有没有改善。遇到的 I2C 问题最好的办法是抓取 I2C 出错时候的波形,通过波形来分析 I2C 问
    题,I2C 的波形非常有用,大部分的问题都能分析出来。

    6. 读取eeprom数据实验

    本章介绍通过IIC接口读写eeprom(AT24C08)的数据。 本次实验会以i2c-7做为示例,接其他i2c引脚操作也是一样的 当然,并不是只能用这个eeprom这个模组,这只是做个简单的示例,如果您没有这个模块,可以通过学习操作eeprom的方式操作您想要操作的i2c设备。

    6.1 硬件连接

    将eeprom接入到ArmSoM-W3开发板的i2c-7的总线上,如下图所示

    在这里插入图片描述

    板子eeprom
    3.3V(1)VCC
    GND(39)GND
    SCL(5)SCL
    SDA(3)SCA

    6.2 软件配置

    在文件kernel\arch\arm64\boot\dts\rockchip\rk3588-armsom-w3.dts文件下添加下面代码:

    &i2c7 {
    	pinctrl-names = "default";
    	pinctrl-0 = <&i2c7m3_xfer>;
    	clock-frequency = <100000>;
    	status = "okay";
    	eeprom@50 {
                    status = "okay";
    				compatible = "at,24c08";
                    reg = <0x50>;
            };
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    eeprom驱动在drivers/misc/eeprom/下面,如果是其他i2c接口芯片在kernel目录下没有驱动,可以去对找对应芯片厂商提供驱动文件

    在这里插入图片描述

    将eeprom的驱动编译进内核测试

    6.3 读写数据测试

    找到模块位置:

    root@linaro-alip:~# find / -name "at24"
    /sys/bus/i2c/drivers/at24
    
    • 1
    • 2

    读eeprom内容:

    在这里插入图片描述

    写eeprom内容:

    在这里插入图片描述

  • 相关阅读:
    关键词生成原创文章软件-原创文章生成软件
    Qt-OpenCV学习笔记--图像二值化--threshold()
    (附源码)ssm高考志愿智能选择系统 毕业设计 134565
    Windows环境下使用python安装PyCrypto模块的方法
    学习-Java输入输出之对象IO流之序列化一个对象
    创建线程的技术难点
    关于Unity 如何与Blazor Server结合
    致谢每一位ChunJun Contributor!这里有一份礼物等你领取!
    JVM相关
    文心一言 VS 讯飞星火 VS chatgpt (285)-- 算法导论21.2 4题
  • 原文地址:https://blog.csdn.net/nb124667390/article/details/134204639