嵌入式Linux系统中触摸屏驱动的研究
在触摸屏设备驱动程序的开发中,全局变量struct s3c2410_ts_device global_ts是很重要的,用来保存触摸屏的相关参数、等待处理的消息队列、当前采样数据、上一次采样数据等信息,数据结构struct s3c2410_ts_device的定义如下:
struct s3c2410_ts_device { //管理触摸屏类
struct s3c2410_ts_general d; //触摸屏设置参数
struct s3c2410_ts_calibration cal; //校正触摸屏参数
struct s3c2410_ts_event buf[MOUSEBUF_SIZE]; //等待处理缓冲队列
struct s3c2410_ts_event cur_data, samples[3],last_data; };
//当前采样数据,采样原始数据,上次采样数据
在了解上面概念之后,编写触摸屏驱动的实际工作并不复杂,需要做如下工作:
3.1模块初始化函数
是调用s3c2410_touchscreen_moudle_init()来实现的,主要完成触摸屏设备的内核模块加载、初始化、中断注册、设备注册等工作,主要涉及到的过程如下:
ADCTSC=(08)|(17)|(16)|(05)|(14)|(03)|(02)|(3);
//触摸屏ADCTSC的设置
ADCDLY=ADC_DELAY_TIME; //触摸屏开始和间隔延时
ADCCON = (114)|( PreScale_n6)|(73)|(02)|(01)|(0);
//触摸屏控制器设置
request_irq(IRQ_ADC_DONE,ts_down_interrupt,SA_INTERRUPT,g_ts_id,ts_down_interrupt); //申请IRQ_ADC_DONE中断
request_irq(IRQ_TC,ts_up_interrupt,SA_INTERRUPT,g_ts_id,ts_up_interrupt);
//申请IRQ_TC中断
devfs_register_chrdev(0,S3C2410_TS_MODULE_NAME,s3c2410_ts_fops);
//注册file_operations结构
request_irq(IRQ_TIMER1,touch_timer_irq,SA_INTERRUPT,g_ts_timer_id,NULL); //申请IRQ_TIMER1中断
touch_timer_irq(int irq, void *dev_id, struct pt_regs *regs)
//根据状态调用触摸中断,控制数据采样
初始化模块利用内核提供的request_irq函数,将触摸笔的按下与弹起的中断号进行登记,从而将中断号与中断服务函数联系起来;利用devfs_register_chrdev函数,向系统注册一个字符型设备;最后注册定时器中断,用来控制触摸屏的数据采样。
3.2 设置触摸笔的状态及对应的处理
触摸屏的中断服务函数ts_down_interrupt和ts_up_interrupt是根据ADCDAT1和ADCDAT0的设置来选择触摸笔的状态,之后调用触摸屏坐标的数据采样处理函数s3c2410_ts_handler()进行处理。部分代码如下:
static void ts_down_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
if ( (ADCDAT10x8000)|| (ADCDAT00x8000) ) {
pen_data.state = PEN_UP;
}
else {
pen_data.state = PEN_DOWN;
}
s3c2410_ts_handler();}
3.3 获得采样值
触摸笔具有三种工作状态:PEN_UP,PEN_DOWN,PEN_SAMPLE。在采样处理函数中,依据触摸笔的状态,调用 ts_timer_operation()来启动或停止采样定时器,然后调用s3c2410_ts_handler()根据不同的状态进行不同的设置和处理,之后得到不同的采样值。
linux操作系统文章专题:linux操作系统详解(linux不再难懂)
评论