]> git.gir.st - tmk_keyboard.git/blob - usb.c
add mouse function.
[tmk_keyboard.git] / 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 <avr/io.h>
25 #include <avr/pgmspace.h>
26 #include <avr/interrupt.h>
27 #include "usb.h"
28 #include "usb_keyboard.h"
29 #include "usb_mouse.h"
30 #include "usb_debug.h"
31
32
33 /**************************************************************************
34 *
35 * Configurable Options
36 *
37 **************************************************************************/
38
39 // You can change these to give your code its own name.
40 #define STR_MANUFACTURER L"t.m.k."
41 #define STR_PRODUCT L"t.m.k. keyboard"
42
43
44 // Mac OS-X and Linux automatically load the correct drivers. On
45 // Windows, even though the driver is supplied by Microsoft, an
46 // INF file is needed to load the driver. These numbers need to
47 // match the INF file.
48 #define VENDOR_ID 0xFEED
49 #define PRODUCT_ID 0xBABE
50
51
52 // USB devices are supposed to implment a halt feature, which is
53 // rarely (if ever) used. If you comment this line out, the halt
54 // code will be removed, saving 102 bytes of space (gcc 4.3.0).
55 // This is not strictly USB compliant, but works with all major
56 // operating systems.
57 #define SUPPORT_ENDPOINT_HALT
58
59
60
61 /**************************************************************************
62 *
63 * Endpoint Buffer Configuration
64 *
65 **************************************************************************/
66
67 #define ENDPOINT0_SIZE 32
68
69 // 0:control endpoint is enabled automatically by controller.
70 static const uint8_t PROGMEM endpoint_config_table[] = {
71 // enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation)
72 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER, // 1
73 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER, // 2
74 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
75 0, // 4
76 0, // 5
77 0, // 6
78 };
79
80
81 /**************************************************************************
82 *
83 * Descriptor Data
84 *
85 **************************************************************************/
86
87 // Descriptors are the data that your computer reads when it auto-detects
88 // this USB device (called "enumeration" in USB lingo). The most commonly
89 // changed items are editable at the top of this file. Changing things
90 // in here should only be done by those who've read chapter 9 of the USB
91 // spec and relevant portions of any USB class specifications!
92
93
94 static uint8_t PROGMEM device_descriptor[] = {
95 18, // bLength
96 1, // bDescriptorType
97 0x00, 0x02, // bcdUSB
98 0, // bDeviceClass
99 0, // bDeviceSubClass
100 0, // bDeviceProtocol
101 ENDPOINT0_SIZE, // bMaxPacketSize0
102 LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
103 LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
104 0x00, 0x01, // bcdDevice
105 1, // iManufacturer
106 2, // iProduct
107 0, // iSerialNumber
108 1 // bNumConfigurations
109 };
110
111 // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
112 static uint8_t PROGMEM keyboard_hid_report_desc[] = {
113 0x05, 0x01, // Usage Page (Generic Desktop),
114 0x09, 0x06, // Usage (Keyboard),
115 0xA1, 0x01, // Collection (Application),
116 0x75, 0x01, // Report Size (1),
117 0x95, 0x08, // Report Count (8),
118 0x05, 0x07, // Usage Page (Key Codes),
119 0x19, 0xE0, // Usage Minimum (224),
120 0x29, 0xE7, // Usage Maximum (231),
121 0x15, 0x00, // Logical Minimum (0),
122 0x25, 0x01, // Logical Maximum (1),
123 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
124 0x95, 0x01, // Report Count (1),
125 0x75, 0x08, // Report Size (8),
126 0x81, 0x03, // Input (Constant), ;Reserved byte
127 0x95, 0x05, // Report Count (5),
128 0x75, 0x01, // Report Size (1),
129 0x05, 0x08, // Usage Page (LEDs),
130 0x19, 0x01, // Usage Minimum (1),
131 0x29, 0x05, // Usage Maximum (5),
132 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
133 0x95, 0x01, // Report Count (1),
134 0x75, 0x03, // Report Size (3),
135 0x91, 0x03, // Output (Constant), ;LED report padding
136 0x95, 0x06, // Report Count (6),
137 0x75, 0x08, // Report Size (8),
138 0x15, 0x00, // Logical Minimum (0),
139 0x25, 0x68, // Logical Maximum(104),
140 0x05, 0x07, // Usage Page (Key Codes),
141 0x19, 0x00, // Usage Minimum (0),
142 0x29, 0x68, // Usage Maximum (104),
143 0x81, 0x00, // Input (Data, Array),
144 0xc0 // End Collection
145 };
146
147 // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
148 static uint8_t PROGMEM mouse_hid_report_desc[] = {
149 0x05, 0x01, // Usage Page (Generic Desktop)
150 0x09, 0x02, // Usage (Mouse)
151 0xA1, 0x01, // Collection (Application)
152 0x05, 0x09, // Usage Page (Button)
153 0x19, 0x01, // Usage Minimum (Button #1)
154 0x29, 0x03, // Usage Maximum (Button #3)
155 0x15, 0x00, // Logical Minimum (0)
156 0x25, 0x01, // Logical Maximum (1)
157 0x95, 0x03, // Report Count (3)
158 0x75, 0x01, // Report Size (1)
159 0x81, 0x02, // Input (Data, Variable, Absolute)
160 0x95, 0x01, // Report Count (1)
161 0x75, 0x05, // Report Size (5)
162 0x81, 0x03, // Input (Constant)
163 0x05, 0x01, // Usage Page (Generic Desktop)
164 0x09, 0x30, // Usage (X)
165 0x09, 0x31, // Usage (Y)
166 0x15, 0x81, // Logical Minimum (-127)
167 0x25, 0x7F, // Logical Maximum (127)
168 0x75, 0x08, // Report Size (8),
169 0x95, 0x02, // Report Count (2),
170 0x81, 0x06, // Input (Data, Variable, Relative)
171 0x09, 0x38, // Usage (Wheel)
172 0x95, 0x01, // Report Count (1),
173 0x81, 0x06, // Input (Data, Variable, Relative)
174 0xC0 // End Collection
175 };
176
177 static uint8_t PROGMEM debug_hid_report_desc[] = {
178 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
179 0x09, 0x74, // Usage 0x74
180 0xA1, 0x53, // Collection 0x53
181 0x75, 0x08, // report size = 8 bits
182 0x15, 0x00, // logical minimum = 0
183 0x26, 0xFF, 0x00, // logical maximum = 255
184 0x95, DEBUG_TX_SIZE, // report count
185 0x09, 0x75, // usage
186 0x81, 0x02, // Input (array)
187 0xC0 // end collection
188 };
189
190 #define CONFIG1_DESC_SIZE (9+(9+9+7)+(9+9+7)+(9+9+7))
191 #define KEYBOARD_HID_DESC_OFFSET (9+9)
192 #define MOUSE_HID_DESC_OFFSET (9+(9+9+7)+9)
193 #define DEBUG_HID_DESC_OFFSET (9+(9+9+7)+(9+9+7)+9)
194 static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
195 // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
196 9, // bLength;
197 2, // bDescriptorType;
198 LSB(CONFIG1_DESC_SIZE), // wTotalLength
199 MSB(CONFIG1_DESC_SIZE),
200 3, // bNumInterfaces
201 1, // bConfigurationValue
202 0, // iConfiguration
203 0xC0, // bmAttributes
204 50, // bMaxPower
205
206 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
207 9, // bLength
208 4, // bDescriptorType
209 KEYBOARD_INTERFACE, // bInterfaceNumber
210 0, // bAlternateSetting
211 1, // bNumEndpoints
212 0x03, // bInterfaceClass (0x03 = HID)
213 0x01, // bInterfaceSubClass (0x01 = Boot)
214 0x01, // bInterfaceProtocol (0x01 = Keyboard)
215 0, // iInterface
216 // HID descriptor, HID 1.11 spec, section 6.2.1
217 9, // bLength
218 0x21, // bDescriptorType
219 0x11, 0x01, // bcdHID
220 0, // bCountryCode
221 1, // bNumDescriptors
222 0x22, // bDescriptorType
223 sizeof(keyboard_hid_report_desc), // wDescriptorLength
224 0,
225 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
226 7, // bLength
227 5, // bDescriptorType
228 KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress
229 0x03, // bmAttributes (0x03=intr)
230 KEYBOARD_SIZE, 0, // wMaxPacketSize
231 1, // bInterval
232
233 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
234 9, // bLength
235 4, // bDescriptorType
236 MOUSE_INTERFACE, // bInterfaceNumber
237 0, // bAlternateSetting
238 1, // bNumEndpoints
239 0x03, // bInterfaceClass (0x03 = HID)
240 0x01, // bInterfaceSubClass (0x01 = Boot)
241 0x02, // bInterfaceProtocol (0x02 = Mouse)
242 0, // iInterface
243 // HID descriptor, HID 1.11 spec, section 6.2.1
244 9, // bLength
245 0x21, // bDescriptorType
246 0x11, 0x01, // bcdHID
247 0, // bCountryCode
248 1, // bNumDescriptors
249 0x22, // bDescriptorType
250 sizeof(mouse_hid_report_desc), // wDescriptorLength
251 0,
252 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
253 7, // bLength
254 5, // bDescriptorType
255 MOUSE_ENDPOINT | 0x80, // bEndpointAddress
256 0x03, // bmAttributes (0x03=intr)
257 4, 0, // wMaxPacketSize
258 1, // bInterval
259
260 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
261 9, // bLength
262 4, // bDescriptorType
263 DEBUG_INTERFACE, // bInterfaceNumber
264 0, // bAlternateSetting
265 1, // bNumEndpoints
266 0x03, // bInterfaceClass (0x03 = HID)
267 0x00, // bInterfaceSubClass
268 0x00, // bInterfaceProtocol
269 0, // iInterface
270 // HID descriptor, HID 1.11 spec, section 6.2.1
271 9, // bLength
272 0x21, // bDescriptorType
273 0x11, 0x01, // bcdHID
274 0, // bCountryCode
275 1, // bNumDescriptors
276 0x22, // bDescriptorType
277 sizeof(debug_hid_report_desc), // wDescriptorLength
278 0,
279 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
280 7, // bLength
281 5, // bDescriptorType
282 DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress
283 0x03, // bmAttributes (0x03=intr)
284 DEBUG_TX_SIZE, 0, // wMaxPacketSize
285 1 // bInterval
286 };
287
288 // If you're desperate for a little extra code memory, these strings
289 // can be completely removed if iManufacturer, iProduct, iSerialNumber
290 // in the device desciptor are changed to zeros.
291 struct usb_string_descriptor_struct {
292 uint8_t bLength;
293 uint8_t bDescriptorType;
294 int16_t wString[];
295 };
296 static struct usb_string_descriptor_struct PROGMEM string0 = {
297 4,
298 3,
299 {0x0409}
300 };
301 static struct usb_string_descriptor_struct PROGMEM string1 = {
302 sizeof(STR_MANUFACTURER),
303 3,
304 STR_MANUFACTURER
305 };
306 static struct usb_string_descriptor_struct PROGMEM string2 = {
307 sizeof(STR_PRODUCT),
308 3,
309 STR_PRODUCT
310 };
311
312 // This table defines which descriptor data is sent for each specific
313 // request from the host (in wValue and wIndex).
314 static struct descriptor_list_struct {
315 uint16_t wValue; // descriptor type
316 uint16_t wIndex;
317 const uint8_t *addr;
318 uint8_t length;
319 } PROGMEM descriptor_list[] = {
320 // DEVICE descriptor
321 {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
322 // CONFIGURATION descriptor
323 {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
324 // HID REPORT
325 {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
326 {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
327 // HID REPORT
328 {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
329 {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
330 // HID REPORT
331 {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
332 {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
333 // STRING descriptor
334 {0x0300, 0x0000, (const uint8_t *)&string0, 4},
335 {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
336 {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
337 };
338 #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
339
340
341 /**************************************************************************
342 *
343 * Variables - these are the only non-stack RAM usage
344 *
345 **************************************************************************/
346
347 // zero when we are not configured, non-zero when enumerated
348 static volatile uint8_t usb_configuration=0;
349
350
351 /**************************************************************************
352 *
353 * Public Functions - these are the API intended for the user
354 *
355 **************************************************************************/
356
357
358 // initialize USB
359 void usb_init(void)
360 {
361 HW_CONFIG();
362 USB_FREEZE(); // enable USB
363 PLL_CONFIG(); // config PLL
364 while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
365 USB_CONFIG(); // start USB clock
366 UDCON = 0; // enable attach resistor
367 usb_configuration = 0;
368 UDIEN = (1<<EORSTE)|(1<<SOFE);
369 sei();
370 }
371
372 // return 0 if the USB is not configured, or the configuration
373 // number selected by the HOST
374 uint8_t usb_configured(void)
375 {
376 return usb_configuration;
377 }
378
379
380
381 /**************************************************************************
382 *
383 * Private Functions - not intended for general user consumption....
384 *
385 **************************************************************************/
386
387
388
389 // USB Device Interrupt - handle all device-level events
390 // the transmit buffer flushing is triggered by the start of frame
391 //
392 ISR(USB_GEN_vect)
393 {
394 uint8_t intbits, t, i;
395 static uint8_t div4=0;
396
397 intbits = UDINT;
398 UDINT = 0;
399 if (intbits & (1<<EORSTI)) {
400 UENUM = 0;
401 UECONX = 1;
402 UECFG0X = EP_TYPE_CONTROL;
403 UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
404 UEIENX = (1<<RXSTPE);
405 usb_configuration = 0;
406 }
407 if ((intbits & (1<<SOFI)) && usb_configuration) {
408 t = debug_flush_timer;
409 if (t) {
410 debug_flush_timer = -- t;
411 if (!t) {
412 UENUM = DEBUG_TX_ENDPOINT;
413 while ((UEINTX & (1<<RWAL))) {
414 UEDATX = 0;
415 }
416 UEINTX = 0x3A;
417 }
418 }
419 if (keyboard_idle_config && (++div4 & 3) == 0) {
420 UENUM = KEYBOARD_ENDPOINT;
421 if (UEINTX & (1<<RWAL)) {
422 keyboard_idle_count++;
423 if (keyboard_idle_count == keyboard_idle_config) {
424 keyboard_idle_count = 0;
425 UEDATX = keyboard_modifier_keys;
426 UEDATX = 0;
427 for (i=0; i<6; i++) {
428 UEDATX = keyboard_keys[i];
429 }
430 UEINTX = 0x3A;
431 }
432 }
433 }
434 }
435 }
436
437
438
439 // Misc functions to wait for ready and send/receive packets
440 static inline void usb_wait_in_ready(void)
441 {
442 while (!(UEINTX & (1<<TXINI))) ;
443 }
444 static inline void usb_send_in(void)
445 {
446 UEINTX = ~(1<<TXINI);
447 }
448 static inline void usb_wait_receive_out(void)
449 {
450 while (!(UEINTX & (1<<RXOUTI))) ;
451 }
452 static inline void usb_ack_out(void)
453 {
454 UEINTX = ~(1<<RXOUTI);
455 }
456
457
458
459 // USB Endpoint Interrupt - endpoint 0 is handled here. The
460 // other endpoints are manipulated by the user-callable
461 // functions, and the start-of-frame interrupt.
462 //
463 ISR(USB_COM_vect)
464 {
465 uint8_t intbits;
466 const uint8_t *list;
467 const uint8_t *cfg;
468 uint8_t i, n, len, en;
469 uint8_t bmRequestType;
470 uint8_t bRequest;
471 uint16_t wValue;
472 uint16_t wIndex;
473 uint16_t wLength;
474 uint16_t desc_val;
475 const uint8_t *desc_addr;
476 uint8_t desc_length;
477
478 UENUM = 0;
479 intbits = UEINTX;
480 if (intbits & (1<<RXSTPI)) {
481 bmRequestType = UEDATX;
482 bRequest = UEDATX;
483 wValue = UEDATX;
484 wValue |= (UEDATX << 8);
485 wIndex = UEDATX;
486 wIndex |= (UEDATX << 8);
487 wLength = UEDATX;
488 wLength |= (UEDATX << 8);
489 UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
490 if (bRequest == GET_DESCRIPTOR) {
491 list = (const uint8_t *)descriptor_list;
492 for (i=0; ; i++) {
493 if (i >= NUM_DESC_LIST) {
494 UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
495 return;
496 }
497 desc_val = pgm_read_word(list);
498 if (desc_val != wValue) {
499 list += sizeof(struct descriptor_list_struct);
500 continue;
501 }
502 list += 2;
503 desc_val = pgm_read_word(list);
504 if (desc_val != wIndex) {
505 list += sizeof(struct descriptor_list_struct)-2;
506 continue;
507 }
508 list += 2;
509 desc_addr = (const uint8_t *)pgm_read_word(list);
510 list += 2;
511 desc_length = pgm_read_byte(list);
512 break;
513 }
514 len = (wLength < 256) ? wLength : 255;
515 if (len > desc_length) len = desc_length;
516 do {
517 // wait for host ready for IN packet
518 do {
519 i = UEINTX;
520 } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
521 if (i & (1<<RXOUTI)) return; // abort
522 // send IN packet
523 n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
524 for (i = n; i; i--) {
525 UEDATX = pgm_read_byte(desc_addr++);
526 }
527 len -= n;
528 usb_send_in();
529 } while (len || n == ENDPOINT0_SIZE);
530 return;
531 }
532 if (bRequest == SET_ADDRESS) {
533 usb_send_in();
534 usb_wait_in_ready();
535 UDADDR = wValue | (1<<ADDEN);
536 return;
537 }
538 if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
539 usb_configuration = wValue;
540 usb_send_in();
541 cfg = endpoint_config_table;
542 for (i=1; i<=6; i++) {
543 UENUM = i;
544 en = pgm_read_byte(cfg++);
545 UECONX = en;
546 if (en) {
547 UECFG0X = pgm_read_byte(cfg++);
548 UECFG1X = pgm_read_byte(cfg++);
549 }
550 }
551 UERST = 0x7E;
552 UERST = 0;
553 return;
554 }
555 if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
556 usb_wait_in_ready();
557 UEDATX = usb_configuration;
558 usb_send_in();
559 return;
560 }
561
562 if (bRequest == GET_STATUS) {
563 usb_wait_in_ready();
564 i = 0;
565 #ifdef SUPPORT_ENDPOINT_HALT
566 if (bmRequestType == 0x82) {
567 UENUM = wIndex;
568 if (UECONX & (1<<STALLRQ)) i = 1;
569 UENUM = 0;
570 }
571 #endif
572 UEDATX = i;
573 UEDATX = 0;
574 usb_send_in();
575 return;
576 }
577 #ifdef SUPPORT_ENDPOINT_HALT
578 if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
579 && bmRequestType == 0x02 && wValue == 0) {
580 i = wIndex & 0x7F;
581 if (i >= 1 && i <= MAX_ENDPOINT) {
582 usb_send_in();
583 UENUM = i;
584 if (bRequest == SET_FEATURE) {
585 UECONX = (1<<STALLRQ)|(1<<EPEN);
586 } else {
587 UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
588 UERST = (1 << i);
589 UERST = 0;
590 }
591 return;
592 }
593 }
594 #endif
595 if (wIndex == KEYBOARD_INTERFACE) {
596 if (bmRequestType == 0xA1) {
597 if (bRequest == HID_GET_REPORT) {
598 usb_wait_in_ready();
599 UEDATX = keyboard_modifier_keys;
600 UEDATX = 0;
601 for (i=0; i<6; i++) {
602 UEDATX = keyboard_keys[i];
603 }
604 usb_send_in();
605 return;
606 }
607 if (bRequest == HID_GET_IDLE) {
608 usb_wait_in_ready();
609 UEDATX = keyboard_idle_config;
610 usb_send_in();
611 return;
612 }
613 if (bRequest == HID_GET_PROTOCOL) {
614 usb_wait_in_ready();
615 UEDATX = keyboard_protocol;
616 usb_send_in();
617 return;
618 }
619 }
620 if (bmRequestType == 0x21) {
621 if (bRequest == HID_SET_REPORT) {
622 usb_wait_receive_out();
623 keyboard_leds = UEDATX;
624 usb_ack_out();
625 usb_send_in();
626 return;
627 }
628 if (bRequest == HID_SET_IDLE) {
629 keyboard_idle_config = (wValue >> 8);
630 keyboard_idle_count = 0;
631 //usb_wait_in_ready();
632 usb_send_in();
633 return;
634 }
635 if (bRequest == HID_SET_PROTOCOL) {
636 keyboard_protocol = wValue;
637 //usb_wait_in_ready();
638 usb_send_in();
639 return;
640 }
641 }
642 }
643 if (wIndex == MOUSE_INTERFACE) {
644 if (bmRequestType == 0xA1) {
645 if (bRequest == HID_GET_REPORT) {
646 usb_wait_in_ready();
647 UEDATX = mouse_buttons;
648 UEDATX = 0;
649 UEDATX = 0;
650 UEDATX = 0;
651 usb_send_in();
652 return;
653 }
654 if (bRequest == HID_GET_PROTOCOL) {
655 usb_wait_in_ready();
656 UEDATX = mouse_protocol;
657 usb_send_in();
658 return;
659 }
660 }
661 if (bmRequestType == 0x21) {
662 if (bRequest == HID_SET_PROTOCOL) {
663 mouse_protocol = wValue;
664 usb_send_in();
665 return;
666 }
667 }
668 }
669 if (wIndex == DEBUG_INTERFACE) {
670 if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
671 len = wLength;
672 do {
673 // wait for host ready for IN packet
674 do {
675 i = UEINTX;
676 } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
677 if (i & (1<<RXOUTI)) return; // abort
678 // send IN packet
679 n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
680 for (i = n; i; i--) {
681 UEDATX = 0;
682 }
683 len -= n;
684 usb_send_in();
685 } while (len || n == ENDPOINT0_SIZE);
686 return;
687 }
688 }
689 }
690 UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
691 }
692
693
Imprint / Impressum