嵌入式linux驱动-触摸屏笔记

来源:互联网 发布:云收银软件 编辑:程序博客网 时间:2024/05/17 22:53

一、开发环境

1、内核:Linux 2.6.22.6;

2、JZ2440v3

3、ubuntu 9.10

二、过程


三、程序

#include <linux/errno.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/init.h>#include <linux/serio.h>#include <linux/delay.h>#include <linux/platform_device.h>#include <linux/clk.h>#include <asm/io.h>#include <asm/irq.h>//#include <asm/plat-s3c24xx/ts.h>#include <asm/arch/regs-adc.h>#include <asm/arch/regs-gpio.h>static struct input_dev *myts_dev;static struct timer_list ts_time;struct ts_regs{unsigned long adccon;unsigned long adctsc;unsigned long adcdly;unsigned long adcdat0;unsigned long adcdat1;unsigned long adcupdn;};static volatile struct ts_regs *ts_regs;static int enter_pen_up_mode(void){ts_regs->adctsc=0x1d3;return 0;}static void enter_pen_down_mode(void){ts_regs->adctsc=0xd3;}static void enter_measure_xy_mode(void){ts_regs->adctsc=(1<<3)|(1<<2)|(3<<0);}static void start_adc(void){ts_regs->adccon |=(1<<0);}static int filter_ts(int x[],int y[]){#define ERR_LIMIT 10int avr_x, avr_y;int det_x, det_y;avr_x = (x[0] + x[1])/2;avr_y = (y[0] + y[1])/2;det_x = (x[2] > avr_x) ? (x[2] - avr_x) : (avr_x - x[2]);det_y = (y[2] > avr_y) ? (y[2] - avr_y) : (avr_y - y[2]);if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))return 0;avr_x = (x[1] + x[2])/2;avr_y = (y[1] + y[2])/2;det_x = (x[3] > avr_x) ? (x[3] - avr_x) : (avr_x - x[3]);det_y = (y[3] > avr_y) ? (y[3] - avr_y) : (avr_y - y[3]);if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))return 0;return 1;}static int adc_irq(int irq,void  *dev_id){static int cnt;static int x[4],y[4];int adcdat0,adcdat1;adcdat0=ts_regs->adcdat0 & 0x3ff;adcdat1=ts_regs->adcdat1 & 0x3ff;if(ts_regs->adcdat0 &(1<<15)){//已经松开cnt=0;input_report_abs(myts_dev, ABS_PRESSURE, 0);input_report_key(myts_dev, BTN_TOUCH,0);input_sync(myts_dev);enter_pen_down_mode();}else{//未松开x[cnt]=adcdat0;y[cnt]=adcdat1;++cnt;if(cnt==4){if(filter_ts( x,y))//printk("adc_irq cnt=%d,x=%d,y=%d \n",cnt,(x[0]+x[1]+x[2]+x[3])/4,(y[0]+y[1]+y[2]+y[3])/4);input_report_abs(myts_dev, ABS_X, (x[0]+x[1]+x[2]+x[3])/4);input_report_abs(myts_dev, ABS_Y, (y[0]+y[1]+y[2]+y[3])/4);input_report_abs(myts_dev, ABS_PRESSURE, 1);input_report_key(myts_dev, BTN_TOUCH, 1);input_sync(myts_dev);cnt=0;enter_pen_up_mode();//启动定时器处理长按滑动的情况mod_timer(&ts_time, jiffies+HZ/100);}else{enter_measure_xy_mode();start_adc();}}return IRQ_HANDLED;}static void ts_timer_function(unsigned long data){if(ts_regs->adcdat0 &(1<<15)){//已经松开,进入等待按下模式input_report_abs(myts_dev, ABS_PRESSURE, 0);input_report_key(myts_dev, BTN_TOUCH,0);input_sync(myts_dev);enter_pen_down_mode();}else{//否则再次启动转换测量xy坐标enter_measure_xy_mode();start_adc();}//return IRQ_HANDLED;}static int pen_updown_irq(int irq,void  *dev_id){if(ts_regs->adcdat0 &(1<<15)){printk("pen_up!\n");enter_pen_down_mode();}else{printk("pen_down!\n");//enter_pen_up_mode();enter_measure_xy_mode();start_adc();}return IRQ_HANDLED;}static int ts_init(void){static struct clk *adc_clock;//1.分配一个input_dev结构体myts_dev=input_allocate_device();//2设置//2.1能产生那类事件set_bit(EV_KEY,myts_dev->evbit);set_bit(EV_ABS,myts_dev->evbit);//2.2能产生这类事件里的那类事件set_bit(BTN_TOUCH,myts_dev->keybit);input_set_abs_params(myts_dev, ABS_X, 0, 0x3FF, 0, 0);input_set_abs_params(myts_dev, ABS_Y, 0, 0x3FF, 0, 0);input_set_abs_params(myts_dev, ABS_PRESSURE, 0, 1, 0, 0);//3注册input_register_device(myts_dev);//4硬件相关的操作//4.1使能时钟adc_clock = clk_get(NULL, "adc");clk_enable(adc_clock);//4.2设置s3c2410触摸屏寄存器ts_regs=ioremap(0x58000000, sizeof(struct ts_regs));ts_regs->adccon=(1<<14)|(49<<6);request_irq(IRQ_TC, pen_updown_irq, IRQF_SAMPLE_RANDOM,"ts_action", NULL);request_irq(IRQ_ADC, adc_irq, IRQF_SAMPLE_RANDOM,"ts_adc", NULL);//优化延时ts_regs->adcdly=0xffff;//使用定时器处理长按滑动的情况init_timer(&ts_time);ts_time.function=ts_timer_function;add_timer(&ts_time);enter_pen_down_mode();return 0;}static void ts_exit(void){free_irq(IRQ_TC, NULL);free_irq(IRQ_ADC, NULL);iounmap(ts_regs);input_unregister_device(myts_dev);input_free_device(myts_dev);del_timer(&ts_time);}module_init(ts_init);module_exit(ts_exit);MODULE_LICENSE("GPL");




0 0
原创粉丝点击