首页 > 其他 > 详细

触摸屏驱动

时间:2019-11-17 22:23:30      阅读:93      评论:0      收藏:0      [点我收藏+]

硬件配置

硬件原理

技术分享图片

ADC AND TOUCH SCREEN INTERFACE SPECIAL REGISTERS

技术分享图片

?

技术分享图片

?

技术分享图片

?

?

技术分享图片

以 d 3 作 刈 d 了

技术分享图片

?

在砂量X.Y坐标的情况下,应该禁用上拉

技术分享图片

? ?

技术分享图片

? ?

技术分享图片

?

技术分享图片技术分享图片

? ?

技术分享图片

? ?

技术分享图片

? ?

程序框架

软件架构:输入子系统

?技术分享图片

? ?

优化措施

①问题:ADC转换出来的值变化太大,不稳定;

原因1:触摸屏被"触摸",触摸点电压值尚未稳定,已经被ADC转换成数字量;

改善1:设置ADC转换延时(reg:ADCDLY),把延时值设为最大;

? ?

原因2:假设在ADC转换结束之前,触摸屏已"触摸松开",那么转换出来的值将不正确;

改善2ADC转换完成,判断触摸屏状态,如果已经"松开",则认为转换无效,丢弃已转换数据;

? ?

②为了使ADC转换出来的数据稳定可靠,可增加软件滤波算法;

? ?

驱动程序

driver.c

