MINIGUI V1.6.0及V1.3.3触摸屏较正详细解决方案

作者:黄思华 华侨大学信息学院

 

Crosstool: arm-linux-gcc-3.4.1硬件环境:

 

HostX86PC

 

Target:友善之臂mini2440开发板

 

软件环境:

 

Hostfedora 10.0

 

Targetarm-linux             kernel:linux-2.6.17

 

本实验方案采纳Singlewolfyu (大漠孤狼) MiniGUI  1.3.3 移植详解中带屏幕校正功能的 2410 IAL 作者通过改写MiniGUI  1.3.3 版本中的 2410 IAL 程序,采用SMDK2410作为IAL引擎,实现了触摸屏原理,我将该方案弄到V1.6.0版本也成功地实现触摸屏的较正。改写的程序我命名为2410_touchmodify.c

 

该程序的说明:

 

2410_touchmodify.c中定义了两个数组,如下

 

 

typedef struct mPoint {      int      x,

                               y ;

                   } mPOINT ;

 

static mPOINT ts_position[4]={ {940,926},{940,102},{96,104},{120,940} };

static mPOINT display_position[4]={ {0,0},{0,319},{239,319},{239,0} };

 

ts_position 意思为 TouchScreen 位置

display_position 意思为屏幕上显示的 位置

 

比如我前面说的,我的屏幕是 240x320 的,我交叉编译tslib并移植tslib到开发板,然后我点四个角 {0,0},{0,319},{239,319},{239,0} ,从触屏上读出来的数据分别为 {26,283},{26,32},{216,31},{216,285} ,填入这两个数就行

 

所以使用方法就是,你自己取四个顶角的点,点这四个点,得到相应的触摸屏读出来的值,把这些数据填到这两个数组中,OK,你的 触摸屏 就可以正常工作了 :)

 

得到四个顶点的原始坐标可以采用大漠孤狼的readpos.c  的程序,也可以采用我的方法交叉编译、移植tslib,运行tslib./ts_print_raw来得到,关于tslib的交叉编译及使用,请参考我的另一篇文章,minigui V1.6.10 + tslib 触摸屏较正完美解决方案,博客地址http://blog.csdn.net/huangsihua/archive/2009/03/15/3992775.aspx我这里就不写出来了。我采用的是tslibts_printraw,当然大漠孤狼的readpos.c的方法我实验过也是可行的。

 

步骤一:

 

readpos.c程序放入/libminigui1.6.0/rea/ial,然后在终端输入:

 

cd …./libminigui1.6.0/res/ial

 

进入该目录,对其进行交叉编译命令如下:

 

arm-linux-gcc –o readpos readpos.c

 

这样得到readpos可执行文件,你入到板子上运行一下就可以读取触摸屏的坐标了,是不是比较简单。

 

后面附一个 readpos.c  的程序,你可以执行它,然后点击触摸屏,它会显示出触摸屏读出来的值。

 

步骤二:

 

复制修改好后的2410.c程序到…./libminigui1.6.0/res/ial/替换原来的2410.c

 

程序在文章后面的附程序二:2410_touchmodify.c

 

步骤三:

 

重新配置编译libminigui1.6.0

 

./configure  --prefix=/usr/local/arm/2.95.3/arm-linux  --build=i386-linux --host=arm-linux --target=arm-linux --enable-smdk2410ial

 

make

 

make install

 

应该没什么问题。

 

步骤四:重新编译我的PDA应用程序

 

arm-linux-gcc -o pda pda.c -lminigui -lm -lz -lpng -ljpeg -lmgext -lpthread –lts

 

步骤五:改写配置文件Minigui.cfgts.conf并测试

 

Migigui.cfg修改部分:

 

[system]

# GAL engine

gal_engine=fbcon

 

# IAL engine

ial_engine=SMDK2410

 

mdev=/dev/input/ts0

mtype=none

 

[fbcon]

defaultmode=240x320-16bpp

 

ts.conf修改部分:

 

#module mousebuts

module variance xlimit=50 ylimit=50 pthreshold=3

module dejitter xdelta=1 ydelta=1 pthreshold=3

module linear

 

将应用程序放入开发板运行,好了,较正的不错哦,Perfect.

交流邮箱:huangsihua@hqu.edu.cn

说明对于MINIGUI V1.3.3当然也是一样的,我的文章就是参考大漠孤狼在MINIGUI V1.3.3上的实现。只是那个版本的配置可以使用图形化的方式,make menuconfig

 

附程序一:Readpos.c 程序,帮助你读取触摸屏的值

 

#include <stdio.h>

 

