initial commit
[usb-nixie.git] / usb_serial.c
1 /* USB Serial Example for Teensy USB Development Board
2  * http://www.pjrc.com/teensy/
3  * Copyright (c) 2008 PJRC.COM, LLC
4  * 
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  * 
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21  * THE SOFTWARE.
22  */
23
24 // Version 1.0: Initial Release
25 // Version 1.1: support Teensy++
26 // Version 1.2: fixed usb_serial_available
27 // Version 1.3: added transmit bandwidth test
28 // Version 1.4: added usb_serial_write
29 // Version 1.5: add support for Teensy 2.0
30
31 #define USB_SERIAL_PRIVATE_INCLUDE
32 #include "usb_serial.h"
33
34
35 /**************************************************************************
36  *
37  *  Configurable Options
38  *
39  **************************************************************************/
40
41 // You can change these to give your code its own name.  On Windows,
42 // these are only used before an INF file (driver install) is loaded.
43 #define STR_MANUFACTURER        L"Your Name"
44 #define STR_PRODUCT             L"USB Serial"
45
46 // All USB serial devices are supposed to have a serial number
47 // (according to Microsoft).  On windows, a new COM port is created
48 // for every unique serial/vendor/product number combination.  If
49 // you program 2 identical boards with 2 different serial numbers
50 // and they are assigned COM7 and COM8, each will always get the
51 // same COM port number because Windows remembers serial numbers.
52 //
53 // On Mac OS-X, a device file is created automatically which
54 // incorperates the serial number, eg, /dev/cu-usbmodem12341
55 //
56 // Linux by default ignores the serial number, and creates device
57 // files named /dev/ttyACM0, /dev/ttyACM1... in the order connected.
58 // Udev rules (in /etc/udev/rules.d) can define persistent device
59 // names linked to this serial number, as well as permissions, owner
60 // and group settings.
61 #define STR_SERIAL_NUMBER       L"12345"
62
63 // Mac OS-X and Linux automatically load the correct drivers.  On
64 // Windows, even though the driver is supplied by Microsoft, an
65 // INF file is needed to load the driver.  These numbers need to
66 // match the INF file.
67 #define VENDOR_ID               0x16C0
68 #define PRODUCT_ID              0x047A
69
70 // When you write data, it goes into a USB endpoint buffer, which
71 // is transmitted to the PC when it becomes full, or after a timeout
72 // with no more writes.  Even if you write in exactly packet-size
73 // increments, this timeout is used to send a "zero length packet"
74 // that tells the PC no more data is expected and it should pass
75 // any buffered data to the application that may be waiting.  If
76 // you want data sent immediately, call usb_serial_flush_output().
77 #define TRANSMIT_FLUSH_TIMEOUT  5   /* in milliseconds */
78
79 // If the PC is connected but not "listening", this is the length
80 // of time before usb_serial_getchar() returns with an error.  This
81 // is roughly equivilant to a real UART simply transmitting the
82 // bits on a wire where nobody is listening, except you get an error
83 // code which you can ignore for serial-like discard of data, or
84 // use to know your data wasn't sent.
85 #define TRANSMIT_TIMEOUT        25   /* in milliseconds */
86
87 // USB devices are supposed to implment a halt feature, which is
88 // rarely (if ever) used.  If you comment this line out, the halt
89 // code will be removed, saving 116 bytes of space (gcc 4.3.0).
90 // This is not strictly USB compliant, but works with all major
91 // operating systems.
92 #define SUPPORT_ENDPOINT_HALT
93
94
95
96 /**************************************************************************
97  *
98  *  Endpoint Buffer Configuration
99  *
100  **************************************************************************/
101
102 // These buffer sizes are best for most applications, but perhaps if you
103 // want more buffering on some endpoint at the expense of others, this
104 // is where you can make such changes.  The AT90USB162 has only 176 bytes
105 // of DPRAM (USB buffers) and only endpoints 3 & 4 can double buffer.
106
107 #define ENDPOINT0_SIZE          16
108 #define CDC_ACM_ENDPOINT        2
109 #define CDC_RX_ENDPOINT         3
110 #define CDC_TX_ENDPOINT         4
111 #if defined(__AVR_AT90USB162__)
112 #define CDC_ACM_SIZE            16
113 #define CDC_ACM_BUFFER          EP_SINGLE_BUFFER
114 #define CDC_RX_SIZE             32
115 #define CDC_RX_BUFFER           EP_DOUBLE_BUFFER
116 #define CDC_TX_SIZE             32
117 #define CDC_TX_BUFFER           EP_DOUBLE_BUFFER
118 #else
119 #define CDC_ACM_SIZE            16
120 #define CDC_ACM_BUFFER          EP_SINGLE_BUFFER
121 #define CDC_RX_SIZE             64
122 #define CDC_RX_BUFFER           EP_DOUBLE_BUFFER
123 #define CDC_TX_SIZE             64
124 #define CDC_TX_BUFFER           EP_DOUBLE_BUFFER
125 #endif
126
127 static const uint8_t PROGMEM endpoint_config_table[] = {
128         0,
129         1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(CDC_ACM_SIZE) | CDC_ACM_BUFFER,
130         1, EP_TYPE_BULK_OUT,      EP_SIZE(CDC_RX_SIZE) | CDC_RX_BUFFER,
131         1, EP_TYPE_BULK_IN,       EP_SIZE(CDC_TX_SIZE) | CDC_TX_BUFFER
132 };
133
134
135 /**************************************************************************
136  *
137  *  Descriptor Data
138  *
139  **************************************************************************/
140
141 // Descriptors are the data that your computer reads when it auto-detects
142 // this USB device (called "enumeration" in USB lingo).  The most commonly
143 // changed items are editable at the top of this file.  Changing things
144 // in here should only be done by those who've read chapter 9 of the USB
145 // spec and relevant portions of any USB class specifications!
146
147 static uint8_t PROGMEM device_descriptor[] = {
148         18,                                     // bLength
149         1,                                      // bDescriptorType
150         0x00, 0x02,                             // bcdUSB
151         2,                                      // bDeviceClass
152         0,                                      // bDeviceSubClass
153         0,                                      // bDeviceProtocol
154         ENDPOINT0_SIZE,                         // bMaxPacketSize0
155         LSB(VENDOR_ID), MSB(VENDOR_ID),         // idVendor
156         LSB(PRODUCT_ID), MSB(PRODUCT_ID),       // idProduct
157         0x00, 0x01,                             // bcdDevice
158         1,                                      // iManufacturer
159         2,                                      // iProduct
160         3,                                      // iSerialNumber
161         1                                       // bNumConfigurations
162 };
163
164 #define CONFIG1_DESC_SIZE (9+9+5+5+4+5+7+9+7+7)
165 static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
166         // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
167         9,                                      // bLength;
168         2,                                      // bDescriptorType;
169         LSB(CONFIG1_DESC_SIZE),                 // wTotalLength
170         MSB(CONFIG1_DESC_SIZE),
171         2,                                      // bNumInterfaces
172         1,                                      // bConfigurationValue
173         0,                                      // iConfiguration
174         0xC0,                                   // bmAttributes
175         50,                                     // bMaxPower
176         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
177         9,                                      // bLength
178         4,                                      // bDescriptorType
179         0,                                      // bInterfaceNumber
180         0,                                      // bAlternateSetting
181         1,                                      // bNumEndpoints
182         0x02,                                   // bInterfaceClass
183         0x02,                                   // bInterfaceSubClass
184         0x01,                                   // bInterfaceProtocol
185         0,                                      // iInterface
186         // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
187         5,                                      // bFunctionLength
188         0x24,                                   // bDescriptorType
189         0x00,                                   // bDescriptorSubtype
190         0x10, 0x01,                             // bcdCDC
191         // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
192         5,                                      // bFunctionLength
193         0x24,                                   // bDescriptorType
194         0x01,                                   // bDescriptorSubtype
195         0x01,                                   // bmCapabilities
196         1,                                      // bDataInterface
197         // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
198         4,                                      // bFunctionLength
199         0x24,                                   // bDescriptorType
200         0x02,                                   // bDescriptorSubtype
201         0x06,                                   // bmCapabilities
202         // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
203         5,                                      // bFunctionLength
204         0x24,                                   // bDescriptorType
205         0x06,                                   // bDescriptorSubtype
206         0,                                      // bMasterInterface
207         1,                                      // bSlaveInterface0
208         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
209         7,                                      // bLength
210         5,                                      // bDescriptorType
211         CDC_ACM_ENDPOINT | 0x80,                // bEndpointAddress
212         0x03,                                   // bmAttributes (0x03=intr)
213         CDC_ACM_SIZE, 0,                        // wMaxPacketSize
214         64,                                     // bInterval
215         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
216         9,                                      // bLength
217         4,                                      // bDescriptorType
218         1,                                      // bInterfaceNumber
219         0,                                      // bAlternateSetting
220         2,                                      // bNumEndpoints
221         0x0A,                                   // bInterfaceClass
222         0x00,                                   // bInterfaceSubClass
223         0x00,                                   // bInterfaceProtocol
224         0,                                      // iInterface
225         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
226         7,                                      // bLength
227         5,                                      // bDescriptorType
228         CDC_RX_ENDPOINT,                        // bEndpointAddress
229         0x02,                                   // bmAttributes (0x02=bulk)
230         CDC_RX_SIZE, 0,                         // wMaxPacketSize
231         0,                                      // bInterval
232         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
233         7,                                      // bLength
234         5,                                      // bDescriptorType
235         CDC_TX_ENDPOINT | 0x80,                 // bEndpointAddress
236         0x02,                                   // bmAttributes (0x02=bulk)
237         CDC_TX_SIZE, 0,                         // wMaxPacketSize
238         0                                       // bInterval
239 };
240
241 // If you're desperate for a little extra code memory, these strings
242 // can be completely removed if iManufacturer, iProduct, iSerialNumber
243 // in the device desciptor are changed to zeros.
244 struct usb_string_descriptor_struct {
245         uint8_t bLength;
246         uint8_t bDescriptorType;
247         int16_t wString[];
248 };
249 static struct usb_string_descriptor_struct PROGMEM string0 = {
250         4,
251         3,
252         {0x0409}
253 };
254 static struct usb_string_descriptor_struct PROGMEM string1 = {
255         sizeof(STR_MANUFACTURER),
256         3,
257         STR_MANUFACTURER
258 };
259 static struct usb_string_descriptor_struct PROGMEM string2 = {
260         sizeof(STR_PRODUCT),
261         3,
262         STR_PRODUCT
263 };
264 static struct usb_string_descriptor_struct PROGMEM string3 = {
265         sizeof(STR_SERIAL_NUMBER),
266         3,
267         STR_SERIAL_NUMBER
268 };
269
270 // This table defines which descriptor data is sent for each specific
271 // request from the host (in wValue and wIndex).
272 static struct descriptor_list_struct {
273         uint16_t        wValue;
274         uint16_t        wIndex;
275         const uint8_t   *addr;
276         uint8_t         length;
277 } PROGMEM descriptor_list[] = {
278         {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
279         {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
280         {0x0300, 0x0000, (const uint8_t *)&string0, 4},
281         {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
282         {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)},
283         {0x0303, 0x0409, (const uint8_t *)&string3, sizeof(STR_SERIAL_NUMBER)}
284 };
285 #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
286
287
288 /**************************************************************************
289  *
290  *  Variables - these are the only non-stack RAM usage
291  *
292  **************************************************************************/
293
294 // zero when we are not configured, non-zero when enumerated
295 static volatile uint8_t usb_configuration=0;
296
297 // the time remaining before we transmit any partially full
298 // packet, or send a zero length packet.
299 static volatile uint8_t transmit_flush_timer=0;
300 static uint8_t transmit_previous_timeout=0;
301
302 // serial port settings (baud rate, control signals, etc) set
303 // by the PC.  These are ignored, but kept in RAM.
304 static uint8_t cdc_line_coding[7]={0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x08};
305 static uint8_t cdc_line_rtsdtr=0;
306
307
308 /**************************************************************************
309  *
310  *  Public Functions - these are the API intended for the user
311  *
312  **************************************************************************/
313
314 // initialize USB serial
315 void usb_init(void)
316 {
317         HW_CONFIG();
318         USB_FREEZE();                           // enable USB
319         PLL_CONFIG();                           // config PLL, 16 MHz xtal
320         while (!(PLLCSR & (1<<PLOCK))) ;        // wait for PLL lock
321         USB_CONFIG();                           // start USB clock
322         UDCON = 0;                              // enable attach resistor
323         usb_configuration = 0;
324         cdc_line_rtsdtr = 0;
325         UDIEN = (1<<EORSTE)|(1<<SOFE);
326         sei();
327 }
328
329 // return 0 if the USB is not configured, or the configuration
330 // number selected by the HOST
331 uint8_t usb_configured(void)
332 {
333         return usb_configuration;
334 }
335
336 // get the next character, or -1 if nothing received
337 int16_t usb_serial_getchar(void)
338 {
339         uint8_t c, intr_state;
340
341         // interrupts are disabled so these functions can be
342         // used from the main program or interrupt context,
343         // even both in the same program!
344         intr_state = SREG;
345         cli();
346         if (!usb_configuration) {
347                 SREG = intr_state;
348                 return -1;
349         }
350         UENUM = CDC_RX_ENDPOINT;
351         if (!(UEINTX & (1<<RWAL))) {
352                 // no data in buffer
353                 SREG = intr_state;
354                 return -1;
355         }
356         // take one byte out of the buffer
357         c = UEDATX;
358         // if buffer completely used, release it
359         if (!(UEINTX & (1<<RWAL))) UEINTX = 0x6B;
360         SREG = intr_state;
361         return c;
362 }
363
364 // number of bytes available in the receive buffer
365 uint8_t usb_serial_available(void)
366 {
367         uint8_t n=0, intr_state;
368
369         intr_state = SREG;
370         cli();
371         if (usb_configuration) {
372                 UENUM = CDC_RX_ENDPOINT;
373                 n = UEBCLX;
374         }
375         SREG = intr_state;
376         return n;
377 }
378
379 // discard any buffered input
380 void usb_serial_flush_input(void)
381 {
382         uint8_t intr_state;
383
384         if (usb_configuration) {
385                 intr_state = SREG;
386                 cli();
387                 UENUM = CDC_RX_ENDPOINT;
388                 while ((UEINTX & (1<<RWAL))) {
389                         UEINTX = 0x6B; 
390                 }
391                 SREG = intr_state;
392         }
393 }
394
395 // transmit a character.  0 returned on success, -1 on error
396 int8_t usb_serial_putchar(uint8_t c)
397 {
398         uint8_t timeout, intr_state;
399
400         // if we're not online (enumerated and configured), error
401         if (!usb_configuration) return -1;
402         // interrupts are disabled so these functions can be
403         // used from the main program or interrupt context,
404         // even both in the same program!
405         intr_state = SREG;
406         cli();
407         UENUM = CDC_TX_ENDPOINT;
408         // if we gave up due to timeout before, don't wait again
409         if (transmit_previous_timeout) {
410                 if (!(UEINTX & (1<<RWAL))) {
411                         SREG = intr_state;
412                         return -1;
413                 }
414                 transmit_previous_timeout = 0;
415         }
416         // wait for the FIFO to be ready to accept data
417         timeout = UDFNUML + TRANSMIT_TIMEOUT;
418         while (1) {
419                 // are we ready to transmit?
420                 if (UEINTX & (1<<RWAL)) break;
421                 SREG = intr_state;
422                 // have we waited too long?  This happens if the user
423                 // is not running an application that is listening
424                 if (UDFNUML == timeout) {
425                         transmit_previous_timeout = 1;
426                         return -1;
427                 }
428                 // has the USB gone offline?
429                 if (!usb_configuration) return -1;
430                 // get ready to try checking again
431                 intr_state = SREG;
432                 cli();
433                 UENUM = CDC_TX_ENDPOINT;
434         }
435         // actually write the byte into the FIFO
436         UEDATX = c;
437         // if this completed a packet, transmit it now!
438         if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
439         transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
440         SREG = intr_state;
441         return 0;
442 }
443
444
445 // transmit a character, but do not wait if the buffer is full,
446 //   0 returned on success, -1 on buffer full or error 
447 int8_t usb_serial_putchar_nowait(uint8_t c)
448 {
449         uint8_t intr_state;
450
451         if (!usb_configuration) return -1;
452         intr_state = SREG;
453         cli();
454         UENUM = CDC_TX_ENDPOINT;
455         if (!(UEINTX & (1<<RWAL))) {
456                 // buffer is full
457                 SREG = intr_state;
458                 return -1;
459         }
460         // actually write the byte into the FIFO
461         UEDATX = c;
462                 // if this completed a packet, transmit it now!
463         if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
464         transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
465         SREG = intr_state;
466         return 0;
467 }
468
469 // transmit a buffer.
470 //  0 returned on success, -1 on error
471 // This function is optimized for speed!  Each call takes approx 6.1 us overhead
472 // plus 0.25 us per byte.  12 Mbit/sec USB has 8.67 us per-packet overhead and
473 // takes 0.67 us per byte.  If called with 64 byte packet-size blocks, this function
474 // can transmit at full USB speed using 43% CPU time.  The maximum theoretical speed
475 // is 19 packets per USB frame, or 1216 kbytes/sec.  However, bulk endpoints have the
476 // lowest priority, so any other USB devices will likely reduce the speed.  Speed
477 // can also be limited by how quickly the PC-based software reads data, as the host
478 // controller in the PC will not allocate bandwitdh without a pending read request.
479 // (thanks to Victor Suarez for testing and feedback and initial code)
480
481 int8_t usb_serial_write(const uint8_t *buffer, uint16_t size)
482 {
483         uint8_t timeout, intr_state, write_size;
484
485         // if we're not online (enumerated and configured), error
486         if (!usb_configuration) return -1;
487         // interrupts are disabled so these functions can be
488         // used from the main program or interrupt context,
489         // even both in the same program!
490         intr_state = SREG;
491         cli();
492         UENUM = CDC_TX_ENDPOINT;
493         // if we gave up due to timeout before, don't wait again
494         if (transmit_previous_timeout) {
495                 if (!(UEINTX & (1<<RWAL))) {
496                         SREG = intr_state;
497                         return -1;
498                 }
499                 transmit_previous_timeout = 0;
500         }
501         // each iteration of this loop transmits a packet
502         while (size) {
503                 // wait for the FIFO to be ready to accept data
504                 timeout = UDFNUML + TRANSMIT_TIMEOUT;
505                 while (1) {
506                         // are we ready to transmit?
507                         if (UEINTX & (1<<RWAL)) break;
508                         SREG = intr_state;
509                         // have we waited too long?  This happens if the user
510                         // is not running an application that is listening
511                         if (UDFNUML == timeout) {
512                                 transmit_previous_timeout = 1;
513                                 return -1;
514                         }
515                         // has the USB gone offline?
516                         if (!usb_configuration) return -1;
517                         // get ready to try checking again
518                         intr_state = SREG;
519                         cli();
520                         UENUM = CDC_TX_ENDPOINT;
521                 }
522
523                 // compute how many bytes will fit into the next packet
524                 write_size = CDC_TX_SIZE - UEBCLX;
525                 if (write_size > size) write_size = size;
526                 size -= write_size;
527
528                 // write the packet
529                 switch (write_size) {
530                         #if (CDC_TX_SIZE == 64)
531                         case 64: UEDATX = *buffer++;
532                         case 63: UEDATX = *buffer++;
533                         case 62: UEDATX = *buffer++;
534                         case 61: UEDATX = *buffer++;
535                         case 60: UEDATX = *buffer++;
536                         case 59: UEDATX = *buffer++;
537                         case 58: UEDATX = *buffer++;
538                         case 57: UEDATX = *buffer++;
539                         case 56: UEDATX = *buffer++;
540                         case 55: UEDATX = *buffer++;
541                         case 54: UEDATX = *buffer++;
542                         case 53: UEDATX = *buffer++;
543                         case 52: UEDATX = *buffer++;
544                         case 51: UEDATX = *buffer++;
545                         case 50: UEDATX = *buffer++;
546                         case 49: UEDATX = *buffer++;
547                         case 48: UEDATX = *buffer++;
548                         case 47: UEDATX = *buffer++;
549                         case 46: UEDATX = *buffer++;
550                         case 45: UEDATX = *buffer++;
551                         case 44: UEDATX = *buffer++;
552                         case 43: UEDATX = *buffer++;
553                         case 42: UEDATX = *buffer++;
554                         case 41: UEDATX = *buffer++;
555                         case 40: UEDATX = *buffer++;
556                         case 39: UEDATX = *buffer++;
557                         case 38: UEDATX = *buffer++;
558                         case 37: UEDATX = *buffer++;
559                         case 36: UEDATX = *buffer++;
560                         case 35: UEDATX = *buffer++;
561                         case 34: UEDATX = *buffer++;
562                         case 33: UEDATX = *buffer++;
563                         #endif
564                         #if (CDC_TX_SIZE >= 32)
565                         case 32: UEDATX = *buffer++;
566                         case 31: UEDATX = *buffer++;
567                         case 30: UEDATX = *buffer++;
568                         case 29: UEDATX = *buffer++;
569                         case 28: UEDATX = *buffer++;
570                         case 27: UEDATX = *buffer++;
571                         case 26: UEDATX = *buffer++;
572                         case 25: UEDATX = *buffer++;
573                         case 24: UEDATX = *buffer++;
574                         case 23: UEDATX = *buffer++;
575                         case 22: UEDATX = *buffer++;
576                         case 21: UEDATX = *buffer++;
577                         case 20: UEDATX = *buffer++;
578                         case 19: UEDATX = *buffer++;
579                         case 18: UEDATX = *buffer++;
580                         case 17: UEDATX = *buffer++;
581                         #endif
582                         #if (CDC_TX_SIZE >= 16)
583                         case 16: UEDATX = *buffer++;
584                         case 15: UEDATX = *buffer++;
585                         case 14: UEDATX = *buffer++;
586                         case 13: UEDATX = *buffer++;
587                         case 12: UEDATX = *buffer++;
588                         case 11: UEDATX = *buffer++;
589                         case 10: UEDATX = *buffer++;
590                         case  9: UEDATX = *buffer++;
591                         #endif
592                         case  8: UEDATX = *buffer++;
593                         case  7: UEDATX = *buffer++;
594                         case  6: UEDATX = *buffer++;
595                         case  5: UEDATX = *buffer++;
596                         case  4: UEDATX = *buffer++;
597                         case  3: UEDATX = *buffer++;
598                         case  2: UEDATX = *buffer++;
599                         default:
600                         case  1: UEDATX = *buffer++;
601                         case  0: break;
602                 }
603                 // if this completed a packet, transmit it now!
604                 if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
605                 transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
606         }
607         SREG = intr_state;
608         return 0;
609 }
610
611
612 // immediately transmit any buffered output.
613 // This doesn't actually transmit the data - that is impossible!
614 // USB devices only transmit when the host allows, so the best
615 // we can do is release the FIFO buffer for when the host wants it
616 void usb_serial_flush_output(void)
617 {
618         uint8_t intr_state;
619
620         intr_state = SREG;
621         cli();
622         if (transmit_flush_timer) {
623                 UENUM = CDC_TX_ENDPOINT;
624                 UEINTX = 0x3A;
625                 transmit_flush_timer = 0;
626         }
627         SREG = intr_state;
628 }
629
630 // functions to read the various async serial settings.  These
631 // aren't actually used by USB at all (communication is always
632 // at full USB speed), but they are set by the host so we can
633 // set them properly if we're converting the USB to a real serial
634 // communication
635 uint32_t usb_serial_get_baud(void)
636 {
637         return *(uint32_t *)cdc_line_coding;
638 }
639 uint8_t usb_serial_get_stopbits(void)
640 {
641         return cdc_line_coding[4];
642 }
643 uint8_t usb_serial_get_paritytype(void)
644 {
645         return cdc_line_coding[5];
646 }
647 uint8_t usb_serial_get_numbits(void)
648 {
649         return cdc_line_coding[6];
650 }
651 uint8_t usb_serial_get_control(void)
652 {
653         return cdc_line_rtsdtr;
654 }
655 // write the control signals, DCD, DSR, RI, etc
656 // There is no CTS signal.  If software on the host has transmitted
657 // data to you but you haven't been calling the getchar function,
658 // it remains buffered (either here or on the host) and can not be
659 // lost because you weren't listening at the right time, like it
660 // would in real serial communication.
661 // TODO: this function is untested.  Does it work?  Please email
662 // paul@pjrc.com if you have tried it....
663 int8_t usb_serial_set_control(uint8_t signals)
664 {
665         uint8_t intr_state;
666
667         intr_state = SREG;
668         cli();
669         if (!usb_configuration) {
670                 // we're not enumerated/configured
671                 SREG = intr_state;
672                 return -1;
673         }
674
675         UENUM = CDC_ACM_ENDPOINT;
676         if (!(UEINTX & (1<<RWAL))) {
677                 // unable to write
678                 // TODO; should this try to abort the previously
679                 // buffered message??
680                 SREG = intr_state;
681                 return -1;
682         }
683         UEDATX = 0xA1;
684         UEDATX = 0x20;
685         UEDATX = 0;
686         UEDATX = 0;
687         UEDATX = 0; // TODO: should this be 1 or 0 ???
688         UEDATX = 0;
689         UEDATX = 2;
690         UEDATX = 0;
691         UEDATX = signals;
692         UEDATX = 0;
693         UEINTX = 0x3A;
694         SREG = intr_state;
695         return 0;
696 }
697
698
699
700 /**************************************************************************
701  *
702  *  Private Functions - not intended for general user consumption....
703  *
704  **************************************************************************/
705
706
707 // USB Device Interrupt - handle all device-level events
708 // the transmit buffer flushing is triggered by the start of frame
709 //
710 ISR(USB_GEN_vect)
711 {
712         uint8_t intbits, t;
713
714         intbits = UDINT;
715         UDINT = 0;
716         if (intbits & (1<<EORSTI)) {
717                 UENUM = 0;
718                 UECONX = 1;
719                 UECFG0X = EP_TYPE_CONTROL;
720                 UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
721                 UEIENX = (1<<RXSTPE);
722                 usb_configuration = 0;
723                 cdc_line_rtsdtr = 0;
724         }
725         if (intbits & (1<<SOFI)) {
726                 if (usb_configuration) {
727                         t = transmit_flush_timer;
728                         if (t) {
729                                 transmit_flush_timer = --t;
730                                 if (!t) {
731                                         UENUM = CDC_TX_ENDPOINT;
732                                         UEINTX = 0x3A;
733                                 }
734                         }
735                 }
736         }
737 }
738
739
740 // Misc functions to wait for ready and send/receive packets
741 static inline void usb_wait_in_ready(void)
742 {
743         while (!(UEINTX & (1<<TXINI))) ;
744 }
745 static inline void usb_send_in(void)
746 {
747         UEINTX = ~(1<<TXINI);
748 }
749 static inline void usb_wait_receive_out(void)
750 {
751         while (!(UEINTX & (1<<RXOUTI))) ;
752 }
753 static inline void usb_ack_out(void)
754 {
755         UEINTX = ~(1<<RXOUTI);
756 }
757
758
759
760 // USB Endpoint Interrupt - endpoint 0 is handled here.  The
761 // other endpoints are manipulated by the user-callable
762 // functions, and the start-of-frame interrupt.
763 //
764 ISR(USB_COM_vect)
765 {
766         uint8_t intbits;
767         const uint8_t *list;
768         const uint8_t *cfg;
769         uint8_t i, n, len, en;
770         uint8_t *p;
771         uint8_t bmRequestType;
772         uint8_t bRequest;
773         uint16_t wValue;
774         uint16_t wIndex;
775         uint16_t wLength;
776         uint16_t desc_val;
777         const uint8_t *desc_addr;
778         uint8_t desc_length;
779
780         UENUM = 0;
781         intbits = UEINTX;
782         if (intbits & (1<<RXSTPI)) {
783                 bmRequestType = UEDATX;
784                 bRequest = UEDATX;
785                 wValue = UEDATX;
786                 wValue |= (UEDATX << 8);
787                 wIndex = UEDATX;
788                 wIndex |= (UEDATX << 8);
789                 wLength = UEDATX;
790                 wLength |= (UEDATX << 8);
791                 UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
792                 if (bRequest == GET_DESCRIPTOR) {
793                         list = (const uint8_t *)descriptor_list;
794                         for (i=0; ; i++) {
795                                 if (i >= NUM_DESC_LIST) {
796                                         UECONX = (1<<STALLRQ)|(1<<EPEN);  //stall
797                                         return;
798                                 }
799                                 desc_val = pgm_read_word(list);
800                                 if (desc_val != wValue) {
801                                         list += sizeof(struct descriptor_list_struct);
802                                         continue;
803                                 }
804                                 list += 2;
805                                 desc_val = pgm_read_word(list);
806                                 if (desc_val != wIndex) {
807                                         list += sizeof(struct descriptor_list_struct)-2;
808                                         continue;
809                                 }
810                                 list += 2;
811                                 desc_addr = (const uint8_t *)pgm_read_word(list);
812                                 list += 2;
813                                 desc_length = pgm_read_byte(list);
814                                 break;
815                         }
816                         len = (wLength < 256) ? wLength : 255;
817                         if (len > desc_length) len = desc_length;
818                         do {
819                                 // wait for host ready for IN packet
820                                 do {
821                                         i = UEINTX;
822                                 } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
823                                 if (i & (1<<RXOUTI)) return;    // abort
824                                 // send IN packet
825                                 n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
826                                 for (i = n; i; i--) {
827                                         UEDATX = pgm_read_byte(desc_addr++);
828                                 }
829                                 len -= n;
830                                 usb_send_in();
831                         } while (len || n == ENDPOINT0_SIZE);
832                         return;
833                 }
834                 if (bRequest == SET_ADDRESS) {
835                         usb_send_in();
836                         usb_wait_in_ready();
837                         UDADDR = wValue | (1<<ADDEN);
838                         return;
839                 }
840                 if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
841                         usb_configuration = wValue;
842                         cdc_line_rtsdtr = 0;
843                         transmit_flush_timer = 0;
844                         usb_send_in();
845                         cfg = endpoint_config_table;
846                         for (i=1; i<5; i++) {
847                                 UENUM = i;
848                                 en = pgm_read_byte(cfg++);
849                                 UECONX = en;
850                                 if (en) {
851                                         UECFG0X = pgm_read_byte(cfg++);
852                                         UECFG1X = pgm_read_byte(cfg++);
853                                 }
854                         }
855                         UERST = 0x1E;
856                         UERST = 0;
857                         return;
858                 }
859                 if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
860                         usb_wait_in_ready();
861                         UEDATX = usb_configuration;
862                         usb_send_in();
863                         return;
864                 }
865                 if (bRequest == CDC_GET_LINE_CODING && bmRequestType == 0xA1) {
866                         usb_wait_in_ready();
867                         p = cdc_line_coding;
868                         for (i=0; i<7; i++) {
869                                 UEDATX = *p++;
870                         }
871                         usb_send_in();
872                         return;
873                 }
874                 if (bRequest == CDC_SET_LINE_CODING && bmRequestType == 0x21) {
875                         usb_wait_receive_out();
876                         p = cdc_line_coding;
877                         for (i=0; i<7; i++) {
878                                 *p++ = UEDATX;
879                         }
880                         usb_ack_out();
881                         usb_send_in();
882                         return;
883                 }
884                 if (bRequest == CDC_SET_CONTROL_LINE_STATE && bmRequestType == 0x21) {
885                         cdc_line_rtsdtr = wValue;
886                         usb_wait_in_ready();
887                         usb_send_in();
888                         return;
889                 }
890                 if (bRequest == GET_STATUS) {
891                         usb_wait_in_ready();
892                         i = 0;
893                         #ifdef SUPPORT_ENDPOINT_HALT
894                         if (bmRequestType == 0x82) {
895                                 UENUM = wIndex;
896                                 if (UECONX & (1<<STALLRQ)) i = 1;
897                                 UENUM = 0;
898                         }
899                         #endif
900                         UEDATX = i;
901                         UEDATX = 0;
902                         usb_send_in();
903                         return;
904                 }
905                 #ifdef SUPPORT_ENDPOINT_HALT
906                 if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
907                   && bmRequestType == 0x02 && wValue == 0) {
908                         i = wIndex & 0x7F;
909                         if (i >= 1 && i <= MAX_ENDPOINT) {
910                                 usb_send_in();
911                                 UENUM = i;
912                                 if (bRequest == SET_FEATURE) {
913                                         UECONX = (1<<STALLRQ)|(1<<EPEN);
914                                 } else {
915                                         UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
916                                         UERST = (1 << i);
917                                         UERST = 0;
918                                 }
919                                 return;
920                         }
921                 }
922                 #endif
923         }
924         UECONX = (1<<STALLRQ) | (1<<EPEN);      // stall
925 }
926
927