Rev Author Line No. Line
3331 kaklik 1 // ======================================================================
2 // USB driver
3 //
4 // Entry points:
5 // usb_init() - enable the USB interrupt
6 // usb_poll() - poll for incoming packets and process them
7 //
8 // This code communicates with the interrupt handler through a number of
9 // global variables, including two input buffers and one output buffer.
10 // Packets are queued for transmission by copying them into the output
11 // buffer. The interrupt handler will transmit such a packet on the
12 // reception of an IN packet.
13 //
14 // Standard SETUP packets are handled here. Non-standard SETUP packets
15 // are forwarded to the application code by calling usb_setup(). The
16 // macros USBTINY_CALLBACK_IN and USBTINY_CALLBACK_OUT control whether
17 // the callback functions usb_in() and usb_out() will be called for IN
18 // and OUT transfers.
19 //
20 // Maximum stack usage (gcc 3.4.3 & 4.1.0) of usb_poll(): 5 bytes plus
21 // possible additional stack usage in usb_setup(), usb_in() or usb_out().
22 //
23 // Copyright (C) 2006 Dick Streefland
24 //
25 // This is free software, licensed under the terms of the GNU General
26 // Public License as published by the Free Software Foundation.
27 // ======================================================================
28  
29 #include <avr/pgmspace.h>
30 #include <avr/interrupt.h>
31 #include "def.h"
32 #include "usb.h"
33  
34 #define LE(word) (word) & 0xff, (word) >> 8
35  
36 // ----------------------------------------------------------------------
37 // USB constants
38 // ----------------------------------------------------------------------
39  
40 enum
41 {
42 DESCRIPTOR_TYPE_DEVICE = 1,
43 DESCRIPTOR_TYPE_CONFIGURATION,
44 DESCRIPTOR_TYPE_STRING,
45 DESCRIPTOR_TYPE_INTERFACE,
46 DESCRIPTOR_TYPE_ENDPOINT,
47 };
48  
49 // ----------------------------------------------------------------------
50 // Interrupt handler interface
51 // ----------------------------------------------------------------------
52  
53 byte_t usb_rx_buf[2*USB_BUFSIZE]; // two input buffers
54 byte_t usb_rx_off; // buffer offset: 0 or USB_BUFSIZE
55 byte_t usb_rx_len; // buffer size, 0 means empty
56 byte_t usb_rx_token; // PID of token packet: SETUP or OUT
57  
58 byte_t usb_tx_buf[USB_BUFSIZE]; // output buffer
59 byte_t usb_tx_len; // output buffer size, 0 means empty
60  
61 byte_t usb_address; // assigned USB address
62  
63 // ----------------------------------------------------------------------
64 // Local data
65 // ----------------------------------------------------------------------
66  
67 enum
68 {
69 TX_STATE_IDLE = 0, // transmitter idle
70 TX_STATE_RAM, // usb_tx_data is a RAM address
71 TX_STATE_ROM, // usb_tx_data is a ROM address
72 TX_STATE_CALLBACK, // call usb_in() to obtain transmit data
73 };
74  
75 static byte_t usb_tx_state; // TX_STATE_*, see enum above
76 static byte_t usb_tx_total; // total transmit size
77 static byte_t* usb_tx_data; // pointer to data to transmit
78 static byte_t new_address; // new device address
79  
80 #if defined USBTINY_VENDOR_NAME
81 struct
82 {
83 byte_t length;
84 byte_t type;
85 int string[sizeof(USBTINY_VENDOR_NAME)-1];
86 } string_vendor PROGMEM =
87 {
88 2 * sizeof(USBTINY_VENDOR_NAME),
89 DESCRIPTOR_TYPE_STRING,
90 { CAT2(L, USBTINY_VENDOR_NAME) }
91 };
92 # define VENDOR_NAME_ID 1
93 #else
94 # define VENDOR_NAME_ID 0
95 #endif
96  
97 #if defined USBTINY_DEVICE_NAME
98 struct
99 {
100 byte_t length;
101 byte_t type;
102 int string[sizeof(USBTINY_DEVICE_NAME)-1];
103 } string_device PROGMEM =
104 {
105 2 * sizeof(USBTINY_DEVICE_NAME),
106 DESCRIPTOR_TYPE_STRING,
107 { CAT2(L, USBTINY_DEVICE_NAME) }
108 };
109 # define DEVICE_NAME_ID 2
110 #else
111 # define DEVICE_NAME_ID 0
112 #endif
113  
114 #if defined USBTINY_SERIAL
115 struct
116 {
117 byte_t length;
118 byte_t type;
119 int string[sizeof(USBTINY_SERIAL)-1];
120 } string_serial PROGMEM =
121 {
122 2 * sizeof(USBTINY_SERIAL),
123 DESCRIPTOR_TYPE_STRING,
124 { CAT2(L, USBTINY_SERIAL) }
125 };
126 # define SERIAL_ID 3
127 #else
128 # define SERIAL_ID 0
129 #endif
130  
131 #if VENDOR_NAME_ID || DEVICE_NAME_ID || SERIAL_ID
132 static byte_t string_langid [] PROGMEM =
133 {
134 4, // bLength
135 DESCRIPTOR_TYPE_STRING, // bDescriptorType (string)
136 LE(0x0409), // wLANGID[0] (American English)
137 };
138 #endif
139  
140 // Device Descriptor
141 static byte_t descr_device [18] PROGMEM =
142 {
143 18, // bLength
144 DESCRIPTOR_TYPE_DEVICE, // bDescriptorType
145 LE(0x0110), // bcdUSB
146 USBTINY_DEVICE_CLASS, // bDeviceClass
147 USBTINY_DEVICE_SUBCLASS, // bDeviceSubClass
148 USBTINY_DEVICE_PROTOCOL, // bDeviceProtocol
149 8, // bMaxPacketSize0
150 LE(USBTINY_VENDOR_ID), // idVendor
151 LE(USBTINY_DEVICE_ID), // idProduct
152 LE(USBTINY_DEVICE_VERSION), // bcdDevice
153 VENDOR_NAME_ID, // iManufacturer
154 DEVICE_NAME_ID, // iProduct
155 SERIAL_ID, // iSerialNumber
156 1, // bNumConfigurations
157 };
158  
159 // Configuration Descriptor
160 static byte_t descr_config [] PROGMEM =
161 {
162 9, // bLength
163 DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType
164 LE(9+9+7*USBTINY_ENDPOINT), // wTotalLength
165 1, // bNumInterfaces
166 1, // bConfigurationValue
167 0, // iConfiguration
168 (USBTINY_MAX_POWER ? 0x80 : 0xc0), // bmAttributes
169 (USBTINY_MAX_POWER + 1) / 2, // MaxPower
170  
171 // Standard Interface Descriptor
172 9, // bLength
173 DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType
174 0, // bInterfaceNumber
175 0, // bAlternateSetting
176 USBTINY_ENDPOINT, // bNumEndpoints
177 USBTINY_INTERFACE_CLASS, // bInterfaceClass
178 USBTINY_INTERFACE_SUBCLASS, // bInterfaceSubClass
179 USBTINY_INTERFACE_PROTOCOL, // bInterfaceProtocol
180 0, // iInterface
181  
182 #if USBTINY_ENDPOINT
183 // Additional Endpoint
184 7, // bLength
185 DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
186 USBTINY_ENDPOINT_ADDRESS, // bEndpointAddress
187 USBTINY_ENDPOINT_TYPE, // bmAttributes
188 LE(8), // wMaxPacketSize
189 USBTINY_ENDPOINT_INTERVAL, // bInterval
190 #endif
191 };
192  
193 // ----------------------------------------------------------------------
194 // Inspect an incoming packet.
195 // ----------------------------------------------------------------------
196 static void usb_receive ( byte_t* data, byte_t rx_len )
197 {
198 byte_t len;
199 byte_t type;
200 byte_t limit;
201  
202 usb_tx_state = TX_STATE_RAM;
203 len = 0;
204 if ( usb_rx_token == USB_PID_SETUP )
205 {
206 limit = data[6];
207 if ( data[7] )
208 {
209 limit = 255;
210 }
211 type = data[0] & 0x60;
212 if ( type == 0x00 )
213 { // Standard request
214 if ( data[1] == 0 ) // GET_STATUS
215 {
216 len = 2;
217 #if USBTINY_MAX_POWER == 0
218 data[0] = (data[0] == 0x80);
219 #else
220 data[0] = 0;
221 #endif
222 data[1] = 0;
223 }
224 else if ( data[1] == 5 ) // SET_ADDRESS
225 {
226 new_address = data[2];
227 }
228 else if ( data[1] == 6 ) // GET_DESCRIPTOR
229 {
230 usb_tx_state = TX_STATE_ROM;
231 if ( data[3] == 1 )
232 { // DEVICE
233 data = (byte_t*) &descr_device;
234 len = sizeof(descr_device);
235 }
236 else if ( data[3] == 2 )
237 { // CONFIGURATION
238 data = (byte_t*) &descr_config;
239 len = sizeof(descr_config);
240 }
241 #if VENDOR_NAME_ID || DEVICE_NAME_ID || SERIAL_ID
242 else if ( data[3] == 3 )
243 { // STRING
244 if ( data[2] == 0 )
245 {
246 data = (byte_t*) &string_langid;
247 len = sizeof(string_langid);
248 }
249 #if VENDOR_NAME_ID
250 else if ( data[2] == VENDOR_NAME_ID )
251 {
252 data = (byte_t*) &string_vendor;
253 len = sizeof(string_vendor);
254 }
255 #endif
256 #if DEVICE_NAME_ID
257 else if ( data[2] == DEVICE_NAME_ID )
258 {
259 data = (byte_t*) &string_device;
260 len = sizeof(string_device);
261 }
262 #endif
263 #if SERIAL_ID
264 else if ( data[2] == SERIAL_ID )
265 {
266 data = (byte_t*) &string_serial;
267 len = sizeof(string_serial);
268 }
269 #endif
270 }
271 #endif
272 }
273 else if ( data[1] == 8 ) // GET_CONFIGURATION
274 {
275 data[0] = 1; // return bConfigurationValue
276 len = 1;
277 }
278 else if ( data[1] == 10 ) // GET_INTERFACE
279 {
280 data[0] = 0;
281 len = 1;
282 }
283 }
284 else
285 { // Class or Vendor request
286 len = usb_setup( data );
287 #if USBTINY_CALLBACK_IN
288 if ( len == 0xff )
289 {
290 usb_tx_state = TX_STATE_CALLBACK;
291 }
292 #endif
293 }
294 if ( len > limit )
295 {
296 len = limit;
297 }
298 usb_tx_data = data;
299 }
300 #if USBTINY_CALLBACK_OUT
301 else if ( rx_len > 0 )
302 { // usb_rx_token == USB_PID_OUT
303 usb_out( data, rx_len );
304 }
305 #endif
306 usb_tx_total = len;
307 usb_tx_buf[0] = USB_PID_DATA0; // next data packet will be DATA1
308 }
309  
310 // ----------------------------------------------------------------------
311 // Load the transmit buffer with the next packet.
312 // ----------------------------------------------------------------------
313 static void usb_transmit ( void )
314 {
315 byte_t len;
316 byte_t* src;
317 byte_t* dst;
318 byte_t i;
319 byte_t b;
320  
321 usb_tx_buf[0] ^= (USB_PID_DATA0 ^ USB_PID_DATA1);
322 len = usb_tx_total;
323 if ( len > 8 )
324 {
325 len = 8;
326 }
327 dst = usb_tx_buf + 1;
328 if ( len > 0 )
329 {
330 #if USBTINY_CALLBACK_IN
331 if ( usb_tx_state == TX_STATE_CALLBACK )
332 {
333 len = usb_in( dst, len );
334 }
335 else
336 #endif
337 {
338 src = usb_tx_data;
339 if ( usb_tx_state == TX_STATE_RAM )
340 {
341 for ( i = 0; i < len; i++ )
342 {
343 *dst++ = *src++;
344 }
345 }
346 else // usb_tx_state == TX_STATE_ROM
347 {
348 for ( i = 0; i < len; i++ )
349 {
350 b = pgm_read_byte( src );
351 src++;
352 *dst++ = b;
353 }
354 }
355 usb_tx_data = src;
356 }
357 usb_tx_total -= len;
358 }
359 crc( usb_tx_buf + 1, len );
360 usb_tx_len = len + 3;
361 if ( len < 8 )
362 { // this is the last packet
363 usb_tx_state = TX_STATE_IDLE;
364 }
365 }
366  
367 // ----------------------------------------------------------------------
368 // Initialize the low-level USB driver.
369 // ----------------------------------------------------------------------
370 extern void usb_init ( void )
371 {
372 USB_INT_CONFIG |= USB_INT_CONFIG_SET;
373 USB_INT_ENABLE |= (1 << USB_INT_ENABLE_BIT);
374 sei();
375 }
376  
377 // ----------------------------------------------------------------------
378 // Poll USB driver:
379 // - check for incoming USB packets
380 // - refill an empty transmit buffer
381 // - check for USB bus reset
382 // ----------------------------------------------------------------------
383 extern void usb_poll ( void )
384 {
385 byte_t i;
386  
387 // check for incoming USB packets
388 if ( usb_rx_len != 0 )
389 {
390 usb_receive( usb_rx_buf + USB_BUFSIZE - usb_rx_off + 1, usb_rx_len - 3 );
391 usb_tx_len = 0; // abort pending transmission
392 usb_rx_len = 0; // accept next packet
393 }
394 // refill an empty transmit buffer, when the transmitter is active
395 if ( usb_tx_len == 0 )
396 {
397 if ( usb_tx_state != TX_STATE_IDLE )
398 {
399 usb_transmit();
400 }
401 else
402 { // change the USB address at the end of a transfer
403 usb_address = new_address;
404 }
405 }
406 // check for USB bus reset
407 for ( i = 10; i > 0 && ! (USB_IN & USB_MASK_DMINUS); i-- )
408 {
409 }
410 if ( i == 0 )
411 { // SE0 for more than 2.5uS is a reset
412 cli();
413 usb_tx_len=0;
414 usb_rx_len=0;
415 new_address = 0;
416 sei();
417 }
418 }