2 * FILE: $Header: /home/egg/src/RCS/reg_orion.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_orion.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 /* The Orion REG is powered by the serial port into which
50 it is plugged. If the port is not providing power to
51 the REG before we initialise it, the REG may deliver
52 garbage data as the power comes up. To guard against
53 this we take two precautions. First of all, we sleep
54 REG_INIT seconds after initialising the serial port to
55 let the REG start up and stabilise after power is
56 turned on, and we further discard REG_DISCARD initial
57 samples which may have been queued as the REG was
58 powering up. If either of these symbols is not defined
59 or zero, the corresponding start-up action will not
62 #define REG_INIT 10 /* REG power on delay */
63 #define REG_DISCARD 1024 /* Bytes to discard at start-up */
65 static int32 oldbits[MAXDEV], bitsleft[MAXDEV];
68 static FILE *dumpfile; /* REG dump file handle */
69 static unsigned char dumpbuf[1024]; /* REG dump buffer */
70 static int dumpptr = 0; /* Pointer into dump buffer */
74 extern int flush_fd; /* File descriptor for auto-flush */
77 static int32 OpenDev(DevOpts *opts) {
84 dumpfile = fopen("dumpreg.dat", "w");
85 setbuf(dumpfile, NULL);
90 /* Serial ports (at least built-in ones) have names of
91 /dev/term/a, /dev/term/b, etc. Map the port numbers
92 from the RC file into this nomenclature, with "1"
93 designating /dev/term/a. */
95 sprintf(ttydev, "/dev/ttyd%d", opts->port);
97 sprintf(ttydev, "/dev/term/%c", 'a' + (opts->port - 1));
100 sprintf(ttydev, "/dev/ttyS%d", opts->port);
104 case 1200: baudcon = B1200; break;
105 case 2400: baudcon = B2400; break;
106 case 4800: baudcon = B4800; break;
107 case 9600: baudcon = B9600; break;
108 case 19200: baudcon = B19200; break;
109 case 38400: baudcon = B38400; break;
111 case 115200: baudcon = B115200; break;
114 printf("%s: Baud rate %ld not supported.\n", pgmname, opts->baud);
118 fprintf(stderr, "Opening %s at %ld\n", ttydev, opts->baud);
119 if ((TTY_fd = open(ttydev, O_RDONLY
125 fprintf(stderr, "Error in open(%s)\n", ttydev);
129 if (TTY_fd >= MAXDEV) {
130 fprintf(stderr, "%s: Too many devices open.\n", pgmname);
135 res = tcgetattr(TTY_fd, &tt);
140 tt.c_cflag = baudcon | CS8 | CLOCAL;
142 tt.c_cflag = baudcon | CS8 | CREAD | CLOCAL;
145 tt.c_cc[VMIN] = 1; /* This many chars satisfies reads */
146 tt.c_cc[VTIME] = 0; /* or in this many tenths of seconds */
148 res = cfsetospeed(&tt, baudcon);
150 #if !defined(__FreeBSD_kernel__)
151 tt.c_oflag &= (~(TABDLY | ONLCR));
154 res = tcsetattr(TTY_fd, TCSANOW, &tt);
156 oldbits[TTY_fd] = bitsleft[TTY_fd] = 0;
158 /* Perform start-up power on delay and data flush. */
167 if (REG_DISCARD > 0) {
171 for (d = 0; d < REG_DISCARD; d++) {
173 n1 = read(TTY_fd, &c1, 1);
174 } while (n1 == 0 || (n1 == -1 && errno == EAGAIN));
186 static int32 Sample(int32 dd, uint16 bits) {
196 tcsetattr(dd, TCSANOW, &tt);
200 if (dd < 0) return -1;
205 sum += (oldbits[dd] & 0x01);
211 n1 = read(dd, &c1, 1);
212 } while (n1 == 0 || (n1 == -1 && errno == EAGAIN));
214 /* Fatal error occurred, die now? */
218 /* Orion REG does not compensate for first order bias. XOR
219 each sample with 01010101b to invert the sense of
220 alternate bits in the samples. */
224 dumpbuf[dumpptr++] = c1;
225 if (dumpptr >= sizeof(dumpbuf)) {
226 fwrite(dumpbuf, sizeof(dumpbuf), 1, dumpfile);
238 tt.c_cflag &= ~CREAD;
239 tcsetattr(dd, TCSANOW, &tt);
245 #define SAMP_PERIOD 1000 /* msec */
246 #define MARGIN .95 /* how much to headroom to allow in
249 static int32 EvalSpeed(int32 dd) {
250 struct timeval start, end;
253 if (dd < 0) return -1;
255 gettimeofday(&start, NULL);
258 gettimeofday(&end, NULL);
259 if (deltams(&end, &start) >= SAMP_PERIOD) break;
260 samp = Sample(dd, 1);
264 return (int32)(bitct * MARGIN);
267 static int32 Discard(int32 dd) {
274 if (dd < 0) return -1;
281 n1 = read(dd, &c1, 1);
285 tcflush(dd, TCIFLUSH);
291 static int32 CloseDev(int32 dd) {
292 if (dd < 0) return -1;
298 /* Driver description table. */
300 REG_driver REG_orion = {