1 /* USB Keyboard Plus Debug Channel Example for Teensy USB Development Board
2 * http://www.pjrc.com/teensy/usb_keyboard.html
3 * Copyright (c) 2009 PJRC.COM, LLC
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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
24 // Version 1.0: Initial Release
25 // Version 1.1: Add support for Teensy 2.0
27 #define USB_SERIAL_PRIVATE_INCLUDE
28 #include "usb_keyboard_debug.h"
30 /**************************************************************************
32 * Configurable Options
34 **************************************************************************/
36 // You can change these to give your code its own name.
37 #define STR_MANUFACTURER L"MfgName"
38 #define STR_PRODUCT L"Keyboard"
41 // Mac OS-X and Linux automatically load the correct drivers. On
42 // Windows, even though the driver is supplied by Microsoft, an
43 // INF file is needed to load the driver. These numbers need to
44 // match the INF file.
45 #define VENDOR_ID 0x16C0
46 #define PRODUCT_ID 0x047D
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
54 #define SUPPORT_ENDPOINT_HALT
58 /**************************************************************************
60 * Endpoint Buffer Configuration
62 **************************************************************************/
64 #define ENDPOINT0_SIZE 32
66 #define KEYBOARD_INTERFACE 0
67 #define KEYBOARD_ENDPOINT 3
68 #define KEYBOARD_SIZE 8
69 #define KEYBOARD_BUFFER EP_DOUBLE_BUFFER
71 #define DEBUG_INTERFACE 1
72 #define DEBUG_TX_ENDPOINT 4
73 #define DEBUG_TX_SIZE 32
74 #define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER
76 static const uint8_t PROGMEM endpoint_config_table[] = {
79 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
80 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER
84 /**************************************************************************
88 **************************************************************************/
90 // Descriptors are the data that your computer reads when it auto-detects
91 // this USB device (called "enumeration" in USB lingo). The most commonly
92 // changed items are editable at the top of this file. Changing things
93 // in here should only be done by those who've read chapter 9 of the USB
94 // spec and relevant portions of any USB class specifications!
97 static uint8_t PROGMEM device_descriptor[] = {
100 0x00, 0x02, // bcdUSB
102 0, // bDeviceSubClass
103 0, // bDeviceProtocol
104 ENDPOINT0_SIZE, // bMaxPacketSize0
105 LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
106 LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
107 0x00, 0x01, // bcdDevice
111 1 // bNumConfigurations
114 // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
115 static uint8_t PROGMEM keyboard_hid_report_desc[] = {
116 0x05, 0x01, // Usage Page (Generic Desktop),
117 0x09, 0x06, // Usage (Keyboard),
118 0xA1, 0x01, // Collection (Application),
119 0x75, 0x01, // Report Size (1),
120 0x95, 0x08, // Report Count (8),
121 0x05, 0x07, // Usage Page (Key Codes),
122 0x19, 0xE0, // Usage Minimum (224),
123 0x29, 0xE7, // Usage Maximum (231),
124 0x15, 0x00, // Logical Minimum (0),
125 0x25, 0x01, // Logical Maximum (1),
126 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
127 0x95, 0x01, // Report Count (1),
128 0x75, 0x08, // Report Size (8),
129 0x81, 0x03, // Input (Constant), ;Reserved byte
130 0x95, 0x05, // Report Count (5),
131 0x75, 0x01, // Report Size (1),
132 0x05, 0x08, // Usage Page (LEDs),
133 0x19, 0x01, // Usage Minimum (1),
134 0x29, 0x05, // Usage Maximum (5),
135 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
136 0x95, 0x01, // Report Count (1),
137 0x75, 0x03, // Report Size (3),
138 0x91, 0x03, // Output (Constant), ;LED report padding
139 0x95, 0x06, // Report Count (6),
140 0x75, 0x08, // Report Size (8),
141 0x15, 0x00, // Logical Minimum (0),
142 0x25, 0x68, // Logical Maximum(104),
143 0x05, 0x07, // Usage Page (Key Codes),
144 0x19, 0x00, // Usage Minimum (0),
145 0x29, 0x68, // Usage Maximum (104),
146 0x81, 0x00, // Input (Data, Array),
147 0xc0 // End Collection
150 static uint8_t PROGMEM debug_hid_report_desc[] = {
151 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
152 0x09, 0x74, // Usage 0x74
153 0xA1, 0x53, // Collection 0x53
154 0x75, 0x08, // report size = 8 bits
155 0x15, 0x00, // logical minimum = 0
156 0x26, 0xFF, 0x00, // logical maximum = 255
157 0x95, DEBUG_TX_SIZE, // report count
159 0x81, 0x02, // Input (array)
160 0xC0 // end collection
163 #define CONFIG1_DESC_SIZE (9+9+9+7+9+9+7)
164 #define KEYBOARD_HID_DESC_OFFSET (9+9)
165 #define DEBUG_HID_DESC_OFFSET (9+9+9+7+9)
166 static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
167 // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
169 2, // bDescriptorType;
170 LSB(CONFIG1_DESC_SIZE), // wTotalLength
171 MSB(CONFIG1_DESC_SIZE),
173 1, // bConfigurationValue
175 0xC0, // bmAttributes
177 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
179 4, // bDescriptorType
180 KEYBOARD_INTERFACE, // bInterfaceNumber
181 0, // bAlternateSetting
183 0x03, // bInterfaceClass (0x03 = HID)
184 0x01, // bInterfaceSubClass (0x01 = Boot)
185 0x01, // bInterfaceProtocol (0x01 = Keyboard)
187 // HID interface descriptor, HID 1.11 spec, section 6.2.1
189 0x21, // bDescriptorType
190 0x11, 0x01, // bcdHID
192 1, // bNumDescriptors
193 0x22, // bDescriptorType
194 sizeof(keyboard_hid_report_desc), // wDescriptorLength
196 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
198 5, // bDescriptorType
199 KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress
200 0x03, // bmAttributes (0x03=intr)
201 KEYBOARD_SIZE, 0, // wMaxPacketSize
203 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
205 4, // bDescriptorType
206 DEBUG_INTERFACE, // bInterfaceNumber
207 0, // bAlternateSetting
209 0x03, // bInterfaceClass (0x03 = HID)
210 0x00, // bInterfaceSubClass
211 0x00, // bInterfaceProtocol
213 // HID interface descriptor, HID 1.11 spec, section 6.2.1
215 0x21, // bDescriptorType
216 0x11, 0x01, // bcdHID
218 1, // bNumDescriptors
219 0x22, // bDescriptorType
220 sizeof(debug_hid_report_desc), // wDescriptorLength
222 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
224 5, // bDescriptorType
225 DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress
226 0x03, // bmAttributes (0x03=intr)
227 DEBUG_TX_SIZE, 0, // wMaxPacketSize
231 // If you're desperate for a little extra code memory, these strings
232 // can be completely removed if iManufacturer, iProduct, iSerialNumber
233 // in the device desciptor are changed to zeros.
234 struct usb_string_descriptor_struct {
236 uint8_t bDescriptorType;
239 static struct usb_string_descriptor_struct PROGMEM string0 = {
244 static struct usb_string_descriptor_struct PROGMEM string1 = {
245 sizeof(STR_MANUFACTURER),
249 static struct usb_string_descriptor_struct PROGMEM string2 = {
255 // This table defines which descriptor data is sent for each specific
256 // request from the host (in wValue and wIndex).
257 static struct descriptor_list_struct {
262 } PROGMEM descriptor_list[] = {
263 {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
264 {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
265 {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
266 {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
267 {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
268 {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
269 {0x0300, 0x0000, (const uint8_t *)&string0, 4},
270 {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
271 {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
273 #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
276 /**************************************************************************
278 * Variables - these are the only non-stack RAM usage
280 **************************************************************************/
282 // zero when we are not configured, non-zero when enumerated
283 static volatile uint8_t usb_configuration=0;
285 // the time remaining before we transmit any partially full
286 // packet, or send a zero length packet.
287 static volatile uint8_t debug_flush_timer=0;
289 // which modifier keys are currently pressed
290 // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui
291 // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
292 uint8_t keyboard_modifier_keys=0;
294 // which keys are currently pressed, up to 6 keys may be down at once
295 uint8_t keyboard_keys[6]={0,0,0,0,0,0};
297 // protocol setting from the host. We use exactly the same report
298 // either way, so this variable only stores the setting since we
299 // are required to be able to report which setting is in use.
300 static uint8_t keyboard_protocol=1;
302 // the idle configuration, how often we send the report to the
303 // host (ms * 4) even when it hasn't changed
304 static uint8_t keyboard_idle_config=125;
306 // count until idle timeout
307 static uint8_t keyboard_idle_count=0;
309 // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
310 volatile uint8_t keyboard_leds=0;
313 /**************************************************************************
315 * Public Functions - these are the API intended for the user
317 **************************************************************************/
324 USB_FREEZE(); // enable USB
325 PLL_CONFIG(); // config PLL
326 while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
327 USB_CONFIG(); // start USB clock
328 UDCON = 0; // enable attach resistor
329 usb_configuration = 0;
330 UDIEN = (1<<EORSTE)|(1<<SOFE);
334 // return 0 if the USB is not configured, or the configuration
335 // number selected by the HOST
336 uint8_t usb_configured(void)
338 return usb_configuration;
342 // perform a single keystroke
343 int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
347 keyboard_modifier_keys = modifier;
348 keyboard_keys[0] = key;
349 r = usb_keyboard_send();
351 keyboard_modifier_keys = 0;
352 keyboard_keys[0] = 0;
353 return usb_keyboard_send();
356 // send the contents of keyboard_keys and keyboard_modifier_keys
357 int8_t usb_keyboard_send(void)
359 uint8_t i, intr_state, timeout;
361 if (!usb_configuration) return -1;
364 UENUM = KEYBOARD_ENDPOINT;
365 timeout = UDFNUML + 50;
367 // are we ready to transmit?
368 if (UEINTX & (1<<RWAL)) break;
370 // has the USB gone offline?
371 if (!usb_configuration) return -1;
372 // have we waited too long?
373 if (UDFNUML == timeout) return -1;
374 // get ready to try checking again
377 UENUM = KEYBOARD_ENDPOINT;
379 UEDATX = keyboard_modifier_keys;
381 for (i=0; i<6; i++) {
382 UEDATX = keyboard_keys[i];
385 keyboard_idle_count = 0;
390 // transmit a character. 0 returned on success, -1 on error
391 int8_t usb_debug_putchar(uint8_t c)
393 static uint8_t previous_timeout=0;
394 uint8_t timeout, intr_state;
396 // if we're not online (enumerated and configured), error
397 if (!usb_configuration) return -1;
398 // interrupts are disabled so these functions can be
399 // used from the main program or interrupt context,
400 // even both in the same program!
403 UENUM = DEBUG_TX_ENDPOINT;
404 // if we gave up due to timeout before, don't wait again
405 if (previous_timeout) {
406 if (!(UEINTX & (1<<RWAL))) {
410 previous_timeout = 0;
412 // wait for the FIFO to be ready to accept data
413 timeout = UDFNUML + 4;
415 // are we ready to transmit?
416 if (UEINTX & (1<<RWAL)) break;
418 // have we waited too long?
419 if (UDFNUML == timeout) {
420 previous_timeout = 1;
423 // has the USB gone offline?
424 if (!usb_configuration) return -1;
425 // get ready to try checking again
428 UENUM = DEBUG_TX_ENDPOINT;
430 // actually write the byte into the FIFO
432 // if this completed a packet, transmit it now!
433 if (!(UEINTX & (1<<RWAL))) {
435 debug_flush_timer = 0;
437 debug_flush_timer = 2;
444 // immediately transmit any buffered output.
445 void usb_debug_flush_output(void)
451 if (debug_flush_timer) {
452 UENUM = DEBUG_TX_ENDPOINT;
453 while ((UEINTX & (1<<RWAL))) {
457 debug_flush_timer = 0;
464 /**************************************************************************
466 * Private Functions - not intended for general user consumption....
468 **************************************************************************/
472 // USB Device Interrupt - handle all device-level events
473 // the transmit buffer flushing is triggered by the start of frame
477 uint8_t intbits, t, i;
478 static uint8_t div4=0;
482 if (intbits & (1<<EORSTI)) {
485 UECFG0X = EP_TYPE_CONTROL;
486 UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
487 UEIENX = (1<<RXSTPE);
488 usb_configuration = 0;
490 if ((intbits & (1<<SOFI)) && usb_configuration) {
491 t = debug_flush_timer;
493 debug_flush_timer = -- t;
495 UENUM = DEBUG_TX_ENDPOINT;
496 while ((UEINTX & (1<<RWAL))) {
502 if (keyboard_idle_config && (++div4 & 3) == 0) {
503 UENUM = KEYBOARD_ENDPOINT;
504 if (UEINTX & (1<<RWAL)) {
505 keyboard_idle_count++;
506 if (keyboard_idle_count == keyboard_idle_config) {
507 keyboard_idle_count = 0;
508 UEDATX = keyboard_modifier_keys;
510 for (i=0; i<6; i++) {
511 UEDATX = keyboard_keys[i];
522 // Misc functions to wait for ready and send/receive packets
523 static inline void usb_wait_in_ready(void)
525 while (!(UEINTX & (1<<TXINI))) ;
527 static inline void usb_send_in(void)
529 UEINTX = ~(1<<TXINI);
531 static inline void usb_wait_receive_out(void)
533 while (!(UEINTX & (1<<RXOUTI))) ;
535 static inline void usb_ack_out(void)
537 UEINTX = ~(1<<RXOUTI);
542 // USB Endpoint Interrupt - endpoint 0 is handled here. The
543 // other endpoints are manipulated by the user-callable
544 // functions, and the start-of-frame interrupt.
551 uint8_t i, n, len, en;
552 uint8_t bmRequestType;
558 const uint8_t *desc_addr;
563 if (intbits & (1<<RXSTPI)) {
564 bmRequestType = UEDATX;
567 wValue |= (UEDATX << 8);
569 wIndex |= (UEDATX << 8);
571 wLength |= (UEDATX << 8);
572 UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
573 if (bRequest == GET_DESCRIPTOR) {
574 list = (const uint8_t *)descriptor_list;
576 if (i >= NUM_DESC_LIST) {
577 UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
580 desc_val = pgm_read_word(list);
581 if (desc_val != wValue) {
582 list += sizeof(struct descriptor_list_struct);
586 desc_val = pgm_read_word(list);
587 if (desc_val != wIndex) {
588 list += sizeof(struct descriptor_list_struct)-2;
592 desc_addr = (const uint8_t *)pgm_read_word(list);
594 desc_length = pgm_read_byte(list);
597 len = (wLength < 256) ? wLength : 255;
598 if (len > desc_length) len = desc_length;
600 // wait for host ready for IN packet
603 } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
604 if (i & (1<<RXOUTI)) return; // abort
606 n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
607 for (i = n; i; i--) {
608 UEDATX = pgm_read_byte(desc_addr++);
612 } while (len || n == ENDPOINT0_SIZE);
615 if (bRequest == SET_ADDRESS) {
618 UDADDR = wValue | (1<<ADDEN);
621 if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
622 usb_configuration = wValue;
624 cfg = endpoint_config_table;
625 for (i=1; i<5; i++) {
627 en = pgm_read_byte(cfg++);
630 UECFG0X = pgm_read_byte(cfg++);
631 UECFG1X = pgm_read_byte(cfg++);
638 if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
640 UEDATX = usb_configuration;
645 if (bRequest == GET_STATUS) {
648 #ifdef SUPPORT_ENDPOINT_HALT
649 if (bmRequestType == 0x82) {
651 if (UECONX & (1<<STALLRQ)) i = 1;
660 #ifdef SUPPORT_ENDPOINT_HALT
661 if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
662 && bmRequestType == 0x02 && wValue == 0) {
664 if (i >= 1 && i <= MAX_ENDPOINT) {
667 if (bRequest == SET_FEATURE) {
668 UECONX = (1<<STALLRQ)|(1<<EPEN);
670 UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
678 if (wIndex == KEYBOARD_INTERFACE) {
679 if (bmRequestType == 0xA1) {
680 if (bRequest == HID_GET_REPORT) {
682 UEDATX = keyboard_modifier_keys;
684 for (i=0; i<6; i++) {
685 UEDATX = keyboard_keys[i];
690 if (bRequest == HID_GET_IDLE) {
692 UEDATX = keyboard_idle_config;
696 if (bRequest == HID_GET_PROTOCOL) {
698 UEDATX = keyboard_protocol;
703 if (bmRequestType == 0x21) {
704 if (bRequest == HID_SET_REPORT) {
705 usb_wait_receive_out();
706 keyboard_leds = UEDATX;
711 if (bRequest == HID_SET_IDLE) {
712 keyboard_idle_config = (wValue >> 8);
713 keyboard_idle_count = 0;
714 //usb_wait_in_ready();
718 if (bRequest == HID_SET_PROTOCOL) {
719 keyboard_protocol = wValue;
720 //usb_wait_in_ready();
726 if (wIndex == DEBUG_INTERFACE) {
727 if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
730 // wait for host ready for IN packet
733 } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
734 if (i & (1<<RXOUTI)) return; // abort
736 n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
737 for (i = n; i; i--) {
742 } while (len || n == ENDPOINT0_SIZE);
747 UECONX = (1<<STALLRQ) | (1<<EPEN); // stall