EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 EDA365_PCB 于 2024-1-22 17:54 编辑
; a; Y P1 N6 g) A
, u# s K# d' G9 [' D3 K ?I2C七宗罪之第五罪——没有ACK怎么办? - U$ k$ S6 _% C# O+ N
EDA365原创 作者:John / F+ m3 p3 A1 w$ M3 j }8 K5 S
每一笔I2C的访问都是随着设备互相之间的ACK后结束的,这就好像你和别人商量个事情,要等到别人答应了,这次对话才算结束;又或者你给别人寄一个包裹,一般要等到收件人收到东西后,给你回了电话,你才会认为东西送到了。 这里的“答应”和“回电话”就等于I2C里面的ACK,这一点在前面都已经反复叙述了,这里不再展开说明(可以戳文段开头的链接回顾哦)。5 d( F8 R) `5 G6 O( j, m
我们先来看看下面这张图:
" U: j& U, m" t9 ]
做几点说明,让大家明白讨论内容。 9 u6 E% y1 L. Z. a) s# u
1.系统串口打印信息如下,表示I2C访问失败:
9 B3 M0 ]. a: c7 \" X
. [ [' _6 S: E6 U* R& U; lI2C slave device not found num1,addr 0xe2====i2c_send_command_to+scc_rommon send_status Failed.
- e+ E& g0 n7 f' G& KI2C slave device not found num1,addr 0xe2====i2c_send_command_to+scc_rommon send_status Failed.
7 O: m1 o4 @. U7 ^$ Q8 h R6 `" V2 ^) d- L7 R
2.上图中我在ACK的位置坐了标注,细心的读者只要和下面这张正常的图一比较,就可以看出差别,在ACK的位置,SCL为High/SDA为Low,但是上图确刚刚好相反; 3.我们现在知道在第一个ACK的位置, Slave设备本来应该给出SDA=Low,为了更加清楚的分析问题,我们再来一张说明更多的图。 由前面的说明,我知道是Slave设备出了问题,那么到底出了什么问题呢? k, @" e% _( f! I
我们先把最前面那张图的案例分析一下,可能有人已经注意到了图中有一个@-40C,对了,没错!就是我们的交换机放在温箱里面做高低温时,在零下-40C的时候发现的问题。/ m( ]* u0 d/ f6 z0 O$ S7 O& Z
: [" Q' I1 A* v6 m' I7 a5 H- q8 b有人问-40度下,这波形怎么量到的啊? 这明显问到了关键点上, 硬件工程师的辛苦就体现出来。首先要把I2C信号线和串口线分别从板子上焊接出来,再分别连到外面的示波器和电脑上,然后就苦逼地守着温箱,运气好的话很快就能复现问题,运气不好要折腾很久才能trigger到这个issue,真的是一把辛酸泪啊。 3 B' n5 C! c7 u. d& r+ y
解决的问题过程更加复杂,而且并没有什么技术含量可言——说服Supply Chain的人认为是vendor的器件问题,让他们在芯片生产线做Screen的时候,从原来的泡-40/5分钟改为-45/20分钟,把没有margin的芯片筛选掉。这个和Supply chain以及vendor沟通的过程是痛苦的,大公司嘛,不说了,你们懂的…… 6 ~. A0 S2 B7 Q' M7 V4 J& C
, w+ }) r4 S2 [5 P& J5 o: P E现在我们知道了器件受环境影响会产生I2C不ACK的问题,下面这张图是另外一种情况,先故设迷局,一起看看下图中有什么问题?
! P. B3 G* T/ {+ y$ x4 e: d
我承认,这个真的不好发现,以前团队中的某工程师在调试一个Sony的IMX291 Sensor时,CPU通过I2C死活访问不了,最后把波形一点一点在示波器上触发下来看,还是看不出来,这就难怪,没有经验确实很难找。 ' `& P* B6 i- Y% G; E0 ]
$ ?+ A* w) K% P1 g/ T7 C我们先来看单次写操作: $ L! j: P8 s7 k' m1 P
1.Start 9 ?! Q7 X* z8 W& z0 t, Q/ C
2.Master发device address ' K p; p7 j3 m0 d9 L E
3.Master发 R/W为Write 3 V1 B+ l; T; v% d9 s9 y' J
4.Slave 回ACK
- t( m" R+ Q# @# ^: R) \, G- o5.Master发寄存器地址,也叫Word Address
- Z: v: `; f7 N6.Slave 再回ACK $ R4 o$ I: |* M0 _" x" ?2 e8 o' I
7.Master发要写的数据给Slave $ F& r) n5 J+ }; c( _" ]+ g2 |' C7 R$ W
8.Slave收到数据后回ACK E) O) r! A- |. D
9.Master看到ACK后发Stop结束本次操作 ( ?" ]7 N. b9 U2 I ~
5 H6 A* x# `* k+ q) E3 G
我们再来看单次多操作:
3 p) P& c6 m# f" Y2 B1.Start ( _# l# X$ |: s
2.Master发device address
# T a; y$ p; p: J4 O- H! }3.Master发 R/W为Write 2 ~5 w4 ^; g2 p# {/ B/ T$ m
4.Slave 回ACK " D5 V& E; g1 }5 z, j& o
5.Master发寄存器地址,也叫Word Address
2 V6 _; q$ l: I$ r. ?6.Slave收到后再回ACK 7 Y `$ ^+ D% _6 A! D& J p) g
7.此时Slave内部的寄存器指针已经知道对应的寄存器地址 2 |' U2 t$ e8 M8 Z
8.Master发start
" w1 G& I/ @) t' o/ D9.Master再次发device address
! m- Q7 f0 E6 k, ?, F10.Master 发R/W为Read
# U+ G% N6 q" j: ]# m( {11.Slave发出ACK $ t" D" u/ U* Q
12.Slave发数据给Slave
1 \7 Q. S$ l' X4 P# r: ~! T13.Master收到数据后发NAK给Slave 3
% b* M3 G4 ^/ H14.Master发stop结束本次读操作
" \6 K' K: C" v: W6 Q8 t+ ?: i$ u+ }0 q' Q0 r" A
所以上图的读操作一共有两个错误,为了防止读者烧脑,我直接标注出来吧: $ w4 p+ ^. ?) @/ K8 G; ^
不知道大家在前面阅读的时候有没有看出来呢? 特别是第一个Start很容易漏掉,不是老司机一下子真心发现不了。) l$ i2 @( S2 E, u6 S
添加了这里漏掉的START和ACK后,我们的Sony Sensor终于可以访问了,所以时刻要注意ACK是否少了。5 R/ R. ~5 a/ L: E* K7 K* }! s
; i' u, a2 y8 l v) X% @8 T2 a为了让大家清晰理解,这里给出一张完整的逻辑图,大家在理解时要注意和写操作做对比,然后一定要独立思考弄清楚为什么会有这样的差别?一直到自己彻底想明白了,以后独立解决问题的速度也就会变快。
5 i+ @6 e" ?1 t最后我再给大家看一张图,请大家自行研究错在哪里? 答案我们将在“第六宗罪”里面揭晓。
8 H+ I! c8 p3 I, y1 ?4 S注:本文为EDA365电子论坛原创文章,未经允许,不得转载。 / t2 R, I- W5 o5 a
|