免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3250 | 回复: 9
打印 上一主题 下一主题

求助:mpc8xx CPU的I2C使用问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-03-29 22:53 |只看该作者 |倒序浏览
嵌入式Linux系统,CPU使用powerPC系列的mpc875,CPU通过I2C与一个slave设备相连,需要提供通讯接口,接口很简单,即向slave设备写入一个字节,或者从slave设备读取一个字节。

目前遇到的问题是:mpc875提供的I2C 读时序与该slave要求的读时序不一致,并且好像无法调整为一致(写时序没有问题)。
mpc875 datasheet上讲的I2C接口的使用方式大致为:
发送:准备好发送缓冲区的数据,其中第一个字节为 slave设备地址(7 bit)+写命令(1 bit),后边的字节为要发送的数据,然后设置缓冲区描述符BD,设置I2C Command寄存器给一个起始信号,剩下的事情都是CPU自己完成(根据I2C标准协议进行)。
接收:发送缓冲区准备n+1个字节,其中第一个字节为 slave设备地址(7 bit)+读命令(1 bit),后边的n个字节只是为了提供严格的时序,即CPU在发出第一个字节之后便等待从slave接收数据。设置好接收缓冲区描述符及相应的缓冲区,设置I2C Command寄存器给一个起始信号,剩下的事情都是CPU自己完成。
每次读/写都会自动产生一个I2C起始条件,完成之后会产生一个I2C结束条件。
而slave要求的读时序为:接收到I2C起始条件后,要接收一个字节的地址+写命令,接着还需要一个字节的slave内部寄存器地址,然后再接收I2C起始条件,再接收一个字节的slave地址+读命令,然后才开始向CPU发送数据。
上述读时序中包括了两次命令,第一次写,第二次读,但两次之间没有I2C结束条件,这样slave接收到相应的信号后当作一个完整的命令,才能响应CPU。而mpc875 CPU中好像每一个命令都包含了I2C起始和结束条件,这样两个命令就会被分开,不会算作一个命令,因此slave无法响应,从slave读取字节总是失败,此时mpc875的I2C中断寄存器I2CER中显示txErr

请教各位大侠,这种情况应该怎么处理?mpc875提供的I2C到底该如何使用啊,貌似不符合一般情况啊。。。小弟不胜感激。

论坛徽章:
5
2 [报告]
发表于 2010-04-02 13:09 |只看该作者
而mpc875 CPU中好像每一个命令都包含了I2C起始和结束条件,这样两个命令就会被分开,不会算作一个命令,因此slave无法响应,从slave读取字节总是失败,此时mpc875的I2C中断寄存器I2CER中显示txErr
lonia3390 发表于 2010-03-29 22:53



   
明白你的问题。但按你所述,MPC875这样时序,是不符合I2C协议的。貌似不太可能。读命令一定会是:start + slave addr + read bit + bytes + end.

如果按你所讲:mpc875 CPU中好像每一个命令都包含了I2C起始和结束条件,这样两个命令就会被分开,不会算作一个命令
start + slave addr + read bit + bytes + end. 就变成了 start + slave addr + read bit + end  + start + bytes + end. 成了两个transactions.
前面的一个transaction (start + slave addr + read bit + bytes + end), 符合协议,可以被slave解析。 后面的start + bytes + end, 不符合协议,没有设备会响应它,总线必然会停留在ACK/NAK阶段,最后导致超时。

论坛徽章:
0
3 [报告]
发表于 2010-04-03 22:47 |只看该作者
I2C_FUNC_I2C

ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset)

  Do combined read/write transaction without stop in between.
  Only valid if the adapter has I2C_FUNC_I2C.  The argument is
  a pointer to a

  struct i2c_rdwr_ioctl_data {
      struct i2c_msg *msgs;  /* ptr to array of simple messages */
      int nmsgs;             /* number of messages to exchange */
  }

  The msgs[] themselves contain further pointers into data buffers.
  The function will write or read data to or from that buffers depending
  on whether the I2C_M_RD flag is set in a particular message or not.
  The slave address and whether to use ten bit address mode has to be
  set in each message, overriding the values set with the above ioctl's.


static u32 cpm_i2c_func(struct i2c_adapter *adap)
{
        return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
}

论坛徽章:
0
4 [报告]
发表于 2010-04-05 16:15 |只看该作者
仔细查一下寄存器看有没有控制不发送第一个i2c stop的地方,很多i2c芯片对这个i2c stop是可选的。

论坛徽章:
0
5 [报告]
发表于 2010-04-06 15:32 |只看该作者
可以选择用GPIO仿真I2C时序的方式,这样就不用去设置I2C寄存器了,而且平台一直也很方便!

论坛徽章:
0
6 [报告]
发表于 2010-04-20 21:30 |只看该作者
本帖最后由 lonia3390 于 2010-04-20 21:40 编辑
明白你的问题。但按你所述,MPC875这样时序,是不符合I2C协议的。貌似不太可能。读命令一定会是 ...
yidou 发表于 2010-04-02 13:09


问题解决了,呵呵,多谢版主,多谢各位大侠的热心回复。

读命令时序是这样的:start + (slave addr + write bit) + (slave reg) + start + (slave addr + read bit) + [read byte] + stop
第2个start之前不能有stop

发送和接收数据是通过缓冲区描述符(Buffer Descriptor, BD)来进行的,一个BD包含一个Control/Status寄存器,一个数据长度和一个指向数据缓冲区的指针,在Control/Status寄存器中对当前BD进行设置,其中有一位是设置当前BD是否包含最后一个字符,如果包含,则当前BD对应的Buffer数据发送出去之后会产生一个stop条件,如果不包含,则不产生stop条件。

这个问题关键就在这里是否产生stop条件,当时没弄明白这一位的意义,所以试了多次都没能成功,呵呵

最近太忙了,还没来得及总结一下,等过段时间有空了稍微整理下,与大家共同研究

论坛徽章:
0
7 [报告]
发表于 2010-04-20 21:32 |只看该作者
I2C_FUNC_I2C

ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset)

  Do combined read/write  ...
Roemer 发表于 2010-04-03 22:47



    mpc8xx使用BD,本质与这个相同,呵呵,多谢

论坛徽章:
0
8 [报告]
发表于 2010-04-20 21:34 |只看该作者
仔细查一下寄存器看有没有控制不发送第一个i2c stop的地方,很多i2c芯片对这个i2c stop是可选的。
garyv 发表于 2010-04-05 16:15



    一语中的,确实有的,可以控制是否发送第1个stop,当时没弄明白这个意义,呵呵,多谢

论坛徽章:
0
9 [报告]
发表于 2010-04-20 21:36 |只看该作者
可以选择用GPIO仿真I2C时序的方式,这样就不用去设置I2C寄存器了,而且平台一直也很方便!
wmmy2008 发表于 2010-04-06 15:32



    模块也是不错的方法,以前做过模拟的,这次想直接使用CPU的I2C控制器,呵呵,有时间的话倒可以试试模拟的,多谢

论坛徽章:
0
10 [报告]
发表于 2010-04-21 11:08 |只看该作者
static u32 cpm_i2c_func(struct i2c_adapter *adap)
{
        return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
}
这句话就是出自mpc8xx的驱动~~
说明驱动本身就支持!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP