FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/gpib.c
1 /*
2 * GPIB driver for FreeBSD.
3 * Version 0.1 (No interrupts, no DMA)
4 * Supports National Instruments AT-GPIB and AT-GPIB/TNT boards.
5 * (AT-GPIB not tested, but it should work)
6 *
7 * Written by Fred Cawthorne (fcawth@delphi.umd.edu)
8 * Some sections were based partly on the lpt driver.
9 * (some remnants may remain)
10 *
11 * This software is distributed with NO WARRANTIES, not even the implied
12 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * The author grants any other persons or organizations permission to use
15 * or modify this software as long as this message is kept with the software,
16 * all derivative works or modified versions.
17 *
18 * $FreeBSD: releng/5.0/sys/i386/isa/gpib.c 106696 2002-11-09 12:55:07Z alfred $
19 */
20
21 /* Please read the README file for usage information */
22
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/kernel.h>
26 #include <sys/conf.h>
27 #include <sys/uio.h>
28 #include <sys/malloc.h>
29 #include <sys/bus.h>
30 #include <i386/isa/gpibreg.h>
31 #include <i386/isa/gpib.h>
32 #include <i386/isa/isa_device.h>
33
34 #ifndef COMPAT_OLDISA
35 #error "The gpib device requires the old isa compatibility shims"
36 #endif
37
38 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
39
40 #define GPIBPRI (PZERO + 8) | PCATCH
41 #define SLEEP_MAX 1000
42 #define SLEEP_MIN 4
43
44 static int initgpib(void);
45 static void closegpib(void);
46 static int sendgpibfifo(unsigned char device, char *data, int count);
47 static int sendrawgpibfifo(unsigned char device, char *data, int count);
48 static int readgpibfifo(unsigned char device, char *data, int count);
49 #if 0
50 static void showregs(void);
51 #endif
52 static void enableremote(unsigned char device);
53 static void gotolocal(unsigned char device);
54 static void menableremote(unsigned char *device);
55 static void mgotolocal(unsigned char *device);
56 static void mtrigger(unsigned char *device);
57 static void trigger(unsigned char device);
58 static char spoll(unsigned char device);
59
60 static int gpprobe(struct isa_device *dvp);
61 static int gpattach(struct isa_device *dvp);
62
63 struct isa_driver gpdriver = {
64 INTR_TYPE_TTY,
65 gpprobe,
66 gpattach,
67 "gp"
68 };
69 COMPAT_ISA_DRIVER(gp, gpdriver);
70
71 static d_open_t gpopen;
72 static d_close_t gpclose;
73 static d_write_t gpwrite;
74 static d_ioctl_t gpioctl;
75
76 #define CDEV_MAJOR 44
77 static struct cdevsw gp_cdevsw = {
78 /* open */ gpopen,
79 /* close */ gpclose,
80 /* read */ noread,
81 /* write */ gpwrite,
82 /* ioctl */ gpioctl,
83 /* poll */ nopoll,
84 /* mmap */ nommap,
85 /* strategy */ nostrategy,
86 /* name */ "gp",
87 /* maj */ CDEV_MAJOR,
88 /* dump */ nodump,
89 /* psize */ nopsize,
90 /* flags */ 0,
91 };
92
93 #define BUFSIZE 1024
94 #define ATTACHED 0x08
95 #define OPEN 0x04
96 #define INIT 0x02
97
98 static struct gpib_softc {
99 char *sc_cp; /* current data to send */
100 int sc_count; /* bytes queued in sc_inbuf */
101 int sc_type; /* Type of gpib controller */
102 u_char sc_flags; /* flags (open and internal) */
103 char sc_unit; /* gpib device number */
104 char *sc_inbuf; /* buffer for data */
105 } gpib_sc; /* only support one of these? */
106
107 static int oldcount;
108 static char oldbytes[2];
109
110 /*
111 * Probe routine
112 * This needs to be changed to be a bit more robust
113 */
114 static int
115 gpprobe(struct isa_device *dvp)
116 {
117 int status;
118 struct gpib_softc *sc = &gpib_sc;
119
120 gpib_port = dvp->id_iobase;
121 status = 1;
122 sc->sc_type = 3;
123 if ((inb(KSR) & 0xF7) == 0x34)
124 sc->sc_type = 3;
125 else if ((inb(KSR) & 0xF7) == 0x24)
126 sc->sc_type = 2;
127 else if ((inb(KSR) & 0xF7) == 0x14)
128 sc->sc_type = 1;
129 else
130 status = 0;
131 return (status);
132 }
133
134 /*
135 * gpattach()
136 * Attach device and print the type of card to the screen.
137 */
138 static int
139 gpattach(isdp)
140 struct isa_device *isdp;
141 {
142 struct gpib_softc *sc = &gpib_sc;
143
144 sc->sc_unit = isdp->id_unit;
145 if (sc->sc_type == 3)
146 printf ("gp%d: type AT-GPIB/TNT\n", sc->sc_unit);
147 if (sc->sc_type == 2)
148 printf ("gp%d: type AT-GPIB chip NAT4882B\n", sc->sc_unit);
149 if (sc->sc_type == 1)
150 printf ("gp%d: type AT-GPIB chip NAT4882A\n", sc->sc_unit);
151 sc->sc_flags |= ATTACHED;
152 make_dev(&gp_cdevsw, 0, 0, 0, 0600, "gp");
153 return (1);
154 }
155
156 /*
157 * gpopen()
158 * New open on device.
159 *
160 * More than 1 open is not allowed on the entire device.
161 * i.e. even if gpib5 is open, we can't open another minor device
162 */
163 static int
164 gpopen(dev, flags, fmt, td)
165 dev_t dev;
166 int flags;
167 int fmt;
168 struct thread *td;
169 {
170 struct gpib_softc *sc = &gpib_sc;
171 u_char unit;
172 int status;
173
174 unit = minor(dev);
175
176 /* minor number out of limits ? */
177 if (unit >= 32)
178 return (ENXIO);
179
180 /* Attached ? */
181 if (!(sc->sc_flags&ATTACHED)) /* not attached */
182 return (ENXIO);
183
184 /* Already open */
185 if (sc->sc_flags&OPEN) /* too late .. */
186 return (EBUSY);
187
188 /* Have memory for buffer? */
189 sc->sc_inbuf = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
190 if (sc->sc_inbuf == 0)
191 return (ENOMEM);
192
193 if (initgpib()) return (EBUSY);
194 sc->sc_flags |= OPEN;
195 sc->sc_count = 0;
196 oldcount = 0;
197 if (unit != 0) { /* Someone is trying to access an actual device */
198 /* So.. we'll address it to listen */
199 enableremote(unit);
200 do {
201 status = inb(ISR2);
202 } while (!(status & 8) && tsleep((caddr_t)&gpib_sc, GPIBPRI,
203 "gpibpoll", 1) == EWOULDBLOCK);
204
205 outb(CDOR, (unit & 31) + 32); /* address device to listen */
206
207 do
208 status = inb(ISR2);
209 while (!(status & 8) && tsleep((caddr_t)&gpib_sc, GPIBPRI,
210 "gpibpoll", 1) == EWOULDBLOCK);
211 outb(CDOR, 64); /* Address controller (me) to talk */
212 do {
213 status = inb(ISR2);
214 } while (!(status & 8) && tsleep((caddr_t)&gpib_sc, GPIBPRI,
215 "gpibpoll", 1) == EWOULDBLOCK);
216 outb(AUXMR, gts); /* Set to Standby (Controller) */
217
218
219 do {
220 status = inb(ISR1);
221 } while (!(status & 2) && tsleep((caddr_t)&gpib_sc, GPIBPRI,
222 "gpibpoll", 1) == EWOULDBLOCK);
223
224 /* Set up the TURBO488 registers */
225 outb(IMR2, 0x30); /* we have to enable DMA (0x30) for turbo488 to work */
226 outb(CNT0, 0); /* NOTE this does not enable DMA to the host computer!! */
227 outb(CNT1, 0);
228 outb(CNT2, 0);
229 outb(CNT3, 0);
230 outb(CMDR, 0x20);
231 outb(CFG, 0x47); /* 16 bit, write, fifo B first, TMOE TIM */
232 outb(CMDR, 0x10); /* RESET fifos */
233 outb(CMDR, 0x04); /* Tell TURBO488 to GO */
234 }
235 return (0);
236 }
237
238
239 /*
240 * gpclose()
241 * Close gpib device.
242 */
243 static int
244 gpclose(dev, flags, fmt, td)
245 dev_t dev;
246 int flags;
247 int fmt;
248 struct thread *td;
249 {
250 struct gpib_softc *sc = &gpib_sc;
251 unsigned char unit;
252 unsigned char status;
253
254 unit = minor(dev);
255 if (unit != 0) { /* Here we need to send the last character with EOS */
256 /* and unaddress the listening device */
257
258 status = EWOULDBLOCK;
259
260 /* Wait for fifo to become empty */
261 do {
262 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
263 } while ((inb(ISR3) & 0x04) && status == EWOULDBLOCK); /* Fifo is not empty */
264
265 outb(CMDR, 0x08); /* Issue STOP to TURBO488 */
266
267 /* Wait for DONE and STOP */
268 if (status == EWOULDBLOCK) do {
269 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
270 } while (!(inb(ISR3) & 0x11) && status == EWOULDBLOCK); /* not done and stop */
271
272 /* Shut down TURBO488 */
273 outb(IMR2, 0x00); /* DISABLE DMA to turbo488 */
274 outb(CMDR, 0x20); /* soft reset turbo488 */
275 outb(CMDR, 0x10); /* reset fifos */
276
277 /* Send last byte with EOI set */
278 /* Send second to last byte if there are 2 bytes left */
279 if (status == EWOULDBLOCK) {
280 do {
281 if (!(inb(ISR1) & 2)) status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
282 } while (!(inb(ISR1) & 2) && (status == EWOULDBLOCK));
283 if (oldcount == 2) {
284 outb(CDOR, oldbytes[0]); /* Send second to last byte */
285 while (!(inb(ISR1) & 2) && (status == EWOULDBLOCK));
286 status = tsleep((caddr_t)&gpib_sc, GPIBPRI,
287 "gpibpoll", 1);
288 }
289
290 outb(AUXMR, seoi); /* Set EOI for the last byte */
291 outb(AUXMR, 0x5E); /* Clear SYNC */
292 if (oldcount == 1)
293 outb(CDOR, oldbytes[0]);
294 else
295 if (oldcount == 2)
296 outb(CDOR, oldbytes[1]);
297 else {
298 outb(CDOR, 13); /* Send a CR.. we've got trouble */
299 printf("gpib: Warning: gpclose called with nothing left in buffer\n");
300 }
301 }
302
303 do {
304 if (!(inb(ISR1) & 2)) status = tsleep((caddr_t)&gpib_sc,
305 GPIBPRI, "gpibpoll", 1);
306 } while (!(inb(ISR1) & 2) && (status == EWOULDBLOCK));
307
308 if (!(inb(ISR1) & 2) && status == EWOULDBLOCK) do {
309 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
310 } while (!(inb(ISR1) & 2) && status == EWOULDBLOCK);
311
312 outb(AUXMR, tca); /* Regain full control of the bus */
313
314 do {
315 status = inb(ISR2);
316 } while (!(status & 8) && tsleep((caddr_t)&gpib_sc, GPIBPRI,
317 "gpibpoll", 1) == EWOULDBLOCK);
318 outb(CDOR, 63); /* unlisten */
319 do {
320 status = inb(ISR2);
321 } while (!(status & 8) && tsleep((caddr_t)&gpib_sc, GPIBPRI,
322 "gpibpoll", 1) == EWOULDBLOCK);
323 outb(AUXMR, 0x5E); /* Clear SYNC */
324 outb(CDOR, 95); /* untalk */
325 do {
326 status = inb(ISR2);
327 } while (!(status & 8) && tsleep((caddr_t)&gpib_sc, GPIBPRI,
328 "gpibpoll", 1) == EWOULDBLOCK);
329 #if 0
330 gotolocal(minor(dev));
331 #endif
332 }
333 closegpib();
334 sc->sc_flags = ATTACHED;
335 free(sc->sc_inbuf, M_DEVBUF);
336 sc->sc_inbuf = 0; /* Sanity */
337 return (0);
338 }
339
340 /*
341 * gpwrite()
342 * Copy from user's buffer, then write to GPIB device referenced
343 * by minor(dev).
344 */
345 static int
346 gpwrite(dev, uio, ioflag)
347 dev_t dev;
348 struct uio *uio;
349 int ioflag;
350 {
351 int err, count;
352
353 /* main loop */
354 while ((gpib_sc.sc_count = MIN(BUFSIZE-1, uio->uio_resid)) > 0) {
355 /* If there were >1 bytes left over, send them */
356 if (oldcount == 2)
357 sendrawgpibfifo(minor(dev), oldbytes, 2);
358
359 /* If there was 1 character left, put it at the beginning
360 of the new buffer */
361 if (oldcount == 1) {
362 (gpib_sc.sc_inbuf)[0] = oldbytes[0];
363 gpib_sc.sc_cp = gpib_sc.sc_inbuf;
364 /* get from user-space */
365 uiomove(gpib_sc.sc_inbuf + 1, gpib_sc.sc_count, uio);
366 gpib_sc.sc_count++;
367 } else {
368 gpib_sc.sc_cp = gpib_sc.sc_inbuf;
369 /* get from user-space */
370 uiomove(gpib_sc.sc_inbuf, gpib_sc.sc_count, uio);
371 }
372
373 /*
374 * NOTE we always leave one byte in case this is the last write
375 * so close can send EOI with the last byte There may be 2 bytes
376 * since we are doing 16 bit transfers.(note the -1 in the count below)
377 */
378
379 /* If count <= 2 we'll either pick it up on the next write or on close */
380 if (gpib_sc.sc_count>2) {
381 count = sendrawgpibfifo(minor(dev), gpib_sc.sc_cp, gpib_sc.sc_count-1);
382 err = !count;
383 if (err)
384 return (1);
385 oldcount = gpib_sc.sc_count-count; /* Set # of remaining bytes */
386 gpib_sc.sc_count -= count;
387 gpib_sc.sc_cp += count; /* point char pointer to remaining bytes */
388 }
389 else
390 oldcount = gpib_sc.sc_count;
391 oldbytes[0] = gpib_sc.sc_cp[0];
392 if (oldcount == 2)
393 oldbytes[1] = gpib_sc.sc_cp[1];
394 }
395 return (0);
396 }
397
398 /*
399 * Here is how you would usually access a GPIB device
400 * An exception would be a plotter or printer that you can just
401 * write to using a minor device = its GPIB address
402 */
403
404 static int
405 gpioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
406 {
407 struct gpibdata *gd = (struct gpibdata *)data;
408 int error, result;
409 error = 0;
410
411 switch (cmd) {
412 case GPIBWRITE:
413 sendgpibfifo(gd->address, gd->data, *(gd->count));
414 error = 0;
415 break;
416 case GPIBREAD:
417 result = readgpibfifo(gd->address, gd->data, *(gd->count));
418 *(gd->count) = result;
419 error = 0;
420 break;
421 case GPIBINIT:
422 initgpib();
423 error = 0;
424 break;
425 case GPIBTRIGGER:
426 trigger(gd->address);
427 error = 0;
428 break;
429 case GPIBREMOTE:
430 enableremote(gd->address);
431 error = 0;
432 break;
433 case GPIBLOCAL:
434 gotolocal(gd->address);
435 error = 0;
436 break;
437 case GPIBMTRIGGER:
438 mtrigger(gd->data);
439 error = 0;
440 break;
441 case GPIBMREMOTE:
442 menableremote(gd->data);
443 error = 0;
444 break;
445 case GPIBMLOCAL:
446 mgotolocal(gd->data);
447 error = 0;
448 break;
449 case GPIBSPOLL:
450 *(gd->data) = spoll(gd->address);
451 error = 0;
452 break;
453 default:
454 error = ENODEV;
455 }
456
457 return (error);
458 }
459
460 #if 0
461 /* Just in case you want a dump of the registers... */
462
463 static void showregs() {
464 printf ("NAT4882:\n");
465 printf ("ISR1=%X\t", inb(ISR1));
466 printf ("ISR2=%X\t", inb(ISR2));
467 printf ("SPSR=%X\t", inb(SPSR));
468 printf ("KSR =%X\t", inb(KSR));
469 printf ("ADSR=%X\t", inb(ADSR));
470 printf ("CPTR=%X\t", inb(CPTR));
471 printf ("SASR=%X\t", inb(SASR));
472 printf ("ADR0=%X\t", inb(ADR0));
473 printf ("ISR0=%X\t", inb(ISR0));
474 printf ("ADR1=%X\t", inb(ADR1));
475 printf ("BSR =%X\n", inb(BSR));
476
477 printf ("Turbo488\n");
478 printf ("STS1=%X ", inb(STS1));
479 printf ("STS2=%X ", inb(STS2));
480 printf ("ISR3=%X ", inb(ISR3));
481 printf ("CNT0=%X ", inb(CNT0));
482 printf ("CNT1=%X ", inb(CNT1));
483 printf ("CNT2=%X ", inb(CNT2));
484 printf ("CNT3=%X ", inb(CNT3));
485 printf ("IMR3=%X ", inb(IMR3));
486 printf ("TIMER=%X\n", inb(TIMER));
487 }
488 #endif
489
490 /*
491 * Set up the NAT4882 and TURBO488 registers
492 * This will be nonsense to you unless you have a data sheet from
493 * National Instruments. They should give you one if you call them
494 */
495
496 static int
497 initgpib()
498 {
499 outb(CMDR, 0x20);
500 outb(CFG, 0x16);
501 outb(IMR3, 0);
502 outb(CMDR, 0x10);
503 outb(CNT0, 0);
504 outb(CNT1, 0);
505 outb(CNT2, 0);
506 outb(CNT3, 0);
507 outb(INTR, 0); /* Put interrupt line in tri-state mode?? */
508 outb(AUXMR, chip_reset);
509
510 outb(IMR1, 0x10); /* send interrupt to TURBO488 when END received */
511 outb(IMR2, 0);
512 outb(IMR0, 0x90); /* Do we want nba here too??? */
513 outb(ADMR, 1);
514 outb(ADR, 0);
515 outb(ADR, 128);
516 outb(AUXMR, 0xE9);
517 outb(AUXMR, 0x49);
518 outb(AUXMR, 0x70);
519 outb(AUXMR, 0xD0);
520 outb(AUXMR, 0xA0);
521
522 outb(EOSR, 10); /* set EOS message to newline */
523 /* should I make the default to interpret END as EOS? */
524 /* It isn't now. The following changes this */
525 outb(AUXMR, 0x80); /* No special EOS handling */
526 #if 0
527 outb(AUXMR, 0x88) /* Transmit END with EOS */
528 outb(AUXMR, 0x84) /* Set END on EOS received */
529 outb(AUXMR, 0x8C) /* Do both of the above */
530 #endif
531
532 #if 0
533 /* Not currently supported */
534 outb(AUXMR, hldi); /* Perform RFD Holdoff for all data in */
535 #endif
536
537 outb(AUXMR, pon);
538 outb(AUXMR, sic_rsc);
539 tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
540
541 outb(AUXMR, sic_rsc_off);
542
543 return (0);
544 }
545
546 /* This is kind of Brute force.. But it works */
547
548 static void
549 closegpib()
550 {
551 outb(AUXMR, chip_reset);
552 }
553
554 /*
555 * GPIB ROUTINES:
556 * These will also make little sense unless you have a data sheet.
557 * Note that the routines with an "m" in the beginning are for
558 * accessing multiple devices in one call
559 */
560
561 /*
562 * This is one thing I could not figure out how to do correctly.
563 * I tried to use the auxilary command to enable remote, but it
564 * never worked. Here, I bypass everything and write to the BSR
565 * to enable the remote line. NOTE that these lines are effectively
566 * "OR'ed" with the actual lines, so writing a 1 to the bit in the BSR
567 * forces the GPIB line true, no matter what the fancy circuitry of the
568 * NAT4882 wants to do with it
569 */
570
571 static void
572 enableremote(unsigned char device)
573 {
574 int status;
575
576 status = EWOULDBLOCK;
577 if (status == EWOULDBLOCK) do {
578 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
579 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
580
581 outb(BSR, 1); /* Set REN bit on GPIB */
582 if (status == EWOULDBLOCK) do {
583 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
584 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
585 outb(CDOR, (device & 31) + 32); /* address device to listen */
586 if (status == EWOULDBLOCK) do {
587 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
588 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
589 outb(CDOR, 63); /* Unaddress device */
590 if (status == EWOULDBLOCK) do {
591 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
592 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
593
594 }
595
596 /*
597 * This does not release the REM line on the gpib port, because if it did,
598 * all the remote devices would go to local mode. This only sends the
599 * gotolocal message to one device. Currently, REM is always held true
600 * after enableremote is called, and is reset only on a close of the
601 * gpib device
602 */
603
604 static void
605 gotolocal(unsigned char device)
606 {
607 int status;
608
609 status = EWOULDBLOCK;
610 if (status == EWOULDBLOCK) do {
611 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
612 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
613
614 outb(CDOR, (device & 31) + 32);
615
616 if (status == EWOULDBLOCK) do {
617 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
618 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
619
620 outb(AUXMR, 0x5E); /* Clear SYNC */
621 outb(CDOR, 1);
622
623 if (status == EWOULDBLOCK) do {
624 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
625 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
626
627 outb(AUXMR, 0x5E);
628 outb(CDOR, 63); /* unaddress device */
629
630 if (status == EWOULDBLOCK) do {
631 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
632 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
633 }
634
635 static void
636 menableremote(unsigned char *device)
637 {
638 int status, counter = 0;
639
640 status = EWOULDBLOCK;
641 if (status == EWOULDBLOCK) do {
642 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
643 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
644
645 outb(BSR, 1); /* Set REN bit on GPIB */
646 do {
647 if (status == EWOULDBLOCK) do {
648 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
649 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
650 outb(CDOR, (device[counter] & 31) + 32); /* address device to listen */
651 counter++;
652 } while (device[counter] < 32);
653
654 if (status == EWOULDBLOCK) do {
655 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
656 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
657
658 outb(CDOR, 63); /* Unaddress device */
659 if (status == EWOULDBLOCK) do {
660 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
661 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
662
663 }
664
665 static void
666 mgotolocal(unsigned char *device)
667 {
668 int status;
669 int counter = 0;
670
671 status = EWOULDBLOCK;
672 if (device[counter] < 32) do {
673 if (status == EWOULDBLOCK) do {
674 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
675 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
676 outb(CDOR, (device[counter] & 31) + 32);
677 counter++;
678 } while (device[counter] < 32);
679 if (status == EWOULDBLOCK) do {
680 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
681 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
682
683 outb(AUXMR, 0x5E); /* Clear SYNC */
684 outb(CDOR, 1);
685
686 if (status == EWOULDBLOCK) do {
687 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
688 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
689 outb(AUXMR, 0x5E);
690 outb(CDOR, 63); /* unaddress device */
691 if (status == EWOULDBLOCK) do {
692 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 2);
693 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
694 }
695
696 /* Trigger a device. What happens depends on how the device is configured. */
697
698 static void
699 trigger(unsigned char device)
700 {
701 int status;
702
703 status = EWOULDBLOCK;
704 if (device < 32) {
705 if (!(inb(ISR2) & 0x08)) do {
706 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
707 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
708 outb(CDOR, (device & 31) + 32); /* address device to listen */
709 if (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK) do {
710 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
711 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
712
713 outb(CDOR, 8); /* send GET */
714
715 if (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK) do {
716 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
717 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
718 outb(AUXMR, 0x5E);
719 outb(CDOR, 63); /* unaddress device */
720 if (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK) do {
721 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
722 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
723 }
724 }
725
726 /*
727 * Trigger multiple devices by addressing them all to listen, and then
728 * sending GET
729 */
730
731 static void
732 mtrigger(unsigned char *device)
733 {
734 int status = EWOULDBLOCK;
735 int counter = 0;
736 if (device[0] < 32) {
737 do {
738 if (device[counter] < 32)
739 if (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK) do {
740 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
741 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
742 outb(CDOR, (device[counter] & 31) + 32); /* address device to listen */
743 counter++;
744 } while (device[counter] < 32);
745 if (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK) do {
746 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
747 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
748 outb(CDOR, 8); /* send GET */
749
750 if (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK) do {
751 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
752 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
753 outb(AUXMR, 0x5E);
754 outb(CDOR, 63); /* unaddress device */
755 if (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK) do {
756 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
757 } while (!(inb(ISR2) & 0x08) && status == EWOULDBLOCK); /* Wait to send next cmd */
758 }
759 }
760
761 /*
762 * This is not used now, but it should work with NI's 8 bit gpib board
763 * since it does not use the TURBO488 registers at all
764 */
765
766 /*
767 * Send data through the TURBO488 FIFOS to a device that is already
768 * addressed to listen. This is used by the write call when someone is
769 * writing to a printer or plotter, etc...
770 *
771 * The last byte of each write is held off until either the next
772 * write or close, so it can be sent with EOI set
773 */
774
775 static int
776 sendrawgpibfifo(unsigned char device, char *data, int count)
777 {
778 int status;
779 int counter;
780 int fifopos;
781 int sleeptime;
782
783 sleeptime = SLEEP_MIN;
784 counter = 0;
785
786 fifopos = 0;
787
788 status = EWOULDBLOCK;
789 do {
790 /* Wait for fifo to become not full if it is full */
791 sleeptime = SLEEP_MIN;
792 if (!(inb(ISR3) & 0x08)) do {
793 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", sleeptime);
794 if (sleeptime < SLEEP_MAX) sleeptime = sleeptime * 2;
795 } while (!(inb(ISR3) & 0x08) && (status == EWOULDBLOCK)); /* Fifo is full */
796
797 if ((count>1) && (inb(ISR3) & 0x08)) {
798 outw(FIFOB, *(unsigned *)(data + counter));
799 #if 0
800 printf ("gpib: sent:%c, %c\n", data[counter], data[counter + 1]);
801 #endif
802 counter += 2;
803 count -= 2;
804 }
805 }
806 while ((count>1) && (status == EWOULDBLOCK));
807
808 /*
809 * The write routine and close routine must check if there is 1
810 * byte left and handle it accordingly
811 */
812
813 /* Return the number of bytes written to the device */
814 return (counter);
815 }
816
817 static int
818 sendgpibfifo(unsigned char device, char *data, int count)
819 {
820 int status;
821 int counter;
822 int fifopos;
823 int sleeptime;
824
825 outb(IMR2, 0x30); /* we have to enable DMA (0x30) for turbo488 to work */
826 outb(CNT0, 0);
827 outb(CNT1, 0);
828 outb(CNT2, 0);
829 outb(CNT3, 0);
830 status = EWOULDBLOCK;
831 if (!(inb(ISR2) & 8)) do {
832 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
833 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
834
835 outb(CDOR, (device & 31) + 32); /* address device to listen */
836
837 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
838 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
839 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
840 outb(CDOR, 64); /* Address controller (me) to talk */
841
842 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
843 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
844 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
845
846 outb(AUXMR, gts); /* Set to Standby (Controller) */
847 fifopos = 0;
848
849 sleeptime = SLEEP_MIN;
850 counter = 0;
851
852 fifopos = 0;
853
854 outb(CMDR, 0x20);
855 outb(CFG, 0x47); /* 16 bit, write, fifo B first, TMOE TIM */
856 outb(CMDR, 0x10); /* RESET fifos */
857 outb(CCRG, seoi); /* program to send EOI at end */
858 outb(CMDR, 0x04); /* Tell TURBO488 to GO */
859 status = EWOULDBLOCK;
860 do {
861 /* Wait for fifo to become not full if it is full */
862 sleeptime = SLEEP_MIN;
863 if (!(inb(ISR3) & 0x08)) do {
864 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", sleeptime);
865 if (sleeptime < SLEEP_MAX) sleeptime = sleeptime * 2;
866 } while (!(inb(ISR3) & 0x08) && (status == EWOULDBLOCK)); /* Fifo is full */
867
868 if ((count>1) && (inb(ISR3) & 0x08)) {
869 #if 0
870 if (count == 2) outb(CFG, 15 + 0x40); /* send eoi when done */
871 #endif
872 outw(FIFOB, *(unsigned *)(data + counter));
873
874 counter += 2;
875 count -= 2;
876 }
877 } while ((count>2) && (status == EWOULDBLOCK));
878
879 if (count == 2 && status == EWOULDBLOCK) {
880 /* Wait for fifo to become not full */
881 if (status == EWOULDBLOCK && !(inb(ISR3) & 0x08)) do {
882 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", SLEEP_MIN);
883 } while (!(inb(ISR3) & 0x08) && status == EWOULDBLOCK); /* Fifo is full */
884 #if 0
885 outb(CFG, 0x40 + 15); /* send eoi when done */
886 #endif
887 outb(FIFOB, data[counter]);
888 counter++;
889 count--;
890 }
891
892 #if 0
893 outb(CMDR, 0x04);
894 #endif
895
896 /* Wait for fifo to become empty */
897 if (status == EWOULDBLOCK) do {
898 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
899 } while ((inb(ISR3) & 0x04) && status == EWOULDBLOCK); /* Fifo is not empty */
900
901 outb(CMDR, 0x08); /* Issue STOP to TURBO488 */
902
903 /* Wait for DONE and STOP */
904 if (status == EWOULDBLOCK) do {
905 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
906 } while (!(inb(ISR3) & 0x11) && status == EWOULDBLOCK); /* not done and stop */
907
908 outb(IMR2, 0x00); /* we have to enable DMA (0x30) for turbo488 to work */
909 outb(CMDR, 0x20); /* soft reset turbo488 */
910 outb(CMDR, 0x10); /* reset fifos */
911
912
913 /*
914 * Send last byte with EOI set
915 * Here EOI is handled correctly since the string to be sent
916 * is actually all sent during the ioctl. (See above)
917 */
918 if (count == 1 && status == EWOULDBLOCK) { /* Count should always=1 here */
919
920 do {
921 if (!(inb(ISR1) & 2)) status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
922 } while (!(inb(ISR1) & 2) && (status == EWOULDBLOCK));
923
924 outb(AUXMR, seoi); /* Set EOI for the last byte */
925 outb(AUXMR, 0x5E); /* Clear SYNC */
926 outb(CDOR, data[counter]);
927 counter++;
928 count--;
929 }
930
931 do {
932 if (!(inb(ISR1) & 2)) status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
933 } while (!(inb(ISR1) & 2) && (status == EWOULDBLOCK));
934
935
936 if (!(inb(ISR1) & 2) && status == EWOULDBLOCK) do {
937 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
938 } while (!(inb(ISR1) & 2) && status == EWOULDBLOCK);
939 outb(AUXMR, tca); /* Regain full control of the bus */
940
941 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
942 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
943 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
944
945 outb(CDOR, 63); /* unlisten */
946
947 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
948 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
949 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
950
951
952 outb(AUXMR, 0x5E); /* Clear SYNC */
953 outb(CDOR, 95); /* untalk */
954 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
955 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
956 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
957
958 return (counter);
959 }
960
961 static int
962 readgpibfifo(unsigned char device, char *data, int count)
963 {
964 int status;
965 int status2 = 0;
966 int status1;
967 int counter;
968 int fifopos;
969 unsigned inword;
970
971 outb(IMR2, 0x30); /* we have to enable DMA (0x30) for turbo488 to work */
972 #if 0
973 outb(IMR3, 0x1F);
974 outb(INTR, 1);
975 #endif
976 outb(CMDR, 0x20);
977
978 outb(CFG, 14 + 0x60 + 1); /* Halt on int, read, fifo B first, CCEN TMOE TIM */
979 outb(CMDR, 0x10); /* RESET fifos */
980 outb(CCRG, tcs); /* program to tcs at end */
981 outb(CMDR, 0x08); /* STOP?? */
982
983 status = EWOULDBLOCK;
984 do {
985 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
986 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
987
988 outb(CDOR, 32); /* Address controller (me) to listen */
989
990 do {
991 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
992 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
993
994 outb(CDOR, (device & 31) + 64); /* address device to talk */
995
996 do {
997 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
998 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
999
1000 outb(AUXMR, gts); /* Set to Standby (Controller) */
1001
1002 counter = 0;
1003 fifopos = 0;
1004
1005 outb(CMDR, 0x04); /* Tell TURBO488 to GO */
1006
1007 do {
1008 status1 = inb(ISR3);
1009 if (!(status1 & 0x01) && (status1 & 0x04)) {
1010 status2 = inb(STS2);
1011 inword = inw(FIFOB);
1012 *(unsigned *)(data + counter) = inword;
1013 #if 0
1014 printf ("Read:%c, %c\n", data[counter], data[counter + 1]);
1015 #endif
1016 counter += 2;
1017 } else {
1018 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 4);
1019 }
1020 } while (!(status1 & 0x01) && status == EWOULDBLOCK);
1021 if (!(status2 & 0x04)) { /* Only 1 byte came in on last 16 bit transfer */
1022 data[counter-1] = 0;
1023 counter--;
1024 } else
1025 data[counter] = 0;
1026 outb(CMDR, 0x08); /* send STOP */
1027
1028 do {
1029 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1030 } while (!(inb(ISR3) & 0x11) && status == EWOULDBLOCK); /* wait for DONE and STOP */
1031 outb(AUXMR, 0x55);
1032
1033 outb(IMR2, 0x00); /* we have to enable DMA (0x30) for turbo488 to work */
1034 outb(CMDR, 0x20); /* soft reset turbo488 */
1035 outb(CMDR, 0x10); /* reset fifos */
1036
1037 #if 0
1038 do {
1039 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1040 } while (!(inb(ISR1) & 2));
1041 #endif
1042 outb(AUXMR, tca); /* Regain full control of the bus */
1043
1044 do {
1045 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1046 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1047 outb(CDOR, 63); /* unlisten */
1048
1049 do {
1050 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1051 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1052
1053 outb(AUXMR, 0x5E); /* Clear SYNC */
1054 outb(CDOR, 95); /* untalk */
1055 do {
1056 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1057 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1058
1059 return (counter);
1060 }
1061
1062
1063 /* Return the status byte from device */
1064 static char
1065 spoll(unsigned char device)
1066 {
1067 int status = EWOULDBLOCK;
1068 unsigned int statusbyte;
1069
1070 if (!(inb(ISR2) & 8)) do {
1071 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1072 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1073
1074 outb(CDOR, (device & 31) + 64); /* address device to talk */
1075
1076 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
1077 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1078 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1079
1080 outb(CDOR, 32); /* Address controller (me) to listen */
1081
1082 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
1083 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1084 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1085 outb(AUXMR, 0x5E);
1086 outb(CDOR, 0x18); /* Send SPE (serial poll enable) */
1087 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
1088 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1089 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1090
1091 /* wait for bus to be synced */
1092 if (!(inb(ISR0) & 1) && status == EWOULDBLOCK) do {
1093 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1094 } while (!(inb(ISR0) & 1) && status == EWOULDBLOCK);
1095
1096 outb(AUXMR, gts); /* Set to Standby (Controller) */
1097
1098 if (!(inb(ISR1) & 1) && status == EWOULDBLOCK) do {
1099 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1100 } while (!(inb(ISR1) & 1) && status == EWOULDBLOCK);
1101 outb(AUXMR, 0x5E);
1102 outb(AUXMR, tcs); /* Take control after next read */
1103 statusbyte = inb(DIR);
1104
1105 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
1106 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1107 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1108
1109 outb(CDOR, 0x19); /* SPD (serial poll disable) */
1110
1111 /* wait for bus to be synced */
1112 if (!(inb(ISR0) & 1) && status == EWOULDBLOCK) do {
1113 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1114 } while (!(inb(ISR0) & 1) && status == EWOULDBLOCK);
1115
1116
1117 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
1118 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1119 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1120
1121 outb(CDOR, 95); /* untalk */
1122
1123 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
1124 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1125 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1126 outb(AUXMR, 0x5E);
1127 outb(CDOR, 63); /* unlisten */
1128 if (!(inb(ISR2) & 8) && status == EWOULDBLOCK) do {
1129 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1130 } while (!(inb(ISR2) & 8) && status == EWOULDBLOCK);
1131
1132 /* wait for bus to be synced */
1133 if (!(inb(ISR0) & 1) && status == EWOULDBLOCK) do {
1134 status = tsleep((caddr_t)&gpib_sc, GPIBPRI, "gpibpoll", 1);
1135 } while (!(inb(ISR0) & 1) && status == EWOULDBLOCK);
1136
1137 return (statusbyte);
1138 }
Cache object: 55e486e3312e81e1b1d9e73d51fe2df3
|