summary refs log tree commit diff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/action_code.h2
-rw-r--r--common/action_macro.c2
-rw-r--r--common/action_util.c6
-rw-r--r--common/avr/bootloader.c49
-rw-r--r--common/avr/suspend.c2
-rw-r--r--common/command.c198
-rw-r--r--common/keyboard.c6
-rw-r--r--common/keyboard.h8
-rw-r--r--common/keycode.h9
-rw-r--r--common/keymap.c6
-rw-r--r--common/led.h8
-rw-r--r--common/matrix.h4
12 files changed, 179 insertions, 121 deletions
diff --git a/common/action_code.h b/common/action_code.h
index 32ef07216d..4fe9c1d581 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -266,7 +266,7 @@ enum layer_pram_tap_op {
 #define ACTION_LAYER_ON_OFF(layer)                  ACTION_LAYER_TAP((layer), OP_ON_OFF)
 #define ACTION_LAYER_OFF_ON(layer)                  ACTION_LAYER_TAP((layer), OP_OFF_ON)
 #define ACTION_LAYER_SET_CLEAR(layer)               ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
-#define ACTION_LAYER_MODS(layer, mods)              ACTION_LAYER_TAP((layer), 0xe0 | (mods)&0x0f)
+#define ACTION_LAYER_MODS(layer, mods)              ACTION_LAYER_TAP((layer), 0xe0 | ((mods)&0x0f))
 /* With Tapping */
 #define ACTION_LAYER_TAP_KEY(layer, key)            ACTION_LAYER_TAP((layer), (key))
 #define ACTION_LAYER_TAP_TOGGLE(layer)              ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)
diff --git a/common/action_macro.c b/common/action_macro.c
index ba93fc8b23..ffaf125c06 100644
--- a/common/action_macro.c
+++ b/common/action_macro.c
@@ -42,6 +42,7 @@ void action_macro_play(const macro_t *macro_p)
                 dprintf("KEY_DOWN(%02X)\n", macro);
                 if (IS_MOD(macro)) {
                     add_weak_mods(MOD_BIT(macro));
+                    send_keyboard_report();
                 } else {
                     register_code(macro);
                 }
@@ -51,6 +52,7 @@ void action_macro_play(const macro_t *macro_p)
                 dprintf("KEY_UP(%02X)\n", macro);
                 if (IS_MOD(macro)) {
                     del_weak_mods(MOD_BIT(macro));
+                    send_keyboard_report();
                 } else {
                     unregister_code(macro);
                 }
diff --git a/common/action_util.c b/common/action_util.c
index dbee630d18..f81877dd9f 100644
--- a/common/action_util.c
+++ b/common/action_util.c
@@ -76,7 +76,7 @@ void send_keyboard_report(void) {
 void add_key(uint8_t key)
 {
 #ifdef NKRO_ENABLE
-    if (keyboard_nkro) {
+    if (keyboard_protocol && keyboard_nkro) {
         add_key_bit(key);
         return;
     }
@@ -87,7 +87,7 @@ void add_key(uint8_t key)
 void del_key(uint8_t key)
 {
 #ifdef NKRO_ENABLE
-    if (keyboard_nkro) {
+    if (keyboard_protocol && keyboard_nkro) {
         del_key_bit(key);
         return;
     }
@@ -160,7 +160,7 @@ uint8_t has_anymod(void)
 uint8_t get_first_key(void)
 {
 #ifdef NKRO_ENABLE
-    if (keyboard_nkro) {
+    if (keyboard_protocol && keyboard_nkro) {
         uint8_t i = 0;
         for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
             ;
diff --git a/common/avr/bootloader.c b/common/avr/bootloader.c
index cda295b181..7c744e8c79 100644
--- a/common/avr/bootloader.c
+++ b/common/avr/bootloader.c
@@ -11,12 +11,49 @@
 #endif
 
 
-/* Boot Section Size in *BYTEs*
- *   Teensy   halfKay    512
- *   Teensy++ halfKay    1024
- *   Atmel DFU loader    4096
- *   LUFA bootloader     4096
- *   USBaspLoader        2048
+/* Bootloader Size in *bytes*
+ *
+ * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet.
+ * Note that 'Word'(2 bytes) size and address are used in datasheet while TMK uses 'Byte'.
+ *
+ *
+ * Size of Bootloaders in bytes:
+ *   Atmel DFU loader(ATmega32U4)   4096
+ *   Atmel DFU loader(AT90USB128)   8192
+ *   LUFA bootloader(ATmega32U4)    4096
+ *   Arduino Caterina(ATmega32U4)   4096
+ *   USBaspLoader(ATmega***)        2048
+ *   Teensy   halfKay(ATmega32U4)   512
+ *   Teensy++ halfKay(AT90USB128)   1024
+ *
+ *
+ * AVR Boot section is located at the end of Flash memory like the followings.
+ *
+ *
+ * byte     Atmel/LUFA(ATMega32u4)          byte     Atmel(AT90SUB128)
+ * 0x0000   +---------------+               0x00000  +---------------+
+ *          |               |                        |               |
+ *          |               |                        |               |
+ *          |  Application  |                        |  Application  |
+ *          |               |                        |               |
+ *          =               =                        =               =
+ *          |               | 32KB-4KB               |               | 128KB-8KB
+ * 0x6000   +---------------+               0x1FC00  +---------------+
+ *          |  Bootloader   | 4KB                    |  Bootloader   | 8KB
+ * 0x7FFF   +---------------+               0x1FFFF  +---------------+
+ *
+ *
+ * byte     Teensy(ATMega32u4)              byte     Teensy++(AT90SUB128)
+ * 0x0000   +---------------+               0x00000  +---------------+
+ *          |               |                        |               |
+ *          |               |                        |               |
+ *          |  Application  |                        |  Application  |
+ *          |               |                        |               |
+ *          =               =                        =               =
+ *          |               | 32KB-512B              |               | 128KB-1KB
+ * 0x7E00   +---------------+               0x1FC00  +---------------+
+ *          |  Bootloader   | 512B                   |  Bootloader   | 1KB
+ * 0x7FFF   +---------------+               0x1FFFF  +---------------+
  */
 #ifndef BOOTLOADER_SIZE
 #warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h.
diff --git a/common/avr/suspend.c b/common/avr/suspend.c
index 80243f02bc..af99f52b5e 100644
--- a/common/avr/suspend.c
+++ b/common/avr/suspend.c
@@ -85,6 +85,8 @@ void suspend_power_down(void)
     power_down(WDTO_15MS);
 }
 
+__attribute__ ((weak)) void matrix_power_up(void) {}
+__attribute__ ((weak)) void matrix_power_down(void) {}
 bool suspend_wakeup_condition(void)
 {
     matrix_power_up();
diff --git a/common/command.c b/common/command.c
index fbaa9f2d75..d59bb01bbc 100644
--- a/common/command.c
+++ b/common/command.c
@@ -112,30 +112,33 @@ bool command_console_extra(uint8_t code)
  ***********************************************************/
 static void command_common_help(void)
 {
-    print("\n\n----- Command Help -----\n");
-    print("c:	enter console mode\n");
-    print("d:	toggle debug enable\n");
-    print("x:	toggle matrix debug\n");
-    print("k:	toggle keyboard debug\n");
-    print("m:	toggle mouse debug\n");
-#ifdef SLEEP_LED_ENABLE
-    print("z:	toggle sleep LED test\n");
+    print("\n\t- Magic -\n"
+          "d:	debug\n"
+          "x:	debug matrix\n"
+          "k:	debug keyboard\n"
+          "m:	debug mouse\n"
+          "v:	version\n"
+          "s:	status\n"
+          "c:	console mode\n"
+          "0-4:	layer0-4(F10-F4)\n"
+          "Paus:	bootloader\n"
+
+#ifdef KEYBOARD_LOCK_ENABLE
+          "Caps:	Lock\n"
+#endif
+
+#ifdef BOOTMAGIC_ENABLE
+          "e:	eeprom\n"
 #endif
-    print("v:	print device version & info\n");
-    print("t:	print timer count\n");
-    print("s:	print status\n");
-    print("e:	print eeprom config\n");
+
 #ifdef NKRO_ENABLE
-    print("n:	toggle NKRO\n");
+          "n:	NKRO\n"
+#endif
+
+#ifdef SLEEP_LED_ENABLE
+          "z:	sleep LED test\n"
 #endif
-    print("0/F10:	switch to Layer0 \n");
-    print("1/F1:	switch to Layer1 \n");
-    print("2/F2:	switch to Layer2 \n");
-    print("3/F3:	switch to Layer3 \n");
-    print("4/F4:	switch to Layer4 \n");
-    print("PScr:	power down/remote wake-up\n");
-    print("Caps:	Lock Keyboard(Child Proof)\n");
-    print("Paus:	jump to bootloader\n");
+    );
 }
 
 #ifdef BOOTMAGIC_ENABLE
@@ -191,6 +194,7 @@ static bool command_common(uint8_t code)
             print_eeconfig();
             break;
 #endif
+#ifdef KEYBOARD_LOCK_ENABLE
         case KC_CAPSLOCK:
             if (host_get_driver()) {
                 host_driver = host_get_driver();
@@ -202,6 +206,7 @@ static bool command_common(uint8_t code)
                 print("Unlocked.\n");
             }
             break;
+#endif
         case KC_H:
         case KC_SLASH: /* ? */
             command_common_help();
@@ -212,58 +217,56 @@ static bool command_common(uint8_t code)
             debug_mouse    = false;
             debug_enable   = false;
             command_console_help();
-            print("\nEnter Console Mode\n");
             print("C> ");
             command_state = CONSOLE;
             break;
         case KC_PAUSE:
             clear_keyboard();
-            print("\n\nJump to bootloader... ");
+            print("\n\nbootloader... ");
             _delay_ms(1000);
             bootloader_jump(); // not return
-            print("not supported.\n");
             break;
         case KC_D:
             if (debug_enable) {
-                print("\nDEBUG: disabled.\n");
+                print("\ndebug: off\n");
                 debug_matrix   = false;
                 debug_keyboard = false;
                 debug_mouse    = false;
                 debug_enable   = false;
             } else {
-                print("\nDEBUG: enabled.\n");
+                print("\ndebug: on\n");
                 debug_enable   = true;
             }
             break;
         case KC_X: // debug matrix toggle
             debug_matrix = !debug_matrix;
             if (debug_matrix) {
-                print("\nDEBUG: matrix enabled.\n");
+                print("\nmatrix: on\n");
                 debug_enable = true;
             } else {
-                print("\nDEBUG: matrix disabled.\n");
+                print("\nmatrix: off\n");
             }
             break;
         case KC_K: // debug keyboard toggle
             debug_keyboard = !debug_keyboard;
             if (debug_keyboard) {
-                print("\nDEBUG: keyboard enabled.\n");
+                print("\nkeyboard: on\n");
                 debug_enable = true;
             } else {
-                print("\nDEBUG: keyboard disabled.\n");
+                print("\nkeyboard: off\n");
             }
             break;
         case KC_M: // debug mouse toggle
             debug_mouse = !debug_mouse;
             if (debug_mouse) {
-                print("\nDEBUG: mouse enabled.\n");
+                print("\nmouse: on\n");
                 debug_enable = true;
             } else {
-                print("\nDEBUG: mouse disabled.\n");
+                print("\nmouse: off\n");
             }
             break;
         case KC_V: // print version & information
-            print("\n\n----- Version -----\n");
+            print("\n\t- Version -\n");
             print("DESC: " STR(DESCRIPTION) "\n");
             print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
                   "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
@@ -307,14 +310,16 @@ static bool command_common(uint8_t code)
                   " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__
                   " AVR_ARCH: avr" STR(__AVR_ARCH__) "\n");
             break;
-        case KC_T: // print timer
-            print_val_hex32(timer_count);
-            break;
         case KC_S:
-            print("\n\n----- Status -----\n");
+            print("\n\t- Status -\n");
             print_val_hex8(host_keyboard_leds());
             print_val_hex8(keyboard_protocol);
             print_val_hex8(keyboard_idle);
+#ifdef NKRO_ENABLE
+            print_val_hex8(keyboard_nkro);
+#endif
+            print_val_hex32(timer_count);
+
 #ifdef PROTOCOL_PJRC
             print_val_hex8(UDCON);
             print_val_hex8(UDIEN);
@@ -334,39 +339,21 @@ static bool command_common(uint8_t code)
             clear_keyboard(); //Prevents stuck keys.
             keyboard_nkro = !keyboard_nkro;
             if (keyboard_nkro)
-                print("NKRO: enabled\n");
+                print("NKRO: on\n");
             else
-                print("NKRO: disabled\n");
-            break;
-#endif
-#ifdef EXTRAKEY_ENABLE
-        case KC_PSCREEN:
-            // TODO: Power key should take this feature? otherwise any key during suspend.
-#ifdef PROTOCOL_PJRC
-            if (suspend && remote_wakeup) {
-                usb_remote_wakeup();
-            } else {
-                host_system_send(SYSTEM_POWER_DOWN);
-                host_system_send(0);
-                _delay_ms(500);
-            }
-#else
-            host_system_send(SYSTEM_POWER_DOWN);
-            _delay_ms(100);
-            host_system_send(0);
-            _delay_ms(500);
-#endif
+                print("NKRO: off\n");
             break;
 #endif
         case KC_ESC:
         case KC_GRV:
         case KC_0:
+        case KC_F10:
             switch_default_layer(0);
             break;
         case KC_1 ... KC_9:
             switch_default_layer((code - KC_1) + 1);
             break;
-        case KC_F1 ... KC_F12:
+        case KC_F1 ... KC_F9:
             switch_default_layer((code - KC_F1) + 1);
             break;
         default:
@@ -382,11 +369,12 @@ static bool command_common(uint8_t code)
  ***********************************************************/
 static void command_console_help(void)
 {
-    print("\n\n----- Console Help -----\n");
-    print("ESC/q:	quit\n");
+    print("\n\t- Console -\n"
+          "ESC/q:	quit\n"
 #ifdef MOUSEKEY_ENABLE
-    print("m:	mousekey\n");
+          "m:	mousekey\n"
 #endif
+    );
 }
 
 static bool command_console(uint8_t code)
@@ -398,14 +386,12 @@ static bool command_console(uint8_t code)
             break;
         case KC_Q:
         case KC_ESC:
-            print("\nQuit Console Mode\n");
             command_state = ONESHOT;
             return false;
 #ifdef MOUSEKEY_ENABLE
         case KC_M:
             mousekey_console_help();
-            print("\nEnter Mousekey Console\n");
-            print("M0>");
+            print("M> ");
             command_state = MOUSEKEY;
             return true;
 #endif
@@ -426,16 +412,17 @@ static uint8_t mousekey_param = 0;
 
 static void mousekey_param_print(void)
 {
-    print("\n\n----- Mousekey Parameters -----\n");
-    print("1: mk_delay(*10ms): "); pdec(mk_delay); print("\n");
-    print("2: mk_interval(ms): "); pdec(mk_interval); print("\n");
-    print("3: mk_max_speed: "); pdec(mk_max_speed); print("\n");
-    print("4: mk_time_to_max: "); pdec(mk_time_to_max); print("\n");
-    print("5: mk_wheel_max_speed: "); pdec(mk_wheel_max_speed); print("\n");
-    print("6: mk_wheel_time_to_max: "); pdec(mk_wheel_time_to_max); print("\n");
+    print("\n\t- Values -\n");
+    print("1: delay(*10ms): "); pdec(mk_delay); print("\n");
+    print("2: interval(ms): "); pdec(mk_interval); print("\n");
+    print("3: max_speed: "); pdec(mk_max_speed); print("\n");
+    print("4: time_to_max: "); pdec(mk_time_to_max); print("\n");
+    print("5: wheel_max_speed: "); pdec(mk_wheel_max_speed); print("\n");
+    print("6: wheel_time_to_max: "); pdec(mk_wheel_time_to_max); print("\n");
 }
 
-#define PRINT_SET_VAL(v)  print(#v " = "); print_dec(v); print("\n");
+//#define PRINT_SET_VAL(v)  print(#v " = "); print_dec(v); print("\n");
+#define PRINT_SET_VAL(v)  xprintf(#v " = %d\n", (v))
 static void mousekey_param_inc(uint8_t param, uint8_t inc)
 {
     switch (param) {
@@ -534,24 +521,25 @@ static void mousekey_param_dec(uint8_t param, uint8_t dec)
 
 static void mousekey_console_help(void)
 {
-    print("\n\n----- Mousekey Parameters Help -----\n");
-    print("ESC/q:	quit\n");
-    print("1:	select mk_delay(*10ms)\n");
-    print("2:	select mk_interval(ms)\n");
-    print("3:	select mk_max_speed\n");
-    print("4:	select mk_time_to_max\n");
-    print("5:	select mk_wheel_max_speed\n");
-    print("6:	select mk_wheel_time_to_max\n");
-    print("p:	print parameters\n");
-    print("d:	set default values\n");
-    print("up:	increase parameters(+1)\n");
-    print("down:	decrease parameters(-1)\n");
-    print("pgup:	increase parameters(+10)\n");
-    print("pgdown:	decrease parameters(-10)\n");
-    print("\nspeed = delta * max_speed * (repeat / time_to_max)\n");
-    print("where delta: cursor="); pdec(MOUSEKEY_MOVE_DELTA);
-    print(", wheel="); pdec(MOUSEKEY_WHEEL_DELTA); print("\n");
-    print("See http://en.wikipedia.org/wiki/Mouse_keys\n");
+    print("\n\t- Mousekey -\n"
+          "ESC/q:	quit\n"
+          "1:	delay(*10ms)\n"
+          "2:	interval(ms)\n"
+          "3:	max_speed\n"
+          "4:	time_to_max\n"
+          "5:	wheel_max_speed\n"
+          "6:	wheel_time_to_max\n"
+          "\n"
+          "p:	print values\n"
+          "d:	set defaults\n"
+          "up:	+1\n"
+          "down:	-1\n"
+          "pgup:	+10\n"
+          "pgdown:	-10\n"
+          "\n"
+          "speed = delta * max_speed * (repeat / time_to_max)\n");
+    xprintf("where delta: cursor=%d, wheel=%d\n" 
+            "See http://en.wikipedia.org/wiki/Mouse_keys\n", MOUSEKEY_MOVE_DELTA,  MOUSEKEY_WHEEL_DELTA);
 }
 
 static bool mousekey_console(uint8_t code)
@@ -563,11 +551,14 @@ static bool mousekey_console(uint8_t code)
             break;
         case KC_Q:
         case KC_ESC:
-            mousekey_param = 0;
-            print("\nQuit Mousekey Console\n");
-            print("C> ");
-            command_state = CONSOLE;
-            return false;
+            if (mousekey_param) {
+                mousekey_param = 0;
+            } else {
+                print("C> ");
+                command_state = CONSOLE;
+                return false;
+            }
+            break;
         case KC_P:
             mousekey_param_print();
             break;
@@ -577,12 +568,7 @@ static bool mousekey_console(uint8_t code)
         case KC_4:
         case KC_5:
         case KC_6:
-        case KC_7:
-        case KC_8:
-        case KC_9:
-        case KC_0:
             mousekey_param = numkey2num(code);
-            print("selected parameter: "); pdec(mousekey_param); print("\n");
             break;
         case KC_UP:
             mousekey_param_inc(mousekey_param, 1);
@@ -603,13 +589,16 @@ static bool mousekey_console(uint8_t code)
             mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
             mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
             mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
-            print("set default values.\n");
+            print("set default\n");
             break;
         default:
             print("?");
             return false;
     }
-    print("M"); pdec(mousekey_param); print("> ");
+    if (mousekey_param)
+        xprintf("M%d> ", mousekey_param);
+    else
+        print("M>" );
     return true;
 }
 #endif
@@ -637,8 +626,7 @@ static uint8_t numkey2num(uint8_t code)
 
 static void switch_default_layer(uint8_t layer)
 {
-    print("switch_default_layer: "); print_dec(biton32(default_layer_state));
-    print(" to "); print_dec(layer); print("\n");
+    xprintf("L%d\n", layer);
     default_layer_set(1UL<<layer);
     clear_keyboard();
 }
diff --git a/common/keyboard.c b/common/keyboard.c
index b03b124d76..eb7b096bed 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -62,6 +62,12 @@ static bool has_ghost_in_row(uint8_t row)
 #endif
 
 
+__attribute__ ((weak)) void matrix_setup(void) {}
+void keyboard_setup(void)
+{
+    matrix_setup();
+}
+
 void keyboard_init(void)
 {
     timer_init();
diff --git a/common/keyboard.h b/common/keyboard.h
index 6442716fc7..7738251b64 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -58,13 +58,15 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
 }
 
 
+/* it runs once at early stage of startup before keyboard_init. */
+void keyboard_setup(void);
+/* it runs once after initializing host side protocol, debug and MCU peripherals. */
 void keyboard_init(void);
+/* it runs repeatedly in main loop */
 void keyboard_task(void);
+/* it runs when host LED status is updated */
 void keyboard_set_leds(uint8_t leds);
 
-__attribute__ ((weak)) void matrix_power_up(void) {}
-__attribute__ ((weak)) void matrix_power_down(void) {}
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/common/keycode.h b/common/keycode.h
index ac4ef00db6..448195306f 100644
--- a/common/keycode.h
+++ b/common/keycode.h
@@ -156,6 +156,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define KC_WSTP KC_WWW_STOP
 #define KC_WREF KC_WWW_REFRESH
 #define KC_WFAV KC_WWW_FAVORITES
+/* Jump to bootloader */
+#define KC_BTLD KC_BOOTLOADER
 /* Transparent */
 #define KC_TRANSPARENT  1
 #define KC_TRNS KC_TRANSPARENT
@@ -214,7 +216,7 @@ enum hid_keyboard_keypad_usage {
     KC_LBRACKET,
     KC_RBRACKET,        /* 0x30 */
     KC_BSLASH,          /* \ (and |) */
-    KC_NONUS_HASH,      /* Non-US # and ~ */
+    KC_NONUS_HASH,      /* Non-US # and ~ (Typically near the Enter key) */
     KC_SCOLON,          /* ; (and :) */
     KC_QUOTE,           /* ' and " */
     KC_GRAVE,           /* Grave accent and tilde */
@@ -264,7 +266,7 @@ enum hid_keyboard_keypad_usage {
     KC_KP_9,
     KC_KP_0,
     KC_KP_DOT,
-    KC_NONUS_BSLASH,    /* Non-US \ and | */
+    KC_NONUS_BSLASH,    /* Non-US \ and | (Typically near the Left-Shift key) */
     KC_APPLICATION,
     KC_POWER,
     KC_KP_EQUAL,
@@ -426,6 +428,9 @@ enum internal_special_keycodes {
     KC_MEDIA_FAST_FORWARD,
     KC_MEDIA_REWIND,    /* 0xBC */
 
+    /* Jump to bootloader */
+    KC_BOOTLOADER       = 0xBF,
+
     /* Fn key */
     KC_FN0              = 0xC0,
     KC_FN1,
diff --git a/common/keymap.c b/common/keymap.c
index 9f4fab5216..d489238085 100644
--- a/common/keymap.c
+++ b/common/keymap.c
@@ -20,6 +20,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "action_layer.h"
 #include "action.h"
 #include "action_macro.h"
+#include "wait.h"
 #include "debug.h"
 
 
@@ -140,6 +141,11 @@ static action_t keycode_to_action(uint8_t keycode)
         case KC_TRNS:
             action.code = ACTION_TRANSPARENT;
             break;
+        case KC_BOOTLOADER:
+            clear_keyboard();
+            wait_ms(50);
+            bootloader_jump(); // not return
+            break;
         default:
             action.code = ACTION_NO;
             break;
diff --git a/common/led.h b/common/led.h
index 402a247b9a..d5fc051bf5 100644
--- a/common/led.h
+++ b/common/led.h
@@ -28,6 +28,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define USB_LED_KANA                    4
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 void led_set(uint8_t usb_led);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/common/matrix.h b/common/matrix.h
index 107ee72653..ec6f8cd431 100644
--- a/common/matrix.h
+++ b/common/matrix.h
@@ -43,7 +43,9 @@ extern "C" {
 uint8_t matrix_rows(void);
 /* number of matrix columns */
 uint8_t matrix_cols(void);
-/* intialize matrix for scaning. should be called once. */
+/* should be called at early stage of startup before matrix_init.(optional) */
+void matrix_setup(void);
+/* intialize matrix for scaning. */
 void matrix_init(void);
 /* scan all key states on matrix */
 uint8_t matrix_scan(void);