一.简介
触摸屏(touch screen)又称为“触控屏”、“触控面板”,是一种可接收触头等输入讯号的感应式液晶显示装置,当接触了屏幕上的图形按钮时,屏幕上的触觉反馈系统可根据预先编程的程式驱动各种连结装置,可用以取代机械式的按钮面板,并借由液晶显示画面制造出生动的影音效果。触摸屏作为一种最新的电脑输入设备,它是目前最简单、方便、自然的一种人机交互方式。
二.工作原理
关于fl2440的触摸屏的移植,首先要了解关于输入设备是怎样与用户进行交互的。
在linux的输入子系统中,低层驱动(例如按键被按下,触摸屏被触摸,鼠标点击等)都会发生相应的事件,而驱动就会把事件提交给上层,我们在来说一下s3c2440触摸屏工作的原理,触摸屏的接口与ADC的接口是集成在一起的,触摸屏要正常的工作就离不开ADC的转换。
上图是功能方框图,假如我们在触摸屏上按下,它会产生x,y方向上的两个模拟信号(xp,yp)进入到AD转换器,然后再触发相应的中断(分为ADC和TC两种)来进行处理,然后在中断处理程序中来上报数据。
三.内核配置
[leiyuxing@centos6 linux-3.0]$ make menuconfig
Device Drivers --->
Input device support --->
<*> Event interface
<*> Event debugging
[*] Touchscreens --->
<*> Samsung S3C2410/generic touchscreen input driver
四.修改配置文件
[leiyuxing@centos6 linux-3.0]$ vim arch/arm/mach-s3c2440/mach-smdk2440.c
.......
58 #include //添加头文件
......
164 /* Touch Screen driver info add by leiyuxing */
165 static struct s3c2410_ts_mach_info smdk2440_ts_cfg __initdata = {
166 .delay = 10000,
167 .presc = 49,
168 .oversampling_shift = 2,
169 };
......
235 static struct platform_device *smdk2440_devices[] __initdata = {
236 &s3c_device_ohci,
237 &s3c_device_lcd,
238 &s3c_device_wdt,
239 &s3c_device_i2c0,
240 &s3c_device_iis,
241 &s3c_device_dm9000,
242 &uda1340_codec,
243 &s3c24xx_uda134x,
244 &samsung_asoc_dma,
245 &s3c_device_adc, /* modify by leiyuxing */
246 &s3c_device_ts, /* modify by leiyuxing */
247 };
......
270
271 static void __init smdk2440_machine_init(void)
272 {
273 s3c24xx_fb_set_platdata(&smdk2440_fb_info);
274 s3c_i2c0_set_platdata(NULL);
275 s3c24xx_ts_set_platdata(&smdk2440_ts_cfg);/*Add Touch Screen info by leiyuxing*/
.......
126 input_report_abs(ts.input, ABS_Y, ts.yp);
127
128 input_report_key(ts.input, BTN_TOUCH, 1);
129 input_report_abs(ts.input, ABS_PRESSURE, 1);//Add by leiyuxing
130 input_sync(ts.input);
......
316
317 ts.input = input_dev;
318 //ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
319 ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT(EV_SYN); /*Modify by leiyuxing*/
320 ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
321 input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0);
322 input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0);
323 input_set_abs_params(ts.input, ABS_PRESSURE, 0, 1, 0, 0); /*Add by leiyuxing*/
324
325 ts.input->name = "S3C24XX TouchScreen";
[leiyuxing@centos6 linux-3.0]$ make
内核打印如下信息:
多出了event 0设备说明移植成功!!!
六.编写测试程序
[leiyuxing@centos6 ~]$ mkdir TEST
[leiyuxing@centos6 ~]$ cd TEST/
[leiyuxing@centos6 TEST]$ vim test.c
#include
#include
static int event0_fd = -1;
struct input_event ev0[64];
static int handle_event0()
{
int button = 0, realx=0, realy=0, i, rd;
rd = read(event0_fd, ev0, sizeof(struct input_event)* 64);
if(rd < sizeof(struct input_event)) return 0;
for(i=0;i 0)
{
close(event0_fd);
event0_fd = -1;
}
return 0;
}
七.用交叉编译器编译test.c文件将生成的可执行文件test拷贝到开发板上并赋予可执行权限:
[leiyuxing@centos6 TEST]$ /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc test.c -o test[leiyuxing@centos6 TEST]$ ls
test test.c
>: tftp -gr test 192.168.1.2
test 100% |*******************************| 6114 0:00:00 ETA
>: chmod 777 test
>: ./test
begin handle_event0...
当触摸屏幕时会打印如下信息:
event(0):type:3; code: 0; value:546; realx:546; realy: 0
event(1):type:3; code: 1; value:741; realx:546; realy:741
event(2):type:1; code:330; value: 1; realx:546; realy:741
event(3):type:0; code: 0; value: 0; realx:546; realy:741
end handle_event0...
begin handle_event0...
event(0):type:1; code:330; value: 0; realx: 0; realy: 0
event(1):type:0; code: 0; value: 0; realx: 0; realy: 0
end handle_event0...
begin handle_event0...
event(0):type:3; code: 0; value:542; realx:542; realy: 0
event(1):type:3; code: 1; value:720; realx:542; realy:720
event(2):type:1; code:330; value: 1; realx:542; realy:720
event(3):type:0; code: 0; value: 0; realx:542; realy:720
end handle_event0...
begin handle_event0...
event(0):type:1; code:330; value: 0; realx: 0; realy: 0
event(1):type:0; code: 0; value: 0; realx: 0; realy: 0
end handle_event0...
八.使用tslib测试
1.tslib背景:
在采用触摸屏的移动终端中,触摸屏性能的调试是个重要问题之一,因为电磁噪声的缘故,触摸屏容易存在点击不准确、有抖动等问题。
Tslib是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能,通常作为触摸屏驱动的适配层,为上层的应用提供了一个统一的接口。
http://download.csdn.net/detail/scholar_fish/4167788
[leiyuxing@centos6 linux-3.0]$ tar -zxvf tslib-1.4.tar.gz
3.安装
[leiyuxing@centos6 linux-3.0]$ cd tslib
[leiyuxing@centos6 tslib]$ ./autogen.sh
./autogen.sh生成./configure文件
[leiyuxing@centos6 tslib]$ mkdir tslib
[leiyuxing@centos6 tslib]$ cd tslib/
[leiyuxing@centos6 tslib]$ pwd
/home/leiyuxing/fl2440/kernel/linux-3.0/tslib/tslib
注:./configure --prefix=(你自己的安装目录)--host=arm-linux ac_cv_func_malloc_0_nonnull=yes CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc
例如:
[leiyuxing@centos6 tslib]$ ./configure --prefix=/home/leiyuxing/fl2440/kernel/linux-3.0/tslib/tslib --host=arm-linux ac_cv_func_malloc_0_nonnull=yes CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc
[leiyuxing@centos6 tslib]$ make
[leiyuxing@centos6 tslib]$ make install
[leiyuxing@centos6 tslib]$ cd tslib/
[leiyuxing@centos6 tslib]$ ls
bin etc include lib
4.进入到安装目录下,将 bin etc include lib这四个目录打包成一个文件,拷贝到开发板上,在/app/下建立tslib目录
[leiyuxing@centos6 tslib]$ tar -czf tslib.tar.gztslib
>: cd apps
>: tftp -gr tslib.tar.gz 192.168.1.2
tslib.tar.gz 100% |*******************************| 63738 0:00:00 ETA
>: tar -xzf tslib.tar.gz
>: ls
tslib tslib .tar.gz
>: cd tslib/
>: ls
bin etc include lib
>:cd
>:vim /etc/profile
最后还要修改一下配置文件,在vi /apps/tslib/etc/ts.conf 末尾添加
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear
注:
a)、ts.conf文件中的各个设置选项之前不能有空格,否则会出现:Segmentation fault 错误,我就不小心在module...之前多了个空格,害我查了好久。
b)、 不要在pointercal对应的目录下,建立一个空的pointercal文件,否则在运行ts_calibrate时,也可能会出现Segmentation fault
>:cd /apps/tslib/bin
>: ls
ts_calibrate ts_harvest ts_print ts_print_raw ts_test
>: ./ts_calibrate
xres = 480, yres = 272
Took 28 samples...
Top left : X = 155 Y = 319
Took 2 samples...
Top right : X = 166 Y = 327
Took 11 samples...
Bot right : X = 800 Y = 714
Took 24 samples...
Bot left : X = 182 Y = 803
Took 2 samples...
Center : X = 348 Y = 684
277.548950 0.549850 -0.384807
-67.502930 0.061765 0.321581
Calibration constants: 18189448 36034 -25218 -4423872 4047 21075 65536
执行后屏幕上,依次出现5个点,依次点击进行校准,校准完毕后,在/etc下会产生pointercal文件,供其他用户使用,ts_calibrate是一个应用程序,在屏幕上画几个按钮,将用户点击后从
ts驱./ts_print 将屏幕坐标打印出来,比如:
1796351007.320859: 156 116 500 按下
1796351007.355145: 156 116 0 抬起
./ts_print_raw 将屏幕坐标的原始数据打印出来,比如:
1796350964.530867: 216 865 1 按下
1796350989.946831: 0 0 0 抬起
动获得的数据和屏上的坐标通过一套算法来获得校准的数据写到一个校准文件里
./ts_test 检测一下校正的结果,屏幕上出现两个按钮,分别为,Drag时,光标随着手指移动,另一个Draw是在屏幕上画画
屏幕最上方会出现二个按钮,分别为“Drag”、“Draw”,默认是第一个,因此,用触摸笔点击任何一处,十字光标便会到那里。
下面是点击“Draw”按钮并用触摸笔写字的提示信息的一小部分:
265.910352: 270 35 1
265.915326: 265 36 1
265.920129: 261 36 0
316.820271: 718 108 1
316.820271: 718 108 1
316.825324: 718 108 1
316.830363: 714 108 1
316.835188: 708 108 0
第一列为timeval结构体的两个成员:tv_sec和tv_usec,中间两列分别是X和Y的坐标,最后为pressure,这里可以理解成“触摸事件”,为1表示触摸笔点击了(接触)屏幕,为0表示触摸笔离开了屏幕(这里出现很多的1是正常的,因为写字过程中笔没有离开触摸屏)。
按Ctrl+C可退出该程序。
开发板上出现的问题可参考以下文章:
http://blog.csdn.net/xdw1985829/article/details/6670523
http://blog.sina.com.cn/s/blog_664c545f0100vpvh.html
遇到的问题:
问题一:
>: ./ts_calibrate
./ts_calibrate: can't load library 'libts-0.0.so.0'
解决方法:
>: cd /apps/tslib/lib
>: cp libts-0.0.so.0 /lib
问题二:
No raw modules loaded.
Ts_config: No such file or directory
解决办法:
修改$T_ROOT/etc/ts.conf, 至少放开一个module_raw,并去掉前面空格