1 /*
2 * 参考s3c2410_ts.c
3 */
4
5 #include <linux/errno.h>
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 #include <linux/input.h>
10 #include <linux/init.h>
11 #include <linux/serio.h>
12 #include <linux/delay.h>
13 #include <linux/platform_device.h>
14 #include <linux/clk.h>
15 #include <asm/io.h>
16 #include <asm/irq.h>
17
18 #include <asm/plat-s3c24xx/ts.h>
19
20 #include <asm/arch/regs-adc.h>
21 #include <asm/arch/regs-gpio.h>
22
23
24 struct s3c_ts_regs{
25 ????????unsigned long ADCCON;
26 ????????unsigned long ADCTSC;
27 ????????unsigned long ADCDLY;
28 ????????unsigned long ADCDAT0;
29 ????????unsigned long ADCDAT1;
30 ????????unsigned long ADCUPDN;
31 };
32
33 static struct timer_list ts_timer;
34 static struct input_dev *ts_dev;
35 static struct s3c_ts_regs *ts_regs;
36
37 static void enter_wait_pen_down(void)
38 {
39 ????????//设置电阻屏"点击"触发中断
40 ????????ts_regs->ADCTSC = 0xd3;
41 }
42
43 static void enter_wait_pen_up(void)
44 {
45 ????????//设置电阻屏"松开"触发中断????????
46 ????????ts_regs->ADCTSC = 0x1d3;
47 }
48
49 static void enter_measure_xy_mode(void)
50 {
51 ????????//测量"被点击"的坐标
52 ????????ts_regs->ADCTSC &= ~((1<<3) | (1<<2));
53 ????????ts_regs->ADCTSC |= ((1<<3) | (1<<2));
54 }
55
56 static void start_adc(void)
57 {
58 ????????//启动ADC
59 ????????ts_regs->ADCCON |= 1;
60 }
61
62 /*
63 * 电阻屏"点击"或"松开"中断事件处理函数
64 */
65 static irqreturn_t pen_down_up_irq(int irq, void* dev_id)
66 {
67 ????????//电阻屏松开状态
68 ????????if (ts_regs->ADCDAT0 & (1<<15))
69 ????????{
70 ????????????????//上报"松开"事件
71 ????????????????input_report_abs(ts_dev, ABS_PRESSURE, 0);
72 ????????????????input_report_key(ts_dev, BTN_TOUCH, 0);
73 ????????????????input_sync(ts_dev);
74 ????????????????enter_wait_pen_down();
75 ????????}
76 ????????//电阻屏点击状态
77 ????????else {
78 ????????????????//"被点击",测量"被点击"坐标
79 ????????????????enter_measure_xy_mode();
80 ????????????????start_adc();
81 ????????}
82 ????????return IRQ_HANDLED;
83 }
84
85 /*
86 * 软件过滤
87 */
88 static int filter_ts(int sadcdat0, int sadcdat1)
89 {
90 ????????//滤波算法
91 ????????return 1;
92 }
93
94 /*
95 * ADC转换中断处理函数:
96 * 条件:ADC中断处理完成,进入中断
97 * 处理:
98 * ①如果已"松开",丢弃转换结果,上报"松开时间",并进入等待"点击";
99 * ②否则,获取转换值:
100 * 连续记录转换出来的坐标值,如果不能连续获得4次坐标值,认为本次获取的坐标值是不准确的,丢弃结果;
101 * 如果成功测得4组数据,则进行软件滤波处理;通过滤波,上报坐标,否则丢弃结果;
102 */
103 static irqreturn_t adc_irq(int irq, void* dev_id)
104 {
105 ????????static int cnt;
106 ????????static int sadcdat0[4], sadcdat1[4];
107 ????????int adcdat0, adcdat1;
108
109 ????????adcdat0 = ts_regs->ADCDAT0;
110 ????????adcdat1 = ts_regs->ADCDAT1;
111 ????????if (ts_regs->ADCDAT0 & (1<<15))
112 ????????{
113 ????????????????cnt = 0;
114 ????????????????input_report_abs(ts_dev, ABS_PRESSURE, 0);
115 ????????????????input_report_key(ts_dev, BTN_TOUCH, 0);
116 ????????????????input_sync(ts_dev);
117 ????????????????enter_wait_pen_down();
118 ????????}
119 ????????else {
120 ????????????????sadcdat0[cnt] = adcdat0 & 0x3ff;
121 ????????????????sadcdat1[cnt] = adcdat1 & 0x3ff;
122 ????????????????cnt ++;
123 ????????????????if (cnt == 4)
124 ????????????????{
125 ????????????????????????if(filter_ts(sadcdat0, sadcdat1))
126 ????????????????????????{
127 ????????????????????????????????//printk("(%d, %d)\n", (sadcdat0[0]+sadcdat0[1]+sadcdat0[2]+sadcdat0[3])/4 , (sadcdat1[0]+sadcdat1[1]+sadcdat1[2]+sadcdat1[3])/4);
128 ????????????????????????????????//上报事件
129 ????????????????????????????????input_report_abs(ts_dev, ABS_X, (sadcdat0[0]+sadcdat0[1]+sadcdat0[2]+sadcdat0[3])/4);
130 ????????????????????????????????input_report_abs(ts_dev, ABS_Y, (sadcdat1[0]+sadcdat1[1]+sadcdat1[2]+sadcdat1[3])/4);
131 ????????????????????????????????input_report_abs(ts_dev, ABS_PRESSURE, 1);
132 ????????????????????????????????input_report_key(ts_dev, BTN_TOUCH, 1);
133 ????????????????????????????????input_sync(ts_dev);
134 ????????????????????????}
135 ????????????????????????cnt = 0;
136 ????????????????????????enter_wait_pen_up();
137
138 ????????????????????????//启动定时器,处理长按、滑动的情况
139 ????????????????????????mod_timer(&ts_timer, jiffies + HZ/100);????????????????//定时10ms
140 ????????????????}
141 ????????????????else {
142 ????????????????????????enter_measure_xy_mode();
143 ????????????????????????start_adc();
144 ????????????????}
145 ????????}
146 ????????return IRQ_HANDLED;
147 }
148
149 /*
150 * 定时器超时处理函数
151 */
152 static void ts_timer_fun(unsigned long data)
153 {
154 ????????if (ts_regs->ADCDAT0 & (1<<15))
155 ????????{
156 ????????????????//已经"松开"
157 ????????????????input_report_abs(ts_dev, ABS_PRESSURE, 1);
158 ????????????????input_report_key(ts_dev, BTN_TOUCH, 1);
159 ????????????????input_sync(ts_dev);
160 ????????????????enter_wait_pen_down();
161 ????????}
162 ????????else {
163 ????????????????//长按、滑动状态,继续测量坐标值
164 ????????????????enter_measure_xy_mode();
165 ????????????????start_adc();
166 ????????}
167
168 ????????return;
169 }
170
171 /* 1、出入口函数 */
172 static __init int sc_init(void)
173 {
174 ????????struct clk *clk;
175
176 ????????/* 1.1、分配一个input_dev结构体 */
177 ????????ts_dev = input_allocate_device();
178 ????????/******** 1.1 end ********/
179
180 ????????/* 1.2、设置 */
181 ????????//1.2.1 事件类设置
182 ????????set_bit(EV_KEY, ts_dev->evbit);
183 ????????set_bit(EV_ABS, ts_dev->evbit);
184
185 ????????//1.2.2 具体事件的产生
186 ????????set_bit(BTN_TOUCH, ts_dev->keybit);
187
188 ????????input_set_abs_params(ts_dev, ABS_X, 0, 0x3FF, 0, 0);
189 ????????input_set_abs_params(ts_dev, ABS_Y, 0, 0x3FF, 0, 0);
190 ????????input_set_abs_params(ts_dev, ABS_PRESSURE, 0, 1, 0, 0);
191 ????????/******** 1.2 end ********/
192
193 ????????/* 1.3 注册 */
194 ????????input_register_device(ts_dev);
195 ????????/******** 1.3 end ********/
196
197 ????????/* 1.4 硬件相关的操作 */
198 ????????//1.4.1 使能ADC外设时钟(CLKCON[15])
199 ????????clk = clk_get(NULL, "adc");
200 ????????clk_enable(clk);
201
202 ????????//1.4.2 设置s3c2440的ADC/TS寄存器
203 ????????ts_regs = ioremap(0x58000000, sizeof(struct s3c_ts_regs));
204
205 ????????ts_regs->ADCCON = ((1<<14) | (49<<6));//设置预分频
206
207 ????????//模数转换延时,使电压值更稳定
208 ????????ts_regs->ADCDLY = 0xffff;
209
210 ????????//1.4.3 注册中断
211 ????????request_irq(IRQ_TC, pen_down_up_irq, IRQF_SAMPLE_RANDOM, "ts_pen", NULL);
212 ????????request_irq(IRQ_ADC, adc_irq, IRQF_SAMPLE_RANDOM, "adc", NULL);
213 ????????enter_wait_pen_down();
214
215 ????????//1.4.4 使用定时器处理长按、滑动
216 ????????init_timer(&ts_timer);
217 ????????ts_timer.function = ts_timer_fun;
218 ????????add_timer(&ts_timer);
219 ????????/******** 1.4 end ********/
220 ????????return 0;
221 }
222
223 static __exit void sc_exit(void)
224 {
225 ????????free_irq(IRQ_TC, NULL);
226 ????????free_irq(IRQ_ADC, NULL);
227 ????????iounmap(ts_regs);
228 ????????input_unregister_device(ts_dev);
229 ????????input_release_device(ts_dev);
230 ????????del_timer(&ts_timer);
231 ????????return;
232 }
233
234 module_init(sc_init);
235 module_exit(sc_exit);
236
237 MODULE_LICENSE("GPL");
238 /******** 1 end ********/

? ?

Makefile

1 KERN_DIR = /work/system/linux-2.6.22.6
2
3 all:
4 ????????make -C $(KERN_DIR) M=`pwd` modules
5

6 clean:
7 ????????make -C $(KERN_DIR) M=`pwd` modules clean
8
????????rm -rf modules.order

9
10 obj-m????????+= ts.o

? ?

? ?

调试

pc-linux:

cd /work/system/linux-2.6.22.6/

make menuconfig(屏蔽触摸屏驱动)

make uImage

cp arch/arm/boot/uImage /work/nfs_root/uImage_nots

? ?

board-uboot:

nfs 30000000 192.168.0.103:/work/nfs_root/uImage_nots

bootm 30000000

? ?

board-linux:

ls /dev/event*

insmod ts.ko

ls /dev/event*

hexdump /dev/event

? ?

技术分享图片

触摸屏驱动

原文:https://www.cnblogs.com/lilto/p/11878187.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!