发一份Linux2.6.24下用的CH452驱动程序

自己写的……2线制,使用了内核的I2C子系统。只用到了自己需要的几个命令,还有几个命令(如左/右移)没有写

原文发在自己的博客http://ujimori.info/?p=729

驱动程序源码+测试代码:http://ujimori.info/wordpress/wp-content/uploads/2012/05/ch452.zip

一、总述

驱动的基本结构与MCP2510类似,可分为I2C控制器驱动与CH452芯片驱动。因为我们使用的内核中已经有很完善的S3C6410的I2C控制器驱动,因此我们要完成的只有CH452芯片驱动。

因为没有发送数据的需求(控制LED的工作由Ioctl来做),所以没有write函数。所多的无非是向内核的I2C子系统注册驱动的过程。而关于内核I2C子系统的内容,很多书上都已经介绍得很详细,不再赘述。

二、CH452的简单介绍

具体的内容请自行参考CH452的芯片手册。在此只说几个可能要特别注意的地方。

CH452接收的I2C命令都是12bit长度。这12bit中,高4bit构成了I2C的7位地址中的低4bit,低8bit则作为后续数据进行读/写(是读是写视I2C发送地址的最末一位而定。具体请参见I2C总线规范)。而7位地址的高3bit,最高两位固定是01b,第3位为芯片管脚ADDR的值(详见数据手册P9)。在我们的电路中,ADDR被接到VCC上,所以应该为1。 所以, 我们在对CH452进行操作时,要用到的I2C地址不止有1个。详细对照之后可以看到7bit的I2C地址是在0×30~0x3F范围内。这在驱动程序注册i2c client时要特别注意 二线制的CH452应该说只是兼容I2C的时序,但不能严格称之为I2C设备。默认情况下,它是不会向I2C主设备发送ACK信号的。这一点要特别留意。虽然芯片手册说可以用一条I2C命令开启ACK发送功能,但实际测试中发现并没有出现应有的ACK信号。 CH452芯片手册上称I2C数据速率可在500bps~400Kbps之间。但实际测试时,使用344kbps速率时发现I2C总线工作不稳定。因而应将I2C速率适当降低。

三、向I2C子系统注册驱动程序

ch452_init()中调用的i2c_add_driver()函数完成了驱动向I2C子系统注册的过程。调用顺序如下:

ch452_init()

→i2c_add_driver()

→i2c_register_driver()

I2C设备驱动有new style与legacy style的区别。两者似乎使用了不同的注册/操作接口,不可混用。我们这里讨论的都是legacy style。i2c_register_driver()函数中,会对每个I2C adapter调用一次driver->attach_adapter(adapter)。此函数也是由我们自己来实现的,具体到本驱动中就是ch452_attach_adapter()函数。

在ch452_attach_adapter()函数中,有对CH452芯片的初始化操作,最后调用i2c_probe()函数,将i2c client结构关联到i2c adapter上。i2c_probe()函数的第二参数为一个struct i2c_client_address_data类型的指针,该结构提供了待注册的i2c client的地址。我们要关注的只有其中的normal_i2c成员。这个指针提供的I2C地址,如果没有出现在ignore结构中,就对其调用i2c_probe_address()函数。在此函数中,确认该地址的可用性(即确认该地址没有被其它i2c cilent使用)后,调用函数第三个参数found_proc指向的函数。具体到我们的驱动程序中,就是ch452_detect()函数。在这个函数中,初始化i2c client结构、调用i2c_attach_client(),真正完成i2c client与i2c adapter的关联过程。在对normal_i2c内所有地址都完成这个调用过程后,驱动向I2C子系统的注册过程才算结束。

如上所述,CH452要用到I2C地址为0×30 ~ 0x3F,因而在驱动初始化时,向struct ch452_dev结构的client成员分配了16个struct i2c_client的空间,用于这16个地址的i2c client的注册。

四、I2C控制器工作过程

向CH452发送I2C命令,全部是通过i2c_transfer()函数来实现。注意所有struct i2c_msg的flags都被加上了I2C_M_IGNORE_NAK标志。这是因为目前因为未知原因没能打开CH452的ACK使能。I2C控制器驱动在没有接收到ACK的时候会认为发送失败并中止发送过程。因此,加上I2C_M_IGNORE_NAK标志,让I2C控制器忽略对ACK的处理。

i2c_transfer()函数中,通过调用i2c_adapter的algo->master_xfer(adap,msgs,num),实现真正的发送。在i2c-s3c2410.c中的第579行可看到:

static const struct i2c_algorithm s3c24xx_i2c_algorithm = {

.master_xfer = s3c24xx_i2c_xfer,

.functionality = s3c24xx_i2c_func,

};

s3c24xx_i2c_xfer()中有一个重发循环,通过调用s3c24xx_i2c_doxfer()进行发送,如果发送失败则等待+重发。s3c24xx_i2c_doxfer()中,先s3c24xx_i2c_set_master()将控制器配置为主设备(该驱动不支持从设备模式),s3c24xx_i2c_enable_irq()使能I2C中断,最后用s3c24xx_i2c_message_start()开启发送过程。在中断处理中,再根据s3c24xx_i2c控制器设备的state进行不同的处理。可以说整个I2C发送过程就是由中断驱动的,具体的工作过程请自己跟踪代码。很多书上也有相关的讲解。

看了你写的流程,实际上你需要使用硬件IIC来操作CH452,你可以到这里去下载例子程序。 http://www.wch.cn/bbs/View.asp?S=103&I=28488


正好想学习这个,,谁知道下载不了... 求楼主回复!


刚试了下可以下载的啊


楼主的资料可以下载?


楼主,您好!现在这个Linux2.6.24下用的CH452驱动程序还有吗?我现在使用Linux 内核驱动CH452遇到了些问题,想请教您,可否留一下联系方法?我的微信13193356406,谢谢


有关CH452驱动的问题,可直接与我们的技术支持联系025-52638376


只有登录才能回复,可以选择微信账号登录