aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2010-11-03 17:33:20 +0900
committertmk <nobody@nowhere>2010-11-03 17:33:20 +0900
commita31b31e717a2fa67642be33b321cde4b9b3b496a (patch)
tree94be4f4bc54bc93dc407f1bf0cef7624e346f3dd
parent45d4a7a89883c3433604d4e011b665796a583008 (diff)
downloadfirmware-a31b31e717a2fa67642be33b321cde4b9b3b496a.tar.gz
firmware-a31b31e717a2fa67642be33b321cde4b9b3b496a.tar.bz2
firmware-a31b31e717a2fa67642be33b321cde4b9b3b496a.zip
revise Fn key processing.
-rw-r--r--hhkb/keymap.c10
-rw-r--r--key_process.c25
-rw-r--r--layer.c165
-rw-r--r--macway/keymap.c18
-rw-r--r--usb.c28
-rw-r--r--usb_keyboard.c158
-rw-r--r--usb_keyboard.h49
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;
diff --git a/layer.c b/layer.c
index 5b9b591fe..9251e042e 100644
--- a/layer.c
+++ b/layer.c
@@ -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));
}
diff --git a/usb.c b/usb.c
index 5c3240a47..3011ecb2a 100644
--- a/usb.c
+++ b/usb.c
@@ -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