view usb_serial.c @ 8:1969a435a7a2

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