summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-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
18 files changed, 480 insertions, 365 deletions
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++) {
+ keyboard_report->raw[i] = 0;
+ }
+}
+
+
+/* modifier */
+uint8_t get_mods(void) { return real_mods; }
+void add_mods(uint8_t mods) { real_mods |= mods; }
+void del_mods(uint8_t mods) { real_mods &= ~mods; }
+void set_mods(uint8_t mods) { real_mods = mods; }
+void clear_mods(void) { real_mods = 0; }
+
+/* weak modifier */
+uint8_t get_weak_mods(void) { return weak_mods; }
+void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
+void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
+void set_weak_mods(uint8_t mods) { weak_mods = mods; }
+void clear_weak_mods(void) { weak_mods = 0; }
+
+/* Oneshot modifier */
+#ifndef NO_ACTION_ONESHOT
+void set_oneshot_mods(uint8_t mods)
+{
+ oneshot_mods = mods;
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ oneshot_time = timer_read();
+#endif
+}
+void clear_oneshot_mods(void)
+{
+ oneshot_mods = 0;
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ oneshot_time = 0;
+#endif
+}
+#endif
+
+
+
+
+/*
+ * inspect keyboard state
+ */
+uint8_t has_anykey(void)
+{
+ uint8_t cnt = 0;
+ for (uint8_t i = 1; i < REPORT_SIZE; i++) {
+ if (keyboard_report->raw[i])
+ cnt++;
+ }
+ return cnt;
+}
+
+uint8_t has_anymod(void)
+{
+ return bitpop(real_mods);
+}
+
+uint8_t get_first_key(void)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_nkro) {
+ uint8_t i = 0;
+ for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
+ ;
+ return i<<3 | biton(keyboard_report->nkro.bits[i]);
+ }
+#endif
+ return keyboard_report->keys[0];
+}
+
+
+
+/* local functions */
+static inline void add_key_byte(uint8_t code)
+{
+ int8_t i = 0;
+ int8_t empty = -1;
+ for (; i < REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ break;
+ }
+ if (empty == -1 && keyboard_report->keys[i] == 0) {
+ empty = i;
+ }
+ }
+ if (i == REPORT_KEYS) {
+ if (empty != -1) {
+ keyboard_report->keys[empty] = code;
+ }
+ }
+}
+
+static inline void del_key_byte(uint8_t code)
+{
+ for (uint8_t i = 0; i < REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ keyboard_report->keys[i] = 0;
+ }
+ }
+}
+
+#ifdef NKRO_ENABLE
+static inline void add_key_bit(uint8_t code)
+{
+ if ((code>>3) < REPORT_BITS) {
+ keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
+ } else {
+ dprintf("add_key_bit: can't add: %02X\n", code);
+ }
+}
+
+static inline void del_key_bit(uint8_t code)
+{
+ if ((code>>3) < REPORT_BITS) {
+ keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
+ } else {
+ dprintf("del_key_bit: can't del: %02X\n", code);
+ }
+}
+#endif
diff --git a/common/action_util.h b/common/action_util.h
new file mode 100644
index 0000000000..939bc2b662
--- /dev/null
+++ b/common/action_util.h
@@ -0,0 +1,56 @@
+/*
+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_UTIL_H
+#define ACTION_UTIL_H
+
+#include <stdint.h>
+
+extern report_keyboard_t *keyboard_report;
+
+void send_keyboard_report(void);
+
+/* key */
+void add_key(uint8_t key);
+void del_key(uint8_t key);
+void clear_keys(void);
+
+/* modifier */
+uint8_t get_mods(void);
+void add_mods(uint8_t mods);
+void del_mods(uint8_t mods);
+void set_mods(uint8_t mods);
+void clear_mods(void);
+
+/* weak modifier */
+uint8_t get_weak_mods(void);
+void add_weak_mods(uint8_t mods);
+void del_weak_mods(uint8_t mods);
+void set_weak_mods(uint8_t mods);
+void clear_weak_mods(void);
+
+/* oneshot modifier */
+void set_oneshot_mods(uint8_t mods);
+void clear_oneshot_mods(void);
+void oneshot_toggle(void);
+void oneshot_enable(void);
+void oneshot_disable(void);
+
+/* inspect */
+uint8_t has_anykey(void);
+uint8_t has_anymod(void);
+uint8_t get_first_key(void);
+#endif
diff --git a/common/bootloader.c b/common/bootloader.c
index 43a7e47ce2..cda295b181 100644
--- a/common/bootloader.c
+++ b/common/bootloader.c
@@ -71,7 +71,8 @@ void bootloader_jump_after_watchdog_reset(void)
MCUSR &= ~(1<<WDRF);
wdt_disable();
- ((void (*)(void))BOOTLOADER_START)();
+ // This is compled into 'icall', address should be in word unit, not byte.
+ ((void (*)(void))(BOOTLOADER_START/2))();
}
}
@@ -141,7 +142,7 @@ void bootloader_jump(void) {
ADCSRA = 0; TWCR = 0; UCSR0B = 0;
#endif
- // start Bootloader
- ((void (*)(void))BOOTLOADER_START)();
+ // This is compled into 'icall', address should be in word unit, not byte.
+ ((void (*)(void))(BOOTLOADER_START/2))();
}
#endif
diff --git a/common/bootmagic.c b/common/bootmagic.c
index 410dc68364..036d490440 100644
--- a/common/bootmagic.c
+++ b/common/bootmagic.c
@@ -18,8 +18,10 @@ void bootmagic(void)
}
/* do scans in case of bounce */
+ print("boogmagic scan: ... ");
uint8_t scan = 100;
while (scan--) { matrix_scan(); _delay_ms(10); }
+ print("done.\n");
/* bootmagic skip */
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) {
@@ -53,7 +55,7 @@ void bootmagic(void)
/* keymap config */
keymap_config.raw = eeconfig_read_keymap();
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CPASLOCK)) {
+ if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) {
keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock;
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) {
diff --git a/common/bootmagic.h b/common/bootmagic.h
index 2d14b3e763..7c19223973 100644
--- a/common/bootmagic.h
+++ b/common/bootmagic.h
@@ -23,34 +23,72 @@
#endif
/* debug enable */
+#ifndef BOOTMAGIC_KEY_DEBUG_ENABLE
#define BOOTMAGIC_KEY_DEBUG_ENABLE KC_D
+#endif
+#ifndef BOOTMAGIC_KEY_DEBUG_MATRIX
#define BOOTMAGIC_KEY_DEBUG_MATRIX KC_X
+#endif
+#ifndef BOOTMAGIC_KEY_DEBUG_KEYBOARD
#define BOOTMAGIC_KEY_DEBUG_KEYBOARD KC_K
+#endif
+#ifndef BOOTMAGIC_KEY_DEBUG_MOUSE
#define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M
+#endif
/*
* keymap config
*/
-#define BOOTMAGIC_KEY_SWAP_CONTROL_CPASLOCK KC_LCTRL
+#ifndef BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK
+#define BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK KC_LCTRL
+#endif
+#ifndef BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL
#define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_CAPSLOCK
+#endif
+#ifndef BOOTMAGIC_KEY_SWAP_LALT_LGUI
#define BOOTMAGIC_KEY_SWAP_LALT_LGUI KC_LALT
+#endif
+#ifndef BOOTMAGIC_KEY_SWAP_RALT_RGUI
#define BOOTMAGIC_KEY_SWAP_RALT_RGUI KC_RALT
+#endif
+#ifndef BOOTMAGIC_KEY_NO_GUI
#define BOOTMAGIC_KEY_NO_GUI KC_LGUI
+#endif
+#ifndef BOOTMAGIC_KEY_SWAP_GRAVE_ESC
#define BOOTMAGIC_KEY_SWAP_GRAVE_ESC KC_GRAVE
+#endif
+#ifndef BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE
#define BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE KC_BSLASH
+#endif
/*
* change default layer
*/
+#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_0
#define BOOTMAGIC_KEY_DEFAULT_LAYER_0 KC_0
+#endif
+#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_1
#define BOOTMAGIC_KEY_DEFAULT_LAYER_1 KC_1
+#endif
+#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_2
#define BOOTMAGIC_KEY_DEFAULT_LAYER_2 KC_2
+#endif
+#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_3
#define BOOTMAGIC_KEY_DEFAULT_LAYER_3 KC_3
+#endif
+#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_4
#define BOOTMAGIC_KEY_DEFAULT_LAYER_4 KC_4
+#endif
+#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_5
#define BOOTMAGIC_KEY_DEFAULT_LAYER_5 KC_5
+#endif
+#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_6
#define BOOTMAGIC_KEY_DEFAULT_LAYER_6 KC_6
+#endif
+#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_7
#define BOOTMAGIC_KEY_DEFAULT_LAYER_7 KC_7
+#endif
void bootmagic(void);
diff --git a/common/command.c b/common/command.c
index 4649e00ab0..f6f2769513 100644
--- a/common/command.c
+++ b/common/command.c
@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "keyboard.h"
#include "bootloader.h"
#include "action_layer.h"
+#include "action_util.h"
#include "eeconfig.h"
#include "sleep_led.h"
#include "led.h"
@@ -251,10 +252,48 @@ static bool command_common(uint8_t code)
break;
case KC_V: // print version & information
print("\n\n----- Version -----\n");
- print(STR(DESCRIPTION) "\n");
- print(STR(MANUFACTURER) "(" STR(VENDOR_ID) ")/");
- print(STR(PRODUCT) "(" STR(PRODUCT_ID) ") ");
- print("VERSION: " STR(DEVICE_VER) "\n");
+ print("DESC: " STR(DESCRIPTION) "\n");
+ print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
+ "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
+ "VER: " STR(DEVICE_VER) "\n");
+ print("BUILD: " STR(VERSION) " (" __TIME__ " " __DATE__ ")\n");
+ /* build options */
+ print("OPTIONS:"
+#ifdef PROTOCOL_PJRC
+ " PJRC"
+#endif
+#ifdef PROTOCOL_LUFA
+ " LUFA"
+#endif
+#ifdef PROTOCOL_VUSB
+ " VUSB"
+#endif
+#ifdef BOOTMAGIC_ENABLE
+ " BOOTMAGIC"
+#endif
+#ifdef MOUSEKEY_ENABLE
+ " MOUSEKEY"
+#endif
+#ifdef EXTRAKEY_ENABLE
+ " EXTRAKEY"
+#endif
+#ifdef CONSOLE_ENABLE
+ " CONSOLE"
+#endif
+#ifdef COMMAND_ENABLE
+ " COMMAND"
+#endif
+#ifdef NKRO_ENABLE
+ " NKRO"
+#endif
+#ifdef KEYMAP_SECTION_ENABLE
+ " KEYMAP_SECTION"
+#endif
+ " " STR(BOOTLOADER_SIZE) "\n");
+
+ print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
+ " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__
+ " AVR_ARCH: avr" STR(__AVR_ARCH__) "\n");
break;
case KC_T: // print timer
print_val_hex32(timer_count);
diff --git a/common/host.c b/common/host.c
index 5694516527..0703dba013 100644
--- a/common/host.c
+++ b/common/host.c
@@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
bool keyboard_nkro = false;
#endif
-report_keyboard_t *keyboard_report = &(report_keyboard_t){};
report_mouse_t mouse_report = {};
@@ -35,13 +34,6 @@ static host_driver_t *driver;
static uint16_t last_system_report = 0;
static uint16_t last_consumer_report = 0;
-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
-
void host_set_driver(host_driver_t *d)
{
@@ -67,7 +59,7 @@ void host_keyboard_send(report_keyboard_t *report)
if (debug_keyboard) {
dprint("keyboard_report: ");
for (uint8_t i = 0; i < REPORT_SIZE; i++) {
- dprintf("%02X ", keyboard_report->raw[i]);
+ dprintf("%02X ", report->raw[i]);
}
dprint("\n");
}
@@ -97,98 +89,6 @@ void host_consumer_send(uint16_t report)
(*driver->send_consumer)(report);
}
-
-
-/* keyboard report utils */
-void host_add_key(uint8_t key)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_nkro) {
- add_key_bit(key);
- return;
- }
-#endif
- add_key_byte(key);
-}
-
-void host_del_key(uint8_t key)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_nkro) {
- del_key_bit(key);
- return;
- }
-#endif
- del_key_byte(key);
-}
-
-void host_clear_keys(void)
-{
- // not clea mods
- for (int8_t i = 1; i < REPORT_SIZE; i++) {
- keyboard_report->raw[i] = 0;
- }
-}
-
-uint8_t host_get_mods(void)
-{
- return keyboard_report->mods;
-}
-
-void host_add_mods(uint8_t mods)
-{
- keyboard_report->mods |= mods;
-}
-
-void host_del_mods(uint8_t mods)
-{
- keyboard_report->mods &= ~mods;
-}
-
-void host_set_mods(uint8_t mods)
-{
- keyboard_report->mods = mods;
-}
-
-void host_clear_mods(void)
-{
- keyboard_report->mods = 0;
-}
-
-uint8_t host_has_anykey(void)
-{
- uint8_t cnt = 0;
- for (uint8_t i = 1; i < REPORT_SIZE; i++) {
- if (keyboard_report->raw[i])
- cnt++;
- }
- return cnt;
-}
-
-uint8_t host_has_anymod(void)
-{
- return bitpop(keyboard_report->mods);
-}
-
-uint8_t host_get_first_key(void)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_nkro) {
- uint8_t i = 0;
- for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
- ;
- return i<<3 | biton(keyboard_report->nkro.bits[i]);
- }
-#endif
- return keyboard_report->keys[0];
-}
-
-void host_send_keyboard_report(void)
-{
- if (!driver) return;
- host_keyboard_send(keyboard_report);
-}
-
uint8_t host_mouse_in_use(void)
{
return (mouse_report.buttons | mouse_report.x | mouse_report.y | mouse_report.v | mouse_report.h);
@@ -203,51 +103,3 @@ uint16_t host_last_consumer_report(void)
{
return last_consumer_report;
}
-
-static inline void add_key_byte(uint8_t code)
-{
- int8_t i = 0;
- int8_t empty = -1;
- for (; i < REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- break;
- }
- if (empty == -1 && keyboard_report->keys[i] == 0) {
- empty = i;
- }
- }
- if (i == REPORT_KEYS) {
- if (empty != -1) {
- keyboard_report->keys[empty] = code;
- }
- }
-}
-
-static inline void del_key_byte(uint8_t code)
-{
- for (uint8_t i = 0; i < REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- keyboard_report->keys[i] = 0;
- }
- }
-}
-
-#ifdef NKRO_ENABLE
-static inline void add_key_bit(uint8_t code)
-{
- if ((code>>3) < REPORT_BITS) {
- keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
- } else {
- dprintf("add_key_bit: can't add: %02X\n", code);
- }
-}
-
-static inline void del_key_bit(uint8_t code)
-{
- if ((code>>3) < REPORT_BITS) {
- keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
- } else {
- dprintf("del_key_bit: can't del: %02X\n", code);
- }
-}
-#endif
diff --git a/common/host.h b/common/host.h
index 7c4f06601d..c1a0fbac40 100644
--- a/common/host.h
+++ b/common/host.h
@@ -33,7 +33,6 @@ extern bool keyboard_nkro;
#endif
/* report */
-extern report_keyboard_t *keyboard_report;
extern report_mouse_t mouse_report;
@@ -48,22 +47,6 @@ void host_mouse_send(report_mouse_t *report);
void host_system_send(uint16_t data);
void host_consumer_send(uint16_t data);
-/* keyboard report utils */
-void host_add_key(uint8_t key);
-void host_del_key(uint8_t key);
-void host_clear_keys(void);
-
-uint8_t host_get_mods(void);
-void host_add_mods(uint8_t mods);
-void host_del_mods(uint8_t mods);
-void host_set_mods(uint8_t mods);
-void host_clear_mods(void);
-
-uint8_t host_has_anykey(void);
-uint8_t host_has_anymod(void);
-uint8_t host_get_first_key(void);
-void host_send_keyboard_report(void);
-
/* mouse report utils */
uint8_t host_mouse_in_use(void);
diff --git a/common/keyboard.c b/common/keyboard.c
index d1821a099f..601e3abe17 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -54,9 +54,6 @@ static bool has_ghost_in_row(uint8_t row)
void keyboard_init(void)
{
- // TODO: configuration of sendchar impl
- print_set_sendchar(sendchar);
-
timer_init();
matrix_init();
#ifdef PS2_MOUSE_ENABLE
diff --git a/common/keyboard.h b/common/keyboard.h
index 78cb24034f..d1a922420b 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -42,16 +42,15 @@ typedef struct {
/* equivalent test of key_t */
#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
-/* (time == 0) means no event and assumes matrix has no 255 line. */
-#define IS_NOEVENT(event) ((event).time == 0 || ((event).key.row == 255 && (event).key.col == 255))
-
-#define NOEVENT (keyevent_t){ \
- .key = (key_t){ .row = 255, .col = 255 }, \
- .pressed = false, \
- .time = 0 \
-}
-
-/* tick event */
+/* Rules for No Event:
+ * 1) (time == 0) to handle (keyevent_t){} as empty event
+ * 2) Matrix(255, 255) to make TICK event available
+ */
+static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); }
+static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); }
+static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); }
+
+/* Tick event */
#define TICK (keyevent_t){ \
.key = (key_t){ .row = 255, .col = 255 }, \
.pressed = false, \
diff --git a/common/keymap.c b/common/keymap.c
index cf4711bf66..bfb8ffac1a 100644
--- a/common/keymap.c
+++ b/common/keymap.c
@@ -36,10 +36,11 @@ action_t action_for_key(uint8_t layer, key_t key)
return keymap_fn_to_action(keycode);
#ifdef BOOTMAGIC_ENABLE
case KC_CAPSLOCK:
+ case KC_LOCKING_CAPS:
if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) {
return keycode_to_action(KC_LCTL);
}
- return keycode_to_action(KC_CAPS);
+ return keycode_to_action(keycode);
case KC_LCTL:
if (keymap_config.swap_control_capslock) {
return keycode_to_action(KC_CAPSLOCK);
diff --git a/common/suspend.c b/common/suspend.c
index 146b96d5cc..5b378892f3 100644
--- a/common/suspend.c
+++ b/common/suspend.c
@@ -51,8 +51,7 @@ bool suspend_wakeup_condition(void)
// run immediately after wakeup
void suspend_wakeup_init(void)
{
- // clear matrix and keyboard state
- matrix_init();
+ // clear keyboard state
clear_keyboard();
#ifdef BACKLIGHT_ENABLE
backlight_init();