Imported Debian patch 5.1-10
[debian/gcpegg] / reg_pear.c
1 /* PROGRAM:     eggsh
2  * FILE:        $Header: /home/egg/src/RCS/reg_pear.c,v 1.1 1998/12/31 22:04:39 ghn Exp $
3  * PURPOSE:     PEAR (Bradish box/micro-REG) hardware interface
4  * AUTHOR:      Greg Nelson
5  * DATE:        98-04-12
6  *
7  * REVISED:     $Log: reg_pear.c,v $
8  * REVISED:     Revision 1.1  1998/12/31 22:04:39  ghn
9  * REVISED:     Initial revision
10  * REVISED:
11  * REVISED:     Revision 1.3  1998/08/01 18:50:39  ghn
12  * REVISED:     Added John's byte-order-independence changes and PSEUDO support.
13  * REVISED:
14  * REVISED:     Revision 1.2  1998/08/01 17:13:51  ghn
15  * REVISED:     Added John's Solaris support and DUMPREG option.
16  * REVISED:
17  * REVISED:     Revision 1.1  1998/07/21 11:37:41  ghn
18  * REVISED:     Initial revision
19  * REVISED:
20  * Copyright 1998 - Greg Nelson
21  * Redistributable under the terms of the GNU Public Licence (GPL)
22  */
23
24 /* Define this to dump samples from the REG which we actually use into
25    a file named dumpreg.dat.  This can be used to debug serial port
26    mode problems (for example, setting the character frame to 7 bits,
27    or telling it to ignore breaks, which will lose all zero bytes. */
28 /* #define DUMPREG */
29
30 #include <stdio.h>
31 #ifdef __USE_BSD
32 #undef __USE_BSD
33 #endif
34 #define __USE_BSD
35 #include <termios.h>
36 #undef __USE_BSD
37 #include <unistd.h>
38 #include <fcntl.h>
39 #define __USE_BSD
40 #include <errno.h>
41 #undef __USE_BSD
42
43 #include "global.h"
44 #include "genlib.h"
45 #include "reg.h"
46
47 #define MAXDEV  20
48
49 static int32 oldbits[MAXDEV], bitsleft[MAXDEV];
50
51 #ifdef DUMPREG
52 static FILE *dumpfile;                /* REG dump file handle */
53 static unsigned char dumpbuf[1024];   /* REG dump buffer */
54 static int dumpptr = 0;               /* Pointer into dump buffer */
55 #endif
56
57 static int32 OpenDev(DevOpts *opts) {
58   char ttydev[30];
59   speed_t baudcon;
60   struct termios tt;
61   int32 TTY_fd, res;
62
63 #ifdef DUMPREG
64   dumpfile = fopen("dumpreg.dat", "w");
65   setbuf(dumpfile, NULL);
66   dumpptr = 0;
67 #endif
68
69 #ifdef Solaris
70   /* Serial ports (at least built-in ones) have names of
71      /dev/term/a, /dev/term/b, etc.  Map the port numbers
72      from the RC file into this nomenclature, with "1"
73      designating /dev/term/a. */
74 #ifdef Irix
75   sprintf(ttydev, "/dev/ttyd%d", opts->port);
76 #else
77   sprintf(ttydev, "/dev/term/%c", 'a' + (opts->port - 1));
78 #endif
79 #else
80   sprintf(ttydev, "/dev/ttyS%d", opts->port);
81 #endif
82
83   switch(opts->baud) {
84   case 1200: baudcon = B1200; break;
85   case 2400: baudcon = B2400; break;
86   case 4800: baudcon = B4800; break;
87   case 9600: baudcon = B9600; break;
88   case 19200: baudcon = B19200; break;
89   case 38400: baudcon = B38400; break;
90 #ifndef Irix
91   case 115200: baudcon = B115200; break;
92 #endif
93   default:
94     printf("%s: Baud rate %ld not supported.\n", pgmname, opts->baud);
95     return -1;
96   }
97
98   fprintf(stderr, "Opening %s at %ld\n", ttydev, opts->baud);
99   if ((TTY_fd = open(ttydev, O_RDONLY
100 #ifdef CPU_BOUND
101                                     | O_NDELAY
102 #endif
103       )) < 0) {
104     perror(pgmname);
105     return -1;
106   }
107
108   if (TTY_fd >= MAXDEV) {
109     fprintf(stderr, "%s: Too many devices open.\n", pgmname);
110     close(TTY_fd);
111     return -1;
112   }
113
114   res = tcgetattr(TTY_fd, &tt);
115 #ifdef Solaris
116   tt.c_iflag = 0;
117   tt.c_oflag = 0;
118   tt.c_cflag = baudcon | CS8 | CREAD | CLOCAL;
119   tt.c_lflag = 0;
120   tt.c_cc[VMIN] = 1;    /* This many chars satisfies reads */
121   tt.c_cc[VTIME] = 0;   /* or in this many tenths of seconds */
122 #else
123   res = cfsetospeed(&tt, baudcon); 
124   cfmakeraw(&tt);
125 #if !defined(__FreeBSD_kernel__)
126   tt.c_oflag &= (~(TABDLY | ONLCR));
127 #endif
128 #endif
129   res = tcsetattr(TTY_fd, TCSANOW, &tt);
130
131   oldbits[TTY_fd] = bitsleft[TTY_fd] = 0;
132   return TTY_fd;
133 }
134
135 static int32 Sample(int32 dd, uint16 bits) {
136   int32 bc, sum, n1;
137   uint8 c1;
138
139   if (dd < 0) return -1;
140
141   sum = bc = 0;
142   while (bc < bits) {
143     if (bitsleft[dd]) {
144       sum += (oldbits[dd] & 0x01);
145       oldbits[dd] >>= 1;
146       bitsleft[dd]--;
147       bc++;
148     } else {
149       do {
150         n1 = read(dd, &c1, 1);
151       } while (n1 == 0 || (n1 == -1 && errno == EAGAIN));
152       if (n1 == -1) {
153         /* Fatal error occurred, die now? */
154         return -1;
155       }
156 #ifdef DUMPREG
157       dumpbuf[dumpptr++] = c1;
158       if (dumpptr >= sizeof(dumpbuf)) {
159         fwrite(dumpbuf, sizeof(dumpbuf), 1, dumpfile);
160         dumpptr = 0;
161       }
162 #endif
163       oldbits[dd] = c1;
164       bitsleft[dd] = 8;
165     }
166   }
167
168   return sum;
169 }
170
171 #define SAMP_PERIOD     1000    /* msec */
172 #define MARGIN          .95     /* how much to headroom to allow in
173                                    speed measurement */
174
175 static int32 EvalSpeed(int32 dd) {
176   struct timeval start, end;
177   int32 bitct, samp;
178
179   if (dd < 0) return -1;
180
181   gettimeofday(&start, NULL);
182   bitct = 0;
183   while (1) {
184     gettimeofday(&end, NULL);
185     if (deltams(&end, &start) >= SAMP_PERIOD) break;
186     samp = Sample(dd, 1);
187     bitct++;
188   }
189
190   return (int32)(bitct * MARGIN);
191 }
192
193 static int32 Discard(int32 dd) {
194   int32 disc;
195 #ifdef CPU_BOUND
196   int32  n1;
197   uint8 c1;
198 #endif
199   
200   if (dd < 0) return -1;
201
202   disc = bitsleft[dd];
203   bitsleft[dd] = 0;
204
205 #ifdef CPU_BOUND
206   do {
207     n1 = read(dd, &c1, 1);
208     if (n1 == 1) disc++;
209   } while (n1 == 1);
210 #else
211   tcflush(dd, TCIFLUSH);
212 #endif
213
214   return disc;
215 }
216
217 static int32 CloseDev(int32 dd) {
218   if (dd < 0) return -1;
219
220   close(dd);
221   return 0;
222 }
223
224 /*  Driver description table.  */
225
226 REG_driver REG_pear = {
227                         "PEAR", 
228                         0,
229                         OpenDev,
230                         EvalSpeed,
231                         Sample,
232                         Discard,
233                         CloseDev
234                       };