]> git.donarmstrong.com Git - kiibohd-controller.git/blob - usb_keyboard_debug.c
Significant progress made.
[kiibohd-controller.git] / usb_keyboard_debug.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 // 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_keyboard_debug.h"
29
30 /**************************************************************************
31  *
32  *  Configurable Options
33  *
34  **************************************************************************/
35
36 // You can change these to give your code its own name.
37 #define STR_MANUFACTURER        L"MfgName"
38 #define STR_PRODUCT             L"Keyboard"
39
40
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
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          32
65
66 #define KEYBOARD_INTERFACE      0
67 #define KEYBOARD_ENDPOINT       3
68 #define KEYBOARD_SIZE           8
69 #define KEYBOARD_BUFFER         EP_DOUBLE_BUFFER
70
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
75
76 static const uint8_t PROGMEM endpoint_config_table[] = {
77         0,
78         0,
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
81 };
82
83
84 /**************************************************************************
85  *
86  *  Descriptor Data
87  *
88  **************************************************************************/
89
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!
95
96
97 static uint8_t PROGMEM device_descriptor[] = {
98         18,                                     // bLength
99         1,                                      // bDescriptorType
100         0x00, 0x02,                             // bcdUSB
101         0,                                      // bDeviceClass
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
108         1,                                      // iManufacturer
109         2,                                      // iProduct
110         0,                                      // iSerialNumber
111         1                                       // bNumConfigurations
112 };
113
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
148 };
149
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
158         0x09, 0x75,                             // usage
159         0x81, 0x02,                             // Input (array)
160         0xC0                                    // end collection
161 };
162
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
168         9,                                      // bLength;
169         2,                                      // bDescriptorType;
170         LSB(CONFIG1_DESC_SIZE),                 // wTotalLength
171         MSB(CONFIG1_DESC_SIZE),
172         2,                                      // bNumInterfaces
173         1,                                      // bConfigurationValue
174         0,                                      // iConfiguration
175         0xC0,                                   // bmAttributes
176         50,                                     // bMaxPower
177         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
178         9,                                      // bLength
179         4,                                      // bDescriptorType
180         KEYBOARD_INTERFACE,                     // bInterfaceNumber
181         0,                                      // bAlternateSetting
182         1,                                      // bNumEndpoints
183         0x03,                                   // bInterfaceClass (0x03 = HID)
184         0x01,                                   // bInterfaceSubClass (0x01 = Boot)
185         0x01,                                   // bInterfaceProtocol (0x01 = Keyboard)
186         0,                                      // iInterface
187         // HID interface descriptor, HID 1.11 spec, section 6.2.1
188         9,                                      // bLength
189         0x21,                                   // bDescriptorType
190         0x11, 0x01,                             // bcdHID
191         0,                                      // bCountryCode
192         1,                                      // bNumDescriptors
193         0x22,                                   // bDescriptorType
194         sizeof(keyboard_hid_report_desc),       // wDescriptorLength
195         0,
196         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
197         7,                                      // bLength
198         5,                                      // bDescriptorType
199         KEYBOARD_ENDPOINT | 0x80,               // bEndpointAddress
200         0x03,                                   // bmAttributes (0x03=intr)
201         KEYBOARD_SIZE, 0,                       // wMaxPacketSize
202         1,                                      // bInterval
203         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
204         9,                                      // bLength
205         4,                                      // bDescriptorType
206         DEBUG_INTERFACE,                        // bInterfaceNumber
207         0,                                      // bAlternateSetting
208         1,                                      // bNumEndpoints
209         0x03,                                   // bInterfaceClass (0x03 = HID)
210         0x00,                                   // bInterfaceSubClass
211         0x00,                                   // bInterfaceProtocol
212         0,                                      // iInterface
213         // HID interface descriptor, HID 1.11 spec, section 6.2.1
214         9,                                      // bLength
215         0x21,                                   // bDescriptorType
216         0x11, 0x01,                             // bcdHID
217         0,                                      // bCountryCode
218         1,                                      // bNumDescriptors
219         0x22,                                   // bDescriptorType
220         sizeof(debug_hid_report_desc),          // wDescriptorLength
221         0,
222         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
223         7,                                      // bLength
224         5,                                      // bDescriptorType
225         DEBUG_TX_ENDPOINT | 0x80,               // bEndpointAddress
226         0x03,                                   // bmAttributes (0x03=intr)
227         DEBUG_TX_SIZE, 0,                       // wMaxPacketSize
228         1                                       // bInterval
229 };
230
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 {
235         uint8_t bLength;
236         uint8_t bDescriptorType;
237         int16_t wString[];
238 };
239 static struct usb_string_descriptor_struct PROGMEM string0 = {
240         4,
241         3,
242         {0x0409}
243 };
244 static struct usb_string_descriptor_struct PROGMEM string1 = {
245         sizeof(STR_MANUFACTURER),
246         3,
247         STR_MANUFACTURER
248 };
249 static struct usb_string_descriptor_struct PROGMEM string2 = {
250         sizeof(STR_PRODUCT),
251         3,
252         STR_PRODUCT
253 };
254
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 {
258         uint16_t        wValue;
259         uint16_t        wIndex;
260         const uint8_t   *addr;
261         uint8_t         length;
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)}
272 };
273 #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
274
275
276 /**************************************************************************
277  *
278  *  Variables - these are the only non-stack RAM usage
279  *
280  **************************************************************************/
281
282 // zero when we are not configured, non-zero when enumerated
283 static volatile uint8_t usb_configuration=0;
284
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;
288
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;
293
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};
296
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;
301
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;
305
306 // count until idle timeout
307 static uint8_t keyboard_idle_count=0;
308
309 // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
310 volatile uint8_t keyboard_leds=0;
311
312
313 /**************************************************************************
314  *
315  *  Public Functions - these are the API intended for the user
316  *
317  **************************************************************************/
318
319
320 // initialize USB
321 void usb_init(void)
322 {
323         HW_CONFIG();
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);
331         sei();
332 }
333
334 // return 0 if the USB is not configured, or the configuration
335 // number selected by the HOST
336 uint8_t usb_configured(void)
337 {
338         return usb_configuration;
339 }
340
341
342 // perform a single keystroke
343 int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
344 {
345         int8_t r;
346
347         keyboard_modifier_keys = modifier;
348         keyboard_keys[0] = key;
349         r = usb_keyboard_send();
350         if (r) return r;
351         keyboard_modifier_keys = 0;
352         keyboard_keys[0] = 0;
353         return usb_keyboard_send();
354 }
355
356 // send the contents of keyboard_keys and keyboard_modifier_keys
357 int8_t usb_keyboard_send(void)
358 {
359         uint8_t i, intr_state, timeout;
360
361         if (!usb_configuration) return -1;
362         intr_state = SREG;
363         cli();
364         UENUM = KEYBOARD_ENDPOINT;
365         timeout = UDFNUML + 50;
366         while (1) {
367                 // are we ready to transmit?
368                 if (UEINTX & (1<<RWAL)) break;
369                 SREG = intr_state;
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
375                 intr_state = SREG;
376                 cli();
377                 UENUM = KEYBOARD_ENDPOINT;
378         }
379         UEDATX = keyboard_modifier_keys;
380         UEDATX = 0;
381         for (i=0; i<6; i++) {
382                 UEDATX = keyboard_keys[i];
383         }
384         UEINTX = 0x3A;
385         keyboard_idle_count = 0;
386         SREG = intr_state;
387         return 0;
388 }
389
390 // transmit a character.  0 returned on success, -1 on error
391 int8_t usb_debug_putchar(uint8_t c)
392 {
393         static uint8_t previous_timeout=0;
394         uint8_t timeout, intr_state;
395
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!
401         intr_state = SREG;
402         cli();
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))) {
407                         SREG = intr_state;
408                         return -1;
409                 }
410                 previous_timeout = 0;
411         }
412         // wait for the FIFO to be ready to accept data
413         timeout = UDFNUML + 4;
414         while (1) {
415                 // are we ready to transmit?
416                 if (UEINTX & (1<<RWAL)) break;
417                 SREG = intr_state;
418                 // have we waited too long?
419                 if (UDFNUML == timeout) {
420                         previous_timeout = 1;
421                         return -1;
422                 }
423                 // has the USB gone offline?
424                 if (!usb_configuration) return -1;
425                 // get ready to try checking again
426                 intr_state = SREG;
427                 cli();
428                 UENUM = DEBUG_TX_ENDPOINT;
429         }
430         // actually write the byte into the FIFO
431         UEDATX = c;
432         // if this completed a packet, transmit it now!
433         if (!(UEINTX & (1<<RWAL))) {
434                 UEINTX = 0x3A;
435                 debug_flush_timer = 0;
436         } else {
437                 debug_flush_timer = 2;
438         }
439         SREG = intr_state;
440         return 0;
441 }
442
443
444 // immediately transmit any buffered output.
445 void usb_debug_flush_output(void)
446 {
447         uint8_t intr_state;
448
449         intr_state = SREG;
450         cli();
451         if (debug_flush_timer) {
452                 UENUM = DEBUG_TX_ENDPOINT;
453                 while ((UEINTX & (1<<RWAL))) {
454                         UEDATX = 0;
455                 }
456                 UEINTX = 0x3A;
457                 debug_flush_timer = 0;
458         }
459         SREG = intr_state;
460 }
461
462
463
464 /**************************************************************************
465  *
466  *  Private Functions - not intended for general user consumption....
467  *
468  **************************************************************************/
469
470
471
472 // USB Device Interrupt - handle all device-level events
473 // the transmit buffer flushing is triggered by the start of frame
474 //
475 ISR(USB_GEN_vect)
476 {
477         uint8_t intbits, t, i;
478         static uint8_t div4=0;
479
480         intbits = UDINT;
481         UDINT = 0;
482         if (intbits & (1<<EORSTI)) {
483                 UENUM = 0;
484                 UECONX = 1;
485                 UECFG0X = EP_TYPE_CONTROL;
486                 UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
487                 UEIENX = (1<<RXSTPE);
488                 usb_configuration = 0;
489         }
490         if ((intbits & (1<<SOFI)) && usb_configuration) {
491                 t = debug_flush_timer;
492                 if (t) {
493                         debug_flush_timer = -- t;
494                         if (!t) {
495                                 UENUM = DEBUG_TX_ENDPOINT;
496                                 while ((UEINTX & (1<<RWAL))) {
497                                         UEDATX = 0;
498                                 }
499                                 UEINTX = 0x3A;
500                         }
501                 }
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;
509                                         UEDATX = 0;
510                                         for (i=0; i<6; i++) {
511                                                 UEDATX = keyboard_keys[i];
512                                         }
513                                         UEINTX = 0x3A;
514                                 }
515                         }
516                 }
517         }
518 }
519
520
521
522 // Misc functions to wait for ready and send/receive packets
523 static inline void usb_wait_in_ready(void)
524 {
525         while (!(UEINTX & (1<<TXINI))) ;
526 }
527 static inline void usb_send_in(void)
528 {
529         UEINTX = ~(1<<TXINI);
530 }
531 static inline void usb_wait_receive_out(void)
532 {
533         while (!(UEINTX & (1<<RXOUTI))) ;
534 }
535 static inline void usb_ack_out(void)
536 {
537         UEINTX = ~(1<<RXOUTI);
538 }
539
540
541
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.
545 //
546 ISR(USB_COM_vect)
547 {
548         uint8_t intbits;
549         const uint8_t *list;
550         const uint8_t *cfg;
551         uint8_t i, n, len, en;
552         uint8_t bmRequestType;
553         uint8_t bRequest;
554         uint16_t wValue;
555         uint16_t wIndex;
556         uint16_t wLength;
557         uint16_t desc_val;
558         const uint8_t *desc_addr;
559         uint8_t desc_length;
560
561         UENUM = 0;
562         intbits = UEINTX;
563         if (intbits & (1<<RXSTPI)) {
564                 bmRequestType = UEDATX;
565                 bRequest = UEDATX;
566                 wValue = UEDATX;
567                 wValue |= (UEDATX << 8);
568                 wIndex = UEDATX;
569                 wIndex |= (UEDATX << 8);
570                 wLength = UEDATX;
571                 wLength |= (UEDATX << 8);
572                 UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
573                 if (bRequest == GET_DESCRIPTOR) {
574                         list = (const uint8_t *)descriptor_list;
575                         for (i=0; ; i++) {
576                                 if (i >= NUM_DESC_LIST) {
577                                         UECONX = (1<<STALLRQ)|(1<<EPEN);  //stall
578                                         return;
579                                 }
580                                 desc_val = pgm_read_word(list);
581                                 if (desc_val != wValue) {
582                                         list += sizeof(struct descriptor_list_struct);
583                                         continue;
584                                 }
585                                 list += 2;
586                                 desc_val = pgm_read_word(list);
587                                 if (desc_val != wIndex) {
588                                         list += sizeof(struct descriptor_list_struct)-2;
589                                         continue;
590                                 }
591                                 list += 2;
592                                 desc_addr = (const uint8_t *)pgm_read_word(list);
593                                 list += 2;
594                                 desc_length = pgm_read_byte(list);
595                                 break;
596                         }
597                         len = (wLength < 256) ? wLength : 255;
598                         if (len > desc_length) len = desc_length;
599                         do {
600                                 // wait for host ready for IN packet
601                                 do {
602                                         i = UEINTX;
603                                 } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
604                                 if (i & (1<<RXOUTI)) return;    // abort
605                                 // send IN packet
606                                 n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
607                                 for (i = n; i; i--) {
608                                         UEDATX = pgm_read_byte(desc_addr++);
609                                 }
610                                 len -= n;
611                                 usb_send_in();
612                         } while (len || n == ENDPOINT0_SIZE);
613                         return;
614                 }
615                 if (bRequest == SET_ADDRESS) {
616                         usb_send_in();
617                         usb_wait_in_ready();
618                         UDADDR = wValue | (1<<ADDEN);
619                         return;
620                 }
621                 if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
622                         usb_configuration = wValue;
623                         usb_send_in();
624                         cfg = endpoint_config_table;
625                         for (i=1; i<5; i++) {
626                                 UENUM = i;
627                                 en = pgm_read_byte(cfg++);
628                                 UECONX = en;
629                                 if (en) {
630                                         UECFG0X = pgm_read_byte(cfg++);
631                                         UECFG1X = pgm_read_byte(cfg++);
632                                 }
633                         }
634                         UERST = 0x1E;
635                         UERST = 0;
636                         return;
637                 }
638                 if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
639                         usb_wait_in_ready();
640                         UEDATX = usb_configuration;
641                         usb_send_in();
642                         return;
643                 }
644
645                 if (bRequest == GET_STATUS) {
646                         usb_wait_in_ready();
647                         i = 0;
648                         #ifdef SUPPORT_ENDPOINT_HALT
649                         if (bmRequestType == 0x82) {
650                                 UENUM = wIndex;
651                                 if (UECONX & (1<<STALLRQ)) i = 1;
652                                 UENUM = 0;
653                         }
654                         #endif
655                         UEDATX = i;
656                         UEDATX = 0;
657                         usb_send_in();
658                         return;
659                 }
660                 #ifdef SUPPORT_ENDPOINT_HALT
661                 if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
662                   && bmRequestType == 0x02 && wValue == 0) {
663                         i = wIndex & 0x7F;
664                         if (i >= 1 && i <= MAX_ENDPOINT) {
665                                 usb_send_in();
666                                 UENUM = i;
667                                 if (bRequest == SET_FEATURE) {
668                                         UECONX = (1<<STALLRQ)|(1<<EPEN);
669                                 } else {
670                                         UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
671                                         UERST = (1 << i);
672                                         UERST = 0;
673                                 }
674                                 return;
675                         }
676                 }
677                 #endif
678                 if (wIndex == KEYBOARD_INTERFACE) {
679                         if (bmRequestType == 0xA1) {
680                                 if (bRequest == HID_GET_REPORT) {
681                                         usb_wait_in_ready();
682                                         UEDATX = keyboard_modifier_keys;
683                                         UEDATX = 0;
684                                         for (i=0; i<6; i++) {
685                                                 UEDATX = keyboard_keys[i];
686                                         }
687                                         usb_send_in();
688                                         return;
689                                 }
690                                 if (bRequest == HID_GET_IDLE) {
691                                         usb_wait_in_ready();
692                                         UEDATX = keyboard_idle_config;
693                                         usb_send_in();
694                                         return;
695                                 }
696                                 if (bRequest == HID_GET_PROTOCOL) {
697                                         usb_wait_in_ready();
698                                         UEDATX = keyboard_protocol;
699                                         usb_send_in();
700                                         return;
701                                 }
702                         }
703                         if (bmRequestType == 0x21) {
704                                 if (bRequest == HID_SET_REPORT) {
705                                         usb_wait_receive_out();
706                                         keyboard_leds = UEDATX;
707                                         usb_ack_out();
708                                         usb_send_in();
709                                         return;
710                                 }
711                                 if (bRequest == HID_SET_IDLE) {
712                                         keyboard_idle_config = (wValue >> 8);
713                                         keyboard_idle_count = 0;
714                                         //usb_wait_in_ready();
715                                         usb_send_in();
716                                         return;
717                                 }
718                                 if (bRequest == HID_SET_PROTOCOL) {
719                                         keyboard_protocol = wValue;
720                                         //usb_wait_in_ready();
721                                         usb_send_in();
722                                         return;
723                                 }
724                         }
725                 }
726                 if (wIndex == DEBUG_INTERFACE) {
727                         if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
728                                 len = wLength;
729                                 do {
730                                         // wait for host ready for IN packet
731                                         do {
732                                                 i = UEINTX;
733                                         } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
734                                         if (i & (1<<RXOUTI)) return;    // abort
735                                         // send IN packet
736                                         n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
737                                         for (i = n; i; i--) {
738                                                 UEDATX = 0;
739                                         }
740                                         len -= n;
741                                         usb_send_in();
742                                 } while (len || n == ENDPOINT0_SIZE);
743                                 return;
744                         }
745                 }
746         }
747         UECONX = (1<<STALLRQ) | (1<<EPEN);      // stall
748 }
749
750