]> git.friedersdorff.com Git - max/tmk_keyboard.git/commitdiff
Squashed 'tmk_core/' changes from 8da1898..e5f9940
authortmk <hasu@tmk-kbd.com>
Sat, 10 Dec 2016 01:29:51 +0000 (10:29 +0900)
committertmk <hasu@tmk-kbd.com>
Sat, 10 Dec 2016 01:29:51 +0000 (10:29 +0900)
e5f9940 Merge commit '1bc3dd200b023cecf063a0cb3ba347f77f6d759d' into core_update
da03c50 Add note for L/R side bit being ignored
e80f3c1 Add in basic documentation for Macro system
35e8a76 core: Swap position of PEQL and PENT in unimap
00751f1 Merge pull request #406 from 39aldo39/patch-1
e50d7de V-USB remote wakeup
4340997 core: Fix typo in definition AC_g
958144d core: Debug print for system and consumer keys
e7e1030 core: Fix sleep_led
0866323 core: Change matrix_init and matrix_print
0dbf73d core: Add matrix_clear() and default impl.
3202ca3 core: Add suspend mode options
4cda3aa core: Fix suspend/wake for converters #386
4e15247 core: LUFA_DEBUG_SUART for serial debug
b9cf8e7 core: Fix mechanical locking supoort #390
12aa0fd Merge branch 'nemith-master'
fccb3fa core: Fix OPT_DEFS for mbed build
2e2d2c8 Merge branch 'master' of github.com:leizzer/tmk_keyboard
f1d3634 Change .gitignore for ChibiOS
3aab802 core: Fix build config in protocol.mk
5e43da0 core: Add short names in unimap
7a56998 core: Fix dfu wait in rules.mk
6d9c500 Merge branch 'mediakey-fix'
08382ac core: Fix 'make dfu' message
78cb04e Fix OS X Recognizing keyboard as Mouse/Tablet
a114714 core: 'make dfu' waits for bootloader to start
d0a8f13 core: Fix unimap UNIMAP_NO case
e17abef core: Change lufa NKRO report size 16 to 32 bytes
375b20f core: Fix common.mk for build options
394fdff core: Fix unimap layout comment
912326c core: Add unimap support
00f4011 core: Fix doc/keymap.md for new keymap framework
ddbd7b4 core: Add default implemenation of keymap read
671cacc core: action codes are action_t struct now
b4fdb27 core: Change chibios repo directory names
7daed10 core: Fix keycode.txt
90399d7 core: Fix USB remote wakeup on ATmega32U2 #361
3677e84 usb_usb: Add multiple keyboard support
54d5b26 core: Fix Logical Maximum in report descriptor
bd0d372 core: Fix LUFA report descriptor
95327b5 Merge pull request #355 from papodaca/XT
62bf548 core: change API of adb.c to accept device address
3097c9e Fix function name in host.h
836e209 Merge branch 'core_split_160522'
3918ea2 Merge commit '20b787fc1284176834cbe7ca2134e4b36bec5828'
7f87b11 core: Add comment of register 3 of ADB
ef6478a core: Add adb_host_talk()
5c665b4 update macro names in bluefruit
4f2c5bf Merge commit '71381457fa1311dfa0b58ba882a96db740640871'
53a9c08 Merge pull request #321 from njbair/master
f08a656 core: Fix media/consumer keys
d526de8 Clean up wording in keymap example
0bb3dbb Clarify layer precedence
d915c75 clarify layer documentation
72070d4 ps2_usb: Fix for VUSB configuration
170e2dc Mostly working. Is unstable, will emit bad codes after a while.
c8e45b5 core: Actionmap support
aabaa24 Codes appear to be detected correctly, the break codes are broken.

git-subtree-dir: tmk_core
git-subtree-split: e5f994033cbc8700745ac0c6d12772820492eed0

55 files changed:
README.md
common.mk
common/action.c
common/action_code.h
common/action_layer.c
common/actionmap.c [new file with mode: 0644]
common/actionmap.h [new file with mode: 0644]
common/avr/sleep_led.c
common/avr/suart.S [new file with mode: 0644]
common/avr/suart.h [new file with mode: 0644]
common/avr/suspend.c
common/bootmagic.c
common/bootmagic.h
common/command.c
common/host.c
common/host.h
common/keyboard.c
common/keycode.h
common/keymap.c
common/matrix.c [new file with mode: 0644]
common/matrix.h
common/report.h
common/sleep_led.h
common/unimap.c [new file with mode: 0644]
common/unimap.h [new file with mode: 0644]
common/util.h
doc/keycode.txt
doc/keymap.md
doc/unimap.txt [new file with mode: 0644]
protocol.mk
protocol/adb.c
protocol/adb.h
protocol/bluefruit/bluefruit.c
protocol/chibios/README.md
protocol/chibios/usb_main.c
protocol/lufa.mk
protocol/lufa/descriptor.c
protocol/lufa/descriptor.h
protocol/lufa/lufa.c
protocol/mbed/HIDKeyboard.cpp
protocol/pbuff.h [new file with mode: 0644]
protocol/pjrc/usb.c
protocol/ps2_interrupt.c
protocol/usb_hid/parser.cpp
protocol/usb_hid/parser.h
protocol/vusb/main.c
protocol/vusb/vusb.c
protocol/xt.h [new file with mode: 0644]
protocol/xt_interrupt.c [new file with mode: 0644]
protocol/xt_io.h [new file with mode: 0644]
protocol/xt_io_avr.c [new file with mode: 0644]
rules.mk
tool/chibios/.gitignore
tool/chibios/chibios.mk
tool/mbed/gcc.mk

index f460d0ed44aaf7079b2ae47273fe9f36f09c8b43..c9c2eda4c1d2dd5fc4c3dbbf7686d96dfb7baf0a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,6 +7,9 @@ Source code is available here: <https://github.com/tmk/tmk_keyboard/tree/core>
 
 Updates
 -------
+#### 2016/06/26
+Keymap framework was updated. `fn_actions[]` should be defined as `action_t` instead of `uint16_t`. And default code for keymap handling is now included in core you just need define `uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]` and `action_t fn_actions[]`.
+
 #### 2016/02/10
 flabbergast's Chibios protocol was merged from <https://github.com/flabbergast/tmk_keyboard/tree/chibios>. See [protocol/chibios/README.md](protocol/chibios/README.md). Chibios protocol supports Cortex-M such as STM32 and Kinetis.
 
index 6d4be85f24f1f469dc4601971a07a7d3f21f325b..69be0e13e391906b45bbd446118cc1694ca004c2 100644 (file)
--- a/common.mk
+++ b/common.mk
@@ -1,12 +1,12 @@
 COMMON_DIR = common
 SRC += $(COMMON_DIR)/host.c \
        $(COMMON_DIR)/keyboard.c \
+       $(COMMON_DIR)/matrix.c \
        $(COMMON_DIR)/action.c \
        $(COMMON_DIR)/action_tapping.c \
        $(COMMON_DIR)/action_macro.c \
        $(COMMON_DIR)/action_layer.c \
        $(COMMON_DIR)/action_util.c \
-       $(COMMON_DIR)/keymap.c \
        $(COMMON_DIR)/print.c \
        $(COMMON_DIR)/debug.c \
        $(COMMON_DIR)/util.c \
@@ -18,58 +18,70 @@ SRC +=      $(COMMON_DIR)/host.c \
 
 
 # Option modules
-ifdef BOOTMAGIC_ENABLE
+ifeq (yes,$(strip $(UNIMAP_ENABLE)))
+    SRC += $(COMMON_DIR)/unimap.c
+    OPT_DEFS += -DUNIMAP_ENABLE
+else
+    ifeq (yes,$(strip $(ACTIONMAP_ENABLE)))
+       SRC += $(COMMON_DIR)/actionmap.c
+       OPT_DEFS += -DACTIONMAP_ENABLE
+    else
+       SRC += $(COMMON_DIR)/keymap.c
+    endif
+endif
+
+ifeq (yes,$(strip $(BOOTMAGIC_ENABLE)))
     SRC += $(COMMON_DIR)/bootmagic.c
     SRC += $(COMMON_DIR)/avr/eeconfig.c
     OPT_DEFS += -DBOOTMAGIC_ENABLE
 endif
 
-ifdef MOUSEKEY_ENABLE
+ifeq (yes,$(strip $(MOUSEKEY_ENABLE)))
     SRC += $(COMMON_DIR)/mousekey.c
     OPT_DEFS += -DMOUSEKEY_ENABLE
     OPT_DEFS += -DMOUSE_ENABLE
 endif
 
-ifdef EXTRAKEY_ENABLE
+ifeq (yes,$(strip $(EXTRAKEY_ENABLE)))
     OPT_DEFS += -DEXTRAKEY_ENABLE
 endif
 
-ifdef CONSOLE_ENABLE
+ifeq (yes,$(strip $(CONSOLE_ENABLE)))
     OPT_DEFS += -DCONSOLE_ENABLE
 else
     OPT_DEFS += -DNO_PRINT
     OPT_DEFS += -DNO_DEBUG
 endif
 
-ifdef COMMAND_ENABLE
+ifeq (yes,$(strip $(COMMAND_ENABLE)))
     SRC += $(COMMON_DIR)/command.c
     OPT_DEFS += -DCOMMAND_ENABLE
 endif
 
-ifdef NKRO_ENABLE
+ifeq (yes,$(strip $(NKRO_ENABLE)))
     OPT_DEFS += -DNKRO_ENABLE
 endif
 
-ifdef USB_6KRO_ENABLE
+ifeq (yes,$(strip $(USB_6KRO_ENABLE)))
     OPT_DEFS += -DUSB_6KRO_ENABLE
 endif
 
-ifdef KEYBOARD_LOCK_ENABLE
+ifeq (yes, $(strip $(KEYBOARD_LOCK_ENABLE)))
     OPT_DEFS += -DKEYBOARD_LOCK_ENABLE
 endif
 
-ifdef SLEEP_LED_ENABLE
+ifeq (yes,$(strip $(SLEEP_LED_ENABLE)))
     SRC += $(COMMON_DIR)/avr/sleep_led.c
     OPT_DEFS += -DSLEEP_LED_ENABLE
     OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
 endif
 
-ifdef BACKLIGHT_ENABLE
+ifeq (yes,$(strip $(BACKLIGHT_ENABLE)))
     SRC += $(COMMON_DIR)/backlight.c
     OPT_DEFS += -DBACKLIGHT_ENABLE
 endif
 
-ifdef KEYMAP_SECTION_ENABLE
+ifeq (yes,$(strip $(KEYMAP_SECTION_ENABLE)))
     OPT_DEFS += -DKEYMAP_SECTION_ENABLE
 
     ifeq ($(strip $(MCU)),atmega32u2)
index b9040f5b7c6cbf0b45820625193f80af2ee270f7..3a3c4014f7d5b158ae5ed7a81de08d3715808cc3 100644 (file)
@@ -27,6 +27,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "action_util.h"
 #include "action.h"
 #include "hook.h"
+#include "wait.h"
 
 #ifdef DEBUG_ACTION
 #include "debug.h"
@@ -365,6 +366,7 @@ void register_code(uint8_t code)
 #endif
         add_key(KC_CAPSLOCK);
         send_keyboard_report();
+        wait_ms(100);
         del_key(KC_CAPSLOCK);
         send_keyboard_report();
     }
@@ -375,6 +377,7 @@ void register_code(uint8_t code)
 #endif
         add_key(KC_NUMLOCK);
         send_keyboard_report();
+        wait_ms(100);
         del_key(KC_NUMLOCK);
         send_keyboard_report();
     }
@@ -385,6 +388,7 @@ void register_code(uint8_t code)
 #endif
         add_key(KC_SCROLLLOCK);
         send_keyboard_report();
+        wait_ms(100);
         del_key(KC_SCROLLLOCK);
         send_keyboard_report();
     }
@@ -440,6 +444,7 @@ void unregister_code(uint8_t code)
 #endif
         add_key(KC_CAPSLOCK);
         send_keyboard_report();
+        wait_ms(100);
         del_key(KC_CAPSLOCK);
         send_keyboard_report();
     }
@@ -450,6 +455,7 @@ void unregister_code(uint8_t code)
 #endif
         add_key(KC_NUMLOCK);
         send_keyboard_report();
+        wait_ms(100);
         del_key(KC_NUMLOCK);
         send_keyboard_report();
     }
@@ -460,6 +466,7 @@ void unregister_code(uint8_t code)
 #endif
         add_key(KC_SCROLLLOCK);
         send_keyboard_report();
+        wait_ms(100);
         del_key(KC_SCROLLLOCK);
         send_keyboard_report();
     }
