]> git.donarmstrong.com Git - tmk_firmware.git/blob - protocol/pjrc/usb.c
Merge branch 'suspend_fix'
[tmk_firmware.git] / protocol / pjrc / usb.c
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
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 #include <stdint.h>
25 #include <stdbool.h>
26 #include <avr/io.h>
27 #include <avr/pgmspace.h>
28 #include <avr/interrupt.h>
29 #include "usb.h"
30 #include "usb_keyboard.h"
31 #include "usb_mouse.h"
32 #include "usb_debug.h"
33 #include "usb_extra.h"
34 #include "print.h"
35 #include "util.h"
36 #include "sleep_led.h"
37 #include "suspend.h"
38
39
40 /**************************************************************************
41  *
42  *  Configurable Options
43  *
44  **************************************************************************/
45
46 // You can change these to give your code its own name.
47 #ifndef MANUFACTURER
48 #   define STR_MANUFACTURER     L"t.m.k."
49 #else
50 #   define STR_MANUFACTURER     LSTR(MANUFACTURER)
51 #endif
52 #ifndef PRODUCT
53 #   define STR_PRODUCT          L"t.m.k. keyboard"
54 #else
55 #   define STR_PRODUCT          LSTR(PRODUCT)
56 #endif
57
58
59 // Mac OS-X and Linux automatically load the correct drivers.  On
60 // Windows, even though the driver is supplied by Microsoft, an
61 // INF file is needed to load the driver.  These numbers need to
62 // match the INF file.
63 #ifndef VENDOR_ID
64 #   define VENDOR_ID            0xFEED
65 #endif
66
67 #ifndef PRODUCT_ID
68 #   define PRODUCT_ID           0xBABE
69 #endif
70
71 #ifndef DEVICE_VER
72 #   define DEVICE_VER           0x0100
73 #endif
74
75
76 // USB devices are supposed to implment a halt feature, which is
77 // rarely (if ever) used.  If you comment this line out, the halt
78 // code will be removed, saving 102 bytes of space (gcc 4.3.0).
79 // This is not strictly USB compliant, but works with all major
80 // operating systems.
81 #define SUPPORT_ENDPOINT_HALT
82
83
84
85 /**************************************************************************
86  *
87  *  Endpoint Buffer Configuration
88  *
89  **************************************************************************/
90
91 #define ENDPOINT0_SIZE          32
92
93 bool remote_wakeup = false;
94 bool suspend = false;
95
96 // 0:control endpoint is enabled automatically by controller.
97 static const uint8_t PROGMEM endpoint_config_table[] = {
98         // enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation)
99         1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KBD_SIZE)      | KBD_BUFFER,      // 1
100 #ifdef MOUSE_ENABLE
101         1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(MOUSE_SIZE)    | MOUSE_BUFFER,    // 2
102 #else
103         0,                                                                  // 2
104 #endif
105         1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
106 #ifdef EXTRAKEY_ENABLE
107         1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(EXTRA_SIZE)    | EXTRA_BUFFER,    // 4
108 #else
109         0,                                                                  // 4
110 #endif
111 #ifdef NKRO_ENABLE
112         1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KBD2_SIZE)     | KBD2_BUFFER,     // 5
113 #else
114         0,                                                                  // 5
115 #endif
116         0,                                                                  // 6
117 };
118
119
120 /**************************************************************************
121  *
122  *  Descriptor Data
123  *
124  **************************************************************************/
125
126 // Descriptors are the data that your computer reads when it auto-detects
127 // this USB device (called "enumeration" in USB lingo).  The most commonly
128 // changed items are editable at the top of this file.  Changing things
129 // in here should only be done by those who've read chapter 9 of the USB
130 // spec and relevant portions of any USB class specifications!
131
132
133 static const uint8_t PROGMEM device_descriptor[] = {
134         18,                                     // bLength
135         1,                                      // bDescriptorType
136         0x00, 0x02,                             // bcdUSB
137         0,                                      // bDeviceClass
138         0,                                      // bDeviceSubClass
139         0,                                      // bDeviceProtocol
140         ENDPOINT0_SIZE,                         // bMaxPacketSize0
141         LSB(VENDOR_ID), MSB(VENDOR_ID),         // idVendor
142         LSB(PRODUCT_ID), MSB(PRODUCT_ID),       // idProduct
143         LSB(DEVICE_VER), MSB(DEVICE_VER),       // bcdDevice
144         1,                                      // iManufacturer
145         2,                                      // iProduct
146         0,                                      // iSerialNumber
147         1                                       // bNumConfigurations
148 };
149
150 // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
151 static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
152         0x05, 0x01,          // Usage Page (Generic Desktop),
153         0x09, 0x06,          // Usage (Keyboard),
154         0xA1, 0x01,          // Collection (Application),
155         0x75, 0x01,          //   Report Size (1),
156         0x95, 0x08,          //   Report Count (8),
157         0x05, 0x07,          //   Usage Page (Key Codes),
158         0x19, 0xE0,          //   Usage Minimum (224),
159         0x29, 0xE7,          //   Usage Maximum (231),
160         0x15, 0x00,          //   Logical Minimum (0),
161         0x25, 0x01,          //   Logical Maximum (1),
162         0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
163         0x95, 0x01,          //   Report Count (1),
164         0x75, 0x08,          //   Report Size (8),
165         0x81, 0x03,          //   Input (Constant),                 ;Reserved byte
166         0x95, 0x05,          //   Report Count (5),
167         0x75, 0x01,          //   Report Size (1),
168         0x05, 0x08,          //   Usage Page (LEDs),
169         0x19, 0x01,          //   Usage Minimum (1),
170         0x29, 0x05,          //   Usage Maximum (5),
171         0x91, 0x02,          //   Output (Data, Variable, Absolute), ;LED report
172         0x95, 0x01,          //   Report Count (1),
173         0x75, 0x03,          //   Report Size (3),
174         0x91, 0x03,          //   Output (Constant),                 ;LED report padding
175         0x95, KBD_REPORT_KEYS,    //   Report Count (),
176         0x75, 0x08,          //   Report Size (8),
177         0x15, 0x00,          //   Logical Minimum (0),
178         0x25, 0xFF,          //   Logical Maximum(255),
179         0x05, 0x07,          //   Usage Page (Key Codes),
180         0x19, 0x00,          //   Usage Minimum (0),
181         0x29, 0xFF,          //   Usage Maximum (255),
182         0x81, 0x00,          //   Input (Data, Array),
183         0xc0                 // End Collection
184 };
185 #ifdef NKRO_ENABLE
186 static const uint8_t PROGMEM keyboard2_hid_report_desc[] = {
187         0x05, 0x01,                     // Usage Page (Generic Desktop),
188         0x09, 0x06,                     // Usage (Keyboard),
189         0xA1, 0x01,                     // Collection (Application),
190         // bitmap of modifiers
191         0x75, 0x01,                     //   Report Size (1),
192         0x95, 0x08,                     //   Report Count (8),
193         0x05, 0x07,                     //   Usage Page (Key Codes),
194         0x19, 0xE0,                     //   Usage Minimum (224),
195         0x29, 0xE7,                     //   Usage Maximum (231),
196         0x15, 0x00,                     //   Logical Minimum (0),
197         0x25, 0x01,                     //   Logical Maximum (1),
198         0x81, 0x02,                     //   Input (Data, Variable, Absolute), ;Modifier byte
199         // LED output report
200         0x95, 0x05,                     //   Report Count (5),
201         0x75, 0x01,                     //   Report Size (1),
202         0x05, 0x08,                     //   Usage Page (LEDs),
203         0x19, 0x01,                     //   Usage Minimum (1),
204         0x29, 0x05,                     //   Usage Maximum (5),
205         0x91, 0x02,                     //   Output (Data, Variable, Absolute),
206         0x95, 0x01,                     //   Report Count (1),
207         0x75, 0x03,                     //   Report Size (3),
208         0x91, 0x03,                     //   Output (Constant),
209         // bitmap of keys
210         0x95, KBD2_REPORT_KEYS*8,       //   Report Count (),
211         0x75, 0x01,                     //   Report Size (1),
212         0x15, 0x00,                     //   Logical Minimum (0),
213         0x25, 0x01,                     //   Logical Maximum(1),
214         0x05, 0x07,                     //   Usage Page (Key Codes),
215         0x19, 0x00,                     //   Usage Minimum (0),
216         0x29, KBD2_REPORT_KEYS*8-1,     //   Usage Maximum (),
217         0x81, 0x02,                     //   Input (Data, Variable, Absolute),
218         0xc0                            // End Collection
219 };
220 #endif
221
222 #ifdef MOUSE_ENABLE
223 // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
224 // http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
225 // http://www.keil.com/forum/15671/
226 // http://www.microsoft.com/whdc/device/input/wheel.mspx
227 static const uint8_t PROGMEM mouse_hid_report_desc[] = {
228     /* mouse */
229     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
230     0x09, 0x02,                    // USAGE (Mouse)
231     0xa1, 0x01,                    // COLLECTION (Application)
232     //0x85, REPORT_ID_MOUSE,         //   REPORT_ID (1)
233     0x09, 0x01,                    //   USAGE (Pointer)
234     0xa1, 0x00,                    //   COLLECTION (Physical)
235                                    // ----------------------------  Buttons
236     0x05, 0x09,                    //     USAGE_PAGE (Button)
237     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
238     0x29, 0x05,                    //     USAGE_MAXIMUM (Button 5)
239     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
240     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
241     0x75, 0x01,                    //     REPORT_SIZE (1)
242     0x95, 0x05,                    //     REPORT_COUNT (5)
243     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
244     0x75, 0x03,                    //     REPORT_SIZE (3)
245     0x95, 0x01,                    //     REPORT_COUNT (1)
246     0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
247                                    // ----------------------------  X,Y position
248     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
249     0x09, 0x30,                    //     USAGE (X)
250     0x09, 0x31,                    //     USAGE (Y)
251     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
252     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
253     0x75, 0x08,                    //     REPORT_SIZE (8)
254     0x95, 0x02,                    //     REPORT_COUNT (2)
255     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
256                                    // ----------------------------  Vertical wheel
257     0x09, 0x38,                    //     USAGE (Wheel)
258     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
259     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
260     0x35, 0x00,                    //     PHYSICAL_MINIMUM (0)        - reset physical
261     0x45, 0x00,                    //     PHYSICAL_MAXIMUM (0)
262     0x75, 0x08,                    //     REPORT_SIZE (8)
263     0x95, 0x01,                    //     REPORT_COUNT (1)
264     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
265                                    // ----------------------------  Horizontal wheel
266     0x05, 0x0c,                    //     USAGE_PAGE (Consumer Devices)
267     0x0a, 0x38, 0x02,              //     USAGE (AC Pan)
268     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
269     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
270     0x75, 0x08,                    //     REPORT_SIZE (8)
271     0x95, 0x01,                    //     REPORT_COUNT (1)
272     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
273     0xc0,                          //   END_COLLECTION
274     0xc0,                          // END_COLLECTION
275 };
276 #endif
277
278 static const uint8_t PROGMEM debug_hid_report_desc[] = {
279         0x06, 0x31, 0xFF,                       // Usage Page 0xFF31 (vendor defined)
280         0x09, 0x74,                             // Usage 0x74
281         0xA1, 0x53,                             // Collection 0x53
282         0x75, 0x08,                             // report size = 8 bits
283         0x15, 0x00,                             // logical minimum = 0
284         0x26, 0xFF, 0x00,                       // logical maximum = 255
285         0x95, DEBUG_TX_SIZE,                    // report count
286         0x09, 0x75,                             // usage
287         0x81, 0x02,                             // Input (array)
288         0xC0                                    // end collection
289 };
290
291 #ifdef EXTRAKEY_ENABLE
292 // audio controls & system controls
293 // http://www.microsoft.com/whdc/archive/w2kbd.mspx
294 static const uint8_t PROGMEM extra_hid_report_desc[] = {
295     /* system control */
296     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
297     0x09, 0x80,                    // USAGE (System Control)
298     0xa1, 0x01,                    // COLLECTION (Application)
299     0x85, REPORT_ID_SYSTEM,        //   REPORT_ID (2)
300     0x15, 0x01,                    //   LOGICAL_MINIMUM (0x1)
301     0x25, 0xb7,                    //   LOGICAL_MAXIMUM (0xb7)
302     0x19, 0x01,                    //   USAGE_MINIMUM (0x1)
303     0x29, 0xb7,                    //   USAGE_MAXIMUM (0xb7)
304     0x75, 0x10,                    //   REPORT_SIZE (16)
305     0x95, 0x01,                    //   REPORT_COUNT (1)
306     0x81, 0x00,                    //   INPUT (Data,Array,Abs)
307     0xc0,                          // END_COLLECTION
308     /* consumer */
309     0x05, 0x0c,                    // USAGE_PAGE (Consumer Devices)
310     0x09, 0x01,                    // USAGE (Consumer Control)
311     0xa1, 0x01,                    // COLLECTION (Application)
312     0x85, REPORT_ID_CONSUMER,      //   REPORT_ID (3)
313     0x15, 0x01,                    //   LOGICAL_MINIMUM (0x1)
314     0x26, 0x9c, 0x02,              //   LOGICAL_MAXIMUM (0x29c)
315     0x19, 0x01,                    //   USAGE_MINIMUM (0x1)
316     0x2a, 0x9c, 0x02,              //   USAGE_MAXIMUM (0x29c)
317     0x75, 0x10,                    //   REPORT_SIZE (16)
318     0x95, 0x01,                    //   REPORT_COUNT (1)
319     0x81, 0x00,                    //   INPUT (Data,Array,Abs)
320     0xc0,                          // END_COLLECTION
321 };
322 #endif
323
324 #define KBD_HID_DESC_NUM                0
325 #define KBD_HID_DESC_OFFSET             (9+(9+9+7)*KBD_HID_DESC_NUM+9)
326
327 #ifdef MOUSE_ENABLE
328 #   define MOUSE_HID_DESC_NUM           (KBD_HID_DESC_NUM + 1)
329 #   define MOUSE_HID_DESC_OFFSET        (9+(9+9+7)*MOUSE_HID_DESC_NUM+9)
330 #else
331 #   define MOUSE_HID_DESC_NUM           (KBD_HID_DESC_NUM + 0)
332 #endif
333
334 #define DEBUG_HID_DESC_NUM              (MOUSE_HID_DESC_NUM + 1)
335 #define DEBUG_HID_DESC_OFFSET           (9+(9+9+7)*DEBUG_HID_DESC_NUM+9)
336
337 #ifdef EXTRAKEY_ENABLE
338 #   define EXTRA_HID_DESC_NUM           (DEBUG_HID_DESC_NUM + 1)
339 #   define EXTRA_HID_DESC_OFFSET        (9+(9+9+7)*EXTRA_HID_DESC_NUM+9)
340 #else
341 #   define EXTRA_HID_DESC_NUM           (DEBUG_HID_DESC_NUM + 0)
342 #endif
343
344 #ifdef NKRO_ENABLE
345 #   define KBD2_HID_DESC_NUM            (EXTRA_HID_DESC_NUM + 1)
346 #   define KBD2_HID_DESC_OFFSET         (9+(9+9+7)*EXTRA_HID_DESC_NUM+9)
347 #else
348 #   define KBD2_HID_DESC_NUM            (EXTRA_HID_DESC_NUM + 0)
349 #endif
350
351 #define NUM_INTERFACES                  (KBD2_HID_DESC_NUM + 1)
352 #define CONFIG1_DESC_SIZE               (9+(9+9+7)*NUM_INTERFACES)
353 static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
354         // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
355         9,                                      // bLength;
356         2,                                      // bDescriptorType;
357         LSB(CONFIG1_DESC_SIZE),                 // wTotalLength
358         MSB(CONFIG1_DESC_SIZE),
359         NUM_INTERFACES,                         // bNumInterfaces
360         1,                                      // bConfigurationValue
361         0,                                      // iConfiguration
362         0xA0,                                   // bmAttributes
363         50,                                     // bMaxPower
364
365         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
366         9,                                      // bLength
367         4,                                      // bDescriptorType
368         KBD_INTERFACE,                          // bInterfaceNumber
369         0,                                      // bAlternateSetting
370         1,                                      // bNumEndpoints
371         0x03,                                   // bInterfaceClass (0x03 = HID)
372         0x01,                                   // bInterfaceSubClass (0x01 = Boot)
373         0x01,                                   // bInterfaceProtocol (0x01 = Keyboard)
374         0,                                      // iInterface
375         // HID descriptor, HID 1.11 spec, section 6.2.1
376         9,                                      // bLength
377         0x21,                                   // bDescriptorType
378         0x11, 0x01,                             // bcdHID
379         0,                                      // bCountryCode
380         1,                                      // bNumDescriptors
381         0x22,                                   // bDescriptorType
382         sizeof(keyboard_hid_report_desc),       // wDescriptorLength
383         0,
384         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
385         7,                                      // bLength
386         5,                                      // bDescriptorType
387         KBD_ENDPOINT | 0x80,                    // bEndpointAddress
388         0x03,                                   // bmAttributes (0x03=intr)
389         KBD_SIZE, 0,                            // wMaxPacketSize
390         10,                                     // bInterval
391
392 #ifdef MOUSE_ENABLE
393         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
394         9,                                      // bLength
395         4,                                      // bDescriptorType
396         MOUSE_INTERFACE,                        // bInterfaceNumber
397         0,                                      // bAlternateSetting
398         1,                                      // bNumEndpoints
399         0x03,                                   // bInterfaceClass (0x03 = HID)
400         // ThinkPad T23 BIOS doesn't work with boot mouse.
401         0x00,                                   // bInterfaceSubClass (0x01 = Boot)
402         0x00,                                   // bInterfaceProtocol (0x02 = Mouse)
403 /*
404         0x01,                                   // bInterfaceSubClass (0x01 = Boot)
405         0x02,                                   // bInterfaceProtocol (0x02 = Mouse)
406 */
407         0,                                      // iInterface
408         // HID descriptor, HID 1.11 spec, section 6.2.1
409         9,                                      // bLength
410         0x21,                                   // bDescriptorType
411         0x11, 0x01,                             // bcdHID
412         0,                                      // bCountryCode
413         1,                                      // bNumDescriptors
414         0x22,                                   // bDescriptorType
415         sizeof(mouse_hid_report_desc),          // wDescriptorLength
416         0,
417         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
418         7,                                      // bLength
419         5,                                      // bDescriptorType
420         MOUSE_ENDPOINT | 0x80,                  // bEndpointAddress
421         0x03,                                   // bmAttributes (0x03=intr)
422         MOUSE_SIZE, 0,                          // wMaxPacketSize
423         1,                                      // bInterval
424 #endif
425
426         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
427         9,                                      // bLength
428         4,                                      // bDescriptorType
429         DEBUG_INTERFACE,                        // bInterfaceNumber
430         0,                                      // bAlternateSetting
431         1,                                      // bNumEndpoints
432         0x03,                                   // bInterfaceClass (0x03 = HID)
433         0x00,                                   // bInterfaceSubClass
434         0x00,                                   // bInterfaceProtocol
435         0,                                      // iInterface
436         // HID descriptor, HID 1.11 spec, section 6.2.1
437         9,                                      // bLength
438         0x21,                                   // bDescriptorType
439         0x11, 0x01,                             // bcdHID
440         0,                                      // bCountryCode
441         1,                                      // bNumDescriptors
442         0x22,                                   // bDescriptorType
443         sizeof(debug_hid_report_desc),          // wDescriptorLength
444         0,
445         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
446         7,                                      // bLength
447         5,                                      // bDescriptorType
448         DEBUG_TX_ENDPOINT | 0x80,               // bEndpointAddress
449         0x03,                                   // bmAttributes (0x03=intr)
450         DEBUG_TX_SIZE, 0,                       // wMaxPacketSize
451         1,                                      // bInterval
452
453 #ifdef EXTRAKEY_ENABLE
454         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
455         9,                                      // bLength
456         4,                                      // bDescriptorType
457         EXTRA_INTERFACE,                        // bInterfaceNumber
458         0,                                      // bAlternateSetting
459         1,                                      // bNumEndpoints
460         0x03,                                   // bInterfaceClass (0x03 = HID)
461         0x00,                                   // bInterfaceSubClass
462         0x00,                                   // bInterfaceProtocol
463         0,                                      // iInterface
464         // HID descriptor, HID 1.11 spec, section 6.2.1
465         9,                                      // bLength
466         0x21,                                   // bDescriptorType
467         0x11, 0x01,                             // bcdHID
468         0,                                      // bCountryCode
469         1,                                      // bNumDescriptors
470         0x22,                                   // bDescriptorType
471         sizeof(extra_hid_report_desc),          // wDescriptorLength
472         0,
473         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
474         7,                                      // bLength
475         5,                                      // bDescriptorType
476         EXTRA_ENDPOINT | 0x80,                  // bEndpointAddress
477         0x03,                                   // bmAttributes (0x03=intr)
478         EXTRA_SIZE, 0,                          // wMaxPacketSize
479         10,                                     // bInterval
480 #endif
481
482 #ifdef NKRO_ENABLE
483         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
484         9,                                      // bLength
485         4,                                      // bDescriptorType
486         KBD2_INTERFACE,                         // bInterfaceNumber
487         0,                                      // bAlternateSetting
488         1,                                      // bNumEndpoints
489         0x03,                                   // bInterfaceClass (0x03 = HID)
490         0x00,                                   // bInterfaceSubClass (0x01 = Boot)
491         0x00,                                   // bInterfaceProtocol (0x01 = Keyboard)
492         0,                                      // iInterface
493         // HID descriptor, HID 1.11 spec, section 6.2.1
494         9,                                      // bLength
495         0x21,                                   // bDescriptorType
496         0x11, 0x01,                             // bcdHID
497         0,                                      // bCountryCode
498         1,                                      // bNumDescriptors
499         0x22,                                   // bDescriptorType
500         sizeof(keyboard2_hid_report_desc),      // wDescriptorLength
501         0,
502         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
503         7,                                      // bLength
504         5,                                      // bDescriptorType
505         KBD2_ENDPOINT | 0x80,                   // bEndpointAddress
506         0x03,                                   // bmAttributes (0x03=intr)
507         KBD2_SIZE, 0,                           // wMaxPacketSize
508         1,                                      // bInterval
509 #endif
510 };
511
512 // If you're desperate for a little extra code memory, these strings
513 // can be completely removed if iManufacturer, iProduct, iSerialNumber
514 // in the device desciptor are changed to zeros.
515 struct usb_string_descriptor_struct {
516         uint8_t bLength;
517         uint8_t bDescriptorType;
518         int16_t wString[];
519 };
520 static const struct usb_string_descriptor_struct PROGMEM string0 = {
521         4,
522         3,
523         {0x0409}
524 };
525 static const struct usb_string_descriptor_struct PROGMEM string1 = {
526         sizeof(STR_MANUFACTURER),
527         3,
528         STR_MANUFACTURER
529 };
530 static const struct usb_string_descriptor_struct PROGMEM string2 = {
531         sizeof(STR_PRODUCT),
532         3,
533         STR_PRODUCT
534 };
535
536 // This table defines which descriptor data is sent for each specific
537 // request from the host (in wValue and wIndex).
538 static const struct descriptor_list_struct {
539         uint16_t        wValue;     // descriptor type
540         uint16_t        wIndex;
541         const uint8_t   *addr;
542         uint8_t         length;
543 } PROGMEM descriptor_list[] = {
544         // DEVICE descriptor
545         {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
546         // CONFIGURATION descriptor
547         {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
548         // HID/REPORT descriptors
549         {0x2100, KBD_INTERFACE, config1_descriptor+KBD_HID_DESC_OFFSET, 9},
550         {0x2200, KBD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
551 #ifdef MOUSE_ENABLE
552         {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
553         {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
554 #endif
555         {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
556         {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
557 #ifdef EXTRAKEY_ENABLE
558         {0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9},
559         {0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)},
560 #endif
561 #ifdef NKRO_ENABLE
562         {0x2100, KBD2_INTERFACE, config1_descriptor+KBD2_HID_DESC_OFFSET, 9},
563         {0x2200, KBD2_INTERFACE, keyboard2_hid_report_desc, sizeof(keyboard2_hid_report_desc)},
564 #endif
565         // STRING descriptors
566         {0x0300, 0x0000, (const uint8_t *)&string0, 4},
567         {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
568         {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
569 };
570 #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
571
572
573 /**************************************************************************
574  *
575  *  Variables - these are the only non-stack RAM usage
576  *
577  **************************************************************************/
578
579 // zero when we are not configured, non-zero when enumerated
580 static volatile uint8_t usb_configuration=0;
581
582
583 /**************************************************************************
584  *
585  *  Public Functions - these are the API intended for the user
586  *
587  **************************************************************************/
588
589
590 // initialize USB
591 void usb_init(void)
592 {
593         HW_CONFIG();
594         USB_FREEZE();                           // enable USB
595         PLL_CONFIG();                           // config PLL
596         while (!(PLLCSR & (1<<PLOCK))) ;        // wait for PLL lock
597         USB_CONFIG();                           // start USB clock
598         UDCON = 0;                              // enable attach resistor
599         usb_configuration = 0;
600         suspend = false;
601         UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE)|(1<<WAKEUPE);
602         sei();
603 }
604
605 // return 0 if the USB is not configured, or the configuration
606 // number selected by the HOST
607 uint8_t usb_configured(void)
608 {
609         return usb_configuration && !suspend;
610 }
611
612 void usb_remote_wakeup(void)
613 {
614     UDCON |= (1<<RMWKUP);
615 }
616
617
618
619 /**************************************************************************
620  *
621  *  Private Functions - not intended for general user consumption....
622  *
623  **************************************************************************/
624
625
626
627 // USB Device Interrupt - handle all device-level events
628 // the transmit buffer flushing is triggered by the start of frame
629 //
630 ISR(USB_GEN_vect)
631 {
632         uint8_t intbits, t;
633         static uint8_t div4=0;
634
635         intbits = UDINT;
636         UDINT = 0;
637         if ((intbits & (1<<SUSPI)) && (UDIEN & (1<<SUSPE)) && usb_configuration) {
638 #ifdef SLEEP_LED_ENABLE
639             sleep_led_enable();
640 #endif
641             UDIEN &= ~(1<<SUSPE);
642             UDIEN |= (1<<WAKEUPE);
643             suspend = true;
644         }
645         if ((intbits & (1<<WAKEUPI)) && (UDIEN & (1<<WAKEUPE)) && usb_configuration) {
646             suspend_wakeup_init();
647 #ifdef SLEEP_LED_ENABLE
648             sleep_led_disable();
649 #endif
650             led_set(host_keyboard_leds());
651
652             UDIEN |= (1<<SUSPE);
653             UDIEN &= ~(1<<WAKEUPE);
654             suspend = false;
655         }
656         if (intbits & (1<<EORSTI)) {
657                 UENUM = 0;
658                 UECONX = 1;
659                 UECFG0X = EP_TYPE_CONTROL;
660                 UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
661                 UEIENX = (1<<RXSTPE);
662                 usb_configuration = 0;
663         }
664         if ((intbits & (1<<SOFI)) && usb_configuration) {
665                 t = debug_flush_timer;
666                 if (t) {
667                         debug_flush_timer = -- t;
668                         if (!t) {
669                                 UENUM = DEBUG_TX_ENDPOINT;
670                                 while ((UEINTX & (1<<RWAL))) {
671                                         UEDATX = 0;
672                                 }
673                                 UEINTX = 0x3A;
674                         }
675                 }
676                 /* TODO: should keep IDLE rate on each keyboard interface */
677 #ifdef NKRO_ENABLE
678                 if (!keyboard_nkro && usb_keyboard_idle_config && (++div4 & 3) == 0) {
679 #else
680                 if (usb_keyboard_idle_config && (++div4 & 3) == 0) {
681 #endif
682                         UENUM = KBD_ENDPOINT;
683                         if (UEINTX & (1<<RWAL)) {
684                                 usb_keyboard_idle_count++;
685                                 if (usb_keyboard_idle_count == usb_keyboard_idle_config) {
686                                         usb_keyboard_idle_count = 0;
687                                         /* TODO: fix keyboard_report inconsistency */
688 /* To avoid Mac SET_IDLE behaviour.
689                                         UEDATX = keyboard_report_prev->mods;
690                                         UEDATX = 0;
691                                         uint8_t keys = usb_keyboard_protocol ? KBD_REPORT_KEYS : 6;
692                                         for (uint8_t i=0; i<keys; i++) {
693                                                 UEDATX = keyboard_report_prev->keys[i];
694                                         }
695                                         UEINTX = 0x3A;
696 */
697                                 }
698                         }
699                 }
700         }
701 }
702
703
704
705 // Misc functions to wait for ready and send/receive packets
706 static inline void usb_wait_in_ready(void)
707 {
708         while (!(UEINTX & (1<<TXINI))) ;
709 }
710 static inline void usb_send_in(void)
711 {
712         UEINTX = ~(1<<TXINI);
713 }
714 static inline void usb_wait_receive_out(void)
715 {
716         while (!(UEINTX & (1<<RXOUTI))) ;
717 }
718 static inline void usb_ack_out(void)
719 {
720         UEINTX = ~(1<<RXOUTI);
721 }
722
723
724
725 // USB Endpoint Interrupt - endpoint 0 is handled here.  The
726 // other endpoints are manipulated by the user-callable
727 // functions, and the start-of-frame interrupt.
728 //
729 ISR(USB_COM_vect)
730 {
731         uint8_t intbits;
732         const uint8_t *list;
733         const uint8_t *cfg;
734         uint8_t i, n, len, en;
735         uint8_t bmRequestType;
736         uint8_t bRequest;
737         uint16_t wValue;
738         uint16_t wIndex;
739         uint16_t wLength;
740         uint16_t desc_val;
741         const uint8_t *desc_addr;
742         uint8_t desc_length;
743
744         UENUM = 0;
745         intbits = UEINTX;
746         if (intbits & (1<<RXSTPI)) {
747                 bmRequestType = UEDATX;
748                 bRequest = UEDATX;
749                 wValue = UEDATX;
750                 wValue |= (UEDATX << 8);
751                 wIndex = UEDATX;
752                 wIndex |= (UEDATX << 8);
753                 wLength = UEDATX;
754                 wLength |= (UEDATX << 8);
755                 UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
756                 if (bRequest == GET_DESCRIPTOR) {
757                         list = (const uint8_t *)descriptor_list;
758                         for (i=0; ; i++) {
759                                 if (i >= NUM_DESC_LIST) {
760                                         UECONX = (1<<STALLRQ)|(1<<EPEN);  //stall
761                                         return;
762                                 }
763                                 desc_val = pgm_read_word(list);
764                                 if (desc_val != wValue) {
765                                         list += sizeof(struct descriptor_list_struct);
766                                         continue;
767                                 }
768                                 list += 2;
769                                 desc_val = pgm_read_word(list);
770                                 if (desc_val != wIndex) {
771                                         list += sizeof(struct descriptor_list_struct)-2;
772                                         continue;
773                                 }
774                                 list += 2;
775                                 desc_addr = (const uint8_t *)pgm_read_word(list);
776                                 list += 2;
777                                 desc_length = pgm_read_byte(list);
778                                 break;
779                         }
780                         len = (wLength < 256) ? wLength : 255;
781                         if (len > desc_length) len = desc_length;
782                         do {
783                                 // wait for host ready for IN packet
784                                 do {
785                                         i = UEINTX;
786                                 } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
787                                 if (i & (1<<RXOUTI)) return;    // abort
788                                 // send IN packet
789                                 n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
790                                 for (i = n; i; i--) {
791                                         UEDATX = pgm_read_byte(desc_addr++);
792                                 }
793                                 len -= n;
794                                 usb_send_in();
795                         } while (len || n == ENDPOINT0_SIZE);
796                         return;
797                 }
798                 if (bRequest == SET_ADDRESS) {
799                         usb_send_in();
800                         usb_wait_in_ready();
801                         UDADDR = wValue | (1<<ADDEN);
802                         return;
803                 }
804                 if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
805                         usb_configuration = wValue;
806                         usb_send_in();
807                         cfg = endpoint_config_table;
808                         for (i=1; i<=MAX_ENDPOINT; i++) {
809                                 UENUM = i;
810                                 en = pgm_read_byte(cfg++);
811                                 if (en) {
812                                     UECONX = (1<<EPEN);
813                                     UECFG0X = pgm_read_byte(cfg++);
814                                     UECFG1X = pgm_read_byte(cfg++);
815                                 } else {
816                                     UECONX = 0;
817                                 }
818                         }
819                         UERST = UERST_MASK;
820                         UERST = 0;
821                         return;
822                 }
823                 if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
824                         usb_wait_in_ready();
825                         UEDATX = usb_configuration;
826                         usb_send_in();
827                         return;
828                 }
829
830                 if (bRequest == GET_STATUS) {
831                         usb_wait_in_ready();
832                         i = 0;
833                         #ifdef SUPPORT_ENDPOINT_HALT
834                         if (bmRequestType == 0x82) {
835                                 UENUM = wIndex;
836                                 if (UECONX & (1<<STALLRQ)) i = 1;
837                                 UENUM = 0;
838                         }
839                         #endif
840                         UEDATX = i;
841                         UEDATX = 0;
842                         usb_send_in();
843                         return;
844                 }
845                 if (bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE) {
846 #ifdef SUPPORT_ENDPOINT_HALT
847                     if (bmRequestType == 0x02 && wValue == ENDPOINT_HALT) {
848                         i = wIndex & 0x7F;
849                         if (i >= 1 && i <= MAX_ENDPOINT) {
850                                 usb_send_in();
851                                 UENUM = i;
852                                 if (bRequest == SET_FEATURE) {
853                                         UECONX = (1<<STALLRQ)|(1<<EPEN);
854                                 } else {
855                                         UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
856                                         UERST = (1 << i);
857                                         UERST = 0;
858                                 }
859                                 return;
860                         }
861                     }
862 #endif
863                     if (bmRequestType == 0x00 && wValue == DEVICE_REMOTE_WAKEUP) {
864                         if (bRequest == SET_FEATURE) {
865                             remote_wakeup = true;   
866                         } else {
867                             remote_wakeup = false;
868                         }
869                         usb_send_in();
870                         return;
871                     }
872                 }
873                 if (wIndex == KBD_INTERFACE) {
874                         if (bmRequestType == 0xA1) {
875                                 if (bRequest == HID_GET_REPORT) {
876                                         usb_wait_in_ready();
877                                         UEDATX = keyboard_report->mods;
878                                         UEDATX = 0;
879                                         for (i=0; i<6; i++) {
880                                                 UEDATX = keyboard_report->keys[i];
881                                         }
882                                         usb_send_in();
883                                         return;
884                                 }
885                                 if (bRequest == HID_GET_IDLE) {
886                                         usb_wait_in_ready();
887                                         UEDATX = usb_keyboard_idle_config;
888                                         usb_send_in();
889                                         return;
890                                 }
891                                 if (bRequest == HID_GET_PROTOCOL) {
892                                         usb_wait_in_ready();
893                                         UEDATX = usb_keyboard_protocol;
894                                         usb_send_in();
895                                         return;
896                                 }
897                         }
898                         if (bmRequestType == 0x21) {
899                                 if (bRequest == HID_SET_REPORT) {
900                                         usb_wait_receive_out();
901                                         usb_keyboard_leds = UEDATX;
902                                         usb_ack_out();
903                                         usb_send_in();
904                                         return;
905                                 }
906                                 if (bRequest == HID_SET_IDLE) {
907                                         usb_keyboard_idle_config = (wValue >> 8);
908                                         usb_keyboard_idle_count = 0;
909                                         //usb_wait_in_ready();
910                                         usb_send_in();
911                                         return;
912                                 }
913                                 if (bRequest == HID_SET_PROTOCOL) {
914                                         usb_keyboard_protocol = wValue;
915                                         //usb_wait_in_ready();
916                                         usb_send_in();
917                                         return;
918                                 }
919                         }
920                 }
921 #ifdef MOUSE_ENABLE
922                 if (wIndex == MOUSE_INTERFACE) {
923                         if (bmRequestType == 0xA1) {
924                                 if (bRequest == HID_GET_REPORT) {
925                                     if (wValue == HID_REPORT_INPUT) {
926                                         usb_wait_in_ready();
927                                         UEDATX = 0;
928                                         UEDATX = 0;
929                                         UEDATX = 0;
930                                         UEDATX = 0;
931                                         usb_send_in();
932                                         return;
933                                     }
934                                     if (wValue == HID_REPORT_FEATURE) {
935                                         usb_wait_in_ready();
936                                         UEDATX = 0x05;
937                                         usb_send_in();
938                                         return;
939                                     }
940                                 }
941                                 if (bRequest == HID_GET_PROTOCOL) {
942                                         usb_wait_in_ready();
943                                         UEDATX = usb_mouse_protocol;
944                                         usb_send_in();
945                                         return;
946                                 }
947                         }
948                         if (bmRequestType == 0x21) {
949                                 if (bRequest == HID_SET_PROTOCOL) {
950                                         usb_mouse_protocol = wValue;
951                                         usb_send_in();
952                                         return;
953                                 }
954                         }
955                 }
956 #endif
957                 if (wIndex == DEBUG_INTERFACE) {
958                         if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
959                                 len = wLength;
960                                 do {
961                                         // wait for host ready for IN packet
962                                         do {
963                                                 i = UEINTX;
964                                         } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
965                                         if (i & (1<<RXOUTI)) return;    // abort
966                                         // send IN packet
967                                         n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
968                                         for (i = n; i; i--) {
969                                                 UEDATX = 0;
970                                         }
971                                         len -= n;
972                                         usb_send_in();
973                                 } while (len || n == ENDPOINT0_SIZE);
974                                 return;
975                         }
976                 }
977         }
978         UECONX = (1<<STALLRQ) | (1<<EPEN);      // stall
979 }