EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 EDA365_PCB 于 2024-1-22 17:54 编辑
4 a9 R2 h/ f) D9 e+ f5 L& P2 o8 }8 g; k9 K3 p
I2C七宗罪之第五罪——没有ACK怎么办?
, g+ C7 z$ \8 t9 g0 f* MEDA365原创 作者:John . ] b) i: ]! o) W5 ]7 g
每一笔I2C的访问都是随着设备互相之间的ACK后结束的,这就好像你和别人商量个事情,要等到别人答应了,这次对话才算结束;又或者你给别人寄一个包裹,一般要等到收件人收到东西后,给你回了电话,你才会认为东西送到了。 这里的“答应”和“回电话”就等于I2C里面的ACK,这一点在前面都已经反复叙述了,这里不再展开说明(可以戳文段开头的链接回顾哦)。9 u& y. A! g3 e" m6 i% _8 Z
我们先来看看下面这张图:
: [" L& P1 p7 x- T8 P: P
做几点说明,让大家明白讨论内容。
. o+ ]: f5 v( ?! X1.系统串口打印信息如下,表示I2C访问失败: 6 t }) ?- P6 J& V8 J
& h% z$ \+ }, J0 Y
I2C slave device not found num1,addr 0xe2====i2c_send_command_to+scc_rommon send_status Failed. 2 u! y0 P( K3 H* ^% H
I2C slave device not found num1,addr 0xe2====i2c_send_command_to+scc_rommon send_status Failed.
0 i; g6 N; {# e4 z% A1 H' h7 c. {
) B8 Y# N5 a0 G8 i( T, n2.上图中我在ACK的位置坐了标注,细心的读者只要和下面这张正常的图一比较,就可以看出差别,在ACK的位置,SCL为High/SDA为Low,但是上图确刚刚好相反; 3.我们现在知道在第一个ACK的位置, Slave设备本来应该给出SDA=Low,为了更加清楚的分析问题,我们再来一张说明更多的图。 由前面的说明,我知道是Slave设备出了问题,那么到底出了什么问题呢?
; S9 l0 @1 e1 H7 h7 O我们先把最前面那张图的案例分析一下,可能有人已经注意到了图中有一个@-40C,对了,没错!就是我们的交换机放在温箱里面做高低温时,在零下-40C的时候发现的问题。
$ u( t+ G. `5 T% E9 Y. H3 C3 o3 }8 Z. \0 c6 f+ g
有人问-40度下,这波形怎么量到的啊? 这明显问到了关键点上, 硬件工程师的辛苦就体现出来。首先要把I2C信号线和串口线分别从板子上焊接出来,再分别连到外面的示波器和电脑上,然后就苦逼地守着温箱,运气好的话很快就能复现问题,运气不好要折腾很久才能trigger到这个issue,真的是一把辛酸泪啊。
) P. W0 v6 V) d0 B解决的问题过程更加复杂,而且并没有什么技术含量可言——说服Supply Chain的人认为是vendor的器件问题,让他们在芯片生产线做Screen的时候,从原来的泡-40/5分钟改为-45/20分钟,把没有margin的芯片筛选掉。这个和Supply chain以及vendor沟通的过程是痛苦的,大公司嘛,不说了,你们懂的……
" a- d$ j! x' J
( I. f: C( V7 e5 |+ C现在我们知道了器件受环境影响会产生I2C不ACK的问题,下面这张图是另外一种情况,先故设迷局,一起看看下图中有什么问题?
5 |" z' g+ d" O7 Q" W* F 我承认,这个真的不好发现,以前团队中的某工程师在调试一个Sony的IMX291 Sensor时,CPU通过I2C死活访问不了,最后把波形一点一点在示波器上触发下来看,还是看不出来,这就难怪,没有经验确实很难找。 6 i$ f4 Y1 e: h' [3 {
9 g/ u' K5 o6 ^1 R$ v我们先来看单次写操作:
t6 F1 j; {0 z5 T+ i8 K1.Start i: K- Y# `* T6 _
2.Master发device address % q8 n; l8 o, f
3.Master发 R/W为Write
8 o* H* {* J6 [" ~+ M0 n; h: C% E4.Slave 回ACK # Q( N, Z/ Z& S* o7 l6 G. g% P$ K
5.Master发寄存器地址,也叫Word Address - I9 y$ l( j ~& w
6.Slave 再回ACK
0 F+ o6 g0 z/ G/ ]7.Master发要写的数据给Slave " Y0 q# E: l7 K$ w& c: ^) C
8.Slave收到数据后回ACK # W5 R9 B* f H7 U* o& v
9.Master看到ACK后发Stop结束本次操作 2 a1 s1 |' D- t/ A. }) M
! ^# H7 H; c* u4 K- {5 V我们再来看单次多操作:
, D0 q9 r: M. b) v# \/ V' z1.Start : @( }; D( M2 Q/ R
2.Master发device address
5 s7 Y5 Y% x5 p$ Y0 m& l3.Master发 R/W为Write
! ^3 X- n. H( X1 _( V& Y4.Slave 回ACK * l) }1 n4 W( H3 _( ~% ?3 _7 k
5.Master发寄存器地址,也叫Word Address
9 e) W6 q, b$ |$ `6.Slave收到后再回ACK 9 j. {5 D- y6 D+ a
7.此时Slave内部的寄存器指针已经知道对应的寄存器地址
5 I8 q8 f2 g1 H8.Master发start
# B/ F5 V- b: e9.Master再次发device address ! E" H+ S6 E" o* x2 E
10.Master 发R/W为Read
2 W0 V4 ~- p( v) G7 R11.Slave发出ACK $ h; I7 c5 D4 ~7 A& P. o- K8 n
12.Slave发数据给Slave 4 v" c0 H" j" |3 z2 C2 h
13.Master收到数据后发NAK给Slave 34 F+ r& z% r9 }
14.Master发stop结束本次读操作
* Q# I7 \& H/ g) ]" s& b5 @9 g' d8 U! U! ~5 \
所以上图的读操作一共有两个错误,为了防止读者烧脑,我直接标注出来吧: * R1 r! B0 H$ A
不知道大家在前面阅读的时候有没有看出来呢? 特别是第一个Start很容易漏掉,不是老司机一下子真心发现不了。5 M, ?# J' S* F, D
添加了这里漏掉的START和ACK后,我们的Sony Sensor终于可以访问了,所以时刻要注意ACK是否少了。
# f" V" g7 F+ {/ P, y3 t, E# Q6 U, s& O) H
为了让大家清晰理解,这里给出一张完整的逻辑图,大家在理解时要注意和写操作做对比,然后一定要独立思考弄清楚为什么会有这样的差别?一直到自己彻底想明白了,以后独立解决问题的速度也就会变快。 / n7 q3 b1 {5 \' h2 S+ ?
最后我再给大家看一张图,请大家自行研究错在哪里? 答案我们将在“第六宗罪”里面揭晓。 % `% @' h$ d3 R
注:本文为EDA365电子论坛原创文章,未经允许,不得转载。
* j: F2 V" m2 T* ]! y3 o& D0 ^1 ^- W |