Subversion Repositories shark

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/**
22
 ------------
23
 CVS :        $Id: sermouse.c,v 1.1.1.1 2002-03-29 14:12:49 pj Exp $
24
 
25
 File:        $File$
26
 Revision:    $Revision: 1.1.1.1 $
27
 Last update: $Date: 2002-03-29 14:12:49 $
28
 ------------
29
 
30
 Author:        Gerardo Lamastra
31
 Date:  9/5/96
32
 
33
 Revision:      1.1b
34
 Date:        14/Apr/1999
35
 
36
 Serial mouse driver
37
 The mouse driver receives data from the serial RxServer()
38
 Then it processes the mouse packet and sets the variables
39
 representing the external mouse status.
40
 
41
**/
42
 
43
/*
44
 * Copyright (C) 2000 Paolo Gai
45
 *
46
 * This program is free software; you can redistribute it and/or modify
47
 * it under the terms of the GNU General Public License as published by
48
 * the Free Software Foundation; either version 2 of the License, or
49
 * (at your option) any later version.
50
 *
51
 * This program is distributed in the hope that it will be useful,
52
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
53
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
54
 * GNU General Public License for more details.
55
 *
56
 * You should have received a copy of the GNU General Public License
57
 * along with this program; if not, write to the Free Software
58
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
59
 *
60
 */
61
 
62
/*
63
 * Revision: 1.1
64
 * Author: Massimiliano Giorgi
65
 *
66
 * This code were in mouse.c:
67
 * -- there is a mouse server (Microsoft Mouse Protocol)
68
 * -- there is "virtual operation" on a serial mouse
69
 */
70
 
71
/*
72
 * Revison: 1.1b
73
 * Changed to compile on 3.2.0
74
 * -- added wcet time to all task
75
 */
76
 
77
/*
78
 * -- changed internal structure to integrate "gpm" code
79
 * -- now is used ONE task (not two!)
80
 */
81
 
82
//#include <string.h>
83
//#include <stdlib.h>
84
//#include <cons.h>
85
 
86
#include <kernel/kern.h>
87
//#include "sys/sys.h"
88
//#include "vm.h"
89
//#include "kern.h"
90
//#include "exc.h"
91
 
92
#include <drivers/scom.h>
93
#include <drivers/mouse.h>
94
 
95
#include "_mouse.h"
96
#include "sermouse.h"
97
#include <modules/sem.h>
98
 
99
//#define __DEBUG_MOUSE__
100
//#define __XTRA_DEBUG_MOUSE__
101
 
102
/* if defined: trace the initialization */
103
//#define __DEBUG_INIT__ 1
104
 
105
/* if defined: show data received from serial port on the screen */
106
//#define __DEBUG_DATAIN__ 1
107
 
108
/*
109
 * The following code is derived from gpm (under GPL)
110
 */
111
 
112
#include "gpmcomp.h"
113
 
114
/*
115
 * START!!
116
 *
117
 * mice.c - mouse definitions for gpm-Linux
118
 *
119
 * Copyright (C) 1993        Andrew Haylett <ajh@gec-mrc.co.uk>
120
 * Copyright (C) 1994-1999   Alessandro Rubini <rubini@linux.it>
121
 * Copyright (C) 1998,1999   Ian Zimmerman <itz@rahul.net>
122
 */
123
 
124
int M_ms(Gpm_Event *state,  unsigned char *data)
125
{
126
  /*
127
   * some devices report a change of middle-button state by
128
   * repeating the current button state  (patch by Mark Lord)
129
   */
130
  static unsigned char prev=0;
131
 
132
  if (data[0] == 0x40 && !(prev|data[1]|data[2]))
133
    state->buttons = GPM_B_MIDDLE; /* third button on MS compatible mouse */
134
  else
135
    state->buttons= ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4);
136
  prev = state->buttons;
137
  state->dx=      (signed char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F));
138
  state->dy=      (signed char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F));
139
 
140
  return 0;
141
}
142
 
143
int M_ms_plus(Gpm_Event *state, unsigned char *data)
144
{
145
  static unsigned char prev=0;
146
 
147
  state->buttons= ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4);
148
  state->dx=      (signed char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F));
149
  state->dy=      (signed char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F));
150
 
151
  /* Allow motion *and* button change (Michael Plass) */
152
 
153
  if ((state->dx==0) && (state->dy==0)
154
      && (state->buttons == (prev&~GPM_B_MIDDLE)))
