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