博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
韦东山视频实验之触摸屏
阅读量:2446 次
发布时间:2019-05-10

本文共 7315 字,大约阅读时间需要 24 分钟。

在触摸屏实验里遇到的问题:

1. 在加载模块时,就会出现采样数据

# insmod ts.ko

input: s3c2440_touch_screen as /devices/virtual/input/input0
init touch screen input dev
pen down
adc_irq cnt = 0, x = 10, y = 543
adc_irq cnt = 1, x = 507, y = 420
adc_irq cnt = 2, x = 514, y = 420
adc_irq cnt = 3, x = 516, y = 420
pen up

不知何解??

2.在触摸触摸屏弹出的数据更是奇怪,有些相差较大,下面是一次完整的触摸过程闯过来的数据,而且根本没有进入设置的过滤函数??

# pen down

adc_irq cnt = 0, x = 124, y = 471
adc_irq cnt = 1, x = 186, y = 392
adc_irq cnt = 2, x = 224, y = 370
adc_irq cnt = 3, x = 258, y = 368
pen up
pen down
adc_irq cnt = 0, x = 70, y = 500
adc_irq cnt = 1, x = 371, y = 407
adc_irq cnt = 2, x = 121, y = 398
adc_irq cnt = 3, x = 185, y = 381
adc_irq cnt = 0, x = 154, y = 449
adc_irq cnt = 1, x = 279, y = 386
adc_irq cnt = 2, x = 156, y = 386
adc_irq cnt = 3, x = 135, y = 394
pen up
pen down
adc_irq cnt = 0, x = 95, y = 484
adc_irq cnt = 1, x = 335, y = 400

3.在input下的

# cat devices

I: Bus=0013 Vendor=dead Product=beef Version=0100
N: Name="s3c2440_touch_screen"
P: Phys=
S: Sysfs=/devices/virtual/input/input0
U: Uniq=
H: Handlers=mouse0 event0
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=1000003

发现handler同时有mouse0 和event0 会不会因为mouse的原因,待解??

# cat handlers

N: Number=0 Name=kbd
N: Number=1 Name=mousedev Minor=32
N: Number=2 Name=evdev Minor=64

这是调试过程遇到的??