155
    state->buttons = prev^GPM_B_MIDDLE;  /* no move or change: toggle middle */
156
  else
157
    state->buttons |= prev&GPM_B_MIDDLE;    /* change: preserve middle */
158
 
159
  prev=state->buttons;
160
 
161
  return 0;
162
}
163
 
164
int M_ms_plus_lr(Gpm_Event *state,  unsigned char *data)
165
{
166
  /*
167
   * Same as M_ms_plus but with an addition by Edmund GRIMLEY EVANS
168
   */
169
  static unsigned char prev=0;
170
 
171
  state->buttons= ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4);
172
  state->dx=      (signed char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F));
173
  state->dy=      (signed char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F));
174
 
175
  /* Allow motion *and* button change (Michael Plass) */
176
 
177
  if ((state->dx==0) && (state->dy==0)
178
      && (state->buttons == (prev&~GPM_B_MIDDLE)))
179
    state->buttons = prev^GPM_B_MIDDLE;  /* no move or change: toggle middle */
180
  else
181
    state->buttons |= prev&GPM_B_MIDDLE;    /* change: preserve middle */
182
 
183
  /* Allow the user to reset state of middle button by pressing
184
     the other two buttons at once (Edmund GRIMLEY EVANS) */
185
 
186
  if (!((~state->buttons)&(GPM_B_LEFT|GPM_B_RIGHT)) &&
187
      ((~prev)&(GPM_B_LEFT|GPM_B_RIGHT)))
188
    state->buttons &= ~GPM_B_MIDDLE;
189
 
190
  prev=state->buttons;
191
 
192
  return 0;
193
}
194
 
195
int M_bare(Gpm_Event *state,  unsigned char *data)
196
{
197
  /* a bare ms protocol */
198
  state->buttons= ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4);
199
  state->dx=      (signed char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F));
200
  state->dy=      (signed char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F));
201
  return 0;
202
}
203
 
204
int M_sun(Gpm_Event *state,  unsigned char *data)
205
{
206
  state->buttons= (~data[0]) & 0x07;
207
  state->dx=      (signed char)(data[1]);
208
  state->dy=     -(signed char)(data[2]);
209
  return 0;
210
}
211
 
212
int M_mm(Gpm_Event *state,  unsigned char *data)
213
{
214
  state->buttons= data[0] & 0x07;
215
  state->dx=      (data[0] & 0x10) ?   data[1] : - data[1];
216
  state->dy=      (data[0] & 0x08) ? - data[2] :   data[2];
217
  return 0;
218
}
219
 
220
int M_logi(Gpm_Event *state,  unsigned char *data) /* equal to mm */
221
{
222
  state->buttons= data[0] & 0x07;
223
  state->dx=      (data[0] & 0x10) ?   data[1] : - data[1];
224
  state->dy=      (data[0] & 0x08) ? - data[2] :   data[2];
225
  return 0;
226
}
227
 
228
int M_msc(Gpm_Event *state,  unsigned char *data)
229
{
230
  state->buttons= (~data[0]) & 0x07;
231
  state->dx=      (signed char)(data[1]) + (signed char)(data[3]);
232
  state->dy=     -((signed char)(data[2]) + (signed char)(data[4]));
233
  return 0;
234
}
235
 
236
/*
237
 * mice.c - mouse definitions for gpm-Linux
238
 *
239
 * END!!
240
 *
241
 */
242
 
243
static BYTE proto_mouse0,proto_mouse1,proto_mouse2,proto_mouse3;
244
 
245
static char data[4]; // serial can go here?
246
 
247
static PID rx_server_pid = NIL;
248
static short int mouse_port = 0;
249
 
250
extern void (*com_fast)(int);
251
 
252
 
253
#define SBUFFERSIZE 64
254
#define SBUFFERMASK 0x3f
255
static BYTE sbuffer[SBUFFERSIZE];
256
static unsigned stail,shead;
257
static int scount;
258
 
259
void sermouse_fast(int);
260
 
