Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页

    【分析笔记】Linux I2C-Tools 使用踩坑笔记

    Linux
    2
    4
    2909
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D
      dream LV 6 last edited by

      一、踩坑缘由

      在调试 I2C 器件时,我一般习惯于使用 i2cdetect 工具来确认芯片是否有应答,通常有应答之后,就会开始着手移植或者编写对应的驱动程序,但是在调试 sgp41 传感器时却不灵了。

      af47336d-7d7b-48d3-9364-c7444169fe07-image.png

      二、问题现象

      在连续完成多个 I2C 器件的调试和驱动开发之后,最后一个 sgp41 传感器却一直无法被检测到。在使用示波器再次测量芯片供电、检查I2C波形、引脚顺序、电平匹配都正确后,认为是芯片坏了,换了多颗芯片,都无法识别,寄给供应商,供应商又说检测良好,这就很神奇了。

      在同一个座子上,sht41 都能正常被检测到,但是 sgp41 却无法检测,更何况该总线上还挂了其它的 I2C 器件都能准确检测出来。

      79255a34-d236-47af-bc7e-d6f253c1a09c-image.png

      9de9cad8-a396-4d44-99d4-5ffc0dd27a8d-image.png

      三、问题分析

      百思不得其解,在仔细观察逻辑分析仪解析的结果,发现在检测 0x44(sht41) 器件地址的时候,i2cdetect 使用的是采用写的方式检测,而检测 0x59(sgp41) 器件地址时,采用读的方式检测。

      由于之前调试过 sht41 器件,知道这类传感器需要先写再读,才会有应答信号(规格书没有体现出来),因此推测跟这个有关。手写了一个 I2C 设备驱动,先写再读取,发现可以正常通信,证实了我的猜测。

      023395f3-6231-42f6-83ae-639177f866f6-image.png

      四、深入分析

      我特别好奇的是,为什么 i2cdetect 工具会对不同的地址段采用不同的方式进行检测,我分析了 i2cdetect.c 源代码,发现默认是以自动模式检测,而自动模式则会根据不同的地址段采取读或写来实现检测。

      源码下载:http://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/i2c-tools-4.0.tar.gz

      3665f900-2e13-43b7-bd8b-f4a73d965f09-image.png

      如果需要检测类似 sht41、sgp41 这种必须要先写再读才会有应答的芯片,就必须要指定检测模式为写检测(MODE_QUICK),由于 sht41 的器件地址 0x44 恰好在自动模式中以写的方式检测,因此可以检测得到。通过分析源码发现,-r 和 -q 即可指定读写模式:

      74ab0cc3-dcc8-42c6-a9ce-b67146028b7b-image.png

      下图为指定以写的方式检测 sgp41(0x59),可以发现有应答信号,被检测出来了:

      81ff8c47-984b-4b79-b686-83f178c4a678-image.png

      五、经验总结

      1. 不是所有的 I2C 器件都会直接响应读请求。
      2. 使用 i2cdetect 工具检测芯片,建议使用 -q 和 -r 参数都试试。
      1 Reply Last reply Reply Quote Share 3
      • DAIZEBIN
        DAIZEBIN LV 7 last edited by

        按照你的说法,如果使用i2cdetect 工具,不指定参数的话,使用的是以自动模式检测,自动模式在sht41体现为读模式,所以检测不出来?😣 😣

        D 1 Reply Last reply Reply Quote Share 0
        • D
          dream LV 6 @DAIZEBIN last edited by

          @daizebin sht41 的器件地址是 0x44,就决定了在自动模式下,是以写方式检测,所以可以识别到,但是 sgp41 的器件地址是 0x59,落在了以读方式检测的范围,所以无法识别到。具体看本文 scan_i2c_bus() 的源码截图就能看出来。

          D 1 Reply Last reply Reply Quote Share 0
          • D
            dream LV 6 @dream last edited by

            @dream 在 【分析笔记】Linux I2C-Tools 使用踩坑笔记 中说:

            @daizebin sht41 的器件地址是 0x44,就决定了在自动模式下,是以写方式检测,所以可以识别到,但是 sgp41 的器件地址是 0x59,落在了以读方式检测的范围,所以无法识别到。具体看本文 scan_i2c_bus() 的源码截图就能看出来。

            再补充一下,不是所有的 I2C 器件都必须要以写的方式才能检测出来,只有少部分,如 sht41\sgp41 这类器件比较特别,需要先写再读才有应答,正因为大部分 I2C 器件无论是读写都会有应答,所以才会因惯性思维,导致踩坑。

            1 Reply Last reply Reply Quote Share 1
            • 1 / 1
            • First post
              Last post

            Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

            行为准则 | 用户协议 | 隐私权政策