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