Imported Upstream version 5.1
[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   tt.c_oflag &= (~(TABDLY | ONLCR));
126 #endif
127   res = tcsetattr(TTY_fd, TCSANOW, &tt);
128
129   oldbits[TTY_fd] = bitsleft[TTY_fd] = 0;
130   return TTY_fd;
131 }
132
133 static int32 Sample(int32 dd, uint16 bits) {
134   int32 bc, sum, n1;
135   uint8 c1;
136
137   if (dd < 0) return -1;
138
139   sum = bc = 0;
140   while (bc < bits) {
141     if (bitsleft[dd]) {
142       sum += (oldbits[dd] & 0x01);
143       oldbits[dd] >>= 1;
144       bitsleft[dd]--;
145       bc++;
146     } else {
147       do {
148         n1 = read(dd, &c1, 1);
149       } while (n1 == 0 || (n1 == -1 && errno == EAGAIN));
150       if (n1 == -1) {
151         /* Fatal error occurred, die now? */
152         return -1;
153       }
154 #ifdef DUMPREG
155       dumpbuf[dumpptr++] = c1;
156       if (dumpptr >= sizeof(dumpbuf)) {
157         fwrite(dumpbuf, sizeof(dumpbuf), 1, dumpfile);
158         dumpptr = 0;
159       }
160 #endif
161       oldbits[dd] = c1;
162       bitsleft[dd] = 8;
163     }
164   }
165
166   return sum;
167 }
168
169 #define SAMP_PERIOD     1000    /* msec */
170 #define MARGIN          .95     /* how much to headroom to allow in
171                                    speed measurement */
172
173 static int32 EvalSpeed(int32 dd) {
174   struct timeval start, end;
175   int32 bitct, samp;
176
177   if (dd < 0) return -1;
178
179   gettimeofday(&start, NULL);
180   bitct = 0;
181   while (1) {
182     gettimeofday(&end, NULL);
183     if (deltams(&end, &start) >= SAMP_PERIOD) break;
184     samp = Sample(dd, 1);
185     bitct++;
186   }
187
188   return (int32)(bitct * MARGIN);
189 }
190
191 static int32 Discard(int32 dd) {
192   int32 disc;
193 #ifdef CPU_BOUND
194   int32  n1;
195   uint8 c1;
196 #endif
197   
198   if (dd < 0) return -1;
199
200   disc = bitsleft[dd];
201   bitsleft[dd] = 0;
202
203 #ifdef CPU_BOUND
204   do {
205     n1 = read(dd, &c1, 1);
206     if (n1 == 1) disc++;
207   } while (n1 == 1);
208 #else
209   tcflush(dd, TCIFLUSH);
210 #endif
211
212   return disc;
213 }
214
215 static int32 CloseDev(int32 dd) {
216   if (dd < 0) return -1;
217
218   close(dd);
219   return 0;
220 }
221
222 /*  Driver description table.  */
223
224 REG_driver REG_pear = {
225                         "PEAR", 
226                         0,
227                         OpenDev,
228                         EvalSpeed,
229                         Sample,
230                         Discard,
231                         CloseDev
232                       };