Crosstool: arm-linux-gcc-4.4.3硬件环境:
Host:X86PC
Target:smdk2416开发板
软件环境:
Host:debian5
Target:arm-linux kernel:linux-2.6.38.8
Email:[email protected] by 厦门
目前网格上比较多的有2各种方案
1. Singlewolfyu (大漠孤狼)在 MiniGUI 1.3.3 移植详解中带屏幕校正功能的 2410 的 IAL
2. MiniGUI-1.6.10+tslib-1.4移植到s3c2410+linux2.6.33.2
本人试过第2种方案,编译之后一直说找不ts_open之类相关库文件,由于内核触摸屏的驱动采用input系统与第1种方案有所不同,且我的内核中已经移植好了tslib-1.4,校准方面采用tslib-1.4生成好的/etc/pointercal文件,因此结合2种方案重新做了个IAL引擎
1. 在ial.c文件中添加新引擎的入口:
例如:(ial.c文件中)
A) #ifdef _NAME _IAL
#include "NAME.h"
#endif
B) 在input数组中添加
#ifdef _NAME _IAL
{"NAME ", InitNAMEInput, TermNAMEInput},
#endif
2. 把新的 .c 添加到 Makefile.am 文件中即可。
3. 修改配置文件IAL引擎项,使用这个新的IAL引擎_NAME_IAL.
修改后覆盖src/ial/2410.c 2410.h,程序见附录
主要改wait_event这个函数
编译发现个问题,如果是覆盖形式则要make clean/ make distclean 再重新编译,要编个10多分钟,但在原有基础上作修改,则只需要make /make install即可,不知道为何
编译步骤见另一文章
http://blog.csdn.net/hebu007/article/details/6739597
[system]
# GAL engine and default options
gal_engine=fbcon
#gal_engine=qvfb
defaultmode=640x480-16bpp
# IAL engine
#ial_engine=console
ial_engine=SMDK2410 //对应2410.c
mdev=/dev/input/event0
mtype=none
#IMPS2
[fbcon]
defaultmode=640x480-16bpp
[qvfb]
defaultmode=640x480-16bpp
#include
#include
#include
#include
#include
#include "common.h"
#ifdef _SMDK2410_IAL
#include
#include "ial.h"
#include "2410.h"
#include
struct input_event ev0;
#define TS_DEVICE "/dev/input/event0"
#define TS_CALIBFILE "/etc/pointercal"
#define MINX 660
#define MINY 780
#define LCD_MAX_X 640
#define LCD_MAX_Y 480
#define MOUSE_MAX_X 2745
#define MOUSE_MAX_Y 2560
typedef struct {
unsigned short pressure;
unsigned short x;
unsigned short y;
unsigned short pad;
} TS_EVENT;
static TS_EVENT ts;
static POINT lcd;
static int mouse_fd = -1;
int calibParam[7];
int lcdTimeOut = 0;
static int mouse_update(void)
{
return 1;
}
static void mouse_getxy (int* x, int* y)
{
if(lcd.x < 0)
lcd.x = 0;
if(lcd.x > 640)
lcd.x = 639;
if(lcd.y < 0)
lcd.y = 0;
if(lcd.y > 480)
lcd.y = 479;
*x = lcd.x;
*y = lcd.y;
}
void ts_getraw(int *x, int *y)
{
*x = ts.x;
*y = ts.y;
}
static int mouse_getbutton(void)
{
lcdTimeOut = 0;
return (ts.pressure? IAL_MOUSE_LEFTBUTTON:0 );
}
static unsigned char pres_state = 0;
#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 retv;
int e;
static int last_pressure=0;
if (!in) {
in = &rfds;
FD_ZERO (in);
}
if ((which & IAL_MOUSEEVENT) && mouse_fd >= 0) {
FD_SET (mouse_fd, in);
#ifdef _LITE_VERSION
if (mouse_fd > maxfd) maxfd = mouse_fd;
#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 (mouse_fd >= 0 && FD_ISSET (mouse_fd, in) ) {
retv = read(mouse_fd, &ev0, sizeof(struct input_event) );
if ( retv < sizeof(struct input_event) ) return 0;
switch(ev0.type)
{
case EV_ABS:
switch(ev0.code)
{
case ABS_X:
ts.x = ev0.value;
break;
case ABS_Y:
ts.y = ev0.value;
break;
case ABS_PRESSURE:
if(ev0.value == 1)
{
pres_state = 1;
}else
if(ev0.value == 0)
{
if(pres_state == 1)pres_state = 2;
}
ts.pressure = ev0.value;
break;
default:break;
}
break;
case EV_KEY:
if(ev0.code== BTN_TOUCH && ev0.value == 0)
{
}
break;
default:break;
}
if(pres_state) {
if(pres_state == 2) pres_state = 0;
lcd.x = (calibParam[0] * ts.x + calibParam[1] * ts.y + calibParam[2]) / calibParam[6];
lcd.y = (calibParam[3] * ts.x + calibParam[4] * ts.y + calibParam[5]) / calibParam[6];
retvalue |= IAL_MOUSEEVENT;
}
}
}
else if (e < 0) {
return -1;
}
return retvalue;
}
static int wait_event1 (int which, fd_set *in, fd_set *out, fd_set *except,
struct timeval *timeout)
{
int retvalue = 0;
int retv;
retv = read(mouse_fd, &ev0, sizeof(struct input_event) );
if ( retv < sizeof(struct input_event) ) return 0;
switch(ev0.type)
{
case EV_ABS:
switch(ev0.code)
{
case ABS_X:
ts.x = ev0.value;
break;
case ABS_Y:
ts.y = ev0.value;
break;
case ABS_PRESSURE:
if(ev0.value == 1)
{
pres_state = 1;
}else
if(ev0.value == 0)
{
if(pres_state == 1)pres_state = 2;
}
ts.pressure = ev0.value;
break;
default:break;
}
break;
case EV_KEY:
break;
default:break;
}
if(!pres_state) return 0;
if(pres_state == 2) pres_state = 0;
lcd.x = (calibParam[0] * ts.x + calibParam[1] * ts.y + calibParam[2]) / calibParam[6];
lcd.y = (calibParam[3] * ts.x + calibParam[4] * ts.y + calibParam[5]) / calibParam[6];
retvalue |= IAL_MOUSEEVENT;
return retvalue;
}
BOOL Init2410Input (INPUT* input, const char* mdev, const char* mtype)
{
int cal_fd;
int ret;
mouse_fd = open (mdev, O_RDONLY);
if (mouse_fd < 0 ) {
fprintf (stderr, "2410: Can not open Touch Screen!\n");
return FALSE;
}
cal_fd = open(TS_CALIBFILE, O_RDWR);
if (cal_fd < 0)
{
fprintf (stderr, "2410: Open touch screen calibration file error,use default!\n");
calibParam[0] = 354;
calibParam[1] = -71059;
calibParam[2] = 57310544;
calibParam[3] = 62332;
calibParam[4] =-563;
calibParam[5] = -16260456;
calibParam[6] = 65536;
}
else
{
char pcalbuf[200];
int index = 0;
char *tokptr;
ret = read(cal_fd,pcalbuf,200);
calibParam[0] = atoi(strtok(pcalbuf," "));
index=1;
while(index<7) {
tokptr = strtok(NULL," ");
if(*tokptr!='\0') {
calibParam[index] = atoi(tokptr);
index++;
}
}
}
for (ret = 0; ret < 7; ret++)
{
printf("%d\n", calibParam[ret]);
}
close(cal_fd);
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->update_keyboard = NULL;
input->get_keyboard_state = NULL;
input->set_leds = NULL;
input->wait_event = wait_event;
return TRUE;
}
void Term2410Input (void)
{
if (mouse_fd >= 0)
close(mouse_fd);
}
#endif /* _DUMMY_IAL */