Browse Source

revise Fn key processing.

tags/v1.9
tmk 13 years ago
parent
commit
a31b31e717
7 changed files with 293 additions and 160 deletions
  1. 5
    5
      hhkb/keymap.c
  2. 12
    13
      key_process.c
  3. 109
    56
      layer.c
  4. 9
    9
      macway/keymap.c
  5. 14
    14
      usb.c
  6. 107
    51
      usb_keyboard.c
  7. 37
    12
      usb_keyboard.h

+ 5
- 5
hhkb/keymap.c View File

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
* |-----------------------------------------------------------| * |-----------------------------------------------------------|
* |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)
* ,-----------------------------------------------------------. * ,-----------------------------------------------------------.
* ,-----------------------------------------------------------. * ,-----------------------------------------------------------.
* |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 |
* |-----------------------------------------------------------| * |-----------------------------------------------------------|


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));
} }

+ 12
- 13
key_process.c View File

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;
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)
} 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++;
} }
} }


// 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");
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");
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) {
_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)
_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)
_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)
_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");
//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;

+ 109
- 56
layer.c View File

#include "layer.h" #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 #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; static uint8_t current_layer = 0;
{ {
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) {
// 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_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; 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");
} }
} }

+ 9
- 9
macway/keymap.c View File

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
* |-----------------------------------------------------------| * |-----------------------------------------------------------|
* |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)
* ,-------------------------------------------------------- --. * ,-------------------------------------------------------- --.
* |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),






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));
} }

+ 14
- 14
usb.c View File

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++;
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; 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;
} }
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;
} }
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);
keyboard_idle_count = 0;
usb_keyboard_idle_config = (wValue >> 8);
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;

+ 107
- 51
usb_keyboard.c View File

#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;

// 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 // 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_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; uint8_t i, intr_state, timeout;


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) {
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; 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) {
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; 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");
} }

+ 37
- 12
usb_keyboard.h View File

#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;
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_press(uint8_t key, uint8_t modifier);
int8_t usb_keyboard_send(void); 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_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

Loading…
Cancel
Save