1
0

Squashed 'tmk_core/' changes from 8da1898..e5f9940

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
This commit is contained in:
tmk 2016-12-10 10:29:51 +09:00
parent 20b787fc12
commit 22b6e15a17
55 changed files with 2042 additions and 405 deletions

View File

@ -7,6 +7,9 @@ Source code is available here: <https://github.com/tmk/tmk_keyboard/tree/core>
Updates 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 #### 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. 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.

View File

@ -1,12 +1,12 @@
COMMON_DIR = common COMMON_DIR = common
SRC += $(COMMON_DIR)/host.c \ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/keyboard.c \ $(COMMON_DIR)/keyboard.c \
$(COMMON_DIR)/matrix.c \
$(COMMON_DIR)/action.c \ $(COMMON_DIR)/action.c \
$(COMMON_DIR)/action_tapping.c \ $(COMMON_DIR)/action_tapping.c \
$(COMMON_DIR)/action_macro.c \ $(COMMON_DIR)/action_macro.c \
$(COMMON_DIR)/action_layer.c \ $(COMMON_DIR)/action_layer.c \
$(COMMON_DIR)/action_util.c \ $(COMMON_DIR)/action_util.c \
$(COMMON_DIR)/keymap.c \
$(COMMON_DIR)/print.c \ $(COMMON_DIR)/print.c \
$(COMMON_DIR)/debug.c \ $(COMMON_DIR)/debug.c \
$(COMMON_DIR)/util.c \ $(COMMON_DIR)/util.c \
@ -18,58 +18,70 @@ SRC += $(COMMON_DIR)/host.c \
# Option modules # 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)/bootmagic.c
SRC += $(COMMON_DIR)/avr/eeconfig.c SRC += $(COMMON_DIR)/avr/eeconfig.c
OPT_DEFS += -DBOOTMAGIC_ENABLE OPT_DEFS += -DBOOTMAGIC_ENABLE
endif endif
ifdef MOUSEKEY_ENABLE ifeq (yes,$(strip $(MOUSEKEY_ENABLE)))
SRC += $(COMMON_DIR)/mousekey.c SRC += $(COMMON_DIR)/mousekey.c
OPT_DEFS += -DMOUSEKEY_ENABLE OPT_DEFS += -DMOUSEKEY_ENABLE
OPT_DEFS += -DMOUSE_ENABLE OPT_DEFS += -DMOUSE_ENABLE
endif endif
ifdef EXTRAKEY_ENABLE ifeq (yes,$(strip $(EXTRAKEY_ENABLE)))
OPT_DEFS += -DEXTRAKEY_ENABLE OPT_DEFS += -DEXTRAKEY_ENABLE
endif endif
ifdef CONSOLE_ENABLE ifeq (yes,$(strip $(CONSOLE_ENABLE)))
OPT_DEFS += -DCONSOLE_ENABLE OPT_DEFS += -DCONSOLE_ENABLE
else else
OPT_DEFS += -DNO_PRINT OPT_DEFS += -DNO_PRINT
OPT_DEFS += -DNO_DEBUG OPT_DEFS += -DNO_DEBUG
endif endif
ifdef COMMAND_ENABLE ifeq (yes,$(strip $(COMMAND_ENABLE)))
SRC += $(COMMON_DIR)/command.c SRC += $(COMMON_DIR)/command.c
OPT_DEFS += -DCOMMAND_ENABLE OPT_DEFS += -DCOMMAND_ENABLE
endif endif
ifdef NKRO_ENABLE ifeq (yes,$(strip $(NKRO_ENABLE)))
OPT_DEFS += -DNKRO_ENABLE OPT_DEFS += -DNKRO_ENABLE
endif endif
ifdef USB_6KRO_ENABLE ifeq (yes,$(strip $(USB_6KRO_ENABLE)))
OPT_DEFS += -DUSB_6KRO_ENABLE OPT_DEFS += -DUSB_6KRO_ENABLE
endif endif
ifdef KEYBOARD_LOCK_ENABLE ifeq (yes, $(strip $(KEYBOARD_LOCK_ENABLE)))
OPT_DEFS += -DKEYBOARD_LOCK_ENABLE OPT_DEFS += -DKEYBOARD_LOCK_ENABLE
endif endif
ifdef SLEEP_LED_ENABLE ifeq (yes,$(strip $(SLEEP_LED_ENABLE)))
SRC += $(COMMON_DIR)/avr/sleep_led.c SRC += $(COMMON_DIR)/avr/sleep_led.c
OPT_DEFS += -DSLEEP_LED_ENABLE OPT_DEFS += -DSLEEP_LED_ENABLE
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
endif endif
ifdef BACKLIGHT_ENABLE ifeq (yes,$(strip $(BACKLIGHT_ENABLE)))
SRC += $(COMMON_DIR)/backlight.c SRC += $(COMMON_DIR)/backlight.c
OPT_DEFS += -DBACKLIGHT_ENABLE OPT_DEFS += -DBACKLIGHT_ENABLE
endif endif
ifdef KEYMAP_SECTION_ENABLE ifeq (yes,$(strip $(KEYMAP_SECTION_ENABLE)))
OPT_DEFS += -DKEYMAP_SECTION_ENABLE OPT_DEFS += -DKEYMAP_SECTION_ENABLE
ifeq ($(strip $(MCU)),atmega32u2) ifeq ($(strip $(MCU)),atmega32u2)

View File

@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_util.h" #include "action_util.h"
#include "action.h" #include "action.h"
#include "hook.h" #include "hook.h"
#include "wait.h"
#ifdef DEBUG_ACTION #ifdef DEBUG_ACTION
#include "debug.h" #include "debug.h"
@ -365,6 +366,7 @@ void register_code(uint8_t code)
#endif #endif
add_key(KC_CAPSLOCK); add_key(KC_CAPSLOCK);
send_keyboard_report(); send_keyboard_report();
wait_ms(100);
del_key(KC_CAPSLOCK); del_key(KC_CAPSLOCK);
send_keyboard_report(); send_keyboard_report();
} }
@ -375,6 +377,7 @@ void register_code(uint8_t code)
#endif #endif
add_key(KC_NUMLOCK); add_key(KC_NUMLOCK);
send_keyboard_report(); send_keyboard_report();
wait_ms(100);
del_key(KC_NUMLOCK); del_key(KC_NUMLOCK);
send_keyboard_report(); send_keyboard_report();
} }
@ -385,6 +388,7 @@ void register_code(uint8_t code)
#endif #endif
add_key(KC_SCROLLLOCK); add_key(KC_SCROLLLOCK);
send_keyboard_report(); send_keyboard_report();
wait_ms(100);
del_key(KC_SCROLLLOCK); del_key(KC_SCROLLLOCK);
send_keyboard_report(); send_keyboard_report();
} }
@ -440,6 +444,7 @@ void unregister_code(uint8_t code)
#endif #endif
add_key(KC_CAPSLOCK); add_key(KC_CAPSLOCK);
send_keyboard_report(); send_keyboard_report();
wait_ms(100);
del_key(KC_CAPSLOCK); del_key(KC_CAPSLOCK);
send_keyboard_report(); send_keyboard_report();
} }
@ -450,6 +455,7 @@ void unregister_code(uint8_t code)
#endif #endif
add_key(KC_NUMLOCK); add_key(KC_NUMLOCK);
send_keyboard_report(); send_keyboard_report();
wait_ms(100);
del_key(KC_NUMLOCK); del_key(KC_NUMLOCK);
send_keyboard_report(); send_keyboard_report();
} }
@ -460,6 +466,7 @@ void unregister_code(uint8_t code)
#endif #endif
add_key(KC_SCROLLLOCK); add_key(KC_SCROLLLOCK);
send_keyboard_report(); send_keyboard_report();
wait_ms(100);
del_key(KC_SCROLLLOCK); del_key(KC_SCROLLLOCK);
send_keyboard_report(); send_keyboard_report();
} }

View File