经过我再次制作的内核,再次调试,不会出现上次问题,以下为第一次调试的代码

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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_base;static struct input_dev* ts_dev;static struct timer_list ts_timer;//up 等待触摸屏被松开void ts_up_mode(){ ts_base->adctsc = 0x1d3; // 1 1101 0011}//down 等待触摸屏被按下void ts_down_mode(){ ts_base->adctsc = 0xd3; // 1101 0011}//启动adc转换void start_adc(){ ts_base->adccon |= (1<<0);}//设备adc自动转换xy坐标,禁止上拉电阻void measure_xy_mode(){ //measure xy; ts_base->adctsc |= (1<<3) | (1<<2);}static int ts_filter(int x[], int y[]){#define ERR_LIMIT 10 int 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 void ts_timer_functions(unsigned long data){ if(ts_base->adcdat0 & (1<<15)) { printk("timer_func: pen up\n"); //ts_down_mode(); input_report_abs(ts_dev, ABS_PRESSURE, 0); input_report_abs(ts_dev, BTN_TOUCH, 0); input_sync(ts_dev); ts_down_mode(); } else { printk("timer_func: pen down\n"); //ts_up_mode(); measure_xy_mode(); start_adc(); }}//pen已触摸(包括pen点下和松开都会发生中断), 进入此函数static irqreturn_t ts_irq(int irq, void *dev_id){ //up进入等待模式,down就进行转换数据 //if(ts_base->adctsc & (1<<8)) if(ts_base->adcdat0 & (1<<15)) { printk("ts_irq: pen up\n"); ts_down_mode(); } else { printk("ts_irq: pen down\n"); //ts_up_mode(); measure_xy_mode(); start_adc(); } //ts_timer.data = (unsigned long)dev_id; //mod_timer(&ts_timer, jiffies + HZ/100); return IRQ_RETVAL(IRQ_HANDLED);}//转换完成后进入此中断,等待pen的松开static irqreturn_t adc_irq(int irq, void *dev_id){ static int cnt = 0; int adcdata0, adcdata1; static int adcx[4], adcy[4]; //如果adc完成时,发现触摸笔松开,则丢弃 adcdata0 = ts_base->adcdat0; adcdata1 = ts_base->adcdat1; //adcx[cnt] = ts_base->adcdat0 & 0x3ff; //adcy[cnt] = ts_base->adcdat1 & 0x3ff; if( adcdata0 & (1<<15) ) { printk("adc_irq: no wait cnt=4 end \n"); ts_down_mode(); } else { if( cnt == 4 ) { if(ts_filter(adcx, adcy)) { int x, y; x = (adcx[0]+adcx[1]+adcx[2]+adcx[3])/4; y = (adcy[0]+adcy[1]+adcy[2]+adcy[3])/4; //report_abs_evevnt(); printk("touch point: x = %d, y = %d\n\n", x, y); input_report_abs(ts_dev, ABS_X, x); input_report_abs(ts_dev, ABS_Y, y); input_report_abs(ts_dev, ABS_PRESSURE, 1); input_report_key(ts_dev, BTN_TOUCH, 1); input_sync(ts_dev); } cnt = 0; ts_up_mode(); //S3C2410_CS4 //timer mod_timer(&ts_timer, jiffies + HZ); } else { adcx[cnt] = adcdata0 & 0x3ff; adcy[cnt] = adcdata1 & 0x3ff; printk("adc_irq cnt = %d, x = %d, y = %d\n", cnt, adcx[cnt], adcy[cnt]); cnt++; measure_xy_mode(); start_adc(); } //ts_up_mode(); } return IRQ_RETVAL(IRQ_HANDLED);}static int input_init(void){ struct clk* clk; //1 分配一个input_dev ts_dev = input_allocate_device(); //2 设置 //设置产生什么事件 //设置这类事件的那种 ts_dev->name = "s3c2440_touch_screen"; ts_dev->id.bustype = BUS_RS232; ts_dev->id.vendor = 0xDEAD; ts_dev->id.product = 0xBEEF; ts_dev->id.version = 0x0100; //ts_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT(EV_SYN); //ts_dev->keybit[0] = BIT_MASK(EV_KEY); set_bit(EV_KEY, ts_dev->evbit); set_bit(EV_ABS, ts_dev->evbit); set_bit(BTN_TOUCH, ts_dev->keybit); input_set_abs_params(ts_dev, ABS_X, 0, 0x3ff, 0, 0);//adcdat0 xpdata有说明 input_set_abs_params(ts_dev, ABS_Y, 0, 0x3ff, 0, 0);//dactat1 ypdata 有说明 input_set_abs_params(ts_dev, ABS_PRESSURE, 0, 1, 0, 0);//按压 和弹起 //3 注册 input_register_device(ts_dev); //4 硬件相关的操作 //set clk clk = clk_get(NULL, "adc"); clk_enable(clk); //set register ts_base = ioremap(0x58000000, sizeof(struct ts_regs) ); ts_base->adccon = (1<<14) | (0x31<<6); //50/(49+1)=1mhz //设置定时器,使用定时器处理长按,滑动的情况 init_timer(&ts_timer); ts_timer.function = ts_timer_functions; add_timer(&ts_timer); //设置延时,电压稳定后再发出中断 ts_base->adcdly = 0xffff; //设置中断包括ts和adc request_irq(IRQ_TC, ts_irq, IRQF_SAMPLE_RANDOM, "ts_pen", NULL); request_irq(IRQ_ADC, adc_irq, IRQF_SAMPLE_RANDOM, "adc", NULL); ts_down_mode(); printk ("init touch screen input dev\n"); return 0;}static void input_exit(void){ //释放irq //删除定时器 //注销设备,释放所占用空间 free_irq(IRQ_TC, NULL); free_irq(IRQ_ADC, NULL);//del iomap iounmap(ts_base); del_timer(&ts_timer); input_unregister_device(ts_dev); input_free_device(ts_dev);}module_init(input_init);module_exit(input_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("LCL");

