FT5X06 如何应用在10寸电容屏
硬件搭起来看现象,如下图:
红色区域是FT5406上报有效数据的范围(1280*600),以左上角为原点 ,X轴方向上报数据的最大值1280,Y轴方向上报的最大数据是600.。但是我用的LG的10.1寸屏,分辨率为1366*768。若想把触摸IC上报的数据和像素点的值一一对应起来,只能通过校正了。开始做校正的时候有点犯抽。竟然自己写校正算法,代码冗长不说,校准误差也特别大。 还好,后来想起了tslib这个东西。tslib是专门为电阻屏设计的一个校正库,只能校正单点触摸数据。而FT5406是支持5点触摸的。 不过只需要校正一点就可以了,这个点与其他四个点的上报数据的偏差大小无区别,只需要在驱动中做相同的消除偏差处理即可。思路有了,下面就从驱动开始说起:
1. FT5406 在Linux 3.5 中的驱动要点----数据上报过程
FT5406是通过IIC总线同CPU进行数据交互的,内核中的驱动框架符合一个典型IIC设备驱动+输入子系统(默认大家是了解IIC设备驱动和输入子系统驱动的)。硬件I/O的初始化和寄存器配置就不在这里赘述了, 照着手册来就可以了。重点看一下,数据上报过程,先看一个FT5406 原理图(图中标的是5206 ,没关系接口是一样的)::
原理图上可以看到,用到了EINT14这根中断线。通过这条中断线,差不多就能猜到上报流程了吧:当用户触摸到触摸板以后,产生中断,在中断服务程序中读IIC。这样就完成了一次数据的上报。下面就看看内核源码的实现,先看一个流程图:
中断代码实现如下:
static void ft5x0x_ts_pen_irq_work(struct work_struct *work) { //底半部中断
struct ft5x0x_ts_data *ts = container_of(work, struct ft5x0x_ts_data, work); if (!ft5x0x_read_data(ts)) {
ft5x0x_ts_report(ts);
} enable_irq(this_client->irq);
} static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id) {//顶半部中断
struct ft5x0x_ts_data *ts = dev_id; disable_irq_nosync(this_client->irq); if (!work_pending(&ts->work)) {
queue_work(ts->queue, &ts->work);
} return IRQ_HANDLED;
}
从IC中读取触摸数据:
static int ft5x0x_read_data(struct ft5x0x_ts_data *ts) {
struct ft5x0x_event *event = &ts->event;
u8 buf[] = { };
int ret; #ifdef CONFIG_FT5X0X_MULTITOUCH
ret = ft5x0x_i2c_rxdata(buf, );
#else
ret = ft5x0x_i2c_rxdata(buf, );
#endif
if (ret < ) {
printk("%s: read touch data failed, %d\n", __func__, ret);
return ret;
} memset(event, , sizeof(struct ft5x0x_event)); event->touch_point = buf[] & 0x07; if (!event->touch_point) {
ft5x0x_ts_release(ts);
return ;
} #ifdef CONFIG_FT5X0X_MULTITOUCH
switch (event->touch_point) {
case :
event->x[] = (s16)(buf[0x1b] & 0x0F)<< | (s16)buf[0x1c];
event->y[] = (s16)(buf[0x1d] & 0x0F)<< | (s16)buf[0x1e];
case :
event->x[] = (s16)(buf[0x15] & 0x0F)<< | (s16)buf[0x16];
event->y[] = (s16)(buf[0x17] & 0x0F)<< | (s16)buf[0x18];
case :
event->x[] = (s16)(buf[0x0f] & 0x0F)<< | (s16)buf[0x10];
event->y[] = (s16)(buf[0x11] & 0x0F)<< | (s16)buf[0x12];
case :
event->x[] = (s16)(buf[0x09] & 0x0F)<< | (s16)buf[0x0a];
event->y[] = (s16)(buf[0x0b] & 0x0F)<< | (s16)buf[0x0c];
case :
event->x[] = (s16)(buf[0x03] & 0x0F)<< | (s16)buf[0x04];
event->y[] = (s16)(buf[0x05] & 0x0F)<< | (s16)buf[0x06];
break;
default:
printk("%s: invalid touch data, %d\n", __func__, event->touch_point);
return -;
}
#else
if (event->touch_point == ) {
event->x[] = (s16)(buf[0x03] & 0x0F)<< | (s16)buf[0x04];
event->y[] = (s16)(buf[0x05] & 0x0F)<< | (s16)buf[0x06];
}
#endif event->pressure = ; return ;
}
上报过程代码:
static void ft5x0x_ts_report(struct ft5x0x_ts_data *ts) {
struct ft5x0x_event *event = &ts->event;
int x, y;
int i; #ifdef CONFIG_FT5X0X_MULTITOUCH
for (i = ; i < event->touch_point; i++) {
if (swap_xy) {
x = event->y[i];
y = event->x[i];
} else {
x = event->x[i];
y = event->y[i];
} if (scal_xy) {
x = (x * ts->screen_max_x) / TOUCH_MAX_X;
y = (y * ts->screen_max_y) / TOUCH_MAX_Y;
} input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts->input_dev, ABS_MT_PRESSURE, event->pressure);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i); input_mt_sync(ts->input_dev);
}
#else
if (event->touch_point == ) {
if (swap_xy) {
x = event->y[i];
y = event->x[i];
} else {
x = event->x[i];
y = event->y[i];
} if (scal_xy) {
x = (x * ts->screen_max_x) / TOUCH_MAX_X;
y = (y * ts->screen_max_y) / TOUCH_MAX_Y;
} input_report_abs(ts->input_dev, ABS_X, x);
input_report_abs(ts->input_dev, ABS_Y, y);
input_report_abs(ts->input_dev, ABS_PRESSURE, event->pressure);
} input_report_key(ts->input_dev, BTN_TOUCH, );
#endif input_sync(ts->input_dev);
}
IC驱动的大致工作流程就是这样的,下面就来看看该怎么去做校正:
一、这个电容屏是往exynos4412 核心 Android4.2设备上移植的,所以第一步要做的是往Anroid移植TSlib1.4库。简述移植过程
1.生成configure
./autogen.sh
安装tslib中遇到的错误:./autogen.sh: 4: autoreconf: not found
是因为在不同版本的 tslib 下执行 autogen.sh 产生。它们产生的原因一样,是
因为没有安装 automake 工具, (ubuntu 13.10)用下面的命令安装好就可以了。
sudo apt-get install autoconf automake libtool
2./configure --host=交叉编译器路径(注意要用对应android平台自带的bionic c编译器而不是配套开发板的GNU C编译器)
在tslib/config.h文件中加入如下定义:
#define TS_CONF "/system/etc/ts.conf"
#define PLUGIN_DIR "/system/lib"
#define TS_POINTERCAL "/data/etc/pointercal"
另外由于bionic c 和GNU c的差异,需要修改几个tslib的头文件编译才能通过
tslib/src/ts_open.c
tslib/tests/ts_calibrate.c
tslib/tests/fbutils.c
中的
#include <sys/fcntl.h>
修改成
#include <fcntl.h>
将tslib/tests/ts_calibrate.c文件中
static int clearbuf(struct tsdev *ts)
修改为
static void clearbuf(struct tsdev *ts)
3.编译make
将etc/ts.conf 的参考配置:
修改tslib/etc/ts.conf内容如下:
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear
4.在android源代码init.rc中声明tslib相关环境变量如下:
# touchscreen parameters
export TSLIB_FBDEVICE /dev/graphics/fb0
export TSLIB_CALIBFILE /data/etc/pointercal
export TSLIB_CONFFILE /system/etc/ts.conf
export TSLIB_TRIGGERDEV /dev/input/event0
export TSLIB_TSDEVICE /dev/input/event1
5. 将/src/.lib 中生成的库文件,分别全部拷贝开发板的根文件系统对应/system/lib 目录中,将tests目录中的ts_calibrate cp到system/bin中
到此完成对tslib的移植。
在运行ts_calibrate前首先要取消内核对多点触摸的支持,因为tslib只能处理单点的数据格式,而且单点的数据,必须要满足以下上报顺寻:
input_report_abs(ts->input_dev, ABS_X, x);
input_report_abs(ts->input_dev, ABS_Y, y);
input_report_abs(ts->input_dev, ABS_PRESSURE, event->pressure);
通过运行ts_calibrate,获得校正参数,存放在/data 目录下的pointercal文件中
最后要做的就是修改内核驱动 /drivers/input/touchscreen/ft5x06_ts.c,添加校正算法(如下)并添加获得的校正参数(红色标注即为获得的校正参数)。如下:
#ifdef CONFIG_INPUT_TS_LINEAR
static int ts_linear_scale(int *x, int *y, int swap_xy)
{
int xtemp, ytemp;
int a[] = {,-,-,-,,-,};
xtemp = *x;
ytemp = *y; if (a[] == )
return -EINVAL; *x = (a[] + a[] * xtemp + a[] * ytemp) / a[];
*y = (a[] + a[] * xtemp + a[] * ytemp) / a[]; if (swap_xy) {
int tmp = *x;
*x = *y;
*y = tmp;
}
return ;
}
#endif
struct ft5x0x_event *event = &ts->event;
int x, y;
int i;
#ifdef CONFIG_FT5X0X_MULTITOUCH
for (i = 0; i < event->touch_point; i++) {
if (swap_xy) {
x = event->y[i];
y = event->x[i];
} else {
x = event->x[i];
y = event->y[i];
}
if (scal_xy) {
x = (x * ts->screen_max_x) / TOUCH_MAX_X;
y = (y * ts->screen_max_y) / TOUCH_MAX_Y;
}
#ifdef CONFIG_INPUT_TS_LINEAR
ts_linear_scale(&x, &y, swap_xy);
#endif
在上报过程 首先通过static int ts_linear_scale(int *x, int *y, int swap_xy)函数将从IC获得的触摸点坐标消除偏差。
FT5X06 如何应用在10寸电容屏的更多相关文章
- FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析&移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)
这是几个月以前的东西了,在彻底遗忘之前拿出来好好写写.做个笔记,也算是造福后来人了.在做这个项目之前,没有做过电容屏的驱动,印象中的电容触摸屏是不需要校正的.IC支持多大的屏就要配多大的屏.但是拿到需 ...
- 基于GPL329xx linux平台电容屏gsl1680的驱动调试分析
因客户有用到了gsl1680 7寸电容屏,所以拿了一块过来,便在329xx的平台上面开始调试了. 大概浏览了一下所提供的资料,只有介绍模组的资料跟一份中文版的datasheet,datasheet只是 ...
- android 电容屏(三):驱动调试之驱动程序分析篇
平台信息: 内核:linux3.4.39系统:android4.4 平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新浪博 ...
- 【转】android 电容屏(三):驱动调试之驱动程序分析篇
关键词:android 电容屏 tp 工作队列 中断 坐点计算 电容屏主要参数平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV310( ...
- Android电容屏(二):驱动调试分析【转】
本文转载自:http://blog.csdn.net/xubin341719/article/details/7833383 以goodix的gt8105为例 一.总体架构 硬件部分:先看一个总体的图 ...
- kernel 4.4.12 EETI eGTouch 电容屏驱动移植
kernel 4.4.12 EETI eGTouch 电容屏驱动移植: 在make menuconfig 里面添加如下选项: 添加通过事件上报接口节点: Device Drivers ---> ...
- android 电容屏(二):驱动调试之基本概念篇
平台信息: 内核:linux3.4.39系统:android4.4 平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新浪博 ...
- android 电容屏(一):电容屏基本原理篇
平台信息: 内核:linux3.4.39系统:android4.4 平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新浪博 ...
- 【转】android 电容屏(二):驱动调试之基本概念篇
关键词:android 电容屏 tp 工作队列 中断 多点触摸协议平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV310(samsung ...
随机推荐
- 20155201 2016-2017-2 《Java程序设计》第四周学习总结
20155201 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 - 第六章要点: 继承:面向对象中,子类继承父类,避免重复的行为定义.继承基本上就是避免多个 ...
- #include <ntifs.h>出现PEPROCESS redefinition问题处理
转载:http://blog.csdn.net/ytfrdfiw/article/details/23334297 如果在自己的程序中,即包含ntddk.h和ntifs.h的时候,编译的时候会出现如下 ...
- Python学习札记(二十八) 模块1
参考:模块 NOTE 1.模块:一个.py文件称为一个模块. 2.代码模块化的意义:a.提升程序的可维护性 b.不用重复造轮子 3.避免模块冲突,解决方法:引入了按目录来组织模块的方法,称为包(Pac ...
- n个数取前k个最小数
算法题:K 个最近的点 给定一些 points 和一个 origin,从 points 中找到 k 个离 origin 最近的点.按照距离由小到大返回.如果两个点有相同距离,则按照x值来排序:若x值也 ...
- lua if 流程控制
Lua认为false和nil为假,true和非nil为真. 要注意的是Lua中 0 为 true --[ 为 true ] ) then print("0 为 true") end ...
- 例子.ZC简单.JSP和session
1.环境: Win7x64.E:\ZC_IDE\Eclipse\Windows\eclipse-jee-mars-R-win32__apk__20180122_1457\eclipse.exe.E:\ ...
- 一些自己常用的cdn
1.vue <script src="http://cdn.bootcss.com/vue/1.0.28-csp/vue.js"></script> < ...
- Java IO流-随机访问流
2017-11-05 19:45:51 RandomAccessFile类(随机访问流) RandomAccessFile类:是Object的子类,此类的实例支持对随机访问文件的读取和写入.随机访问文 ...
- git 设置 代理服务器
git config --global http.proxy http://proxyuser:proxypwd@proxy.server.com:8080 git config --global h ...
- numpy.zeros(np.zeros)使用方法--python学习笔记31
https://blog.csdn.net/qq_26948675/article/details/54318917