index da93f77b2276760850e157364882497de2962145..8dad38b961d8639e182be2a53b7fa3589be6d270 100644 (file)
@@ -181,9 +181,9 @@ typedef union {
 
 
 /* action utility */
-#define ACTION_NO                       0
-#define ACTION_TRANSPARENT              1
-#define ACTION(kind, param)             ((kind)<<12 | (param))
+#define ACTION_NO                       { .code = 0 }
+#define ACTION_TRANSPARENT              { .code = 1 }
+#define ACTION(kind, param)             { .code = ((kind)<<12 | (param)) }
 
 
 /*
@@ -251,8 +251,8 @@ enum layer_pram_tap_op {
     OP_OFF_ON,
     OP_SET_CLEAR,
 };
-#define ACTION_LAYER_BITOP(op, part, bits, on)      (ACT_LAYER<<12 | (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f))
-#define ACTION_LAYER_TAP(layer, key)                (ACT_LAYER_TAP<<12 | (layer)<<8 | (key))
+#define ACTION_LAYER_BITOP(op, part, bits, on)      ACTION(ACT_LAYER, (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f))
+#define ACTION_LAYER_TAP(layer, key)                ACTION(ACT_LAYER_TAP, (layer)<<8 | (key))
 /* Default Layer */
 #define ACTION_DEFAULT_LAYER_SET(layer)             ACTION_DEFAULT_LAYER_BIT_SET((layer)/4, 1<<((layer)%4))
 #define ACTION_DEFAULT_LAYER_TOGGLE(layer)          ACTION_DEFAULT_LAYER_BIT_XOR((layer)/4, 1<<((layer)%4))
index 6c0be46fee295cf2e682142aa3b1a6775065897e..6b5a7fd2b83e9216939601cb5439ec65da459e86 100644 (file)
@@ -117,8 +117,7 @@ void layer_debug(void)
 
 action_t layer_switch_get_action(keypos_t key)
 {
-    action_t action;
-    action.code = ACTION_TRANSPARENT;
+    action_t action = ACTION_TRANSPARENT;
 
 #ifndef NO_ACTION_LAYER
     uint32_t layers = layer_state | default_layer_state;
@@ -126,7 +125,7 @@ action_t layer_switch_get_action(keypos_t key)
     for (int8_t i = 31; i >= 0; i--) {
         if (layers & (1UL<<i)) {
             action = action_for_key(i, key);
-            if (action.code != ACTION_TRANSPARENT) {
+            if (action.code != (action_t)ACTION_TRANSPARENT.code) {
                 return action;
             }
         }
diff --git a/common/actionmap.c b/common/actionmap.c
new file mode 100644 (file)
index 0000000..6b0fa8e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+Copyright 2015 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 <stdint.h>
+#include "action_code.h"
+#include "actionmap.h"
+
+
+/* Keymapping with 16bit action codes */
+extern const action_t actionmaps[][MATRIX_ROWS][MATRIX_COLS];
+
+
+/* Converts key to action */
+__attribute__ ((weak))
+action_t action_for_key(uint8_t layer, keypos_t key)
+{
+    return (action_t)pgm_read_word(&actionmaps[(layer)][(key.row)][(key.col)]);
+}
+
+/* Macro */
+__attribute__ ((weak))
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+    return MACRO_NONE;
+}
+
+/* Function */
+__attribute__ ((weak))
+void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+}
diff --git a/common/actionmap.h b/common/actionmap.h
new file mode 100644 (file)
index 0000000..2ebfb0d
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+Copyright 2015 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 ACTIONMAP_H
+#define ACTIONMAP_H
+
+#include "keyboard.h"
+#include "report.h"
+#include "keycode.h"
+#include "action_code.h"
+#include "action.h"
+
+
+/* Modified key */
+#define AC_c(kc)                ACTION_MODS_KEY(MOD_LCTL, KC_##kc)
+#define AC_s(kc)                ACTION_MODS_KEY(MOD_LSFT, KC_##kc)
+#define AC_a(kc)                ACTION_MODS_KEY(MOD_LALT, KC_##kc)
+#define AC_g(kc)                ACTION_MODS_KEY(MOD_LGUI, KC_##kc)
+
+/* Normal key */
+#define AC_NO                  ACTION_KEY(KC_NO)
+#define AC_TRANSPARENT          ACTION_KEY(KC_TRANSPARENT)
+#define AC_ROLL_OVER           ACTION_KEY(KC_ROLL_OVER)
+#define AC_POST_FAIL           ACTION_KEY(KC_POST_FAIL)
+#define AC_UNDEFINED           ACTION_KEY(KC_UNDEFINED)
+#define AC_A                   ACTION_KEY(KC_A)
+#define AC_B                   ACTION_KEY(KC_B)
+#define AC_C                   ACTION_KEY(KC_C)
+#define AC_D                   ACTION_KEY(KC_D)
+#define AC_E                   ACTION_KEY(KC_E)
+#define AC_F                   ACTION_KEY(KC_F)
+#define AC_G                   ACTION_KEY(KC_G)
+#define AC_H                   ACTION_KEY(KC_H)
+#define AC_I                   ACTION_KEY(KC_I)
+#define AC_J                   ACTION_KEY(KC_J)
+#define AC_K                   ACTION_KEY(KC_K)
+#define AC_L                   ACTION_KEY(KC_L)
+#define AC_M                   ACTION_KEY(KC_M)
+#define AC_N                   ACTION_KEY(KC_N)
+#define AC_O                   ACTION_KEY(KC_O)
+#define AC_P                   ACTION_KEY(KC_P)
+#define AC_Q                   ACTION_KEY(KC_Q)
+#define AC_R                   ACTION_KEY(KC_R)
+#define AC_S                   ACTION_KEY(KC_S)
+#define AC_T                   ACTION_KEY(KC_T)
+#define AC_U                   ACTION_KEY(KC_U)
+#define AC_V                   ACTION_KEY(KC_V)
+#define AC_W                   ACTION_KEY(KC_W)
+#define AC_X                   ACTION_KEY(KC_X)
+#define AC_Y                   ACTION_KEY(KC_Y)
+#define AC_Z                   ACTION_KEY(KC_Z)
+#define AC_1                   ACTION_KEY(KC_1)
+#define AC_2                   ACTION_KEY(KC_2)
+#define AC_3                   ACTION_KEY(KC_3)
+#define AC_4                   ACTION_KEY(KC_4)
+#define AC_5                   ACTION_KEY(KC_5)
+#define AC_6                   ACTION_KEY(KC_6)
+#define AC_7                   ACTION_KEY(KC_7)
+#define AC_8                   ACTION_KEY(KC_8)
+#define AC_9                   ACTION_KEY(KC_9)
+#define AC_0                   ACTION_KEY(KC_0)
+#define AC_ENTER               ACTION_KEY(KC_ENTER)
+#define AC_ESCAPE              ACTION_KEY(KC_ESCAPE)
+#define AC_BSPACE              ACTION_KEY(KC_BSPACE)
+#define AC_TAB                 ACTION_KEY(KC_TAB)
+#define AC_SPACE               ACTION_KEY(KC_SPACE)
+#define AC_MINUS               ACTION_KEY(KC_MINUS)
+#define AC_EQUAL               ACTION_KEY(KC_EQUAL)
+#define AC_LBRACKET            ACTION_KEY(KC_LBRACKET)
+#define AC_RBRACKET            ACTION_KEY(KC_RBRACKET)
+#define AC_BSLASH              ACTION_KEY(KC_BSLASH)
+#define AC_NONUS_HASH          ACTION_KEY(KC_NONUS_HASH)
+#define AC_SCOLON              ACTION_KEY(KC_SCOLON)
+#define AC_QUOTE               ACTION_KEY(KC_QUOTE)
+#define AC_GRAVE               ACTION_KEY(KC_GRAVE)
+#define AC_COMMA               ACTION_KEY(KC_COMMA)
+#define AC_DOT                 ACTION_KEY(KC_DOT)
+#define AC_SLASH               ACTION_KEY(KC_SLASH)
+#define AC_CAPSLOCK            ACTION_KEY(KC_CAPSLOCK)
+#define AC_F1                  ACTION_KEY(KC_F1)
+#define AC_F2                  ACTION_KEY(KC_F2)
+#define AC_F3                  ACTION_KEY(KC_F3)
+#define AC_F4                  ACTION_KEY(KC_F4)
+#define AC_F5                  ACTION_KEY(KC_F5)
+#define AC_F6                  ACTION_KEY(KC_F6)
+#define AC_F7                  ACTION_KEY(KC_F7)
+#define AC_F8                  ACTION_KEY(KC_F8)
+#define AC_F9                  ACTION_KEY(KC_F9)
+#define AC_F10                 ACTION_KEY(KC_F10)
+#define AC_F11                 ACTION_KEY(KC_F11)
+#define AC_F12                 ACTION_KEY(KC_F12)
+#define AC_PSCREEN             ACTION_KEY(KC_PSCREEN)
+#define AC_SCROLLLOCK          ACTION_KEY(KC_SCROLLLOCK)
+#define AC_PAUSE               ACTION_KEY(KC_PAUSE)
+#define AC_INSERT              ACTION_KEY(KC_INSERT)
+#define AC_HOME                        ACTION_KEY(KC_HOME)
+#define AC_PGUP                        ACTION_KEY(KC_PGUP)
+#define AC_DELETE              ACTION_KEY(KC_DELETE)
+#define AC_END                 ACTION_KEY(KC_END)
+#define AC_PGDOWN              ACTION_KEY(KC_PGDOWN)
+#define AC_RIGHT               ACTION_KEY(KC_RIGHT)
+#define AC_LEFT                        ACTION_KEY(KC_LEFT)
+#define AC_DOWN                        ACTION_KEY(KC_DOWN)
+#define AC_UP                  ACTION_KEY(KC_UP)
+#define AC_NUMLOCK             ACTION_KEY(KC_NUMLOCK)
+#define AC_KP_SLASH            ACTION_KEY(KC_KP_SLASH)
+#define AC_KP_ASTERISK         ACTION_KEY(KC_KP_ASTERISK)
+#define AC_KP_MINUS            ACTION_KEY(KC_KP_MINUS)
+#define AC_KP_PLUS             ACTION_KEY(KC_KP_PLUS)
+#define AC_KP_ENTER            ACTION_KEY(KC_KP_ENTER)
+#define AC_KP_1                        ACTION_KEY(KC_KP_1)
+#define AC_KP_2                        ACTION_KEY(KC_KP_2)
+#define AC_KP_3                        ACTION_KEY(KC_KP_3)
+#define AC_KP_4                        ACTION_KEY(KC_KP_4)
+#define AC_KP_5                        ACTION_KEY(KC_KP_5)
+#define AC_KP_6                        ACTION_KEY(KC_KP_6)
+#define AC_KP_7                        ACTION_KEY(KC_KP_7)
+#define AC_KP_8                        ACTION_KEY(KC_KP_8)
+#define AC_KP_9                        ACTION_KEY(KC_KP_9)
+#define AC_KP_0                        ACTION_KEY(KC_KP_0)
+#define AC_KP_DOT              ACTION_KEY(KC_KP_DOT)
+#define AC_NONUS_BSLASH                ACTION_KEY(KC_NONUS_BSLASH)
+#define AC_APPLICATION         ACTION_KEY(KC_APPLICATION)
+#define AC_POWER               ACTION_KEY(KC_POWER)
+#define AC_KP_EQUAL            ACTION_KEY(KC_KP_EQUAL)
+#define AC_F13                 ACTION_KEY(KC_F13)
+#define AC_F14                 ACTION_KEY(KC_F14)
+#define AC_F15                 ACTION_KEY(KC_F15)
+#define AC_F16                 ACTION_KEY(KC_F16)
+#define AC_F17                 ACTION_KEY(KC_F17)
+#define AC_F18                 ACTION_KEY(KC_F18)
+#define AC_F19                 ACTION_KEY(KC_F19)
+#define AC_F20                 ACTION_KEY(KC_F20)
+#define AC_F21                 ACTION_KEY(KC_F21)
+#define AC_F22                 ACTION_KEY(KC_F22)
+#define AC_F23                 ACTION_KEY(KC_F23)
+#define AC_F24                 ACTION_KEY(KC_F24)
+#define AC_EXECUTE             ACTION_KEY(KC_EXECUTE)
+#define AC_HELP                        ACTION_KEY(KC_HELP)
+#define AC_MENU                        ACTION_KEY(KC_MENU)
+#define AC_SELECT              ACTION_KEY(KC_SELECT)
+#define AC_STOP                        ACTION_KEY(KC_STOP)
+#define AC_AGAIN               ACTION_KEY(KC_AGAIN)
+#define AC_UNDO                        ACTION_KEY(KC_UNDO)
+#define AC_CUT                 ACTION_KEY(KC_CUT)
+#define AC_COPY                        ACTION_KEY(KC_COPY)
+#define AC_PASTE               ACTION_KEY(KC_PASTE)
+#define AC_FIND                        ACTION_KEY(KC_FIND)
+#define AC__MUTE               ACTION_KEY(KC__MUTE)
+#define AC__VOLUP              ACTION_KEY(KC__VOLUP)
+#define AC__VOLDOWN            ACTION_KEY(KC__VOLDOWN)
+#define AC_LOCKING_CAPS                ACTION_KEY(KC_LOCKING_CAPS)
+#define AC_LOCKING_NUM         ACTION_KEY(KC_LOCKING_NUM)
+#define AC_LOCKING_SCROLL      ACTION_KEY(KC_LOCKING_SCROLL)
+#define AC_KP_COMMA            ACTION_KEY(KC_KP_COMMA)
+#define AC_KP_EQUAL_AS400      ACTION_KEY(KC_KP_EQUAL_AS400)
+#define AC_INT1                        ACTION_KEY(KC_INT1)
+#define AC_INT2                        ACTION_KEY(KC_INT2)
+#define AC_INT3                        ACTION_KEY(KC_INT3)
+#define AC_INT4                        ACTION_KEY(KC_INT4)
+#define AC_INT5                        ACTION_KEY(KC_INT5)
+#define AC_INT6                        ACTION_KEY(KC_INT6)
+#define AC_INT7                        ACTION_KEY(KC_INT7)
+#define AC_INT8                        ACTION_KEY(KC_INT8)
+#define AC_INT9                        ACTION_KEY(KC_INT9)
+#define AC_LANG1               ACTION_KEY(KC_LANG1)
+#define AC_LANG2               ACTION_KEY(KC_LANG2)
+#define AC_LANG3               ACTION_KEY(KC_LANG3)
+#define AC_LANG4               ACTION_KEY(KC_LANG4)
+#define AC_LANG5               ACTION_KEY(KC_LANG5)
+#define AC_LANG6               ACTION_KEY(KC_LANG6)
+#define AC_LANG7               ACTION_KEY(KC_LANG7)
+#define AC_LANG8               ACTION_KEY(KC_LANG8)
+#define AC_LANG9               ACTION_KEY(KC_LANG9)
+#define AC_ALT_ERASE           ACTION_KEY(KC_ALT_ERASE)
+#define AC_SYSREQ              ACTION_KEY(KC_SYSREQ)
+#define AC_CANCEL              ACTION_KEY(KC_CANCEL)
+#define AC_CLEAR               ACTION_KEY(KC_CLEAR)
+#define AC_PRIOR               ACTION_KEY(KC_PRIOR)
+#define AC_RETURN              ACTION_KEY(KC_RETURN)
+#define AC_SEPARATOR           ACTION_KEY(KC_SEPARATOR)
+#define AC_OUT                 ACTION_KEY(KC_OUT)
+#define AC_OPER                        ACTION_KEY(KC_OPER)
+#define AC_CLEAR_AGAIN         ACTION_KEY(KC_CLEAR_AGAIN)
+#define AC_CRSEL               ACTION_KEY(KC_CRSEL)
+#define AC_EXSEL               ACTION_KEY(KC_EXSEL)
+#define AC_KP_00               ACTION_KEY(KC_KP_00)
+#define AC_KP_000              ACTION_KEY(KC_KP_000)
+#define AC_THOUSANDS_SEPARATOR ACTION_KEY(KC_THOUSANDS_SEPARATOR)
+#define AC_DECIMAL_SEPARATOR   ACTION_KEY(KC_DECIMAL_SEPARATOR)
+#define AC_CURRENCY_UNIT       ACTION_KEY(KC_CURRENCY_UNIT)
+#define AC_CURRENCY_SUB_UNIT   ACTION_KEY(KC_CURRENCY_SUB_UNIT)
+#define AC_KP_LPAREN           ACTION_KEY(KC_KP_LPAREN)
+#define AC_KP_RPAREN           ACTION_KEY(KC_KP_RPAREN)
+#define AC_KP_LCBRACKET                ACTION_KEY(KC_KP_LCBRACKET)
+#define AC_KP_RCBRACKET                ACTION_KEY(KC_KP_RCBRACKET)
+#define AC_KP_TAB              ACTION_KEY(KC_KP_TAB)
+#define AC_KP_BSPACE           ACTION_KEY(KC_KP_BSPACE)
+#define AC_KP_A                        ACTION_KEY(KC_KP_A)
+#define AC_KP_B                        ACTION_KEY(KC_KP_B)
+#define AC_KP_C                        ACTION_KEY(KC_KP_C)
+#define AC_KP_D                        ACTION_KEY(KC_KP_D)
+#define AC_KP_E                        ACTION_KEY(KC_KP_E)
+#define AC_KP_F                        ACTION_KEY(KC_KP_F)
+#define AC_KP_XOR              ACTION_KEY(KC_KP_XOR)
+#define AC_KP_HAT              ACTION_KEY(KC_KP_HAT)
+#define AC_KP_PERC             ACTION_KEY(KC_KP_PERC)
+#define AC_KP_LT               ACTION_KEY(KC_KP_LT)
+#define AC_KP_GT               ACTION_KEY(KC_KP_GT)
+#define AC_KP_AND              ACTION_KEY(KC_KP_AND)
+#define AC_KP_LAZYAND          ACTION_KEY(KC_KP_LAZYAND)
+#define AC_KP_OR               ACTION_KEY(KC_KP_OR)
+#define AC_KP_LAZYOR           ACTION_KEY(KC_KP_LAZYOR)
+#define AC_KP_COLON            ACTION_KEY(KC_KP_COLON)
+#define AC_KP_HASH             ACTION_KEY(KC_KP_HASH)
+#define AC_KP_SPACE            ACTION_KEY(KC_KP_SPACE)
+#define AC_KP_ATMARK           ACTION_KEY(KC_KP_ATMARK)
+#define AC_KP_EXCLAMATION      ACTION_KEY(KC_KP_EXCLAMATION)
+#define AC_KP_MEM_STORE                ACTION_KEY(KC_KP_MEM_STORE)
+#define AC_KP_MEM_RECALL       ACTION_KEY(KC_KP_MEM_RECALL)
+#define AC_KP_MEM_CLEAR                ACTION_KEY(KC_KP_MEM_CLEAR)
+#define AC_KP_MEM_ADD          ACTION_KEY(KC_KP_MEM_ADD)
+#define AC_KP_MEM_SUB          ACTION_KEY(KC_KP_MEM_SUB)
+#define AC_KP_MEM_MUL          ACTION_KEY(KC_KP_MEM_MUL)
+#define AC_KP_MEM_DIV          ACTION_KEY(KC_KP_MEM_DIV)
+#define AC_KP_PLUS_MINUS       ACTION_KEY(KC_KP_PLUS_MINUS)
+#define AC_KP_CLEAR            ACTION_KEY(KC_KP_CLEAR)
+#define AC_KP_CLEAR_ENTRY      ACTION_KEY(KC_KP_CLEAR_ENTRY)
+#define AC_KP_BINARY           ACTION_KEY(KC_KP_BINARY)
+#define AC_KP_OCTAL            ACTION_KEY(KC_KP_OCTAL)
+#define AC_KP_DECIMAL          ACTION_KEY(KC_KP_DECIMAL)
+#define AC_KP_HEXADECIMAL      ACTION_KEY(KC_KP_HEXADECIMAL)
+
+/* Modifiers */
+#define AC_LCTRL               ACTION_KEY(KC_LCTRL)
+#define AC_LSHIFT              ACTION_KEY(KC_LSHIFT)
+#define AC_LALT                        ACTION_KEY(KC_LALT)
+#define AC_LGUI                        ACTION_KEY(KC_LGUI)
+#define AC_RCTRL               ACTION_KEY(KC_RCTRL)
+#define AC_RSHIFT              ACTION_KEY(KC_RSHIFT)
+#define AC_RALT                        ACTION_KEY(KC_RALT)
+#define AC_RGUI                        ACTION_KEY(KC_RGUI)
+
+/*
+ * TMK extensions
+ */
+/* Sytem Control */
+#define AC_SYSTEM_POWER                ACTION_USAGE_SYSTEM(SYSTEM_POWER_DOWN)
+#define AC_SYSTEM_SLEEP                ACTION_USAGE_SYSTEM(SYSTEM_SLEEP)
+#define AC_SYSTEM_WAKE         ACTION_USAGE_SYSTEM(SYSTEM_WAKE_UP)
+/* Consumer Page */
+#define AC_AUDIO_MUTE          ACTION_USAGE_CONSUMER(AUDIO_MUTE)
+#define AC_AUDIO_VOL_UP                ACTION_USAGE_CONSUMER(AUDIO_VOL_UP)
+#define AC_AUDIO_VOL_DOWN      ACTION_USAGE_CONSUMER(AUDIO_VOL_DOWN)
+#define AC_MEDIA_NEXT_TRACK    ACTION_USAGE_CONSUMER(TRANSPORT_NEXT_TRACK)
+#define AC_MEDIA_PREV_TRACK    ACTION_USAGE_CONSUMER(TRANSPORT_PREV_TRACK)
+#define AC_MEDIA_FAST_FORWARD  ACTION_USAGE_CONSUMER(TRANSPORT_FAST_FORWARD)
+#define AC_MEDIA_REWIND                ACTION_USAGE_CONSUMER(TRANSPORT_REWIND)
+#define AC_MEDIA_STOP          ACTION_USAGE_CONSUMER(TRANSPORT_STOP)
+#define AC_MEDIA_PLAY_PAUSE    ACTION_USAGE_CONSUMER(TRANSPORT_PLAY_PAUSE)
+#define AC_MEDIA_EJECT         ACTION_USAGE_CONSUMER(TRANSPORT_STOP_EJECT)
+#define AC_MEDIA_SELECT                ACTION_USAGE_CONSUMER(APPLAUNCH_CC_CONFIG)
+#define AC_MAIL                        ACTION_USAGE_CONSUMER(APPLAUNCH_EMAIL)
+#define AC_CALCULATOR          ACTION_USAGE_CONSUMER(APPLAUNCH_CALCULATOR)
+#define AC_MY_COMPUTER         ACTION_USAGE_CONSUMER(APPLAUNCH_LOCAL_BROWSER)
+#define AC_WWW_SEARCH          ACTION_USAGE_CONSUMER(APPCONTROL_SEARCH)
+#define AC_WWW_HOME            ACTION_USAGE_CONSUMER(APPCONTROL_HOME)
+#define AC_WWW_BACK            ACTION_USAGE_CONSUMER(APPCONTROL_BACK)
+#define AC_WWW_FORWARD         ACTION_USAGE_CONSUMER(APPCONTROL_FORWARD)
+#define AC_WWW_STOP            ACTION_USAGE_CONSUMER(APPCONTROL_STOP)
+#define AC_WWW_REFRESH         ACTION_USAGE_CONSUMER(APPCONTROL_REFRESH)
+#define AC_WWW_FAVORITES       ACTION_USAGE_CONSUMER(APPCONTROL_BOOKMARKS)
+/* Jump to bootloader */
+#define AC_BOOTLOADER          ACTION_KEY(KC_BOOTLOADER)
+/* Fn key */
+/*
+#define AC_FN0                 ACTION_KEY(KC_FN0)
+#define AC_FN1                 ACTION_KEY(KC_FN1)
+#define AC_FN2                 ACTION_KEY(KC_FN2)
+#define AC_FN3                 ACTION_KEY(KC_FN3)
+#define AC_FN4                 ACTION_KEY(KC_FN4)
+#define AC_FN5                 ACTION_KEY(KC_FN5)
+#define AC_FN6                 ACTION_KEY(KC_FN6)
+#define AC_FN7                 ACTION_KEY(KC_FN7)
+#define AC_FN8                 ACTION_KEY(KC_FN8)
+#define AC_FN9                 ACTION_KEY(KC_FN9)
+#define AC_FN10                        ACTION_KEY(KC_FN10)
+#define AC_FN11                        ACTION_KEY(KC_FN11)
+#define AC_FN12                        ACTION_KEY(KC_FN12)
+#define AC_FN13                        ACTION_KEY(KC_FN13)
+#define AC_FN14                        ACTION_KEY(KC_FN14)
+#define AC_FN15                        ACTION_KEY(KC_FN15)
+#define AC_FN16                        ACTION_KEY(KC_FN16)
+#define AC_FN17                        ACTION_KEY(KC_FN17)
+#define AC_FN18                        ACTION_KEY(KC_FN18)
+#define AC_FN19                        ACTION_KEY(KC_FN19)
+#define AC_FN20                        ACTION_KEY(KC_FN20)
+#define AC_FN21                        ACTION_KEY(KC_FN21)
+#define AC_FN22                        ACTION_KEY(KC_FN22)
+#define AC_FN23                        ACTION_KEY(KC_FN23)
+#define AC_FN24                        ACTION_KEY(KC_FN24)
+#define AC_FN25                        ACTION_KEY(KC_FN25)
+#define AC_FN26                        ACTION_KEY(KC_FN26)
+#define AC_FN27                        ACTION_KEY(KC_FN27)
+#define AC_FN28                        ACTION_KEY(KC_FN28)
+#define AC_FN29                        ACTION_KEY(KC_FN29)
+#define AC_FN30                        ACTION_KEY(KC_FN30)
+#define AC_FN31                        ACTION_KEY(KC_FN31)
+*/
+/* Mousekey */
+#define AC_MS_UP               ACTION_MOUSEKEY(KC_MS_UP)
+#define AC_MS_DOWN             ACTION_MOUSEKEY(KC_MS_DOWN)
+#define AC_MS_LEFT             ACTION_MOUSEKEY(KC_MS_LEFT)
+#define AC_MS_RIGHT            ACTION_MOUSEKEY(KC_MS_RIGHT)
+#define AC_MS_BTN1             ACTION_MOUSEKEY(KC_MS_BTN1)
+#define AC_MS_BTN2             ACTION_MOUSEKEY(KC_MS_BTN2)
+#define AC_MS_BTN3             ACTION_MOUSEKEY(KC_MS_BTN3)
+#define AC_MS_BTN4             ACTION_MOUSEKEY(KC_MS_BTN4)
+#define AC_MS_BTN5             ACTION_MOUSEKEY(KC_MS_BTN5)
+#define AC_MS_WH_UP            ACTION_MOUSEKEY(KC_MS_WH_UP)
+#define AC_MS_WH_DOWN          ACTION_MOUSEKEY(KC_MS_WH_DOWN)
+#define AC_MS_WH_LEFT          ACTION_MOUSEKEY(KC_MS_WH_LEFT)
+#define AC_MS_WH_RIGHT         ACTION_MOUSEKEY(KC_MS_WH_RIGHT)
+#define AC_MS_ACCEL0           ACTION_MOUSEKEY(KC_MS_ACCEL0)
+#define AC_MS_ACCEL1           ACTION_MOUSEKEY(KC_MS_ACCEL1)
+#define AC_MS_ACCEL2           ACTION_MOUSEKEY(KC_MS_ACCEL2)
+
+/*
+ * Short names
+ */
+#define AC_LCTL                        ACTION_KEY(KC_LCTRL)
+#define AC_RCTL                        ACTION_KEY(KC_RCTRL)
+#define AC_LSFT                        ACTION_KEY(KC_LSHIFT)
+#define AC_RSFT                        ACTION_KEY(KC_RSHIFT)
+#define AC_ESC                         ACTION_KEY(KC_ESCAPE)
+#define AC_BSPC                        ACTION_KEY(KC_BSPACE)
+#define AC_ENT                         ACTION_KEY(KC_ENTER)
+#define AC_DEL                         ACTION_KEY(KC_DELETE)
+#define AC_INS                         ACTION_KEY(KC_INSERT)
+#define AC_CAPS                        ACTION_KEY(KC_CAPSLOCK)
+#define AC_CLCK                        ACTION_KEY(KC_CAPSLOCK)
+#define AC_RGHT                        ACTION_KEY(KC_RIGHT)
+#define AC_PGDN                        ACTION_KEY(KC_PGDOWN)
+#define AC_PSCR                        ACTION_KEY(KC_PSCREEN)
+#define AC_SLCK                        ACTION_KEY(KC_SCROLLLOCK)
+#define AC_PAUS                        ACTION_KEY(KC_PAUSE)
+#define AC_BRK                         ACTION_KEY(KC_PAUSE)
+#define AC_NLCK                        ACTION_KEY(KC_NUMLOCK)
+#define AC_SPC                         ACTION_KEY(KC_SPACE)
+#define AC_MINS                        ACTION_KEY(KC_MINUS)
+#define AC_EQL                         ACTION_KEY(KC_EQUAL)
+#define AC_GRV                         ACTION_KEY(KC_GRAVE)
+#define AC_RBRC                        ACTION_KEY(KC_RBRACKET)
+#define AC_LBRC                        ACTION_KEY(KC_LBRACKET)
+#define AC_COMM                        ACTION_KEY(KC_COMMA)
+#define AC_BSLS                        ACTION_KEY(KC_BSLASH)
+#define AC_SLSH                        ACTION_KEY(KC_SLASH)
+#define AC_SCLN                        ACTION_KEY(KC_SCOLON)
+#define AC_QUOT                        ACTION_KEY(KC_QUOTE)
+#define AC_APP                         ACTION_KEY(KC_APPLICATION)
+#define AC_NUHS                        ACTION_KEY(KC_NONUS_HASH)
+#define AC_NUBS                        ACTION_KEY(KC_NONUS_BSLASH)
+#define AC_LCAP                        ACTION_KEY(KC_LOCKING_CAPS)
+#define AC_LNUM                        ACTION_KEY(KC_LOCKING_NUM)
+#define AC_LSCR                        ACTION_KEY(KC_LOCKING_SCROLL)
+#define AC_ERAS                        ACTION_KEY(KC_ALT_ERASE,)
+#define AC_CLR                         ACTION_KEY(KC_CLEAR)
+/* Japanese specific */
+#define AC_ZKHK                        ACTION_KEY(KC_GRAVE)
+#define AC_RO                          ACTION_KEY(KC_INT1)
+#define AC_KANA                        ACTION_KEY(KC_INT2)
+#define AC_JYEN                        ACTION_KEY(KC_INT3)
+#define AC_HENK                        ACTION_KEY(KC_INT4)
+#define AC_MHEN                        ACTION_KEY(KC_INT5)
+/* Keypad */
+#define AC_P1                          ACTION_KEY(KC_KP_1)
+#define AC_P2                          ACTION_KEY(KC_KP_2)
+#define AC_P3                          ACTION_KEY(KC_KP_3)
+#define AC_P4                          ACTION_KEY(KC_KP_4)
+#define AC_P5                          ACTION_KEY(KC_KP_5)
+#define AC_P6                          ACTION_KEY(KC_KP_6)
+#define AC_P7                          ACTION_KEY(KC_KP_7)
+#define AC_P8                          ACTION_KEY(KC_KP_8)
+#define AC_P9                          ACTION_KEY(KC_KP_9)
+#define AC_P0                          ACTION_KEY(KC_KP_0)
+#define AC_PDOT                        ACTION_KEY(KC_KP_DOT)
+#define AC_PCMM                        ACTION_KEY(KC_KP_COMMA)
+#define AC_PSLS                        ACTION_KEY(KC_KP_SLASH)
+#define AC_PAST                        ACTION_KEY(KC_KP_ASTERISK)
+#define AC_PMNS                        ACTION_KEY(KC_KP_MINUS)
+#define AC_PPLS                        ACTION_KEY(KC_KP_PLUS)
+#define AC_PEQL                        ACTION_KEY(KC_KP_EQUAL)
+#define AC_PENT                        ACTION_KEY(KC_KP_ENTER)
+/* Mousekey */
+#define AC_MS_U                        ACTION_MOUSEKEY(KC_MS_UP)
+#define AC_MS_D                        ACTION_MOUSEKEY(KC_MS_DOWN)
+#define AC_MS_L                        ACTION_MOUSEKEY(KC_MS_LEFT)
+#define AC_MS_R                        ACTION_MOUSEKEY(KC_MS_RIGHT)
+#define AC_BTN1                        ACTION_MOUSEKEY(KC_MS_BTN1)
+#define AC_BTN2                        ACTION_MOUSEKEY(KC_MS_BTN2)
+#define AC_BTN3                        ACTION_MOUSEKEY(KC_MS_BTN3)
+#define AC_BTN4                        ACTION_MOUSEKEY(KC_MS_BTN4)
+#define AC_BTN5                        ACTION_MOUSEKEY(KC_MS_BTN5)
+#define AC_WH_U                        ACTION_MOUSEKEY(KC_MS_WH_UP)
+#define AC_WH_D                        ACTION_MOUSEKEY(KC_MS_WH_DOWN)
+#define AC_WH_L                        ACTION_MOUSEKEY(KC_MS_WH_LEFT)
+#define AC_WH_R                        ACTION_MOUSEKEY(KC_MS_WH_RIGHT)
+#define AC_ACL0                        ACTION_MOUSEKEY(KC_MS_ACCEL0)
+#define AC_ACL1                        ACTION_MOUSEKEY(KC_MS_ACCEL1)
+#define AC_ACL2                        ACTION_MOUSEKEY(KC_MS_ACCEL2)
+/* Sytem Control */
+#define AC_PWR                         ACTION_USAGE_SYSTEM(SYSTEM_POWER_DOWN)
+#define AC_SLEP                        ACTION_USAGE_SYSTEM(SYSTEM_SLEEP)
+#define AC_WAKE                        ACTION_USAGE_SYSTEM(SYSTEM_WAKE_UP)
+/* Consumer Page */
+#define AC_MUTE                        ACTION_USAGE_CONSUMER(AUDIO_MUTE)
+#define AC_VOLU                        ACTION_USAGE_CONSUMER(AUDIO_VOL_UP)
+#define AC_VOLD                        ACTION_USAGE_CONSUMER(AUDIO_VOL_DOWN)
+#define AC_MNXT                        ACTION_USAGE_CONSUMER(TRANSPORT_NEXT_TRACK)
+#define AC_MPRV                        ACTION_USAGE_CONSUMER(TRANSPORT_PREV_TRACK)
+#define AC_MFFD                        ACTION_USAGE_CONSUMER(TRANSPORT_FAST_FORWARD)
+#define AC_MRWD                        ACTION_USAGE_CONSUMER(TRANSPORT_REWIND)
+#define AC_MSTP                        ACTION_USAGE_CONSUMER(TRANSPORT_STOP)
+#define AC_MPLY                        ACTION_USAGE_CONSUMER(TRANSPORT_PLAY_PAUSE)
+#define AC_EJCT                        ACTION_USAGE_CONSUMER(TRANSPORT_STOP_EJECT)
+#define AC_MSEL                        ACTION_USAGE_CONSUMER(APPLAUNCH_CC_CONFIG)
+#define AC_MAIL                        ACTION_USAGE_CONSUMER(APPLAUNCH_EMAIL)
+#define AC_CALC                        ACTION_USAGE_CONSUMER(APPLAUNCH_CALCULATOR)
+#define AC_MYCM                        ACTION_USAGE_CONSUMER(APPLAUNCH_LOCAL_BROWSER)
+#define AC_WSCH                        ACTION_USAGE_CONSUMER(APPCONTROL_SEARCH)
+#define AC_WHOM                        ACTION_USAGE_CONSUMER(APPCONTROL_HOME)
+#define AC_WBAK                        ACTION_USAGE_CONSUMER(APPCONTROL_BACK)
+#define AC_WFWD                        ACTION_USAGE_CONSUMER(APPCONTROL_FORWARD)
+#define AC_WSTP                        ACTION_USAGE_CONSUMER(APPCONTROL_STOP)
+#define AC_WREF                        ACTION_USAGE_CONSUMER(APPCONTROL_REFRESH)
+#define AC_WFAV                        ACTION_USAGE_CONSUMER(APPCONTROL_BOOKMARKS)
+/* Jump to bootloader */
+#define AC_BTLD                        ACTION_KEY(KC_BOOTLOADER)
+/* Transparent */
+#define AC_TRNS                        ACTION_KEY(KC_TRANSPARENT)
+
+#endif
index dab3eb0f3ceae9c6d1525c861d328ad825e00bd8..37c2cf1b19b387e6ed7f30b696e5234dffac4f0a 100644 (file)
@@ -45,10 +45,17 @@ void sleep_led_disable(void)
     TIMSK1 &= ~_BV(OCIE1A);
 }
 
-void sleep_led_toggle(void)
+
+__attribute__ ((weak))
+void sleep_led_on(void)
 {
-    /* Disable Compare Match Interrupt */
-    TIMSK1 ^= _BV(OCIE1A);
+    led_set(1<<USB_LED_CAPS_LOCK);
+}
+
+__attribute__ ((weak))
+void sleep_led_off(void)
+{
+    led_set(0);
 }
 
 
@@ -86,10 +93,10 @@ ISR(TIMER1_COMPA_vect)
     
     // LED on
     if (timer.pwm.count == 0) {
-        led_set(1<<USB_LED_CAPS_LOCK);
+        sleep_led_on();
     }
     // LED off
     if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) {
-        led_set(0);
+        sleep_led_off();
     }
 }