第一次现在测试也是正确的,这因为默认情况下,cnt = 4 就进入ts_up_mode();

第二次我修改了adc_ts里面的代码,按照韦东山代码,优化了在adc转换完成后,但是cnt<4的情况下,就报告退出,放弃当前的测试

if( adcdata0 & (1<<15) ) //触摸松开	{		cnt = 0;		printk("touch screen up\n");				input_report_abs(ts_dev, ABS_PRESSURE, 0);		input_report_key(ts_dev, BTN_TOUCH, 0);		input_sync(ts_dev);				ts_down_mode();	}	else   //触摸还在按下状态	{			adcx[cnt] = adcdata0 & 0x3ff;		adcy[cnt] = adcdata1 & 0x3ff;		printk("adc_irq cnt = %d, x = %d, y = %d\n", cnt, adcx[cnt], adcy[cnt]);				cnt++;		if( cnt == 4 )		{			if(ts_filter(adcx, adcy))			{				int x, y;				x = (adcx[0] + adcx[1] + adcx[2] + adcx[3])/4;				y = (adcy[0] + adcy[1] + adcy[2] + adcy[3])/4;				//report evevnt;				printk("touch point: x = %d, y = %d\n\n", x, y);				input_report_abs(ts_dev, ABS_X, x);				input_report_abs(ts_dev, ABS_Y, y);				input_report_abs(ts_dev, ABS_PRESSURE, 1);								input_report_key(ts_dev, BTN_TOUCH, 1);								input_sync(ts_dev);			}			cnt = 0;			ts_up_mode();			//S3C2410_CS4			//timer			mod_timer(&ts_timer, jiffies + HZ/100);		}		else		{								measure_xy_mode();			start_adc();				}

 在第一次加载时默认就会启动定时器,但是就启动这一次,只有以后cnt=4才会调用

# insmod ts.ko

input: s3c2440_touch_screen as /devices/virtual/input/input3
init touch screen input dev
timer_func: pen up

转载地址:http://tbtqb.baihongyu.com/

你可能感兴趣的文章
什么是适用于iPhone和iPad的iOS最新版本?
查看>>
成为产品不一定是坏事
查看>>
Ubuntu 18.04 LTS现在在Microsoft Store中
查看>>
如何检查已安装的Ubuntu版本
查看>>
如何在Windows 10上禁用附近共享
查看>>
gmail_Gmail将提供自毁电子邮件
查看>>
google 禁止广告_是否应禁止针对个人的广告?
查看>>
Plover.io在本地设备之间快速共享文件
查看>>
如何在OS X照片中禁用iCloud照片同步
查看>>
Minecraft的官方网站分发了受恶意软件感染的皮肤
查看>>
word模板快速填内容_如何快速轻松地在Word中选择内容块
查看>>
如何在Word 2013中直接从一个表导航到另一个表
查看>>
twitch 录像_如何通过NVIDIA GeForce Experience将您的PC游戏玩法传送到Twitch
查看>>
linux gnome_在Gnome中学习这些鼠标技巧,以获得更高效的Linux体验
查看>>
打印机疑难解答_使用内置电源疑难解答改善Windows 7中的电池寿命
查看>>
下载spotify音乐_完成播放列表或专辑后如何停止Spotify停止自动播放音乐
查看>>
drupal加密_立即更新您的Drupal网站,否则黑客可能将其变成加密货币矿工
查看>>
vimrc配置 鼠标光标_在“提示”框中:即时调整窗口大小,包含鼠标光标并了解电池配置...
查看>>
询问HTG:安装XBMC附加组件,缩小视频以进行移动播放,自动更改默认打印机
查看>>
High Sierra推出后如何离开macOS公开Beta
查看>>