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 if (ioperm(lpt_base, 4, 1) != 0) {
88 fprintf(stderr,"Nejsou prava na port - musis byt root: %m\n");
92 /* set realtime priority and lock us in memory */
93 struct sched_param scp;
94 memset(&scp, 0, sizeof(scp));
95 scp.sched_priority = sched_get_priority_max(SCHED_RR);
96 sched_setscheduler(0, SCHED_RR, &scp);
102 * this way everything waits for us
103 * otherwise we act like we are not there
105 put_control(TRI | NDAC | NRFD );
107 signal(SIGINT, sig_handler);
110 char lptgpib_read_byte(char *_flags){
111 DBG_low("READ: "); /* previous state: TRI | NDAC | NRFD */
112 put_control(TRI | NDAC); /* clear NRFD */
113 BUSYWAIT( !(get_control() & DAV) ) /* wait for DAV */
116 char value = get_data(); /* read data */
117 char flags = get_control();
118 put_control(TRI | NRFD ); /* clear NDAC and set NRFD back */
119 BUSYWAIT( get_control() & DAV )/* wait for end of DAV */
122 put_control(TRI | NDAC | NRFD ); /* back to default state */
124 flags = (flags & ATN) | (value & EOI);
125 value = value & (~EOI);
127 DBG_low( isprint(value) ? "'%c' %s %s\n" : "'\\x%02hx' %s %s\n",
129 flags & EOI ? "EOI" : "",
130 flags & ATN ? "ATN" : "");
133 lptgpib_print_command(value);
140 void lptgpib_write_byte(char value, char flags){
142 put_control( TRI | (flags & ATN) ); /* clear NRFD and NDAC,
143 possibly enable ATN */
144 int tmp; /* wait for all to be ready */
146 BUSYWAIT(( tmp = get_control(), !(tmp & NDAC) || (tmp & NRFD) ))
148 DBG_low("rfd+ndac, ");
149 put_data(value & ~(flags & EOI) ); /* put data */
150 put_control( (flags & ATN) ); /* clear TRI */
151 put_control( DAV | (flags & ATN) ); /* set DAV*/
153 BUSYWAIT( get_control() & NDAC ) /* wait for all to accept */
155 put_control(TRI | NDAC | NRFD ); /* back to default state */
157 DBG_low( isprint(value) ? "'%c' %s %s\n" : "'\\x%02hx' %s %s\n",
159 flags & EOI ? "EOI" : "",
160 flags & ATN ? "ATN" : "");
163 int lptgpib_read_data(char *dest, int size){
164 if ( !dest || ! (size>0) ) return 0;
168 dest[pos++] = lptgpib_read_byte(&flags);
169 if (flags & ATN){ /* command instead of data */
170 DBG("READ: '%.*s' interrupted by ATN\n", pos, dest);
173 if ( (pos >= size) ||
175 (dest[pos-1] == EOS)){ /* overflow, EOI or EOS */
176 DBG("READ: '%.*s'\n", pos, dest);
182 void lptgpib_command(char value){
183 lptgpib_write_byte(value, ATN);
185 lptgpib_print_command(value);
189 void lptgpib_write_data(char *src, int size){
192 for (i=0; i<size; i++)
193 lptgpib_write_byte(src[i], (i+1 == size) ? EOI : 0);
194 /* lptgpib_write_byte(src[i], 0);
195 lptgpib_write_byte(0x0a, EOI); */
196 DBG("WRITE: '%.*s'\n", size, src);
199 int lptgpib_read(int address, char *dest, int size){
200 if (address > 30 || address < 0 || !dest)
203 lptgpib_command(UNL);
204 lptgpib_command(MLA+0);
205 lptgpib_command(MTA+address);
206 return lptgpib_read_data(dest, size);
209 void lptgpib_write(int address, char *src){
210 if (address > 30 || address < 0)
212 lptgpib_command(MTA+0);
213 lptgpib_command(UNL);
214 lptgpib_command(MLA+address);
215 lptgpib_write_data(src, strlen(src));