首页 > 系统 > Android > 正文

android4.4 电阻触摸校准修改说明

2019-11-08 00:13:58
字体:
来源:转载
供稿:网友

之前写过一篇android4.0的电阻触摸校准是直接用的tslib,感觉没有必要移植tslib,这里记录下通过app校准.

首先保证驱动已经调通,同时需要修改触摸上报的宽高的最大值和lcd屏的分辨率保持一致,不然映射会出现问题,改文件系统调试不是很方便,所以校准就直接放在驱动里了,在调好了触摸驱动后(坐标不一定对应),然后在触摸驱动中加入校准函数,修改如下:

1.驱动修改

#ifdef CONFIG_TSCALIBRATE#include <linux/PRoc_fs.h>#include <asm/uaccess.h>#define TS_PROC	"driver/tscalibrate"#define SCREEN_X	800#define SCREEN_Y	600signed long pointercal[7] = {1,0,0,0,1,0,1};static struct proc_dir_entry *ts_proc_entry;static int ts_proc_write(struct file *file, const char *buffer,			     unsigned long count, void *data){	char buf[256];	unsigned long len;	char *p = (char *)buf;	int i,j;	int flag = 1;	memset(buf,0,256);	len = min_t(unsigned long, sizeof(buf) - 1, count);	if (copy_from_user(buf, buffer, len))		return count;	j = 0;	for(i=0;i<len;i++)	{		if(flag)		{			pointercal[j] = simple_strtol(p, &p, 10);			j++; 			if(j>=7)				break;			flag = 0;		}		if(p[0] == ' ')		{			flag = 1;		}		if(p[0] == '/t')		{			flag = 1;		}		p++;	}	printk("write calibrate value/n");	for(i=0;i<7;i++)		printk("%u ",pointercal[i]);	printk("/n");	return count;}void tscalibrate(int *x,int *y){	long a,b,c,d,e,f,div;	//printk("before x:%d,y:%d/n",*x,*y);	a = pointercal[0];	b = pointercal[1];	c = pointercal[2];	d = pointercal[3];	e = pointercal[4];	f = pointercal[5];	div = pointercal[6];	*x = (a*(*x) + b*(*y) + c)/div;	*y = (d*(*x) + e*(*y) + f)/div;}#endif第一个函数接口ts_proc_write在向sysfs接口写入生成的校准数据时调用,保存校准数据到pointercal中

第二个tscalibrate校准生成校准后的坐标

在probe函数最后增加如下代码

#ifdef CONFIG_TSCALIBRATE	ts_proc_entry = create_proc_entry(TS_PROC, 0, NULL);   	if (ts_proc_entry) {   		ts_proc_entry->write_proc = ts_proc_write;	}  #endif

创建sysfs接口

同时需要修改

	input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);	input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);

input_set_abs_params中的ABS_X和ABS_Y的最大值,例如我的屏的分辨率是800x600这里的最大值就要和这个一样

不然文件系统中映射会出现问题(暂时没找到文件系统在哪修改这个,所以直接在驱动中改)

在remove函数中增加如下代码

#ifdef CONFIG_TSCALIBRATE	remove_proc_entry(TS_PROC,NULL);#endif

然后在上报之前

		input_report_abs(usbtouch->input, ABS_X, usbtouch->y);		input_report_abs(usbtouch->input, ABS_Y, usbtouch->x);input_report_abs之前进行校准

这样修改后还有一个问题就是,最开始没校准之前上报的坐标是大于800x600的,如果使用android app中的view此时view无法获取到这个坐,所以在校准之前还需要进行修改

#ifdef CONFIG_TSCALIBRATE	dev->x = dev->x * SCREEN_X / 0x7ff;	dev->y = dev->y * SCREEN_Y / 0x7ff;#endif

获取到的坐标分别是 * lcd宽高然后 / 触摸最大值(保证最后的最大值小于800x600即可),可以直接把这两条代码加到

tscalibrate函数中

void tscalibrate(int *x,int *y){    long a,b,c,d,e,f,div;    //printk("before x:%d,y:%d/n",*x,*y);    a = pointercal[0];    b = pointercal[1];    c = pointercal[2];    d = pointercal[3];    e = pointercal[4];    f = pointercal[5];    div = pointercal[6];    *x = *x * SCREEN_X / 0x7ff;    *y = *y * SCREEN_Y / 0x7ff;    *x = (a*(*x) + b*(*y) + c)/div;    *y = (d*(*x) + e*(*y) + f)/div;}

其中SCREEN_X和SCREEN_Y对应lcd分辨率800x600最后在文件开始定义CONFIG_TSCALIBRATE

2.系统修改

增加系统服务,写入校准数据

在init.$device.rc中增加

service calibrate /system/bin/calibrate    class main    disabled	oneshoton property:gzsd.calibrate=*    start calibrate

/system/bin/calibrate内容如下

#!/system/bin/shif [ -f /data/etc/pointercal ]; then	cat /data/etc/pointercal > /proc/driver/tscalibrate	echo "calibrate done" > /dev/consoleelse	echo "no calibrate file reset" > /dev/console	echo "1 0 0 0 1 0 1" > /proc/driver/tscalibratefi

app中校准数据保存在/data/etc/pointercal文件中,如果存在这个文件就将校准数据写入到sysfs接品,如果不存在这个文件,写入原始数据,还原成原始坐标,方便重新校准.

然后修改文件系统system/init/core/property_service.c在

struct {    const char *prefix;    unsigned int uid;    unsigned int gid;} property_perms[] = {中加入

{ "gzsd.calibrate",    AID_SYSTEM,   0 },

3.校准app

这个代码是直接放在文件系统源码里编译生成的,源码比较多,就不在这贴出来了最后界面如下:

里面有一些参数需要根据实际坐标进行相应变动,默认里面的参数是全屏后的参数

   	WindowManager windowManager = getWindowManager();   	Display display = windowManager.getDefaultDisplay();    	UI_SCREEN_WIDTH = 800;//display.getWidth();    	UI_SCREEN_HEIGHT = 600;//display.getHeight();    	xList[0] = 50;    	xList[1] = UI_SCREEN_WIDTH - 50;    	xList[2] = UI_SCREEN_WIDTH - 50;    	xList[3] = 50;    	xList[4] = UI_SCREEN_WIDTH / 2;    	yList[0] = 50;    	yList[1] = 50;    	yList[2] = UI_SCREEN_HEIGHT - 50;    	yList[3] = UI_SCREEN_HEIGHT - 50;    	yList[4] = UI_SCREEN_HEIGHT / 2;

这里根据实际坐标进行修改,有可能用display.getWidth()和display.getHeight获取到的不是800x600

app下载地址:http://download.csdn.net/detail/hclydao/9762894

============================================作者:hclydaohttp://blog.csdn.net/hclydao版权没有,但是转载请保留此段声明

============================================


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表