Line 15... |
Line 15... |
15 |
// are forwarded to the application code by calling usb_setup(). The |
15 |
// are forwarded to the application code by calling usb_setup(). The |
16 |
// macros USBTINY_CALLBACK_IN and USBTINY_CALLBACK_OUT control whether |
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 |
17 |
// the callback functions usb_in() and usb_out() will be called for IN |
18 |
// and OUT transfers. |
18 |
// and OUT transfers. |
19 |
// |
19 |
// |
20 |
// Maximum stack usage (gcc 3.4.3 & 4.1.0) of usb_poll(): 5 bytes plus |
20 |
// Maximum stack usage (gcc 4.1.0 & 4.3.4) of usb_poll(): 5 bytes plus |
21 |
// possible additional stack usage in usb_setup(), usb_in() or usb_out(). |
21 |
// possible additional stack usage in usb_setup(), usb_in() or usb_out(). |
22 |
// |
22 |
// |
23 |
// Copyright (C) 2006 Dick Streefland |
23 |
// Copyright 2006-2010 Dick Streefland |
24 |
// |
24 |
// |
25 |
// This is free software, licensed under the terms of the GNU General |
25 |
// This is free software, licensed under the terms of the GNU General |
26 |
// Public License as published by the Free Software Foundation. |
26 |
// Public License as published by the Free Software Foundation. |
27 |
// ====================================================================== |
27 |
// ====================================================================== |
28 |
|
28 |
|
Line 56... |
Line 56... |
56 |
byte_t usb_rx_token; // PID of token packet: SETUP or OUT |
56 |
byte_t usb_rx_token; // PID of token packet: SETUP or OUT |
57 |
|
57 |
|
58 |
byte_t usb_tx_buf[USB_BUFSIZE]; // output buffer |
58 |
byte_t usb_tx_buf[USB_BUFSIZE]; // output buffer |
59 |
byte_t usb_tx_len; // output buffer size, 0 means empty |
59 |
byte_t usb_tx_len; // output buffer size, 0 means empty |
60 |
|
60 |
|
61 |
byte_t usb_address; // assigned USB address |
61 |
byte_t usb_address; // assigned device address |
- |
|
62 |
byte_t usb_new_address; // new device address |
62 |
|
63 |
|
63 |
// ---------------------------------------------------------------------- |
64 |
// ---------------------------------------------------------------------- |
64 |
// Local data |
65 |
// Local data |
65 |
// ---------------------------------------------------------------------- |
66 |
// ---------------------------------------------------------------------- |
66 |
|
67 |
|
Line 73... |
Line 74... |
73 |
}; |
74 |
}; |
74 |
|
75 |
|
75 |
static byte_t usb_tx_state; // TX_STATE_*, see enum above |
76 |
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_total; // total transmit size |
77 |
static byte_t* usb_tx_data; // pointer to data to transmit |
78 |
static byte_t* usb_tx_data; // pointer to data to transmit |
78 |
static byte_t new_address; // new device address |
- |
|
79 |
|
79 |
|
80 |
#if defined USBTINY_VENDOR_NAME |
80 |
#if defined USBTINY_VENDOR_NAME |
81 |
struct |
81 |
struct |
82 |
{ |
82 |
{ |
83 |
byte_t length; |
83 |
byte_t length; |
84 |
byte_t type; |
84 |
byte_t type; |
85 |
int string[sizeof(USBTINY_VENDOR_NAME)-1]; |
85 |
int string[sizeof(USBTINY_VENDOR_NAME)-1]; |
86 |
} string_vendor PROGMEM = |
86 |
} const string_vendor PROGMEM = |
87 |
{ |
87 |
{ |
88 |
2 * sizeof(USBTINY_VENDOR_NAME), |
88 |
2 * sizeof(USBTINY_VENDOR_NAME), |
89 |
DESCRIPTOR_TYPE_STRING, |
89 |
DESCRIPTOR_TYPE_STRING, |
90 |
{ CAT2(L, USBTINY_VENDOR_NAME) } |
90 |
{ CAT2(L, USBTINY_VENDOR_NAME) } |
91 |
}; |
91 |
}; |
Line 98... |
Line 98... |
98 |
struct |
98 |
struct |
99 |
{ |
99 |
{ |
100 |
byte_t length; |
100 |
byte_t length; |
101 |
byte_t type; |
101 |
byte_t type; |
102 |
int string[sizeof(USBTINY_DEVICE_NAME)-1]; |
102 |
int string[sizeof(USBTINY_DEVICE_NAME)-1]; |
103 |
} string_device PROGMEM = |
103 |
} const string_device PROGMEM = |
104 |
{ |
104 |
{ |
105 |
2 * sizeof(USBTINY_DEVICE_NAME), |
105 |
2 * sizeof(USBTINY_DEVICE_NAME), |
106 |
DESCRIPTOR_TYPE_STRING, |
106 |
DESCRIPTOR_TYPE_STRING, |
107 |
{ CAT2(L, USBTINY_DEVICE_NAME) } |
107 |
{ CAT2(L, USBTINY_DEVICE_NAME) } |
108 |
}; |
108 |
}; |
Line 115... |
Line 115... |
115 |
struct |
115 |
struct |
116 |
{ |
116 |
{ |
117 |
byte_t length; |
117 |
byte_t length; |
118 |
byte_t type; |
118 |
byte_t type; |
119 |
int string[sizeof(USBTINY_SERIAL)-1]; |
119 |
int string[sizeof(USBTINY_SERIAL)-1]; |
120 |
} string_serial PROGMEM = |
120 |
} const string_serial PROGMEM = |
121 |
{ |
121 |
{ |
122 |
2 * sizeof(USBTINY_SERIAL), |
122 |
2 * sizeof(USBTINY_SERIAL), |
123 |
DESCRIPTOR_TYPE_STRING, |
123 |
DESCRIPTOR_TYPE_STRING, |
124 |
{ CAT2(L, USBTINY_SERIAL) } |
124 |
{ CAT2(L, USBTINY_SERIAL) } |
125 |
}; |
125 |
}; |
Line 127... |
Line 127... |
127 |
#else |
127 |
#else |
128 |
# define SERIAL_ID 0 |
128 |
# define SERIAL_ID 0 |
129 |
#endif |
129 |
#endif |
130 |
|
130 |
|
131 |
#if VENDOR_NAME_ID || DEVICE_NAME_ID || SERIAL_ID |
131 |
#if VENDOR_NAME_ID || DEVICE_NAME_ID || SERIAL_ID |
132 |
static byte_t string_langid [] PROGMEM = |
132 |
static byte_t const string_langid [] PROGMEM = |
133 |
{ |
133 |
{ |
134 |
4, // bLength |
134 |
4, // bLength |
135 |
DESCRIPTOR_TYPE_STRING, // bDescriptorType (string) |
135 |
DESCRIPTOR_TYPE_STRING, // bDescriptorType (string) |
136 |
LE(0x0409), // wLANGID[0] (American English) |
136 |
LE(0x0409), // wLANGID[0] (American English) |
137 |
}; |
137 |
}; |
138 |
#endif |
138 |
#endif |
139 |
|
139 |
|
140 |
// Device Descriptor |
140 |
// Device Descriptor |
141 |
static byte_t descr_device [18] PROGMEM = |
141 |
static byte_t const descr_device [18] PROGMEM = |
142 |
{ |
142 |
{ |
143 |
18, // bLength |
143 |
18, // bLength |
144 |
DESCRIPTOR_TYPE_DEVICE, // bDescriptorType |
144 |
DESCRIPTOR_TYPE_DEVICE, // bDescriptorType |
145 |
LE(0x0110), // bcdUSB |
145 |
LE(0x0101), // bcdUSB |
146 |
USBTINY_DEVICE_CLASS, // bDeviceClass |
146 |
USBTINY_DEVICE_CLASS, // bDeviceClass |
147 |
USBTINY_DEVICE_SUBCLASS, // bDeviceSubClass |
147 |
USBTINY_DEVICE_SUBCLASS, // bDeviceSubClass |
148 |
USBTINY_DEVICE_PROTOCOL, // bDeviceProtocol |
148 |
USBTINY_DEVICE_PROTOCOL, // bDeviceProtocol |
149 |
8, // bMaxPacketSize0 |
149 |
8, // bMaxPacketSize0 |
150 |
LE(USBTINY_VENDOR_ID), // idVendor |
150 |
LE(USBTINY_VENDOR_ID), // idVendor |
Line 155... |
Line 155... |
155 |
SERIAL_ID, // iSerialNumber |
155 |
SERIAL_ID, // iSerialNumber |
156 |
1, // bNumConfigurations |
156 |
1, // bNumConfigurations |
157 |
}; |
157 |
}; |
158 |
|
158 |
|
159 |
// Configuration Descriptor |
159 |
// Configuration Descriptor |
160 |
static byte_t descr_config [] PROGMEM = |
160 |
static byte_t const descr_config [] PROGMEM = |
161 |
{ |
161 |
{ |
162 |
9, // bLength |
162 |
9, // bLength |
163 |
DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType |
163 |
DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType |
164 |
LE(9+9+7*USBTINY_ENDPOINT), // wTotalLength |
164 |
LE(9+9+7*USBTINY_ENDPOINT), // wTotalLength |
165 |
1, // bNumInterfaces |
165 |
1, // bNumInterfaces |
Line 221... |
Line 221... |
221 |
#endif |
221 |
#endif |
222 |
data[1] = 0; |
222 |
data[1] = 0; |
223 |
} |
223 |
} |
224 |
else if ( data[1] == 5 ) // SET_ADDRESS |
224 |
else if ( data[1] == 5 ) // SET_ADDRESS |
225 |
{ |
225 |
{ |
226 |
new_address = data[2]; |
226 |
usb_new_address = data[2]; |
- |
|
227 |
#ifdef USBTINY_USB_OK_LED |
- |
|
228 |
SET(USBTINY_USB_OK_LED);// LED on |
- |
|
229 |
#endif |
227 |
} |
230 |
} |
228 |
else if ( data[1] == 6 ) // GET_DESCRIPTOR |
231 |
else if ( data[1] == 6 ) // GET_DESCRIPTOR |
229 |
{ |
232 |
{ |
230 |
usb_tx_state = TX_STATE_ROM; |
233 |
usb_tx_state = TX_STATE_ROM; |
231 |
if ( data[3] == 1 ) |
234 |
if ( data[3] == 1 ) |
Line 369... |
Line 372... |
369 |
// ---------------------------------------------------------------------- |
372 |
// ---------------------------------------------------------------------- |
370 |
extern void usb_init ( void ) |
373 |
extern void usb_init ( void ) |
371 |
{ |
374 |
{ |
372 |
USB_INT_CONFIG |= USB_INT_CONFIG_SET; |
375 |
USB_INT_CONFIG |= USB_INT_CONFIG_SET; |
373 |
USB_INT_ENABLE |= (1 << USB_INT_ENABLE_BIT); |
376 |
USB_INT_ENABLE |= (1 << USB_INT_ENABLE_BIT); |
- |
|
377 |
#ifdef USBTINY_USB_OK_LED |
- |
|
378 |
OUTPUT(USBTINY_USB_OK_LED); |
- |
|
379 |
#endif |
- |
|
380 |
#ifdef USBTINY_DMINUS_PULLUP |
- |
|
381 |
SET(USBTINY_DMINUS_PULLUP); |
- |
|
382 |
OUTPUT(USBTINY_DMINUS_PULLUP); // enable pullup on D- |
- |
|
383 |
#endif |
374 |
sei(); |
384 |
sei(); |
375 |
} |
385 |
} |
376 |
|
386 |
|
377 |
// ---------------------------------------------------------------------- |
387 |
// ---------------------------------------------------------------------- |
378 |
// Poll USB driver: |
388 |
// Poll USB driver: |
Line 390... |
Line 400... |
390 |
usb_receive( usb_rx_buf + USB_BUFSIZE - usb_rx_off + 1, usb_rx_len - 3 ); |
400 |
usb_receive( usb_rx_buf + USB_BUFSIZE - usb_rx_off + 1, usb_rx_len - 3 ); |
391 |
usb_tx_len = 0; // abort pending transmission |
401 |
usb_tx_len = 0; // abort pending transmission |
392 |
usb_rx_len = 0; // accept next packet |
402 |
usb_rx_len = 0; // accept next packet |
393 |
} |
403 |
} |
394 |
// refill an empty transmit buffer, when the transmitter is active |
404 |
// refill an empty transmit buffer, when the transmitter is active |
395 |
if ( usb_tx_len == 0 ) |
405 |
if ( usb_tx_len == 0 && usb_tx_state != TX_STATE_IDLE ) |
396 |
{ |
406 |
{ |
397 |
if ( usb_tx_state != TX_STATE_IDLE ) |
- |
|
398 |
{ |
- |
|
399 |
usb_transmit(); |
407 |
usb_transmit(); |
400 |
} |
- |
|
401 |
else |
- |
|
402 |
{ // change the USB address at the end of a transfer |
- |
|
403 |
usb_address = new_address; |
- |
|
404 |
} |
- |
|
405 |
} |
408 |
} |
406 |
// check for USB bus reset |
409 |
// check for USB bus reset |
407 |
for ( i = 10; i > 0 && ! (USB_IN & USB_MASK_DMINUS); i-- ) |
410 |
for ( i = 10; i > 0 && ! (USB_IN & USB_MASK_DMINUS); i-- ) |
408 |
{ |
411 |
{ |
409 |
} |
412 |
} |
410 |
if ( i == 0 ) |
413 |
if ( i == 0 ) |
411 |
{ // SE0 for more than 2.5uS is a reset |
414 |
{ // SE0 for more than 2.5uS is a reset |
412 |
cli(); |
415 |
usb_new_address = 0; |
413 |
usb_tx_len=0; |
416 |
usb_address = 0; |
414 |
usb_rx_len=0; |
417 |
#ifdef USBTINY_USB_OK_LED |
415 |
new_address = 0; |
418 |
CLR(USBTINY_USB_OK_LED); // LED off |
416 |
sei(); |
419 |
#endif |
417 |
} |
420 |
} |
418 |
} |
421 |
} |