diff --git a/common/avr/suart.S b/common/avr/suart.S
new file mode 100644 (file)
index 0000000..9fa5452
--- /dev/null
@@ -0,0 +1,156 @@
+;---------------------------------------------------------------------------;\r
+; Software implemented UART module                                          ;\r
+; (C)ChaN, 2005 (http://elm-chan.org/)                                      ;\r
+;---------------------------------------------------------------------------;\r
+; Bit rate settings:\r
+;\r
+;            1MHz  2MHz  4MHz  6MHz  8MHz  10MHz  12MHz  16MHz  20MHz\r
+;   2.4kbps   138     -     -     -     -      -      -      -      -\r
+;   4.8kbps    68   138     -     -     -      -      -      -      -\r
+;   9.6kbps    33    68   138   208     -      -      -      -      -\r
+;  19.2kbps     -    33    68   102   138    173    208      -      -\r
+;  38.4kbps     -     -    33    50    68     85    102    138    172\r
+;  57.6kbps     -     -    21    33    44     56     68     91    114\r
+; 115.2kbps     -     -     -     -    21     27     33     44     56\r
+\r
+.nolist\r
+#include <avr/io.h>\r
+.list\r
+\r
+#define        BPS     44      /* Bit delay. (see above table) */\r
+#define        BIDIR   0       /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */\r
+\r
+#define        OUT_1           sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */\r
+#define        OUT_0           cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */\r
+#define        SKIP_IN_1       sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT   /* Skip if 1 */\r
+#define        SKIP_IN_0       sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT   /* Skip if 0 */\r
+\r
+\r
+\r
+#ifdef SPM_PAGESIZE\r
+.macro _LPMI   reg\r
+       lpm     \reg, Z+\r
+.endm\r
+.macro _MOVW   dh,dl, sh,sl\r
+       movw    \dl, \sl\r
+.endm\r
+#else\r
+.macro _LPMI   reg\r
+       lpm\r
+       mov     \reg, r0\r
+       adiw    ZL, 1\r
+.endm\r
+.macro _MOVW   dh,dl, sh,sl\r
+       mov     \dl, \sl\r
+       mov     \dh, \sh\r
+.endm\r
+#endif\r
+\r
+\r
+\r
+;---------------------------------------------------------------------------;\r
+; Transmit a byte in serial format of N81\r
+;\r
+;Prototype: void xmit (uint8_t data);\r
+;Size: 16 words\r
+\r
+.global xmit\r
+.func xmit\r
+xmit:\r
+#if BIDIR\r
+       ldi     r23, BPS-1      ;Pre-idle time for bidirectional data line\r
+5:     dec     r23             ;\r
+       brne    5b              ;/\r
+#endif\r
+       in      r0, _SFR_IO_ADDR(SREG)  ;Save flags\r
+\r
+       com     r24             ;C = start bit\r
+       ldi     r25, 10         ;Bit counter\r
+       cli                     ;Start critical section\r
+\r
+1:     ldi     r23, BPS-1      ;----- Bit transferring loop \r
+2:     dec     r23             ;Wait for a bit time\r
+       brne    2b              ;/\r
+       brcs    3f              ;MISO = bit to be sent\r
+       OUT_1                   ;\r
+3:     brcc    4f              ;\r
+       OUT_0                   ;/\r
+4:     lsr     r24             ;Get next bit into C\r
+       dec     r25             ;All bits sent?\r
+       brne    1b              ;  no, coutinue\r
+\r
+       out     _SFR_IO_ADDR(SREG), r0  ;End of critical section\r
+       ret\r
+.endfunc\r
+\r
+\r
+\r
+;---------------------------------------------------------------------------;\r
+; Receive a byte\r
+;\r
+;Prototype: uint8_t rcvr (void);\r
+;Size: 19 words\r
+\r
+.global rcvr\r
+.func rcvr\r
+rcvr:\r
+       in      r0, _SFR_IO_ADDR(SREG)  ;Save flags\r
+\r
+       ldi     r24, 0x80       ;Receiving shift reg\r
+       cli                     ;Start critical section\r
+\r
+1:     SKIP_IN_1               ;Wait for idle\r
+       rjmp    1b\r
+2:     SKIP_IN_0               ;Wait for start bit\r
+       rjmp    2b\r
+       ldi     r25, BPS/2      ;Wait for half bit time\r
+3:     dec     r25\r
+       brne    3b\r
+\r
+4:     ldi     r25, BPS        ;----- Bit receiving loop\r
+5:     dec     r25             ;Wait for a bit time\r
+       brne    5b              ;/\r
+       lsr     r24             ;Next bit\r
+       SKIP_IN_0               ;Get a data bit into r24.7\r
+       ori     r24, 0x80\r
+       brcc    4b              ;All bits received?  no, continue\r
+\r
+       out     _SFR_IO_ADDR(SREG), r0  ;End of critical section\r
+       ret\r
+.endfunc\r
+\r
+\r
+; Not wait for start bit. This should be called after detecting start bit.\r
+.global recv\r
+.func recv\r
+recv:\r
+       in      r0, _SFR_IO_ADDR(SREG)  ;Save flags\r
+\r
+       ldi     r24, 0x80       ;Receiving shift reg\r
+       cli                     ;Start critical section\r
+\r
+;1:    SKIP_IN_1               ;Wait for idle\r
+;      rjmp    1b\r
+;2:    SKIP_IN_0               ;Wait for start bit\r
+;      rjmp    2b\r
+       ldi     r25, BPS/2      ;Wait for half bit time\r
+3:     dec     r25\r
+       brne    3b\r
+\r
+4:     ldi     r25, BPS        ;----- Bit receiving loop\r
+5:     dec     r25             ;Wait for a bit time\r
+       brne    5b              ;/\r
+       lsr     r24             ;Next bit\r
+       SKIP_IN_0               ;Get a data bit into r24.7\r
+       ori     r24, 0x80\r
+       brcc    4b              ;All bits received?  no, continue\r
+\r
+       ldi     r25, BPS/2      ;Wait for half bit time\r
+6:     dec     r25\r
+       brne    6b\r
+7:     SKIP_IN_1               ;Wait for stop bit\r
+       rjmp    7b\r
+\r
+       out     _SFR_IO_ADDR(SREG), r0  ;End of critical section\r
+       ret\r
+.endfunc\r
diff --git a/common/avr/suart.h b/common/avr/suart.h
new file mode 100644 (file)
index 0000000..72725b9
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef SUART\r
+#define SUART\r
+\r
+void xmit(uint8_t);\r
+uint8_t rcvr(void);\r
+uint8_t recv(void);\r
+\r
+#endif /* SUART */\r
index af99f52b5ee18336f4f332eddf5c37bd9ab5b108..02d7e4c9426eea2921a4322d3959fe8952c7154d 100644 (file)
@@ -30,16 +30,6 @@ __asm__ __volatile__ (  \
 )
 
 
-void suspend_idle(uint8_t time)
-{
-    cli();
-    set_sleep_mode(SLEEP_MODE_IDLE);
-    sleep_enable();
-    sei();
-    sleep_cpu();
-    sleep_disable();
-}
-
 /* Power down MCU with watchdog timer
  * wdto: watchdog timer timeout defined in <avr/wdt.h>
  *          WDTO_15MS
@@ -80,13 +70,45 @@ static void power_down(uint8_t wdto)
     wdt_disable();
 }
 
+static void standby(void)
+{
+    set_sleep_mode(SLEEP_MODE_STANDBY);
+    sleep_enable();
+    sei();
+    sleep_cpu();
+    sleep_disable();
+}
+
+static void idle(void)
+{
+    set_sleep_mode(SLEEP_MODE_IDLE);
+    sleep_enable();
+    sei();
+    sleep_cpu();
+    sleep_disable();
+}
+
+
+void suspend_idle(uint8_t time)
+{
+    idle();
+}
+
 void suspend_power_down(void)
 {
+#ifdef NO_SUSPEND_POWER_DOWN
+    ;
+#elif defined(SUSPEND_MODE_NOPOWERSAVE)
+    ;
+#elif defined(SUSPEND_MODE_STANDBY)
+    standby();
+#elif defined(SUSPEND_MODE_IDLE)
+    idle();
+#else
     power_down(WDTO_15MS);
+#endif
 }
 
-__attribute__ ((weak)) void matrix_power_up(void) {}
-__attribute__ ((weak)) void matrix_power_down(void) {}
 bool suspend_wakeup_condition(void)
 {
     matrix_power_up();
@@ -102,6 +124,7 @@ bool suspend_wakeup_condition(void)
 void suspend_wakeup_init(void)
 {
     // clear keyboard state
+    matrix_clear();
     clear_keyboard();
 #ifdef BACKLIGHT_ENABLE
     backlight_init();
index 056806f23065dfec5be575e934c754e2be4312fb..eb06d7874da2fc1963e2a3bb7ea2c58e7f4ebcfe 100644 (file)
@@ -5,6 +5,7 @@
 #include "bootloader.h"
 #include "debug.h"
 #include "keymap.h"
+#include "actionmap.h"
 #include "host.h"
 #include "action_layer.h"
 #include "eeconfig.h"
@@ -27,17 +28,17 @@ void bootmagic(void)
     print("done.\n");
 
     /* bootmagic skip */
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_SKIP)) {
         return;
     }
 
     /* eeconfig clear */
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EEPROM_CLEAR)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_EEPROM_CLEAR)) {
         eeconfig_init();
     }
 
     /* bootloader */
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_BOOTLOADER)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_BOOTLOADER)) {
         bootloader_jump();
     }
 
@@ -46,12 +47,12 @@ void bootmagic(void)
 
     /* debug enable */
     debug_config.raw = eeconfig_read_debug();
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_ENABLE)) {
-        if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MATRIX)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_ENABLE)) {
+        if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_MATRIX)) {
             debug_config.matrix = !debug_config.matrix;
-        } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) {
+        } else if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) {
             debug_config.keyboard = !debug_config.keyboard;
-        } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MOUSE)) {
+        } else if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_MOUSE)) {
             debug_config.mouse = !debug_config.mouse;
         } else {
             debug_config.enable = !debug_config.enable;
@@ -61,28 +62,28 @@ void bootmagic(void)
 
     /* keymap config */
     keymap_config.raw = eeconfig_read_keymap();
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) {
         keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock;
     }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) {
         keymap_config.capslock_to_control = !keymap_config.capslock_to_control;
     }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) {
         keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
     }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) {
         keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui;
     }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_NO_GUI)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_NO_GUI)) {
         keymap_config.no_gui = !keymap_config.no_gui;
     }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) {
         keymap_config.swap_grave_esc = !keymap_config.swap_grave_esc;
     }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) {
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) {
         keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace;
     }
-    if (bootmagic_scan_keycode(BOOTMAGIC_HOST_NKRO)) {
+    if (bootmagic_scan_key(BOOTMAGIC_HOST_NKRO)) {
         keymap_config.nkro = !keymap_config.nkro;
     }
     eeconfig_write_keymap(keymap_config.raw);
@@ -93,14 +94,14 @@ void bootmagic(void)
 
     /* default layer */
     uint8_t default_layer = 0;
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) { default_layer |= (1<<1); }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) { default_layer |= (1<<2); }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) { default_layer |= (1<<3); }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) { default_layer |= (1<<4); }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) { default_layer |= (1<<5); }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) { default_layer |= (1<<6); }
-    if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) { default_layer |= (1<<7); }
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); }
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) { default_layer |= (1<<1); }
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) { default_layer |= (1<<2); }
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) { default_layer |= (1<<3); }
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) { default_layer |= (1<<4); }
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) { default_layer |= (1<<5); }
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) { default_layer |= (1<<6); }
+    if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) { default_layer |= (1<<7); }
     if (default_layer) {
         eeconfig_write_default_layer(default_layer);
         default_layer_set((uint32_t)default_layer);
@@ -110,13 +111,22 @@ void bootmagic(void)
     }
 }
 
