换了个10.4寸的新屏,同样的分辨率,点起来后,触摸完全不准。由于android系统还没有移植tslib,所以只能在底层的驱动中把触摸原始点上报android读取。
底层内核版本2.6.27
首先从点击触摸屏的现象来看好像是左右反了,那就先把坐标值打印出来看看,点击触摸屏4个顶点,结果显示如下,
(823,20) (0,16)
(810,596) (1,601)
正确的应该是:
(0,20) (823,16)
(1,596) (810,601)
以上是触摸坐标转换后的LCD坐标,可以看出应该是X值左右反了,看下这部分的驱动:
//设定触摸的最大范围 #define TS_X_SZ 800 #define TS_Y_SZ 600 //定时器服务程序 static void touch_timer_fire(unsigned long data) { unsigned long data0; unsigned long data1; int updown; #ifdef ANDROID_TS int a0,a1,a2,a3,a4,a5,a6; int x,y; a0= a1= a2= a3= a4= a5= a6= #endif data0 = readl(ts_base+S3C_ADCDAT0); data1 = readl(ts_base+S3C_ADCDAT1); updown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN)); if (updown) { if (ts->count) { #ifdef CONFIG_TOUCHSCREEN_S3C_DEBUG { struct timeval tv; do_gettimeofday(&tv); printk(KERN_INFO "T: %06d, X: %03ld, Y: %03ld/n", (int)tv.tv_usec, ts->xp, ts->yp);//如果编译内核的时候选上了 则会打印出这个坐标 } #endif #ifdef ANDROID_TS x=(int) ts->xp; y=(int) ts->yp; ts->xp = ((x - 964)*800)/(3088-964); ts->yp = ((y - 1012)*600)/(2840-1012); //这里使用了这个方式来传换成LCD坐标,这里的964/1012/3088/2840这4个值,也是LCD屏上4个顶点触摸值,然后再根据LCD屏的4个顶点LCD坐标值,建立4个4个未知数的方程即可。算出上面4个值。 //ts->xp=(long) ((a2+(a0*x)+(a1*y))/a6); //ts->yp=(long) ((a5+(a3*x)+(a4*y))/a6); //printk("x=%d, y=%d/n",(int) ts->xp,(int) ts->yp); //这里还有种方式是用前面定义的7个值来转换成LCD坐标。关于a0~a6这些值的定义,网上也有很多方法,都是需要先把LCD屏上4个顶点的触摸坐标先打印出来,然后根据v This implementation is a linear transformation using 7 parameters (a, b, c, d, e, f and s) to transform the device coordinates (Xd, Yd) into screen coordinates (Xs, Ys) using the following equations: s*Xs = a*Xd + b*Yd + c s*Ys = d*Xd + e*Yd + f 来计算出a0~a6这些值。这个计算用到了大1时候学的线性代数克莱姆法则哦,算起来烦! if(ts->xp!=ts->xp_old || ts->yp!=ts->yp_old) { input_report_abs(ts->dev, ABS_X, ts->xp);// /*报告X、Y的绝对坐标值*/ input_report_abs(ts->dev, ABS_Y, ts->yp); //input_report_abs(ts->dev, ABS_Z, 0); input_report_key(ts->dev, BTN_TOUCH, 1);// /*报告触摸屏的状态,1表明触摸屏被按下*/ // input_report_abs(ts->dev, ABS_PRESSURE, 1); input_sync(ts->dev);//同步 } ts->xp_old=ts->xp; ts->yp_old=ts->yp; #else input_report_abs(ts->dev, ABS_X, ts->xp); input_report_abs(ts->dev, ABS_Y, ts->yp); input_report_key(ts->dev, BTN_TOUCH, 1); input_report_abs(ts->dev, ABS_PRESSURE, 1); input_sync(ts->dev); #endif } ts->xp = 0; ts->yp = 0; ts->count = 0; //设置触摸屏初始以及*启动ADC转换*/ writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base+S3C_ADCTSC); writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base+S3C_ADCCON); } else { //这里是抬起状态了 ts->count = 0; #ifdef ANDROID_TS input_report_abs(ts->dev, ABS_X, ts->xp_old); input_report_abs(ts->dev, ABS_Y, ts->yp_old); input_report_abs(ts->dev, ABS_Z, 0); #endif input_report_key(ts->dev, BTN_TOUCH, 0); #ifndef ANDROID_TS input_report_abs(ts->dev, ABS_PRESSURE, 0); #endif input_sync(ts->dev); writel(WAIT4INT(0), ts_base+S3C_ADCTSC); } }
已经可以判断出X坐标左右反了,那么只需调整下,即可
ts->xp = ((x - 964)*800)/(3088-964);这个是LCD X坐标,所有只需
ts->xp = (800-((x - 964)*800)/(3088-964));就可以了
重新编译后检验 可以了~仅此记录下