revise Fn key processing.

This commit is contained in:
tmk 2010-11-03 17:33:20 +09:00
parent 45d4a7a898
commit a31b31e717
7 changed files with 294 additions and 161 deletions

View File

@ -43,7 +43,7 @@ static const uint8_t PROGMEM fn_keycode[] = {
KB_NO, // FN_1 layer 1 KB_NO, // FN_1 layer 1
KB_QUOTE, // FN_2 layer 2 KB_QUOTE, // FN_2 layer 2
KB_SCOLON, // FN_3 layer 3 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_5 [NOT USED]
KB_NO, // FN_6 [NOT USED] KB_NO, // FN_6 [NOT USED]
KB_NO // FN_7 layer 1 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| * |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, \ 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_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_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_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) /* 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| * |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 | * |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) 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));
} }

View File

@ -57,7 +57,7 @@ void proc_matrix(void) {
return; return;
} }
usb_keyboard_clear(); usb_keyboard_clear_report();
for (int row = 0; row < matrix_rows(); row++) { for (int row = 0; row < matrix_rows(); row++) {
for (int col = 0; col < matrix_cols(); col++) { for (int col = 0; col < matrix_cols(); col++) {
if (!matrix_is_on(row, col)) continue; if (!matrix_is_on(row, col)) continue;
@ -66,7 +66,7 @@ void proc_matrix(void) {
if (code == KB_NO) { if (code == KB_NO) {
// do nothing // do nothing
} else if (IS_MOD(code)) { } else if (IS_MOD(code)) {
keyboard_modifier_keys |= MOD_BIT(code); usb_keyboard_mods |= MOD_BIT(code);
} else if (IS_MOUSE(code)) { } else if (IS_MOUSE(code)) {
// mouse // mouse
if (code == MS_UP) if (code == MS_UP)
@ -91,7 +91,7 @@ void proc_matrix(void) {
} else { } else {
// normal keys // normal keys
if (key_index < 6) if (key_index < 6)
keyboard_keys[key_index] = code; usb_keyboard_keys[key_index] = code;
key_index++; key_index++;
} }
} }
@ -100,7 +100,7 @@ void proc_matrix(void) {
// when 4 left modifier keys down // when 4 left modifier keys down
if (keymap_is_special_mode(fn_bits)) { if (keymap_is_special_mode(fn_bits)) {
switch (keyboard_keys[0]) { switch (usb_keyboard_keys[0]) {
case KB_H: // help case KB_H: // help
print_enable = true; print_enable = true;
print("b: jump to bootloader\n"); print("b: jump to bootloader\n");
@ -115,7 +115,7 @@ void proc_matrix(void) {
print_enable = false; print_enable = false;
break; break;
case KB_B: // bootloader case KB_B: // bootloader
usb_keyboard_clear(); usb_keyboard_clear_report();
usb_keyboard_send(); usb_keyboard_send();
print_enable = true; print_enable = true;
print("jump to bootloader...\n"); print("jump to bootloader...\n");
@ -123,7 +123,7 @@ void proc_matrix(void) {
jump_bootloader(); // not return jump_bootloader(); // not return
break; break;
case KB_D: // debug all toggle case KB_D: // debug all toggle
usb_keyboard_clear(); usb_keyboard_clear_report();
usb_keyboard_send(); usb_keyboard_send();
debug_enable = !debug_enable; debug_enable = !debug_enable;
if (debug_enable) { if (debug_enable) {
@ -142,7 +142,7 @@ void proc_matrix(void) {
_delay_ms(1000); _delay_ms(1000);
break; break;
case KB_X: // debug matrix toggle case KB_X: // debug matrix toggle
usb_keyboard_clear(); usb_keyboard_clear_report();
usb_keyboard_send(); usb_keyboard_send();
debug_matrix = !debug_matrix; debug_matrix = !debug_matrix;
if (debug_matrix) if (debug_matrix)
@ -152,7 +152,7 @@ void proc_matrix(void) {
_delay_ms(1000); _delay_ms(1000);
break; break;
case KB_K: // debug keyboard toggle case KB_K: // debug keyboard toggle
usb_keyboard_clear(); usb_keyboard_clear_report();
usb_keyboard_send(); usb_keyboard_send();
debug_keyboard = !debug_keyboard; debug_keyboard = !debug_keyboard;
if (debug_keyboard) if (debug_keyboard)
@ -162,7 +162,7 @@ void proc_matrix(void) {
_delay_ms(1000); _delay_ms(1000);
break; break;
case KB_M: // debug mouse toggle case KB_M: // debug mouse toggle
usb_keyboard_clear(); usb_keyboard_clear_report();
usb_keyboard_send(); usb_keyboard_send();
debug_mouse = !debug_mouse; debug_mouse = !debug_mouse;
if (debug_mouse) if (debug_mouse)
@ -172,21 +172,21 @@ void proc_matrix(void) {
_delay_ms(1000); _delay_ms(1000);
break; break;
case KB_V: // print version & information case KB_V: // print version & information
usb_keyboard_clear(); usb_keyboard_clear_report();
usb_keyboard_send(); usb_keyboard_send();
print_enable = true; print_enable = true;
print(STR(DESCRIPTION) "\n"); print(STR(DESCRIPTION) "\n");
_delay_ms(1000); _delay_ms(1000);
break; break;
case KB_T: // print timer case KB_T: // print timer
usb_keyboard_clear(); usb_keyboard_clear_report();
usb_keyboard_send(); usb_keyboard_send();
print_enable = true; print_enable = true;
print("timer: "); phex16(timer_count); print("\n"); print("timer: "); phex16(timer_count); print("\n");
_delay_ms(500); _delay_ms(500);
break; break;
case KB_P: // print toggle case KB_P: // print toggle
usb_keyboard_clear(); usb_keyboard_clear_report();
usb_keyboard_send(); usb_keyboard_send();
if (print_enable) { if (print_enable) {
print("print disabled.\n"); print("print disabled.\n");
@ -224,7 +224,6 @@ void proc_matrix(void) {
//Rollover //Rollover
} }
usb_keyboard_send(); usb_keyboard_send();
usb_keyboard_print();
#ifdef DEBUG_LED #ifdef DEBUG_LED
// LED flash for debug // LED flash for debug
DEBUG_LED_CONFIG; DEBUG_LED_CONFIG;

153
layer.c
View File

@ -5,26 +5,51 @@
#include "layer.h" #include "layer.h"
/* /*
* LAYER_ENTER_DELAY: prevent from moving new layer * Parameters:
* press release * enter_delay |=======|
* Fn key sate ____|~~~~~~~~~~~~~~~~~~~|_______________ * send_fn_term |================|
* *
* enter_delay |======| * Fn key processing cases:
* new layer * 1. release Fn after send_fn_term.
* Layer sw ___________|~~~~~~~~~~~~|_______________ * 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 #define LAYER_ENTER_DELAY 10
/* // LAYER_SEND_FN_TERM: send keycode if release key in this term
* LAYER_SEND_FN_TERM: send keycode if release key in this term #define LAYER_SEND_FN_TERM 40
* press release(send)
* Fn key state ____|~~~~~~~~~~~~~|_______________
* press | release(not send)
* Fn key state ____|~~~~~~~~~~~~~|~~~~~~|__________
* | |
* send_fn_term |=============o==| x
*/
#define LAYER_SEND_FN_TERM 30
static uint8_t current_layer = 0; 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); uint8_t code = keymap_get_keycode(current_layer, row, col);
// normal key or mouse key // normal key or mouse key
if ((IS_KEY(code) || IS_MOUSE(code))) if ((IS_KEY(code) || IS_MOUSE(code))) {
layer_used = true; layer_used = true;
}
return code; return code;
} }
void layer_switching(uint8_t fn_bits) void layer_switching(uint8_t fn_bits)
{ {
// layer switching // layer switching
static uint8_t new_layer = 0;
static uint8_t last_bits = 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; static uint16_t last_timer = 0;
//uint16_t now_timer; if (fn_bits == last_bits) { // Fn key is not changed
if (current_layer != new_layer) {
if (fn_bits == last_bits) { // not switch layer yet
// switch layer when specific time elapsed if (timer_elapsed(last_timer) > LAYER_ENTER_DELAY) {
if (current_layer != keymap_fn_layer(fn_bits) && debug("Fn case: 1,2,3(switch layer)\n");
timer_elapsed(last_timer) > LAYER_ENTER_DELAY) { // case: 1,2,3
current_layer = keymap_fn_layer(fn_bits); // switch layer after LAYER_ENTER_DELAY elapse
debug("time_elapsed: "); debug_hex16(timer_elapsed(last_timer)); debug("\n"); current_layer = new_layer;
debug("timer_elapsed: "); debug_hex16(timer_elapsed(last_timer)); debug("\n");
debug("switch layer: "); debug_hex(current_layer); debug("\n"); debug("switch layer: "); debug_hex(current_layer); debug("\n");
} } else if (usb_keyboard_has_key()) {
} else if (fn_bits == 0) { debug("Fn case: 4(send Fn first, then add Fn to report)\n");
// send key when Fn key is released without using the layer and within specific time // case: 4
if ((!layer_used || current_layer != keymap_fn_layer(last_bits)) && // send only Fn key first
timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) { usb_keyboard_swap_report();
uint8_t code = keymap_fn_keycode(last_bits); usb_keyboard_clear_report();
if (code != KB_NO) { usb_keyboard_add_code(keymap_fn_keycode(last_bits));
if (IS_MOD(code)) { usb_keyboard_set_mods(last_mods);
keyboard_modifier_keys = last_mod | MOD_BIT(code);
} else {
keyboard_keys[0] = code;
keyboard_modifier_keys = last_mod;
}
usb_keyboard_send(); usb_keyboard_send();
usb_keyboard_print(); usb_keyboard_swap_report();
usb_keyboard_clear(); // 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));
} }
} }
last_bits = 0; } else { // Fn key is changed
last_mod = 0; if (fn_bits == 0) { // Fn key is released(falling edge)
layer_used = false; if (!layer_used && timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) {
current_layer = 0; // default layer debug("Fn case: 2(send Fn)\n");
} else if ((fn_bits & (fn_bits - 1)) == 0) { // send Fn key (case: 2[no layer used],3)
// switch layer when just one Fn Key is pressed 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();
}
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()) { 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));
}
}
layer_used = false;
last_bits = fn_bits; last_bits = fn_bits;
last_mod = keyboard_modifier_keys; last_mods = usb_keyboard_mods;
last_timer = timer_read(); last_timer = timer_read();
debug("new_layer: "); debug_hex(new_layer); debug("\n");
debug("last_bits: "); debug_bin(last_bits); debug("\n"); debug("last_bits: "); debug_bin(last_bits); debug("\n");
debug("last_mod: "); debug_hex(last_mod); debug("\n"); debug("last_mods: "); debug_hex(last_mods); debug("\n");
debug("last_timer: "); debug_hex16(last_timer); debug("\n"); debug("last_timer: "); debug_hex16(last_timer); debug("\n");
} }
} }
}

View File

@ -42,7 +42,7 @@ static const uint8_t PROGMEM fn_keycode[] = {
KB_NO, // FN_1 layer 1 KB_NO, // FN_1 layer 1
KB_QUOTE, // FN_2 layer 2 KB_QUOTE, // FN_2 layer 2
KB_SCOLON, // FN_3 layer 3 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_5 [NOT USED]
KB_NO, // FN_6 layer 2 KB_NO, // FN_6 layer 2
KB_NO // FN_7 layer 3 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| * |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, \ 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_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_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_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) /* 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 | * |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 | | | | | * |xxx|Gui |Alt |Mb1 |Alt | | | | |
* `-----------------------------------------------------------' * `-----------------------------------------------------------'
* Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel * 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, \ 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_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), 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) 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));
} }

28
usb.c
View File

@ -478,16 +478,16 @@ ISR(USB_GEN_vect)
UEINTX = 0x3A; UEINTX = 0x3A;
} }
} }
if (keyboard_idle_config && (++div4 & 3) == 0) { if (usb_keyboard_idle_config && (++div4 & 3) == 0) {
UENUM = KEYBOARD_ENDPOINT; UENUM = KEYBOARD_ENDPOINT;
if (UEINTX & (1<<RWAL)) { if (UEINTX & (1<<RWAL)) {
keyboard_idle_count++; usb_keyboard_idle_count++;
if (keyboard_idle_count == keyboard_idle_config) { if (usb_keyboard_idle_count == usb_keyboard_idle_config) {
keyboard_idle_count = 0; usb_keyboard_idle_count = 0;
UEDATX = keyboard_modifier_keys; UEDATX = usb_keyboard_mods;
UEDATX = 0; UEDATX = 0;
for (i=0; i<6; i++) { for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i]; UEDATX = usb_keyboard_keys[i];
} }
UEINTX = 0x3A; UEINTX = 0x3A;
} }
@ -658,23 +658,23 @@ ISR(USB_COM_vect)
if (bmRequestType == 0xA1) { if (bmRequestType == 0xA1) {
if (bRequest == HID_GET_REPORT) { if (bRequest == HID_GET_REPORT) {
usb_wait_in_ready(); usb_wait_in_ready();
UEDATX = keyboard_modifier_keys; UEDATX = usb_keyboard_mods;
UEDATX = 0; UEDATX = 0;
for (i=0; i<6; i++) { for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i]; UEDATX = usb_keyboard_keys[i];
} }
usb_send_in(); usb_send_in();
return; return;
} }
if (bRequest == HID_GET_IDLE) { if (bRequest == HID_GET_IDLE) {
usb_wait_in_ready(); usb_wait_in_ready();
UEDATX = keyboard_idle_config; UEDATX = usb_keyboard_idle_config;
usb_send_in(); usb_send_in();
return; return;
} }
if (bRequest == HID_GET_PROTOCOL) { if (bRequest == HID_GET_PROTOCOL) {
usb_wait_in_ready(); usb_wait_in_ready();
UEDATX = keyboard_protocol; UEDATX = usb_keyboard_protocol;
usb_send_in(); usb_send_in();
return; return;
} }
@ -682,20 +682,20 @@ ISR(USB_COM_vect)
if (bmRequestType == 0x21) { if (bmRequestType == 0x21) {
if (bRequest == HID_SET_REPORT) { if (bRequest == HID_SET_REPORT) {
usb_wait_receive_out(); usb_wait_receive_out();
keyboard_leds = UEDATX; usb_keyboard_leds = UEDATX;
usb_ack_out(); usb_ack_out();
usb_send_in(); usb_send_in();
return; return;
} }
if (bRequest == HID_SET_IDLE) { if (bRequest == HID_SET_IDLE) {
keyboard_idle_config = (wValue >> 8); usb_keyboard_idle_config = (wValue >> 8);
keyboard_idle_count = 0; usb_keyboard_idle_count = 0;
//usb_wait_in_ready(); //usb_wait_in_ready();
usb_send_in(); usb_send_in();
return; return;
} }
if (bRequest == HID_SET_PROTOCOL) { if (bRequest == HID_SET_PROTOCOL) {
keyboard_protocol = wValue; usb_keyboard_protocol = wValue;
//usb_wait_in_ready(); //usb_wait_in_ready();
usb_send_in(); usb_send_in();
return; return;

View File

@ -1,52 +1,40 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include "usb_keycodes.h"
#include "usb_keyboard.h" #include "usb_keyboard.h"
#include "print.h" #include "print.h"
#include "debug.h" #include "debug.h"
static bool is_sent = false; // keyboard report.
static usb_keyboard_report_t _report0 = { {0,0,0,0,0,0}, 0 };
// which modifier keys are currently pressed static usb_keyboard_report_t _report1 = { {0,0,0,0,0,0}, 0 };
// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui usb_keyboard_report_t *usb_keyboard_report = &_report0;
// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui usb_keyboard_report_t *usb_keyboard_report_back = &_report1;
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};
// protocol setting from the host. We use exactly the same report // protocol setting from the host. We use exactly the same report
// either way, so this variable only stores the setting since we // either way, so this variable only stores the setting since we
// are required to be able to report which setting is in use. // 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 // the idle configuration, how often we send the report to the
// host (ms * 4) even when it hasn't changed // 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 // 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 // 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_send(void)
int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
{ {
int8_t r; return usb_keyboard_send_report(usb_keyboard_report);
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();
} }
// 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; uint8_t i, intr_state, timeout;
@ -68,54 +56,122 @@ int8_t usb_keyboard_send(void)
cli(); cli();
UENUM = KEYBOARD_ENDPOINT; UENUM = KEYBOARD_ENDPOINT;
} }
UEDATX = keyboard_modifier_keys; UEDATX = report->mods;
UEDATX = 0; UEDATX = 0;
for (i=0; i<6; i++) { for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i]; UEDATX = report->keys[i];
} }
UEINTX = 0x3A; UEINTX = 0x3A;
keyboard_idle_count = 0; usb_keyboard_idle_count = 0;
SREG = intr_state; SREG = intr_state;
is_sent = true;
report->is_sent =true;
usb_keyboard_print_report(report);
return 0; return 0;
} }
void usb_keyboard_init(void) { void usb_keyboard_swap_report(void) {
usb_keyboard_clear(); usb_keyboard_report_t *tmp = usb_keyboard_report_back;
is_sent = false; usb_keyboard_report_back = usb_keyboard_report;
usb_keyboard_report = tmp;
} }
void usb_keyboard_clear(void) { void usb_keyboard_clear_report(void) {
usb_keyboard_clear_key(); usb_keyboard_clear_keys();
usb_keyboard_clear_mod(); usb_keyboard_clear_mods();
usb_keyboard_report->is_sent = false;
} }
void usb_keyboard_clear_key(void) { void usb_keyboard_clear_keys(void) {
for (int i = 0; i < 6; i++) keyboard_keys[i] = 0; for (int i = 0; i < 6; i++) usb_keyboard_report->keys[i] = 0;
} }
void usb_keyboard_clear_mod(void) { void usb_keyboard_clear_mods(void)
keyboard_modifier_keys = 0; {
usb_keyboard_report->mods = 0;
} }
bool usb_keyboard_is_sent(void) { void usb_keyboard_add_code(uint8_t code)
return is_sent; {
if (IS_MOD(code)) {
usb_keyboard_add_mod(code);
} else {
usb_keyboard_add_key(code);
}
} }
bool usb_keyboard_has_key(void) { 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;
}
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; 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; return keys ? true : false;
} }
bool usb_keyboard_has_mod(void) { bool usb_keyboard_has_mod(void)
return keyboard_modifier_keys ? true : false; {
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; if (!debug_keyboard) return;
print("\nkeys: "); print("keys: ");
for (int i = 0; i < 6; i++) { phex(keyboard_keys[i]); print(" "); } for (int i = 0; i < 6; i++) { phex(report->keys[i]); print(" "); }
print("\n"); print(" mods: "); phex(report->mods); print("\n");
print("mods: "); phex(keyboard_modifier_keys); print("\n");
} }