@ -181,9 +181,9 @@ typedef union {
/* action utility */ /* action utility */
#define ACTION_NO 0 #define ACTION_NO { .code = 0 }
#define ACTION_TRANSPARENT 1 #define ACTION_TRANSPARENT { .code = 1 }
#define ACTION(kind, param) ((kind)<<12 | (param)) #define ACTION(kind, param) { .code = ((kind)<<12 | (param)) }
/* /*
@ -251,8 +251,8 @@ enum layer_pram_tap_op {
OP_OFF_ON, OP_OFF_ON,
OP_SET_CLEAR, 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_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f))
#define ACTION_LAYER_TAP(layer, key) (ACT_LAYER_TAP<<12 | (layer)<<8 | (key)) #define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer)<<8 | (key))
/* Default Layer */ /* Default Layer */
#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer)/4, 1<<((layer)%4)) #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)) #define ACTION_DEFAULT_LAYER_TOGGLE(layer) ACTION_DEFAULT_LAYER_BIT_XOR((layer)/4, 1<<((layer)%4))

View File

@ -117,8 +117,7 @@ void layer_debug(void)
action_t layer_switch_get_action(keypos_t key) action_t layer_switch_get_action(keypos_t key)
{ {
action_t action; action_t action = ACTION_TRANSPARENT;
action.code = ACTION_TRANSPARENT;
#ifndef NO_ACTION_LAYER #ifndef NO_ACTION_LAYER
uint32_t layers = layer_state | default_layer_state; 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--) { for (int8_t i = 31; i >= 0; i--) {
if (layers & (1UL<<i)) { if (layers & (1UL<<i)) {
action = action_for_key(i, key); action = action_for_key(i, key);
if (action.code != ACTION_TRANSPARENT) { if (action.code != (action_t)ACTION_TRANSPARENT.code) {
return action; return action;
} }
} }

44
common/actionmap.c Normal file
View File

@ -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)
{
}

455
common/actionmap.h Normal file
View File

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

View File

@ -45,10 +45,17 @@ void sleep_led_disable(void)
TIMSK1 &= ~_BV(OCIE1A); TIMSK1 &= ~_BV(OCIE1A);
} }
void sleep_led_toggle(void)
__attribute__ ((weak))
void sleep_led_on(void)
{ {
/* Disable Compare Match Interrupt */ led_set(1<<USB_LED_CAPS_LOCK);
TIMSK1 ^= _BV(OCIE1A); }
__attribute__ ((weak))
void sleep_led_off(void)
{
led_set(0);
} }
@ -86,10 +93,10 @@ ISR(TIMER1_COMPA_vect)
// LED on // LED on
if (timer.pwm.count == 0) { if (timer.pwm.count == 0) {
led_set(1<<USB_LED_CAPS_LOCK); sleep_led_on();
} }
// LED off // LED off
if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) { if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) {
led_set(0); sleep_led_off();
} }
} }

156
common/avr/suart.S Normal file
View File

