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

View file

@ -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
View file

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

View file

@ -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
View file

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

View file

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

View file

@ -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