-static bool scan_keycode(uint8_t keycode)
+static bool scan_key(uint16_t code)
 {
     for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
         matrix_row_t matrix_row = matrix_get_row(r);
         for (uint8_t c = 0; c < MATRIX_COLS; c++) {
             if (matrix_row & ((matrix_row_t)1<<c)) {
-                if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) {
+                // read key from Layer 0
+                action_t action = action_for_key(0, (keypos_t){ .row = r, .col = c });
+                if (action.code == code ||
+                    ((action.kind.id == ACT_LMODS ||
+                      action.kind.id == ACT_RMODS ||
+                      action.kind.id == ACT_LMODS_TAP ||
+                      action.kind.id == ACT_RMODS_TAP ||
+                      action.kind.id == ACT_LAYER_TAP ||
+                      action.kind.id == ACT_LAYER_TAP_EXT) &&
+                     action.key.code == code)) {
                     return true;
                 }
             }
@@ -125,9 +135,9 @@ static bool scan_keycode(uint8_t keycode)
     return false;
 }
 
-bool bootmagic_scan_keycode(uint8_t keycode)
+bool bootmagic_scan_key(uint16_t code)
 {
-    if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false;
+    if (!scan_key(BOOTMAGIC_KEY_SALT)) return false;
 
-    return scan_keycode(keycode);
+    return scan_key(code);
 }
index 8f6618f4bd0da0de18ea3ffc20d8cbab6f72c63f..5260e48f0bd3f525803c19ce1f522ab81ed67e13 100644 (file)
@@ -95,6 +95,6 @@
 
 
 void bootmagic(void);
-bool bootmagic_scan_keycode(uint8_t keycode);
+bool bootmagic_scan_key(uint16_t action);
 
 #endif
index 6920970020cc3f0a8ec72e645940b39132074362..bb471e887e5d7de3638888c1062a623f4616f9e3 100644 (file)
@@ -182,14 +182,22 @@ static bool command_common(uint8_t code)
 {
 #ifdef KEYBOARD_LOCK_ENABLE
     static host_driver_t *host_driver = 0;
+#endif
+#ifdef SLEEP_LED_ENABLE
+    static bool sleep_led_test = false;
 #endif
     switch (code) {
 #ifdef SLEEP_LED_ENABLE
         case KC_Z:
             // test breathing sleep LED
             print("Sleep LED test\n");
-            sleep_led_toggle();
-            led_set(host_keyboard_leds());
+            if (sleep_led_test) {
+                sleep_led_disable();
+                led_set(host_keyboard_leds());
+            } else {
+                sleep_led_enable();
+            }
+            sleep_led_test = !sleep_led_test;
             break;
 #endif
 #ifdef BOOTMAGIC_ENABLE
index e9b791670670eed07b9956495c1fc38dde989bab..56d65e505c66ef0c59faa549855aa65e6da0787d 100644 (file)
@@ -54,7 +54,7 @@ void host_keyboard_send(report_keyboard_t *report)
     (*driver->send_keyboard)(report);
 
     if (debug_keyboard) {
-        dprint("keyboard_report: ");
+        dprint("keyboard: ");
         for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
             dprintf("%02X ", report->raw[i]);
         }
@@ -75,6 +75,10 @@ void host_system_send(uint16_t report)
 
     if (!driver) return;
     (*driver->send_system)(report);
+
+    if (debug_keyboard) {
+        dprintf("system: %04X\n", report);
+    }
 }
 
 void host_consumer_send(uint16_t report)
@@ -84,9 +88,13 @@ void host_consumer_send(uint16_t report)
 
     if (!driver) return;
     (*driver->send_consumer)(report);
+
+    if (debug_keyboard) {
+        dprintf("consumer: %04X\n", report);
+    }
 }
 
-uint16_t host_last_sysytem_report(void)
+uint16_t host_last_system_report(void)
 {
     return last_system_report;
 }
index 918af69e8f41242083912519d9486b16f758572a..9814b10d2d0855b9aeea6d6e4cdcd31794051bcf 100644 (file)
@@ -47,7 +47,7 @@ void host_mouse_send(report_mouse_t *report);
 void host_system_send(uint16_t data);
 void host_consumer_send(uint16_t data);
 
-uint16_t host_last_sysytem_report(void);
+uint16_t host_last_system_report(void);
 uint16_t host_last_consumer_report(void);
 
 #ifdef __cplusplus
index 707351bcb8f10eb4e1a58caff3e1e34869027756..b0319369d0f590a9f3f87761ec74f1d93ab53ba2 100644 (file)
@@ -63,7 +63,6 @@ static bool has_ghost_in_row(uint8_t row)
 #endif
 
 
-__attribute__ ((weak)) void matrix_setup(void) {}
 void keyboard_setup(void)
 {
     matrix_setup();
index f34027120093530c1f9b274a5374e5ad68cec7e8..51c919509ddd287c2efeaa0184373e9d250b49b4 100644 (file)
@@ -153,8 +153,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define KC_MRWD KC_MEDIA_REWIND
 #define KC_MSTP KC_MEDIA_STOP
 #define KC_MPLY KC_MEDIA_PLAY_PAUSE
-#define KC_MSEL KC_MEDIA_SELECT
 #define KC_EJCT KC_MEDIA_EJECT
+#define KC_MSEL KC_MEDIA_SELECT
 #define KC_MAIL KC_MAIL
 #define KC_CALC KC_CALCULATOR
 #define KC_MYCM KC_MY_COMPUTER
@@ -420,10 +420,12 @@ enum internal_special_keycodes {
     KC_AUDIO_VOL_DOWN,
     KC_MEDIA_NEXT_TRACK,
     KC_MEDIA_PREV_TRACK,
+    KC_MEDIA_FAST_FORWARD,
+    KC_MEDIA_REWIND,
     KC_MEDIA_STOP,
     KC_MEDIA_PLAY_PAUSE,
-    KC_MEDIA_SELECT,
     KC_MEDIA_EJECT,
+    KC_MEDIA_SELECT,
     KC_MAIL,
     KC_CALCULATOR,
     KC_MY_COMPUTER,
@@ -433,9 +435,7 @@ enum internal_special_keycodes {
     KC_WWW_FORWARD,
     KC_WWW_STOP,
     KC_WWW_REFRESH,
-    KC_WWW_FAVORITES,
-    KC_MEDIA_FAST_FORWARD,
-    KC_MEDIA_REWIND,    /* 0xBC */
+    KC_WWW_FAVORITES,    /* 0xBC */
 
     /* Jump to bootloader */
     KC_BOOTLOADER       = 0xBF,
index 25161748bd9cf3bc687be997fff148d7b99755e7..01c6e64290a25cf6c6cf4666d953194a00d4bb9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Copyright 2013 Jun Wako <wakojun@gmail.com>
+Copyright 2013,2016 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
@@ -23,6 +23,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "wait.h"
 #include "debug.h"
 #include "bootloader.h"
+#if defined(__AVR__)
+#include <avr/pgmspace.h>
+#endif
 
 #ifdef BOOTMAGIC_ENABLE
 extern keymap_config_t keymap_config;
@@ -32,6 +35,7 @@ static action_t keycode_to_action(uint8_t keycode);
 
 
 /* converts key to action */
+__attribute__ ((weak))
 action_t action_for_key(uint8_t layer, keypos_t key)
 {
     uint8_t keycode = keymap_key_to_keycode(layer, key);
@@ -53,7 +57,7 @@ action_t action_for_key(uint8_t layer, keypos_t key)
         case KC_LALT:
             if (keymap_config.swap_lalt_lgui) {
                 if (keymap_config.no_gui) {
-                    return keycode_to_action(ACTION_NO);
+                    return keycode_to_action(KC_NO);
                 }
                 return keycode_to_action(KC_LGUI);
             }
@@ -63,13 +67,13 @@ action_t action_for_key(uint8_t layer, keypos_t key)
                 return keycode_to_action(KC_LALT);
             }
             if (keymap_config.no_gui) {
-                return keycode_to_action(ACTION_NO);
+                return keycode_to_action(KC_NO);
             }
             return keycode_to_action(KC_LGUI);
         case KC_RALT:
             if (keymap_config.swap_ralt_rgui) {
                 if (keymap_config.no_gui) {
-                    return keycode_to_action(ACTION_NO);
+                    return keycode_to_action(KC_NO);
                 }
                 return keycode_to_action(KC_RGUI);
             }
@@ -79,7 +83,7 @@ action_t action_for_key(uint8_t layer, keypos_t key)
                 return keycode_to_action(KC_RALT);
             }
             if (keymap_config.no_gui) {
-                return keycode_to_action(ACTION_NO);
+                return keycode_to_action(KC_NO);
             }
             return keycode_to_action(KC_RGUI);
         case KC_GRAVE:
@@ -133,23 +137,22 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
 /* translates keycode to action */
 static action_t keycode_to_action(uint8_t keycode)
 {
-    action_t action = {};
     switch (keycode) {
         case KC_A ... KC_EXSEL:
         case KC_LCTRL ... KC_RGUI:
-            action.code = ACTION_KEY(keycode);
+            return (action_t)ACTION_KEY(keycode);
             break;
         case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
-            action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
+            return (action_t)ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
             break;
         case KC_AUDIO_MUTE ... KC_WWW_FAVORITES:
-            action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
+            return (action_t)ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
             break;
         case KC_MS_UP ... KC_MS_ACCEL2:
-            action.code = ACTION_MOUSEKEY(keycode);
+            return (action_t)ACTION_MOUSEKEY(keycode);
             break;
         case KC_TRNS:
-            action.code = ACTION_TRANSPARENT;
+            return (action_t)ACTION_TRANSPARENT;
             break;
         case KC_BOOTLOADER:
             clear_keyboard();
@@ -157,10 +160,10 @@ static action_t keycode_to_action(uint8_t keycode)
             bootloader_jump(); // not return
             break;
         default:
-            action.code = ACTION_NO;
+            return (action_t)ACTION_NO;
             break;
     }
-    return action;
+    return (action_t)ACTION_NO;
 }
 
 
@@ -170,6 +173,28 @@ static action_t keycode_to_action(uint8_t keycode)
  * Legacy keymap support
  *      Consider using new keymap API instead.
  */
+extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
+extern const uint8_t fn_layer[];
+extern const uint8_t fn_keycode[];
+
+__attribute__ ((weak))
+uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
+{
+    return pgm_read_byte(&keymaps[(layer)][(row)][(col)]);
+}
+
+__attribute__ ((weak))
+uint8_t keymap_fn_layer(uint8_t index)
+{
+    return pgm_read_byte(&fn_layer[index]);
+}
+
+__attribute__ ((weak))
+uint8_t keymap_fn_keycode(uint8_t index)
+{
+    return pgm_read_byte(&fn_keycode[index]);
+}
+
 __attribute__ ((weak))
 uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
 {
@@ -181,21 +206,47 @@ uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
 __attribute__ ((weak))
 action_t keymap_fn_to_action(uint8_t keycode)
 {
-    action_t action = { .code = ACTION_NO };
     switch (keycode) {
         case KC_FN0 ... KC_FN31:
             {
                 uint8_t layer = keymap_fn_layer(FN_INDEX(keycode));
                 uint8_t key = keymap_fn_keycode(FN_INDEX(keycode));
                 if (key) {
-                    action.code = ACTION_LAYER_TAP_KEY(layer, key);
+                    return (action_t)ACTION_LAYER_TAP_KEY(layer, key);
                 } else {
-                    action.code = ACTION_LAYER_MOMENTARY(layer);
+                    return (action_t)ACTION_LAYER_MOMENTARY(layer);
                 }
             }
-            return action;
+            return (action_t)ACTION_NO;
         default:
-            return action;
+            return (action_t)ACTION_NO;
     }
 }
+
+#else
+
+/* user keymaps should be defined somewhere */
+extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
+extern const action_t fn_actions[];
+
+__attribute__ ((weak))
+uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
+{
+#if defined(__AVR__)
+    return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
+#else
+    return keymaps[(layer)][(key.row)][(key.col)];
+#endif
+}
+
+__attribute__ ((weak))
+action_t keymap_fn_to_action(uint8_t keycode)
+{
+#if defined(__AVR__)
+    return (action_t)pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
+#else
+    return fn_actions[FN_INDEX(keycode)];
+#endif
+}
+
 #endif
diff --git a/common/matrix.c b/common/matrix.c
new file mode 100644 (file)
index 0000000..9939307
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+Copyright 2016 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 "print.h"
+#include "matrix.h"
+
+
+__attribute__ ((weak))
+uint8_t matrix_rows(void)
+{
+    return MATRIX_ROWS;
+}
+
+__attribute__ ((weak))
+uint8_t matrix_cols(void)
+{
+    return MATRIX_COLS;
+}
+
+__attribute__ ((weak))
+void matrix_clear(void)
+{
+}
+
+__attribute__ ((weak))
+void matrix_setup(void) {}
+
+__attribute__ ((weak))
+bool matrix_is_on(uint8_t row, uint8_t col)
+{
+    return (matrix_get_row(row) & (1<<col));
+}
+
+__attribute__ ((weak))
+void matrix_print(void)
+{
+#if (MATRIX_COLS <= 8)
+    print("r/c 01234567\n");
+#elif (MATRIX_COLS <= 16)
+    print("r/c 0123456789ABCDEF\n");
+#elif (MATRIX_COLS <= 32)
+    print("r/c 0123456789ABCDEF0123456789ABCDEF\n");
+#endif
+
+    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+
+#if (MATRIX_COLS <= 8)
+        xprintf("%02X: %08b%s\n", row, bitrev(matrix_get_row(row)),
+#elif (MATRIX_COLS <= 16)
+        xprintf("%02X: %016b%s\n", row, bitrev16(matrix_get_row(row)),
+#elif (MATRIX_COLS <= 32)
+        xprintf("%02X: %032b%s\n", row, bitrev32(matrix_get_row(row)),
+#endif
+#ifdef MATRIX_HAS_GHOST
+        matrix_has_ghost_in_row(row) ?  " <ghost" : ""
+#else
+        ""
+#endif
+        );
+    }
+}
+
+#ifdef MATRIX_HAS_GHOST
+__attribute__ ((weak))
+bool matrix_has_ghost_in_row(uint8_t row)
+{
+    matrix_row_t matrix_row = matrix_get_row(row);
+    // No ghost exists when less than 2 keys are down on the row
+    if (((matrix_row - 1) & matrix_row) == 0)
+        return false;
+
+    // Ghost occurs when the row shares column line with other row
+    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
+        if (i != row && (matrix_get_row(i) & matrix_row))
+            return true;
+    }
+    return false;
+}
+#endif
+
+__attribute__ ((weak)) void matrix_power_up(void) {}
+__attribute__ ((weak)) void matrix_power_down(void) {}
index ec6f8cd431895d19c957d4b28c069779eae5f05b..bf866477f4579704f82ef337006e7dc581ea12a1 100644 (file)
@@ -32,6 +32,10 @@ typedef  uint32_t   matrix_row_t;
 #error "MATRIX_COLS: invalid value"
 #endif
 
+#if (MATRIX_ROWS > 255)
+#error "MATRIX_ROWS must not exceed 255"
+#endif
+
 #define MATRIX_IS_ON(row, col)  (matrix_get_row(row) && (1<<col))
 
 
@@ -57,7 +61,12 @@ bool matrix_is_on(uint8_t row, uint8_t col);
 matrix_row_t matrix_get_row(uint8_t row);
 /* print matrix for debug */
 void matrix_print(void);
+/* clear matrix */
+void matrix_clear(void);
 
+#ifdef MATRIX_HAS_GHOST
+bool matrix_has_ghost_in_row(uint8_t row);
+#endif
 
 /* power control */
 void matrix_power_up(void);
index 0c799eca39af5581cb22912f24ea749524afc11a..f21e84ee146819eef02659b1f25111b5cfbad420 100644 (file)
@@ -46,25 +46,25 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define TRANSPORT_STOP_EJECT    0x00CC
 #define TRANSPORT_PLAY_PAUSE    0x00CD
 /* application launch */
-#define AL_CC_CONFIG            0x0183
-#define AL_EMAIL                0x018A
-#define AL_CALCULATOR           0x0192
-#define AL_LOCAL_BROWSER        0x0194
+#define APPLAUNCH_CC_CONFIG     0x0183
+#define APPLAUNCH_EMAIL         0x018A
+#define APPLAUNCH_CALCULATOR    0x0192
+#define APPLAUNCH_LOCAL_BROWSER 0x0194
 /* application control */
-#define AC_SEARCH               0x0221
-#define AC_HOME                 0x0223
-#define AC_BACK                 0x0224
-#define AC_FORWARD              0x0225
-#define AC_STOP                 0x0226
-#define AC_REFRESH              0x0227
-#define AC_BOOKMARKS            0x022A
+#define APPCONTROL_SEARCH       0x0221
+#define APPCONTROL_HOME         0x0223
+#define APPCONTROL_BACK         0x0224
+#define APPCONTROL_FORWARD      0x0225
+#define APPCONTROL_STOP         0x0226
+#define APPCONTROL_REFRESH      0x0227
+#define APPCONTROL_BOOKMARKS    0x022A
 /* supplement for Bluegiga iWRAP HID(not supported by Windows?) */
-#define AL_LOCK                 0x019E
+#define APPLAUNCH_LOCK          0x019E
 #define TRANSPORT_RECORD        0x00B2
 #define TRANSPORT_FAST_FORWARD  0x00B3
 #define TRANSPORT_REWIND        0x00B4
 #define TRANSPORT_EJECT         0x00B8
-#define AC_MINIMIZE             0x0206
+#define APPCONTROL_MINIMIZE     0x0206
 
 /* Generic Desktop Page(0x01) - system power control */
 #define SYSTEM_POWER_DOWN       0x0081
@@ -159,27 +159,27 @@ typedef struct {
 
 /* keycode to consumer usage */
 #define KEYCODE2CONSUMER(key) \
-    (key == KC_AUDIO_MUTE       ?  AUDIO_MUTE : \
-    (key == KC_AUDIO_VOL_UP     ?  AUDIO_VOL_UP : \
-    (key == KC_AUDIO_VOL_DOWN   ?  AUDIO_VOL_DOWN : \
-    (key == KC_MEDIA_NEXT_TRACK ?  TRANSPORT_NEXT_TRACK : \
-    (key == KC_MEDIA_PREV_TRACK ?  TRANSPORT_PREV_TRACK : \
-    (key == KC_MEDIA_FAST_FORWARD ?  TRANSPORT_FAST_FORWARD : \
-    (key == KC_MEDIA_REWIND     ?  TRANSPORT_REWIND : \
-    (key == KC_MEDIA_STOP       ?  TRANSPORT_STOP : \
-    (key == KC_MEDIA_EJECT      ?  TRANSPORT_STOP_EJECT : \
-    (key == KC_MEDIA_PLAY_PAUSE ?  TRANSPORT_PLAY_PAUSE : \
-    (key == KC_MEDIA_SELECT     ?  AL_CC_CONFIG : \
-    (key == KC_MAIL             ?  AL_EMAIL : \
-    (key == KC_CALCULATOR       ?  AL_CALCULATOR : \
-    (key == KC_MY_COMPUTER      ?  AL_LOCAL_BROWSER : \
-    (key == KC_WWW_SEARCH       ?  AC_SEARCH : \
-    (key == KC_WWW_HOME         ?  AC_HOME : \
-    (key == KC_WWW_BACK         ?  AC_BACK : \
-    (key == KC_WWW_FORWARD      ?  AC_FORWARD : \
-    (key == KC_WWW_STOP         ?  AC_STOP : \
-    (key == KC_WWW_REFRESH      ?  AC_REFRESH : \
-    (key == KC_WWW_FAVORITES    ?  AC_BOOKMARKS : 0)))))))))))))))))))))
+    (key == KC_AUDIO_MUTE           ?  AUDIO_MUTE : \
+    (key == KC_AUDIO_VOL_UP         ?  AUDIO_VOL_UP : \
+    (key == KC_AUDIO_VOL_DOWN       ?  AUDIO_VOL_DOWN : \
+    (key == KC_MEDIA_NEXT_TRACK     ?  TRANSPORT_NEXT_TRACK : \
+    (key == KC_MEDIA_PREV_TRACK     ?  TRANSPORT_PREV_TRACK : \
+    (key == KC_MEDIA_FAST_FORWARD   ?  TRANSPORT_FAST_FORWARD : \
+    (key == KC_MEDIA_REWIND         ?  TRANSPORT_REWIND : \
+    (key == KC_MEDIA_STOP           ?  TRANSPORT_STOP : \
+    (key == KC_MEDIA_EJECT          ?  TRANSPORT_STOP_EJECT : \
+    (key == KC_MEDIA_PLAY_PAUSE     ?  TRANSPORT_PLAY_PAUSE : \
+    (key == KC_MEDIA_SELECT         ?  APPLAUNCH_CC_CONFIG : \
+    (key == KC_MAIL                 ?  APPLAUNCH_EMAIL : \
+    (key == KC_CALCULATOR           ?  APPLAUNCH_CALCULATOR : \
+    (key == KC_MY_COMPUTER          ?  APPLAUNCH_LOCAL_BROWSER : \
+    (key == KC_WWW_SEARCH           ?  APPCONTROL_SEARCH : \
+    (key == KC_WWW_HOME             ?  APPCONTROL_HOME : \
+    (key == KC_WWW_BACK             ?  APPCONTROL_BACK : \
+    (key == KC_WWW_FORWARD          ?  APPCONTROL_FORWARD : \
+    (key == KC_WWW_STOP             ?  APPCONTROL_STOP : \
+    (key == KC_WWW_REFRESH          ?  APPCONTROL_REFRESH : \
+    (key == KC_WWW_FAVORITES        ?  APPCONTROL_BOOKMARKS : 0)))))))))))))))))))))
 
 #ifdef __cplusplus
 }
index 6bdcf558a4503f50b1c81a81546482cf56a4112a..585c0d995b75ad22b9b6dd39d31026fe8ea5207e 100644 (file)
@@ -2,20 +2,10 @@
 #define SLEEP_LED_H
 
 
-#ifdef SLEEP_LED_ENABLE
-
 void sleep_led_init(void);
 void sleep_led_enable(void);
 void sleep_led_disable(void);
-void sleep_led_toggle(void);
-
-#else
-
-#define sleep_led_init()
-#define sleep_led_enable()
-#define sleep_led_disable()
-#define sleep_led_toggle()
-
-#endif
+void sleep_led_on(void);
+void sleep_led_off(void);
 
 #endif
diff --git a/common/unimap.c b/common/unimap.c
new file mode 100644 (file)
index 0000000..84109b5
--- /dev/null
@@ -0,0 +1,59 @@
+#include "keyboard.h"
+#include "action.h"
+#include "unimap.h"
+#include "print.h"
+#if defined(__AVR__)
+#   include <avr/pgmspace.h>
+#endif
+
+
+/* Keymapping with 16bit action codes */
+extern const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS];
+
+// table translates matrix to universal keymap
+extern const uint8_t unimap_trans[MATRIX_ROWS][MATRIX_COLS];
+
+
+
+// translates raw matrix to universal map
+keypos_t unimap_translate(keypos_t key)
+{
+    uint8_t unimap_pos = 
+#if defined(__AVR__)
+        pgm_read_byte(&unimap_trans[key.row][key.col]);
+#else
+        unimap_trans[key.row][key.col];
+#endif
+    return (keypos_t) {
+        .row = ((unimap_pos & 0xf0) >> 4),
+        .col = (unimap_pos & 0x0f)
+    };
+}
+
+/* Converts key to action */
+__attribute__ ((weak))
+action_t action_for_key(uint8_t layer, keypos_t key)
+{
+    keypos_t uni = unimap_translate(key);
+    if ((uni.row << 4 | uni.col) == UNIMAP_NO) {
+        return (action_t)ACTION_NO;
+    }
+#if defined(__AVR__)
+    return (action_t)pgm_read_word(&actionmaps[(layer)][(uni.row & 0x7)][(uni.col)]);
+#else
+    return actionmaps[(layer)][(uni.row & 0x7)][(uni.col)];
+#endif
+}
+
+/* Macro */
+__attribute__ ((weak))
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+    return MACRO_NONE;
+}
+
+/* Function */
+__attribute__ ((weak))
+void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+}
diff --git a/common/unimap.h b/common/unimap.h
new file mode 100644 (file)
index 0000000..6a78d88
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+Copyright 2016 Jun Wako <wakojun@gmail.com>
+*/
+#ifndef _UNIMAP_H_
+#define _UNIMAP_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "action.h"
+#include "action_code.h"
+#include "actionmap.h"
+
+
+// Universal map table: 8x16=128key
+#define UNIMAP_ROWS 8
+#define UNIMAP_COLS 16
+
+/* Universal 128-key keyboard layout(8x16)
+        ,-----------------------------------------------.
+        |F13|F14|F15|F16|F17|F18|F19|F20|F21|F22|F23|F24|
+,---.   |-----------------------------------------------|     ,-----------.     ,-----------.
+|Esc|   |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|     |PrS|ScL|Pau|     |VDn|VUp|Mut|
+`---'   `-----------------------------------------------'     `-----------'     `-----------'
+,-----------------------------------------------------------. ,-----------. ,---------------.
+|  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|JPY|Bsp| |Ins|Hom|PgU| |NmL|  /|  *|  -|
+|-----------------------------------------------------------| |-----------| |---------------|
+|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \  | |Del|End|PgD| |  7|  8|  9|  +|
+|-----------------------------------------------------------| `-----------' |---------------|
+|CapsL |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  #|Entr|               |  4|  5|  6|KP,|
+|-----------------------------------------------------------|     ,---.     |---------------|
+|Shft|  <|  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /| RO|Shift |     |Up |     |  1|  2|  3|Ent|
+|-----------------------------------------------------------| ,-----------. |---------------|
+|Ctl|Gui|Alt|MHEN|     Space      |HENK|KANA|Alt|Gui|App|Ctl| |Lef|Dow|Rig| |  0    |  .|KP=|
+`-----------------------------------------------------------' `-----------' `---------------'
+App:         Windows Menu key
+Gui:         Windows key, Mac ⌘ key or Meta key
+VDn Vup Mut: Volume control
+< #:         ISO keys(in UK legend)
+KP=:         Keypad = for Mac
+KP,:         Brazilian Keypad Comma
+JPY:         Japanese Yen(¥)
+RO:          Japanese ろ(Ro) or Brazilian /(Slash)
+MHEN:        Japanese 無変換(Non Conversion) or Korean Hanja
+HENK:        Japanese 変換(Conversion) or Korean Hangul/English
+KANA:        Japanese かな(Hiragana/Katakana)
+https://en.wikipedia.org/wiki/Keyboard_layout#Japanese
+https://en.wikipedia.org/wiki/Keyboard_layout#Hangul_.28for_Korean.29
+*/
+#define UNIMAP( \
+            K68,K69,K6A,K6B,K6C,K6D,K6E,K6F,K70,K71,K72,K73,                                     \
+    K29,    K3A,K3B,K3C,K3D,K3E,K3F,K40,K41,K42,K43,K44,K45,      K46,K47,K48,      K01,K02,K03, \
+    K35,K1E,K1F,K20,K21,K22,K23,K24,K25,K26,K27,K2D,K2E,K74,K2A,  K49,K4A,K4B,  K53,K54,K55,K56, \
+    K2B,K14,K1A,K08,K15,K17,K1C,K18,K0C,K12,K13,K2F,K30,    K31,  K4C,K4D,K4E,  K5F,K60,K61,K57, \
+    K39,K04,K16,K07,K09,K0A,K0B,K0D,K0E,K0F,K33,K34,    K32,K28,                K5C,K5D,K5E,K66, \
+    K79,K64,K1D,K1B,K06,K19,K05,K11,K10,K36,K37,K38,    K75,K7D,      K52,      K59,K5A,K5B,K58, \
+    K78,K7B,K7A,K77,        K2C,        K76,K00,K7E,K7F,K65,K7C,  K50,K51,K4F,      K62,K63,K67  \
+) { \
+    { AC_##K00, AC_##K01, AC_##K02, AC_##K03, AC_##K04, AC_##K05, AC_##K06, AC_##K07,   /* 00-07 */ \
+      AC_##K08, AC_##K09, AC_##K0A, AC_##K0B, AC_##K0C, AC_##K0D, AC_##K0E, AC_##K0F }, /* 08-0F */ \
+    { AC_##K10, AC_##K11, AC_##K12, AC_##K13, AC_##K14, AC_##K15, AC_##K16, AC_##K17,   /* 10-17 */ \
+      AC_##K18, AC_##K19, AC_##K1A, AC_##K1B, AC_##K1C, AC_##K1D, AC_##K1E, AC_##K1F }, /* 18-1F */ \
+    { AC_##K20, AC_##K21, AC_##K22, AC_##K23, AC_##K24, AC_##K25, AC_##K26, AC_##K27,   /* 20-27 */ \
+      AC_##K28, AC_##K29, AC_##K2A, AC_##K2B, AC_##K2C, AC_##K2D, AC_##K2E, AC_##K2F }, /* 28-2F */ \
+    { AC_##K30, AC_##K31, AC_##K32, AC_##K33, AC_##K34, AC_##K35, AC_##K36, AC_##K37,   /* 30-37 */ \
+      AC_##K38, AC_##K39, AC_##K3A, AC_##K3B, AC_##K3C, AC_##K3D, AC_##K3E, AC_##K3F }, /* 38-3F */ \
+    { AC_##K40, AC_##K41, AC_##K42, AC_##K43, AC_##K44, AC_##K45, AC_##K46, AC_##K47,   /* 40-47 */ \
+      AC_##K48, AC_##K49, AC_##K4A, AC_##K4B, AC_##K4C, AC_##K4D, AC_##K4E, AC_##K4F }, /* 48-4F */ \
+    { AC_##K50, AC_##K51, AC_##K52, AC_##K53, AC_##K54, AC_##K55, AC_##K56, AC_##K57,   /* 50-57 */ \
+      AC_##K58, AC_##K59, AC_##K5A, AC_##K5B, AC_##K5C, AC_##K5D, AC_##K5E, AC_##K5F }, /* 58-5F */ \
+    { AC_##K60, AC_##K61, AC_##K62, AC_##K63, AC_##K64, AC_##K65, AC_##K66, AC_##K67,   /* 60-67 */ \
+      AC_##K68, AC_##K69, AC_##K6A, AC_##K6B, AC_##K6C, AC_##K6D, AC_##K6E, AC_##K6F }, /* 68-6F */ \
+    { AC_##K70, AC_##K71, AC_##K72, AC_##K73, AC_##K74, AC_##K75, AC_##K76, AC_##K77,   /* 70-77 */ \
+      AC_##K78, AC_##K79, AC_##K7A, AC_##K7B, AC_##K7C, AC_##K7D, AC_##K7E, AC_##K7F }  /* 78-7F */ \
+}
+
+// Universal map position codes
+enum unimap_position_codes {
+//  logical name            position(row << 4 | col)
+//  ------------------------------------------------
+    UNIMAP_KANA,            // 0x00
+    UNIMAP_VOLUME_DOWN,     // 0x01
+    UNIMAP_VOLUME_UP,       // 0x02
+    UNIMAP_VOLUME_MUTE,     // 0x03
+    UNIMAP_A,               // 0x04
+    UNIMAP_B,               // 0x05
+    UNIMAP_C,               // 0x06
+    UNIMAP_D,               // 0x07
+    UNIMAP_E,               // 0x08
+    UNIMAP_F,               // 0x09
+    UNIMAP_G,               // 0x0A
+    UNIMAP_H,               // 0x0B
+    UNIMAP_I,               // 0x0C
+    UNIMAP_J,               // 0x0D
+    UNIMAP_K,               // 0x0E
+    UNIMAP_L,               // 0x0F
+    UNIMAP_M,               // 0x10
+    UNIMAP_N,               // 0x11
+    UNIMAP_O,               // 0x12
+    UNIMAP_P,               // 0x13
+    UNIMAP_Q,               // 0x14
+    UNIMAP_R,               // 0x15
+    UNIMAP_S,               // 0x16
+    UNIMAP_T,               // 0x17
+    UNIMAP_U,               // 0x18
+    UNIMAP_V,               // 0x19
+    UNIMAP_W,               // 0x1A
+    UNIMAP_X,               // 0x1B
+    UNIMAP_Y,               // 0x1C
+    UNIMAP_Z,               // 0x1D
+    UNIMAP_1,               // 0x1E
+    UNIMAP_2,               // 0x1F
+    UNIMAP_3,               // 0x20
+    UNIMAP_4,               // 0x21
+    UNIMAP_5,               // 0x22
+    UNIMAP_6,               // 0x23
+    UNIMAP_7,               // 0x24
+    UNIMAP_8,               // 0x25
+    UNIMAP_9,               // 0x26
+    UNIMAP_0,               // 0x27
+    UNIMAP_ENTER,           // 0x28
+    UNIMAP_ESCAPE,          // 0x29
+    UNIMAP_BSPACE,          // 0x2A
+    UNIMAP_TAB,             // 0x2B
+    UNIMAP_SPACE,           // 0x2C
+    UNIMAP_MINUS,           // 0x2D
+    UNIMAP_EQUAL,           // 0x2E
+    UNIMAP_LBRACKET,        // 0x2F
+    UNIMAP_RBRACKET,        // 0x30
+    UNIMAP_BSLASH,          // 0x31
+    UNIMAP_NONUS_HASH,      // 0x32 ISO UK hasu
+    UNIMAP_SCOLON,          // 0x33
+    UNIMAP_QUOTE,           // 0x34
+    UNIMAP_GRAVE,           // 0x35
+    UNIMAP_COMMA,           // 0x36
+    UNIMAP_DOT,             // 0x37
+    UNIMAP_SLASH,           // 0x38
+    UNIMAP_CAPSLOCK,        // 0x39
+    UNIMAP_F1,              // 0x3A
+    UNIMAP_F2,              // 0x3B
+    UNIMAP_F3,              // 0x3C
+    UNIMAP_F4,              // 0x3D
+    UNIMAP_F5,              // 0x3E
+    UNIMAP_F6,              // 0x3F
+    UNIMAP_F7,              // 0x40
+    UNIMAP_F8,              // 0x41
+    UNIMAP_F9,              // 0x42
+    UNIMAP_F10,             // 0x43
+    UNIMAP_F11,             // 0x44
+    UNIMAP_F12,             // 0x45
+    UNIMAP_PSCREEN,         // 0x46
+    UNIMAP_SCROLLLOCK,      // 0x47
+    UNIMAP_PAUSE,           // 0x48
+    UNIMAP_INSERT,          // 0x49
+    UNIMAP_HOME,            // 0x4A
+    UNIMAP_PGUP,            // 0x4B
+    UNIMAP_DELETE,          // 0x4C
+    UNIMAP_END,             // 0x4D
+    UNIMAP_PGDOWN,          // 0x4E
+    UNIMAP_RIGHT,           // 0x4F
+    UNIMAP_LEFT,            // 0x50
+    UNIMAP_DOWN,            // 0x51
+    UNIMAP_UP,              // 0x52
+    UNIMAP_NUMLOCK,         // 0x53
+    UNIMAP_KP_SLASH,        // 0x54
+    UNIMAP_KP_ASTERISK,     // 0x55
+    UNIMAP_KP_MINUS,        // 0x56
+    UNIMAP_KP_PLUS,         // 0x57
+    UNIMAP_KP_ENTER,        // 0x58
+    UNIMAP_KP_1,            // 0x59
+    UNIMAP_KP_2,            // 0x5A
+    UNIMAP_KP_3,            // 0x5B
+    UNIMAP_KP_4,            // 0x5C
+    UNIMAP_KP_5,            // 0x5D
+    UNIMAP_KP_6,            // 0x5E
+    UNIMAP_KP_7,            // 0x5F
+    UNIMAP_KP_8,            // 0x60
+    UNIMAP_KP_9,            // 0x61
+    UNIMAP_KP_0,            // 0x62
+    UNIMAP_KP_DOT,          // 0x63
+    UNIMAP_NONUS_BSLASH,    // 0x64 ISO UK backslash
+    UNIMAP_APPLICATION,     // 0x65
+    UNIMAP_KP_COMMA,        // 0x66
+    UNIMAP_KP_EQUAL,        // 0x67
+    UNIMAP_F13,             // 0x68
+    UNIMAP_F14,             // 0x69
+    UNIMAP_F15,             // 0x6A
+    UNIMAP_F16,             // 0x6B
+    UNIMAP_F17,             // 0x6C
+    UNIMAP_F18,             // 0x6D
+    UNIMAP_F19,             // 0x6E
+    UNIMAP_F20,             // 0x6F
+    UNIMAP_F21,             // 0x70
+    UNIMAP_F22,             // 0x71
+    UNIMAP_F23,             // 0x72
+    UNIMAP_F24,             // 0x73
+    UNIMAP_JYEN,            // 0x74
+    UNIMAP_RO,              // 0x75
+    UNIMAP_HENK,            // 0x76
+    UNIMAP_MHEN,            // 0x77
+    UNIMAP_LCTRL,           // 0x78
+    UNIMAP_LSHIFT,          // 0x79
+    UNIMAP_LALT,            // 0x7A
+    UNIMAP_LGUI,            // 0x7B
+    UNIMAP_RCTRL,           // 0x7C
+    UNIMAP_RSHIFT,          // 0x7D
+    UNIMAP_RALT,            // 0x7E
+    UNIMAP_RGUI,            // 0x7F
+    UNIMAP_NO,              // 0x80
+};
+
+/*
+ * Short names
+ */
+#define UNIMAP_LCTL UNIMAP_LCTRL
+#define UNIMAP_RCTL UNIMAP_RCTRL
+#define UNIMAP_LSFT UNIMAP_LSHIFT
+#define UNIMAP_RSFT UNIMAP_RSHIFT
+#define UNIMAP_ESC  UNIMAP_ESCAPE
+#define UNIMAP_BSPC UNIMAP_BSPACE
+#define UNIMAP_ENT  UNIMAP_ENTER
+#define UNIMAP_DEL  UNIMAP_DELETE
+#define UNIMAP_INS  UNIMAP_INSERT
+#define UNIMAP_CAPS UNIMAP_CAPSLOCK
+#define UNIMAP_CLCK UNIMAP_CAPSLOCK
+#define UNIMAP_RGHT UNIMAP_RIGHT
+#define UNIMAP_PGDN UNIMAP_PGDOWN
+#define UNIMAP_PSCR UNIMAP_PSCREEN
+#define UNIMAP_SLCK UNIMAP_SCROLLLOCK
+#define UNIMAP_PAUS UNIMAP_PAUSE
+#define UNIMAP_BRK  UNIMAP_PAUSE
+#define UNIMAP_NLCK UNIMAP_NUMLOCK
+#define UNIMAP_SPC  UNIMAP_SPACE
+#define UNIMAP_MINS UNIMAP_MINUS
+#define UNIMAP_EQL  UNIMAP_EQUAL
+#define UNIMAP_GRV  UNIMAP_GRAVE
+#define UNIMAP_RBRC UNIMAP_RBRACKET
+#define UNIMAP_LBRC UNIMAP_LBRACKET
+#define UNIMAP_COMM UNIMAP_COMMA
+#define UNIMAP_BSLS UNIMAP_BSLASH
+#define UNIMAP_SLSH UNIMAP_SLASH
+#define UNIMAP_SCLN UNIMAP_SCOLON
+#define UNIMAP_QUOT UNIMAP_QUOTE
+#define UNIMAP_APP  UNIMAP_APPLICATION
+#define UNIMAP_NUHS UNIMAP_NONUS_HASH
+#define UNIMAP_NUBS UNIMAP_NONUS_BSLASH
+/* Japanese specific */
+#define UNIMAP_ZKHK UNIMAP_GRAVE
+/* Keypad */
+#define UNIMAP_P1   UNIMAP_KP_1
+#define UNIMAP_P2   UNIMAP_KP_2
+#define UNIMAP_P3   UNIMAP_KP_3
+#define UNIMAP_P4   UNIMAP_KP_4
+#define UNIMAP_P5   UNIMAP_KP_5
+#define UNIMAP_P6   UNIMAP_KP_6
+#define UNIMAP_P7   UNIMAP_KP_7
+#define UNIMAP_P8   UNIMAP_KP_8
+#define UNIMAP_P9   UNIMAP_KP_9
+#define UNIMAP_P0   UNIMAP_KP_0
+#define UNIMAP_PDOT UNIMAP_KP_DOT
+#define UNIMAP_PCMM UNIMAP_KP_COMMA
+#define UNIMAP_PSLS UNIMAP_KP_SLASH
+#define UNIMAP_PAST UNIMAP_KP_ASTERISK
+#define UNIMAP_PMNS UNIMAP_KP_MINUS
+#define UNIMAP_PPLS UNIMAP_KP_PLUS
+#define UNIMAP_PEQL UNIMAP_KP_EQUAL
+#define UNIMAP_PENT UNIMAP_KP_ENTER
+/* Consumer Page */
+#define UNIMAP_MUTE UNIMAP_VOLUME_MUTE
+#define UNIMAP_VOLU UNIMAP_VOLUME_UP
+#define UNIMAP_VOLD UNIMAP_VOLUME_DOWN
+
+#endif
index 7451cc084da9e4483977411dc1ed19eb99475d5a..3e01a93dd92980bfe918faf4f4e1e850789cd91a 100644 (file)
@@ -28,6 +28,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define XSTR(s) #s
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 uint8_t bitpop(uint8_t bits);
 uint8_t bitpop16(uint16_t bits);
 uint8_t bitpop32(uint32_t bits);
@@ -40,4 +44,8 @@ uint8_t  bitrev(uint8_t bits);
 uint16_t bitrev16(uint16_t bits);
 uint32_t bitrev32(uint32_t bits);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index 44d7e27cd6a562f4efef616cc2f9c7981de3a73f..1712929cefa36e7a8e5cc2b6b35366404053f8a1 100644 (file)
@@ -1,7 +1,7 @@
 Keycode Symbol Table
 ====================
 Keycodes are defined in `common/keycode.h`.
-Range of 00-A4 and E0-E7 are identical with HID Usage:
+Range of 00-A4 and E0-E7 are identical with HID Usage of Keyboard/Keypad Page(0x07):
 <http://www.usb.org/developers/devclass_docs/Hut1_11.pdf>
 Virtual keycodes are defined out of above range to support special actions.
 
@@ -186,30 +186,35 @@ KC_RGUI                             E7 Keyboard Right GUI(Windows/Apple/Meta key
 /* 
  * Virtual keycodes
  */
-/* System Control */
+/* Generic Desktop Page(0x01) - System Control */
 KC_SYSTEM_POWER     KC_PWR          System Power Down
 KC_SYSTEM_SLEEP     KC_SLEP         System Sleep
 KC_SYSTEM_WAKE      KC_WAKE         System Wake
-/* Consumer Page */
-KC_AUDIO_MUTE       KC_MUTE
-KC_AUDIO_VOL_UP     KC_VOLU
-KC_AUDIO_VOL_DOWN   KC_VOLD
-KC_MEDIA_NEXT_TRACK KC_MNXT
-KC_MEDIA_PREV_TRACK KC_MPRV
-KC_MEDIA_STOP       KC_MSTP
-KC_MEDIA_PLAY_PAUSE KC_MPLY
-KC_MEDIA_SELECT     KC_MSEL
-KC_MAIL             KC_MAIL
-KC_CALCULATOR       KC_CALC
-KC_MY_COMPUTER      KC_MYCM
-KC_WWW_SEARCH       KC_WSCH
-KC_WWW_HOME         KC_WHOM
-KC_WWW_BACK         KC_WBAK
-KC_WWW_FORWARD      KC_WFWD
-KC_WWW_STOP         KC_WSTP
-KC_WWW_REFRESH      KC_WREF
-KC_WWW_FAVORITES    KC_WFAV
-/* Mousekey */
+
+/* Consumer Page(0x07) */
+KC_AUDIO_MUTE       KC_MUTE         Mute
+KC_AUDIO_VOL_UP     KC_VOLU         Volume Increment
+KC_AUDIO_VOL_DOWN   KC_VOLD         Volume Decrement
+KC_MEDIA_NEXT_TRACK KC_MNXT         Scan Next Track
+KC_MEDIA_PREV_TRACK KC_MPRV         Scan Previous Track
+KC_MEDIA_STOP       KC_MSTP         Stop
+KC_MEDIA_FAST_FORWARD   KC_MFFD     Fast Forward
+KC_MEDIA_REWIND     KC_MRWD         Rewind
+KC_MEDIA_PLAY_PAUSE KC_MPLY         Play/Pause
+KC_EJCT             KC_MEDIA_EJECT  Stop/Eject
+KC_MEDIA_SELECT     KC_MSEL         AL Consumer Control Configuration
+KC_MAIL             KC_MAIL         AL Email Reader
+KC_CALCULATOR       KC_CALC         AL Calculator
+KC_MY_COMPUTER      KC_MYCM         AL Local Machine Browser
+KC_WWW_SEARCH       KC_WSCH         AC Search
+KC_WWW_HOME         KC_WHOM         AC Home
+KC_WWW_BACK         KC_WBAK         AC Back
+KC_WWW_FORWARD      KC_WFWD         AC Forward
+KC_WWW_STOP         KC_WSTP         AC Stop
+KC_WWW_REFRESH      KC_WREF         AC Refresh
+KC_WWW_FAVORITES    KC_WFAV         AC Bookmarks
+
+/* Mousekey - TMK specific */
 KC_MS_UP            KC_MS_U         Mouse Cursor Up
 KC_MS_DOWN          KC_MS_D         Mouse Cursor Down
 KC_MS_LEFT          KC_MS_L         Mouse Cursor Left
@@ -226,7 +231,8 @@ KC_MS_WH_RIGHT      KC_WH_R         Mouse Wheel Right
 KC_MS_ACCEL0        KC_ACL0         Mouse Acceleration 0
 KC_MS_ACCEL1        KC_ACL1         Mouse Acceleration 1
 KC_MS_ACCEL2        KC_ACL2         Mouse Acceleration 2
-/* Fn key */
+
+/* Fn key - TMK specific */
 KC_FN0
 KC_FN1
 KC_FN2
index 3a196a2dd5bb17e3ff8c0af8b29c156024fe548e..87b72e059bc249a2e7d48f1a4154cc3955b80828 100644 (file)
@@ -95,7 +95,7 @@ Note that ***higher layers have priority in the layer stack***. The firmware sta
 
 
 ### 0.3 Keymap Example
-The keymap is defined in the **`keymaps[]`** array, a 2-dimensional array of rows and columns corresponding to positions in the keyboard matrix. But most often the layers are defined using C macros to allow for easier reading and editing of the keymap files. To use complex actions you need to define `Fn` keycodes in the **`fn_actions[]`** array.
+The keymap is defined in the **`uint8_t keymaps[]`** array, a 2-dimensional array of rows and columns corresponding to positions in the keyboard matrix. But most often the layers are defined using C macros to allow for easier reading and editing of the keymap files. To use complex actions you need to define `Fn` action in the **`action_t fn_actions[]`** array.
 
 This is a keymap example for the [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard.
 This example has three layers: the QWERTY base layer, and two overlay layers for cursor and mousekey control, respectively.
@@ -109,7 +109,7 @@ In this example,
 
 You can find other keymap definitions in file `keymap.c` located on project directories.
 
-    static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+    const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
         /* 0: Qwerty
          * ,-----------------------------------------------------------.
          * |Esc|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|  \|  `|
@@ -167,7 +167,7 @@ You can find other keymap definitions in file `keymap.c` located on project dire
                     LGUI,LALT,          BTN1,               RALT,TRNS),
     };
 
-    static const uint16_t PROGMEM fn_actions[] = {
+    const action_t PROGMEM fn_actions[] = {
         ACTION_LAYER_MOMENTARY(1),                  // FN0
         ACTION_LAYER_TAP_KEY(2, KC_SCLN),           // FN1
         ACTION_LAYER_TOGGLE(2),                     // FN2
@@ -214,7 +214,7 @@ There are 8 modifiers which has discrimination between left and right.
 - `KC_WSCH`, `KC_WHOM`, `KC_WBAK`, `KC_WFWD`, `KC_WSTP`, `KC_WREF`, `KC_WFAV` for web browser operation
 
 ### 1.5 Fn key
-`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.***
+`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `action_t fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.***
 
 ### 1.6 Keycode Table
  See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes.
@@ -379,19 +379,33 @@ Default Layer also has bitwise operations, they are executed when key is release
     ACTION_DEFAULT_LAYER_BIT_SET(part, bits)
 
 
-
 ### 2.3 Macro action
-***TBD***
+`Macro` actions allow you to register a complex sequence of keystrokes when a key is pressed, where macros are simple sequences of keypresses.
+
+    ACTION_MACRO(id)
+    ACTION_MACRO_TAP(id)
+
+`id` is an 8-bit user-defined value the macro getter function can use to pick the specific macro.
+
+
+#### 2.3.1 Implementing Macro getter function
+To implement `macro` functions, the macro lookup list must be implemented: 
+
+    const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
 
-`Macro` action indicates complex key strokes.
-    MACRO( D(LSHIFT), D(D), END )
-    MACRO( U(D), U(LSHIFT), END )
-    MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END )
+The function must always return a valid macro, and default implementation of `action_get_macro` always returns `MACRO_NONE` which has no effect.
+  
+#### 2.3.1.1 Limitations
+Similar to the Function Action system, the selector functions is passed  a `keyrecord_t` object, so it can inspect the key state (e.g. different macros on key press or release), and key itself.
+  
+Unlike the Function Action system,`macros` are pre-recorded key sequences, so you can only select from a list. If you want to use dynamic macros then you should look at the more complex function action system. 
 
-#### 2.3.1 Macro Commands
-- **MACRO()**
-- **MACRO_NONE**
+#### 2.3.2 Implementing/Defining Macro sequences
+Macros are of the form (must be wrapped by the `MACRO` function, and end with an `END` mark)
+
+    MACRO( ..., END )
+    
+Within each macro, the following commands can be used:
 
 - **I()**   change interval of stroke.
 - **D()**   press key
@@ -401,19 +415,25 @@ Default Layer also has bitwise operations, they are executed when key is release
 - **SM()**  store modifier state
 - **RM()**  restore modifier state
 - **CM()**  clear modifier state
-- **END**   end mark
+
+e.g.:
+
+    MACRO( D(LSHIFT), D(D), END )  // hold down LSHIFT and D - will print 'D'  
+    MACRO( U(D), U(LSHIFT), END )  // release U and LSHIFT keys (an event.pressed == False counterpart for the one above)
+    MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ) // slowly print out h-e-l-l---o
 
 #### 2.3.2 Examples
-***TBD***
+
+in keymap.c, define `action_get_macro`
 
     const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
     {
         switch (id) {
-            case HELLO:
+            case 0:
                 return (record->event.pressed ?
                         MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) :
                         MACRO_NONE );
-            case ALT_TAB:
+            case 1:
                 return (record->event.pressed ?
                         MACRO( D(LALT), D(TAB), END ) :
                         MACRO( U(TAB), END ));
@@ -421,7 +441,12 @@ Default Layer also has bitwise operations, they are executed when key is release
         return MACRO_NONE;
     }
 
-
+in keymap.c, bind items in `fn_actions` to the macro function
+  
+    const action_t PROGMEM fn_actions[] = {
+         [0] = ACTION_MACRO(0), // will print 'hello' for example
+         [1] = ACTION_MACRO(1),
+    };
 
 
 ### 2.4 Function action
@@ -443,7 +468,7 @@ To define tappable `Function` action in keymap use this.
 #### 2.4.3 Implement user function
 `Function` actions can be defined freely with C by user in callback function:
 
-    void keymap_call_function(keyrecord_t *event, uint8_t id, uint8_t opt)
+    void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
 
 This C function is called every time key is operated, argument `id` selects action to be performed and `opt` can be used for option. Function `id` can be 0-255 and `opt` can be 0-15.
 
@@ -544,6 +569,7 @@ This registers modifier key(s) simultaneously with layer switching.
 
     ACTION_LAYER_MODS(2, MOD_LSFT | MOD_LALT)
 
+This function can only register left-sided modifiers. The handedness of the modifier (left/right) is an extra bit that is not able to be passed through into the layer system. See: [`common/action_code.h`](../common/action_code.h), the spec for ACT_LAYER_TAP only allows four bits for the mods, whereas the mods themselves require five bits, with the high bit being the left/right handedness.
 
 
 ## 4. Tapping
@@ -598,13 +624,13 @@ Legacy Keymap uses two arrays `fn_layer[]` and `fn_keycode[]` to define Fn key.
 
 In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tapping while `Fn0` and `Fn1` doesn't send any key.
 
-    static const uint8_t PROGMEM fn_layer[] = {
+    const uint8_t PROGMEM fn_layer[] = {
         1,              // Fn0
         2,              // Fn1
         2,              // Fn2
     };
 
-    static const uint8_t PROGMEM fn_keycode[] = {
+    const uint8_t PROGMEM fn_keycode[] = {
         KC_NO,          // Fn0
         KC_NO,          // Fn1
         KC_SPC,         // Fn2
diff --git a/doc/unimap.txt b/doc/unimap.txt
new file mode 100644 (file)
index 0000000..0db038e
--- /dev/null
@@ -0,0 +1,51 @@
+Unimap
+======
+universal keymapping framework
+using logical 128-key keyboard layout independent from physical keyboad matrix
+
+unimap is actually an actionmap whose size is row:8xcol:16.
+
+/* Keymapping with 16bit action codes */
+extern const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS];
+
+/* Universal 128-key keyboard layout(8x16)
+        ,-----------------------------------------------.
+        |F13|F14|F15|F16|F17|F18|F19|F20|F21|F22|F23|F24|
+,---.   |-----------------------------------------------|     ,-----------.     ,-----------.
+|Esc|   |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|     |PrS|ScL|Pau|     |VDn|VUp|Mut|
+`---'   `-----------------------------------------------'     `-----------'     `-----------'
+,-----------------------------------------------------------. ,-----------. ,---------------.
+|  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|JPY|Bsp| |Ins|Hom|PgU| |NmL|  /|  *|  -|
+|-----------------------------------------------------------| |-----------| |---------------|
+|Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \  | |Del|End|PgD| |  7|  8|  9|  +|
+|-----------------------------------------------------------| `-----------' |---------------|
+|CapsL |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  #|Retn|               |  4|  5|  6|KP,|
+|-----------------------------------------------------------|     ,---.     |---------------|
+|Shft|  <|  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /| RO|Shift |     |Up |     |  1|  2|  3|KP=|
+|-----------------------------------------------------------| ,-----------. |---------------|
+|Ctl|Gui|Alt|MHEN|     Space      |HENK|KANA|Alt|Gui|App|Ctl| |Lef|Dow|Rig| |  0    |  .|Ent|
+`-----------------------------------------------------------' `-----------' `---------------'
+App:         Windows Menu key
+Gui:         Windows key, Mac ⌘ key or Meta key
+VDn Vup Mut: Volume control
+< #:         ISO keys(in UK legend)
+KP=:         Keypad = for Mac
+KP,:         Brazilian Keypad Comma
+JPY:         Japanese Yen(¥)
+RO:          Japanese ろ(Ro) or Brazilian /(Slash)
+MHEN:        Japanese 無変換(Non Conversion) or Korean Hanja
+HENK:        Japanese 変換(Conversion) or Korean Hangul/English
+KANA:        Japanese かな(Hiragana/Katakana)
+https://en.wikipedia.org/wiki/Keyboard_layout#Japanese
+https://en.wikipedia.org/wiki/Keyboard_layout#Hangul_.28for_Korean.29
+*/
+
+
+when refering to keymapping physical matrix position needed to be translated into logical one on unimap
+the translation is defined in unimap array
+
+row and col of unimap positon is encoded as follows
+position = (row << 4) | col
+
+// table translates matrix to universal keymap
+extern const uint8_t unimap_trans[MATRIX_ROWS][MATRIX_COLS];
index 54913329e69ff0e9c9dcfde2445ad476d455b9c1..2bf05742f8782f57d4dbccb537cbd1ee768b49f2 100644 (file)
@@ -1,52 +1,59 @@
 PROTOCOL_DIR = protocol
 
 
-ifdef PS2_MOUSE_ENABLE
+ifeq (yes,$(strip $(PS2_MOUSE_ENABLE)))
     SRC += $(PROTOCOL_DIR)/ps2_mouse.c
     OPT_DEFS += -DPS2_MOUSE_ENABLE
     OPT_DEFS += -DMOUSE_ENABLE
 endif
 
-ifdef PS2_USE_BUSYWAIT
+ifeq (yes,$(strip $(PS2_USE_BUSYWAIT)))
     SRC += protocol/ps2_busywait.c
     SRC += protocol/ps2_io_avr.c
     OPT_DEFS += -DPS2_USE_BUSYWAIT
 endif
 
-ifdef PS2_USE_INT
+ifeq (yes,$(strip $(PS2_USE_INT)))
     SRC += protocol/ps2_interrupt.c
     SRC += protocol/ps2_io_avr.c
     OPT_DEFS += -DPS2_USE_INT
 endif
 
-ifdef PS2_USE_USART
+ifeq (yes,$(strip $(PS2_USE_USART)))
     SRC += protocol/ps2_usart.c
     SRC += protocol/ps2_io_avr.c
     OPT_DEFS += -DPS2_USE_USART
 endif
 
 
-ifdef SERIAL_MOUSE_MICROSOFT_ENABLE
+ifeq (yes,$(strip $(XT_USE_INT)))
+    SRC += protocol/xt_interrupt.c
+    SRC += protocol/xt_io_avr.c
+    OPT_DEFS += -DXT_USE_INT
+endif
+
+
+ifeq (yes,$(strip $(SERIAL_MOUSE_MICROSOFT_ENABLE)))
     SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c
     OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \
                 -DMOUSE_ENABLE
 endif
 
-ifdef SERIAL_MOUSE_MOUSESYSTEMS_ENABLE
+ifeq (yes,$(strip $(SERIAL_MOUSE_MOUSESYSTEMS_ENABLE)))
     SRC += $(PROTOCOL_DIR)/serial_mouse_mousesystems.c
     OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MOUSESYSTEMS \
                 -DMOUSE_ENABLE
 endif
 
-ifdef SERIAL_MOUSE_USE_SOFT
+ifeq (yes,$(strip $(SERIAL_MOUSE_USE_SOFT)))
     SRC += $(PROTOCOL_DIR)/serial_soft.c
 endif
 
-ifdef SERIAL_MOUSE_USE_UART
+ifeq (yes,$(strip $(SERIAL_MOUSE_USE_UART)))
     SRC += $(PROTOCOL_DIR)/serial_uart.c
 endif
 
-ifdef ADB_MOUSE_ENABLE
+ifeq (yes,$(strip $(ADB_MOUSE_ENABLE)))
         OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE
 endif
 
index 5c6c99b4fcc225fd4b5293eeafe1459271608a9c..164255efaeccf25b63c2a0cbbafb3d890b4317e8 100644 (file)
@@ -60,7 +60,6 @@ static inline void place_bit1(void);
 static inline void send_byte(uint8_t data);
 static inline uint16_t wait_data_lo(uint16_t us);
 static inline uint16_t wait_data_hi(uint16_t us);
-static inline uint16_t adb_host_dev_recv(uint8_t device);
 
 
 void adb_host_init(void)
@@ -87,49 +86,9 @@ bool adb_host_psw(void)
  * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
  * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
  */
-
-// ADB Bit Cells
-//
-// bit cell time: 70-130us
-// low part of bit0: 60-70% of bit cell
-// low part of bit1: 30-40% of bit cell
-//
-//    bit cell time         70us        130us
-//    --------------------------------------------
-//    low  part of bit0     42-49       78-91
-//    high part of bit0     21-28       39-52
-//    low  part of bit1     21-28       39-52
-//    high part of bit1     42-49       78-91
-//
-//
-// bit0:
-//    70us bit cell:
-//      ____________~~~~~~
-//      42-49        21-28  
-//
-//    130us bit cell:
-//      ____________~~~~~~
-//      78-91        39-52  
-//
-// bit1:
-//    70us bit cell:
-//      ______~~~~~~~~~~~~
-//      21-28        42-49
-//
-//    130us bit cell:
-//      ______~~~~~~~~~~~~
-//      39-52        78-91
-//
-// [from Apple IIgs Hardware Reference Second Edition]
-
-enum {
-    ADDR_KEYB  = 0x20,
-    ADDR_MOUSE = 0x30
-};
-
-uint16_t adb_host_kbd_recv(void)
+uint16_t adb_host_kbd_recv(uint8_t addr)
 {
-    return adb_host_dev_recv(ADDR_KEYB);
+    return adb_host_talk(addr, ADB_REG_0);
 }
 
 #ifdef ADB_MOUSE_ENABLE
@@ -139,16 +98,16 @@ void adb_mouse_init(void) {
 
 uint16_t adb_host_mouse_recv(void)
 {
-    return adb_host_dev_recv(ADDR_MOUSE);
+    return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0);
 }
 #endif
 
-static inline uint16_t adb_host_dev_recv(uint8_t device)
+uint16_t adb_host_talk(uint8_t addr, uint8_t reg)
 {
     uint16_t data = 0;
     cli();
     attention();
-    send_byte(device|0x0C);     // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
+    send_byte((addr<<4) | (ADB_CMD_TALK<<2) | reg);
     place_bit0();               // Stopbit(0)
     if (!wait_data_hi(500)) {    // Service Request(310us Adjustable Keyboard): just ignored
         sei();
@@ -158,20 +117,20 @@ static inline uint16_t adb_host_dev_recv(uint8_t device)
         sei();
         return 0;               // No data to send
     }
-    
+
     uint8_t n = 17; // start bit + 16 data bits
     do {
         uint8_t lo = (uint8_t) wait_data_hi(130);
         if (!lo)
             goto error;
-        
+
         uint8_t hi = (uint8_t) wait_data_lo(lo);
         if (!hi)
             goto error;
-        
+
         hi = lo - hi;
         lo = 130 - lo;
-        
+
         data <<= 1;
         if (lo < hi) {
             data |= 1;
@@ -197,27 +156,27 @@ error:
     return -n;
 }
 
-void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l)
+void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l)
 {
     cli();
     attention();
-    send_byte(cmd);
+    send_byte((addr<<4) | (ADB_CMD_LISTEN<<2) | reg);
     place_bit0();               // Stopbit(0)
     _delay_us(200);             // Tlt/Stop to Start
     place_bit1();               // Startbit(1)
-    send_byte(data_h); 
+    send_byte(data_h);
     send_byte(data_l);
     place_bit0();               // Stopbit(0);
     sei();
 }
 
 // send state of LEDs
-void adb_host_kbd_led(uint8_t led)
+void adb_host_kbd_led(uint8_t addr, uint8_t led)
 {
-    // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10)
-    // send upper byte (not used)
-    // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0:
-    adb_host_listen(0x2A,0,led&0x07);
+    // Listen Register2
+    //  upper byte: not used
+    //  lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
+    adb_host_listen(addr, 2, 0, led & 0x07);
 }
 
 
@@ -366,7 +325,7 @@ Commands
 
     bits                commands
     ------------------------------------------------------
-    - - - - 0 0 0 0     Send Request(reset all devices)
+    - - - - 0 0 0 0     Send Reset(reset all devices)
     A A A A 0 0 0 1     Flush(reset a device)
     - - - - 0 0 1 0     Reserved
     - - - - 0 0 1 1     Reserved
@@ -375,7 +334,7 @@ Commands
     A A A A 1 1 R R     Talk(read from a device)
 
     The command to read keycodes from keyboard is 0x2C which
-    consist of keyboard address 2 and Talk against register 0. 
+    consist of keyboard address 2 and Talk against register 0.
 
     Address:
     2:  keyboard
@@ -457,7 +416,7 @@ Keyboard Data(Register0)
 Keyboard LEDs & state of keys(Register2)
     This register hold current state of three LEDs and nine keys.
     The state of LEDs can be changed by sending Listen command.
-    
+
     1514 . . . . . . 7 6 5 . 3 2 1 0
      | | | | | | | | | | | | | | | +-   LED1(NumLock)
      | | | | | | | | | | | | | | +---   LED2(CapsLock)
@@ -474,5 +433,56 @@ Keyboard LEDs & state of keys(Register2)
      | +-----------------------------   Delete
      +-------------------------------   Reserved
 
+Address, Handler ID and bits(Register3)
+    1514131211 . . 8 7 . . . . . . 0
+     | | | | | | | | | | | | | | | |
+     | | | | | | | | +-+-+-+-+-+-+-+-   Handler ID
+     | | | | +-+-+-+-----------------   Address
+     | | | +-------------------------   0
+     | | +---------------------------   Service request enable(1 = enabled)
+     | +-----------------------------   Exceptional event(alwyas 1 if not used)
+     +-------------------------------   0
+
+ADB Bit Cells
+    bit cell time: 70-130us
+    low part of bit0: 60-70% of bit cell
+    low part of bit1: 30-40% of bit cell
+
+       bit cell time         70us        130us
+       --------------------------------------------
+       low  part of bit0     42-49       78-91
+       high part of bit0     21-28       39-52
+       low  part of bit1     21-28       39-52
+       high part of bit1     42-49       78-91
+
+
+    bit0:
+       70us bit cell:
+         ____________~~~~~~
+         42-49        21-28
+
+       130us bit cell:
+         ____________~~~~~~
+         78-91        39-52
+
+    bit1:
+       70us bit cell:
+         ______~~~~~~~~~~~~
+         21-28        42-49
+
+       130us bit cell:
+         ______~~~~~~~~~~~~
+         39-52        78-91
+
+    [from Apple IIgs Hardware Reference Second Edition]
+
+Keyboard Handle ID
+    Apple Standard Keyboard M0116:      0x01
+    Apple Extended Keyboard M0115:      0x02
+    Apple Extended Keyboard II M3501:   0x02
+    Apple Adjustable Keybaord:          0x10
+
+    http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
+
 END_OF_ADB
 */
index b4b3633cf450a5bd6ba37a3a952f692ce3e313a1..a8b97ea57d122e815b7e94b5dabb7a02cccdf09a 100644 (file)
@@ -52,13 +52,41 @@ POSSIBILITY OF SUCH DAMAGE.
 #define ADB_CAPS        0x39
 
 
+/* ADB commands */
+// Default Address
+#define ADB_ADDR_DONGLE     1
+#define ADB_ADDR_KEYBOARD   2
+#define ADB_ADDR_MOUSE      3
+#define ADB_ADDR_TABLET     4
+#define ADB_ADDR_APPLIANCE  7
+// Command Type
+#define ADB_CMD_RESET       0
+#define ADB_CMD_FLUSH       1
+#define ADB_CMD_LISTEN      2
+#define ADB_CMD_TALK        3
+// Register
+#define ADB_REG_0           0
+#define ADB_REG_1           1
+#define ADB_REG_2           2
+#define ADB_REG_3           3
+
+/* ADB keyboard handler id */
+#define ADB_HANDLER_M0116               0x01
+#define ADB_HANDLER_IIGS                0x01
+#define ADB_HANDLER_M0115               0x02
+#define ADB_HANDLER_M3501               0x02
+#define ADB_HANDLER_M1242_ANSI          0x10
+#define ADB_HANDLER_EXTENDED_PROTOCOL   0x03
+
+
 // ADB host
 void     adb_host_init(void);
 bool     adb_host_psw(void);
-uint16_t adb_host_kbd_recv(void);
+uint16_t adb_host_kbd_recv(uint8_t addr);
 uint16_t adb_host_mouse_recv(void);
-void     adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
-void     adb_host_kbd_led(uint8_t led);
+uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
+void     adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
+void     adb_host_kbd_led(uint8_t addr, uint8_t led);
 void     adb_mouse_task(void);
 void     adb_mouse_init(void);
 
index cf26b83dfff3693c8dd89514db8823cef21abb94..7f7d06253b0e9ceb8d4fcb864ab95567a3222a39 100644 (file)
@@ -150,25 +150,25 @@ static void send_system(uint16_t data)
 +-------------------------------------+-------+
 */
 #define CONSUMER2BLUEFRUIT(usage) \
-    (usage == AUDIO_MUTE           ? 0x0000  : \
-    (usage == AUDIO_VOL_UP         ? 0x1000  : \
-    (usage == AUDIO_VOL_DOWN       ? 0x2000  : \
-    (usage == TRANSPORT_NEXT_TRACK ? 0x0002  : \
-    (usage == TRANSPORT_PREV_TRACK ? 0x0004  : \
-    (usage == TRANSPORT_STOP       ? 0x0010  : \
-    (usage == TRANSPORT_STOP_EJECT ? 0x0000  : \
-    (usage == TRANSPORT_PLAY_PAUSE ? 0x4000  : \
-    (usage == AL_CC_CONFIG         ? 0x0000  : \
-    (usage == AL_EMAIL             ? 0x0000  : \
-    (usage == AL_CALCULATOR        ? 0x0000  : \
-    (usage == AL_LOCAL_BROWSER     ? 0x0000  : \
-    (usage == AC_SEARCH            ? 0x0400  : \
-    (usage == AC_HOME              ? 0x0100  : \
-    (usage == AC_BACK              ? 0x0000  : \
-    (usage == AC_FORWARD           ? 0x0000  : \
-    (usage == AC_STOP              ? 0x0000  : \
-    (usage == AC_REFRESH           ? 0x0000  : \
-    (usage == AC_BOOKMARKS         ? 0x0000  : 0)))))))))))))))))))
+    (usage == AUDIO_MUTE              ? 0x0000  : \
+    (usage == AUDIO_VOL_UP            ? 0x1000  : \
+    (usage == AUDIO_VOL_DOWN          ? 0x2000  : \
+    (usage == TRANSPORT_NEXT_TRACK    ? 0x0002  : \
+    (usage == TRANSPORT_PREV_TRACK    ? 0x0004  : \
+    (usage == TRANSPORT_STOP          ? 0x0010  : \
+    (usage == TRANSPORT_STOP_EJECT    ? 0x0000  : \
+    (usage == TRANSPORT_PLAY_PAUSE    ? 0x4000  : \
+    (usage == APPLAUNCH_CC_CONFIG     ? 0x0000  : \
+    (usage == APPLAUNCH_EMAIL         ? 0x0000  : \
+    (usage == APPLAUNCH_CALCULATOR    ? 0x0000  : \
+    (usage == APPLAUNCH_LOCAL_BROWSER ? 0x0000  : \
+    (usage == APPCONTROL_SEARCH       ? 0x0400  : \
+    (usage == APPCONTROL_HOME         ? 0x0100  : \
+    (usage == APPCONTROL_BACK         ? 0x0000  : \
+    (usage == APPCONTROL_FORWARD      ? 0x0000  : \
+    (usage == APPCONTROL_STOP         ? 0x0000  : \
+    (usage == APPCONTROL_REFRESH      ? 0x0000  : \
+    (usage == APPCONTROL_BOOKMARKS    ? 0x0000  : 0)))))))))))))))))))
 
 static void send_consumer(uint16_t data)
 {
index 63e6641f824cb2fde350b9d89737117362d9b3af..2fadc799f13e8f1ceda5620b2983a3644b5c25ed 100644 (file)
@@ -1,16 +1,16 @@
 ## TMK running on top of ChibiOS
 
-This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever [ChibiOS] supports. The notable examples are ARM-based Teensies (3.x and LC) and on the boards with STM32 MCUs.
+This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever ChibiOS supports. The notable examples are PJRC Teensies(3.x and LC) with NXP Kinetis and dev boards with ST Micro STM32 MCUs.
 
 ### Usage
 
-- To use, [get a zip of chibios](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip) and unpack/rename it to `tmk_core/tool/chibios/chibios`; or you can just clone [the repo](https://github.com/ChibiOS/ChibiOS) there. For Freescale/NXP Kinetis support (meaning ARM Teensies and the Infinity keyboard), you'll also need [a zip of chibios-contrib](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip), unpacked/renamed to `tmk_core/tool/chibios/chibios-contrib`. Likewise, for git-savvy people, just clone [the repo](https://github.com/ChibiOS/ChibiOS-Contrib) there.
-- Note: the abovementioned directories are the defaults. You can have the two chibios repositories wherever you want, just define their location in `CHIBIOS` and `CHIBIOS_CONTRIB` variables in your `Makefile`.
+- To use, get a [zip file](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip) of ChibiOS and unpack/rename it to `tmk_core/tool/chibios/ChibiOS`; or you can just clone [ChibiOS repo](https://github.com/ChibiOS/ChibiOS) there. For Freescale/NXP Kinetis support (meaning Teensies 3.x/LC and the Infinity keyboard), you'll also need a [zip](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip) of ChibiOS-Contrib, unpacked/renamed to `tmk_core/tool/chibios/ChibiOS-Contrib`. Likewise, for git-savvy people, just clone [ChibiOS-Contrib repo](https://github.com/ChibiOS/ChibiOS-Contrib) there.
+- Note: the above mentioned directories are the defaults. You can have the two ChibiOS repositories wherever you want, just define their location in `CHIBIOS` and `CHIBIOS_CONTRIB` variables in your `Makefile`.
 - You will also need to install an ARM toolchain, for instance from [here](https://launchpad.net/gcc-arm-embedded). On linux, this is usually also present as a package for your distribution (as `gcc-arm` or something similar). On OS X, you can use [homebrew](http://brew.sh/) with an appropriate tap.
 
 ### Notes
 
-- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for ARM Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md).
+- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md).
 - For gcc options, inspect `tmk_core/tool/chibios/chibios.mk`. For instance, I enabled `-Wno-missing-field-initializers`, because TMK common bits generated a lot of warnings on that.
 - For debugging, it is sometimes useful disable gcc optimisations, you can do that by adding `-O0` to `OPT_DEFS` in your `Makefile`.
 - USB string descriptors are messy. I did not find a way to cleanly generate the right structures from actual strings, so the definitions in individual keyboards' `config.h` are ugly as heck.
index 106ce0879dbbfcd2dc7e316cae1d2120c735d438..fbf0ceba2bec6d5b7f998be788d9b731cecca63a 100644 (file)
@@ -153,7 +153,7 @@ static const uint8_t keyboard_hid_report_desc_data[] = {
   0x95, KBD_REPORT_KEYS,          //   Report Count (),
   0x75, 0x08,                //   Report Size (8),
   0x15, 0x00,                //   Logical Minimum (0),
-  0x25, 0xFF,                //   Logical Maximum(255),
+  0x26, 0xFF, 0x00,          //   Logical Maximum(255),
   0x05, 0x07,                //   Usage Page (Key Codes),
   0x19, 0x00,                //   Usage Minimum (0),
   0x29, 0xFF,                //   Usage Maximum (255),
@@ -299,7 +299,7 @@ static const uint8_t extra_hid_report_desc_data[] = {
   0xa1, 0x01,                      // COLLECTION (Application)
   0x85, REPORT_ID_SYSTEM,          //   REPORT_ID (2)
   0x15, 0x01,                      //   LOGICAL_MINIMUM (0x1)
-  0x25, 0xb7,                      //   LOGICAL_MAXIMUM (0xb7)
+  0x26, 0xb7, 0x00,                //   LOGICAL_MAXIMUM (0xb7)
   0x19, 0x01,                      //   USAGE_MINIMUM (0x1)
   0x29, 0xb7,                      //   USAGE_MAXIMUM (0xb7)
   0x75, 0x10,                      //   REPORT_SIZE (16)
index 87386be99881052ab30b04c80ed950cf5d0626db..1b529bde61e15dc6575150545b1de1f8cefdc0e3 100644 (file)
@@ -37,6 +37,10 @@ LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABL
 #LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
 LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 
 LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
+# Remote wakeup fix for ATmega32U2        https://github.com/tmk/tmk_keyboard/issues/361
+ifeq ($(MCU),atmega32u2)
+       LUFA_OPTS += -DNO_LIMITED_CONTROLLER_CONNECT
+endif
 
 OPT_DEFS += -DF_USB=$(F_USB)UL
 OPT_DEFS += -DARCH=ARCH_$(ARCH)
@@ -44,3 +48,8 @@ OPT_DEFS += $(LUFA_OPTS)
 
 # This indicates using LUFA stack
 OPT_DEFS += -DPROTOCOL_LUFA
+
+ifeq (yes,$(strip $(LUFA_DEBUG_SUART)))
+    SRC += common/avr/suart.S
+    LUFA_OPTS += -DLUFA_DEBUG_SUART
+endif
index c13a81bda8cd6f68f14207f09ebabff6c991d36b..4fb5219d6f5156bdd26a11153a4abc59c735ceff 100644 (file)
@@ -73,10 +73,10 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
         HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
 
         HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
-        HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
-        HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
+        HID_RI_USAGE_MINIMUM(8, 0x00),
+        HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Usage ID 0x00-0xFF */
         HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), /* needs 16 bit to indicate positive value */
         HID_RI_REPORT_COUNT(8, 0x06),
         HID_RI_REPORT_SIZE(8, 0x08),
         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
@@ -140,9 +140,9 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
     HID_RI_USAGE(8, 0x80), /* System Control */
     HID_RI_COLLECTION(8, 0x01), /* Application */
         HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
-        HID_RI_LOGICAL_MINIMUM(16, 0x0001),
+        HID_RI_LOGICAL_MINIMUM(16, 0x0081),
         HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
-        HID_RI_USAGE_MINIMUM(16, 0x0001), /* System Power Down */
+        HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
         HID_RI_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */
         HID_RI_REPORT_SIZE(8, 16),
         HID_RI_REPORT_COUNT(8, 1),
@@ -172,13 +172,13 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
     HID_RI_COLLECTION(8, 0x01), /* Application */
         HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
         HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
         HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
         HID_RI_REPORT_SIZE(8, 0x08),
         HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
         HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
         HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
         HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
         HID_RI_REPORT_SIZE(8, 0x08),
         HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
index 42af07917c33f5795e538c40e7bf19c6d01d5269..119f4298549340596aa4002e703d43c5e6ad0a34 100644 (file)
@@ -155,7 +155,7 @@ typedef struct
 #define MOUSE_EPSIZE                8
 #define EXTRAKEY_EPSIZE             8
 #define CONSOLE_EPSIZE              32
-#define NKRO_EPSIZE                 16
+#define NKRO_EPSIZE                 32
 
 
 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
index beec6b2be31d3f30d926f0fbcc652f4bce839473..93fe9a2facd586e369a34ef2daf6eefc6525a913 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright 2012 Jun Wako <wakojun@gmail.com>
  * This file is based on:
  *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
 #include "suspend.h"
 #include "hook.h"
 
+#ifdef LUFA_DEBUG_SUART
+#include "avr/suart.h"
+#endif
+
+#include "matrix.h"
 #include "descriptor.h"
 #include "lufa.h"
 
+
+//#define LUFA_DEBUG
+
+
 uint8_t keyboard_idle = 0;
 /* 0: Boot Protocol, 1: Report Protocol(default) */
 uint8_t keyboard_protocol = 1;
@@ -100,10 +109,10 @@ static void Console_Task(void)
         {
             /* Create a temporary buffer to hold the read in report from the host */
             uint8_t ConsoleData[CONSOLE_EPSIZE];
+
             /* Read Console Report Data */
             Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
+
             /* Process Console Report Data */
             //ProcessConsoleHIDReport(ConsoleData);
         }
@@ -164,7 +173,7 @@ void EVENT_USB_Device_Disconnect(void)
     print("[D]");
     /* For battery powered device */
     USB_IsInitialized = false;
-/* TODO: This doesn't work. After several plug in/outs can not be enumerated. 
+/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
     if (USB_IsInitialized) {
         USB_Disable();  // Disable all interrupts
        USB_Controller_Enable();
@@ -175,18 +184,24 @@ void EVENT_USB_Device_Disconnect(void)
 
 void EVENT_USB_Device_Reset(void)
 {
+#ifdef LUFA_DEBUG
     print("[R]");
+#endif
 }
 
 void EVENT_USB_Device_Suspend()
 {
+#ifdef LUFA_DEBUG
     print("[S]");
+#endif
     hook_usb_suspend_entry();
 }
 
 void EVENT_USB_Device_WakeUp()
 {
+#ifdef LUFA_DEBUG
     print("[W]");
+#endif
     hook_usb_wakeup();
 }
 
@@ -217,6 +232,9 @@ void EVENT_USB_Device_StartOfFrame(void)
  */
 void EVENT_USB_Device_ConfigurationChanged(void)
 {
+#ifdef LUFA_DEBUG
+    print("[c]");
+#endif
     bool ConfigSuccess = true;
 
     /* Setup Keyboard HID Report Endpoints */
@@ -293,6 +311,9 @@ void EVENT_USB_Device_ControlRequest(void)
                 /* Write the report data to the control endpoint */
                 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
                 Endpoint_ClearOUT();
+#ifdef LUFA_DEBUG
+                xprintf("[r%d]", USB_ControlRequest.wIndex);
+#endif
             }
 
             break;
@@ -316,6 +337,9 @@ void EVENT_USB_Device_ControlRequest(void)
 
                     Endpoint_ClearOUT();
                     Endpoint_ClearStatusStage();
+#ifdef LUFA_DEBUG
+                    xprintf("[L%d]", USB_ControlRequest.wIndex);
+#endif
                     break;
                 }
 
@@ -332,6 +356,9 @@ void EVENT_USB_Device_ControlRequest(void)
                     Endpoint_Write_8(keyboard_protocol);
                     Endpoint_ClearIN();
                     Endpoint_ClearStatusStage();
+#ifdef LUFA_DEBUG
+                    print("[p]");
+#endif
                 }
             }
 
@@ -345,6 +372,9 @@ void EVENT_USB_Device_ControlRequest(void)
 
                     keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
                     clear_keyboard();
+#ifdef LUFA_DEBUG
+                    print("[P]");
+#endif
                 }
             }
 
@@ -356,6 +386,9 @@ void EVENT_USB_Device_ControlRequest(void)
                 Endpoint_ClearStatusStage();
 
                 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
+#ifdef LUFA_DEBUG
+                xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8);
+#endif
             }
 
             break;
@@ -367,6 +400,9 @@ void EVENT_USB_Device_ControlRequest(void)
                 Endpoint_Write_8(keyboard_idle);
                 Endpoint_ClearIN();
                 Endpoint_ClearStatusStage();
+#ifdef LUFA_DEBUG
+                print("[i]");
+#endif
             }
 
             break;
@@ -374,7 +410,7 @@ void EVENT_USB_Device_ControlRequest(void)
 }
 
 /*******************************************************************************
- * Host driver 
+ * Host driver
  ******************************************************************************/
 static uint8_t keyboard_leds(void)
 {
@@ -494,6 +530,9 @@ static void send_consumer(uint16_t data)
 #define SEND_TIMEOUT 5
 int8_t sendchar(uint8_t c)
 {
+#ifdef LUFA_DEBUG_SUART
+    xmit(c);
+#endif
     // Not wait once timeouted.
     // Because sendchar() is called so many times, waiting each call causes big lag.
     static bool timeouted = false;
@@ -551,6 +590,9 @@ ERROR_EXIT:
 #else
 int8_t sendchar(uint8_t c)
 {
+#ifdef LUFA_DEBUG_SUART
+    xmit(c);
+#endif
     return 0;
 }
 #endif
@@ -578,13 +620,20 @@ static void setup_usb(void)
 
     // for Console_Task
     USB_Device_EnableSOFEvents();
-    print_set_sendchar(sendchar);
 }
 
 int main(void)  __attribute__ ((weak));
 int main(void)
 {
     setup_mcu();
+
+#ifdef LUFA_DEBUG_SUART
+    SUART_OUT_DDR |= (1<<SUART_OUT_BIT);
+    SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
+#endif
+    print_set_sendchar(sendchar);
+    print("\r\ninit\n");
+
     hook_early_init();
     keyboard_setup();
     setup_usb();
@@ -611,7 +660,9 @@ int main(void)
     hook_late_init();
     while (1) {
         while (USB_DeviceState == DEVICE_STATE_Suspended) {
+#ifdef LUFA_DEBUG
             print("[s]");
+#endif
             hook_usb_suspend_loop();
         }
 
@@ -631,9 +682,19 @@ void hook_early_init(void) {}
 __attribute__((weak))
 void hook_late_init(void) {}
 
+static uint8_t _led_stats = 0;
  __attribute__((weak))
 void hook_usb_suspend_entry(void)
 {
+    // Turn LED off to save power
+    // Set 0 with putting aside status before suspend and restore
+    // it after wakeup, then LED is updated at keyboard_task() in main loop
+    _led_stats = keyboard_led_stats;
+    keyboard_led_stats = 0;
+    led_set(keyboard_led_stats);
+
+    matrix_clear();
+    clear_keyboard();
 #ifdef SLEEP_LED_ENABLE
     sleep_led_enable();
 #endif
@@ -644,7 +705,7 @@ void hook_usb_suspend_loop(void)
 {
     suspend_power_down();
     if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
-            USB_Device_SendRemoteWakeup();
+        USB_Device_SendRemoteWakeup();
     }
 }
 
@@ -654,7 +715,12 @@ void hook_usb_wakeup(void)
     suspend_wakeup_init();
 #ifdef SLEEP_LED_ENABLE
     sleep_led_disable();
-    // NOTE: converters may not accept this
-    led_set(host_keyboard_leds());
 #endif
+
+    // Restore LED status
+    // BIOS/grub won't recognize/enumerate if led_set() takes long(around 40ms?)
+    // Converters fall into the case and miss wakeup event(timeout to reply?) in the end.
+    //led_set(host_keyboard_leds());
+    // Instead, restore stats and update at keyboard_task() in main loop
+    keyboard_led_stats = _led_stats;
 }
index 947077cd2453c64ad1bbad9ef3beaed33734608d..cc2250ec67f8fa678b0abb5f634d62fa664e1b79 100644 (file)
@@ -97,7 +97,7 @@ uint8_t * HIDKeyboard::reportDesc() {
         REPORT_COUNT(1), 0x06,
         REPORT_SIZE(1), 0x08,
         LOGICAL_MINIMUM(1), 0x00,
-        LOGICAL_MAXIMUM(1), 0xFF,
+        LOGICAL_MAXIMUM(2), 0xFF, 0x00,
         USAGE_PAGE(1), 0x07,                    // Key Codes
         USAGE_MINIMUM(1), 0x00,
         USAGE_MAXIMUM(1), 0xFF,
diff --git a/protocol/pbuff.h b/protocol/pbuff.h
new file mode 100644 (file)
index 0000000..2737392
--- /dev/null
@@ -0,0 +1,57 @@
+/*--------------------------------------------------------------------
+ * Ring buffer to store scan codes from keyboard
+ *------------------------------------------------------------------*/
+
+#ifndef PBUFF_H
+#define PBUFF_H
+
+#include "print.h"
+
+#define PBUF_SIZE 32
+static uint16_t pbuf[PBUF_SIZE];
+static uint16_t pbuf_head = 0;
+static uint16_t pbuf_tail = 0;
+static inline void pbuf_enqueue(uint16_t data)
+{
+    uint8_t sreg = SREG;
+    cli();
+    uint16_t next = (pbuf_head + 1) % PBUF_SIZE;
+    if (next != pbuf_tail) {
+        pbuf[pbuf_head] = data;
+        pbuf_head = next;
+    } else {
+        print("pbuf: full\n");
+    }
+    SREG = sreg;
+}
+static inline uint16_t pbuf_dequeue(void)
+{
+    uint16_t val = 0;
+
+    uint8_t sreg = SREG;
+    cli();
+    if (pbuf_head != pbuf_tail) {
+        val = pbuf[pbuf_tail];
+        pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
+    }
+    SREG = sreg;
+
+    return val;
+}
+static inline bool pbuf_has_data(void)
+{
+    uint8_t sreg = SREG;
+    cli();
+    bool has_data = (pbuf_head != pbuf_tail);
+    SREG = sreg;
+    return has_data;
+}
+static inline void pbuf_clear(void)
+{
+    uint8_t sreg = SREG;
+    cli();
+    pbuf_head = pbuf_tail = 0;
+    SREG = sreg;
+}
+
+#endif
index 1e6ba8719a2a124ef687e63916bc30dd037df120..9f9c4e1b001ef2d567013e12a5643c881418a3a9 100644 (file)
@@ -184,7 +184,7 @@ static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
         0x95, KBD_REPORT_KEYS,    //   Report Count (),
         0x75, 0x08,          //   Report Size (8),
         0x15, 0x00,          //   Logical Minimum (0),
-        0x25, 0xFF,          //   Logical Maximum(255),
+        0x26, 0xFF, 0x00,    //   Logical Maximum(255),
         0x05, 0x07,          //   Usage Page (Key Codes),
         0x19, 0x00,          //   Usage Minimum (0),
         0x29, 0xFF,          //   Usage Maximum (255),
@@ -307,7 +307,7 @@ static const uint8_t PROGMEM extra_hid_report_desc[] = {
     0xa1, 0x01,                    // COLLECTION (Application)
     0x85, REPORT_ID_SYSTEM,        //   REPORT_ID (2)
     0x15, 0x01,                    //   LOGICAL_MINIMUM (0x1)
-    0x25, 0xb7,                    //   LOGICAL_MAXIMUM (0xb7)
+    0x26, 0xb7, 0x00,              //   LOGICAL_MAXIMUM (0xb7)
     0x19, 0x01,                    //   USAGE_MINIMUM (0x1)
     0x29, 0xb7,                    //   USAGE_MAXIMUM (0xb7)
     0x75, 0x10,                    //   REPORT_SIZE (16)
index 8114442bac663667f82dfbf78580b4069d381510..0fd3d3600fb8c2a5fe05265150e72253215f6f9d 100644 (file)
@@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include <stdbool.h>
 #include <avr/interrupt.h>
 #include <util/delay.h>
+#include "pbuff.h"
 #include "ps2.h"
 #include "ps2_io.h"
 #include "print.h"
@@ -57,13 +58,6 @@ POSSIBILITY OF SUCH DAMAGE.
 
 uint8_t ps2_error = PS2_ERR_NONE;
 
-
-static inline uint8_t pbuf_dequeue(void);
-static inline void pbuf_enqueue(uint8_t data);
-static inline bool pbuf_has_data(void);
-static inline void pbuf_clear(void);
-
-
 void ps2_host_init(void)
 {
     idle();
@@ -225,55 +219,3 @@ void ps2_host_set_led(uint8_t led)
     ps2_host_send(0xED);
     ps2_host_send(led);
 }
-
-
-/*--------------------------------------------------------------------
- * Ring buffer to store scan codes from keyboard
- *------------------------------------------------------------------*/
-#define PBUF_SIZE 32
-static uint8_t pbuf[PBUF_SIZE];
-static uint8_t pbuf_head = 0;
-static uint8_t pbuf_tail = 0;
-static inline void pbuf_enqueue(uint8_t data)
-{
-    uint8_t sreg = SREG;
-    cli();
-    uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
-    if (next != pbuf_tail) {
-        pbuf[pbuf_head] = data;
-        pbuf_head = next;
-    } else {
-        print("pbuf: full\n");
-    }
-    SREG = sreg;
-}
-static inline uint8_t pbuf_dequeue(void)
-{
-    uint8_t val = 0;
-
-    uint8_t sreg = SREG;
-    cli();
-    if (pbuf_head != pbuf_tail) {
-        val = pbuf[pbuf_tail];
-        pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
-    }
-    SREG = sreg;
-
-    return val;
-}
-static inline bool pbuf_has_data(void)
-{
-    uint8_t sreg = SREG;
-    cli();
-    bool has_data = (pbuf_head != pbuf_tail);
-    SREG = sreg;
-    return has_data;
-}
-static inline void pbuf_clear(void)
-{
-    uint8_t sreg = SREG;
-    cli();
-    pbuf_head = pbuf_tail = 0;
-    SREG = sreg;
-}
-
index fe002c0d961d75fb72da070e5b8d959ca8ebd967..94e747ca4b8313f9e17a3a523c531b103151aef7 100644 (file)
@@ -4,30 +4,14 @@
 #include "debug.h"
 
 
-report_keyboard_t usb_hid_keyboard_report;
-uint16_t usb_hid_time_stamp;
-
-
 void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
 {
-    bool is_error = false;
-    report_keyboard_t *report = (report_keyboard_t *)buf;
+    ::memcpy(&report, buf, sizeof(report_keyboard_t));
+    time_stamp = millis();
 
-    dprintf("keyboard input:  %02X %02X", report->mods, report->reserved);
+    dprintf("input %d:  %02X %02X", hid->GetAddress(), report.mods, report.reserved);
     for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
-        if (IS_ERROR(report->keys[i])) {
-            is_error = true;
-        }
-        dprintf(" %02X", report->keys[i]);
+        dprintf(" %02X", report.keys[i]);
     }
     dprint("\r\n");
-
-    // ignore error and not send report to computer
-    if (is_error) {
-        dprint("Error usage! \r\n");
-        return;
-    }
-
-    ::memcpy(&usb_hid_keyboard_report, buf, sizeof(report_keyboard_t));
-    usb_hid_time_stamp = millis();
 }
index 703eb1ed4ce6f4499b7dc1ae680d03089bb5a74e..036281fa661342b43fa89a6fe1a7440072a7f8e4 100644 (file)
@@ -2,11 +2,14 @@
 #define PARSER_H
 
 #include "hid.h"
+#include "report.h"
 
 class KBDReportParser : public HIDReportParser
 {
 public:
-       virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
+    report_keyboard_t report;
+    uint16_t time_stamp;
+    virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
 };
 
 #endif
index 0d809536d3514471cfd1fa3e5e88d95ce3c3c260..794e4000eaddd446eddeae8644f8f986b30ccf7f 100644 (file)
@@ -20,6 +20,7 @@
 #include "timer.h"
 #include "uart.h"
 #include "debug.h"
+#include "suspend.h"
 
 
 #define UART_BAUD_RATE 115200
@@ -41,6 +42,23 @@ static void initForUsbConnectivity(void)
     sei();
 }
 
+void usb_remote_wakeup(void) {
+    cli();
+
+    int8_t ddr_orig = USBDDR;
+    USBOUT |= (1 << USBMINUS);
+    USBDDR = ddr_orig | USBMASK;
+    USBOUT ^= USBMASK;
+
+    _delay_ms(25);
+
+    USBOUT ^= USBMASK;
+    USBDDR = ddr_orig;
+    USBOUT &= ~(1 << USBMINUS);
+
+    sei();
+}
+
 int main(void)
 {
     bool suspended = false;
@@ -70,19 +88,6 @@ int main(void)
             // Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
             if (timer_elapsed(last_timer) > 5) {
                 suspended = true;
-/*
-                uart_putchar('S');
-                _delay_ms(1);
-                cli();
-                set_sleep_mode(SLEEP_MODE_PWR_DOWN);
-                sleep_enable();
-                sleep_bod_disable();
-                sei();
-                sleep_cpu();
-                sleep_disable();
-                _delay_ms(10);
-                uart_putchar('W');
-*/
             }
         }
 #endif
@@ -95,6 +100,8 @@ int main(void)
                 keyboard_task();
             }
             vusb_transfer_keyboard();
+        } else if (suspend_wakeup_condition()) {
+            usb_remote_wakeup();
         }
     }
 }
index 7d0292ed171336022bf16ee7c54fa40f3217dd72..5d00165c0ac6f643bff0c789447b321ab8531479 100644 (file)
@@ -266,7 +266,7 @@ const PROGMEM uchar keyboard_hid_report[] = {
     0x95, 0x06,          //   Report Count (6),
     0x75, 0x08,          //   Report Size (8),
     0x15, 0x00,          //   Logical Minimum (0),
-    0x25, 0xFF,          //   Logical Maximum(255),
+    0x26, 0xFF, 0x00,    //   Logical Maximum(255),
     0x05, 0x07,          //   Usage Page (Key Codes),
     0x19, 0x00,          //   Usage Minimum (0),
     0x29, 0xFF,          //   Usage Maximum (255),
@@ -336,7 +336,7 @@ const PROGMEM uchar mouse_hid_report[] = {
     0xa1, 0x01,                    // COLLECTION (Application)
     0x85, REPORT_ID_SYSTEM,        //   REPORT_ID (2)
     0x15, 0x01,                    //   LOGICAL_MINIMUM (0x1)
-    0x25, 0xb7,                    //   LOGICAL_MAXIMUM (0xb7)
+    0x26, 0xb7, 0x00,              //   LOGICAL_MAXIMUM (0xb7)
     0x19, 0x01,                    //   USAGE_MINIMUM (0x1)
     0x29, 0xb7,                    //   USAGE_MAXIMUM (0xb7)
     0x75, 0x10,                    //   REPORT_SIZE (16)
diff --git a/protocol/xt.h b/protocol/xt.h
new file mode 100644 (file)
index 0000000..55efd75
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
+Copyright 2016 Ethan Apodaca <papodaca@gmail.com>
+
+This software is licensed with a Modified BSD License.
+All of this is supposed to be Free Software, Open Source, DFSG-free,
+GPL-compatible, and OK to use in both free and proprietary applications.
+Additions and corrections to this file are welcome.
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in
+  the documentation and/or other materials provided with the
+  distribution.
+
+* Neither the name of the copyright holders nor the names of
+  contributors may be used to endorse or promote products derived
+  from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef XT_H
+#define XT_H
+
+#include <stdbool.h>
+#include "wait.h"
+#include "xt_io.h"
+#include "print.h"
+
+void xt_host_init(void);
+uint8_t xt_host_recv(void);
+
+
+/*--------------------------------------------------------------------
+ * static functions
+ *------------------------------------------------------------------*/
+static inline uint16_t wait_clock_lo(uint16_t us)
+{
+    while (clock_in()  && us) { asm(""); wait_us(1); us--; }
+    return us;
+}
+static inline uint16_t wait_clock_hi(uint16_t us)
+{
+    while (!clock_in() && us) { asm(""); wait_us(1); us--; }
+    return us;
+}
+static inline uint16_t wait_data_lo(uint16_t us)
+{
+    while (data_in() && us)  { asm(""); wait_us(1); us--; }
+    return us;
+}
+static inline uint16_t wait_data_hi(uint16_t us)
+{
+    while (!data_in() && us)  { asm(""); wait_us(1); us--; }
+    return us;
+}
+
+#endif
diff --git a/protocol/xt_interrupt.c b/protocol/xt_interrupt.c
new file mode 100644 (file)
index 0000000..94b47db
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
+
+This software is licensed with a Modified BSD License.
+All of this is supposed to be Free Software, Open Source, DFSG-free,
+GPL-compatible, and OK to use in both free and proprietary applications.
+Additions and corrections to this file are welcome.
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in
+  the documentation and/or other materials provided with the
+  distribution.
+
+* Neither the name of the copyright holders nor the names of
+  contributors may be used to endorse or promote products derived
+  from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * PS/2 protocol Pin interrupt version
+ */
+
+#include <stdbool.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "pbuff.h"
+#include "xt.h"
+#include "xt_io.h"
+#include "wait.h"
+#include "print.h"
+
+void xt_host_init(void)
+{
+    XT_INT_INIT();
+    XT_INT_ON();
+}
+
+/* get data received by interrupt */
+uint8_t xt_host_recv(void)
+{
+    if (pbuf_has_data()) {
+        return pbuf_dequeue();
+    } else {
+        return 0;
+    }
+}
+
+ISR(XT_INT_VECT)
+{
+    static uint8_t state = 0;
+    static uint8_t data = 0;
+
+    if (state == 0) {
+        if (data_in())
+            state++;
+    } else if (state >= 1 && state <= 8) {
+        wait_clock_lo(20);
+        data >>= 1;
+        if (data_in())
+            data |= 0x80;
+        if (state == 8)
+            goto END;
+        state++;
+    } else {
+        goto DONE;
+    }
+    goto RETURN;
+END:
+    pbuf_enqueue(data);
+DONE:
+    state = 0;
+    data = 0;
+RETURN:
+    return;
+}
diff --git a/protocol/xt_io.h b/protocol/xt_io.h
new file mode 100644 (file)
index 0000000..2e5f31b
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef XT_IO_H
+#define XT_IO_H
+
+bool clock_in(void);
+bool data_in(void);
+
+#endif
diff --git a/protocol/xt_io_avr.c b/protocol/xt_io_avr.c
new file mode 100644 (file)
index 0000000..6cd153a
--- /dev/null
@@ -0,0 +1,34 @@
+#include <stdbool.h>
+#include <avr/io.h>
+#include <util/delay.h>
+
+/* Check port settings for clock and data line */
+#if !(defined(XT_CLOCK_PORT) && \
+      defined(XT_CLOCK_PIN) && \
+      defined(XT_CLOCK_DDR) && \
+      defined(XT_CLOCK_BIT))
+#   error "XT clock port setting is required in config.h"
+#endif
+
+#if !(defined(XT_DATA_PORT) && \
+      defined(XT_DATA_PIN) && \
+      defined(XT_DATA_DDR) && \
+      defined(XT_DATA_BIT))
+#   error "XT data port setting is required in config.h"
+#endif
+
+bool clock_in(void)
+{
+    XT_CLOCK_DDR  &= ~(1<<XT_CLOCK_BIT);
+    XT_CLOCK_PORT |=  (1<<XT_CLOCK_BIT);
+    _delay_us(1);
+    return XT_CLOCK_PIN&(1<<XT_CLOCK_BIT);
+}
+
+bool data_in(void)
+{
+    XT_DATA_DDR  &= ~(1<<XT_DATA_BIT);
+    XT_DATA_PORT |=  (1<<XT_DATA_BIT);
+    _delay_us(1);
+    return XT_DATA_PIN&(1<<XT_DATA_BIT);
+}
index 0ae84d912fd452b1a9a2000402b487e91569f1c7..66b4cbd88eaf7dd840a0cbc1c2adc807e5140794 100644 (file)
--- a/rules.mk
+++ b/rules.mk
@@ -420,6 +420,13 @@ flip: $(TARGET).hex
        batchisp -hardware usb -device $(MCU) -operation start reset 0
 
 dfu: $(TARGET).hex
+       @echo -n dfu-programmer: waiting
+       @until dfu-programmer $(MCU) get bootloader-version > /dev/null 2>&1; do \
+               echo  -n "."; \
+               sleep 1; \
+       done
+       @echo
+
 ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1)))
        dfu-programmer $(MCU) erase --force
 else