@ -0,0 +1,156 @@
;---------------------------------------------------------------------------;
; Software implemented UART module ;
; (C)ChaN, 2005 (http://elm-chan.org/) ;
;---------------------------------------------------------------------------;
; Bit rate settings:
;
; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz
; 2.4kbps 138 - - - - - - - -
; 4.8kbps 68 138 - - - - - - -
; 9.6kbps 33 68 138 208 - - - - -
; 19.2kbps - 33 68 102 138 173 208 - -
; 38.4kbps - - 33 50 68 85 102 138 172
; 57.6kbps - - 21 33 44 56 68 91 114
; 115.2kbps - - - - 21 27 33 44 56
.nolist
#include <avr/io.h>
.list
#define BPS 44 /* Bit delay. (see above table) */
#define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */
#define OUT_1 sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */
#define OUT_0 cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */
#define SKIP_IN_1 sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 1 */
#define SKIP_IN_0 sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 0 */
#ifdef SPM_PAGESIZE
.macro _LPMI reg
lpm \reg, Z+
.endm
.macro _MOVW dh,dl, sh,sl
movw \dl, \sl
.endm
#else
.macro _LPMI reg
lpm
mov \reg, r0
adiw ZL, 1
.endm
.macro _MOVW dh,dl, sh,sl
mov \dl, \sl
mov \dh, \sh
.endm
#endif
;---------------------------------------------------------------------------;
; Transmit a byte in serial format of N81
;
;Prototype: void xmit (uint8_t data);
;Size: 16 words
.global xmit
.func xmit
xmit:
#if BIDIR
ldi r23, BPS-1 ;Pre-idle time for bidirectional data line
5: dec r23 ;
brne 5b ;/
#endif
in r0, _SFR_IO_ADDR(SREG) ;Save flags
com r24 ;C = start bit
ldi r25, 10 ;Bit counter
cli ;Start critical section
1: ldi r23, BPS-1 ;----- Bit transferring loop
2: dec r23 ;Wait for a bit time
brne 2b ;/
brcs 3f ;MISO = bit to be sent
OUT_1 ;
3: brcc 4f ;
OUT_0 ;/
4: lsr r24 ;Get next bit into C
dec r25 ;All bits sent?
brne 1b ; no, coutinue
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
ret
.endfunc
;---------------------------------------------------------------------------;
; Receive a byte
;
;Prototype: uint8_t rcvr (void);
;Size: 19 words
.global rcvr
.func rcvr
rcvr:
in r0, _SFR_IO_ADDR(SREG) ;Save flags
ldi r24, 0x80 ;Receiving shift reg
cli ;Start critical section
1: SKIP_IN_1 ;Wait for idle
rjmp 1b
2: SKIP_IN_0 ;Wait for start bit
rjmp 2b
ldi r25, BPS/2 ;Wait for half bit time
3: dec r25
brne 3b
4: ldi r25, BPS ;----- Bit receiving loop
5: dec r25 ;Wait for a bit time
brne 5b ;/
lsr r24 ;Next bit
SKIP_IN_0 ;Get a data bit into r24.7
ori r24, 0x80
brcc 4b ;All bits received? no, continue
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
ret
.endfunc
; Not wait for start bit. This should be called after detecting start bit.
.global recv
.func recv
recv:
in r0, _SFR_IO_ADDR(SREG) ;Save flags
ldi r24, 0x80 ;Receiving shift reg
cli ;Start critical section
;1: SKIP_IN_1 ;Wait for idle
; rjmp 1b
;2: SKIP_IN_0 ;Wait for start bit
; rjmp 2b
ldi r25, BPS/2 ;Wait for half bit time
3: dec r25
brne 3b
4: ldi r25, BPS ;----- Bit receiving loop
5: dec r25 ;Wait for a bit time
brne 5b ;/
lsr r24 ;Next bit
SKIP_IN_0 ;Get a data bit into r24.7
ori r24, 0x80
brcc 4b ;All bits received? no, continue
ldi r25, BPS/2 ;Wait for half bit time
6: dec r25
brne 6b
7: SKIP_IN_1 ;Wait for stop bit
rjmp 7b
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
ret
.endfunc

8
common/avr/suart.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef SUART
#define SUART
void xmit(uint8_t);
uint8_t rcvr(void);
uint8_t recv(void);
#endif /* SUART */

View 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 /* Power down MCU with watchdog timer
* wdto: watchdog timer timeout defined in <avr/wdt.h> * wdto: watchdog timer timeout defined in <avr/wdt.h>
* WDTO_15MS * WDTO_15MS
@ -80,13 +70,45 @@ static void power_down(uint8_t wdto)
wdt_disable(); wdt_disable();
} }
void suspend_power_down(void) static void standby(void)
{ {
power_down(WDTO_15MS); 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) bool suspend_wakeup_condition(void)
{ {
matrix_power_up(); matrix_power_up();
@ -102,6 +124,7 @@ bool suspend_wakeup_condition(void)
void suspend_wakeup_init(void) void suspend_wakeup_init(void)
{ {
// clear keyboard state // clear keyboard state
matrix_clear();
clear_keyboard(); clear_keyboard();
#ifdef BACKLIGHT_ENABLE #ifdef BACKLIGHT_ENABLE
backlight_init(); backlight_init();

View File

@ -5,6 +5,7 @@
#include "bootloader.h" #include "bootloader.h"
#include "debug.h" #include "debug.h"
#include "keymap.h" #include "keymap.h"
#include "actionmap.h"
#include "host.h" #include "host.h"
#include "action_layer.h" #include "action_layer.h"
#include "eeconfig.h" #include "eeconfig.h"
@ -27,17 +28,17 @@ void bootmagic(void)
print("done.\n"); print("done.\n");
/* bootmagic skip */ /* bootmagic skip */
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) { if (bootmagic_scan_key(BOOTMAGIC_KEY_SKIP)) {
return; return;
} }
/* eeconfig clear */ /* eeconfig clear */
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EEPROM_CLEAR)) { if (bootmagic_scan_key(BOOTMAGIC_KEY_EEPROM_CLEAR)) {
eeconfig_init(); eeconfig_init();
} }
/* bootloader */ /* bootloader */
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_BOOTLOADER)) { if (bootmagic_scan_key(BOOTMAGIC_KEY_BOOTLOADER)) {
bootloader_jump(); bootloader_jump();
} }
@ -46,12 +47,12 @@ void bootmagic(void)
/* debug enable */ /* debug enable */
debug_config.raw = eeconfig_read_debug(); debug_config.raw = eeconfig_read_debug();
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_ENABLE)) { if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_ENABLE)) {
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MATRIX)) { if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_MATRIX)) {
debug_config.matrix = !debug_config.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; 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; debug_config.mouse = !debug_config.mouse;
} else { } else {
debug_config.enable = !debug_config.enable; debug_config.enable = !debug_config.enable;
@ -61,28 +62,28 @@ void bootmagic(void)
/* keymap config */ /* keymap config */
keymap_config.raw = eeconfig_read_keymap(); 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; 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; 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; 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; 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; 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; 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; 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; keymap_config.nkro = !keymap_config.nkro;
} }
eeconfig_write_keymap(keymap_config.raw); eeconfig_write_keymap(keymap_config.raw);
@ -93,14 +94,14 @@ void bootmagic(void)
/* default layer */ /* default layer */
uint8_t default_layer = 0; uint8_t default_layer = 0;
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); } if (bootmagic_scan_key(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_key(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_key(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_key(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_key(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_key(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_key(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_7)) { default_layer |= (1<<7); }
if (default_layer) { if (default_layer) {
eeconfig_write_default_layer(default_layer); eeconfig_write_default_layer(default_layer);
default_layer_set((uint32_t)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++) { for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
matrix_row_t matrix_row = matrix_get_row(r); matrix_row_t matrix_row = matrix_get_row(r);
for (uint8_t c = 0; c < MATRIX_COLS; c++) { for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_row & ((matrix_row_t)1<<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; return true;
} }
} }
@ -125,9 +135,9 @@ static bool scan_keycode(uint8_t keycode)
return false; 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);
} }

View File

@ -95,6 +95,6 @@
void bootmagic(void); void bootmagic(void);
bool bootmagic_scan_keycode(uint8_t keycode); bool bootmagic_scan_key(uint16_t action);
#endif #endif

View File

@ -182,14 +182,22 @@ static bool command_common(uint8_t code)
{ {
#ifdef KEYBOARD_LOCK_ENABLE #ifdef KEYBOARD_LOCK_ENABLE
static host_driver_t *host_driver = 0; static host_driver_t *host_driver = 0;
#endif
#ifdef SLEEP_LED_ENABLE
static bool sleep_led_test = false;
#endif #endif
switch (code) { switch (code) {
#ifdef SLEEP_LED_ENABLE #ifdef SLEEP_LED_ENABLE
case KC_Z: case KC_Z:
// test breathing sleep LED // test breathing sleep LED
print("Sleep LED test\n"); print("Sleep LED test\n");
sleep_led_toggle(); if (sleep_led_test) {
led_set(host_keyboard_leds()); sleep_led_disable();
led_set(host_keyboard_leds());
} else {
sleep_led_enable();
}
sleep_led_test = !sleep_led_test;
break; break;
#endif #endif
#ifdef BOOTMAGIC_ENABLE #ifdef BOOTMAGIC_ENABLE

View File

@ -54,7 +54,7 @@ void host_keyboard_send(report_keyboard_t *report)
(*driver->send_keyboard)(report); (*driver->send_keyboard)(report);
if (debug_keyboard) { if (debug_keyboard) {
dprint("keyboard_report: "); dprint("keyboard: ");
for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) { for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
dprintf("%02X ", report->raw[i]); dprintf("%02X ", report->raw[i]);
} }
@ -75,6 +75,10 @@ void host_system_send(uint16_t report)
if (!driver) return; if (!driver) return;
(*driver->send_system)(report); (*driver->send_system)(report);
if (debug_keyboard) {
dprintf("system: %04X\n", report);
}
} }
void host_consumer_send(uint16_t report) void host_consumer_send(uint16_t report)
@ -84,9 +88,13 @@ void host_consumer_send(uint16_t report)
if (!driver) return; if (!driver) return;
(*driver->send_consumer)(report); (*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; return last_system_report;
} }

View File

@ -47,7 +47,7 @@ void host_mouse_send(report_mouse_t *report);
void host_system_send(uint16_t data); void host_system_send(uint16_t data);
void host_consumer_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); uint16_t host_last_consumer_report(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -63,7 +63,6 @@ static bool has_ghost_in_row(uint8_t row)
#endif #endif
__attribute__ ((weak)) void matrix_setup(void) {}
void keyboard_setup(void) void keyboard_setup(void)
{ {
matrix_setup(); matrix_setup();

View 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_MRWD KC_MEDIA_REWIND
#define KC_MSTP KC_MEDIA_STOP #define KC_MSTP KC_MEDIA_STOP
#define KC_MPLY KC_MEDIA_PLAY_PAUSE #define KC_MPLY KC_MEDIA_PLAY_PAUSE
#define KC_MSEL KC_MEDIA_SELECT
#define KC_EJCT KC_MEDIA_EJECT #define KC_EJCT KC_MEDIA_EJECT
#define KC_MSEL KC_MEDIA_SELECT
#define KC_MAIL KC_MAIL #define KC_MAIL KC_MAIL
#define KC_CALC KC_CALCULATOR #define KC_CALC KC_CALCULATOR
#define KC_MYCM KC_MY_COMPUTER #define KC_MYCM KC_MY_COMPUTER
@ -420,10 +420,12 @@ enum internal_special_keycodes {
KC_AUDIO_VOL_DOWN, KC_AUDIO_VOL_DOWN,
KC_MEDIA_NEXT_TRACK, KC_MEDIA_NEXT_TRACK,
KC_MEDIA_PREV_TRACK, KC_MEDIA_PREV_TRACK,
KC_MEDIA_FAST_FORWARD,
KC_MEDIA_REWIND,
KC_MEDIA_STOP, KC_MEDIA_STOP,
KC_MEDIA_PLAY_PAUSE, KC_MEDIA_PLAY_PAUSE,
KC_MEDIA_SELECT,
KC_MEDIA_EJECT, KC_MEDIA_EJECT,
KC_MEDIA_SELECT,
KC_MAIL, KC_MAIL,
KC_CALCULATOR, KC_CALCULATOR,
KC_MY_COMPUTER, KC_MY_COMPUTER,
@ -433,9 +435,7 @@ enum internal_special_keycodes {
KC_WWW_FORWARD, KC_WWW_FORWARD,
KC_WWW_STOP, KC_WWW_STOP,
KC_WWW_REFRESH, KC_WWW_REFRESH,
KC_WWW_FAVORITES, KC_WWW_FAVORITES, /* 0xBC */
KC_MEDIA_FAST_FORWARD,
KC_MEDIA_REWIND, /* 0xBC */
/* Jump to bootloader */ /* Jump to bootloader */
KC_BOOTLOADER = 0xBF, KC_BOOTLOADER = 0xBF,

View 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 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 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 "wait.h"
#include "debug.h" #include "debug.h"
#include "bootloader.h" #include "bootloader.h"
#if defined(__AVR__)
#include <avr/pgmspace.h>
#endif
#ifdef BOOTMAGIC_ENABLE #ifdef BOOTMAGIC_ENABLE
extern keymap_config_t keymap_config; extern keymap_config_t keymap_config;
@ -32,6 +35,7 @@ static action_t keycode_to_action(uint8_t keycode);
/* converts key to action */ /* converts key to action */
__attribute__ ((weak))
action_t action_for_key(uint8_t layer, keypos_t key) action_t action_for_key(uint8_t layer, keypos_t key)
{ {
uint8_t keycode = keymap_key_to_keycode(layer, 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: case KC_LALT:
if (keymap_config.swap_lalt_lgui) { if (keymap_config.swap_lalt_lgui) {
if (keymap_config.no_gui) { if (keymap_config.no_gui) {
return keycode_to_action(ACTION_NO); return keycode_to_action(KC_NO);
} }
return keycode_to_action(KC_LGUI); 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); return keycode_to_action(KC_LALT);
} }
if (keymap_config.no_gui) { if (keymap_config.no_gui) {
return keycode_to_action(ACTION_NO); return keycode_to_action(KC_NO);
} }
return keycode_to_action(KC_LGUI); return keycode_to_action(KC_LGUI);
case KC_RALT: case KC_RALT:
if (keymap_config.swap_ralt_rgui) { if (keymap_config.swap_ralt_rgui) {
if (keymap_config.no_gui) { if (keymap_config.no_gui) {
return keycode_to_action(ACTION_NO); return keycode_to_action(KC_NO);
} }
return keycode_to_action(KC_RGUI); 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); return keycode_to_action(KC_RALT);
} }
if (keymap_config.no_gui) { if (keymap_config.no_gui) {
return keycode_to_action(ACTION_NO); return keycode_to_action(KC_NO);
} }
return keycode_to_action(KC_RGUI); return keycode_to_action(KC_RGUI);
case KC_GRAVE: case KC_GRAVE:
@ -133,23 +137,22 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
/* translates keycode to action */ /* translates keycode to action */
static action_t keycode_to_action(uint8_t keycode) static action_t keycode_to_action(uint8_t keycode)
{ {
action_t action = {};
switch (keycode) { switch (keycode) {
case KC_A ... KC_EXSEL: case KC_A ... KC_EXSEL:
case KC_LCTRL ... KC_RGUI: case KC_LCTRL ... KC_RGUI:
action.code = ACTION_KEY(keycode); return (action_t)ACTION_KEY(keycode);
break; break;
case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); return (action_t)ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
break; break;
case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: case KC_AUDIO_MUTE ... KC_WWW_FAVORITES:
action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); return (action_t)ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
break; break;
case KC_MS_UP ... KC_MS_ACCEL2: case KC_MS_UP ... KC_MS_ACCEL2:
action.code = ACTION_MOUSEKEY(keycode); return (action_t)ACTION_MOUSEKEY(keycode);
break; break;
case KC_TRNS: case KC_TRNS:
action.code = ACTION_TRANSPARENT; return (action_t)ACTION_TRANSPARENT;
break; break;
case KC_BOOTLOADER: case KC_BOOTLOADER:
clear_keyboard(); clear_keyboard();
@ -157,10 +160,10 @@ static action_t keycode_to_action(uint8_t keycode)
bootloader_jump(); // not return bootloader_jump(); // not return
break; break;
default: default:
action.code = ACTION_NO; return (action_t)ACTION_NO;
break; break;
} }
return action; return (action_t)ACTION_NO;
} }
@ -170,6 +173,28 @@ static action_t keycode_to_action(uint8_t keycode)
* Legacy keymap support * Legacy keymap support
* Consider using new keymap API instead. * 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)) __attribute__ ((weak))
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key) 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)) __attribute__ ((weak))
action_t keymap_fn_to_action(uint8_t keycode) action_t keymap_fn_to_action(uint8_t keycode)
{ {
action_t action = { .code = ACTION_NO };
switch (keycode) { switch (keycode) {
case KC_FN0 ... KC_FN31: case KC_FN0 ... KC_FN31:
{ {
uint8_t layer = keymap_fn_layer(FN_INDEX(keycode)); uint8_t layer = keymap_fn_layer(FN_INDEX(keycode));
uint8_t key = keymap_fn_keycode(FN_INDEX(keycode)); uint8_t key = keymap_fn_keycode(FN_INDEX(keycode));
if (key) { if (key) {
action.code = ACTION_LAYER_TAP_KEY(layer, key); return (action_t)ACTION_LAYER_TAP_KEY(layer, key);
} else { } else {
action.code = ACTION_LAYER_MOMENTARY(layer); return (action_t)ACTION_LAYER_MOMENTARY(layer);
} }
} }
return action; return (action_t)ACTION_NO;
default: 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 #endif

95
common/matrix.c Normal file
View File

@ -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) {}

View File

@ -32,6 +32,10 @@ typedef uint32_t matrix_row_t;
#error "MATRIX_COLS: invalid value" #error "MATRIX_COLS: invalid value"
#endif #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)) #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); matrix_row_t matrix_get_row(uint8_t row);
/* print matrix for debug */ /* print matrix for debug */
void matrix_print(void); 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 */ /* power control */
void matrix_power_up(void); void matrix_power_up(void);

View File

@ -46,25 +46,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define TRANSPORT_STOP_EJECT 0x00CC #define TRANSPORT_STOP_EJECT 0x00CC
#define TRANSPORT_PLAY_PAUSE 0x00CD #define TRANSPORT_PLAY_PAUSE 0x00CD
/* application launch */ /* application launch */
#define AL_CC_CONFIG 0x0183 #define APPLAUNCH_CC_CONFIG 0x0183
#define AL_EMAIL 0x018A #define APPLAUNCH_EMAIL 0x018A
#define AL_CALCULATOR 0x0192 #define APPLAUNCH_CALCULATOR 0x0192
#define AL_LOCAL_BROWSER 0x0194 #define APPLAUNCH_LOCAL_BROWSER 0x0194
/* application control */ /* application control */
#define AC_SEARCH 0x0221 #define APPCONTROL_SEARCH 0x0221
#define AC_HOME 0x0223 #define APPCONTROL_HOME 0x0223
#define AC_BACK 0x0224 #define APPCONTROL_BACK 0x0224
#define AC_FORWARD 0x0225 #define APPCONTROL_FORWARD 0x0225
#define AC_STOP 0x0226 #define APPCONTROL_STOP 0x0226
#define AC_REFRESH 0x0227 #define APPCONTROL_REFRESH 0x0227
#define AC_BOOKMARKS 0x022A #define APPCONTROL_BOOKMARKS 0x022A
/* supplement for Bluegiga iWRAP HID(not supported by Windows?) */ /* supplement for Bluegiga iWRAP HID(not supported by Windows?) */
#define AL_LOCK 0x019E #define APPLAUNCH_LOCK 0x019E
#define TRANSPORT_RECORD 0x00B2 #define TRANSPORT_RECORD 0x00B2
#define TRANSPORT_FAST_FORWARD 0x00B3 #define TRANSPORT_FAST_FORWARD 0x00B3
#define TRANSPORT_REWIND 0x00B4 #define TRANSPORT_REWIND 0x00B4
#define TRANSPORT_EJECT 0x00B8 #define TRANSPORT_EJECT 0x00B8
#define AC_MINIMIZE 0x0206 #define APPCONTROL_MINIMIZE 0x0206
/* Generic Desktop Page(0x01) - system power control */ /* Generic Desktop Page(0x01) - system power control */
#define SYSTEM_POWER_DOWN 0x0081 #define SYSTEM_POWER_DOWN 0x0081
@ -159,27 +159,27 @@ typedef struct {
/* keycode to consumer usage */ /* keycode to consumer usage */
#define KEYCODE2CONSUMER(key) \ #define KEYCODE2CONSUMER(key) \
(key == KC_AUDIO_MUTE ? AUDIO_MUTE : \ (key == KC_AUDIO_MUTE ? AUDIO_MUTE : \
(key == KC_AUDIO_VOL_UP ? AUDIO_VOL_UP : \ (key == KC_AUDIO_VOL_UP ? AUDIO_VOL_UP : \
(key == KC_AUDIO_VOL_DOWN ? AUDIO_VOL_DOWN : \ (key == KC_AUDIO_VOL_DOWN ? AUDIO_VOL_DOWN : \
(key == KC_MEDIA_NEXT_TRACK ? TRANSPORT_NEXT_TRACK : \ (key == KC_MEDIA_NEXT_TRACK ? TRANSPORT_NEXT_TRACK : \
(key == KC_MEDIA_PREV_TRACK ? TRANSPORT_PREV_TRACK : \ (key == KC_MEDIA_PREV_TRACK ? TRANSPORT_PREV_TRACK : \
(key == KC_MEDIA_FAST_FORWARD ? TRANSPORT_FAST_FORWARD : \ (key == KC_MEDIA_FAST_FORWARD ? TRANSPORT_FAST_FORWARD : \
(key == KC_MEDIA_REWIND ? TRANSPORT_REWIND : \ (key == KC_MEDIA_REWIND ? TRANSPORT_REWIND : \
(key == KC_MEDIA_STOP ? TRANSPORT_STOP : \ (key == KC_MEDIA_STOP ? TRANSPORT_STOP : \
(key == KC_MEDIA_EJECT ? TRANSPORT_STOP_EJECT : \ (key == KC_MEDIA_EJECT ? TRANSPORT_STOP_EJECT : \
(key == KC_MEDIA_PLAY_PAUSE ? TRANSPORT_PLAY_PAUSE : \ (key == KC_MEDIA_PLAY_PAUSE ? TRANSPORT_PLAY_PAUSE : \
(key == KC_MEDIA_SELECT ? AL_CC_CONFIG : \ (key == KC_MEDIA_SELECT ? APPLAUNCH_CC_CONFIG : \
(key == KC_MAIL ? AL_EMAIL : \ (key == KC_MAIL ? APPLAUNCH_EMAIL : \
(key == KC_CALCULATOR ? AL_CALCULATOR : \ (key == KC_CALCULATOR ? APPLAUNCH_CALCULATOR : \
(key == KC_MY_COMPUTER ? AL_LOCAL_BROWSER : \ (key == KC_MY_COMPUTER ? APPLAUNCH_LOCAL_BROWSER : \
(key == KC_WWW_SEARCH ? AC_SEARCH : \ (key == KC_WWW_SEARCH ? APPCONTROL_SEARCH : \
(key == KC_WWW_HOME ? AC_HOME : \ (key == KC_WWW_HOME ? APPCONTROL_HOME : \
(key == KC_WWW_BACK ? AC_BACK : \ (key == KC_WWW_BACK ? APPCONTROL_BACK : \
(key == KC_WWW_FORWARD ? AC_FORWARD : \ (key == KC_WWW_FORWARD ? APPCONTROL_FORWARD : \
(key == KC_WWW_STOP ? AC_STOP : \ (key == KC_WWW_STOP ? APPCONTROL_STOP : \
(key == KC_WWW_REFRESH ? AC_REFRESH : \ (key == KC_WWW_REFRESH ? APPCONTROL_REFRESH : \
(key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0))))))))))))))))))))) (key == KC_WWW_FAVORITES ? APPCONTROL_BOOKMARKS : 0)))))))))))))))))))))
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -2,20 +2,10 @@
#define SLEEP_LED_H #define SLEEP_LED_H
#ifdef SLEEP_LED_ENABLE
void sleep_led_init(void); void sleep_led_init(void);
void sleep_led_enable(void); void sleep_led_enable(void);
void sleep_led_disable(void); void sleep_led_disable(void);
void sleep_led_toggle(void); void sleep_led_on(void);
void sleep_led_off(void);
#else
#define sleep_led_init()
#define sleep_led_enable()
#define sleep_led_disable()
#define sleep_led_toggle()
#endif
#endif #endif

59
common/unimap.c Normal file
View File

@ -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)
{
}

272
common/unimap.h Normal file
View File

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

View File

@ -28,6 +28,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define XSTR(s) #s #define XSTR(s) #s
#ifdef __cplusplus
extern "C" {
#endif
uint8_t bitpop(uint8_t bits); uint8_t bitpop(uint8_t bits);
uint8_t bitpop16(uint16_t bits); uint8_t bitpop16(uint16_t bits);
uint8_t bitpop32(uint32_t bits); uint8_t bitpop32(uint32_t bits);
@ -40,4 +44,8 @@ uint8_t bitrev(uint8_t bits);
uint16_t bitrev16(uint16_t bits); uint16_t bitrev16(uint16_t bits);
uint32_t bitrev32(uint32_t bits); uint32_t bitrev32(uint32_t bits);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -1,7 +1,7 @@
Keycode Symbol Table Keycode Symbol Table
==================== ====================
Keycodes are defined in `common/keycode.h`. 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> <http://www.usb.org/developers/devclass_docs/Hut1_11.pdf>
Virtual keycodes are defined out of above range to support special actions. 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 * Virtual keycodes
*/ */
/* System Control */ /* Generic Desktop Page(0x01) - System Control */
KC_SYSTEM_POWER KC_PWR System Power Down KC_SYSTEM_POWER KC_PWR System Power Down
KC_SYSTEM_SLEEP KC_SLEP System Sleep KC_SYSTEM_SLEEP KC_SLEP System Sleep
KC_SYSTEM_WAKE KC_WAKE System Wake KC_SYSTEM_WAKE KC_WAKE System Wake
/* Consumer Page */
KC_AUDIO_MUTE KC_MUTE /* Consumer Page(0x07) */
KC_AUDIO_VOL_UP KC_VOLU KC_AUDIO_MUTE KC_MUTE Mute
KC_AUDIO_VOL_DOWN KC_VOLD KC_AUDIO_VOL_UP KC_VOLU Volume Increment
KC_MEDIA_NEXT_TRACK KC_MNXT KC_AUDIO_VOL_DOWN KC_VOLD Volume Decrement
KC_MEDIA_PREV_TRACK KC_MPRV KC_MEDIA_NEXT_TRACK KC_MNXT Scan Next Track
KC_MEDIA_STOP KC_MSTP KC_MEDIA_PREV_TRACK KC_MPRV Scan Previous Track
KC_MEDIA_PLAY_PAUSE KC_MPLY KC_MEDIA_STOP KC_MSTP Stop
KC_MEDIA_SELECT KC_MSEL KC_MEDIA_FAST_FORWARD KC_MFFD Fast Forward
KC_MAIL KC_MAIL KC_MEDIA_REWIND KC_MRWD Rewind
KC_CALCULATOR KC_CALC KC_MEDIA_PLAY_PAUSE KC_MPLY Play/Pause
KC_MY_COMPUTER KC_MYCM KC_EJCT KC_MEDIA_EJECT Stop/Eject
KC_WWW_SEARCH KC_WSCH KC_MEDIA_SELECT KC_MSEL AL Consumer Control Configuration
KC_WWW_HOME KC_WHOM KC_MAIL KC_MAIL AL Email Reader
KC_WWW_BACK KC_WBAK KC_CALCULATOR KC_CALC AL Calculator
KC_WWW_FORWARD KC_WFWD KC_MY_COMPUTER KC_MYCM AL Local Machine Browser
KC_WWW_STOP KC_WSTP KC_WWW_SEARCH KC_WSCH AC Search
KC_WWW_REFRESH KC_WREF KC_WWW_HOME KC_WHOM AC Home
KC_WWW_FAVORITES KC_WFAV KC_WWW_BACK KC_WBAK AC Back
/* Mousekey */ 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_UP KC_MS_U Mouse Cursor Up
KC_MS_DOWN KC_MS_D Mouse Cursor Down KC_MS_DOWN KC_MS_D Mouse Cursor Down
KC_MS_LEFT KC_MS_L Mouse Cursor Left 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_ACCEL0 KC_ACL0 Mouse Acceleration 0
KC_MS_ACCEL1 KC_ACL1 Mouse Acceleration 1 KC_MS_ACCEL1 KC_ACL1 Mouse Acceleration 1
KC_MS_ACCEL2 KC_ACL2 Mouse Acceleration 2 KC_MS_ACCEL2 KC_ACL2 Mouse Acceleration 2
/* Fn key */
/* Fn key - TMK specific */
KC_FN0 KC_FN0
KC_FN1 KC_FN1
KC_FN2 KC_FN2

View File

@ -95,7 +95,7 @@ Note that ***higher layers have priority in the layer stack***. The firmware sta
### 0.3 Keymap Example ### 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 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. 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. 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 /* 0: Qwerty
* ,-----------------------------------------------------------. * ,-----------------------------------------------------------.
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| * |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), 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_MOMENTARY(1), // FN0
ACTION_LAYER_TAP_KEY(2, KC_SCLN), // FN1 ACTION_LAYER_TAP_KEY(2, KC_SCLN), // FN1
ACTION_LAYER_TOGGLE(2), // FN2 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 - `KC_WSCH`, `KC_WHOM`, `KC_WBAK`, `KC_WFWD`, `KC_WSTP`, `KC_WREF`, `KC_WFAV` for web browser operation
### 1.5 Fn key ### 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 ### 1.6 Keycode Table
See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes. 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) ACTION_DEFAULT_LAYER_BIT_SET(part, bits)
### 2.3 Macro action ### 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.
`Macro` action indicates complex key strokes. ACTION_MACRO(id)
ACTION_MACRO_TAP(id)
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 )
#### 2.3.1 Macro Commands `id` is an 8-bit user-defined value the macro getter function can use to pick the specific macro.
- **MACRO()**
- **MACRO_NONE**
#### 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);
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.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. - **I()** change interval of stroke.
- **D()** press key - **D()** press key
@ -401,19 +415,25 @@ Default Layer also has bitwise operations, they are executed when key is release
- **SM()** store modifier state - **SM()** store modifier state
- **RM()** restore modifier state - **RM()** restore modifier state
- **CM()** clear 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 #### 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) const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{ {
switch (id) { switch (id) {
case HELLO: case 0:
return (record->event.pressed ? return (record->event.pressed ?
MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) : MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) :
MACRO_NONE ); MACRO_NONE );
case ALT_TAB: case 1:
return (record->event.pressed ? return (record->event.pressed ?
MACRO( D(LALT), D(TAB), END ) : MACRO( D(LALT), D(TAB), END ) :
MACRO( U(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; 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 ### 2.4 Function action
@ -443,7 +468,7 @@ To define tappable `Function` action in keymap use this.
#### 2.4.3 Implement user function #### 2.4.3 Implement user function
`Function` actions can be defined freely with C by user in callback 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. 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) 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 ## 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. 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 1, // Fn0
2, // Fn1 2, // Fn1
2, // Fn2 2, // Fn2
}; };
static const uint8_t PROGMEM fn_keycode[] = { const uint8_t PROGMEM fn_keycode[] = {
KC_NO, // Fn0 KC_NO, // Fn0
KC_NO, // Fn1 KC_NO, // Fn1
KC_SPC, // Fn2 KC_SPC, // Fn2

51
doc/unimap.txt Normal file
View File

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

View File

@ -1,52 +1,59 @@
PROTOCOL_DIR = protocol PROTOCOL_DIR = protocol
ifdef PS2_MOUSE_ENABLE ifeq (yes,$(strip $(PS2_MOUSE_ENABLE)))
SRC += $(PROTOCOL_DIR)/ps2_mouse.c SRC += $(PROTOCOL_DIR)/ps2_mouse.c
OPT_DEFS += -DPS2_MOUSE_ENABLE OPT_DEFS += -DPS2_MOUSE_ENABLE
OPT_DEFS += -DMOUSE_ENABLE OPT_DEFS += -DMOUSE_ENABLE
endif endif
ifdef PS2_USE_BUSYWAIT ifeq (yes,$(strip $(PS2_USE_BUSYWAIT)))
SRC += protocol/ps2_busywait.c SRC += protocol/ps2_busywait.c
SRC += protocol/ps2_io_avr.c SRC += protocol/ps2_io_avr.c
OPT_DEFS += -DPS2_USE_BUSYWAIT OPT_DEFS += -DPS2_USE_BUSYWAIT
endif endif
ifdef PS2_USE_INT ifeq (yes,$(strip $(PS2_USE_INT)))
SRC += protocol/ps2_interrupt.c SRC += protocol/ps2_interrupt.c
SRC += protocol/ps2_io_avr.c SRC += protocol/ps2_io_avr.c
OPT_DEFS += -DPS2_USE_INT OPT_DEFS += -DPS2_USE_INT
endif endif
ifdef PS2_USE_USART ifeq (yes,$(strip $(PS2_USE_USART)))
SRC += protocol/ps2_usart.c SRC += protocol/ps2_usart.c
SRC += protocol/ps2_io_avr.c SRC += protocol/ps2_io_avr.c
OPT_DEFS += -DPS2_USE_USART OPT_DEFS += -DPS2_USE_USART
endif 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 SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c
OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \ OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \
-DMOUSE_ENABLE -DMOUSE_ENABLE
endif endif
ifdef SERIAL_MOUSE_MOUSESYSTEMS_ENABLE ifeq (yes,$(strip $(SERIAL_MOUSE_MOUSESYSTEMS_ENABLE)))
SRC += $(PROTOCOL_DIR)/serial_mouse_mousesystems.c SRC += $(PROTOCOL_DIR)/serial_mouse_mousesystems.c
OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MOUSESYSTEMS \ OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MOUSESYSTEMS \
-DMOUSE_ENABLE -DMOUSE_ENABLE
endif endif
ifdef SERIAL_MOUSE_USE_SOFT ifeq (yes,$(strip $(SERIAL_MOUSE_USE_SOFT)))
SRC += $(PROTOCOL_DIR)/serial_soft.c SRC += $(PROTOCOL_DIR)/serial_soft.c
endif endif
ifdef SERIAL_MOUSE_USE_UART ifeq (yes,$(strip $(SERIAL_MOUSE_USE_UART)))
SRC += $(PROTOCOL_DIR)/serial_uart.c SRC += $(PROTOCOL_DIR)/serial_uart.c
endif endif
ifdef ADB_MOUSE_ENABLE ifeq (yes,$(strip $(ADB_MOUSE_ENABLE)))
OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE
endif endif

View File

@ -60,7 +60,6 @@ static inline void place_bit1(void);
static inline void send_byte(uint8_t data); static inline void send_byte(uint8_t data);
static inline uint16_t wait_data_lo(uint16_t us); static inline uint16_t wait_data_lo(uint16_t us);
static inline uint16_t wait_data_hi(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) 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.msg1068919#msg1068919>
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
*/ */
uint16_t adb_host_kbd_recv(uint8_t addr)
// 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)
{ {
return adb_host_dev_recv(ADDR_KEYB); return adb_host_talk(addr, ADB_REG_0);
} }
#ifdef ADB_MOUSE_ENABLE #ifdef ADB_MOUSE_ENABLE
@ -139,16 +98,16 @@ void adb_mouse_init(void) {
uint16_t adb_host_mouse_recv(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 #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; uint16_t data = 0;
cli(); cli();
attention(); 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) place_bit0(); // Stopbit(0)
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
sei(); sei();
@ -158,20 +117,20 @@ static inline uint16_t adb_host_dev_recv(uint8_t device)
sei(); sei();
return 0; // No data to send return 0; // No data to send
} }
uint8_t n = 17; // start bit + 16 data bits uint8_t n = 17; // start bit + 16 data bits
do { do {
uint8_t lo = (uint8_t) wait_data_hi(130); uint8_t lo = (uint8_t) wait_data_hi(130);
if (!lo) if (!lo)
goto error; goto error;
uint8_t hi = (uint8_t) wait_data_lo(lo); uint8_t hi = (uint8_t) wait_data_lo(lo);
if (!hi) if (!hi)
goto error; goto error;
hi = lo - hi; hi = lo - hi;
lo = 130 - lo; lo = 130 - lo;
data <<= 1; data <<= 1;
if (lo < hi) { if (lo < hi) {
data |= 1; data |= 1;
@ -197,27 +156,27 @@ error:
return -n; 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(); cli();
attention(); attention();
send_byte(cmd); send_byte((addr<<4) | (ADB_CMD_LISTEN<<2) | reg);
place_bit0(); // Stopbit(0) place_bit0(); // Stopbit(0)
_delay_us(200); // Tlt/Stop to Start _delay_us(200); // Tlt/Stop to Start
place_bit1(); // Startbit(1) place_bit1(); // Startbit(1)
send_byte(data_h); send_byte(data_h);
send_byte(data_l); send_byte(data_l);
place_bit0(); // Stopbit(0); place_bit0(); // Stopbit(0);
sei(); sei();
} }
// send state of LEDs // 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) // Listen Register2
// send upper byte (not used) // upper byte: not used
// send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
adb_host_listen(0x2A,0,led&0x07); adb_host_listen(addr, 2, 0, led & 0x07);
} }
@ -366,7 +325,7 @@ Commands
bits 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) A A A A 0 0 0 1 Flush(reset a device)
- - - - 0 0 1 0 Reserved - - - - 0 0 1 0 Reserved
- - - - 0 0 1 1 Reserved - - - - 0 0 1 1 Reserved
@ -375,7 +334,7 @@ Commands
A A A A 1 1 R R Talk(read from a device) A A A A 1 1 R R Talk(read from a device)
The command to read keycodes from keyboard is 0x2C which 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: Address:
2: keyboard 2: keyboard
@ -457,7 +416,7 @@ Keyboard Data(Register0)
Keyboard LEDs & state of keys(Register2) Keyboard LEDs & state of keys(Register2)
This register hold current state of three LEDs and nine keys. This register hold current state of three LEDs and nine keys.
The state of LEDs can be changed by sending Listen command. The state of LEDs can be changed by sending Listen command.
1514 . . . . . . 7 6 5 . 3 2 1 0 1514 . . . . . . 7 6 5 . 3 2 1 0
| | | | | | | | | | | | | | | +- LED1(NumLock) | | | | | | | | | | | | | | | +- LED1(NumLock)
| | | | | | | | | | | | | | +--- LED2(CapsLock) | | | | | | | | | | | | | | +--- LED2(CapsLock)
@ -474,5 +433,56 @@ Keyboard LEDs & state of keys(Register2)
| +----------------------------- Delete | +----------------------------- Delete
+------------------------------- Reserved +------------------------------- 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 END_OF_ADB
*/ */

View File

@ -52,13 +52,41 @@ POSSIBILITY OF SUCH DAMAGE.
#define ADB_CAPS 0x39 #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 // ADB host
void adb_host_init(void); void adb_host_init(void);
bool adb_host_psw(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); uint16_t adb_host_mouse_recv(void);
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
void adb_host_kbd_led(uint8_t led); 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_task(void);
void adb_mouse_init(void); void adb_mouse_init(void);

View File

@ -150,25 +150,25 @@ static void send_system(uint16_t data)
+-------------------------------------+-------+ +-------------------------------------+-------+
*/ */
#define CONSUMER2BLUEFRUIT(usage) \ #define CONSUMER2BLUEFRUIT(usage) \
(usage == AUDIO_MUTE ? 0x0000 : \ (usage == AUDIO_MUTE ? 0x0000 : \
(usage == AUDIO_VOL_UP ? 0x1000 : \ (usage == AUDIO_VOL_UP ? 0x1000 : \
(usage == AUDIO_VOL_DOWN ? 0x2000 : \ (usage == AUDIO_VOL_DOWN ? 0x2000 : \
(usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \ (usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \
(usage == TRANSPORT_PREV_TRACK ? 0x0004 : \ (usage == TRANSPORT_PREV_TRACK ? 0x0004 : \
(usage == TRANSPORT_STOP ? 0x0010 : \ (usage == TRANSPORT_STOP ? 0x0010 : \
(usage == TRANSPORT_STOP_EJECT ? 0x0000 : \ (usage == TRANSPORT_STOP_EJECT ? 0x0000 : \
(usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \ (usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \
(usage == AL_CC_CONFIG ? 0x0000 : \ (usage == APPLAUNCH_CC_CONFIG ? 0x0000 : \
(usage == AL_EMAIL ? 0x0000 : \ (usage == APPLAUNCH_EMAIL ? 0x0000 : \
(usage == AL_CALCULATOR ? 0x0000 : \ (usage == APPLAUNCH_CALCULATOR ? 0x0000 : \
(usage == AL_LOCAL_BROWSER ? 0x0000 : \ (usage == APPLAUNCH_LOCAL_BROWSER ? 0x0000 : \
(usage == AC_SEARCH ? 0x0400 : \ (usage == APPCONTROL_SEARCH ? 0x0400 : \
(usage == AC_HOME ? 0x0100 : \ (usage == APPCONTROL_HOME ? 0x0100 : \
(usage == AC_BACK ? 0x0000 : \ (usage == APPCONTROL_BACK ? 0x0000 : \
(usage == AC_FORWARD ? 0x0000 : \ (usage == APPCONTROL_FORWARD ? 0x0000 : \
(usage == AC_STOP ? 0x0000 : \ (usage == APPCONTROL_STOP ? 0x0000 : \
(usage == AC_REFRESH ? 0x0000 : \ (usage == APPCONTROL_REFRESH ? 0x0000 : \
(usage == AC_BOOKMARKS ? 0x0000 : 0))))))))))))))))))) (usage == APPCONTROL_BOOKMARKS ? 0x0000 : 0)))))))))))))))))))
static void send_consumer(uint16_t data) static void send_consumer(uint16_t data)
{ {

View File

@ -1,16 +1,16 @@
## TMK running on top of ChibiOS ## 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 ### 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. - 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 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`. - 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. - 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 ### 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 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`. - 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. - 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.

View File

@ -153,7 +153,7 @@ static const uint8_t keyboard_hid_report_desc_data[] = {
0x95, KBD_REPORT_KEYS, // Report Count (), 0x95, KBD_REPORT_KEYS, // Report Count (),
0x75, 0x08, // Report Size (8), 0x75, 0x08, // Report Size (8),
0x15, 0x00, // Logical Minimum (0), 0x15, 0x00, // Logical Minimum (0),
0x25, 0xFF, // Logical Maximum(255), 0x26, 0xFF, 0x00, // Logical Maximum(255),
0x05, 0x07, // Usage Page (Key Codes), 0x05, 0x07, // Usage Page (Key Codes),
0x19, 0x00, // Usage Minimum (0), 0x19, 0x00, // Usage Minimum (0),
0x29, 0xFF, // Usage Maximum (255), 0x29, 0xFF, // Usage Maximum (255),
@ -299,7 +299,7 @@ static const uint8_t extra_hid_report_desc_data[] = {
0xa1, 0x01, // COLLECTION (Application) 0xa1, 0x01, // COLLECTION (Application)
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
0x15, 0x01, // LOGICAL_MINIMUM (0x1) 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) 0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7)
0x19, 0x01, // USAGE_MINIMUM (0x1) 0x19, 0x01, // USAGE_MINIMUM (0x1)
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) 0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
0x75, 0x10, // REPORT_SIZE (16) 0x75, 0x10, // REPORT_SIZE (16)

View 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 += -DINTERRUPT_CONTROL_ENDPOINT
LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1 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 += -DF_USB=$(F_USB)UL
OPT_DEFS += -DARCH=ARCH_$(ARCH) OPT_DEFS += -DARCH=ARCH_$(ARCH)
@ -44,3 +48,8 @@ OPT_DEFS += $(LUFA_OPTS)
# This indicates using LUFA stack # This indicates using LUFA stack
OPT_DEFS += -DPROTOCOL_LUFA OPT_DEFS += -DPROTOCOL_LUFA
ifeq (yes,$(strip $(LUFA_DEBUG_SUART)))
SRC += common/avr/suart.S
LUFA_OPTS += -DLUFA_DEBUG_SUART
endif

View File

@ -73,10 +73,10 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
HID_RI_OUTPUT(8, HID_IOF_CONSTANT), HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */ HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */ HID_RI_USAGE_MINIMUM(8, 0x00),
HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */ HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Usage ID 0x00-0xFF */
HID_RI_LOGICAL_MINIMUM(8, 0x00), 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_COUNT(8, 0x06),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), 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_USAGE(8, 0x80), /* System Control */
HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_COLLECTION(8, 0x01), /* Application */
HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM), 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_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_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */
HID_RI_REPORT_SIZE(8, 16), HID_RI_REPORT_SIZE(8, 16),
HID_RI_REPORT_COUNT(8, 1), 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_COLLECTION(8, 0x01), /* Application */
HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */ HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
HID_RI_LOGICAL_MINIMUM(8, 0x00), 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_COUNT(8, CONSOLE_EPSIZE),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */ HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
HID_RI_LOGICAL_MINIMUM(8, 0x00), 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_COUNT(8, CONSOLE_EPSIZE),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),

View File

@ -155,7 +155,7 @@ typedef struct
#define MOUSE_EPSIZE 8 #define MOUSE_EPSIZE 8
#define EXTRAKEY_EPSIZE 8 #define EXTRAKEY_EPSIZE 8
#define CONSOLE_EPSIZE 32 #define CONSOLE_EPSIZE 32
#define NKRO_EPSIZE 16 #define NKRO_EPSIZE 32
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,

View File

@ -1,4 +1,4 @@
/* /*
* Copyright 2012 Jun Wako <wakojun@gmail.com> * Copyright 2012 Jun Wako <wakojun@gmail.com>
* This file is based on: * This file is based on:
* LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
@ -50,9 +50,18 @@
#include "suspend.h" #include "suspend.h"
#include "hook.h" #include "hook.h"
#ifdef LUFA_DEBUG_SUART
#include "avr/suart.h"
#endif
#include "matrix.h"
#include "descriptor.h" #include "descriptor.h"
#include "lufa.h" #include "lufa.h"
//#define LUFA_DEBUG
uint8_t keyboard_idle = 0; uint8_t keyboard_idle = 0;
/* 0: Boot Protocol, 1: Report Protocol(default) */ /* 0: Boot Protocol, 1: Report Protocol(default) */
uint8_t keyboard_protocol = 1; 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 */ /* Create a temporary buffer to hold the read in report from the host */
uint8_t ConsoleData[CONSOLE_EPSIZE]; uint8_t ConsoleData[CONSOLE_EPSIZE];
/* Read Console Report Data */ /* Read Console Report Data */
Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL); Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
/* Process Console Report Data */ /* Process Console Report Data */
//ProcessConsoleHIDReport(ConsoleData); //ProcessConsoleHIDReport(ConsoleData);
} }
@ -164,7 +173,7 @@ void EVENT_USB_Device_Disconnect(void)
print("[D]"); print("[D]");
/* For battery powered device */ /* For battery powered device */
USB_IsInitialized = false; 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) { if (USB_IsInitialized) {
USB_Disable(); // Disable all interrupts USB_Disable(); // Disable all interrupts
USB_Controller_Enable(); USB_Controller_Enable();
@ -175,18 +184,24 @@ void EVENT_USB_Device_Disconnect(void)
void EVENT_USB_Device_Reset(void) void EVENT_USB_Device_Reset(void)
{ {
#ifdef LUFA_DEBUG
print("[R]"); print("[R]");
#endif
} }
void EVENT_USB_Device_Suspend() void EVENT_USB_Device_Suspend()
{ {
#ifdef LUFA_DEBUG
print("[S]"); print("[S]");
#endif
hook_usb_suspend_entry(); hook_usb_suspend_entry();
} }
void EVENT_USB_Device_WakeUp() void EVENT_USB_Device_WakeUp()
{ {
#ifdef LUFA_DEBUG
print("[W]"); print("[W]");
#endif
hook_usb_wakeup(); hook_usb_wakeup();
} }
@ -217,6 +232,9 @@ void EVENT_USB_Device_StartOfFrame(void)
*/ */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
#ifdef LUFA_DEBUG
print("[c]");
#endif
bool ConfigSuccess = true; bool ConfigSuccess = true;
/* Setup Keyboard HID Report Endpoints */ /* Setup Keyboard HID Report Endpoints */
@ -293,6 +311,9 @@ void EVENT_USB_Device_ControlRequest(void)
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
Endpoint_ClearOUT(); Endpoint_ClearOUT();
#ifdef LUFA_DEBUG
xprintf("[r%d]", USB_ControlRequest.wIndex);
#endif
} }
break; break;
@ -316,6 +337,9 @@ void EVENT_USB_Device_ControlRequest(void)
Endpoint_ClearOUT(); Endpoint_ClearOUT();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
#ifdef LUFA_DEBUG
xprintf("[L%d]", USB_ControlRequest.wIndex);
#endif
break; break;
} }
@ -332,6 +356,9 @@ void EVENT_USB_Device_ControlRequest(void)
Endpoint_Write_8(keyboard_protocol); Endpoint_Write_8(keyboard_protocol);
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
#ifdef LUFA_DEBUG
print("[p]");
#endif
} }
} }
@ -345,6 +372,9 @@ void EVENT_USB_Device_ControlRequest(void)
keyboard_protocol = (USB_ControlRequest.wValue & 0xFF); keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
clear_keyboard(); clear_keyboard();
#ifdef LUFA_DEBUG
print("[P]");
#endif
} }
} }
@ -356,6 +386,9 @@ void EVENT_USB_Device_ControlRequest(void)
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
#ifdef LUFA_DEBUG
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8);
#endif
} }
break; break;
@ -367,6 +400,9 @@ void EVENT_USB_Device_ControlRequest(void)
Endpoint_Write_8(keyboard_idle); Endpoint_Write_8(keyboard_idle);
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
#ifdef LUFA_DEBUG
print("[i]");
#endif
} }
break; break;
@ -374,7 +410,7 @@ void EVENT_USB_Device_ControlRequest(void)
} }
/******************************************************************************* /*******************************************************************************
* Host driver * Host driver
******************************************************************************/ ******************************************************************************/
static uint8_t keyboard_leds(void) static uint8_t keyboard_leds(void)
{ {
@ -494,6 +530,9 @@ static void send_consumer(uint16_t data)
#define SEND_TIMEOUT 5 #define SEND_TIMEOUT 5
int8_t sendchar(uint8_t c) int8_t sendchar(uint8_t c)
{ {
#ifdef LUFA_DEBUG_SUART
xmit(c);
#endif
// Not wait once timeouted. // Not wait once timeouted.
// Because sendchar() is called so many times, waiting each call causes big lag. // Because sendchar() is called so many times, waiting each call causes big lag.
static bool timeouted = false; static bool timeouted = false;
@ -551,6 +590,9 @@ ERROR_EXIT:
#else #else
int8_t sendchar(uint8_t c) int8_t sendchar(uint8_t c)
{ {
#ifdef LUFA_DEBUG_SUART
xmit(c);
#endif
return 0; return 0;
} }
#endif #endif
@ -578,13 +620,20 @@ static void setup_usb(void)
// for Console_Task // for Console_Task
USB_Device_EnableSOFEvents(); USB_Device_EnableSOFEvents();
print_set_sendchar(sendchar);
} }
int main(void) __attribute__ ((weak)); int main(void) __attribute__ ((weak));
int main(void) int main(void)
{ {
setup_mcu(); 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(); hook_early_init();
keyboard_setup(); keyboard_setup();
setup_usb(); setup_usb();
@ -611,7 +660,9 @@ int main(void)
hook_late_init(); hook_late_init();
while (1) { while (1) {
while (USB_DeviceState == DEVICE_STATE_Suspended) { while (USB_DeviceState == DEVICE_STATE_Suspended) {
#ifdef LUFA_DEBUG
print("[s]"); print("[s]");
#endif
hook_usb_suspend_loop(); hook_usb_suspend_loop();
} }
@ -631,9 +682,19 @@ void hook_early_init(void) {}
__attribute__((weak)) __attribute__((weak))
void hook_late_init(void) {} void hook_late_init(void) {}
static uint8_t _led_stats = 0;
__attribute__((weak)) __attribute__((weak))
void hook_usb_suspend_entry(void) 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 #ifdef SLEEP_LED_ENABLE
sleep_led_enable(); sleep_led_enable();
#endif #endif
@ -644,7 +705,7 @@ void hook_usb_suspend_loop(void)
{ {
suspend_power_down(); suspend_power_down();
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { 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(); suspend_wakeup_init();
#ifdef SLEEP_LED_ENABLE #ifdef SLEEP_LED_ENABLE
sleep_led_disable(); sleep_led_disable();
// NOTE: converters may not accept this
led_set(host_keyboard_leds());
#endif #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;
} }

View File

@ -97,7 +97,7 @@ uint8_t * HIDKeyboard::reportDesc() {
REPORT_COUNT(1), 0x06, REPORT_COUNT(1), 0x06,
REPORT_SIZE(1), 0x08, REPORT_SIZE(1), 0x08,
LOGICAL_MINIMUM(1), 0x00, LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0xFF, LOGICAL_MAXIMUM(2), 0xFF, 0x00,
USAGE_PAGE(1), 0x07, // Key Codes USAGE_PAGE(1), 0x07, // Key Codes
USAGE_MINIMUM(1), 0x00, USAGE_MINIMUM(1), 0x00,
USAGE_MAXIMUM(1), 0xFF, USAGE_MAXIMUM(1), 0xFF,

57
protocol/pbuff.h Normal file
View File

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

View File

@ -184,7 +184,7 @@ static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
0x95, KBD_REPORT_KEYS, // Report Count (), 0x95, KBD_REPORT_KEYS, // Report Count (),
0x75, 0x08, // Report Size (8), 0x75, 0x08, // Report Size (8),
0x15, 0x00, // Logical Minimum (0), 0x15, 0x00, // Logical Minimum (0),
0x25, 0xFF, // Logical Maximum(255), 0x26, 0xFF, 0x00, // Logical Maximum(255),
0x05, 0x07, // Usage Page (Key Codes), 0x05, 0x07, // Usage Page (Key Codes),
0x19, 0x00, // Usage Minimum (0), 0x19, 0x00, // Usage Minimum (0),
0x29, 0xFF, // Usage Maximum (255), 0x29, 0xFF, // Usage Maximum (255),
@ -307,7 +307,7 @@ static const uint8_t PROGMEM extra_hid_report_desc[] = {
0xa1, 0x01, // COLLECTION (Application) 0xa1, 0x01, // COLLECTION (Application)
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
0x15, 0x01, // LOGICAL_MINIMUM (0x1) 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) 0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7)
0x19, 0x01, // USAGE_MINIMUM (0x1) 0x19, 0x01, // USAGE_MINIMUM (0x1)
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) 0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
0x75, 0x10, // REPORT_SIZE (16) 0x75, 0x10, // REPORT_SIZE (16)

View File

@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdbool.h> #include <stdbool.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <util/delay.h> #include <util/delay.h>
#include "pbuff.h"
#include "ps2.h" #include "ps2.h"
#include "ps2_io.h" #include "ps2_io.h"
#include "print.h" #include "print.h"
@ -57,13 +58,6 @@ POSSIBILITY OF SUCH DAMAGE.
uint8_t ps2_error = PS2_ERR_NONE; 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) void ps2_host_init(void)
{ {
idle(); idle();
@ -225,55 +219,3 @@ void ps2_host_set_led(uint8_t led)
ps2_host_send(0xED); ps2_host_send(0xED);
ps2_host_send(led); 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;
}

View File

@ -4,30 +4,14 @@
#include "debug.h" #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) void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{ {
bool is_error = false; ::memcpy(&report, buf, sizeof(report_keyboard_t));
report_keyboard_t *report = (report_keyboard_t *)buf; 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++) { for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
if (IS_ERROR(report->keys[i])) { dprintf(" %02X", report.keys[i]);
is_error = true;
}
dprintf(" %02X", report->keys[i]);
} }
dprint("\r\n"); 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();
} }

View File

@ -2,11 +2,14 @@
#define PARSER_H #define PARSER_H
#include "hid.h" #include "hid.h"
#include "report.h"
class KBDReportParser : public HIDReportParser class KBDReportParser : public HIDReportParser
{ {
public: 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 #endif

View File

@ -20,6 +20,7 @@
#include "timer.h" #include "timer.h"
#include "uart.h" #include "uart.h"
#include "debug.h" #include "debug.h"
#include "suspend.h"
#define UART_BAUD_RATE 115200 #define UART_BAUD_RATE 115200
@ -41,6 +42,23 @@ static void initForUsbConnectivity(void)
sei(); 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) int main(void)
{ {
bool suspended = false; 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) // Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
if (timer_elapsed(last_timer) > 5) { if (timer_elapsed(last_timer) > 5) {
suspended = true; 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 #endif
@ -95,6 +100,8 @@ int main(void)
keyboard_task(); keyboard_task();
} }
vusb_transfer_keyboard(); vusb_transfer_keyboard();
} else if (suspend_wakeup_condition()) {
usb_remote_wakeup();
} }
} }
} }

