谈谈MXL608的坑和I2C的时钟拉伸功能

Posted by LuckXiang on March 23, 2018

MXL608是MaxLinear的一款tuner产品,支持DVB-C/DVB-T/DVB-T2/ATSC/ISDB-T等制式应用,这款芯片的调试工作占用了我2017年一个多月的时间,先是给客户调试linux和ecos驱动花了大半个月,弄了一个临时解决方案,后来领导想在公版方案彻底解决这个问题,又把我拖进去搞了半个月。中间找了很多人都没办法搞定,还好我最后灵光一闪,找到了问题的根本点,也算是2017年比较大的一个成就吧。在我看来,MXL608这个芯片确实做得很烂,原厂的驱动代码也写得很烂,下边我就谈谈这个芯片的问题和经验教训.

MXL608有那些坑

1.芯片硬复位异常,芯片很容易挂掉,只能软复位 2.683的ts输出没有高阻状态,主芯片使用内置demod的时候,需要683的ts输出高阻才能避免信号干扰。没办法,这个时候只能把683 disable掉,用的时候重新初始化。 3.683如果没有正常初始化,会响应其他设备地址的信号并把总线拉低,导致i2c死锁。 4.683需要下载固件,原厂的驱动代码直接把几十k的固件写成一个局部变量,像ecos这种堆栈空间大的跑起来没问题,linux内核这种函数堆栈很小的系统,一跑就挂了。 5.683有clock stretching功能,这个功能原厂支持的人居然也不知道,参考手册里边也没有说明,而且手册有个地方很奇怪,读数据的时候,写完寄存器地址需要等500ms才能再读数据,处理完这个问题之后回头看这个地方,明显是为了规避clock stretching功能,开发工程师都没有理解这个东西,给以后的使用者埋下了一堆隐患。

I2C的clock stretching怎么回事

时钟拉伸是I2C协议的一个标准,它允许从设备来不及响应主设备请求的时候主动拉低总线,等数据处理完在释放总线。就是说主设备向从设备读数据,主设备发完地址,从设备说我给你数据需要时间,我先把总线拉低,等我数据准备好了再释放。然而这个功能需要主从设备都支持才行,很多I2C控制器都没有实现时钟拉伸,比如说我们的主芯片就没有,这个时候会导致什么问题呢?主设备并不知道总线被拉低了,所以会继续读取数据,导致读取到的数据都是0。读完之后又发起下一次请求,这个时候683就会挂掉。这个问题怎么解决呢,只能修改I2C频率,先估算683处理好数据需要多少时间,然后计算出大概的频率,或者直接用二分法去找到一个稳定的I2C频率。这样修改之后整条I2C总线速度都降下来了,只能是无奈之举。

这种底层问题怎么调

处理问题最关键的是要找到问题域,在问题的领域上去分析,比如说驱动的问题,你就直接去调驱动,如果你从应用去调试是很难解决的,如是没办法定位,我一般习惯从最底层开始调试,先测试接口问题,保证驱动最底层的调用是正常的,再一级一级往上排查,像这个683的问题,我直接查看I2C数据读写接口,发现没问题,那问题基本上就在硬件上或者协议上了,分析协议和硬件这一层的问题,一定需要调试设备,比如说这个问题就需要逻辑分析仪抓波形,结合协议去分析。处理问题要大胆猜测,细心排除,一个一个可能的原因排查过去,总会发现一丝曙光的,特别是有些疑难杂症,如果没有足够的毅力和细致,很容易就变成不治之症。