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