View File

@ -266,7 +266,7 @@ const PROGMEM uchar keyboard_hid_report[] = {
0x95, 0x06, // Report Count (6), 0x95, 0x06, // Report Count (6),
0x75, 0x08, // Report Size (8), 0x75, 0x08, // Report Size (8),
0x15, 0x00, // Logical Minimum (0), 0x15, 0x00, // Logical Minimum (0),
0x25, 0xFF, // Logical Maximum(255), 0x26, 0xFF, 0x00, // Logical Maximum(255),
0x05, 0x07, // Usage Page (Key Codes), 0x05, 0x07, // Usage Page (Key Codes),
0x19, 0x00, // Usage Minimum (0), 0x19, 0x00, // Usage Minimum (0),
0x29, 0xFF, // Usage Maximum (255), 0x29, 0xFF, // Usage Maximum (255),
@ -336,7 +336,7 @@ const PROGMEM uchar mouse_hid_report[] = {
0xa1, 0x01, // COLLECTION (Application) 0xa1, 0x01, // COLLECTION (Application)
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
0x15, 0x01, // LOGICAL_MINIMUM (0x1) 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) 0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7)
0x19, 0x01, // USAGE_MINIMUM (0x1) 0x19, 0x01, // USAGE_MINIMUM (0x1)
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) 0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
0x75, 0x10, // REPORT_SIZE (16) 0x75, 0x10, // REPORT_SIZE (16)

75
protocol/xt.h Normal file
View File

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

94
protocol/xt_interrupt.c Normal file
View File

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

7
protocol/xt_io.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef XT_IO_H
#define XT_IO_H
bool clock_in(void);
bool data_in(void);
#endif

34
protocol/xt_io_avr.c Normal file
View File

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

View File

@ -420,6 +420,13 @@ flip: $(TARGET).hex
batchisp -hardware usb -device $(MCU) -operation start reset 0 batchisp -hardware usb -device $(MCU) -operation start reset 0
dfu: $(TARGET).hex 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))) ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1)))
dfu-programmer $(MCU) erase --force dfu-programmer $(MCU) erase --force
else else