typedef struct {

  unsigned short pressure;

  unsigned short x;

  unsigned short y;

  unsigned short pad;

} TS_EVENT;

 

static TS_EVENT ts_event;

static int ts;

 

int main()

{

  ts = open ("/dev/ts", 0);

  if (ts < 0) {

      fprintf (stderr, "2410: Can not open touch screen!/n");

      return 0;

  }

 

while(1)  

{

      if(       read (ts, &ts_event, sizeof (TS_EVENT)))

     {

         printf("X=%d,Y=%d,Pressure=%d /n",ts_event.x,ts_event.y,ts_event.pressure);

      }      

 

}

 

}

 

附程序二:   2410_touchmodify.c,修改后的SMDK2410的引擎2410.c

 

程序: 2410.c      (2410_touchmodify.c )

/*

** $Id: 2410.c,v 1.4 2003/11/21 12:15:37 weiym Exp $

**

** 2410.c: Low Level Input Engine for SMDK2410 Dev Board.

**

** Copyright (C) 2003 Feynman Software.

*/

 

/*

** This program is free software; you can redistribute it and/or modify

** it under the terms of the GNU General Public License as published by

** the Free Software Foundation; either version 2 of the License, or

** (at your option) any later version.

**

** This program is distributed in the hope that it will be useful,

** but WITHOUT ANY WARRANTY; without even the implied warranty of

** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

** GNU General Public License for more details.

**

** You should have received a copy of the GNU General Public License

** along with this program; if not, write to the Free Software

** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

 

#include "common.h"

 

#ifdef _SMDK2410_IAL

 

#include <sys/ioctl.h>

#include <sys/poll.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <linux/kd.h>

 

#include <sys/time.h>  /* i add it here */

#include <math.h>

#include <sys/poll.h>

#include <sys/types.h>

 

#include "ial.h"

#include "2410.h"

 

typedef struct mPoint {

                      int      x,

                               y ;

                   } mPOINT ;

 

static mPOINT ts_position[4]={ {26,283},{26,32},{216,31},{216,285}

 

                             };

static mPOINT display_position[4]={ {0,0},{0,319},{239,319},{239,0}

                                };

 

typedef struct Matrix {

/* This arrangement of values facilitates

*  calculations within getDisplayPoint()

*/

                      int      An,     /* A = An/Divider */

                               Bn,     /* B = Bn/Divider */

                               Cn,     /* C = Cn/Divider */

                               Dn,     /* D = Dn/Divider */

                               En,     /* E = En/Divider */

                               Fn,     /* F = Fn/Divider */

                               Divider ;

                   } mMATRIX ;

 

static mMATRIX m_matrix;

 

int setCalibrationMatrix( mPOINT * display,

                               mPOINT * screen,

                               mMATRIX * matrix) ;

 

 

int getDisplayPoint( mPOINT * display,

                          mPOINT * screen,

                          mMATRIX * matrix ) ;

 

 

 

/* for data reading from /dev/ts */

typedef struct {

  unsigned short pressure;

  unsigned short x;

  unsigned short y;

  unsigned short pad;

} TS_EVENT;

 

static unsigned char state [NR_KEYS];

static int ts = -1;

static int mousex = 0;

static int mousey = 0;

static TS_EVENT ts_event;

 

 

#undef _DEBUG

 

/************************  Low Level Input Operations **********************/

/*

* Mouse operations -- Event

*/

static int mouse_update(void)

{

  return 1;

}

 

static void mouse_getxy(int *x, int* y)

{

#ifdef _DEBUG

  printf ("mousex = %d, mousey = %d/n", mousex, mousey);

#endif

 

  if (mousex < 0) mousex = 0;

  if (mousey < 0) mousey = 0;

  if (mousex > 239) mousex = 239;

  if (mousey > 319) mousey = 319;

 

  *x = mousex;

  *y = mousey;

}

 

static int mouse_getbutton(void)

{

 return ts_event.pressure;

}

 

#ifdef _LITE_VERSION

static int wait_event (int which, int maxfd, fd_set *in, fd_set *out, fd_set *except,

              struct timeval *timeout)

#else

static int wait_event (int which, fd_set *in, fd_set *out, fd_set *except,

              struct timeval *timeout)

#endif

