找回密码
 注册
关于网站域名变更的通知
查看: 7347|回复: 11
打印 上一主题 下一主题

I2C七宗罪之第一罪

  [复制链接]
  • TA的每日心情
    开心
    2023-5-19 15:05
  • 签到天数: 339 天

    [LV.8]以坛为家I

    跳转到指定楼层
    1#
    发表于 2018-12-7 10:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    本帖最后由 alexwang 于 2018-12-12 13:45 编辑
    1 C# L1 e, |: h0 B" O
    6 q* O8 x) i( g( q/ e  A9 \7 {  Q, ]
    , H2 M" I+ F( B% }. C3 R2 u% ~- L, G
    I2C七宗罪之第一罪
    EDA365原创 作者:John

    ; Q9 v8 \0 l4 y5 ]( p( n8 G
    七宗罪,七个天主教的罪过,简称七宗罪。宗为来源、根源的意思。! `6 k1 E; S- f3 [4 l0 |' z8 J

    7 @/ h& e6 A; U% l7 x0 i
    天主教教义中提出“按若望格西安和教宗格里高利一世分辨出教徒常遇到的重大恶行”。“重大”在这里的意思在于这些恶行会引发其他罪行的发生,罪行按严重程度递增依次为傲慢、嫉妒、愤怒、懒惰、贪婪、淫欲和暴食。

    " i5 b: ]( p  }1 n- S7 z) l
    0 g3 O0 J0 O9 e$ B8 f
    , O: i2 m& I& C* q8 d9 |. A

    ' Z6 k0 S+ a' {' x3 U7 q' ^, G4 U4 _" n

    ) O& Z) a+ o2 E8 s& ?% }

    4 Y( H( Q' k( {0 e; t, X' t
    有些工程师聊起I2C的时候,会有不屑一顾的感觉, “切,不就是两根线吗,一个时钟,一个数据”!每每碰到这些人,就会有一种感觉,兄dei,你真是坑没有踩够啊!
    下面是我按照本人工作时间先后顺序,列出碰到过的I2C的问题。有一点我要强调一下,我所列出的问题,不是从书上看来或者从哪里杜撰来的,每一个问题都是来自于不同的公司以及不同的项目,由本人亲历并且解决好的问题,希望对年轻的工程师和EDA365网友们有所帮助!
    2005年, 在L公司(想想当年的L公司,那可是风光的很。)的光网络系统上有一块叫LKAXXX的线卡上出现了一个怪事,说到这里,肯定有人一看到MPC860, 就忍不住笑了, 一看就是上了年纪的大叔,哎,岁月不饶人呐 ^_^,我刚刚从学校里毕业的时候就是MPC860差不多诞生的时候。
    : ]' q2 g  I3 S- P; n  y5 ]' E( V/ j

    : B6 {4 W0 Q% i$ Y/ F

    / p2 S, P7 g5 Z. K. O* }7 c
    先来描述一下问题:
    - w  }7 Z  A1 l
    1. 经常当有人按下Reset button后发现系统起不来了,UART console打印了一半就死在那里;
    2. 再次按下复位后,症状一样, 不管怎么按复位按钮系统都死,UART打印一点点信息挂在那里;
    3. 多次按复位按钮无效后,断电重启后OK;
    4. 大部分情况,同一块板子按复位按钮后是OK的,但是少数情况是Fail的。

    + e& ^, c% A& L* p$ m$ A
    这时候很多网友就会说,这不是很简单,让软件用调试器加断点跟踪啊,说对了,我们firmware工程师还是很牛逼的,很快就告诉我们问题出在I2C上, 我们用示波器测量在死机情况下的I2C信号,发现SDA数据信号一直是低电平,怎么复位都没有用,一直是低,只有断电重启后,SDA才变高。那么原因初步定位了,正式因为I2C-SDA被强行拉低,才导致系统起不来,而断电后SDA被释放了,系统也就正常了。
    我们知道I2C是open drain的,肯定是被什么芯片给拉了啊,这个很容易想到,不应该是CPU, 因为CPU已经被复位了啊, 那么怀疑的对象就到了和CPU相连的Device上, 乍一看下面的原理图, 我Kao,这是连连看么?还能有比这个更加简单的事情吗?

    ( R% C. T4 K. I1 h/ l) R; `  e

    7 |; T5 s/ t$ Q; @
    那么究竟是什么原因导致SDA被EEPROM拉低了呢?
    我们再来看一张图:

    2 K+ U2 j0 I8 u( `. y! r! E1 b

    ) k4 ?- Z5 ]1 Z
    我们看到这里对EEPROM的处理比较特殊, 在绝大部分的原理图里面,我从来都看不到,就是把EEPROM的电源加一个开关:

    ' S. b6 ]: Y3 M) w- S
    1. 当复位为低电平时,EEPROM的VDD连到低,断电;
    2. 当复位为高电平时,EEPROM的VDD重新连到外部的VDD,恢复供电。
    0 Y6 _! \8 b: Z+ D$ J
    这时候聪明的EDA365小伙伴们已经悟出来, Kao!刚刚上面的LKAXXX的板子,如果我们每次按下复位按钮复位CPU的时候,通过按钮产生的复位信号High-Low-High由这里的开关电路把EEPROM的电源断开一会儿,是不是EEPROM就不会去把SDA拉低了啊,Bingo, 对了。
    可是又有人说了,这不是增加成本嘛,还有啊,也没有看见有人这么干过啊,哈哈,对了,只有日本人才会这么用一根筋的设计方法,我们中国人永远找到更好的解决办法,我们继续往下走。
    5 ?& _" T& O0 p# e8 L
    请看下面这张图,有没有很熟悉?
    这是一个I2C的读操作,顺序如下:
    . c! V6 X+ i. }% O. q2 M
    1. Master发出start;
    2. Master发出地址和读命令;
    3. Slave给出ACK然后发出数据data7-0,这一共8拍由slave来驱动I2C SDA,(这里要记住SCL一直是由master来驱动的,当然后面也有特殊情况,这个我们留在后面的七宗罪里面详述),8拍的时间(假设100K的速率,周期为10us)是80us。

    1 n1 J9 }, I: f' ^4 `
    停停停停停, 搞笑的事情来了,如果在这80us的时间里面,有人按下了复位按钮, 会怎样 ?

    5 W4 K) i; o! c' n8 H- y
    举个“栗子”

    % x) b6 r' T0 `% f0 n. N( t
    假设四个人打麻将,我的上家把牌打出来后,就该轮到我出牌了,可是这时候来了个电话,我去接电话了, 等我回到牌桌后,我忘记了刚刚轮到我出牌,我以为上一把结束了,直接把麻将推倒洗牌了,这时候等着我的下家可就不干了,人家等着我出牌好胡呢。然后我这重来的举动惹恼了人家,道歉也好,赔不是也罢,人家不接受,不玩了!得嘞,这局麻将是玩不下去了。

    $ t7 ?+ c( ~( X5 r9 m* d: m
    类比上面I2C的情况,想象一下:
    1. 80us的时候 EEPROM Slave正在配合CPU输出读的数据,人家玩得正high呢;
    2. 这时候CPU收到一个复位指令,而且是强行复位,类似于接电话;
    3. 等到CPU复位完了,完全忘记了刚刚EEPROM正在drive数据,甚至有可能EERPROM已经传完8bit数据,正在CPU的NAK(看上图),这事搁谁身上能受得了;
    4. 这种情况CPU看起来也是没有办法,谁叫我们按下了复位按钮了呢。还有一种情况就是CPU自己不厚道,比如去执行优先级中断程序后,回来也忘记了别人(EEPROM)正在等待自己继续刚才的工作。
    ' U& }8 b0 ^% _3 u
    这里肯定会有人问,不是复位了吗? 请仔细看上面的原理图, EEPROM是没有复位管脚的,也就是说, 我们按下复位按钮时, CPU复位了,但是EEPROM没有复位,它的状态机还在等待输出数据给CPU或者等待CPU的NAK指令以便结束当前的这笔操作,这和上面打麻将的例子是一回事。
    那么请问刚刚的SDA被拉低是怎么回事呢?很简单, 上图的ACK就是低电平,或者Slave drive的data bit7-0其中有高有低啊。
    那么除了上面给EEPROM的电源加开关的方式,我们还有上面办法来解决这个问题呢?
    # u, t! m6 G# }1 U% c
    我们继续看图:
    ! {' n2 x/ g" A% a) m$ R
    先来想想刚刚打麻将的事情,如果我打完麻将回来后,直接牌友每个人100块钱,别人肯定是乐意继续陪你玩的,很简单的办法解决了问题。如上图, 我们让软件工程师在代码里面做了下修改:

    , j0 F, G0 ^1 d- [
    1. 当检测到SDA被拉低后;
    2. 软件就持续发送9个时钟;
    3. 在发9个clock的过程中SDA会变高变低;
    4. 当Device发完所有数据后,SDA被释放;
    5. 此时状态机到达NAK的phase时,SDA释放变高,产生了一个NAK;
    6. 注意此时9个时钟不一定用完,EEPROM就把到达NAK phase把SDA释放了,但是CPU是不知道的,他会一直发完9个时钟;
    7. 最后CPU再发送一个stop把整个读操作结束掉;
    6 S: N" D& U: n% e& f& \9 c
    The 9 clock pulses make the hanging device’s state machine move to the next state after each clock pulse while the SDA released (not pulled down) which will cause a NACK when the state machine will move to the ACK phase. The NACK will force the device to go to idle mode(意思和我上面的步骤一样)。
    . z; R  R, ^- ?9 \5 K
    1. Master tries to assert a logic 1 on the SDA line;
    2. Master still see a logic 0 and then generate a clock pulse on SCL;
    3. When device come to NAK phase, then master will generate SDA high which;is a NAK, but master does not know, until master send all the 9 clocks;
    4. Master Generate a stop condition。

    & \( t. z/ J- T) w+ Z5 f+ u
    上面讲的是I2C读操作被中断导致死机的情况,下面聊聊I2C写操作被中断的情况,解决办法“简单粗暴”一些, 大家想想为什么。
    " D/ t+ i- j  B4 c
    : \* u* {& i8 q; @( _8 K
    这里一样还是只发9个时钟,在9个时钟的过程中,device就可能发出一个ack,CPU看到ACK后,再发一个stop结束本次操作:

      f3 ?# a2 F2 p& N2 {0 L+ }: A
    : }) ]) e$ {9 g! u
    1. Master tries to assert a logic 1 on the SDA line;
    2. Master still see a logic 0 and then generate 9 clock pulse on SCL;
    3. Generate a stop condition。
    ; p& J- S' T! M" ~* x. v- \
    这里要注意,写操作被中断时,发出的9个clock一定是等到最后一个时钟发完, device才被释放。而读操作则不一定,有可能发了第一个时钟时device就被释放了只是CPU不知道,到第9个时钟时stop。

    3 q! V/ d3 D  D. ~3 v; `
    文章结束,给大家留一个思考题,为什么这里一定是9个时钟呢?欢迎在EDA365电子论坛留言讨论,想明白了,这篇文章你就看懂了。
    注:本文为EDA365电子论坛原创文章,未经允许,不得转载。
    1 d* |% u4 P1 m5 c! s
  • TA的每日心情
    奋斗
    2020-8-11 15:51
  • 签到天数: 1 天

    [LV.1]初来乍到

    推荐
    发表于 2020-5-8 14:10 | 只看该作者
    受教了,虽然现在看不懂,但以后肯定会用到

    “来自电巢APP”

  • TA的每日心情
    慵懒
    2019-12-4 15:45
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    2#
    发表于 2018-12-19 17:52 | 只看该作者
    连载啊,期待~
  • TA的每日心情
    开心
    2020-3-18 15:31
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    3#
    发表于 2019-11-28 14:00 | 只看该作者
    对I2C没有接触,但是看了楼主的文字,觉得也只有亲身经历过才会这么清楚,赞!
  • TA的每日心情
    慵懒
    2020-3-11 15:24
  • 签到天数: 1 天

    [LV.1]初来乍到

    5#
    发表于 2020-5-8 18:51 | 只看该作者
    多谢分享

    “来自电巢APP”

    该用户从未签到

    6#
    发表于 2020-5-12 20:55 | 只看该作者
    是不是一次会发送8位数据,还有一位是结束用的?

    “来自电巢APP”

    该用户从未签到

    7#
    发表于 2020-5-18 23:30 | 只看该作者
    CPU 断电复位情况好像还是存在没有解决?

    “来自电巢APP”

    该用户从未签到

    8#
    发表于 2020-11-25 10:35 | 只看该作者

    该用户从未签到

    9#
    发表于 2020-11-25 10:43 | 只看该作者
    谢谢分享

    “来自电巢APP”

    该用户从未签到

    10#
    发表于 2020-11-26 08:52 | 只看该作者

    该用户从未签到

    11#
    发表于 2020-11-26 09:18 | 只看该作者
    看不太懂,哈哈,让我遇到就完了

    “来自电巢APP”

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-6-23 23:18 , Processed in 0.125000 second(s), 27 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表