index 88bbafe34ff87c062c0ef75e56dc872823587a4d..6be9cf9ef05908c43ba0e284a7ace761063f815f 100644 (file)
@@ -1,2 +1,2 @@
-chibios
-chibios-contrib
+ChibiOS
+ChibiOS-Contrib
index f2fedd22af1975650139158be5a6c213434bc692..88ba94ae0e34da94aece6f0784cce844f338abe5 100644 (file)
@@ -83,8 +83,8 @@ endif
 #
 
 # Imported source files and paths
-CHIBIOS ?= $(TMK_DIR)/tool/chibios/chibios
-CHIBIOS_CONTRIB ?= $(TMK_DIR)/tool/chibios/chibios-contrib
+CHIBIOS ?= $(TMK_DIR)/tool/chibios/ChibiOS
+CHIBIOS_CONTRIB ?= $(TMK_DIR)/tool/chibios/ChibiOS-Contrib
 # Startup files. Try a few different locations, for compability with old versions and 
 # for things hardware in the contrib repository
 STARTUP_MK = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk
index b8c7336b45192d48fe95b13d95bbd0d6fa681f76..596fbc8a1e3060d6fd0c6902facd133a4a737be0 100644 (file)
@@ -23,6 +23,7 @@ CC_FLAGS += \
        -fdata-sections \
        -fomit-frame-pointer
 CC_FLAGS += -MMD -MP
+CC_FLAGS += $(OPT_DEFS)
 
 LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs
 #LD_FLAGS += -u _printf_float -u _scanf_float