您的位置:首页 > 其它

s3c6410 winCE6.0 IIC驱动BUG

2009-11-02 18:23 288 查看
 
前段时间搞winCE6.0,发现使用IIC进行读写外围器件时,有个显现比较怪,写正常,而读则需要打印出信息才正确,否则就是一些无规则的数。当时时间不够没彻底解决,这两天仔细研究了下,终于搞清楚这个问题! 是BSP里IIC驱动的BUG!
s3c6410_iic_lib.cpp里,HW_Read()是实际的控制IIC读的函数。读过程如下:
1.写器件地址(W)+写读地址。
2.写器件地址(R)+接收数据
中断服务里IIC_IST()判断一个读或写完成的条件
        if (bDone)
        {
            RETAILMSG(ZONE_INFO, (TEXT("SetEvent DONE/r/n")));
            SetEvent(g_hTransferDone);
        }
发现这里在读一个字节(4字节TRANSMIT)过程中会有三次进入到bDone条件里面,第一次是正常Master_transmit,第二次没有正常Master_receive,也没有正常Master_transmit,第三次是正常Master_receive。 也就是说中间有一次进入中断是假的,是不应该激发bDone事件的!
 高亮显示bDone,发现bDone是在IIC_IST()里定义的局部变量BOOL bDone = FALSE;只有在开始传输时被设置为FALSE,传输完后一直是TRUE。 所以第二次中断会让这次条件成立,设置g_hTransferDone,而此时还没到读取要读字节的时候,所以读出的数是pOutBuff本来的数据,但是过一会时间,第三次中断到来,真正读取的数据就会进到pOutBuff里。也就是说,如果设置clock够快,还是能够在返回时读取到正确的数值。
总结:
        if (bDone)
        {
            RETAILMSG(ZONE_INFO, (TEXT("SetEvent DONE/r/n")));
         bDone = FALSE;     //添加这行
            SetEvent(g_hTransferDone);
        }
添加的行就不会重复执行一次中断完成事件。

另外,示波器抓波形发现读过程中一直没有ACK,4个字节都是一样。 原来是
 case Master_receive:
          。。。。。
           if (g_uIIC_PT==g_uIIC_DATALEN)
            {
                //g_pIICReg->IICCON &= ~(1<<7);   //注释掉
            }
          。。。。。
         break;
这样波形就对了,有了ACK.

还有,原来读的时候,读两次就可以得到正确的数,由此可以猜想到,IIC寄存器IICDS的写和读是分开的两个寄存器,只是名称一样而已。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  wince c