【分析笔记】Linux I2C-Tools 使用踩坑笔记
-
一、踩坑缘由
在调试 I2C 器件时,我一般习惯于使用 i2cdetect 工具来确认芯片是否有应答,通常有应答之后,就会开始着手移植或者编写对应的驱动程序,但是在调试 sgp41 传感器时却不灵了。
二、问题现象
在连续完成多个 I2C 器件的调试和驱动开发之后,最后一个 sgp41 传感器却一直无法被检测到。在使用示波器再次测量芯片供电、检查I2C波形、引脚顺序、电平匹配都正确后,认为是芯片坏了,换了多颗芯片,都无法识别,寄给供应商,供应商又说检测良好,这就很神奇了。
在同一个座子上,sht41 都能正常被检测到,但是 sgp41 却无法检测,更何况该总线上还挂了其它的 I2C 器件都能准确检测出来。
三、问题分析
百思不得其解,在仔细观察逻辑分析仪解析的结果,发现在检测 0x44(sht41) 器件地址的时候,i2cdetect 使用的是采用写的方式检测,而检测 0x59(sgp41) 器件地址时,采用读的方式检测。
由于之前调试过 sht41 器件,知道这类传感器需要先写再读,才会有应答信号(规格书没有体现出来),因此推测跟这个有关。手写了一个 I2C 设备驱动,先写再读取,发现可以正常通信,证实了我的猜测。
四、深入分析
我特别好奇的是,为什么 i2cdetect 工具会对不同的地址段采用不同的方式进行检测,我分析了 i2cdetect.c 源代码,发现默认是以自动模式检测,而自动模式则会根据不同的地址段采取读或写来实现检测。
源码下载:http://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/i2c-tools-4.0.tar.gz
如果需要检测类似 sht41、sgp41 这种必须要先写再读才会有应答的芯片,就必须要指定检测模式为写检测(MODE_QUICK),由于 sht41 的器件地址 0x44 恰好在自动模式中以写的方式检测,因此可以检测得到。通过分析源码发现,-r 和 -q 即可指定读写模式:
下图为指定以写的方式检测 sgp41(0x59),可以发现有应答信号,被检测出来了:
五、经验总结
- 不是所有的 I2C 器件都会直接响应读请求。
- 使用 i2cdetect 工具检测芯片,建议使用 -q 和 -r 参数都试试。
-
按照你的说法,如果使用i2cdetect 工具,不指定参数的话,使用的是以自动模式检测,自动模式在sht41体现为读模式,所以检测不出来?
-
@daizebin sht41 的器件地址是 0x44,就决定了在自动模式下,是以写方式检测,所以可以识别到,但是 sgp41 的器件地址是 0x59,落在了以读方式检测的范围,所以无法识别到。具体看本文 scan_i2c_bus() 的源码截图就能看出来。
-
@dream 在 【分析笔记】Linux I2C-Tools 使用踩坑笔记 中说:
@daizebin sht41 的器件地址是 0x44,就决定了在自动模式下,是以写方式检测,所以可以识别到,但是 sgp41 的器件地址是 0x59,落在了以读方式检测的范围,所以无法识别到。具体看本文 scan_i2c_bus() 的源码截图就能看出来。
再补充一下,不是所有的 I2C 器件都必须要以写的方式才能检测出来,只有少部分,如 sht41\sgp41 这类器件比较特别,需要先写再读才有应答,正因为大部分 I2C 器件无论是读写都会有应答,所以才会因惯性思维,导致踩坑。
Copyright © 2023 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号