view gpib.cc @ 0:6dfcd8e5b8df

first release
author Frank Kingswood <frank@kingswood-consulting.co.uk>
date Tue, 25 Mar 2014 20:31:00 +0000
parents
children a70e0a8ac73e
line wrap: on
line source
1 /* #------------------------------------------------------------------------#
2 | |
3 | gpib.cc |
4 | |
5 | USB-GPIB GPIB processing and state machine. |
6 | |
7 | Copyright 2014, Frank A. Kingswood, www.kingswood-consulting.co.uk |
8 | |
9 #------------------------------------------------------------------------# */
11 #include <avr/io.h>
12 #include <avr/pgmspace.h>
13 #include <stdint.h>
14 #include <ctype.h>
15 #include <util/delay.h>
16 #include "usb_serial.h"
17 #include "serial.h"
18 #include "gpib.h"
20 #define Debug USB
22 uint16_t GPIBDriver::MyAddress;
23 uint16_t GPIBDriver::DeviceAddress;
24 uint16_t GPIBDriver::Timeout;
25 bool GPIBDriver::MicroPro;
27 GPIBDriver::GPIBDriver()
28 {
29 Initialize();
30 }
32 void GPIBDriver::Initialize()
33 {
34 MyAddress=0;
35 DeviceAddress=1;
36 MicroPro=test_bit_clear(PIND,PORTD_TEENSY_N_ARDUINO);
37 Float();
38 }
40 // float data bus
41 void GPIBDriver::FloatData()
42 {
43 DDRB=0;
44 PORTB=0xff;
45 if(MicroPro)
46 { clear_bit(DDRE,6);
47 clear_bit(DDRC,6);
48 }
49 }
51 // float all pins
52 void GPIBDriver::Float()
53 {
54 // data lines all inputs
55 FloatData();
57 static const uint8_t used_c=(1<<PORTC_DIO8);
58 DDRC&=0xff^used_c;
59 PORTC=(PORTC&~used_c)|(0xff&used_c);
61 static const uint8_t used_e=(1<<PORTE_DIO1);
62 DDRE&=0xff^used_e;
63 PORTE=(PORTE&~used_e)|(0xff&used_e);
65 static const uint8_t used_d=(1<<PORTD_EOI) |
66 (1<<PORTD_NDAC) |
67 (1<<PORTD_NRFD) |
68 (1<<PORTD_SRQ) |
69 (1<<PORTD_TEENSY_N_ARDUINO) |
70 (1<<PORTD_DAV);
71 DDRD=0xff^used_d;
72 PORTD=(PORTD&~used_d)|(0xff&used_d);
74 // controls, used indicates bits that are used by us
75 static const uint8_t used_f=(1<<PORTF_ATN) | (1<<PORTF_IFC) | (1<<PORTF_REN) | (1<<PORTF_DIO8);
76 DDRF&=0xff^used_f;
77 PORTF=(PORTF&~used_f)|(0xff&used_f);
78 }
80 // drive LED
81 void GPIBDriver::LED(bool on)
82 {
83 if(MicroPro)
84 { if(on)
85 set_bit(PORTD,PORTD_LED_MP);
86 else
87 clear_bit(PORTD,PORTD_LED_MP);
88 }
89 else
90 { if(on)
91 set_bit(PORTD,PORTD_LED_T);
92 else
93 clear_bit(PORTD,PORTD_LED_T);
94 }
95 }
97 // Become controller in charge of the bus
98 //
99 // ++cic
100 // - float all pins
101 // - REN=0
103 void GPIBDriver::Controller()
104 {
105 Float();
107 // start driving ATN IFC and REN, pull up DIO8
108 PORTF |= (1<<PORTF_ATN) | (1<<PORTF_IFC) | (1<<PORTF_REN) | (1<<PORTF_DIO8);
109 DDRF |= (1<<PORTF_ATN) | (1<<PORTF_IFC) | (1<<PORTF_REN);
111 // pull /REN low to become actice controller
112 REN(true);
113 }
116 uint8_t GPIBDriver::Lines()
117 {
118 uint8_t pd=PIND & ((1<<PORTD_EOI) | (1<<PORTD_NRFD) | (1<<PORTD_NDAC) |
119 (1<<PORTD_SRQ) | (1<<PORTD_DAV));
120 uint8_t pf=PINF & ((1<<PORTF_ATN) | (1<<PORTF_IFC) | (1<<PORTF_REN));
122 return ~(pf | pd);
123 }
125 void GPIBDriver::Report(const char *msg)
126 {
127 if(msg)
128 {
129 Debug.Send(msg);
130 Debug.Send(':');
131 }
132 Debug.Send('<');
133 Debug.Hex(Data());
135 uint8_t lines=Lines();
136 if(lines & (1<<PORTD_EOI)) Debug.Send(ROMS(" EOI"));
137 if(lines & (1<<PORTF_ATN)) Debug.Send(ROMS(" ATN"));
138 if(lines & (1<<PORTD_SRQ)) Debug.Send(ROMS(" SRQ"));
139 if(lines & (1<<PORTF_REN)) Debug.Send(ROMS(" REN"));
140 if(lines & (1<<PORTF_IFC)) Debug.Send(ROMS(" IFC"));
141 if(lines & (1<<PORTD_NRFD)) Debug.Send(ROMS(" NRFD"));
142 if(lines & (1<<PORTD_NDAC)) Debug.Send(ROMS(" NDAC"));
143 if(lines & (1<<PORTD_DAV)) Debug.Send(ROMS(" DAV"));
145 Debug.Send('>');
146 if(msg)
147 Debug.Send();
148 }
150 static const uint32_t TIMEOUT=0x1ff000ULL; // 20 seconds
152 int16_t GPIBDriver::Command(const int16_t *command)
153 {
154 int8_t status=0;
155 while(int16_t word=pgm_read_word(*command++))
156 {
157 ATN(word&(1<<9));
158 EOI(word&(1<<8));
159 status=Out(word);
160 if(status)
161 break;
162 }
163 return -status;
164 }
166 void GPIBDriver::Data(uint8_t byte)
167 {
168 PORTB=~byte;
169 DDRB=SAFER ? byte : 0xff;
170 if(MicroPro)
171 {
172 clear_bit(DDRB,0)
173 ;
174 // pathetic board does not have an 8-bit port
175 if(byte&1)
176 { clear_bit(PORTE,6);
177 set_bit(DDRE,6);
178 }
179 else
180 { clear_bit(DDRE,6);
181 set_bit(PORTE,6);
182 }
184 if(byte&0x80)
185 { clear_bit(PORTC,6);
186 set_bit(DDRC,6);
187 }
188 else
189 { clear_bit(DDRC,6);
190 set_bit(PORTC,6);
191 }
192 }
193 }
195 uint8_t GPIBDriver::Out(uint8_t byte)
196 {
197 DAV(false);
199 if(!NRFD() && !NDAC())
200 { USB.Send("++error 1\r\n");
201 // disabled while debugging
202 // return -1;
203 }
205 // drive data
206 Data(byte);
208 // settling delay
209 _delay_us(2);
211 uint32_t timeout;
212 for(timeout=TIMEOUT; timeout!=0; timeout--)
213 {
214 _delay_us(10);
216 if(!NRFD())
217 break;
218 }
220 if(!timeout)
221 goto fail;
223 DAV(true);
225 for(timeout=TIMEOUT; timeout!=0; timeout--)
226 {
227 _delay_us(10);
229 if(!NDAC())
230 break;
231 }
233 if(!timeout)
234 goto fail;
236 DAV(false);
238 // float data bus
239 PORTB=0xff;
240 DDRB=0;
242 return 0;
244 fail:
245 DAV(false);
247 // float data bus
248 PORTB=0xff;
249 DDRB=0;
251 USB.Send(ROMS("++error 2\r\n"));
252 return -1;
253 }
255 /* .......................................................................... */
257 uint8_t GPIBDriver::Data()
258 {
259 uint8_t byte=~PINB;
260 if(MicroPro)
261 {
262 // pathetic board does not have an 8-bit port
263 byte &= 0x7e;
264 if(test_bit_clear(PINE,6))
265 byte |= 1;
266 if(test_bit_clear(PINE,6))
267 byte |= 0x80;
268 }
269 }
271 int16_t GPIBDriver::In()
272 {
273 NRFD(true);
274 NDAC(true);
276 // ready for data
277 NRFD(false);
279 uint8_t byte,atn,eoi;
280 uint32_t timeout;
281 for(timeout=TIMEOUT; timeout!=0; timeout--)
282 {
283 _delay_us(10);
285 if(DAV())
286 break;
287 }
289 if(!timeout)
290 goto fail;
292 NRFD(true);
294 byte=Data();
296 atn=ATN();
297 eoi=EOI();
299 NDAC(false);
301 for(timeout=TIMEOUT; timeout!=0; timeout--)
302 {
303 _delay_us(10);
305 if(!DAV())
306 break;
307 }
309 if(!timeout)
310 goto fail;
312 if(!eoi)
313 NDAC(true);
315 return byte | (eoi<<8) | (atn<<9);
317 fail:
318 NDAC(false);
319 NRFD(false);
320 USB.Send(ROMS("++error 4\r\n"));
321 return -1;
322 }
324 const GPIBDriver __attribute__((__progmem__)) GPIB;
326 //
328 // GPIB System Concepts
329 // ====================
330 // ______________________
331 // ATN_________________________ATN___/ ATN
332 //
333 // ______ _________ ________ ________
334 // DAV \________/ DAV \________/ DAV
335 //
336 // _____ _____ __________ ____
337 // NRFD__/ \_________/ NRFD \_________/ NRFD
338 //
339 // _____ _____
340 // NDAC__________/ \_______NDAC____________/ \______NDAC
341 //
342 // ________________ ___________________
343 // DATA---<________________>---DATA--<___________________>--DATA
344 //
345 //
346 // TNT4882 Manual
347 // ==============
348 // __________________________
349 // ATN___/ ATN
350 //
351 // ___________ _________
352 // DAV \________/ DAV
353 //
354 // ________ ___
355 // NRFD_____/ \__________/ NRFD
356 //
357 // _____
358 // NDAC________________/ \______NDAC
359 //
360 // ___________________
361 // DATA--------<___________________>--DATA
362 //
364 /* ----- EOF gpib.cc ----- */