revise Fn key processing.
This commit is contained in:
parent
45d4a7a898
commit
a31b31e717
7 changed files with 294 additions and 161 deletions
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
167
layer.c
167
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");
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
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_print();
|
||||
usb_keyboard_clear();
|
||||
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));
|
||||
}
|
||||
}
|
||||
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");
|
||||
} 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_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));
|
||||
}
|
||||
}
|
||||
layer_used = false;
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
28
usb.c
28
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;
|
||||
|
|
158
usb_keyboard.c
158
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue