Hi, Stuart
I working with Phytec development board.
My application (GUI, GTK with DirectFB) working with touch screen.
I want to tell what problems I encountered and how to solve them.
Touch screen driver "LPC32xx Touchscreen" in Linux this is device event0.
1. Touch screen driver not working if started as module, built-in it's working good.
2. event0 need to move from /dev/event0 to /dev/input/event0, because DirectFB search it in this directory.
3. Need make enviroment variales for ts_calibration util.
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
4. DirectFB not working correct with "LPC32xx Touchscreen" driver, because use raw data - not calibrated values.
To solve this problem:
1. Need extract /opt/ltib/pkgs/DirectFB-1.1.0.tar.gz to your directory of ltib ../ltib/rpm/BUILD
2. Copy file tsc_correct.c (see attachment) to ltib/rpm/BUILD/DirectFB-1.1.0/inputdrivers/linux_input
3. Edit source code of linux_input.c file. (see below comment "Dima")
4. Rebuild the file system of target linux (cd ltib && ./ltib )
How it's work.
After
screen calibration with ts_calibration util will be created file with
name that contain in TSLIB_CALIBFILE enviroment variable.
In run time of linux_input_EventThread function tsc_get_calib_file() get the values from the TSLIB_CALIBFILE.
After each driver event tsc_correct_ts_data( &devt ); function do calculation for screen values.
--------------- linux_input.c file. Fragment ----------------------
/* Dima */
#include "tsc_correct.c"
/* */
/*
* Input thread reading from device.
* Generates events on incoming data.
*/
static void*
linux_input_EventThread( DirectThread *thread, void *driver_data )
{
LinuxInputData *data = "" driver_data;
int readlen, status, i;
struct input_event levt[64];
fd_set set;
struct touchpad_fsm_state fsm_state;
/* Query min/max coordinates. */
if (data->touchpad) {
touchpad_fsm_init( &fsm_state );
struct input_absinfo absinfo;
ioctl( data->fd, EVIOCGABS(ABS_X), &absinfo );
fsm_state.x.min = absinfo.minimum;
fsm_state.x.max = absinfo.maximum;
ioctl( data->fd, EVIOCGABS(ABS_Y), &absinfo );
fsm_state.y.min = absinfo.minimum;
fsm_state.y.max = absinfo.maximum;
}
/* Dima */
tsc_get_calib_file();
/* */
while (1)
{
FD_ZERO( &set );
FD_SET( data->fd, &set );
if (data->touchpad && timeout_is_set( &fsm_state.timeout )) {
struct timeval time;
gettimeofday( &time, NULL );
if (!timeout_passed( &fsm_state.timeout, &time )) {
struct timeval timeout = fsm_state.timeout;
timeout_sub( &timeout, &time );
status = select( data->fd + 1, &set, NULL, NULL, &timeout );
} else {
status = 0;
}
}
else {
status = select( data->fd + 1, &set, NULL, NULL, NULL );
}
if (status < 0 && errno != EINTR)
break;
direct_thread_testcancel( thread );
if (status < 0)
continue;
/* timeout? */
if (status == 0) {
DFBInputEvent devt;
if (data->touchpad && touchpad_fsm( &fsm_state, NULL, &devt ) > 0)
dfb_input_dispatch( data->device, &devt );
continue;
}
readlen = read( data->fd, levt, sizeof(levt) );
if (readlen < 0 && errno != EINTR)
break;
direct_thread_testcancel( thread );
if (readlen <= 0)
continue;
for (i=0; i<readlen / sizeof(levt[0]); i++) {
DFBInputEvent devt;
if (data->touchpad) {
status = touchpad_fsm( &fsm_state, &levt[i], &devt );
if (status < 0) {
/* Not handled. Try the direct approach. */
if (!translate_event( &levt[i], &devt ))
continue;
}
else if (status == 0) {
/* Handled but no further processing is necessary. */
continue;
}
}
else {
if (!translate_event( &levt[i], &devt ))
continue;
}
if (devt.type == DIET_AXISMOTION && (devt.flags & DIEF_AXISREL)) {
switch (devt.axis) {
case DIAI_X:
data->dx += devt.axisrel;
continue;
case DIAI_Y:
data->dy += devt.axisrel;
continue;
default:
break;
}
}
flush_xy( data );
/* Dima */
tsc_correct_ts_data( &devt );
/* */
dfb_input_dispatch( data->device, &devt );
if (data->has_leds && (devt.locks != data->locks)) {
set_led( data, LED_SCROLLL, devt.locks & DILS_SCROLL );
set_led( data, LED_NUML, devt.locks & DILS_NUM );
set_led( data, LED_CAPSL, devt.locks & DILS_CAPS );
data->locks = devt.locks;
}
}
flush_xy( data );
}
if (status <= 0)
D_PERROR ("linux_input thread died\n");
return NULL;
}
--
Best Regards,
Dmitry.
Embedded Development Engineer
Israel.
Mobile:
052 6 144 338
0507 63 53 10