├── LICENSE ├── Makefile ├── README.md ├── debugdev.c ├── uart.c ├── uart.h ├── usb_debug.c └── usb_debug.h /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "[]" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright [yyyy] [name of copyright owner] 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avivgr/teensy_debugdev/293a5ffc5fcc2be34ac23cb37bb0cb4d7b6e0fe1/Makefile -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | teensy_debugdev 2 | =============== 3 | 4 | USB 2.0 Debug cable using teensy 5 | 6 | * What is a USB 2.0 Debug Device and what is it used for? 7 | 8 | A usb debug device can be used to debug a remote machine through a usb port. 9 | For debugging linux search for the kgdbdbgp or earlyprintk=dbgp kernel parameters. 10 | For using WinDbg and Windows see this guide at http://blogs.msdn.com/b/usbcoreblog/archive/2010/10/25/setting-up-kernel-debugging-with-usb-2-0.aspx 11 | 12 | There are existing commercial debug devices for sale, but they cost ~100USD :( this project is aimed to be a DIY replacement using Teensy 2.0. 13 | 14 | * What is Teensy ? 15 | 16 | http://www.pjrc.com/store/teensy.html Teensy 2.0 is a tiny USB Development Board based on ATMEGA32U4 8 bit AVR 16 MHz chip. 17 | It costs only 16 USD and its a lot of fun to play with. Check out the cool projects using Teensy! 18 | 19 | Some useful links related to USB 2.0 debug device: 20 | * http://www.usb.org/developers/presentations/pres0602/john_keys.pdf - this is a ppt explaining usb debug 21 | * google usb2 debug device specification - there is a PDF that describes the USB descriptor requirements for implementing debug device. 22 | * http://lxr.linux.no/linux+v3.11/drivers/usb/early/ehci-dbgp.c - simple code for programming ehci for debug + using debug device for kgdb 23 | * http://lxr.linux.no/linux+v3.11/drivers/usb/serial/usb_debug.c - for using debug as serial, early printk etc 24 | * http://www.pjrc.com/teensy/td_uart.html - project that show how to connect serial to teensy. but - he uses a max chip, i use a TTL cable, much less complicated. 25 | * http://www.coreboot.org/EHCI_Debug_Port - great info, especially the DYI section, includes some FW code. Inspiring! 26 | 27 | Possible hardware configirations: 28 | 29 | 1) USB<->Serial : On the debugee machine, connect teensy to the USB debug port. Then connect teensy through its i/o pins, using serial, to the debugger machine. However, You need to convert the serial signals from Teensy (TTL) to something the remote PC could consume. I use a PL2303HX based TTL Converter Cable that cost 5 USD on eBay (cheaper than 100 USD, right?) [picture that shows how i soldered the pins to connect to the TTL converter]. I used RX/TX and GND (found no need for VSS) 30 | 31 | 2) USB<->USB : you will need 2 Teensy devices for this. Connect the 2 teensy devices through their i/o pins (serial, cross link). 32 | 33 | 34 | ----------------------- 35 | 36 | Current code status: 37 | * debug device is recognized and configured by the OS 38 | * i can send and receive data over the debug device 39 | * i could not actually use a debugger using it yet. WIP, so please patience (or contribute code) :) 40 | -------------------------------------------------------------------------------- /debugdev.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "uart.h" 8 | #include "usb_debug.h" 9 | 10 | #define BAUD_RATE 38400 11 | #define LED_CONFIG (DDRD |= (1<<6)) 12 | #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) 13 | 14 | // write a string to the uart 15 | #define uart_print(s) uart_print_P(PSTR(s)) 16 | void uart_print_P(const char *str) 17 | { 18 | char c; 19 | while (1) { 20 | c = pgm_read_byte(str++); 21 | if (!c) break; 22 | uart_putchar(c); 23 | } 24 | } 25 | 26 | // A very basic example... 27 | // when the user types a character, print it back 28 | int main(void) 29 | { 30 | uint8_t c; 31 | uint32_t cnt = 0; 32 | 33 | CPU_PRESCALE(0); // run at 16 MHz 34 | LED_CONFIG; 35 | // Initialize the USB, and then wait for the host to set configuration. 36 | // If the Teensy is powered without a PC connected to the USB port, 37 | // this will wait forever. 38 | usb_init(); 39 | //while (!usb_configured()) /* wait */ ; 40 | 41 | uart_init(BAUD_RATE); 42 | 43 | // Wait an extra second for the PC's operating system to load drivers 44 | // and do whatever it does to actually be ready for input 45 | _delay_ms(1000); 46 | 47 | while (1) { 48 | /* BUGBUG : need to read/write in chunks and not char at a time */ 49 | if (uart_available()) { 50 | c = uart_getchar(); 51 | usb_putchar(c); 52 | } 53 | if(usb_available()) { 54 | c = usb_getchar(); 55 | uart_putchar(c); 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /uart.c: -------------------------------------------------------------------------------- 1 | /* UART Example for Teensy USB Development Board 2 | * http://www.pjrc.com/teensy/ 3 | * Copyright (c) 2009 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: Add support for Teensy 2.0, minor optimizations 26 | 27 | 28 | #include 29 | #include 30 | 31 | #include "uart.h" 32 | 33 | // These buffers may be any size from 2 to 256 bytes. 34 | #define RX_BUFFER_SIZE 128 35 | #define TX_BUFFER_SIZE 128 36 | 37 | static volatile uint8_t tx_buffer[TX_BUFFER_SIZE]; 38 | static volatile uint8_t tx_buffer_head; 39 | static volatile uint8_t tx_buffer_tail; 40 | static volatile uint8_t rx_buffer[RX_BUFFER_SIZE]; 41 | static volatile uint8_t rx_buffer_head; 42 | static volatile uint8_t rx_buffer_tail; 43 | 44 | // Initialize the UART 45 | void uart_init(uint32_t baud) 46 | { 47 | cli(); 48 | UBRR1 = (F_CPU / 4 / baud - 1) / 2; 49 | UCSR1A = (1<= TX_BUFFER_SIZE) i = 0; 64 | while (tx_buffer_tail == i) ; // wait until space in buffer 65 | //cli(); 66 | tx_buffer[i] = c; 67 | tx_buffer_head = i; 68 | UCSR1B = (1<= RX_BUFFER_SIZE) i = 0; 80 | c = rx_buffer[i]; 81 | rx_buffer_tail = i; 82 | return c; 83 | } 84 | 85 | // Return the number of bytes waiting in the receive buffer. 86 | // Call this before uart_getchar() to check if it will need 87 | // to wait for a byte to arrive. 88 | uint8_t uart_available(void) 89 | { 90 | uint8_t head, tail; 91 | 92 | head = rx_buffer_head; 93 | tail = rx_buffer_tail; 94 | if (head >= tail) return head - tail; 95 | return RX_BUFFER_SIZE + head - tail; 96 | } 97 | 98 | // Transmit Interrupt 99 | ISR(USART1_UDRE_vect) 100 | { 101 | uint8_t i; 102 | 103 | if (tx_buffer_head == tx_buffer_tail) { 104 | // buffer is empty, disable transmit interrupt 105 | UCSR1B = (1<= TX_BUFFER_SIZE) i = 0; 109 | UDR1 = tx_buffer[i]; 110 | tx_buffer_tail = i; 111 | } 112 | } 113 | 114 | // Receive Interrupt 115 | ISR(USART1_RX_vect) 116 | { 117 | uint8_t c, i; 118 | 119 | c = UDR1; 120 | i = rx_buffer_head + 1; 121 | if (i >= RX_BUFFER_SIZE) i = 0; 122 | if (i != rx_buffer_tail) { 123 | rx_buffer[i] = c; 124 | rx_buffer_head = i; 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /uart.h: -------------------------------------------------------------------------------- 1 | #ifndef _uart_included_h_ 2 | #define _uart_included_h_ 3 | 4 | #include 5 | 6 | void uart_init(uint32_t baud); 7 | void uart_putchar(uint8_t c); 8 | uint8_t uart_getchar(void); 9 | uint8_t uart_available(void); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /usb_debug.c: -------------------------------------------------------------------------------- 1 | /* USB Keyboard Example for Teensy USB Development Board 2 | * http://www.pjrc.com/teensy/usb_keyboard.html 3 | * Copyright (c) 2009 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: Add support for Teensy 2.0 26 | 27 | #define USB_SERIAL_PRIVATE_INCLUDE 28 | #include "usb_debug.h" 29 | 30 | #define LED_CONFIG (DDRD |= (1<<6)) 31 | #define LED_ON (PORTD &= ~(1<<6)) 32 | #define LED_OFF (PORTD |= (1<<6)) 33 | /************************************************************************** 34 | * 35 | * Configurable Options 36 | * 37 | **************************************************************************/ 38 | 39 | // You can change these to give your code its own name. 40 | #define STR_MANUFACTURER L"Manufacturer" 41 | #define STR_PRODUCT L"USB 2.0 Debug Cable" 42 | #define STR_SERIAL L"002" 43 | 44 | /* These are recognized by all major OSs as debug device */ 45 | #define VENDOR_ID 0x0525 46 | #define PRODUCT_ID 0x127a 47 | 48 | 49 | // USB devices are supposed to implment a halt feature, which is 50 | // rarely (if ever) used. If you comment this line out, the halt 51 | // code will be removed, saving 102 bytes of space (gcc 4.3.0). 52 | // This is not strictly USB compliant, but works with all major 53 | // operating systems. 54 | #define SUPPORT_ENDPOINT_HALT 55 | 56 | 57 | 58 | /************************************************************************** 59 | * 60 | * Endpoint Buffer Configuration 61 | * 62 | **************************************************************************/ 63 | 64 | #define ENDPOINT0_SIZE 64 65 | 66 | #define USB_DEBUG_INTERFACE 0 67 | 68 | 69 | #define DEBUG_RX_ENDPOINT 3 70 | #define DEBUG_RX_SIZE 32 71 | #define DEBUG_RX_BUFFER EP_DOUBLE_BUFFER 72 | 73 | #define DEBUG_TX_ENDPOINT 2 74 | #define DEBUG_TX_SIZE 64 75 | #define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER 76 | 77 | static const uint8_t PROGMEM endpoint_config_table[] = { 78 | 0, 79 | 1, EP_TYPE_BULK_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, 80 | 1, EP_TYPE_BULK_OUT, EP_SIZE(DEBUG_RX_SIZE) | DEBUG_RX_BUFFER, 81 | 0 82 | }; 83 | static volatile uint8_t transmit_flush_timer=0; 84 | static uint8_t transmit_previous_timeout=0; 85 | #define TRANSMIT_FLUSH_TIMEOUT 5 86 | #define TRANSMIT_TIMEOUT 25 /* in milliseconds */ 87 | 88 | /************************************************************************** 89 | * 90 | * Descriptor Data 91 | * 92 | **************************************************************************/ 93 | 94 | // Descriptors are the data that your computer reads when it auto-detects 95 | // this USB device (called "enumeration" in USB lingo). The most commonly 96 | // changed items are editable at the top of this file. Changing things 97 | // in here should only be done by those who've read chapter 9 of the USB 98 | // spec and relevant portions of any USB class specifications! 99 | 100 | 101 | static uint8_t PROGMEM device_descriptor[] = { 102 | 18, // bLength 103 | 1, // bDescriptorType 104 | 0x00, 0x02, // bcdUSB 105 | 255, // bDeviceClass 106 | 0, // bDeviceSubClass 107 | 0, // bDeviceProtocol 108 | ENDPOINT0_SIZE, // bMaxPacketSize0 109 | LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor 110 | LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct 111 | 0x01, 0x01, // bcdDevice 112 | 1, // iManufacturer 113 | 2, // iProduct 114 | 3, // iSerialNumber 115 | 1 // bNumConfigurations 116 | }; 117 | 118 | static uint8_t PROGMEM device_qualifier_desc[] = { 119 | 10, //bLength 120 | 6, //bDescriptorType 121 | 0x00, 0x02, // bcdUSB 122 | 255, //bDeviceClass Vendor Specific Class 123 | 0, //bDeviceSubClass 124 | 0, //bDeviceProtocol 125 | ENDPOINT0_SIZE, //bMaxPacketSize0 126 | 1, //bNumConfigurations 127 | 0 128 | }; 129 | 130 | // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 131 | static uint8_t PROGMEM debug_desc[] = { 132 | 4, // bLength 133 | 10, // bDescriptorType 134 | DEBUG_TX_ENDPOINT | 0x80, // bDebugInEndpoint 135 | DEBUG_RX_ENDPOINT // bDebugOutEndpoint 136 | }; 137 | 138 | #define CONFIG1_DESC_SIZE (9+9+7+7) 139 | #define USB_DEBUG_DESC_OFFSET (9+9) 140 | static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { 141 | // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 142 | 9, // bLength; 143 | 2, // bDescriptorType; 144 | LSB(CONFIG1_DESC_SIZE), // wTotalLength 145 | MSB(CONFIG1_DESC_SIZE), 146 | 1, // bNumInterfaces 147 | 1, // bConfigurationValue 148 | 0, // iConfiguration 149 | 0xA0, // bmAttributes 150 | 50, // bMaxPower 151 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 152 | 9, // bLength 153 | 4, // bDescriptorType 154 | USB_DEBUG_INTERFACE,// bInterfaceNumber 155 | 0, // bAlternateSetting 156 | 2, // bNumEndpoints 157 | 0xff, // bInterfaceClass (0x03 = HID) 158 | 0x00, // bInterfaceSubClass (0x01 = Boot) 159 | 0x00, // bInterfaceProtocol (0x01 = Keyboard) 160 | 0, // iInterface 161 | // Endpoint 1 162 | 7, // bLength 163 | 5, // bDescriptorType 164 | DEBUG_RX_ENDPOINT, // bEndpointAddress 165 | 2, // bmAttributes 166 | DEBUG_RX_SIZE,0x00,// wMaxPacketSize 167 | 0, // bInterval 168 | // Endpoint 2 169 | 7, // bLength 170 | 5, // bDescriptorType 171 | DEBUG_TX_ENDPOINT | 0x80,// bEndpointAddress 172 | 2, // bmAttributes 173 | DEBUG_TX_SIZE,0x00, // wMaxPacketSize 174 | 0 // bInterval 175 | }; 176 | 177 | static uint8_t PROGMEM other_speed_descriptor[9] = { 178 | // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 179 | 9, // bLength; 180 | 7, // bDescriptorType; 181 | 9,0, // wTotalLength 182 | 1, // bNumInterfaces 183 | 1, // bConfigurationValue 184 | 0, // iConfiguration 185 | 0xA0, // bmAttributes 186 | 50, // bMaxPower 187 | }; 188 | // If you're desperate for a little extra code memory, these strings 189 | // can be completely removed if iManufacturer, iProduct, iSerialNumber 190 | // in the device desciptor are changed to zeros. 191 | struct usb_string_descriptor_struct { 192 | uint8_t bLength; 193 | uint8_t bDescriptorType; 194 | int16_t wString[]; 195 | }; 196 | static struct usb_string_descriptor_struct PROGMEM string0 = { 197 | 4, 198 | 3, 199 | {0x0409} 200 | }; 201 | static struct usb_string_descriptor_struct PROGMEM string1 = { 202 | sizeof(STR_MANUFACTURER), 203 | 3, 204 | STR_MANUFACTURER 205 | }; 206 | static struct usb_string_descriptor_struct PROGMEM string2 = { 207 | sizeof(STR_PRODUCT), 208 | 3, 209 | STR_PRODUCT 210 | }; 211 | static struct usb_string_descriptor_struct PROGMEM string3 = { 212 | sizeof(STR_SERIAL), 213 | 3, 214 | STR_SERIAL 215 | }; 216 | 217 | // This table defines which descriptor data is sent for each specific 218 | // request from the host (in wValue and wIndex). 219 | static struct descriptor_list_struct { 220 | uint16_t wValue; 221 | uint16_t wIndex; 222 | const uint8_t *addr; 223 | uint8_t length; 224 | } PROGMEM descriptor_list[] = { 225 | {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, 226 | {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, 227 | {0x0700, 0x0000, other_speed_descriptor, sizeof(other_speed_descriptor)}, 228 | {0x0A00, 0x0000, debug_desc, sizeof(debug_desc)}, 229 | {0x0600, 0x0000, device_qualifier_desc, sizeof(device_qualifier_desc)}, 230 | {0x0300, 0x0000, (const uint8_t *)&string0, 4}, 231 | {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, 232 | {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}, 233 | {0x0303, 0x0409, (const uint8_t *)&string3, sizeof(STR_SERIAL)} 234 | }; 235 | #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct)) 236 | 237 | 238 | /************************************************************************** 239 | * 240 | * Variables - these are the only non-stack RAM usage 241 | * 242 | **************************************************************************/ 243 | 244 | // zero when we are not configured, non-zero when enumerated 245 | static volatile uint8_t usb_configuration=0; 246 | 247 | 248 | /************************************************************************** 249 | * 250 | * Public Functions - these are the API intended for the user 251 | * 252 | **************************************************************************/ 253 | 254 | 255 | // initialize USB 256 | void usb_init(void) 257 | { 258 | HW_CONFIG(); 259 | USB_FREEZE(); // enable USB 260 | PLL_CONFIG(); // config PLL 261 | while (!(PLLCSR & (1<= NUM_DESC_LIST) { 499 | UECONX = (1< desc_length) len = desc_length; 521 | do { 522 | // wait for host ready for IN packet 523 | do { 524 | i = UEINTX; 525 | } while (!(i & ((1<= 1 && i <= MAX_ENDPOINT) { 608 | usb_send_in(); 609 | UENUM = i; 610 | if (bRequest == SET_FEATURE) { 611 | UECONX = (1<> 8); 662 | keyboard_idle_count = 0; 663 | usb_send_in(); 664 | return; 665 | } 666 | if (bRequest == HID_SET_PROTOCOL) { 667 | keyboard_protocol = wValue; 668 | usb_send_in(); 669 | return; 670 | } 671 | 672 | } 673 | #endif 674 | 675 | } 676 | 677 | } 678 | UECONX = (1< 5 | 6 | void usb_init(void); // initialize everything 7 | uint8_t usb_configured(void); // is the USB port configured 8 | int8_t usb_putchar_nowait(uint8_t c); 9 | int8_t usb_putchar(uint8_t c); 10 | uint8_t usb_available(void); 11 | uint8_t usb_getchar(void); 12 | 13 | // This file does not include the HID debug functions, so these empty 14 | // macros replace them with nothing, so users can compile code that 15 | // has calls to these functions. 16 | #define usb_debug_putchar(c) 17 | #define usb_debug_flush_output() 18 | 19 | // Everything below this point is only intended for usb_serial.c 20 | #ifdef USB_SERIAL_PRIVATE_INCLUDE 21 | #include 22 | #include 23 | #include 24 | 25 | #define EP_TYPE_CONTROL 0x00 26 | #define EP_TYPE_BULK_IN 0x81 27 | #define EP_TYPE_BULK_OUT 0x80 28 | #define EP_TYPE_INTERRUPT_IN 0xC1 29 | #define EP_TYPE_INTERRUPT_OUT 0xC0 30 | #define EP_TYPE_ISOCHRONOUS_IN 0x41 31 | #define EP_TYPE_ISOCHRONOUS_OUT 0x40 32 | 33 | #define EP_SINGLE_BUFFER 0x02 34 | #define EP_DOUBLE_BUFFER 0x06 35 | 36 | #define EP_SIZE(s) ((s) == 64 ? 0x30 : \ 37 | ((s) == 32 ? 0x20 : \ 38 | ((s) == 16 ? 0x10 : \ 39 | 0x00))) 40 | 41 | #define MAX_ENDPOINT 4 42 | 43 | #define LSB(n) (n & 255) 44 | #define MSB(n) ((n >> 8) & 255) 45 | 46 | #if defined(__AVR_AT90USB162__) 47 | #define HW_CONFIG() 48 | #define PLL_CONFIG() (PLLCSR = ((1<