1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
/*
* Copyright (C) 2011 Wolfram Sang
*
* SPDX-License-Identifier: LGPL-2.1
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include "config.h"
#include "tslib-private.h"
/*
* TouchKit RS232 driver
* (controller type SAT4000UR)
* 2009.07 Fred Salabartan
*
* Packet format for position report (5 bytes):
* [0] 1 0 0 0 0 0 0 t = header (t=touched)
* [1] 0 0 0 0 X X X X = X coord most significant bits
* [2] 0 X X X X X X X = X coord less significant bits
* [3] 0 0 0 0 Y Y Y Y = Y coord most significant bits
* [4] 0 Y Y Y Y Y Y Y = Y coord less significant bits
*
* Problem: sometimes some packets overlap, so it is possible
* to find a new packet in the middle of another packet.
* -> check that no byte in the packet (but the first one)
* have its first bit set (0x80 = start)
*
* This file is placed under the LGPL. Please see the file
* COPYING for more details.
*/
enum {
PACKET_SIZE = 5,
BUFFER_SIZE = 100,
PACKET_SIGNATURE = 0x81
};
/* Is is a start of packet ? */
#define IsStart(x) (((x)|1) == PACKET_SIGNATURE)
static int touchkit_init(int dev)
{
struct termios tty;
tcgetattr(dev, &tty);
tty.c_iflag = IGNBRK | IGNPAR;
tty.c_oflag = 0;
tty.c_lflag = 0;
#ifdef __linux__
tty.c_line = 0;
#endif
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 1;
tty.c_cflag = CS8 | CREAD | CLOCAL | HUPCL;
tty.c_cflag |= B9600;
tcsetattr(dev, TCSAFLUSH, &tty);
return 1;
}
static int touchkit_read(struct tslib_module_info *inf, struct ts_sample *samp,
__attribute__ ((unused)) int nr)
{
static int initDone;
/* enough space for 2 "normal" packets */
static unsigned char buffer[BUFFER_SIZE];
static int pos;
int ret;
struct tsdev *ts = inf->dev;
int p;
int total = 0;
int q;
if (initDone == 0) {
initDone = touchkit_init(ts->fd);
if (initDone == -1)
return -1;
}
/* read some new bytes (enough for 1 normal packet) */
ret = read(ts->fd, buffer + pos, PACKET_SIZE);
if (ret <= 0)
return -1;
pos += ret;
if (pos < PACKET_SIZE)
return 0;
/* find start */
for (p = 0; p < pos; ++p)
if (IsStart(buffer[p])) {
/* we have enough data for a packet ? */
if (p + PACKET_SIZE > pos) {
if (p > 0) {
/*
* we have found a start >0, it means
* we have garbage at beginning of
* buffer so let's shift data to ignore
* this garbage
*/
memcpy(buffer, buffer + p, pos - p);
pos -= p;
}
break;
}
unsigned char *data = buffer + p;
/* check if all bytes are ok (no 'start' embedded) */
for (q = 1; q < PACKET_SIZE; ++q)
if (IsStart(buffer[p + q]))
break;
if (q < PACKET_SIZE) {
#ifdef DEBUG
fprintf(stderr,
"Start found within packet [%X %X %X %X %X] ignore %d bytes\n",
data[0], data[1], data[2], data[3],
data[4], q);
#endif
p += q - 1;
continue;
}
/* now let's decode it */
samp->x = (data[1] & 0x000F) << 7 | (data[2] & 0x007F);
samp->y =
((data[3] & 0x000F) << 7 | (data[4] & 0x007F));
samp->pressure = (data[0] & 1) ? 200 : 0;
gettimeofday(&samp->tv, NULL);
#ifdef DEBUG
fprintf(stderr,
"RAW -------------------------> data=[%X %X %X %X %X] x=%d y=%d pres=%d\n",
data[0], data[1], data[2], data[3], data[4],
samp->x, samp->y, samp->pressure);
#endif
samp++;
/* now remove it */
memcpy(buffer, buffer + p + PACKET_SIZE,
pos - p - PACKET_SIZE);
pos -= p + PACKET_SIZE;
total = 1;
break;
}
return total;
}
static const struct tslib_ops touchkit_ops = {
.read = touchkit_read,
};
TSAPI struct tslib_module_info *touchkit_mod_init(__attribute__ ((unused)) struct tsdev *dev,
__attribute__ ((unused)) const char *params)
{
struct tslib_module_info *m;
m = malloc(sizeof(struct tslib_module_info));
if (m == NULL)
return NULL;
m->ops = &touchkit_ops;
return m;
}
#ifndef TSLIB_STATIC_TOUCHKIT_MODULE
TSLIB_MODULE_INIT(touchkit_mod_init);
#endif
|