]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/drivers/mou_dynapro.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / drivers / mou_dynapro.c
1 /* Dynapro SC3 touchscreen driver 
2    Written by Jordan Crouse, September 5, 2001
3
4    Copyright 2001, Century Embedded Technologies 
5 */
6
7 /* TODO:
8    Add support for rotated displays 
9 */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <math.h>
17 #include <sys/ioctl.h>
18 #include <sys/termios.h>
19 #include "device.h"
20
21 /* The current and saved termios */
22 static struct termios ios_saved, ios_current;
23
24 /* The file descriptor for the mouse device */
25 static int mouFd = 0;
26
27 /* The calibration data */
28 /* We plug in some generic default data here, so if */
29 /* all else fails, the pointer should still work    */
30
31 unsigned short calData[4] = { 73, 956, 883, 167 };
32
33 /* Flags to indicate if we should invert the values on the X and Y axis */
34 /* This does not mean rotation, just a backwards TS                     */
35
36 static int invX = 0, invY = 0;
37
38 extern SCREENDEVICE scrdev;
39
40 static int initSerial(char *dev) {
41   
42   /* Open up the serial port */
43   int fd = open(dev, O_NONBLOCK);
44   
45   if (fd <= 0) {
46     EPRINTF("Error opening %s\n", dev);
47     return(-1);
48   }
49   
50   /* Save the previous IO settings */
51
52   tcgetattr(fd, &ios_saved);
53   ios_current = ios_saved;
54
55   cfmakeraw(&ios_current);
56
57   /* Set the baud rate */
58
59   cfsetispeed(&ios_current, B2400);  
60   cfsetospeed(&ios_current, B2400);
61   
62   /* Set the data bits and remove the parity */
63
64   ios_current.c_cflag &= ~(CSIZE | PARENB);
65   ios_current.c_cflag |= CS8;
66
67   ios_current.c_cc[VMIN] = 3;
68   ios_current.c_cc[VTIME] = 1;
69
70   tcsetattr(fd, TCSANOW, &ios_current);
71   tcflush(fd, TCIOFLUSH);
72   
73   return(fd);
74 }
75
76 static void closeSerial(int fd) {
77
78   /* Restore the saved settings */
79
80   tcsetattr(fd, TCSANOW, &ios_saved);
81   tcflush(fd, TCIOFLUSH);
82
83   close(fd);
84 }
85
86 /* Read a byte from the fd */
87
88 static int readSerial(int fd) {
89
90   unsigned char f;
91   int val = read(fd, &f, sizeof(f));
92   
93   if (val <= 0) return(val);
94   
95   return((int) f);
96 }
97
98 /* Get some data points from the device */
99
100 static int getInput(int fd, int *data) {
101
102   int count = 0;
103   int state = 0;
104
105   /* Read the data coming in off the line */
106
107   while(1) {
108     int c;
109
110     c = readSerial(fd);
111
112     if (c < 0) {
113       if (errno == EAGAIN || errno == EINTR) return(0);
114       else return(-1);
115     }
116     
117     if (count++ > 150) return(0);  
118     
119
120     switch(state) {
121
122     case 0:
123       if (c & 0x80) {
124         data[0] = (unsigned char) c;
125         state = 1;
126       }
127
128       /* This is a useless warning */
129
130 #ifdef NOTUSED
131       else 
132         fprintf(stderr, "Non start byte recieved (%2.2x)\n", c);
133 #endif
134
135       break;
136
137     case 1:
138       if (!(c & 0x80)) {
139         data[1] = (unsigned char) c;
140         state = 2;
141       }
142       else {
143 #ifdef NOTUSED
144         fprintf(stderr, "Got a start byte in the middle of the packet\n");
145 #endif
146
147         data[0] = (unsigned char) c;
148
149         state = 0;
150       }
151
152       break;
153
154     case 2:
155
156       if (!(c & 0x80)) {
157         data[2] = (unsigned char) c;
158         return(1);
159       }
160       else {
161 #ifdef NOTUSED
162         fprintf(stderr, "Got a start byte in the middle of the packet\n");
163 #endif
164         data[0] = (unsigned char) c;
165
166         state = 0;
167       }
168
169       break;
170     }
171   }
172
173   return(1);
174 }
175
176 /* Read calibration from a file */
177
178 static int readCalibration(char *filename) {
179
180   char buffer[128];
181
182   int calfd = open(filename, O_RDONLY);
183
184   /* If the file doesn't exist, then just use the default values */
185   if (calfd < 0)  return(0);
186   
187   /* The data will be formated as 4 values:
188      xmin xmax ymin ymax
189   */
190
191   if (read(calfd, buffer, sizeof(buffer)) <= 0) {
192     close(calfd);
193     return(0);
194   }
195   
196   sscanf(buffer, "%d %d %d %d\n", &calData[0], &calData[1], &calData[2], &calData[3]);
197   
198   close(calfd);
199
200   /* Check the calibration values, and reverse them if we have to */
201
202   if (calData[1] < calData[0]) {
203     int  tmp = calData[1];
204
205     calData[1] = calData[0];
206     calData[0] = tmp;
207     
208     invX = 1;
209   }
210
211   if (calData[3] < calData[2]) {
212     int tmp = calData[3];
213     calData[3] = calData[2];
214     calData[2] = tmp;
215
216     invY = 1;
217   }
218   
219   return(0);
220 }
221
222 static void doScale(int x, int y, int *dx, int *dy) {
223   
224   /* Scale the data appropriately to the screen */
225   
226   *dx = ((x - calData[0]) * scrdev.xres) / (calData[1] - calData[0]);
227   *dy = ((y - calData[2]) * scrdev.yres) / (calData[3] - calData[2]);
228 }
229
230 static int MOU_Open(MOUSEDEVICE *pmd) {
231
232   int calfd;
233
234   mouFd = initSerial("/dev/ttyS1");
235
236   if (mouFd == -1) {
237     EPRINTF("Unable to open /dev/ttyS1 for reading\n");
238     return(-1);
239   }
240
241   if (readCalibration("/etc/caldata") == -1) {
242     closeSerial(mouFd);
243     EPRINTF("Unable to get the calibration data\n");
244     return(-1);
245   }
246
247   /* success */
248   
249   GdHideCursor(&scrdev);
250   return(mouFd);
251 }
252
253 static int MOU_GetButtonInfo(void) {
254   return(MWBUTTON_L);
255 }
256
257 static void MOU_GetDefaultAccel(int *pscale, int *pthresh) {
258   *pscale = 3;
259   *pthresh = 5;
260 }
261
262 static void MOU_Close(void) {
263
264   if (mouFd >= 0)
265     closeSerial(mouFd);
266   
267   mouFd = -1;
268 }
269
270 static int MOU_Read(MWCOORD *px, MWCOORD *py, MWCOORD *pz, int *pb) {
271
272   int i;
273
274   int totalx = 0, totaly = 0;
275   int data[4];
276
277   /* For now, only grab one reading, this touchscreen is pretty */
278   /* good, so jitter isn't a problem                            */
279
280   for(i = 0; i < 1; i++) {
281     int x, y, sx, sy;
282     int val;
283
284     val = getInput(mouFd, data);
285     
286     if (val == -1) return(0);
287     else if (val == 0) break;
288
289     x = data[1] | ((data[0] & 0x38) << 4);
290     y = data[2] | ((data[0] & 0x07) << 7);
291
292     /* Send the data in for calibration */
293     doScale(x, y, &sx, &sy);
294
295     /* Inver the axii if needed */
296
297     if (invX) 
298       sx = scrdev.xres - sx;
299     if (invY)
300       sy = scrdev.yres - sy;
301
302     totalx += sx;
303     totaly += sy;
304   }
305
306   if (i == 0) return(0);
307
308   *px = totalx / (i);
309   *py = totaly / (i);
310
311   /* Record the last state of the mouse */
312  
313   *pb = ( (data[0] & 0x40) ? MWBUTTON_L : 0 );
314   *pz = 0;
315
316   if (!*pb) return(3); else return(2);
317 }
318
319 MOUSEDEVICE mousedev = {
320   MOU_Open,
321   MOU_Close,
322   MOU_GetButtonInfo,
323   MOU_GetDefaultAccel,
324   MOU_Read,
325   NULL
326 };
327