summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.mk10
-rw-r--r--common/action.c151
-rw-r--r--common/action.h6
-rw-r--r--common/action_code.h14
-rw-r--r--common/action_oneshot.c21
-rw-r--r--common/action_oneshot.h52
-rw-r--r--common/action_tapping.c39
-rw-r--r--common/action_util.c213
-rw-r--r--common/action_util.h56
-rw-r--r--common/bootloader.c7
-rw-r--r--common/bootmagic.c4
-rw-r--r--common/bootmagic.h40
-rw-r--r--common/command.c47
-rw-r--r--common/host.c150
-rw-r--r--common/host.h17
-rw-r--r--common/keyboard.c3
-rw-r--r--common/keyboard.h19
-rw-r--r--common/keymap.c3
-rw-r--r--common/suspend.c3
-rw-r--r--converter/adb_usb/Makefile108
-rw-r--r--converter/adb_usb/Makefile.blargg (renamed from converter/adb_usb/Makefile.lufa)4
-rw-r--r--converter/adb_usb/Makefile.pjrc63
-rw-r--r--converter/adb_usb/adb_blargg.c216
-rw-r--r--converter/adb_usb/adb_blargg.h38
-rw-r--r--converter/adb_usb/config.h6
-rw-r--r--converter/adb_usb/led.c5
-rw-r--r--converter/adb_usb/matrix.c12
-rw-r--r--converter/m0110_usb/Makefile3
-rw-r--r--converter/m0110_usb/README.md128
-rw-r--r--converter/m0110_usb/config.h12
-rw-r--r--converter/m0110_usb/doc/m0110.jpgbin49360 -> 0 bytes
-rw-r--r--converter/m0110_usb/doc/teensy.jpgbin50081 -> 0 bytes
-rw-r--r--converter/m0110_usb/keymap.c139
-rw-r--r--converter/news_usb/config_pjrc.h6
-rw-r--r--converter/ps2_usb/config.h6
-rw-r--r--doc/keymap.md21
-rw-r--r--keyboard/IIgs/config.h6
-rw-r--r--keyboard/hhkb/Makefile18
-rw-r--r--keyboard/hhkb/config.h3
-rw-r--r--keyboard/hhkb/config_iwrap.h5
-rw-r--r--keyboard/hhkb/config_vusb.h6
-rw-r--r--keyboard/hhkb/keymap.c19
-rw-r--r--ldscript_keymap_avr5.x268
-rw-r--r--protocol/adb.c217
-rw-r--r--protocol/lufa/lufa.c9
-rw-r--r--protocol/m0110.c50
-rw-r--r--protocol/pjrc/main.c3
-rw-r--r--protocol/pjrc/usb.c1
48 files changed, 1516 insertions, 711 deletions
diff --git a/common.mk b/common.mk
index 47d5c852f3..5b70db9499 100644
--- a/common.mk
+++ b/common.mk
@@ -3,9 +3,9 @@ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/keyboard.c \
$(COMMON_DIR)/action.c \
$(COMMON_DIR)/action_tapping.c \
- $(COMMON_DIR)/action_oneshot.c \
$(COMMON_DIR)/action_macro.c \
$(COMMON_DIR)/action_layer.c \
+ $(COMMON_DIR)/action_util.c \
$(COMMON_DIR)/keymap.c \
$(COMMON_DIR)/timer.c \
$(COMMON_DIR)/print.c \
@@ -68,6 +68,14 @@ ifdef BACKLIGHT_ENABLE
OPT_DEFS += -DBACKLIGHT_ENABLE
endif
+ifdef KEYMAP_SECTION_ENABLE
+ OPT_DEFS += -DKEYMAP_SECTION_ENABLE
+ EXTRALDFLAGS = -Wl,-L$(TOP_DIR),-Tldscript_keymap_avr5.x
+endif
+
+# Version string
+OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null)
+
# Search Path
VPATH += $(TOP_DIR)/common
diff --git a/common/action.c b/common/action.c
index 59c6f252dc..f7ae85b941 100644
--- a/common/action.c
+++ b/common/action.c
@@ -23,8 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "backlight.h"
#include "action_layer.h"
#include "action_tapping.h"
-#include "action_oneshot.h"
#include "action_macro.h"
+#include "action_util.h"
#include "action.h"
#ifdef DEBUG_ACTION
@@ -79,15 +79,15 @@ void process_action(keyrecord_t *record)
action.key.mods<<4;
if (event.pressed) {
if (mods) {
- host_add_mods(mods);
- host_send_keyboard_report();
+ add_weak_mods(mods);
+ send_keyboard_report();
}
register_code(action.key.code);
} else {
unregister_code(action.key.code);
if (mods) {
- host_del_mods(mods);
- host_send_keyboard_report();
+ del_weak_mods(mods);
+ send_keyboard_report();
}
}
}
@@ -100,43 +100,30 @@ void process_action(keyrecord_t *record)
action.key.mods<<4;
switch (action.layer_tap.code) {
#ifndef NO_ACTION_ONESHOT
- case 0x00:
+ case MODS_ONESHOT:
// Oneshot modifier
if (event.pressed) {
if (tap_count == 0) {
- dprint("MODS_TAP: Oneshot: add_mods\n");
- add_mods(mods);
+ register_mods(mods);
}
else if (tap_count == 1) {
dprint("MODS_TAP: Oneshot: start\n");
- oneshot_start(mods);
- }
- else if (tap_count == TAPPING_TOGGLE) {
- dprint("MODS_TAP: Oneshot: toggle\n");
- oneshot_toggle();
+ set_oneshot_mods(mods);
}
else {
- dprint("MODS_TAP: Oneshot: cancel&add_mods\n");
- // double tap cancels oneshot and works as normal modifier.
- oneshot_cancel();
- add_mods(mods);
+ register_mods(mods);
}
} else {
if (tap_count == 0) {
- dprint("MODS_TAP: Oneshot: cancel/del_mods\n");
- // cancel oneshot on hold
- oneshot_cancel();
- del_mods(mods);
+ clear_oneshot_mods();
+ unregister_mods(mods);
}
else if (tap_count == 1) {
- dprint("MODS_TAP: Oneshot: del_mods\n");
- // retain Oneshot
- del_mods(mods);
+ // Retain Oneshot mods
}
else {
- dprint("MODS_TAP: Oneshot: del_mods\n");
- // cancel Mods
- del_mods(mods);
+ clear_oneshot_mods();
+ unregister_mods(mods);
}
}
break;
@@ -148,14 +135,14 @@ void process_action(keyrecord_t *record)
dprint("MODS_TAP: Tap: Cancel: add_mods\n");
// ad hoc: set 0 to cancel tap
record->tap.count = 0;
- add_mods(mods);
+ register_mods(mods);
} else {
dprint("MODS_TAP: Tap: register_code\n");
register_code(action.key.code);
}
} else {
dprint("MODS_TAP: No tap: add_mods\n");
- add_mods(mods);
+ register_mods(mods);
}
} else {
if (tap_count > 0) {
@@ -163,7 +150,7 @@ void process_action(keyrecord_t *record)
unregister_code(action.key.code);
} else {
dprint("MODS_TAP: No tap: add_mods\n");
- del_mods(mods);
+ unregister_mods(mods);
}
}
break;
@@ -343,30 +330,30 @@ void register_code(uint8_t code)
// Resync: ignore if caps lock already is on
if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
#endif
- host_add_key(KC_CAPSLOCK);
- host_send_keyboard_report();
- host_del_key(KC_CAPSLOCK);
- host_send_keyboard_report();
+ add_key(KC_CAPSLOCK);
+ send_keyboard_report();
+ del_key(KC_CAPSLOCK);
+ send_keyboard_report();
}
else if (KC_LOCKING_NUM == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) return;
#endif
- host_add_key(KC_NUMLOCK);
- host_send_keyboard_report();
- host_del_key(KC_NUMLOCK);
- host_send_keyboard_report();
+ add_key(KC_NUMLOCK);
+ send_keyboard_report();
+ del_key(KC_NUMLOCK);
+ send_keyboard_report();
}
else if (KC_LOCKING_SCROLL == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) return;
#endif
- host_add_key(KC_SCROLLLOCK);
- host_send_keyboard_report();
- host_del_key(KC_SCROLLLOCK);
- host_send_keyboard_report();
+ add_key(KC_SCROLLLOCK);
+ send_keyboard_report();
+ del_key(KC_SCROLLLOCK);
+ send_keyboard_report();
}
#endif
@@ -375,25 +362,28 @@ void register_code(uint8_t code)
if (command_proc(code)) return;
#ifndef NO_ACTION_ONESHOT
+/* TODO: remove
if (oneshot_state.mods && !oneshot_state.disabled) {
- uint8_t tmp_mods = host_get_mods();
- host_add_mods(oneshot_state.mods);
+ uint8_t tmp_mods = get_mods();
+ add_mods(oneshot_state.mods);
- host_add_key(code);
- host_send_keyboard_report();
+ add_key(code);
+ send_keyboard_report();
- host_set_mods(tmp_mods);
+ set_mods(tmp_mods);
+ send_keyboard_report();
oneshot_cancel();
} else
+*/
#endif
{
- host_add_key(code);
- host_send_keyboard_report();
+ add_key(code);
+ send_keyboard_report();
}
}
else if IS_MOD(code) {
- host_add_mods(MOD_BIT(code));
- host_send_keyboard_report();
+ add_mods(MOD_BIT(code));
+ send_keyboard_report();
}
else if IS_SYSTEM(code) {
host_system_send(KEYCODE2SYSTEM(code));
@@ -415,40 +405,40 @@ void unregister_code(uint8_t code)
// Resync: ignore if caps lock already is off
if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
#endif
- host_add_key(KC_CAPSLOCK);
- host_send_keyboard_report();
- host_del_key(KC_CAPSLOCK);
- host_send_keyboard_report();
+ add_key(KC_CAPSLOCK);
+ send_keyboard_report();
+ del_key(KC_CAPSLOCK);
+ send_keyboard_report();
}
else if (KC_LOCKING_NUM == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) return;
#endif
- host_add_key(KC_NUMLOCK);
- host_send_keyboard_report();
- host_del_key(KC_NUMLOCK);
- host_send_keyboard_report();
+ add_key(KC_NUMLOCK);
+ send_keyboard_report();
+ del_key(KC_NUMLOCK);
+ send_keyboard_report();
}
else if (KC_LOCKING_SCROLL == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (!(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK))) return;
#endif
- host_add_key(KC_SCROLLLOCK);
- host_send_keyboard_report();
- host_del_key(KC_SCROLLLOCK);
- host_send_keyboard_report();
+ add_key(KC_SCROLLLOCK);
+ send_keyboard_report();
+ del_key(KC_SCROLLLOCK);
+ send_keyboard_report();
}
#endif
else if IS_KEY(code) {
- host_del_key(code);
- host_send_keyboard_report();
+ del_key(code);
+ send_keyboard_report();
}
else if IS_MOD(code) {
- host_del_mods(MOD_BIT(code));
- host_send_keyboard_report();
+ del_mods(MOD_BIT(code));
+ send_keyboard_report();
}
else if IS_SYSTEM(code) {
host_system_send(0);
@@ -458,38 +448,33 @@ void unregister_code(uint8_t code)
}
}
-void add_mods(uint8_t mods)
+void register_mods(uint8_t mods)
{
if (mods) {
- host_add_mods(mods);
- host_send_keyboard_report();
+ add_mods(mods);
+ send_keyboard_report();
}
}
-void del_mods(uint8_t mods)
+void unregister_mods(uint8_t mods)
{
if (mods) {
- host_del_mods(mods);
- host_send_keyboard_report();
+ del_mods(mods);
+ send_keyboard_report();
}
}
-void set_mods(uint8_t mods)
-{
- host_set_mods(mods);
- host_send_keyboard_report();
-}
-
void clear_keyboard(void)
{
- host_clear_mods();
+ clear_mods();
clear_keyboard_but_mods();
}
void clear_keyboard_but_mods(void)
{
- host_clear_keys();
- host_send_keyboard_report();
+ clear_weak_mods();
+ clear_keys();
+ send_keyboard_report();
#ifdef MOUSEKEY_ENABLE
mousekey_clear();
mousekey_send();
@@ -502,7 +487,7 @@ void clear_keyboard_but_mods(void)
bool sending_anykey(void)
{
- return (host_has_anykey() || host_mouse_in_use() ||
+ return (has_anykey() || host_mouse_in_use() ||
host_last_sysytem_report() || host_last_consumer_report());
}
diff --git a/common/action.h b/common/action.h
index 8f1f5b7986..d57f4a86ff 100644
--- a/common/action.h
+++ b/common/action.h
@@ -59,9 +59,9 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
void process_action(keyrecord_t *record);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
-void add_mods(uint8_t mods);
-void del_mods(uint8_t mods);
-void set_mods(uint8_t mods);
+void register_mods(uint8_t mods);
+void unregister_mods(uint8_t mods);
+//void set_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
bool sending_anykey(void);
diff --git a/common/action_code.h b/common/action_code.h
index 45e974a668..c153838f2b 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -29,13 +29,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 000r|0000|0000 0001 Transparent code
* 000r|0000| keycode Key
* 000r|mods|0000 0000 Modifiers
- * 000r|mods| keycode Key and Modifiers
+ * 000r|mods| keycode Modifiers+Key(Modified key)
* r: Left/Right flag(Left:0, Right:1)
*
* ACT_MODS_TAP(001r):
* 001r|mods|0000 0000 Modifiers with OneShot
* 001r|mods|0000 00xx (reserved)
- * 001r|mods| keycode Modifiers with Tap Key
+ * 001r|mods| keycode Modifiers with Tap Key(Dual role)
*
*
* Other Keys(01xx)
@@ -69,7 +69,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 1001|oopp|BBBB BBBB 8-bit Bitwise Operation???
*
* ACT_LAYER_TAP(101x):
- * 101E|LLLL| keycode Invert with tap key
+ * 101E|LLLL| keycode On/Off with tap key
* 101E|LLLL|1110 xxxx Reserved(0xE0-EF)
* 101E|LLLL|1111 0000 Invert with tap toggle(0xF0)
* 101E|LLLL|1111 0001 On/Off
@@ -207,10 +207,10 @@ enum mods_codes {
MODS_ONESHOT = 0x00,
};
#define ACTION_KEY(key) ACTION(ACT_MODS, (key))
-#define ACTION_MODS(mods) ACTION(ACT_MODS, (mods)<<8 | 0)
-#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, (mods)<<8 | (key))
-#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, (mods)<<8 | (key))
-#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, (mods)<<8 | MODS_ONESHOT)
+#define ACTION_MODS(mods) ACTION(ACT_MODS, (mods&0x1f)<<8 | 0)
+#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, (mods&0x1f)<<8 | (key))
+#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, (mods&0x1f)<<8 | (key))
+#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, (mods&0x1f)<<8 | MODS_ONESHOT)
/*
diff --git a/common/action_oneshot.c b/common/action_oneshot.c
deleted file mode 100644
index d34f44b5ab..0000000000
--- a/common/action_oneshot.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "action_oneshot.h"
-
-
-#ifndef NO_ACTION_ONESHOT
-oneshot_state_t oneshot_state;
-
-void oneshot_start(uint8_t mods)
-{
- oneshot_state.mods = mods;
-}
-
-void oneshot_cancel(void)
-{
- oneshot_state.mods = 0;
-}
-
-void oneshot_toggle(void)
-{
- oneshot_state.disabled = !oneshot_state.disabled;
-}
-#endif
diff --git a/common/action_oneshot.h b/common/action_oneshot.h
deleted file mode 100644
index 36ef9e9bce..0000000000
--- a/common/action_oneshot.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-Copyright 2013 Jun Wako <wakojun@gmail.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef ACTION_ONESHOT_H
-#define ACTION_ONESHOT_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#ifdef NO_ACTION_TAPPING
- #define NO_ACTION_ONESHOT
-#endif
-
-#ifndef NO_ACTION_ONESHOT
-/* Oneshot modifier
- *
- * Problem: Want to capitalize like 'The' but the result tends to be 'THe'.
- * Solution: Oneshot modifier have its effect on only one key coming next.
- * Tap Shift, then type 't', 'h' and 'e'. Not need to hold Shift key.
- *
- * Hold: works as normal modifier.
- * Tap: one shot modifier.
- * 2 Tap: cancel one shot modifier.
- * 5-Tap: toggles enable/disable oneshot feature.
- */
-typedef struct {
- uint8_t mods;
- bool disabled;
-} oneshot_state_t;
-
-
-oneshot_state_t oneshot_state;
-
-void oneshot_start(uint8_t mods);
-void oneshot_cancel(void);
-void oneshot_toggle(void);
-#endif
-
-#endif
diff --git a/common/action_tapping.c b/common/action_tapping.c
index a6292535ed..826c233096 100644
--- a/common/action_tapping.c
+++ b/common/action_tapping.c
@@ -1,7 +1,9 @@
#include <stdint.h>
#include <stdbool.h>
#include "action.h"
+#include "action_layer.h"
#include "action_tapping.h"
+#include "keycode.h"
#include "timer.h"
#ifdef DEBUG_ACTION
@@ -27,9 +29,7 @@ static uint8_t waiting_buffer_tail = 0;
static bool process_tapping(keyrecord_t *record);
static bool waiting_buffer_enq(keyrecord_t record);
static void waiting_buffer_clear(void);
-#if TAPPING_TERM >= 500
static bool waiting_buffer_typed(keyevent_t event);
-#endif
static bool waiting_buffer_has_anykey_pressed(void);
static void waiting_buffer_scan_tap(void);
static void debug_tapping_key(void);
@@ -97,18 +97,43 @@ bool process_tapping(keyrecord_t *keyp)
return false;
}
#if TAPPING_TERM >= 500
- /* This can settle mod/fn state fast but may prevent from typing fast. */
- else if (!event.pressed && waiting_buffer_typed(event)) {
- // other key typed. not tap.
+ /* Process a key typed within TAPPING_TERM
+ * This can register the key before settlement of tapping,
+ * useful for long TAPPING_TERM but may prevent fast typing.
+ */
+ else if (IS_RELEASED(event) && waiting_buffer_typed(event)) {
debug("Tapping: End. No tap. Interfered by typing key\n");
process_action(&tapping_key);
tapping_key = (keyrecord_t){};
debug_tapping_key();
-
// enqueue
return false;
}
#endif
+ /* Process release event of a key pressed before tapping starts
+ * Without this unexpected repeating will occur with having fast repeating setting
+ * https://github.com/tmk/tmk_keyboard/issues/60
+ */
+ else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) {
+ // Modifier should be retained till end of this tapping.
+ action_t action = layer_switch_get_action(event.key);
+ switch (action.kind.id) {
+ case ACT_LMODS:
+ case ACT_RMODS:
+ if (action.key.mods && !action.key.code) return false;
+ if (IS_MOD(action.key.code)) return false;
+ break;
+ case ACT_LMODS_TAP:
+ case ACT_RMODS_TAP:
+ if (action.key.mods && keyp->tap.count == 0) return false;
+ if (IS_MOD(action.key.code)) return false;
+ break;
+ }
+ // Release of key should be process immediately.
+ debug("Tapping: release event of a key pressed before tapping\n");
+ process_action(keyp);
+ return true;
+ }
else {
// set interrupted flag when other key preesed during tapping
if (event.pressed) {
@@ -289,7 +314,6 @@ void waiting_buffer_clear(void)
waiting_buffer_tail = 0;
}
-#if TAPPING_TERM >= 500
bool waiting_buffer_typed(keyevent_t event)
{
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
@@ -299,7 +323,6 @@ bool waiting_buffer_typed(keyevent_t event)
}
return false;
}
-#endif
bool waiting_buffer_has_anykey_pressed(void)
{
diff --git a/common/action_util.c b/common/action_util.c
new file mode 100644
index 0000000000..99a3adaab6
--- /dev/null
+++ b/common/action_util.c
@@ -0,0 +1,213 @@
+/*
+Copyright 2013 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "host.h"
+#include "report.h"
+#include "debug.h"
+#include "action_util.h"
+#include "timer.h"
+
+static inline void add_key_byte(uint8_t code);
+static inline void del_key_byte(uint8_t code);
+#ifdef NKRO_ENABLE
+static inline void add_key_bit(uint8_t code);
+static inline void del_key_bit(uint8_t code);
+#endif
+
+static uint8_t real_mods = 0;
+static uint8_t weak_mods = 0;
+
+
+// TODO: pointer variable is not needed
+//report_keyboard_t keyboard_report = {};
+report_keyboard_t *keyboard_report = &(report_keyboard_t){};
+
+#ifndef NO_ACTION_ONESHOT
+static int8_t oneshot_mods = 0;
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+static int16_t oneshot_time = 0;
+#endif
+#endif
+
+
+void send_keyboard_report(void) {
+ keyboard_report->mods = real_mods;
+ keyboard_report->mods |= weak_mods;
+#ifndef NO_ACTION_ONESHOT
+ if (oneshot_mods) {
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) {
+ dprintf("Oneshot: timeout\n");
+ clear_oneshot_mods();
+ }
+#endif
+ keyboard_report->mods |= oneshot_mods;
+ if (has_anykey()) {
+ clear_oneshot_mods();
+ }
+ }
+#endif
+ host_keyboard_send(keyboard_report);
+}
+
+/* key */
+void add_key(uint8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_nkro) {
+ add_key_bit(key);
+ return;
+ }
+#endif
+ add_key_byte(key);
+}
+
+void del_key(uint8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_nkro) {
+ del_key_bit(key);
+ return;
+ }
+#endif
+ del_key_byte(key);
+}
+
+void clear_keys(void)
+{
+ // not clear mods
+ for (int8_t i = 1; i < REPORT_SIZE; i+