View File

@ -24,25 +24,50 @@
#define BIT_LSFT BIT_LSHIFT #define BIT_LSFT BIT_LSHIFT
#define BIT_RSFT BIT_RSHIFT #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; #define usb_keyboard_keys usb_keyboard_report->keys
extern uint8_t keyboard_keys[6]; #define usb_keyboard_mods usb_keyboard_report->mods
extern uint8_t keyboard_protocol;
extern uint8_t keyboard_idle_config;
extern uint8_t keyboard_idle_count; extern usb_keyboard_report_t *usb_keyboard_report;
extern volatile uint8_t keyboard_leds; // TODO: delete NOT USED? 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_press(uint8_t key, uint8_t modifier);
int8_t usb_keyboard_send(void); int8_t usb_keyboard_send(void);
void usb_keyboard_init(void); int8_t usb_keyboard_send_report(usb_keyboard_report_t *report);
void usb_keyboard_clear(void);
void usb_keyboard_clear_key(void); void usb_keyboard_swap_report(void);
void usb_keyboard_clear_mod(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_is_sent(void);
bool usb_keyboard_has_key(void); bool usb_keyboard_has_key(void);
bool usb_keyboard_has_mod(void); bool usb_keyboard_has_mod(void);
void usb_keyboard_print(void);
void usb_keyboard_print_report(usb_keyboard_report_t *report);
#endif #endif