Dr Andrew Scott G7VAV

My photo
 
June 2025
Mo Tu We Th Fr Sa Su
26 27 28 29 30 31 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 1 2 3 4 5 6


isdv4.h
001: /*
002:  * Copyright 2010 by Red Hat, Inc.
003:  *
004:  * This program is free software; you can redistribute it and/or
005:  * modify it under the terms of the GNU General Public License
006:  * as published by the Free Software Foundation; either version 2
007:  * of the License, or (at your option) any later version.
008:  *
009:  * This program is distributed in the hope that it will be useful,
010:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012:  * GNU General Public License for more details.
013:  *
014:  * You should have received a copy of the GNU General Public License
015:  * along with this program; if not, write to the Free Software
016:  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017:  */
018: 
019: 
020: #ifndef ISDV4_H
021: #define ISDV4_H
022: 
023: #define ISDV4_QUERY "*"       /* ISDV4 query command */
024: #define ISDV4_RESET "&"       /* ISDV4 touch panel reset command */
025: #define ISDV4_TOUCH_QUERY "%" /* ISDV4 touch query command */
026: #define ISDV4_STOP "0"        /* ISDV4 stop command */
027: #define ISDV4_SAMPLING "1"    /* ISDV4 sampling command */
028: 
029: /* packet length for individual models */
030: #define ISDV4_PKGLEN_TOUCH93    5
031: #define ISDV4_PKGLEN_TOUCH9A    7
032: #define ISDV4_PKGLEN_TPCPEN     9
033: #define ISDV4_PKGLEN_TPCCTL     11
034: #define ISDV4_PKGLEN_TOUCH2FG   13
035: 
036: #define HEADER_BIT      0x80
037: #define CONTROL_BIT     0x40
038: #define DATA_ID_MASK    0x3F
039: #define TOUCH_CONTROL_BIT 0x10
040: 
041: /* Only for touch devices: use serial ID as index to get packet length for device */
042: int ISDV4PacketLengths[] = {
043:         /* 0x00 => */ ISDV4_PKGLEN_TOUCH93,
044:         /* 0x01 => */ ISDV4_PKGLEN_TOUCH9A,
045:         /* 0x02 => */ ISDV4_PKGLEN_TOUCH93,
046:         /* 0x03 => */ ISDV4_PKGLEN_TOUCH9A,
047:         /* 0x04 => */ ISDV4_PKGLEN_TOUCH9A,
048:         /* 0x05 => */ ISDV4_PKGLEN_TOUCH2FG
049: };
050: 
051: /* ISDV4 protocol parsing structs. */
052: 
053: /* Query reply data */
054: typedef struct {
055:         unsigned char data_id;   /* always 00H */
056:         uint16_t x_max;
057:         uint16_t y_max;
058:         uint16_t pressure_max;
059:         uint8_t  tilt_x_max;
060:         uint8_t  tilt_y_max;
061:         uint16_t version;
062: } ISDV4QueryReply;
063: 
064: /* Touch Query reply data */
065: typedef struct {
066:         uint8_t data_id;        /* always 01H */
067:         uint8_t panel_resolution;
068:         uint8_t sensor_id;
069:         uint16_t x_max;
070:         uint16_t y_max;
071:         uint8_t capacity_resolution;
072:         uint16_t version;
073: } ISDV4TouchQueryReply;
074: 
075: /* Touch Data format. Note that capacity and finger2 are only set for some
076:  * devices (0 on all others) */
077: typedef struct {
078:         uint8_t status;         /* touch down/up */
079:         uint16_t x;
080:         uint16_t y;
081:         uint16_t capacity;
082:         struct {
083:                 uint8_t status;         /* touch down/up */
084:                 uint16_t x;
085:                 uint16_t y;
086:         } finger2;
087: } ISDV4TouchData;
088: 
089: /* Coordinate data format */
090: typedef struct {
091:         uint8_t proximity;      /* in proximity? */
092:         uint8_t tip;            /* tip/eraser pressed? */
093:         uint8_t side;           /* side switch pressed? */
094:         uint8_t eraser;         /* eraser pressed? */
095:         uint16_t x;
096:         uint16_t y;
097:         uint16_t pressure;
098:         uint8_t tilt_x;
099:         uint8_t tilt_y;
100: } ISDV4CoordinateData;
101: 
102: static int isdv4ParseQuery(const unsigned char *buffer, const size_t len,
103:                     ISDV4QueryReply *reply)
104: {
105:         int header, control;
106: 
107:         if (!reply || len < ISDV4_PKGLEN_TPCCTL)
108:                 return 0;
109: 
110:         header = !!(buffer[0] & HEADER_BIT);
111:         control = !!(buffer[0] & CONTROL_BIT);
112: 
113:         if (!header || !control)
114:                 return -1;
115: 
116:         reply->data_id = buffer[0] & DATA_ID_MASK;
117: 
118:         /* FIXME: big endian? */
119:         reply->x_max = (buffer[1] << 9) | (buffer[2] << 2) | ((buffer[6] >> 5) & 0x3);
120:         reply->y_max = (buffer[3] << 9) | (buffer[4] << 2) | ((buffer[6] >> 3) & 0x3);
121:         reply->pressure_max = (buffer[6] & 0x7) << 7 | buffer[5];
122:         reply->tilt_y_max = buffer[7];
123:         reply->tilt_x_max = buffer[8];
124:         reply->version = buffer[9] << 7 | buffer[10];
125: 
126:         return ISDV4_PKGLEN_TPCCTL;
127: }
128: 
129: static int isdv4ParseTouchQuery(const unsigned char *buffer, const size_t len,
130:                          ISDV4TouchQueryReply *reply)
131: {
132:         int header, control;
133: 
134:         if (!reply || len < ISDV4_PKGLEN_TPCCTL)
135:                 return 0;
136: 
137:         header = !!(buffer[0] & HEADER_BIT);
138:         control = !!(buffer[0] & CONTROL_BIT);
139: 
140:         if (!header || !control)
141:                 return -1;
142: 
143:         reply->data_id = buffer[0] & DATA_ID_MASK;
144:         reply->sensor_id = buffer[2] & 0x7;
145:         reply->panel_resolution = buffer[1];
146:         /* FIXME: big endian? */
147:         reply->x_max = (buffer[3] << 9) | (buffer[4] << 2) | ((buffer[2] >> 5) & 0x3);
148:         reply->y_max = (buffer[5] << 9) | (buffer[6] << 2) | ((buffer[2] >> 3) & 0x3);
149:         reply->capacity_resolution = buffer[7];
150:         reply->version = buffer[9] << 7 | buffer[10];
151: 
152:         return ISDV4_PKGLEN_TPCCTL;
153: }
154: 
155: /* pktlen defines what touch type we parse */
156: static int isdv4ParseTouchData(const unsigned char *buffer, const size_t buff_len,
157:                         const size_t pktlen, ISDV4TouchData *touchdata)
158: {
159:         int header, touch;
160: 
161:         if (!touchdata || buff_len < pktlen)
162:                 return 0;
163: 
164:         header = !!(buffer[0] & HEADER_BIT);
165:         touch = !!(buffer[0] & TOUCH_CONTROL_BIT);
166: 
167:         if (header != 1 || touch != 1)
168:                 return -1;
169: 
170:         memset(touchdata, 0, sizeof(*touchdata));
171: 
172:         touchdata->status = buffer[0] & 0x1;
173:         /* FIXME: big endian */
174:         touchdata->x = buffer[1] << 7 | buffer[2];
175:         touchdata->y = buffer[3] << 7 | buffer[4];
176:         if (pktlen == ISDV4_PKGLEN_TOUCH9A)
177:                 touchdata->capacity = buffer[5] << 7 | buffer[6];
178: 
179:         if (pktlen == ISDV4_PKGLEN_TOUCH2FG)
180:         {
181:                 touchdata->finger2.x = buffer[7] << 7 | buffer[8];
182:                 touchdata->finger2.y = buffer[9] << 7 | buffer[10];
183:                 touchdata->finger2.status = !!(buffer[0] & 0x2);
184:                 /* FIXME: is there a fg2 capacity? */
185:         }
186: 
187:         return pktlen;
188: }
189: 
190: static int isdv4ParseCoordinateData(const unsigned char *buffer, const size_t len,
191:                              ISDV4CoordinateData *coord)
192: {
193:         int header, control;
194: 
195:         if (!coord || len < ISDV4_PKGLEN_TPCPEN)
196:                 return 0;
197: 
198:         header = !!(buffer[0] & HEADER_BIT);
199:         control = !!(buffer[0] & TOUCH_CONTROL_BIT);
200: 
201:         if (header != 1 || control != 0)
202:                 return -1;
203: 
204:         coord->proximity = (buffer[0] >> 5) & 0x1;
205:         coord->tip = buffer[0] & 0x1;
206:         coord->side = (buffer[0] >> 1) & 0x1;
207:         coord->eraser = (buffer[0] >> 2) & 0x1;
208:         /* FIXME: big endian */
209:         coord->x = (buffer[1] << 9) | (buffer[2] << 2) | ((buffer[6] >> 5) & 0x3);
210:         coord->y = (buffer[3] << 9) | (buffer[4] << 2) | ((buffer[6] >> 3) & 0x3);
211: 
212:         coord->pressure = ((buffer[6] & 0x7) << 7) | buffer[5];
213:         coord->tilt_x = buffer[7];
214:         coord->tilt_y = buffer[8];
215: 
216:         return ISDV4_PKGLEN_TPCPEN;
217: }
218: 
219: #endif /* ISDV4_H */
220: 
221: /* vim: set noexpandtab tabstop=8 shiftwidth=8: */
222: 


for client (none)
© Andrew Scott 2006 - 2025,
All Rights Reserved
http://www.andrew-scott.uk/
Andrew Scott
http://www.andrew-scott.co.uk/