View File

@ -1,2 +1,2 @@
chibios ChibiOS
chibios-contrib ChibiOS-Contrib

View File

@ -83,8 +83,8 @@ endif
# #
# Imported source files and paths # Imported source files and paths
CHIBIOS ?= $(TMK_DIR)/tool/chibios/chibios CHIBIOS ?= $(TMK_DIR)/tool/chibios/ChibiOS
CHIBIOS_CONTRIB ?= $(TMK_DIR)/tool/chibios/chibios-contrib CHIBIOS_CONTRIB ?= $(TMK_DIR)/tool/chibios/ChibiOS-Contrib
# Startup files. Try a few different locations, for compability with old versions and # Startup files. Try a few different locations, for compability with old versions and
# for things hardware in the contrib repository # for things hardware in the contrib repository
STARTUP_MK = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk STARTUP_MK = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk

View File

@ -23,6 +23,7 @@ CC_FLAGS += \
-fdata-sections \ -fdata-sections \
-fomit-frame-pointer -fomit-frame-pointer
CC_FLAGS += -MMD -MP CC_FLAGS += -MMD -MP
CC_FLAGS += $(OPT_DEFS)
LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs
#LD_FLAGS += -u _printf_float -u _scanf_float #LD_FLAGS += -u _printf_float -u _scanf_float