I2C七宗罪之第六罪——枯燥的协议

EDA365 2019-03-07 11:43
关注我们
遇见更好的攻城狮自己!


I2C七宗罪(连载)
I2C七宗罪之第一罪
I2C七宗罪之第二罪
I2C七宗罪之第三罪
I2C七宗罪之第四罪
I2C七宗罪之第五罪

(点击文章题目,即可阅读往期精彩!)


I2C第六罪


越到后面的几宗罪,难度越来越大,请读者要认真仔细的思考,确保学为己用。

先来讲个有趣的故事,我们在大学里喜欢去图书馆自习的时候抢位置,特别是喜欢抢靠近漂亮女生旁边的位置,可以一边上自习一边欣赏美女,^_^

当你要临时离开一会儿的时候,方法也比较简单,就是放一本书在椅子上,很多时候当你回来的时候却发现你的书被人拿开了,椅子上坐着的另外一个帅哥和旁边的那位美女在攀谈,恨的牙痒痒啊。

你能做的就是等那位帅哥和美女聊完走人,你再回到那个座位上,可是你却沮丧的发现,刚刚旁边那位美女也走了,换了另外一位男的,唉,人生最悲惨的事情不过如此。

下面给出一张图,大家来看看是否存在问题。这张图是用I2C协议分析仪抓出来的,乍一看也没啥问题,该有的都有,特别是最后在Stop之前的NAK也是有的,但真的是OK的吗?

我们再来看一张图。

对比这两张图,我们得出:这是一个读数据的操作。

要找到第一张图的问题其实不难,我们只要仔细核对就可以了。

下面是核对出来的结果,我们发现在第二个Start之前,多了一个Stop。 这样一看,这个错误还是挺明显的。

说说总是很容易,软件工程师在代码里构建这个时序的时候,很自然会认为,前面第一笔的写操作(把Word address写入Slave的指针)已经结束,后面的一笔,读操作开始之前就应该Stop掉。


为了清洗的说明,我们列一个顺序如下:

1.Master把要读的数据(或者寄存器)的Address先写入Slave,这里要注意理解好,这里Word Address相当于是一笔数据;

2.此时要注意整个读操作刚刚进行了一半,千万不能加Stop;

3.Master在收到前面写操作的ACK后,发一个Start;

4.Master再发一次Device Address,然后开始接收读的数据;

5.Master收到数据发一个NAK, 然后再发一个Stop结束整笔操作。

有人问,既然我们在第二个Start前多加了一个Stop,也没有见系统报错,一切正常啊,有时候访问还是成功的,这到底是为什么啊?

这里有个原因很重要:因为读操作最后是有Master发出的NAK + Stop来结束掉的,而NAK是SDA-HIGH,所以即便有时候操作不正常,只要不操作SDA(SDA默认的电平时HIGH),也能得到NAK误导对方。

我们继续来说一下,如果第二Start前面多了一个Stop会产生什么样的现象?

这是发生在ONU光猫上的Issue,现象是:从光模块SFP读回来的数据值总是不对,反复试验发现偶尔也能读对,但是写操作都是准确的。

这里一定会有人问,你读操作不正常,怎么知道写的是对的啊? 好问题, 我们通过设置环回和打开/关闭光模块等写寄存器操作,反复确认我们写寄存器的操作是准确的。

我们来看光模块的I2C读写标准SFF-8431里面的图,可以看到一次读操作和前面叙述的一样,分为两个部分,中间用一个START隔开。

1.Master写device address =0XA2和写命令

2.Master发出word address 0X6E

3.Master插入第二个Start

4.Master再次发出device address =0XA2和读命令

5.Master接收光模块的数据0X82

6.Master发NAK

7.Master发Stop结束本次操作

注意:图中黑色部分是我们在Vendor的平台上用准确的方式读写抓到的波形。

如果按照上面所说的,我们在中间加了一个Stop会产生什么样的现象呢?

 为啥读数据会不正确,但是I2C总线并没有出错信息吖? 前面我们已经林林总总的叙述了一些,下面给出最终的描述。

看下面这张图,是我们和Samtec的FAE在出问题的板子上一起抓到的波形图,很明显我们看到多了一个Stop,下面我们来进行分析:

1.Master写device address =0XA2和写命令

2.Master发出word address 0X6E

3.Master多插入了一个Stop

4.Master插入第二个Start

注意:下面被插入了一笔完整的写数据的操作。

5.Master又发出device address =0XA2和写命令

6.Master发出word address 0X7F

7.Master发出写的数据0X80

注意:开始接着上面未完成的读操作继续

8.Master又多插入了一个Stop

9.Master又插入第二个Start

10.Master再次发出device address =0XA2和读命令

11.Master接收光模块的数据,我们看到读到的数据是全0,为什么呢?

12.Master发NAK

13.Master发Stop结束本次操作

相信很多人已经晕了,这到底是咋回事啊?

原来:一笔读操作,由于中间多了一个Stop,所以系统软件进程误以为前面读操作完成了,所以横空插进来一个写的操作,并且这里的写操作准确的完成了。

在写操作完成了,我们看到Master试图继续完成刚刚被中断掉的读操作,其实这也可以啊,大不了分两次,只要最终数据能准确读出来也行,可我们此时得到的数据却不是刚刚的0X82了,而是0X00,这又是为什么呢?


我们来结合这张图描述一下发生错误的过程:

1.Master开始读操作的第一步把0X6E写入Device;

2.此时被插入另外一个写操作;

3.写操作顺利完成并且把Pointer写成了0X7F(注意已经不是原来的0X6E);

4.Master继续刚才被中断的写操作;

5.注意此时Pointer的值是0X7F,所以读到的值是0X7F这个地址的值。

这里就清楚了:一次完整的I2C读操作访问,如果中间加了不应该有的Stop,就会被其它进程强占,从而插入另外的写操作,导致访问memory或者寄存器的地址指针被覆盖,Master然后接着完成刚刚被中断的操作,也不能正确读写到要访问的值。


这里分享几件有趣的事:

1.由于只是读有问题,写操作是好的,所以产品的功能是OK的,在市场卖了那么多,都没有人发现这个问题,也蛮搞笑的;

2.I2C的读操作一直NAK操作是SDA=HIGH, 由于SDA默认就是High(前面讲过Open drain和上拉),所以即便设备没有做什么? 也会让等待NAK的设备误认为NAK已经产生了;

3.系统软件有时候是会和硬件打架的,所以相互合作才能找到问题的根源,否则相互推责任只会让解决问题很困难;

4.发现问题并且解决问题,写个文章很简单,但是调试的过程却是痛苦的,特别是I2C这种接口,一共2根线,很多人比较轻视,这是不可取的。


——END——



产品研发必修课:EMC安规整改及设计关键技术点系列研讨会(一)|| EDA365公益培训


I2C七宗罪之第四罪——电平转换

90%的DSP事故都是因为它造成的……

除了“干货”,工程师们最在乎的是什么?

PCB 布线是机械活?错!layout 最关键设计步奏都在这里了……

看更多精彩文章

请长按下方图片扫码关注


EDA365

WWW.EDA365.COM

专注电子工程师的价值提升与体现


给我【好看】

你也越好看!

EDA365 EDA365网站官方公众号,定期分享热门技术,行业新闻,培训课程,线下活动以及高端职位推荐。
评论
热门推荐
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