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
7 * REVISED: $Log: reg_pear.c,v $
8 * REVISED: Revision 1.1 1998/12/31 22:04:39 ghn
9 * REVISED: Initial revision
11 * REVISED: Revision 1.3 1998/08/01 18:50:39 ghn
12 * REVISED: Added John's byte-order-independence changes and PSEUDO support.
14 * REVISED: Revision 1.2 1998/08/01 17:13:51 ghn
15 * REVISED: Added John's Solaris support and DUMPREG option.
17 * REVISED: Revision 1.1 1998/07/21 11:37:41 ghn
18 * REVISED: Initial revision
20 * Copyright 1998 - Greg Nelson
21 * Redistributable under the terms of the GNU Public Licence (GPL)
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. */
49 static int32 oldbits[MAXDEV], bitsleft[MAXDEV];
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 */
57 static int32 OpenDev(DevOpts *opts) {
64 dumpfile = fopen("dumpreg.dat", "w");
65 setbuf(dumpfile, NULL);
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. */
75 sprintf(ttydev, "/dev/ttyd%d", opts->port);
77 sprintf(ttydev, "/dev/term/%c", 'a' + (opts->port - 1));
80 sprintf(ttydev, "/dev/REG", opts->port);
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;
91 case 115200: baudcon = B115200; break;
94 printf("%s: Baud rate %d not supported.\n", pgmname, opts->baud);
98 fprintf(stderr, "Opening %s at %d\n", ttydev, opts->baud);
99 if ((TTY_fd = open(ttydev, O_RDONLY
108 if (TTY_fd >= MAXDEV) {
109 fprintf(stderr, "%s: Too many devices open.\n", pgmname);
114 res = tcgetattr(TTY_fd, &tt);
118 tt.c_cflag = baudcon | CS8 | CREAD | CLOCAL;
120 tt.c_cc[VMIN] = 1; /* This many chars satisfies reads */
121 tt.c_cc[VTIME] = 0; /* or in this many tenths of seconds */
123 res = cfsetospeed(&tt, baudcon);
125 #if !defined(__FreeBSD_kernel__)
126 tt.c_oflag &= (~(TABDLY | ONLCR));
129 res = tcsetattr(TTY_fd, TCSANOW, &tt);
131 oldbits[TTY_fd] = bitsleft[TTY_fd] = 0;
135 static int32 Sample(int32 dd, uint16 bits) {
139 if (dd < 0) return -1;
144 sum += (oldbits[dd] & 0x01);
150 n1 = read(dd, &c1, 1);
151 } while (n1 == 0 || (n1 == -1 && errno == EAGAIN));
153 /* Fatal error occurred, die now? */
157 dumpbuf[dumpptr++] = c1;
158 if (dumpptr >= sizeof(dumpbuf)) {
159 fwrite(dumpbuf, sizeof(dumpbuf), 1, dumpfile);
171 #define SAMP_PERIOD 1000 /* msec */
172 #define MARGIN .95 /* how much to headroom to allow in
175 static int32 EvalSpeed(int32 dd) {
176 struct timeval start, end;
179 if (dd < 0) return -1;
181 gettimeofday(&start, NULL);
184 gettimeofday(&end, NULL);
185 if (deltams(&end, &start) >= SAMP_PERIOD) break;
186 samp = Sample(dd, 1);
190 return (int32)(bitct * MARGIN);
193 static int32 Discard(int32 dd) {
200 if (dd < 0) return -1;
207 n1 = read(dd, &c1, 1);
211 tcflush(dd, TCIFLUSH);
217 static int32 CloseDev(int32 dd) {
218 if (dd < 0) return -1;
224 /* Driver description table. */
226 REG_driver REG_pear = {