261
int sermouse_open(void *info)
262
{
263
  SERMOUSE_INFO *sinfo=(SERMOUSE_INFO*)info;
264
//  MODEL m = BASE_MODEL;
265
  int status;
266
 
267
#ifdef __DEBUG_INIT__
268
  cprintf("sermouse_open: START\n");
269
#endif
270
 
271
  /*
272
   * Open serial device
273
   */
274
  switch (sinfo->type) {
275
  case MSCMOUSE:
276
  case SUNMOUSE:
277
  case LOGIMOUSE:
278
    status=com_open(sinfo->port,1200,NONE,8,1); /* perhaps needs 2 stop bits */
279
    break;
280
  case MMMOUSE:
281
    status=com_open(sinfo->port,1200,ODD,8,1);
282
    break;
283
  case MSMOUSE:
284
  case MSPMOUSE:
285
  case MSPLRMOUSE:
286
  case BAREMOUSE:
287
  default:
288
    status=com_open(sinfo->port,1200,NONE,7,1);
289
    break;
290
  }
291
  if (status!=1) return -1;
292
 
293
#ifdef __DEBUG_INIT__
294
  cprintf("sermouse_open: COM port opened\n");
295
#endif
296
 
297
  /* for some old logitech mouse */
298
  if (sinfo->type==LOGIMOUSE) {
299
 
300
    static struct {
301
      int sample; char code[1];
302
    } sampletab[]={
303
      {  0,{'O'}},
304
      { 15,{'J'}},
305
      { 27,{'K'}},
306
      { 42,{'L'}},
307
      { 60,{'R'}},
308
      { 85,{'M'}},
309
      {125,{'Q'}},
310
      {1E9,{'N'}}
311
    };
312
    int opt_sample=40;
313
    int i;
314
 
315
    /* UNTESTED!!! */
316
    /* probably don't work*/
317
 
318
    /* this stuff is peculiar of logitech mice, also for the serial ones */
319
    com_send(sinfo->port,'S');
320
 
321
    /* configure the sample rate */
322
    for (i=0;opt_sample<=sampletab[i].sample;i++);
323
    com_send(sinfo->port,sampletab[i].code[0]);
324
 
325
#ifdef __DEBUG_INIT__
326
    cprintf("sermouse_open: 'logi' initialization done\n");
327
#endif
328
  }
329
 
330
  proto_mouse0=proto_mouse[0];
331
  proto_mouse1=proto_mouse[1];
332
  proto_mouse2=proto_mouse[2];
333
  proto_mouse3=proto_mouse[3];
334
  scount=0;
335
  stail=0;
336
  shead=1;
337
 
338
  /*
339
   * Create Serial port task
340
   */
341
 
342
  /* MG: to use one task */
343
  //task_def_arg(m,sinfo->port);
344
  //task_def_wcet(m,500);
345
  //rx_server_pid = task_create("RxServer",rxServer,HARD,APERIODIC,100,&m);
346
  rx_server_pid=sinfo->pid;
347
 
348
  /* test if exist the task...*/
349
  if (rx_server_pid==-1) {
350
    com_close(sinfo->port);
351
    return -1;    
352
  }
353
  com_fast=sermouse_fast;
354
  com_server(sinfo->port,RX_FULL,NIL);
355
#ifdef __DEBUG_INIT__
356
  cprintf("sermouse_open: COM task created\n");
357
#endif
358
 
359
  /* MG: not needed (the fast handler activate the task) */
360
  task_activate(rx_server_pid);
361
#ifdef __DEBUG_INIT__
362
  //cprintf("sermouse_open: COM task activated\n");
363
#endif
364
 
365
  mouse_port = sinfo->port;
366
  com_link[sinfo->port].msk = RX_FULL;
367
  com_write(sinfo->port,IER,RX_FULL);
368
  /* this is for safety! */
369
  com_link[sinfo->port].rx_buf = data;
370
 
371
#ifdef __DEBUG_INIT__
372
  cprintf("sermouse_open: COM port configurated\n");
373
#endif
374
 
375
  /* Enable RTS & DTR to activate mouse! */
376
  sermouse_enable();
377
#ifdef __DEBUG_INIT__
378
  cprintf("sermouse_open: mouse activated\n");
379
#endif
380
  return 0;
381
}
382
 
383
/*
384
 * return the server's address
385
 */
386
 
387
TASK (*sermouse_getserveraddr(SERMOUSE_INFO *infoptr))(void)
388
{
389
  return generalmouse_server;
390
}
391
 
392
/*
393
 * test if a mouse is present
394
 *
395
 * "When DTR line is toggled, mouse should send one data byte"
396
 * "containing letter 'M' (ascii 77)."
397
 * Tomi Engdahl <then@delta.hut.fi>
398
 *
399
 * this for Microsoft Serial mouse
400
 */
401
 
