14 #define DEBUG 3 /* 4 - all, 3 - data, */
17 #define DBG_low(...) { fprintf(stderr,__VA_ARGS__); fflush(stderr); }
23 #define DBG(...) { fprintf(stderr,__VA_ARGS__); fflush(stderr); }
30 * GPIB uses negative logic,
31 * LPT control lines (except 0x04) are inverted in hw,
33 #define get_data() (~inb(lpt_base))
34 #define put_data(x) outb(~(x), lpt_base)
35 #define get_control() (inb(lpt_base+2) ^ 0x04)
36 #define put_control(x) outb((x) ^ 0x04, lpt_base+2)
37 #define TRI 0x20 /* tristate data lines */
38 #define IRQ 0x10 /* enable irq */
40 /* these depend on wiring */
41 #define EOI 0x80 /* LPT 8th data bit */
42 #define DAV 0x01 /* LPT pin 1 */
43 #define NRFD 0x02 /* LPT pin 14 */
44 #define NDAC 0x04 /* LPT pin 16 */
45 #define ATN 0x08 /* LPT pin 17 */
47 struct timespec sleeptime = {0, 10000}; /* 10 us*/
48 #define BUSYWAIT(cond) while(cond) nanosleep(&sleeptime, NULL);
50 struct {int val; char *desc; int len;} cmds[] = {
52 {SDC, "Selected device clear"},
53 {PPC, "Parallel poll configure"},
54 {GET, "Group execute trigger"},
55 {TCT, "Take control"},
56 {LLO, "Local lockout"},
57 {DCL, "Device clear"},
58 {PPU, "Parallel poll unconfigure"},
59 {SPE, "Serial poll enable"},
60 {SPD, "Serial poll disable"},
61 {MLA, "My primary listen address", 30},
63 {MTA, "My primary talk address", 30},
65 {MSA, "My secondary address", 30},
66 {PPE, "Parallel poll enable"},
67 {PPD, "Parallel poll disable"},
68 {0, "Unknown command"},
71 void lptgpib_print_command(unsigned char val){
73 while (cmds[i].val && !(cmds[i].val <= val &&
74 val <= cmds[i].val+cmds[i].len) ) i++;
75 char *desc = cmds[i].desc;
76 fprintf(stderr,"CMD: %02hx (%s)\n", val, desc);
79 void sig_handler(int sig){
85 void lptgpib_init(int base){
87 ioperm(lpt_base, 4, 1);
89 /* set realtime priority and lock us in memory */
90 struct sched_param scp;
91 memset(&scp, 0, sizeof(scp));
92 scp.sched_priority = sched_get_priority_max(SCHED_RR);
93 sched_setscheduler(0, SCHED_RR, &scp);
99 * this way everything waits for us
100 * otherwise we act like we are not there
102 put_control(TRI | NDAC | NRFD );
104 signal(SIGINT, sig_handler);
107 char lptgpib_read_byte(char *_flags){
108 DBG_low("READ: "); /* previous state: TRI | NDAC | NRFD */
109 put_control(TRI | NDAC); /* clear NRFD */
110 BUSYWAIT( !(get_control() & DAV) ) /* wait for DAV */
113 char value = get_data(); /* read data */
114 char flags = get_control();
115 put_control(TRI | NRFD ); /* clear NDAC and set NRFD back */
116 BUSYWAIT( get_control() & DAV )/* wait for end of DAV */
119 put_control(TRI | NDAC | NRFD ); /* back to default state */
121 flags = (flags & ATN) | (value & EOI);
122 value = value & (~EOI);
124 DBG_low( isprint(value) ? "'%c' %s %s\n" : "'\\x%02hx' %s %s\n",
126 flags & EOI ? "EOI" : "",
127 flags & ATN ? "ATN" : "");
130 lptgpib_print_command(value);
137 void lptgpib_write_byte(char value, char flags){
139 put_control( TRI | (flags & ATN) ); /* clear NRFD and NDAC,
140 possibly enable ATN */
141 int tmp; /* wait for all to be ready */
143 BUSYWAIT(( tmp = get_control(), !(tmp & NDAC) || (tmp & NRFD) ))
145 DBG_low("rfd+ndac, ");
146 put_data(value & ~(flags & EOI) ); /* put data */
147 put_control( (flags & ATN) ); /* clear TRI */
148 put_control( DAV | (flags & ATN) ); /* set DAV*/
150 BUSYWAIT( get_control() & NDAC ) /* wait for all to accept */
152 put_control(TRI | NDAC | NRFD ); /* back to default state */
154 DBG_low( isprint(value) ? "'%c' %s %s\n" : "'\\x%02hx' %s %s\n",
156 flags & EOI ? "EOI" : "",
157 flags & ATN ? "ATN" : "");
160 int lptgpib_read_data(char *dest, int size){
161 if ( !dest || ! (size>0) ) return 0;
165 dest[pos++] = lptgpib_read_byte(&flags);
166 if (flags & ATN){ /* command instead of data */
167 DBG("READ: '%.*s' interrupted by ATN\n", pos, dest);
170 if ( (pos >= size) ||
172 (dest[pos-1] == EOS)){ /* overflow, EOI or EOS */
173 DBG("READ: '%.*s'\n", pos, dest);
179 void lptgpib_command(char value){
180 lptgpib_write_byte(value, ATN);
182 lptgpib_print_command(value);
186 void lptgpib_write_data(char *src, int size){
189 for (i=0; i<size; i++)
190 lptgpib_write_byte(src[i], (i+1 == size) ? EOI : 0);
191 /* lptgpib_write_byte(src[i], 0);
192 lptgpib_write_byte(0x0a, EOI); */
193 DBG("WRITE: '%.*s'\n", size, src);
196 int lptgpib_read(int address, char *dest, int size){
197 if (address > 30 || address < 0 || !dest)
200 lptgpib_command(UNL);
201 lptgpib_command(MLA+0);
202 lptgpib_command(MTA+address);
203 return lptgpib_read_data(dest, size);
206 void lptgpib_write(int address, char *src){
207 if (address > 30 || address < 0)
209 lptgpib_command(MTA+0);
210 lptgpib_command(UNL);
211 lptgpib_command(MLA+address);
212 lptgpib_write_data(src, strlen(src));