s3c6410 winCE6.0 IIC驱动BUG

 

前段时间搞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的写和读是分开的两个寄存器,只是名称一样而已。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值