diff options
| author | tmk <nobody@nowhere> | 2010-09-23 20:23:50 +0900 |
|---|---|---|
| committer | tmk <nobody@nowhere> | 2010-09-23 20:23:50 +0900 |
| commit | 7fd9003f59ad6a1de8d8b70fae74ba16df666c09 (patch) | |
| tree | 965fa71209fbb0a947aa9848ab9dba2247d9b5b9 | |
| parent | 6be0e4fafb3875264317f048b2c823dea87a9f49 (diff) | |
| download | qmk_firmware-7fd9003f59ad6a1de8d8b70fae74ba16df666c09.tar.gz qmk_firmware-7fd9003f59ad6a1de8d8b70fae74ba16df666c09.zip | |
divide usb_keyboard_debug.[c|h] into usb_device, usb_keyboard, usb_debug.
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | mykey.c | 2 | ||||
| -rw-r--r-- | print.h | 2 | ||||
| -rw-r--r-- | usb_debug.c | 80 | ||||
| -rw-r--r-- | usb_debug.h | 20 | ||||
| -rw-r--r-- | usb_device.c (renamed from usb_keyboard_debug.c) | 176 | ||||
| -rw-r--r-- | usb_device.h (renamed from usb_keyboard_debug.h) | 26 | ||||
| -rw-r--r-- | usb_keyboard.c | 76 | ||||
| -rw-r--r-- | usb_keyboard.h | 25 |
9 files changed, 225 insertions, 186 deletions
| @@ -48,7 +48,9 @@ TARGET = mykey | |||
| 48 | SRC = $(TARGET).c \ | 48 | SRC = $(TARGET).c \ |
| 49 | keymap.c \ | 49 | keymap.c \ |
| 50 | matrix.c \ | 50 | matrix.c \ |
| 51 | usb_keyboard_debug.c \ | 51 | usb_device.c \ |
| 52 | usb_keyboard.c \ | ||
| 53 | usb_debug.c \ | ||
| 52 | print.c | 54 | print.c |
| 53 | 55 | ||
| 54 | 56 | ||
| @@ -30,7 +30,7 @@ | |||
| 30 | #include <avr/interrupt.h> | 30 | #include <avr/interrupt.h> |
| 31 | #include <util/delay.h> | 31 | #include <util/delay.h> |
| 32 | 32 | ||
| 33 | #include "usb_keyboard_debug.h" | 33 | #include "usb_device.h" |
| 34 | #include "print.h" | 34 | #include "print.h" |
| 35 | #include "matrix.h" | 35 | #include "matrix.h" |
| 36 | #include "keymap.h" | 36 | #include "keymap.h" |
| @@ -2,7 +2,7 @@ | |||
| 2 | #define print_h__ | 2 | #define print_h__ |
| 3 | 3 | ||
| 4 | #include <avr/pgmspace.h> | 4 | #include <avr/pgmspace.h> |
| 5 | #include "usb_keyboard_debug.h" | 5 | #include "usb_debug.h" |
| 6 | 6 | ||
| 7 | // this macro allows you to write print("some text") and | 7 | // this macro allows you to write print("some text") and |
| 8 | // the string is automatically placed into flash memory :) | 8 | // the string is automatically placed into flash memory :) |
diff --git a/usb_debug.c b/usb_debug.c new file mode 100644 index 000000000..97590184a --- /dev/null +++ b/usb_debug.c | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | #include <avr/interrupt.h> | ||
| 2 | #include "usb_debug.h" | ||
| 3 | |||
| 4 | |||
| 5 | // the time remaining before we transmit any partially full | ||
| 6 | // packet, or send a zero length packet. | ||
| 7 | volatile uint8_t debug_flush_timer=0; | ||
| 8 | |||
| 9 | |||
| 10 | // transmit a character. 0 returned on success, -1 on error | ||
| 11 | int8_t usb_debug_putchar(uint8_t c) | ||
| 12 | { | ||
| 13 | static uint8_t previous_timeout=0; | ||
| 14 | uint8_t timeout, intr_state; | ||
| 15 | |||
| 16 | // if we're not online (enumerated and configured), error | ||
| 17 | if (!usb_configured()) return -1; | ||
| 18 | // interrupts are disabled so these functions can be | ||
| 19 | // used from the main program or interrupt context, | ||
| 20 | // even both in the same program! | ||
| 21 | intr_state = SREG; | ||
| 22 | cli(); | ||
| 23 | UENUM = DEBUG_TX_ENDPOINT; | ||
| 24 | // if we gave up due to timeout before, don't wait again | ||
| 25 | if (previous_timeout) { | ||
| 26 | if (!(UEINTX & (1<<RWAL))) { | ||
| 27 | SREG = intr_state; | ||
| 28 | return -1; | ||
| 29 | } | ||
| 30 | previous_timeout = 0; | ||
| 31 | } | ||
| 32 | // wait for the FIFO to be ready to accept data | ||
| 33 | timeout = UDFNUML + 4; | ||
| 34 | while (1) { | ||
| 35 | // are we ready to transmit? | ||
| 36 | if (UEINTX & (1<<RWAL)) break; | ||
| 37 | SREG = intr_state; | ||
| 38 | // have we waited too long? | ||
| 39 | if (UDFNUML == timeout) { | ||
| 40 | previous_timeout = 1; | ||
| 41 | return -1; | ||
| 42 | } | ||
| 43 | // has the USB gone offline? | ||
| 44 | if (!usb_configured()) return -1; | ||
| 45 | // get ready to try checking again | ||
| 46 | intr_state = SREG; | ||
| 47 | cli(); | ||
| 48 | UENUM = DEBUG_TX_ENDPOINT; | ||
| 49 | } | ||
| 50 | // actually write the byte into the FIFO | ||
| 51 | UEDATX = c; | ||
| 52 | // if this completed a packet, transmit it now! | ||
| 53 | if (!(UEINTX & (1<<RWAL))) { | ||
| 54 | UEINTX = 0x3A; | ||
| 55 | debug_flush_timer = 0; | ||
| 56 | } else { | ||
| 57 | debug_flush_timer = 2; | ||
| 58 | } | ||
| 59 | SREG = intr_state; | ||
| 60 | return 0; | ||
| 61 | } | ||
| 62 | |||
| 63 | |||
| 64 | // immediately transmit any buffered output. | ||
| 65 | void usb_debug_flush_output(void) | ||
| 66 | { | ||
| 67 | uint8_t intr_state; | ||
| 68 | |||
| 69 | intr_state = SREG; | ||
| 70 | cli(); | ||
| 71 | if (debug_flush_timer) { | ||
| 72 | UENUM = DEBUG_TX_ENDPOINT; | ||
| 73 | while ((UEINTX & (1<<RWAL))) { | ||
| 74 | UEDATX = 0; | ||
| 75 | } | ||
| 76 | UEINTX = 0x3A; | ||
| 77 | debug_flush_timer = 0; | ||
| 78 | } | ||
| 79 | SREG = intr_state; | ||
| 80 | } | ||
diff --git a/usb_debug.h b/usb_debug.h new file mode 100644 index 000000000..acc6716cd --- /dev/null +++ b/usb_debug.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | #ifndef USB_DEBUG_H | ||
| 2 | #define USB_DEBUG_H 1 | ||
| 3 | |||
| 4 | #include <stdint.h> | ||
| 5 | #include "usb_device.h" | ||
| 6 | |||
| 7 | |||
| 8 | #define DEBUG_INTERFACE 1 | ||
| 9 | #define DEBUG_TX_ENDPOINT 4 | ||
| 10 | #define DEBUG_TX_SIZE 32 | ||
| 11 | #define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER | ||
| 12 | |||
| 13 | |||
| 14 | extern volatile uint8_t debug_flush_timer; | ||
| 15 | |||
| 16 | |||
| 17 | int8_t usb_debug_putchar(uint8_t c); // transmit a character | ||
| 18 | void usb_debug_flush_output(void); // immediately transmit any buffered output | ||
| 19 | |||
| 20 | #endif | ||
diff --git a/usb_keyboard_debug.c b/usb_device.c index 9bab25e90..a6ad770ec 100644 --- a/usb_keyboard_debug.c +++ b/usb_device.c | |||
| @@ -21,11 +21,12 @@ | |||
| 21 | * THE SOFTWARE. | 21 | * THE SOFTWARE. |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | // Version 1.0: Initial Release | 24 | #include <avr/pgmspace.h> |
| 25 | // Version 1.1: Add support for Teensy 2.0 | 25 | #include <avr/interrupt.h> |
| 26 | #include "usb_device.h" | ||
| 27 | #include "usb_keyboard.h" | ||
| 28 | #include "usb_debug.h" | ||
| 26 | 29 | ||
| 27 | #define USB_SERIAL_PRIVATE_INCLUDE | ||
| 28 | #include "usb_keyboard_debug.h" | ||
| 29 | 30 | ||
| 30 | /************************************************************************** | 31 | /************************************************************************** |
| 31 | * | 32 | * |
| @@ -63,16 +64,6 @@ | |||
| 63 | 64 | ||
| 64 | #define ENDPOINT0_SIZE 32 | 65 | #define ENDPOINT0_SIZE 32 |
| 65 | 66 | ||
| 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[] = { | 67 | static const uint8_t PROGMEM endpoint_config_table[] = { |
| 77 | 0, | 68 | 0, |
| 78 | 0, | 69 | 0, |
| @@ -191,7 +182,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { | |||
| 191 | 0, // bCountryCode | 182 | 0, // bCountryCode |
| 192 | 1, // bNumDescriptors | 183 | 1, // bNumDescriptors |
| 193 | 0x22, // bDescriptorType | 184 | 0x22, // bDescriptorType |
| 194 | sizeof(keyboard_hid_report_desc), // wDescriptorLength | 185 | sizeof(keyboard_hid_report_desc), // wDescriptorLength |
| 195 | 0, | 186 | 0, |
| 196 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | 187 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
| 197 | 7, // bLength | 188 | 7, // bLength |
| @@ -255,17 +246,22 @@ static struct usb_string_descriptor_struct PROGMEM string2 = { | |||
| 255 | // This table defines which descriptor data is sent for each specific | 246 | // This table defines which descriptor data is sent for each specific |
| 256 | // request from the host (in wValue and wIndex). | 247 | // request from the host (in wValue and wIndex). |
| 257 | static struct descriptor_list_struct { | 248 | static struct descriptor_list_struct { |
| 258 | uint16_t wValue; | 249 | uint16_t wValue; // descriptor type |
| 259 | uint16_t wIndex; | 250 | uint16_t wIndex; |
| 260 | const uint8_t *addr; | 251 | const uint8_t *addr; |
| 261 | uint8_t length; | 252 | uint8_t length; |
| 262 | } PROGMEM descriptor_list[] = { | 253 | } PROGMEM descriptor_list[] = { |
| 254 | // DEVICE descriptor | ||
| 263 | {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, | 255 | {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, |
| 256 | // CONFIGURATION descriptor | ||
| 264 | {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, | 257 | {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, |
| 258 | // HID REPORT | ||
| 265 | {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)}, | 259 | {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)}, |
| 266 | {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9}, | 260 | {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9}, |
| 261 | // HID REPORT | ||
| 267 | {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)}, | 262 | {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)}, |
| 268 | {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9}, | 263 | {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9}, |
| 264 | // STRING descriptor | ||
| 269 | {0x0300, 0x0000, (const uint8_t *)&string0, 4}, | 265 | {0x0300, 0x0000, (const uint8_t *)&string0, 4}, |
| 270 | {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, | 266 | {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, |
| 271 | {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)} | 267 | {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)} |
| @@ -282,33 +278,6 @@ static struct descriptor_list_struct { | |||
| 282 | // zero when we are not configured, non-zero when enumerated | 278 | // zero when we are not configured, non-zero when enumerated |
| 283 | static volatile uint8_t usb_configuration=0; | 279 | static volatile uint8_t usb_configuration=0; |
| 284 | 280 | ||
| 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 | 281 | ||
| 313 | /************************************************************************** | 282 | /************************************************************************** |
| 314 | * | 283 | * |
| @@ -339,127 +308,6 @@ uint8_t usb_configured(void) | |||
| 339 | } | 308 | } |
| 340 | 309 | ||
| 341 | 310 | ||
| 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 | 311 | ||
| 464 | /************************************************************************** | 312 | /************************************************************************** |
| 465 | * | 313 | * |
diff --git a/usb_keyboard_debug.h b/usb_device.h index 3f3de9f12..233e439f4 100644 --- a/usb_keyboard_debug.h +++ b/usb_device.h | |||
| @@ -1,30 +1,18 @@ | |||
| 1 | #ifndef usb_serial_h__ | 1 | #ifndef USB_DEVICE_H |
| 2 | #define usb_serial_h__ | 2 | #define USB_DEVICE_H 1 |
| 3 | 3 | ||
| 4 | #include <stdint.h> | 4 | #include <stdint.h> |
| 5 | #include <avr/io.h> | ||
| 6 | #include "usb_keyboard.h" | ||
| 7 | #include "usb_debug.h" | ||
| 8 | |||
| 5 | 9 | ||
| 6 | void usb_init(void); // initialize everything | 10 | void usb_init(void); // initialize everything |
| 7 | uint8_t usb_configured(void); // is the USB port configured | 11 | uint8_t usb_configured(void); // is the USB port configured |
| 8 | 12 | ||
| 9 | int8_t usb_keyboard_press(uint8_t key, uint8_t modifier); | ||
| 10 | int8_t usb_keyboard_send(void); | ||
| 11 | extern uint8_t keyboard_modifier_keys; | ||
| 12 | extern uint8_t keyboard_keys[6]; | ||
| 13 | extern volatile uint8_t keyboard_leds; | ||
| 14 | |||
| 15 | int8_t usb_debug_putchar(uint8_t c); // transmit a character | ||
| 16 | void usb_debug_flush_output(void); // immediately transmit any buffered output | ||
| 17 | #define USB_DEBUG_HID | ||
| 18 | |||
| 19 | 13 | ||
| 20 | 14 | ||
| 21 | 15 | ||
| 22 | // Everything below this point is only intended for usb_serial.c | ||
| 23 | #ifdef USB_SERIAL_PRIVATE_INCLUDE | ||
| 24 | #include <avr/io.h> | ||
| 25 | #include <avr/pgmspace.h> | ||
| 26 | #include <avr/interrupt.h> | ||
| 27 | |||
| 28 | #define EP_TYPE_CONTROL 0x00 | 16 | #define EP_TYPE_CONTROL 0x00 |
| 29 | #define EP_TYPE_BULK_IN 0x81 | 17 | #define EP_TYPE_BULK_IN 0x81 |
| 30 | #define EP_TYPE_BULK_OUT 0x80 | 18 | #define EP_TYPE_BULK_OUT 0x80 |
| @@ -89,5 +77,5 @@ void usb_debug_flush_output(void); // immediately transmit any buffered output | |||
| 89 | #define CDC_SET_LINE_CODING 0x20 | 77 | #define CDC_SET_LINE_CODING 0x20 |
| 90 | #define CDC_GET_LINE_CODING 0x21 | 78 | #define CDC_GET_LINE_CODING 0x21 |
| 91 | #define CDC_SET_CONTROL_LINE_STATE 0x22 | 79 | #define CDC_SET_CONTROL_LINE_STATE 0x22 |
| 92 | #endif | 80 | |
| 93 | #endif | 81 | #endif |
diff --git a/usb_keyboard.c b/usb_keyboard.c new file mode 100644 index 000000000..9d41e8bc5 --- /dev/null +++ b/usb_keyboard.c | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | #include <avr/interrupt.h> | ||
| 2 | #include <avr/pgmspace.h> | ||
| 3 | #include "usb_keyboard.h" | ||
| 4 | |||
| 5 | |||
| 6 | // which modifier keys are currently pressed | ||
| 7 | // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui | ||
| 8 | // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui | ||
| 9 | uint8_t keyboard_modifier_keys=0; | ||
| 10 | |||
| 11 | // which keys are currently pressed, up to 6 keys may be down at once | ||
| 12 | uint8_t keyboard_keys[6]={0,0,0,0,0,0}; | ||
| 13 | |||
| 14 | // protocol setting from the host. We use exactly the same report | ||
| 15 | // either way, so this variable only stores the setting since we | ||
| 16 | // are required to be able to report which setting is in use. | ||
| 17 | uint8_t keyboard_protocol=1; | ||
| 18 | |||
| 19 | // the idle configuration, how often we send the report to the | ||
| 20 | // host (ms * 4) even when it hasn't changed | ||
| 21 | uint8_t keyboard_idle_config=125; | ||
| 22 | |||
| 23 | // count until idle timeout | ||
| 24 | uint8_t keyboard_idle_count=0; | ||
| 25 | |||
| 26 | // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana | ||
| 27 | volatile uint8_t keyboard_leds=0; | ||
| 28 | |||
| 29 | |||
| 30 | // perform a single keystroke | ||
| 31 | int8_t usb_keyboard_press(uint8_t key, uint8_t modifier) | ||
| 32 | { | ||
| 33 | int8_t r; | ||
| 34 | |||
| 35 | keyboard_modifier_keys = modifier; | ||
| 36 | keyboard_keys[0] = key; | ||
| 37 | r = usb_keyboard_send(); | ||
| 38 | if (r) return r; | ||
| 39 | keyboard_modifier_keys = 0; | ||
| 40 | keyboard_keys[0] = 0; | ||
| 41 | return usb_keyboard_send(); | ||
| 42 | } | ||
| 43 | |||
| 44 | // send the contents of keyboard_keys and keyboard_modifier_keys | ||
| 45 | int8_t usb_keyboard_send(void) | ||
| 46 | { | ||
| 47 | uint8_t i, intr_state, timeout; | ||
| 48 | |||
| 49 | if (!usb_configured()) return -1; | ||
| 50 | intr_state = SREG; | ||
| 51 | cli(); | ||
| 52 | UENUM = KEYBOARD_ENDPOINT; | ||
| 53 | timeout = UDFNUML + 50; | ||
| 54 | while (1) { | ||
| 55 | // are we ready to transmit? | ||
| 56 | if (UEINTX & (1<<RWAL)) break; | ||
| 57 | SREG = intr_state; | ||
| 58 | // has the USB gone offline? | ||
| 59 | if (!usb_configured()) return -1; | ||
| 60 | // have we waited too long? | ||
| 61 | if (UDFNUML == timeout) return -1; | ||
| 62 | // get ready to try checking again | ||
| 63 | intr_state = SREG; | ||
| 64 | cli(); | ||
| 65 | UENUM = KEYBOARD_ENDPOINT; | ||
| 66 | } | ||
| 67 | UEDATX = keyboard_modifier_keys; | ||
| 68 | UEDATX = 0; | ||
| 69 | for (i=0; i<6; i++) { | ||
| 70 | UEDATX = keyboard_keys[i]; | ||
| 71 | } | ||
| 72 | UEINTX = 0x3A; | ||
| 73 | keyboard_idle_count = 0; | ||
| 74 | SREG = intr_state; | ||
| 75 | return 0; | ||
| 76 | } | ||
diff --git a/usb_keyboard.h b/usb_keyboard.h new file mode 100644 index 000000000..3a9e51ce4 --- /dev/null +++ b/usb_keyboard.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #ifndef USB_KEYBOARD_H | ||
| 2 | #define USB_KEYBOARD_H 1 | ||
| 3 | |||
| 4 | #include <stdint.h> | ||
| 5 | #include "usb_device.h" | ||
| 6 | |||
| 7 | |||
| 8 | #define KEYBOARD_INTERFACE 0 | ||
| 9 | #define KEYBOARD_ENDPOINT 3 | ||
| 10 | #define KEYBOARD_SIZE 8 | ||
| 11 | #define KEYBOARD_BUFFER EP_DOUBLE_BUFFER | ||
| 12 | |||
| 13 | |||
| 14 | extern uint8_t keyboard_modifier_keys; | ||
| 15 | extern uint8_t keyboard_keys[6]; | ||
| 16 | extern uint8_t keyboard_protocol; | ||
| 17 | extern uint8_t keyboard_idle_config; | ||
| 18 | extern uint8_t keyboard_idle_count; | ||
| 19 | extern volatile uint8_t keyboard_leds; | ||
| 20 | |||
| 21 | |||
| 22 | int8_t usb_keyboard_press(uint8_t key, uint8_t modifier); | ||
| 23 | int8_t usb_keyboard_send(void); | ||
| 24 | |||
| 25 | #endif | ||
