之前写过一篇android4.0的电阻触摸校准是直接用的tslib,感觉没有必要移植tslib,这里记录下通过app校准.
首先保证驱动已经调通,同时需要修改触摸上报的宽高的最大值和lcd屏的分辨率保持一致,不然映射会出现问题,改文件系统调试不是很方便,所以校准就直接放在驱动里了,在调好了触摸驱动后(坐标不一定对应),然后在触摸驱动中加入校准函数,修改如下:
#ifdef CONFIG_TSCALIBRATE
#include
#include
#define TS_PROC "driver/tscalibrate"
#define SCREEN_X 800
#define SCREEN_Y 600
signed 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=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
增加系统服务,写入校准数据
在init.$device.rc中增加
service calibrate /system/bin/calibrate
class main
disabled
oneshot
on property:gzsd.calibrate=*
start calibrate
/system/bin/calibrate内容如下
#!/system/bin/sh
if [ -f /data/etc/pointercal ]; then
cat /data/etc/pointercal > /proc/driver/tscalibrate
echo "calibrate done" > /dev/console
else
echo "no calibrate file reset" > /dev/console
echo "1 0 0 0 1 0 1" > /proc/driver/tscalibrate
fi
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 },
这个代码是直接放在文件系统源码里编译生成的,源码比较多,就不在这贴出来了
最后界面如下:
里面有一些参数需要根据实际坐标进行相应变动,默认里面的参数是全屏后的参数
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
============================================
作者:hclydao
http://blog.csdn.net/hclydao
版权没有,但是转载请保留此段声明
============================================