Hardware Touchscreen

From OpenTom

Jump to: navigation, search

General

  • see Hello world example
  • The touch screen must be calibrated if you replace ttn (which does calibration for you). The calibration data is stored in flash memory, and can be accessed (on OpenTom 0.0.2) by reading the file /mnt/flash/sysfile/cal .
  • The touch screen is available on character device 254:0 (should be /dev/ts)

Calibration

Here is an exemple for the TomTom One. For other models, it may be necessary to swap horizontal and vertical calibration data.

 static MATRIX cal_data;
 ioctl(tsfd,TS_GET_CAL,&cal_data);
 // Read calibration data in flash memory
 FILE * cal_file = fopen ("/mnt/flash/sysfile/cal","rb");
 if ((cal_file == NULL) || (fread (&cal_data.xMin, sizeof(int), 4, cal_file) != 4))
 {
    perror ("Reading calibration file");
    exit (1);
 }
 fclose (cal_file);
 ioctl(tsfd,TS_SET_CAL,&cal_data);
 ioctl(tsfd,TS_SET_RAW_OFF,NULL);

Using the touch screen

Also check Tslib.

#include <linux/input.h>
#include "Barc_ts.h" // (this file can be found in the latest toolchain; e.g. http://www.tomtom.com/gpl/toolchain_cygwin_gcc-3.3.4_glibc-2.3.2-20060131a.tar.gz)

// = /dev/ts =============================================================

//struct input_event {
//   struct timeval time;
//   unsigned short type;
//   unsigned short code;
//   unsigned int value;
//};
struct input_event ev2;
static MATRIX ts_matrix;
boolean eventMode = false;
TS_EVENT ev;
int ts = -1;

bool initTS() {
  if (ts == -1) { // Old mode?
     ts = open("/dev/ts", O_RDONLY | O_NONBLOCK);
     if (ts == -1) { // Seems not, try the new mode
        ts = open("/dev/input/event0", O_RDONLY | O_NONBLOCK);
        if (ts != -1) { // Ok, that worked.
           eventMode = true; // Remember that!
           FILE * cal_file = fopen ("/mnt/flash/sysfile/cal","rb");
           if ((cal_file == NULL) || (fread (&ts_matrix.xMin, sizeof(int), 4, cal_file) != 4)) {
              debug("Error reading calibration file!");
              close(ts);
              ts = -1;
           }
           fclose (cal_file);
        } else {
          debug("Error opening ts!");
        }
     }
  }
  return ts != -1;
}

int readTS () {
  if (eventMode) {
     int retval = read(ts, &ev2, sizeof(struct input_event)) == sizeof(struct input_event) ? 1 : 0;
     while (retval) {
       if (ev2.type==EV_ABS && ev2.code==ABS_X) {
          ev.x = ev2.value;
           ev.x = (((ev.x - ts_matrix.xMin) * (vinfo.xres-30)) / (ts_matrix.xMax - ts_matrix.xMin)) +15;
           if (ev.x < 0)
              ev.x = 0;
           else if ((unsigned)ev.x > vinfo.xres)
              ev.x = vinfo.xres;
           ev.x = vinfo.xres - ev.x;
           if (ev.y!=-1) // -> full dataset.
              return 1;
        } else if (ev2.type==EV_ABS && ev2.code==ABS_Y) {
          ev.y = ev2.value;
           ev.y = (((ev.y - ts_matrix.yMin) * (vinfo.yres-30)) / (ts_matrix.yMax - ts_matrix.yMin)) +15;
           if (ev.y < 0)
              ev.y = 0;
           else if ((unsigned)ev.y > vinfo.yres)
              ev.y = vinfo.yres;
           ev.y = vinfo.yres - ev.y;
           if (ev.x!=-1) // -> full dataset.
              return 1;
       } else if (ev2.type==EV_KEY && ev2.code==BTN_TOUCH) {
     if (ev2.value) {
        ev.pressure = 255;
        ev.x = -1; // Reset...
        ev.y = -1;
           } else {
        ev.pressure = 0;
        return 1; // button-release -> another full dataset.
           }
        }
        retval = read(ts, &ev2, sizeof(struct input_event)) == sizeof(struct input_event) ? 1 : 0;
     }
     return retval;
  } else
     return read(ts, &ev, sizeof(TS_EVENT)) == sizeof(TS_EVENT) ? 1 : 0;
}

int flushTS() {
  int count=0;
  while (readTS())
     count++;
  return count;
}

void closeTS() {
  if (ts!=-1) {
     flushTS();
     close(ts);
     ts = -1;
  }
}

// = /dev/ts =============================================================
Personal tools