设为首页 加入收藏

TOP

Linux下i2c与时钟芯片PCF8563的通信
2014-11-24 08:29:36 来源: 作者: 【 】 浏览:2
Tags:Linux i2c 时钟 芯片 PCF8563 通信

Linux下的i2c驱动以及与时钟芯片PCF8563通信过程。


为更深入的了解linux下的i2c总线驱动以及通信原理,可以用一个用户程序模拟,这个程序,可以使用一个addr, 一个offset,对i2c的从设备地址为addr,寄存器地址为offset的寄存器读写操作。


在我们的版卡上时钟芯片pcf8563的i2c地址为0x51 , pcf8563有00—0f个寄存器,通过读写秒,分钟,小时等的寄存器,可以验证我们的程序是否执行成功。


一,这个测试程序怎么写?


思路是: hwclock -w /hwclock -s 这些命令都是对始终芯片pcf8563执行了读写的操作命令,那么我们的程序,就模仿hwclock -w 的执行过程,最后实现通过cpu(octeon) 与i2c从设备的数据通信。 这样就看到了i2c总线在处理器octeon的控制下的通信过程。


二,怎么观察hwclock -w 的执行过程?


hwclock -w 读写了时钟芯片pcf8563,那么从pcf8563的驱动程序入手,在pcf8563中的read,write 函数中进入i2c层。再有i2c层进入octeon。


即从rtc层进入i2c层, 再进入cpu层。 在这之间的执行函数分别加printk,在版卡上观察dmesg, 这样就可以找到执行的层层路径。


知道了数据的发送路径,再观察出hwclock -w 实现了哪些数据的包装和发送,那么我们的程序就可以在以用户层模仿这些操作。


注意:


我们版卡的cpu是CaviumNetworks OCTEON CN52XX


********************************************************************


by 韩大卫 @卓讯技术@吉林师范大学


handawei@jusontech.com


转载务必表明出处!


********************************************** **********************


hwclock -w 命令需要使用到的rtc芯片pcf8563中的读写函数如下:



在driver/rtc/rtc-pcf8563.c 中


static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
int i, err;
unsigned char buf[9];


printk(KERN_DEBUG "%s: secs=%d, mins=%d, hours=%d,ecs=%d, mins=%d, hours=%d\n",
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);



/* hours, minutes and seconds */
buf[PCF8563_REG_SC] = bin2bcd(tm->tm_sec);
buf[PCF8563_REG_MN] = bin2bcd(tm->tm_min);
buf[PCF8563_REG_HR] = bin2bcd(tm->tm_hour);


buf[PCF8563_REG_DM] = bin2bcd(tm->tm_mday);


/* month, 1 - 12 */
buf[PCF8563_REG_MO] = bin2bcd(tm->tm_mon + 1);


/* year and century */
buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year % 100);
if (pcf8563->c_polarity (tm->tm_year >= 100) : (tm->tm_year < 100))
buf[PCF8563_REG_MO] |= PCF8563_MO_C;


buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;


/* write register's data */
for (i = 0; i < 7; i++) {
unsigned char data[2] = { PCF8563_REG_SC + i,
buf[PCF8563_REG_SC + i] };



err = i2c_master_send(client, data, sizeof(data));
if (err != sizeof(data)) {
dev_err(&client->dev,
"%s: err=%d addr=%02x, data=%02x\n",
__func__, err, data[0], data[1]);
return -EIO;
}



在 driver/i2c/i2c-core.c 中:



int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
{
int ret;
struct i2c_adapter *adap=client->adapter;
struct i2c_msg msg;


msg.addr = client->addr;
msg.flags = client->flags & I2C_M_TEN;
msg.len = count;
msg.buf = (char *)buf;

//added by handwei.2012.7.5
printk(KERN_DEBUG "%s: msg.addr = %x,msg.flags = %x,msg.len = %d,msg.buf[0] = %x,msg.buf[1] = %x\n",__func__,msg.addr,msg.flags,msg.len,msg.buf[0],msg.buf[1]);


ret = i2c_transfer(adap, &msg, 1);


/* If everything went ok (i.e. 1 msg transmitted), return #bytes
transmitted, else error code. */
return (ret == 1) count : ret;
}



注意: i2c_transfer(adap, &msg, 1);


中的 1 决定了 进入 octeon_i2c_xfer ()后,要进入 if(num==1)中。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇openGL的project matrix 和 model.. 下一篇网络间通信socket传输任意格式任..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Python 数据分析与可 (2025-12-26 21:51:20)
·从零开始学Python之 (2025-12-26 21:51:17)
·超长干货:Python实 (2025-12-26 21:51:14)
·为什么 Java 社区至 (2025-12-26 21:19:10)
·Java多线程阻塞队列 (2025-12-26 21:19:07)