Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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