diff options
author | tmk <nobody@nowhere> | 2010-11-03 17:33:20 +0900 |
---|---|---|
committer | tmk <nobody@nowhere> | 2010-11-03 17:33:20 +0900 |
commit | a31b31e717a2fa67642be33b321cde4b9b3b496a (patch) | |
tree | 94be4f4bc54bc93dc407f1bf0cef7624e346f3dd | |
parent | 45d4a7a89883c3433604d4e011b665796a583008 (diff) | |
download | firmware-a31b31e717a2fa67642be33b321cde4b9b3b496a.tar.gz firmware-a31b31e717a2fa67642be33b321cde4b9b3b496a.tar.bz2 firmware-a31b31e717a2fa67642be33b321cde4b9b3b496a.zip |
revise Fn key processing.
-rw-r--r-- | hhkb/keymap.c | 10 | ||||
-rw-r--r-- | key_process.c | 25 | ||||
-rw-r--r-- | layer.c | 165 | ||||
-rw-r--r-- | macway/keymap.c | 18 | ||||
-rw-r--r-- | usb.c | 28 | ||||
-rw-r--r-- | usb_keyboard.c | 158 | ||||
-rw-r--r-- | usb_keyboard.h | 49 |
7 files changed, 293 insertions, 160 deletions
diff --git a/hhkb/keymap.c b/hhkb/keymap.c index cad601d46..cce8fb0a0 100644 --- a/hhkb/keymap.c +++ b/hhkb/keymap.c @@ -43,7 +43,7 @@ static const uint8_t PROGMEM fn_keycode[] = { KB_NO, // FN_1 layer 1 KB_QUOTE, // FN_2 layer 2 KB_SCOLON, // FN_3 layer 3 - KB_SPACE, // FN_4 layer 4 [NOT USED] + KB_SPACE, // FN_4 layer 4 KB_NO, // FN_5 [NOT USED] KB_NO, // FN_6 [NOT USED] KB_NO // FN_7 layer 1 @@ -60,14 +60,14 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |-----------------------------------------------------------| * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn1| * `-----------------------------------------------------------' - * |Gui|Alt |Space |Alt |Fn7| + * |Gui|Alt |Fn4 |Alt |Fn7| * `-------------------------------------------' */ KEYMAP(KB_ESC, KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8, KB_9, KB_0, KB_MINS,KB_EQL, KB_BSLS,KB_GRV, \ KB_TAB, KB_Q, KB_W, KB_E, KB_R, KB_T, KB_Y, KB_U, KB_I, KB_O, KB_P, KB_LBRC,KB_RBRC,KB_BSPC, \ KB_LCTL,KB_A, KB_S, KB_D, KB_F, KB_G, KB_H, KB_J, KB_K, KB_L, FN_3, FN_2, KB_ENT, \ KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, KB_SLSH,KB_RSFT,FN_1, \ - KB_LGUI,KB_LALT,KB_SPC, KB_RALT,FN_7), + KB_LGUI,KB_LALT,FN_4, KB_RALT,FN_7), /* Layer 1: HHKB mode (HHKB Fn) * ,-----------------------------------------------------------. @@ -111,7 +111,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * ,-----------------------------------------------------------. * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| * |-----------------------------------------------------------| - * |Tab |MwL|MwU|McU|MwD|MwL|MwR|MwD|MwU|MwR| | | |Backs| + * |Tab |MwL|MwU|McU|MwD|MwR|MwL|MwD|MwU|MwR| | | |Backs| * |-----------------------------------------------------------| * |Contro| |McL|McD|McR| |McL|McD|McU|McR|xxx| |Return | * |-----------------------------------------------------------| @@ -165,5 +165,5 @@ uint8_t keymap_fn_keycode(uint8_t fn_bits) bool keymap_is_special_mode(uint8_t fn_bits) { - return (keyboard_modifier_keys == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); + return (usb_keyboard_mods == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); } diff --git a/key_process.c b/key_process.c index af0b5897a..dc75c2c61 100644 --- a/key_process.c +++ b/key_process.c @@ -57,7 +57,7 @@ void proc_matrix(void) { return; } - usb_keyboard_clear(); + usb_keyboard_clear_report(); for (int row = 0; row < matrix_rows(); row++) { for (int col = 0; col < matrix_cols(); col++) { if (!matrix_is_on(row, col)) continue; @@ -66,7 +66,7 @@ void proc_matrix(void) { if (code == KB_NO) { // do nothing } else if (IS_MOD(code)) { - keyboard_modifier_keys |= MOD_BIT(code); + usb_keyboard_mods |= MOD_BIT(code); } else if (IS_MOUSE(code)) { // mouse if (code == MS_UP) @@ -91,7 +91,7 @@ void proc_matrix(void) { } else { // normal keys if (key_index < 6) - keyboard_keys[key_index] = code; + usb_keyboard_keys[key_index] = code; key_index++; } } @@ -100,7 +100,7 @@ void proc_matrix(void) { // when 4 left modifier keys down if (keymap_is_special_mode(fn_bits)) { - switch (keyboard_keys[0]) { + switch (usb_keyboard_keys[0]) { case KB_H: // help print_enable = true; print("b: jump to bootloader\n"); @@ -115,7 +115,7 @@ void proc_matrix(void) { print_enable = false; break; case KB_B: // bootloader - usb_keyboard_clear(); + usb_keyboard_clear_report(); usb_keyboard_send(); print_enable = true; print("jump to bootloader...\n"); @@ -123,7 +123,7 @@ void proc_matrix(void) { jump_bootloader(); // not return break; case KB_D: // debug all toggle - usb_keyboard_clear(); + usb_keyboard_clear_report(); usb_keyboard_send(); debug_enable = !debug_enable; if (debug_enable) { @@ -142,7 +142,7 @@ void proc_matrix(void) { _delay_ms(1000); break; case KB_X: // debug matrix toggle - usb_keyboard_clear(); + usb_keyboard_clear_report(); usb_keyboard_send(); debug_matrix = !debug_matrix; if (debug_matrix) @@ -152,7 +152,7 @@ void proc_matrix(void) { _delay_ms(1000); break; case KB_K: // debug keyboard toggle - usb_keyboard_clear(); + usb_keyboard_clear_report(); usb_keyboard_send(); debug_keyboard = !debug_keyboard; if (debug_keyboard) @@ -162,7 +162,7 @@ void proc_matrix(void) { _delay_ms(1000); break; case KB_M: // debug mouse toggle - usb_keyboard_clear(); + usb_keyboard_clear_report(); usb_keyboard_send(); debug_mouse = !debug_mouse; if (debug_mouse) @@ -172,21 +172,21 @@ void proc_matrix(void) { _delay_ms(1000); break; case KB_V: // print version & information - usb_keyboard_clear(); + usb_keyboard_clear_report(); usb_keyboard_send(); print_enable = true; print(STR(DESCRIPTION) "\n"); _delay_ms(1000); break; case KB_T: // print timer - usb_keyboard_clear(); + usb_keyboard_clear_report(); usb_keyboard_send(); print_enable = true; print("timer: "); phex16(timer_count); print("\n"); _delay_ms(500); break; case KB_P: // print toggle - usb_keyboard_clear(); + usb_keyboard_clear_report(); usb_keyboard_send(); if (print_enable) { print("print disabled.\n"); @@ -224,7 +224,6 @@ void proc_matrix(void) { //Rollover } usb_keyboard_send(); - usb_keyboard_print(); #ifdef DEBUG_LED // LED flash for debug DEBUG_LED_CONFIG; @@ -5,26 +5,51 @@ #include "layer.h" /* - * LAYER_ENTER_DELAY: prevent from moving new layer - * press release - * Fn key sate ____|~~~~~~~~~~~~~~~~~~~|_______________ - * - * enter_delay |======| - * new layer - * Layer sw ___________|~~~~~~~~~~~~|_______________ - */ + * Parameters: + * enter_delay |=======| + * send_fn_term |================| + * + * Fn key processing cases: + * 1. release Fn after send_fn_term. + * Layer sw ___________|~~~~~~~~~~~|___ + * Fn press ___|~~~~~~~~~~~~~~~~~~~|___ + * Fn send ___________________________ + * + * 2. release Fn in send_fn_term.(not layer used) + * Layer sw ___________|~~~~~~|________ + * Fn press ___|~~~~~~~~~~~~~~|________ + * Fn key send __________________|~|______ + * other key press ___________________________ + * other key send ___________________________ + * + * 3. release Fn in send_fn_term.(layer used) + * Layer sw ___________|~~~~~~|________ + * Fn press ___|~~~~~~~~~~~~~~|________ + * Fn key send ___________________________ + * Fn send ___________________________ + * other key press _____________|~~|__________ + * other key send _____________|~~|__________ + * + * 4. press other key in ENTER_DELAY. + * Layer sw ___________________________ + * Fn key press ___|~~~~~~~~~|_____________ + * Fn key send ______|~~~~~~|_____________ + * other key press ______|~~~|________________ + * other key send _______|~~|________________ + * + * 5. press Fn while press other key. + * Layer sw ___________________________ + * Fn key press ___|~~~~~~~~~|_____________ + * Fn key send ___|~~~~~~~~~|_____________ + * other key press ~~~~~~~|___________________ + * other key send ~~~~~~~|___________________ + */ + +// LAYER_ENTER_DELAY: prevent from moving new layer #define LAYER_ENTER_DELAY 10 -/* - * LAYER_SEND_FN_TERM: send keycode if release key in this term - * press release(send) - * Fn key state ____|~~~~~~~~~~~~~|_______________ - * press | release(not send) - * Fn key state ____|~~~~~~~~~~~~~|~~~~~~|__________ - * | | - * send_fn_term |=============o==| x - */ -#define LAYER_SEND_FN_TERM 30 +// LAYER_SEND_FN_TERM: send keycode if release key in this term +#define LAYER_SEND_FN_TERM 40 static uint8_t current_layer = 0; @@ -35,58 +60,86 @@ uint8_t layer_get_keycode(uint8_t row, uint8_t col) { uint8_t code = keymap_get_keycode(current_layer, row, col); // normal key or mouse key - if ((IS_KEY(code) || IS_MOUSE(code))) + if ((IS_KEY(code) || IS_MOUSE(code))) { layer_used = true; + } return code; } void layer_switching(uint8_t fn_bits) { // layer switching + static uint8_t new_layer = 0; static uint8_t last_bits = 0; - static uint8_t last_mod = 0; + static uint8_t last_mods = 0; static uint16_t last_timer = 0; - //uint16_t now_timer; - - if (fn_bits == last_bits) { - // switch layer when specific time elapsed - if (current_layer != keymap_fn_layer(fn_bits) && - timer_elapsed(last_timer) > LAYER_ENTER_DELAY) { - current_layer = keymap_fn_layer(fn_bits); - debug("time_elapsed: "); debug_hex16(timer_elapsed(last_timer)); debug("\n"); - debug("switch layer: "); debug_hex(current_layer); debug("\n"); + if (fn_bits == last_bits) { // Fn key is not changed + if (current_layer != new_layer) { + // not switch layer yet + if (timer_elapsed(last_timer) > LAYER_ENTER_DELAY) { + debug("Fn case: 1,2,3(switch layer)\n"); + // case: 1,2,3 + // switch layer after LAYER_ENTER_DELAY elapse + current_layer = new_layer; + debug("timer_elapsed: "); debug_hex16(timer_elapsed(last_timer)); debug("\n"); + debug("switch layer: "); debug_hex(current_layer); debug("\n"); + } else if (usb_keyboard_has_key()) { + debug("Fn case: 4(send Fn first, then add Fn to report)\n"); + // case: 4 + // send only Fn key first + usb_keyboard_swap_report(); + usb_keyboard_clear_report(); + usb_keyboard_add_code(keymap_fn_keycode(last_bits)); + usb_keyboard_set_mods(last_mods); + usb_keyboard_send(); + usb_keyboard_swap_report(); + // add Fn key to send with other keys + usb_keyboard_add_code(keymap_fn_keycode(last_bits)); + // cancel layer switching + new_layer = 0; + } + } else { + if (fn_bits && new_layer == 0) { + // case: 4,5 + // send Fn key + usb_keyboard_add_code(keymap_fn_keycode(last_bits)); + } } - } else if (fn_bits == 0) { - // send key when Fn key is released without using the layer and within specific time - if ((!layer_used || current_layer != keymap_fn_layer(last_bits)) && - timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) { - uint8_t code = keymap_fn_keycode(last_bits); - if (code != KB_NO) { - if (IS_MOD(code)) { - keyboard_modifier_keys = last_mod | MOD_BIT(code); - } else { - keyboard_keys[0] = code; - keyboard_modifier_keys = last_mod; - } + } else { // Fn key is changed + if (fn_bits == 0) { // Fn key is released(falling edge) + if (!layer_used && timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) { + debug("Fn case: 2(send Fn)\n"); + // send Fn key (case: 2[no layer used],3) + usb_keyboard_swap_report(); + usb_keyboard_clear_report(); + usb_keyboard_add_code(keymap_fn_keycode(last_bits)); + usb_keyboard_set_mods(last_mods); usb_keyboard_send(); - usb_keyboard_print(); - usb_keyboard_clear(); + usb_keyboard_swap_report(); + } + debug("Fn case: 1,2,3,4,5(return to default layer)\n"); + // return to default layer(case: 1,2,3,4,5) + new_layer = 0; + current_layer = 0; + } else { // Fn Key is pressed(rising edge) + if (!usb_keyboard_has_key()) { + debug("Fn case: 1,2,3,4(ready for switching layer)\n"); + // ready for switching layer(case: 1,2,3,4) + new_layer = keymap_fn_layer(fn_bits); + } else { + debug("Fn case: 5(add Fn to report)\n"); + // add Fn key to send with other keys(case: 5) + usb_keyboard_add_code(keymap_fn_keycode(fn_bits)); } } - last_bits = 0; - last_mod = 0; layer_used = false; - current_layer = 0; // default layer - } else if ((fn_bits & (fn_bits - 1)) == 0) { - // switch layer when just one Fn Key is pressed - if (!usb_keyboard_has_key()) { - last_bits = fn_bits; - last_mod = keyboard_modifier_keys; - last_timer = timer_read(); - debug("last_bits: "); debug_bin(last_bits); debug("\n"); - debug("last_mod: "); debug_hex(last_mod); debug("\n"); - debug("last_timer: "); debug_hex16(last_timer); debug("\n"); - } + last_bits = fn_bits; + last_mods = usb_keyboard_mods; + last_timer = timer_read(); + debug("new_layer: "); debug_hex(new_layer); debug("\n"); + debug("last_bits: "); debug_bin(last_bits); debug("\n"); + debug("last_mods: "); debug_hex(last_mods); debug("\n"); + debug("last_timer: "); debug_hex16(last_timer); debug("\n"); } } diff --git a/macway/keymap.c b/macway/keymap.c index 00927a665..e78d6b7d1 100644 --- a/macway/keymap.c +++ b/macway/keymap.c @@ -42,7 +42,7 @@ static const uint8_t PROGMEM fn_keycode[] = { KB_NO, // FN_1 layer 1 KB_QUOTE, // FN_2 layer 2 KB_SCOLON, // FN_3 layer 3 - KB_SPACE, // FN_4 layer 4 [NOT USED] + KB_SPACE, // FN_4 layer 4 KB_NO, // FN_5 [NOT USED] KB_NO, // FN_6 layer 2 KB_NO // FN_7 layer 3 @@ -59,14 +59,14 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |-----------------------------------------------------------| * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn1| * |-----------------------------------------------------------| - * |Fn7|Gui |Alt |Space |Fn6 |\ |` | | | + * |Fn7|Gui |Alt |Fn4 |Fn6 |\ |` | | | * `-----------------------------------------------------------' */ KEYMAP(KB_ESC, KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8, KB_9, KB_0, KB_MINS,KB_EQL, KB_BSPC, \ KB_TAB, KB_Q, KB_W, KB_E, KB_R, KB_T, KB_Y, KB_U, KB_I, KB_O, KB_P, KB_LBRC,KB_RBRC, \ KB_LCTL,KB_A, KB_S, KB_D, KB_F, KB_G, KB_H, KB_J, KB_K, KB_L, FN_3, FN_2, KB_ENT, \ KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, KB_SLSH,KB_RSFT,FN_1, \ - FN_7, KB_LGUI,KB_LALT,KB_SPC, FN_6, KB_BSLS,KB_GRV, KB_NO, KB_NO), + FN_7, KB_LGUI,KB_LALT,FN_4, FN_6, KB_BSLS,KB_GRV, KB_NO, KB_NO), /* Layer 1: HHKB mode (HHKB Fn) @@ -113,20 +113,20 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * ,-------------------------------------------------------- --. * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | * |-----------------------------------------------------------| - * |Tab |MwL|MwU|McU|MwD|MwR|MwL|MwD|MwU|MwR| | | | | + * |Tab |MwL|MwD|McU|MwU|MwR|MwL|MwD|MwU|MwR| | | | | * |-----------------------------------------------------' | - * |Contro|Mb1|Mb2|Mb3| | |McL|McD|McU|McR|xxx| |Return | + * |Contro| |McL|McD|McR| |McL|McD|McU|McR|xxx| |Return | * |-----------------------------------------------------------| - * |Shift | | | | | |MwL|MwD|MwU|MwR| |Shift | | + * |Shift | | |Mb1|Mb2|Mb3|Mb2|Mb1| | | |Shift | | * |-----------------------------------------------------------| * |xxx|Gui |Alt |Mb1 |Alt | | | | | * `-----------------------------------------------------------' * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel */ KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_DEL, \ - KB_TAB, MS_WH_L,MS_WH_U,MS_UP, MS_WH_D,MS_WH_R,MS_WH_L,MS_WH_D,MS_WH_U,MS_WH_R,KB_NO, KB_NO, KB_NO, \ + KB_TAB, MS_WH_L,MS_WH_D,MS_UP, MS_WH_U,MS_WH_R,MS_WH_L,MS_WH_D,MS_WH_U,MS_WH_R,KB_NO, KB_NO, KB_NO, \ KB_LCTL,KB_NO, MS_LEFT,MS_DOWN,MS_RGHT,KB_NO, MS_LEFT,MS_DOWN,MS_UP, MS_RGHT,FN_3, KB_NO, KB_ENT, \ - KB_LSFT,KB_NO, MS_DOWN,KB_NO, KB_NO, KB_NO, MS_BTN2,MS_BTN1,MS_BTN2,MS_BTN3,KB_NO, KB_RSFT,KB_NO, \ + KB_LSFT,KB_NO, KB_NO, MS_BTN1,MS_BTN2,MS_BTN3,MS_BTN2,MS_BTN1,KB_NO, KB_NO, KB_NO, KB_RSFT,KB_NO, \ FN_7, KB_LGUI,KB_LALT,MS_BTN1,KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), @@ -168,5 +168,5 @@ uint8_t keymap_fn_keycode(uint8_t fn_bits) bool keymap_is_special_mode(uint8_t fn_bits) { - return (keyboard_modifier_keys == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); + return (usb_keyboard_mods == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); } @@ -478,16 +478,16 @@ ISR(USB_GEN_vect) UEINTX = 0x3A; } } - if (keyboard_idle_config && (++div4 & 3) == 0) { + if (usb_keyboard_idle_config && (++div4 & 3) == 0) { UENUM = KEYBOARD_ENDPOINT; if (UEINTX & (1<<RWAL)) { - keyboard_idle_count++; - if (keyboard_idle_count == keyboard_idle_config) { - keyboard_idle_count = 0; - UEDATX = keyboard_modifier_keys; + usb_keyboard_idle_count++; + if (usb_keyboard_idle_count == usb_keyboard_idle_config) { + usb_keyboard_idle_count = 0; + UEDATX = usb_keyboard_mods; UEDATX = 0; for (i=0; i<6; i++) { - UEDATX = keyboard_keys[i]; + UEDATX = usb_keyboard_keys[i]; } UEINTX = 0x3A; } @@ -658,23 +658,23 @@ ISR(USB_COM_vect) if (bmRequestType == 0xA1) { if (bRequest == HID_GET_REPORT) { usb_wait_in_ready(); - UEDATX = keyboard_modifier_keys; + UEDATX = usb_keyboard_mods; UEDATX = 0; for (i=0; i<6; i++) { - UEDATX = keyboard_keys[i]; + UEDATX = usb_keyboard_keys[i]; } usb_send_in(); return; } if (bRequest == HID_GET_IDLE) { usb_wait_in_ready(); - UEDATX = keyboard_idle_config; + UEDATX = usb_keyboard_idle_config; usb_send_in(); return; } if (bRequest == HID_GET_PROTOCOL) { usb_wait_in_ready(); - UEDATX = keyboard_protocol; + UEDATX = usb_keyboard_protocol; usb_send_in(); return; } @@ -682,20 +682,20 @@ ISR(USB_COM_vect) if (bmRequestType == 0x21) { if (bRequest == HID_SET_REPORT) { usb_wait_receive_out(); - keyboard_leds = UEDATX; + usb_keyboard_leds = UEDATX; usb_ack_out(); usb_send_in(); return; } if (bRequest == HID_SET_IDLE) { - keyboard_idle_config = (wValue >> 8); - keyboard_idle_count = 0; + usb_keyboard_idle_config = (wValue >> 8); + usb_keyboard_idle_count = 0; //usb_wait_in_ready(); usb_send_in(); return; } if (bRequest == HID_SET_PROTOCOL) { - keyboard_protocol = wValue; + usb_keyboard_protocol = wValue; //usb_wait_in_ready(); usb_send_in(); return; diff --git a/usb_keyboard.c b/usb_keyboard.c index dc781f017..d289af8e0 100644 --- a/usb_keyboard.c +++ b/usb_keyboard.c @@ -1,52 +1,40 @@ #include <avr/interrupt.h> #include <avr/pgmspace.h> +#include "usb_keycodes.h" #include "usb_keyboard.h" #include "print.h" #include "debug.h" -static bool is_sent = false; - -// which modifier keys are currently pressed -// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui -// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui -uint8_t keyboard_modifier_keys=0; - -// which keys are currently pressed, up to 6 keys may be down at once -uint8_t keyboard_keys[6]={0,0,0,0,0,0}; +// keyboard report. +static usb_keyboard_report_t _report0 = { {0,0,0,0,0,0}, 0 }; +static usb_keyboard_report_t _report1 = { {0,0,0,0,0,0}, 0 }; +usb_keyboard_report_t *usb_keyboard_report = &_report0; +usb_keyboard_report_t *usb_keyboard_report_back = &_report1; // protocol setting from the host. We use exactly the same report // either way, so this variable only stores the setting since we // are required to be able to report which setting is in use. -uint8_t keyboard_protocol=1; +uint8_t usb_keyboard_protocol=1; // the idle configuration, how often we send the report to the // host (ms * 4) even when it hasn't changed -uint8_t keyboard_idle_config=125; +uint8_t usb_keyboard_idle_config=125; // count until idle timeout -uint8_t keyboard_idle_count=0; +uint8_t usb_keyboard_idle_count=0; // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana -volatile uint8_t keyboard_leds=0; +volatile uint8_t usb_keyboard_leds=0; -// perform a single keystroke -int8_t usb_keyboard_press(uint8_t key, uint8_t modifier) +int8_t usb_keyboard_send(void) { - int8_t r; - - keyboard_modifier_keys = modifier; - keyboard_keys[0] = key; - r = usb_keyboard_send(); - if (r) return r; - keyboard_modifier_keys = 0; - keyboard_keys[0] = 0; - return usb_keyboard_send(); + return usb_keyboard_send_report(usb_keyboard_report); } -// send the contents of keyboard_keys and keyboard_modifier_keys -int8_t usb_keyboard_send(void) + +int8_t usb_keyboard_send_report(usb_keyboard_report_t *report) { uint8_t i, intr_state, timeout; @@ -68,54 +56,122 @@ int8_t usb_keyboard_send(void) cli(); UENUM = KEYBOARD_ENDPOINT; } - UEDATX = keyboard_modifier_keys; + UEDATX = report->mods; UEDATX = 0; for (i=0; i<6; i++) { - UEDATX = keyboard_keys[i]; + UEDATX = report->keys[i]; } UEINTX = 0x3A; - keyboard_idle_count = 0; + usb_keyboard_idle_count = 0; SREG = intr_state; - is_sent = true; + + report->is_sent =true; + + usb_keyboard_print_report(report); return 0; } -void usb_keyboard_init(void) { - usb_keyboard_clear(); - is_sent = false; +void usb_keyboard_swap_report(void) { + usb_keyboard_report_t *tmp = usb_keyboard_report_back; + usb_keyboard_report_back = usb_keyboard_report; + usb_keyboard_report = tmp; } -void usb_keyboard_clear(void) { - usb_keyboard_clear_key(); - usb_keyboard_clear_mod(); +void usb_keyboard_clear_report(void) { + usb_keyboard_clear_keys(); + usb_keyboard_clear_mods(); + usb_keyboard_report->is_sent = false; } -void usb_keyboard_clear_key(void) { - for (int i = 0; i < 6; i++) keyboard_keys[i] = 0; +void usb_keyboard_clear_keys(void) { + for (int i = 0; i < 6; i++) usb_keyboard_report->keys[i] = 0; } -void usb_keyboard_clear_mod(void) { - keyboard_modifier_keys = 0; +void usb_keyboard_clear_mods(void) +{ + usb_keyboard_report->mods = 0; } -bool usb_keyboard_is_sent(void) { - return is_sent; +void usb_keyboard_add_code(uint8_t code) +{ + if (IS_MOD(code)) { + usb_keyboard_add_mod(code); + } else { + usb_keyboard_add_key(code); + } +} + +void usb_keyboard_add_key(uint8_t code) +{ + for (int i = 0; i < 6; i++) { + if (!usb_keyboard_report->keys[i]) { + usb_keyboard_report->keys[i] = code; + return; + } + } +} + +void usb_keyboard_set_keys(uint8_t keys[6]) +{ + for (int i = 0; i < 6; i++) + usb_keyboard_report->keys[i] = keys[i]; +} + +void usb_keyboard_set_mods(uint8_t mods) +{ + usb_keyboard_report->mods = mods; } -bool usb_keyboard_has_key(void) { +void usb_keyboard_add_mod(uint8_t code) +{ + usb_keyboard_report->mods |= MOD_BIT(code); +} + +void usb_keyboard_del_code(uint8_t code) +{ + if (IS_MOD(code)) { + usb_keyboard_del_mod(code); + } else { + usb_keyboard_del_key(code); + } +} + +void usb_keyboard_del_key(uint8_t code) +{ + for (int i = 0; i < 6; i++) { + if (usb_keyboard_report->keys[i] == code) { + usb_keyboard_report->keys[i] = KB_NO; + return; + } + } +} + +void usb_keyboard_del_mod(uint8_t code) +{ + usb_keyboard_report->mods &= ~MOD_BIT(code); +} + +bool usb_keyboard_is_sent(void) +{ + return usb_keyboard_report->is_sent; +} + +bool usb_keyboard_has_key(void) +{ uint8_t keys = 0; - for (int i = 0; i < 6; i++) keys |= keyboard_keys[i]; + for (int i = 0; i < 6; i++) keys |= usb_keyboard_report->keys[i]; return keys ? true : false; } -bool usb_keyboard_has_mod(void) { - return keyboard_modifier_keys ? true : false; +bool usb_keyboard_has_mod(void) +{ + return usb_keyboard_report->mods ? true : false; } -void usb_keyboard_print(void) { +void usb_keyboard_print_report(usb_keyboard_report_t *report) +{ if (!debug_keyboard) return; - print("\nkeys: "); - for (int i = 0; i < 6; i++) { phex(keyboard_keys[i]); print(" "); } - print("\n"); - print("mods: "); phex(keyboard_modifier_keys); print("\n"); + print("keys: "); + for (int i = 0; i < 6; i++) { phex(report->keys[i]); print(" "); } + print(" mods: "); phex(report->mods); print("\n"); } diff --git a/usb_keyboard.h b/usb_keyboard.h index 691ef8b27..4be40aaaf 100644 --- a/usb_keyboard.h +++ b/usb_keyboard.h @@ -24,25 +24,50 @@ #define BIT_LSFT BIT_LSHIFT #define BIT_RSFT BIT_RSHIFT +typedef struct report { + uint8_t keys[6]; + uint8_t mods; + bool is_sent; +} usb_keyboard_report_t; -// TODO: change variable name: usb_keyboard_ or usb_kb_ -extern uint8_t keyboard_modifier_keys; -extern uint8_t keyboard_keys[6]; -extern uint8_t keyboard_protocol; -extern uint8_t keyboard_idle_config; -extern uint8_t keyboard_idle_count; -extern volatile uint8_t keyboard_leds; // TODO: delete NOT USED? + +#define usb_keyboard_keys usb_keyboard_report->keys +#define usb_keyboard_mods usb_keyboard_report->mods + + +extern usb_keyboard_report_t *usb_keyboard_report; +extern usb_keyboard_report_t *usb_keyboard_report_prev; +extern uint8_t usb_keyboard_protocol; +extern uint8_t usb_keyboard_idle_config; +extern uint8_t usb_keyboard_idle_count; +extern volatile uint8_t usb_keyboard_leds; int8_t usb_keyboard_press(uint8_t key, uint8_t modifier); int8_t usb_keyboard_send(void); -void usb_keyboard_init(void); -void usb_keyboard_clear(void); -void usb_keyboard_clear_key(void); -void usb_keyboard_clear_mod(void); +int8_t usb_keyboard_send_report(usb_keyboard_report_t *report); + +void usb_keyboard_swap_report(void); + +void usb_keyboard_clear_report(void); +void usb_keyboard_clear_keys(void); +void usb_keyboard_clear_mods(void); + +void usb_keyboard_set_keys(uint8_t keys[6]); +void usb_keyboard_set_mods(uint8_t mods); + +void usb_keyboard_add_code(uint8_t code); +void usb_keyboard_add_key(uint8_t code); +void usb_keyboard_add_mod(uint8_t code); + +void usb_keyboard_del_code(uint8_t code); +void usb_keyboard_del_key(uint8_t code); +void usb_keyboard_del_mod(uint8_t code); + bool usb_keyboard_is_sent(void); bool usb_keyboard_has_key(void); bool usb_keyboard_has_mod(void); -void usb_keyboard_print(void); + +void usb_keyboard_print_report(usb_keyboard_report_t *report); #endif |