402
SERMOUSE_INFO *sermouse_present(void)
403
{
404
  static SERMOUSE_INFO info;
405
  int port;
406
  int ret;
407
  int found;
408
 
409
  found=0;
410
  for (port=COM1;port<=COM4;port++) {
411
    ret=com_open(port,1200,NONE,7,1);
412
    if (ret==1) {
413
      com_write(port,MCR,0x0e);
414
      task_delay(500000l); /* necessary? */
415
      com_write(port,MCR,0x0f);
416
      task_delay(500000l); /* necessary? */
417
      ret=sem_wait(&com_link[mouse_port].rx_sem);
418
      if (ret==TRUE) {
419
        if (*(com_link[mouse_port].rx_buf)=='M') found=1;
420
      }    
421
      com_close(port);
422
      if (found) {
423
        info.type=BAREMOUSE;
424
        info.port=port;
425
        return &info;
426
      }
427
    }
428
  }
429
  return NULL;
430
}
431
 
432
/* MG: the "virtual operation" operate on a serial port */
433
void sermouse_close(void)
434
{
435
  com_close(mouse_port);
436
}
437
 
438
void sermouse_disable(void)
439
{
440
  com_write(mouse_port,MCR,0);
441
}
442
 
443
void sermouse_enable(void)
444
{
445
  com_write(mouse_port,MCR,0x0F);
446
}
447
 
448
void sermouse_wait(void)
449
{
450
  task_endcycle();
451
  /* changed to use one task */
452
  //sem_wait(&com_link[mouse_port].rx_sem);
453
}
454
 
455
#ifdef __DEBUG_DATAIN__
456
 
457
/* debug values for keyboadget() and auxget() */
458
#define YDEB     2
459
#define COLORDEB WHITE
460
 
461
static int auxx=2;
462
 
463
#endif
464
 
465
int sermouse_get(BYTE *data)
466
{
467
  SYS_FLAGS f;
468
  int i;
469
//  BYTE *p=data;
470
//  BYTE t;
471
 
472
 
473
  f=kern_fsave();
474
  if (((stail+1)&SBUFFERMASK)==shead) {
475
    kern_frestore(f);
476
    return 0;
477
  }
478
  for (i=0;i<packetlen_mouse;i++) {
479
    stail=(stail+1)&SBUFFERMASK;
480
    *data++=sbuffer[stail];
481
  }
482
  kern_frestore(f);
483
 
484
#ifdef __DEBUG_DATAIN__
485
    /*
486
     * if debug...
487
     * show all data from the serial port on YDEB line of the screen
488
     */
489
    {
490
      int i;
491
      for (i=-packetlen_mouse;i<0;i++) {       
492
        if (auxx+5>=80) {
493
          printf_xy(auxx,YDEB,COLORDEB," ");
494
          auxx=2;
495
        }
496
        if (auxx==2) printf_xy(0,YDEB,COLORDEB,"S ");
497
        printf_xy(auxx,YDEB,COLORDEB,"%02x > ",(unsigned)*(data+i));
498
        auxx+=3;
499
      }
500
    }
501
#endif
502
 
503
  return packetlen_mouse;
504
  //*data=com_read(mouse_port,RBR);
505
     //com_write(mouse_port,IER,com_link[mouse_port].msk);
506
     //return 1;
507
     /* changed to use one task */
508
    //return *(com_link[mouse_port].rx_buf);
509
}
510
 
511
void sermouse_fast(int port)
512
{
513
  SYS_FLAGS f;
514
  BYTE data;
515
 
516
  f=kern_fsave();
517
 
518
  data=com_read(mouse_port,RBR);
519
  com_write(mouse_port,IER,com_link[mouse_port].msk);
520
 
521
  if (scount==0&&((data&proto_mouse0)!=proto_mouse1)) {
522
    kern_frestore(f);
523
    return;
524
  } else if (scount==1&&((data&proto_mouse2)!=proto_mouse3)) {
525
    shead=(shead-scount+SBUFFERSIZE)&SBUFFERMASK;
526
    scount=0;
527
    kern_frestore(f);
528
    return;
529
  }
530
  scount++;
531
 
532
  if (stail!=shead) {
533
    sbuffer[shead]=data;
534
    shead=(shead+1)&SBUFFERMASK;
535
  } else {
536
    shead=(shead-(scount-1)+SBUFFERSIZE)&SBUFFERMASK;
537
    scount=0;
538
  }
539
 
540
  if (scount==packetlen_mouse) {
541
    scount=0;
542
    kern_frestore(f);
543
    task_activate(rx_server_pid);
544
    return;
545
  }
546
 
547
  kern_frestore(f);
548
}