{

  fd_set rfds;

  int    retvalue = 0;

 

  int    e;

 

static int last_pressure=0;

 

  if (!in) {

      in = &rfds;

      FD_ZERO (in);

  }

 

  if ((which & IAL_MOUSEEVENT) && ts >= 0) {

      FD_SET (ts, in);

#ifdef _LITE_VERSION

      if (ts > maxfd) maxfd = ts;

#endif

  }

 

 

#ifdef _LITE_VERSION

  e = select (maxfd + 1, in, out, except, timeout) ;

#else

  e = select (FD_SETSIZE, in, out, except, timeout) ;

#endif

 

 

  if (e > 0) {

      if (ts >= 0  && FD_ISSET (ts, in) ) {

          FD_CLR (ts, in);

          ts_event.x=0;

          ts_event.y=0;

 

          read (ts, &ts_event, sizeof (TS_EVENT)); 

 

         if(last_pressure==0)

         {

            read(ts,&ts_event,sizeof(TS_EVENT));

            read(ts,&ts_event,sizeof(TS_EVENT));

 }

        

          if (ts_event.pressure > 0 ) {

      

              int new_x;

              int new_y;

 

mPOINT ts_point,display_point;

            

              ts_point.x=ts_event.x;

              ts_point.y=ts_event.y;

               

              getDisplayPoint(&display_point,&ts_point,&m_matrix);

              

 

              new_x = display_point.x;

              new_y = display_point.y;

            

if(last_pressure==0 || (last_pressure>0 && abs(new_x-mousex)<7))

                      mousex=new_x;

              if(last_pressure==0 || (last_pressure>0 && abs(new_y-mousey)<7))

                      mousey=new_y;

/*

printf("ts_x=%d,ts_y=%d/n",ts_event.x,ts_event.y);             

printf("mounsex=%dmousey=%d/n",mousex,mousey);

*/

          }

 

#ifdef _DEBUG

          if (ts_event.pressure > 0) {

              printf ("mouse down: ts_event.x = %d, ts_event.y = %d/n", ts_event.x, ts_event.y);

          }

#endif

        

          ts_event.pressure = ( ts_event.pressure > 0 ? IAL_MOUSE_LEFTBUTTON : 0);

            

  last_pressure=ts_event.pressure;

/*   

printf("pressure=%d/n",ts_event.pressure);

*/

          retvalue |= IAL_MOUSEEVENT;

      }

 

  }

  else if (e < 0) {

      return -1;

  }

 

  return retvalue;

}

 

BOOL Init2410Input (INPUT* input, const char* mdev, const char* mtype)

{

  ts = open (mdev, O_RDONLY);

  if (ts < 0) {

      fprintf (stderr, "2410: Can not open touch screen!/n");

      return FALSE;

  }

 

 

 

  input->update_mouse = mouse_update;

  input->get_mouse_xy = mouse_getxy;

  input->set_mouse_xy = NULL;

  input->get_mouse_button = mouse_getbutton;

  input->set_mouse_range = NULL;

 

  input->wait_event = wait_event;

  mousex = 0;

  mousey = 0;

  ts_event.x = ts_event.y = ts_event.pressure = 0;

 

setCalibrationMatrix(&display_position,&ts_position,&m_matrix);   

  return TRUE;

}

 

void Term2410Input(void)

{

  if (ts >= 0)

      close(ts);   

}

 

#endif /* _SMDK2410_IAL */

 

int setCalibrationMatrix( mPOINT * displayPtr,

                        mPOINT * screenPtr,

                        mMATRIX * matrixPtr)

{

 

  int  retvalue = 0 ;

 

 

 

  matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -

                       ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;

 

  if( matrixPtr->Divider == 0 )

  {

      retvalue = -1 ;

  }

  else

  {

      matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -

                      ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;

 

      matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -

                      ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;

 

      matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +

                      (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +

                      (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;

 

      matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -

                      ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;

 

      matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -

                      ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;

 

      matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +

                      (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +

                      (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;

  }

 

  return( retvalue ) ;

 

} /* end of setCalibrationMatrix() */

 

int getDisplayPoint( mPOINT * displayPtr,

                   mPOINT * screenPtr,

                   mMATRIX * matrixPtr )

{

  int  retvalue = 0 ;

 

 

  if( matrixPtr->Divider != 0 )

  {

 

          /* Operation order is important since we are doing integer */

          /*  math. Make sure you add all terms together before      */

          /*  dividing, so that the remainder is not rounded off     */

          /*  prematurely.                                           */

 

      displayPtr->x = ( (matrixPtr->An * screenPtr->x) +

                        (matrixPtr->Bn * screenPtr->y) +

                         matrixPtr->Cn

                      ) / matrixPtr->Divider ;

 

      displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +

                        (matrixPtr->En * screenPtr->y) +

                         matrixPtr->Fn

                      ) / matrixPtr->Divider ;

  }

  else

  {

      retvalue = -1 ;

  }

 

  return( retvalue ) ;

 

} /* end of getDisplayPoint() */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值