mastere5f9940
Merge commit '1bc3dd200b023cecf063a0cb3ba347f77f6d759d' into core_updateda03c50
Add note for L/R side bit being ignorede80f3c1
Add in basic documentation for Macro system35e8a76
core: Swap position of PEQL and PENT in unimap00751f1
Merge pull request #406 from 39aldo39/patch-1e50d7de
V-USB remote wakeup4340997
core: Fix typo in definition AC_g958144d
core: Debug print for system and consumer keyse7e1030
core: Fix sleep_led0866323
core: Change matrix_init and matrix_print0dbf73d
core: Add matrix_clear() and default impl.3202ca3
core: Add suspend mode options4cda3aa
core: Fix suspend/wake for converters #3864e15247
core: LUFA_DEBUG_SUART for serial debugb9cf8e7
core: Fix mechanical locking supoort #39012aa0fd
Merge branch 'nemith-master'fccb3fa
core: Fix OPT_DEFS for mbed build2e2d2c8
Merge branch 'master' of github.com:leizzer/tmk_keyboardf1d3634
Change .gitignore for ChibiOS3aab802
core: Fix build config in protocol.mk5e43da0
core: Add short names in unimap7a56998
core: Fix dfu wait in rules.mk6d9c500
Merge branch 'mediakey-fix'08382ac
core: Fix 'make dfu' message78cb04e
Fix OS X Recognizing keyboard as Mouse/Tableta114714
core: 'make dfu' waits for bootloader to startd0a8f13
core: Fix unimap UNIMAP_NO casee17abef
core: Change lufa NKRO report size 16 to 32 bytes375b20f
core: Fix common.mk for build options394fdff
core: Fix unimap layout comment912326c
core: Add unimap support00f4011
core: Fix doc/keymap.md for new keymap frameworkddbd7b4
core: Add default implemenation of keymap read671cacc
core: action codes are action_t struct nowb4fdb27
core: Change chibios repo directory names7daed10
core: Fix keycode.txt90399d7
core: Fix USB remote wakeup on ATmega32U2 #3613677e84
usb_usb: Add multiple keyboard support54d5b26
core: Fix Logical Maximum in report descriptorbd0d372
core: Fix LUFA report descriptor95327b5
Merge pull request #355 from papodaca/XT62bf548
core: change API of adb.c to accept device address3097c9e
Fix function name in host.h836e209
Merge branch 'core_split_160522'3918ea2
Merge commit '20b787fc1284176834cbe7ca2134e4b36bec5828'7f87b11
core: Add comment of register 3 of ADBef6478a
core: Add adb_host_talk()5c665b4
update macro names in bluefruit4f2c5bf
Merge commit '71381457fa1311dfa0b58ba882a96db740640871'53a9c08
Merge pull request #321 from njbair/masterf08a656
core: Fix media/consumer keysd526de8
Clean up wording in keymap example0bb3dbb
Clarify layer precedenced915c75
clarify layer documentation72070d4
ps2_usb: Fix for VUSB configuration170e2dc
Mostly working. Is unstable, will emit bad codes after a while.c8e45b5
core: Actionmap supportaabaa24
Codes appear to be detected correctly, the break codes are broken. git-subtree-dir: tmk_core git-subtree-split:e5f994033c
@@ -7,6 +7,9 @@ Source code is available here: <https://github.com/tmk/tmk_keyboard/tree/core> | |||
Updates | |||
------- | |||
#### 2016/06/26 | |||
Keymap framework was updated. `fn_actions[]` should be defined as `action_t` instead of `uint16_t`. And default code for keymap handling is now included in core you just need define `uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]` and `action_t fn_actions[]`. | |||
#### 2016/02/10 | |||
flabbergast's Chibios protocol was merged from <https://github.com/flabbergast/tmk_keyboard/tree/chibios>. See [protocol/chibios/README.md](protocol/chibios/README.md). Chibios protocol supports Cortex-M such as STM32 and Kinetis. | |||
@@ -1,12 +1,12 @@ | |||
COMMON_DIR = common | |||
SRC += $(COMMON_DIR)/host.c \ | |||
$(COMMON_DIR)/keyboard.c \ | |||
$(COMMON_DIR)/matrix.c \ | |||
$(COMMON_DIR)/action.c \ | |||
$(COMMON_DIR)/action_tapping.c \ | |||
$(COMMON_DIR)/action_macro.c \ | |||
$(COMMON_DIR)/action_layer.c \ | |||
$(COMMON_DIR)/action_util.c \ | |||
$(COMMON_DIR)/keymap.c \ | |||
$(COMMON_DIR)/print.c \ | |||
$(COMMON_DIR)/debug.c \ | |||
$(COMMON_DIR)/util.c \ | |||
@@ -18,58 +18,70 @@ SRC += $(COMMON_DIR)/host.c \ | |||
# Option modules | |||
ifdef BOOTMAGIC_ENABLE | |||
ifeq (yes,$(strip $(UNIMAP_ENABLE))) | |||
SRC += $(COMMON_DIR)/unimap.c | |||
OPT_DEFS += -DUNIMAP_ENABLE | |||
else | |||
ifeq (yes,$(strip $(ACTIONMAP_ENABLE))) | |||
SRC += $(COMMON_DIR)/actionmap.c | |||
OPT_DEFS += -DACTIONMAP_ENABLE | |||
else | |||
SRC += $(COMMON_DIR)/keymap.c | |||
endif | |||
endif | |||
ifeq (yes,$(strip $(BOOTMAGIC_ENABLE))) | |||
SRC += $(COMMON_DIR)/bootmagic.c | |||
SRC += $(COMMON_DIR)/avr/eeconfig.c | |||
OPT_DEFS += -DBOOTMAGIC_ENABLE | |||
endif | |||
ifdef MOUSEKEY_ENABLE | |||
ifeq (yes,$(strip $(MOUSEKEY_ENABLE))) | |||
SRC += $(COMMON_DIR)/mousekey.c | |||
OPT_DEFS += -DMOUSEKEY_ENABLE | |||
OPT_DEFS += -DMOUSE_ENABLE | |||
endif | |||
ifdef EXTRAKEY_ENABLE | |||
ifeq (yes,$(strip $(EXTRAKEY_ENABLE))) | |||
OPT_DEFS += -DEXTRAKEY_ENABLE | |||
endif | |||
ifdef CONSOLE_ENABLE | |||
ifeq (yes,$(strip $(CONSOLE_ENABLE))) | |||
OPT_DEFS += -DCONSOLE_ENABLE | |||
else | |||
OPT_DEFS += -DNO_PRINT | |||
OPT_DEFS += -DNO_DEBUG | |||
endif | |||
ifdef COMMAND_ENABLE | |||
ifeq (yes,$(strip $(COMMAND_ENABLE))) | |||
SRC += $(COMMON_DIR)/command.c | |||
OPT_DEFS += -DCOMMAND_ENABLE | |||
endif | |||
ifdef NKRO_ENABLE | |||
ifeq (yes,$(strip $(NKRO_ENABLE))) | |||
OPT_DEFS += -DNKRO_ENABLE | |||
endif | |||
ifdef USB_6KRO_ENABLE | |||
ifeq (yes,$(strip $(USB_6KRO_ENABLE))) | |||
OPT_DEFS += -DUSB_6KRO_ENABLE | |||
endif | |||
ifdef KEYBOARD_LOCK_ENABLE | |||
ifeq (yes, $(strip $(KEYBOARD_LOCK_ENABLE))) | |||
OPT_DEFS += -DKEYBOARD_LOCK_ENABLE | |||
endif | |||
ifdef SLEEP_LED_ENABLE | |||
ifeq (yes,$(strip $(SLEEP_LED_ENABLE))) | |||
SRC += $(COMMON_DIR)/avr/sleep_led.c | |||
OPT_DEFS += -DSLEEP_LED_ENABLE | |||
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN | |||
endif | |||
ifdef BACKLIGHT_ENABLE | |||
ifeq (yes,$(strip $(BACKLIGHT_ENABLE))) | |||
SRC += $(COMMON_DIR)/backlight.c | |||
OPT_DEFS += -DBACKLIGHT_ENABLE | |||
endif | |||
ifdef KEYMAP_SECTION_ENABLE | |||
ifeq (yes,$(strip $(KEYMAP_SECTION_ENABLE))) | |||
OPT_DEFS += -DKEYMAP_SECTION_ENABLE | |||
ifeq ($(strip $(MCU)),atmega32u2) |
@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#include "action_util.h" | |||
#include "action.h" | |||
#include "hook.h" | |||
#include "wait.h" | |||
#ifdef DEBUG_ACTION | |||
#include "debug.h" | |||
@@ -365,6 +366,7 @@ void register_code(uint8_t code) | |||
#endif | |||
add_key(KC_CAPSLOCK); | |||
send_keyboard_report(); | |||
wait_ms(100); | |||
del_key(KC_CAPSLOCK); | |||
send_keyboard_report(); | |||
} | |||
@@ -375,6 +377,7 @@ void register_code(uint8_t code) | |||
#endif | |||
add_key(KC_NUMLOCK); | |||
send_keyboard_report(); | |||
wait_ms(100); | |||
del_key(KC_NUMLOCK); | |||
send_keyboard_report(); | |||
} | |||
@@ -385,6 +388,7 @@ void register_code(uint8_t code) | |||
#endif | |||
add_key(KC_SCROLLLOCK); | |||
send_keyboard_report(); | |||
wait_ms(100); | |||
del_key(KC_SCROLLLOCK); | |||
send_keyboard_report(); | |||
} | |||
@@ -440,6 +444,7 @@ void unregister_code(uint8_t code) | |||
#endif | |||
add_key(KC_CAPSLOCK); | |||
send_keyboard_report(); | |||
wait_ms(100); | |||
del_key(KC_CAPSLOCK); | |||
send_keyboard_report(); | |||
} | |||
@@ -450,6 +455,7 @@ void unregister_code(uint8_t code) | |||
#endif | |||
add_key(KC_NUMLOCK); | |||
send_keyboard_report(); | |||
wait_ms(100); | |||
del_key(KC_NUMLOCK); | |||
send_keyboard_report(); | |||
} | |||
@@ -460,6 +466,7 @@ void unregister_code(uint8_t code) | |||
#endif | |||
add_key(KC_SCROLLLOCK); | |||
send_keyboard_report(); | |||
wait_ms(100); | |||
del_key(KC_SCROLLLOCK); | |||
send_keyboard_report(); | |||
} |
@@ -181,9 +181,9 @@ typedef union { | |||
/* action utility */ | |||
#define ACTION_NO 0 | |||
#define ACTION_TRANSPARENT 1 | |||
#define ACTION(kind, param) ((kind)<<12 | (param)) | |||
#define ACTION_NO { .code = 0 } | |||
#define ACTION_TRANSPARENT { .code = 1 } | |||
#define ACTION(kind, param) { .code = ((kind)<<12 | (param)) } | |||
/* | |||
@@ -251,8 +251,8 @@ enum layer_pram_tap_op { | |||
OP_OFF_ON, | |||
OP_SET_CLEAR, | |||
}; | |||
#define ACTION_LAYER_BITOP(op, part, bits, on) (ACT_LAYER<<12 | (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f)) | |||
#define ACTION_LAYER_TAP(layer, key) (ACT_LAYER_TAP<<12 | (layer)<<8 | (key)) | |||
#define ACTION_LAYER_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f)) | |||
#define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer)<<8 | (key)) | |||
/* Default Layer */ | |||
#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer)/4, 1<<((layer)%4)) | |||
#define ACTION_DEFAULT_LAYER_TOGGLE(layer) ACTION_DEFAULT_LAYER_BIT_XOR((layer)/4, 1<<((layer)%4)) |
@@ -117,8 +117,7 @@ void layer_debug(void) | |||
action_t layer_switch_get_action(keypos_t key) | |||
{ | |||
action_t action; | |||
action.code = ACTION_TRANSPARENT; | |||
action_t action = ACTION_TRANSPARENT; | |||
#ifndef NO_ACTION_LAYER | |||
uint32_t layers = layer_state | default_layer_state; | |||
@@ -126,7 +125,7 @@ action_t layer_switch_get_action(keypos_t key) | |||
for (int8_t i = 31; i >= 0; i--) { | |||
if (layers & (1UL<<i)) { | |||
action = action_for_key(i, key); | |||
if (action.code != ACTION_TRANSPARENT) { | |||
if (action.code != (action_t)ACTION_TRANSPARENT.code) { | |||
return action; | |||
} | |||
} |
@@ -0,0 +1,44 @@ | |||
/* | |||
Copyright 2015 Jun Wako <[email protected]> | |||
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) | |||
{ | |||
} |
@@ -0,0 +1,455 @@ | |||
/* | |||
Copyright 2015 Jun Wako <[email protected]> | |||
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 |
@@ -45,10 +45,17 @@ void sleep_led_disable(void) | |||
TIMSK1 &= ~_BV(OCIE1A); | |||
} | |||
void sleep_led_toggle(void) | |||
__attribute__ ((weak)) | |||
void sleep_led_on(void) | |||
{ | |||
/* Disable Compare Match Interrupt */ | |||
TIMSK1 ^= _BV(OCIE1A); | |||
led_set(1<<USB_LED_CAPS_LOCK); | |||
} | |||
__attribute__ ((weak)) | |||
void sleep_led_off(void) | |||
{ | |||
led_set(0); | |||
} | |||
@@ -86,10 +93,10 @@ ISR(TIMER1_COMPA_vect) | |||
// LED on | |||
if (timer.pwm.count == 0) { | |||
led_set(1<<USB_LED_CAPS_LOCK); | |||
sleep_led_on(); | |||
} | |||
// LED off | |||
if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) { | |||
led_set(0); | |||
sleep_led_off(); | |||
} | |||
} |
@@ -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 |
@@ -0,0 +1,8 @@ | |||
#ifndef SUART | |||
#define SUART | |||
void xmit(uint8_t); | |||
uint8_t rcvr(void); | |||
uint8_t recv(void); | |||
#endif /* SUART */ |
@@ -30,16 +30,6 @@ __asm__ __volatile__ ( \ | |||
) | |||
void suspend_idle(uint8_t time) | |||
{ | |||
cli(); | |||
set_sleep_mode(SLEEP_MODE_IDLE); | |||
sleep_enable(); | |||
sei(); | |||
sleep_cpu(); | |||
sleep_disable(); | |||
} | |||
/* Power down MCU with watchdog timer | |||
* wdto: watchdog timer timeout defined in <avr/wdt.h> | |||
* WDTO_15MS | |||
@@ -80,13 +70,45 @@ static void power_down(uint8_t wdto) | |||
wdt_disable(); | |||
} | |||
static void standby(void) | |||
{ | |||
set_sleep_mode(SLEEP_MODE_STANDBY); | |||
sleep_enable(); | |||
sei(); | |||
sleep_cpu(); | |||
sleep_disable(); | |||
} | |||
static void idle(void) | |||
{ | |||
set_sleep_mode(SLEEP_MODE_IDLE); | |||
sleep_enable(); | |||
sei(); | |||
sleep_cpu(); | |||
sleep_disable(); | |||
} | |||
void suspend_idle(uint8_t time) | |||
{ | |||
idle(); | |||
} | |||
void suspend_power_down(void) | |||
{ | |||
#ifdef NO_SUSPEND_POWER_DOWN | |||
; | |||
#elif defined(SUSPEND_MODE_NOPOWERSAVE) | |||
; | |||
#elif defined(SUSPEND_MODE_STANDBY) | |||
standby(); | |||
#elif defined(SUSPEND_MODE_IDLE) | |||
idle(); | |||
#else | |||
power_down(WDTO_15MS); | |||
#endif | |||
} | |||
__attribute__ ((weak)) void matrix_power_up(void) {} | |||
__attribute__ ((weak)) void matrix_power_down(void) {} | |||
bool suspend_wakeup_condition(void) | |||
{ | |||
matrix_power_up(); | |||
@@ -102,6 +124,7 @@ bool suspend_wakeup_condition(void) | |||
void suspend_wakeup_init(void) | |||
{ | |||
// clear keyboard state | |||
matrix_clear(); | |||
clear_keyboard(); | |||
#ifdef BACKLIGHT_ENABLE | |||
backlight_init(); |
@@ -5,6 +5,7 @@ | |||
#include "bootloader.h" | |||
#include "debug.h" | |||
#include "keymap.h" | |||
#include "actionmap.h" | |||
#include "host.h" | |||
#include "action_layer.h" | |||
#include "eeconfig.h" | |||
@@ -27,17 +28,17 @@ void bootmagic(void) | |||
print("done.\n"); | |||
/* bootmagic skip */ | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SKIP)) { | |||
return; | |||
} | |||
/* eeconfig clear */ | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EEPROM_CLEAR)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_EEPROM_CLEAR)) { | |||
eeconfig_init(); | |||
} | |||
/* bootloader */ | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_BOOTLOADER)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_BOOTLOADER)) { | |||
bootloader_jump(); | |||
} | |||
@@ -46,12 +47,12 @@ void bootmagic(void) | |||
/* debug enable */ | |||
debug_config.raw = eeconfig_read_debug(); | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_ENABLE)) { | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MATRIX)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_ENABLE)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_MATRIX)) { | |||
debug_config.matrix = !debug_config.matrix; | |||
} else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) { | |||
} else if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) { | |||
debug_config.keyboard = !debug_config.keyboard; | |||
} else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MOUSE)) { | |||
} else if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_MOUSE)) { | |||
debug_config.mouse = !debug_config.mouse; | |||
} else { | |||
debug_config.enable = !debug_config.enable; | |||
@@ -61,28 +62,28 @@ void bootmagic(void) | |||
/* keymap config */ | |||
keymap_config.raw = eeconfig_read_keymap(); | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) { | |||
keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock; | |||
} | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) { | |||
keymap_config.capslock_to_control = !keymap_config.capslock_to_control; | |||
} | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) { | |||
keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; | |||
} | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) { | |||
keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui; | |||
} | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_NO_GUI)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_NO_GUI)) { | |||
keymap_config.no_gui = !keymap_config.no_gui; | |||
} | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) { | |||
keymap_config.swap_grave_esc = !keymap_config.swap_grave_esc; | |||
} | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) { | |||
keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace; | |||
} | |||
if (bootmagic_scan_keycode(BOOTMAGIC_HOST_NKRO)) { | |||
if (bootmagic_scan_key(BOOTMAGIC_HOST_NKRO)) { | |||
keymap_config.nkro = !keymap_config.nkro; | |||
} | |||
eeconfig_write_keymap(keymap_config.raw); | |||
@@ -93,14 +94,14 @@ void bootmagic(void) | |||
/* default layer */ | |||
uint8_t default_layer = 0; | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); } | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) { default_layer |= (1<<1); } | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) { default_layer |= (1<<2); } | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) { default_layer |= (1<<3); } | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) { default_layer |= (1<<4); } | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) { default_layer |= (1<<5); } | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) { default_layer |= (1<<6); } | |||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) { default_layer |= (1<<7); } | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); } | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) { default_layer |= (1<<1); } | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) { default_layer |= (1<<2); } | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) { default_layer |= (1<<3); } | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) { default_layer |= (1<<4); } | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) { default_layer |= (1<<5); } | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) { default_layer |= (1<<6); } | |||
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) { default_layer |= (1<<7); } | |||
if (default_layer) { | |||
eeconfig_write_default_layer(default_layer); | |||
default_layer_set((uint32_t)default_layer); | |||
@@ -110,13 +111,22 @@ void bootmagic(void) | |||
} | |||
} | |||
static bool scan_keycode(uint8_t keycode) | |||
static bool scan_key(uint16_t code) | |||
{ | |||
for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | |||
matrix_row_t matrix_row = matrix_get_row(r); | |||
for (uint8_t c = 0; c < MATRIX_COLS; c++) { | |||
if (matrix_row & ((matrix_row_t)1<<c)) { | |||
if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) { | |||
// read key from Layer 0 | |||
action_t action = action_for_key(0, (keypos_t){ .row = r, .col = c }); | |||
if (action.code == code || | |||
((action.kind.id == ACT_LMODS || | |||
action.kind.id == ACT_RMODS || | |||
action.kind.id == ACT_LMODS_TAP || | |||
action.kind.id == ACT_RMODS_TAP || | |||
action.kind.id == ACT_LAYER_TAP || | |||
action.kind.id == ACT_LAYER_TAP_EXT) && | |||
action.key.code == code)) { | |||
return true; | |||
} | |||
} | |||
@@ -125,9 +135,9 @@ static bool scan_keycode(uint8_t keycode) | |||
return false; | |||
} | |||
bool bootmagic_scan_keycode(uint8_t keycode) | |||
bool bootmagic_scan_key(uint16_t code) | |||
{ | |||
if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false; | |||
if (!scan_key(BOOTMAGIC_KEY_SALT)) return false; | |||
return scan_keycode(keycode); | |||
return scan_key(code); | |||
} |
@@ -95,6 +95,6 @@ | |||
void bootmagic(void); | |||
bool bootmagic_scan_keycode(uint8_t keycode); | |||
bool bootmagic_scan_key(uint16_t action); | |||
#endif |
@@ -182,14 +182,22 @@ static bool command_common(uint8_t code) | |||
{ | |||
#ifdef KEYBOARD_LOCK_ENABLE | |||
static host_driver_t *host_driver = 0; | |||
#endif | |||
#ifdef SLEEP_LED_ENABLE | |||
static bool sleep_led_test = false; | |||
#endif | |||
switch (code) { | |||
#ifdef SLEEP_LED_ENABLE | |||
case KC_Z: | |||
// test breathing sleep LED | |||
print("Sleep LED test\n"); | |||
sleep_led_toggle(); | |||
led_set(host_keyboard_leds()); | |||
if (sleep_led_test) { | |||
sleep_led_disable(); | |||
led_set(host_keyboard_leds()); | |||
} else { | |||
sleep_led_enable(); | |||
} | |||
sleep_led_test = !sleep_led_test; | |||
break; | |||
#endif | |||
#ifdef BOOTMAGIC_ENABLE |
@@ -54,7 +54,7 @@ void host_keyboard_send(report_keyboard_t *report) | |||
(*driver->send_keyboard)(report); | |||
if (debug_keyboard) { | |||
dprint("keyboard_report: "); | |||
dprint("keyboard: "); | |||
for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) { | |||
dprintf("%02X ", report->raw[i]); | |||
} | |||
@@ -75,6 +75,10 @@ void host_system_send(uint16_t report) | |||
if (!driver) return; | |||
(*driver->send_system)(report); | |||
if (debug_keyboard) { | |||
dprintf("system: %04X\n", report); | |||
} | |||
} | |||
void host_consumer_send(uint16_t report) | |||
@@ -84,9 +88,13 @@ void host_consumer_send(uint16_t report) | |||
if (!driver) return; | |||
(*driver->send_consumer)(report); | |||
if (debug_keyboard) { | |||
dprintf("consumer: %04X\n", report); | |||
} | |||
} | |||
uint16_t host_last_sysytem_report(void) | |||
uint16_t host_last_system_report(void) | |||
{ | |||
return last_system_report; | |||
} |
@@ -47,7 +47,7 @@ void host_mouse_send(report_mouse_t *report); | |||
void host_system_send(uint16_t data); | |||
void host_consumer_send(uint16_t data); | |||
uint16_t host_last_sysytem_report(void); | |||
uint16_t host_last_system_report(void); | |||
uint16_t host_last_consumer_report(void); | |||
#ifdef __cplusplus |
@@ -63,7 +63,6 @@ static bool has_ghost_in_row(uint8_t row) | |||
#endif | |||
__attribute__ ((weak)) void matrix_setup(void) {} | |||
void keyboard_setup(void) | |||
{ | |||
matrix_setup(); |
@@ -153,8 +153,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#define KC_MRWD KC_MEDIA_REWIND | |||
#define KC_MSTP KC_MEDIA_STOP | |||
#define KC_MPLY KC_MEDIA_PLAY_PAUSE | |||
#define KC_MSEL KC_MEDIA_SELECT | |||
#define KC_EJCT KC_MEDIA_EJECT | |||
#define KC_MSEL KC_MEDIA_SELECT | |||
#define KC_MAIL KC_MAIL | |||
#define KC_CALC KC_CALCULATOR | |||
#define KC_MYCM KC_MY_COMPUTER | |||
@@ -420,10 +420,12 @@ enum internal_special_keycodes { | |||
KC_AUDIO_VOL_DOWN, | |||
KC_MEDIA_NEXT_TRACK, | |||
KC_MEDIA_PREV_TRACK, | |||
KC_MEDIA_FAST_FORWARD, | |||
KC_MEDIA_REWIND, | |||
KC_MEDIA_STOP, | |||
KC_MEDIA_PLAY_PAUSE, | |||
KC_MEDIA_SELECT, | |||
KC_MEDIA_EJECT, | |||
KC_MEDIA_SELECT, | |||
KC_MAIL, | |||
KC_CALCULATOR, | |||
KC_MY_COMPUTER, | |||
@@ -433,9 +435,7 @@ enum internal_special_keycodes { | |||
KC_WWW_FORWARD, | |||
KC_WWW_STOP, | |||
KC_WWW_REFRESH, | |||
KC_WWW_FAVORITES, | |||
KC_MEDIA_FAST_FORWARD, | |||
KC_MEDIA_REWIND, /* 0xBC */ | |||
KC_WWW_FAVORITES, /* 0xBC */ | |||
/* Jump to bootloader */ | |||
KC_BOOTLOADER = 0xBF, |
@@ -1,5 +1,5 @@ | |||
/* | |||
Copyright 2013 Jun Wako <[email protected]> | |||
Copyright 2013,2016 Jun Wako <[email protected]> | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
@@ -23,6 +23,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#include "wait.h" | |||
#include "debug.h" | |||
#include "bootloader.h" | |||
#if defined(__AVR__) | |||
#include <avr/pgmspace.h> | |||
#endif | |||
#ifdef BOOTMAGIC_ENABLE | |||
extern keymap_config_t keymap_config; | |||
@@ -32,6 +35,7 @@ static action_t keycode_to_action(uint8_t keycode); | |||
/* converts key to action */ | |||
__attribute__ ((weak)) | |||
action_t action_for_key(uint8_t layer, keypos_t key) | |||
{ | |||
uint8_t keycode = keymap_key_to_keycode(layer, key); | |||
@@ -53,7 +57,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
case KC_LALT: | |||
if (keymap_config.swap_lalt_lgui) { | |||
if (keymap_config.no_gui) { | |||
return keycode_to_action(ACTION_NO); | |||
return keycode_to_action(KC_NO); | |||
} | |||
return keycode_to_action(KC_LGUI); | |||
} | |||
@@ -63,13 +67,13 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
return keycode_to_action(KC_LALT); | |||
} | |||
if (keymap_config.no_gui) { | |||
return keycode_to_action(ACTION_NO); | |||
return keycode_to_action(KC_NO); | |||
} | |||
return keycode_to_action(KC_LGUI); | |||
case KC_RALT: | |||
if (keymap_config.swap_ralt_rgui) { | |||
if (keymap_config.no_gui) { | |||
return keycode_to_action(ACTION_NO); | |||
return keycode_to_action(KC_NO); | |||
} | |||
return keycode_to_action(KC_RGUI); | |||
} | |||
@@ -79,7 +83,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
return keycode_to_action(KC_RALT); | |||
} | |||
if (keymap_config.no_gui) { | |||
return keycode_to_action(ACTION_NO); | |||
return keycode_to_action(KC_NO); | |||
} | |||
return keycode_to_action(KC_RGUI); | |||
case KC_GRAVE: | |||
@@ -133,23 +137,22 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
/* translates keycode to action */ | |||
static action_t keycode_to_action(uint8_t keycode) | |||
{ | |||
action_t action = {}; | |||
switch (keycode) { | |||
case KC_A ... KC_EXSEL: | |||
case KC_LCTRL ... KC_RGUI: | |||
action.code = ACTION_KEY(keycode); | |||
return (action_t)ACTION_KEY(keycode); | |||
break; | |||
case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: | |||
action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); | |||
return (action_t)ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); | |||
break; | |||
case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: | |||
action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); | |||
return (action_t)ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); | |||
break; | |||
case KC_MS_UP ... KC_MS_ACCEL2: | |||
action.code = ACTION_MOUSEKEY(keycode); | |||
return (action_t)ACTION_MOUSEKEY(keycode); | |||
break; | |||
case KC_TRNS: | |||
action.code = ACTION_TRANSPARENT; | |||
return (action_t)ACTION_TRANSPARENT; | |||
break; | |||
case KC_BOOTLOADER: | |||
clear_keyboard(); | |||
@@ -157,10 +160,10 @@ static action_t keycode_to_action(uint8_t keycode) | |||
bootloader_jump(); // not return | |||
break; | |||
default: | |||
action.code = ACTION_NO; | |||
return (action_t)ACTION_NO; | |||
break; | |||
} | |||
return action; | |||
return (action_t)ACTION_NO; | |||
} | |||
@@ -170,6 +173,28 @@ static action_t keycode_to_action(uint8_t keycode) | |||
* Legacy keymap support | |||
* Consider using new keymap API instead. | |||
*/ | |||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | |||
extern const uint8_t fn_layer[]; | |||
extern const uint8_t fn_keycode[]; | |||
__attribute__ ((weak)) | |||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | |||
{ | |||
return pgm_read_byte(&keymaps[(layer)][(row)][(col)]); | |||
} | |||
__attribute__ ((weak)) | |||
uint8_t keymap_fn_layer(uint8_t index) | |||
{ | |||
return pgm_read_byte(&fn_layer[index]); | |||
} | |||
__attribute__ ((weak)) | |||
uint8_t keymap_fn_keycode(uint8_t index) | |||
{ | |||
return pgm_read_byte(&fn_keycode[index]); | |||
} | |||
__attribute__ ((weak)) | |||
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key) | |||
{ | |||
@@ -181,21 +206,47 @@ uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key) | |||
__attribute__ ((weak)) | |||
action_t keymap_fn_to_action(uint8_t keycode) | |||
{ | |||
action_t action = { .code = ACTION_NO }; | |||
switch (keycode) { | |||
case KC_FN0 ... KC_FN31: | |||
{ | |||
uint8_t layer = keymap_fn_layer(FN_INDEX(keycode)); | |||
uint8_t key = keymap_fn_keycode(FN_INDEX(keycode)); | |||
if (key) { | |||
action.code = ACTION_LAYER_TAP_KEY(layer, key); | |||
return (action_t)ACTION_LAYER_TAP_KEY(layer, key); | |||
} else { | |||
action.code = ACTION_LAYER_MOMENTARY(layer); | |||
return (action_t)ACTION_LAYER_MOMENTARY(layer); | |||
} | |||
} | |||
return action; | |||
return (action_t)ACTION_NO; | |||
default: | |||
return action; | |||
return (action_t)ACTION_NO; | |||
} | |||
} | |||
#else | |||
/* user keymaps should be defined somewhere */ | |||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | |||
extern const action_t fn_actions[]; | |||
__attribute__ ((weak)) | |||
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key) | |||
{ | |||
#if defined(__AVR__) | |||
return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]); | |||
#else | |||
return keymaps[(layer)][(key.row)][(key.col)]; | |||
#endif | |||
} | |||
__attribute__ ((weak)) | |||
action_t keymap_fn_to_action(uint8_t keycode) | |||
{ | |||
#if defined(__AVR__) | |||
return (action_t)pgm_read_word(&fn_actions[FN_INDEX(keycode)]); | |||
#else | |||
return fn_actions[FN_INDEX(keycode)]; | |||
#endif | |||
} | |||
#endif |
@@ -0,0 +1,95 @@ | |||
/* | |||
Copyright 2016 Jun Wako <[email protected]> | |||
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) {} |
@@ -32,6 +32,10 @@ typedef uint32_t matrix_row_t; | |||
#error "MATRIX_COLS: invalid value" | |||
#endif | |||
#if (MATRIX_ROWS > 255) | |||
#error "MATRIX_ROWS must not exceed 255" | |||
#endif | |||
#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1<<col)) | |||
@@ -57,7 +61,12 @@ bool matrix_is_on(uint8_t row, uint8_t col); | |||
matrix_row_t matrix_get_row(uint8_t row); | |||
/* print matrix for debug */ | |||
void matrix_print(void); | |||
/* clear matrix */ | |||
void matrix_clear(void); | |||
#ifdef MATRIX_HAS_GHOST | |||
bool matrix_has_ghost_in_row(uint8_t row); | |||
#endif | |||
/* power control */ | |||
void matrix_power_up(void); |
@@ -46,25 +46,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#define TRANSPORT_STOP_EJECT 0x00CC | |||
#define TRANSPORT_PLAY_PAUSE 0x00CD | |||
/* application launch */ | |||
#define AL_CC_CONFIG 0x0183 | |||
#define AL_EMAIL 0x018A | |||
#define AL_CALCULATOR 0x0192 | |||
#define AL_LOCAL_BROWSER 0x0194 | |||
#define APPLAUNCH_CC_CONFIG 0x0183 | |||
#define APPLAUNCH_EMAIL 0x018A | |||
#define APPLAUNCH_CALCULATOR 0x0192 | |||
#define APPLAUNCH_LOCAL_BROWSER 0x0194 | |||
/* application control */ | |||
#define AC_SEARCH 0x0221 | |||
#define AC_HOME 0x0223 | |||
#define AC_BACK 0x0224 | |||
#define AC_FORWARD 0x0225 | |||
#define AC_STOP 0x0226 | |||
#define AC_REFRESH 0x0227 | |||
#define AC_BOOKMARKS 0x022A | |||
#define APPCONTROL_SEARCH 0x0221 | |||
#define APPCONTROL_HOME 0x0223 | |||
#define APPCONTROL_BACK 0x0224 | |||
#define APPCONTROL_FORWARD 0x0225 | |||
#define APPCONTROL_STOP 0x0226 | |||
#define APPCONTROL_REFRESH 0x0227 | |||
#define APPCONTROL_BOOKMARKS 0x022A | |||
/* supplement for Bluegiga iWRAP HID(not supported by Windows?) */ | |||
#define AL_LOCK 0x019E | |||
#define APPLAUNCH_LOCK 0x019E | |||
#define TRANSPORT_RECORD 0x00B2 | |||
#define TRANSPORT_FAST_FORWARD 0x00B3 | |||
#define TRANSPORT_REWIND 0x00B4 | |||
#define TRANSPORT_EJECT 0x00B8 | |||
#define AC_MINIMIZE 0x0206 | |||
#define APPCONTROL_MINIMIZE 0x0206 | |||
/* Generic Desktop Page(0x01) - system power control */ | |||
#define SYSTEM_POWER_DOWN 0x0081 | |||
@@ -159,27 +159,27 @@ typedef struct { | |||
/* keycode to consumer usage */ | |||
#define KEYCODE2CONSUMER(key) \ | |||
(key == KC_AUDIO_MUTE ? AUDIO_MUTE : \ | |||
(key == KC_AUDIO_VOL_UP ? AUDIO_VOL_UP : \ | |||
(key == KC_AUDIO_VOL_DOWN ? AUDIO_VOL_DOWN : \ | |||
(key == KC_MEDIA_NEXT_TRACK ? TRANSPORT_NEXT_TRACK : \ | |||
(key == KC_MEDIA_PREV_TRACK ? TRANSPORT_PREV_TRACK : \ | |||
(key == KC_MEDIA_FAST_FORWARD ? TRANSPORT_FAST_FORWARD : \ | |||
(key == KC_MEDIA_REWIND ? TRANSPORT_REWIND : \ | |||
(key == KC_MEDIA_STOP ? TRANSPORT_STOP : \ | |||
(key == KC_MEDIA_EJECT ? TRANSPORT_STOP_EJECT : \ | |||
(key == KC_MEDIA_PLAY_PAUSE ? TRANSPORT_PLAY_PAUSE : \ | |||
(key == KC_MEDIA_SELECT ? AL_CC_CONFIG : \ | |||
(key == KC_MAIL ? AL_EMAIL : \ | |||
(key == KC_CALCULATOR ? AL_CALCULATOR : \ | |||
(key == KC_MY_COMPUTER ? AL_LOCAL_BROWSER : \ | |||
(key == KC_WWW_SEARCH ? AC_SEARCH : \ | |||
(key == KC_WWW_HOME ? AC_HOME : \ | |||
(key == KC_WWW_BACK ? AC_BACK : \ | |||
(key == KC_WWW_FORWARD ? AC_FORWARD : \ | |||
(key == KC_WWW_STOP ? AC_STOP : \ | |||
(key == KC_WWW_REFRESH ? AC_REFRESH : \ | |||
(key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0))))))))))))))))))))) | |||
(key == KC_AUDIO_MUTE ? AUDIO_MUTE : \ | |||
(key == KC_AUDIO_VOL_UP ? AUDIO_VOL_UP : \ | |||
(key == KC_AUDIO_VOL_DOWN ? AUDIO_VOL_DOWN : \ | |||
(key == KC_MEDIA_NEXT_TRACK ? TRANSPORT_NEXT_TRACK : \ | |||
(key == KC_MEDIA_PREV_TRACK ? TRANSPORT_PREV_TRACK : \ | |||
(key == KC_MEDIA_FAST_FORWARD ? TRANSPORT_FAST_FORWARD : \ | |||
(key == KC_MEDIA_REWIND ? TRANSPORT_REWIND : \ | |||
(key == KC_MEDIA_STOP ? TRANSPORT_STOP : \ | |||
(key == KC_MEDIA_EJECT ? TRANSPORT_STOP_EJECT : \ | |||
(key == KC_MEDIA_PLAY_PAUSE ? TRANSPORT_PLAY_PAUSE : \ | |||
(key == KC_MEDIA_SELECT ? APPLAUNCH_CC_CONFIG : \ | |||
(key == KC_MAIL ? APPLAUNCH_EMAIL : \ | |||
(key == KC_CALCULATOR ? APPLAUNCH_CALCULATOR : \ | |||
(key == KC_MY_COMPUTER ? APPLAUNCH_LOCAL_BROWSER : \ | |||
(key == KC_WWW_SEARCH ? APPCONTROL_SEARCH : \ | |||
(key == KC_WWW_HOME ? APPCONTROL_HOME : \ | |||
(key == KC_WWW_BACK ? APPCONTROL_BACK : \ | |||
(key == KC_WWW_FORWARD ? APPCONTROL_FORWARD : \ | |||
(key == KC_WWW_STOP ? APPCONTROL_STOP : \ | |||
(key == KC_WWW_REFRESH ? APPCONTROL_REFRESH : \ | |||
(key == KC_WWW_FAVORITES ? APPCONTROL_BOOKMARKS : 0))))))))))))))))))))) | |||
#ifdef __cplusplus | |||
} |
@@ -2,20 +2,10 @@ | |||
#define SLEEP_LED_H | |||
#ifdef SLEEP_LED_ENABLE | |||
void sleep_led_init(void); | |||
void sleep_led_enable(void); | |||
void sleep_led_disable(void); | |||
void sleep_led_toggle(void); | |||
#else | |||
#define sleep_led_init() | |||
#define sleep_led_enable() | |||
#define sleep_led_disable() | |||
#define sleep_led_toggle() | |||
#endif | |||
void sleep_led_on(void); | |||
void sleep_led_off(void); | |||
#endif |
@@ -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) | |||
{ | |||
} |
@@ -0,0 +1,272 @@ | |||
/* | |||
Copyright 2016 Jun Wako <[email protected]> | |||
*/ | |||
#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 |
@@ -28,6 +28,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#define XSTR(s) #s | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
uint8_t bitpop(uint8_t bits); | |||
uint8_t bitpop16(uint16_t bits); | |||
uint8_t bitpop32(uint32_t bits); | |||
@@ -40,4 +44,8 @@ uint8_t bitrev(uint8_t bits); | |||
uint16_t bitrev16(uint16_t bits); | |||
uint32_t bitrev32(uint32_t bits); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif |
@@ -1,7 +1,7 @@ | |||
Keycode Symbol Table | |||
==================== | |||
Keycodes are defined in `common/keycode.h`. | |||
Range of 00-A4 and E0-E7 are identical with HID Usage: | |||
Range of 00-A4 and E0-E7 are identical with HID Usage of Keyboard/Keypad Page(0x07): | |||
<http://www.usb.org/developers/devclass_docs/Hut1_11.pdf> | |||
Virtual keycodes are defined out of above range to support special actions. | |||
@@ -186,30 +186,35 @@ KC_RGUI E7 Keyboard Right GUI(Windows/Apple/Meta key | |||
/* | |||
* Virtual keycodes | |||
*/ | |||
/* System Control */ | |||
/* Generic Desktop Page(0x01) - System Control */ | |||
KC_SYSTEM_POWER KC_PWR System Power Down | |||
KC_SYSTEM_SLEEP KC_SLEP System Sleep | |||
KC_SYSTEM_WAKE KC_WAKE System Wake | |||
/* Consumer Page */ | |||
KC_AUDIO_MUTE KC_MUTE | |||
KC_AUDIO_VOL_UP KC_VOLU | |||
KC_AUDIO_VOL_DOWN KC_VOLD | |||
KC_MEDIA_NEXT_TRACK KC_MNXT | |||
KC_MEDIA_PREV_TRACK KC_MPRV | |||
KC_MEDIA_STOP KC_MSTP | |||
KC_MEDIA_PLAY_PAUSE KC_MPLY | |||
KC_MEDIA_SELECT KC_MSEL | |||
KC_MAIL KC_MAIL | |||
KC_CALCULATOR KC_CALC | |||
KC_MY_COMPUTER KC_MYCM | |||
KC_WWW_SEARCH KC_WSCH | |||
KC_WWW_HOME KC_WHOM | |||
KC_WWW_BACK KC_WBAK | |||
KC_WWW_FORWARD KC_WFWD | |||
KC_WWW_STOP KC_WSTP | |||
KC_WWW_REFRESH KC_WREF | |||
KC_WWW_FAVORITES KC_WFAV | |||
/* Mousekey */ | |||
/* Consumer Page(0x07) */ | |||
KC_AUDIO_MUTE KC_MUTE Mute | |||
KC_AUDIO_VOL_UP KC_VOLU Volume Increment | |||
KC_AUDIO_VOL_DOWN KC_VOLD Volume Decrement | |||
KC_MEDIA_NEXT_TRACK KC_MNXT Scan Next Track | |||
KC_MEDIA_PREV_TRACK KC_MPRV Scan Previous Track | |||
KC_MEDIA_STOP KC_MSTP Stop | |||
KC_MEDIA_FAST_FORWARD KC_MFFD Fast Forward | |||
KC_MEDIA_REWIND KC_MRWD Rewind | |||
KC_MEDIA_PLAY_PAUSE KC_MPLY Play/Pause | |||
KC_EJCT KC_MEDIA_EJECT Stop/Eject | |||
KC_MEDIA_SELECT KC_MSEL AL Consumer Control Configuration | |||
KC_MAIL KC_MAIL AL Email Reader | |||
KC_CALCULATOR KC_CALC AL Calculator | |||
KC_MY_COMPUTER KC_MYCM AL Local Machine Browser | |||
KC_WWW_SEARCH KC_WSCH AC Search | |||
KC_WWW_HOME KC_WHOM AC Home | |||
KC_WWW_BACK KC_WBAK AC Back | |||
KC_WWW_FORWARD KC_WFWD AC Forward | |||
KC_WWW_STOP KC_WSTP AC Stop | |||
KC_WWW_REFRESH KC_WREF AC Refresh | |||
KC_WWW_FAVORITES KC_WFAV AC Bookmarks | |||
/* Mousekey - TMK specific */ | |||
KC_MS_UP KC_MS_U Mouse Cursor Up | |||
KC_MS_DOWN KC_MS_D Mouse Cursor Down | |||
KC_MS_LEFT KC_MS_L Mouse Cursor Left | |||
@@ -226,7 +231,8 @@ KC_MS_WH_RIGHT KC_WH_R Mouse Wheel Right | |||
KC_MS_ACCEL0 KC_ACL0 Mouse Acceleration 0 | |||
KC_MS_ACCEL1 KC_ACL1 Mouse Acceleration 1 | |||
KC_MS_ACCEL2 KC_ACL2 Mouse Acceleration 2 | |||
/* Fn key */ | |||
/* Fn key - TMK specific */ | |||
KC_FN0 | |||
KC_FN1 | |||
KC_FN2 |
@@ -95,7 +95,7 @@ Note that ***higher layers have priority in the layer stack***. The firmware sta | |||
### 0.3 Keymap Example | |||
The keymap is defined in the **`keymaps[]`** array, a 2-dimensional array of rows and columns corresponding to positions in the keyboard matrix. But most often the layers are defined using C macros to allow for easier reading and editing of the keymap files. To use complex actions you need to define `Fn` keycodes in the **`fn_actions[]`** array. | |||
The keymap is defined in the **`uint8_t keymaps[]`** array, a 2-dimensional array of rows and columns corresponding to positions in the keyboard matrix. But most often the layers are defined using C macros to allow for easier reading and editing of the keymap files. To use complex actions you need to define `Fn` action in the **`action_t fn_actions[]`** array. | |||
This is a keymap example for the [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard. | |||
This example has three layers: the QWERTY base layer, and two overlay layers for cursor and mousekey control, respectively. | |||
@@ -109,7 +109,7 @@ In this example, | |||
You can find other keymap definitions in file `keymap.c` located on project directories. | |||
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
/* 0: Qwerty | |||
* ,-----------------------------------------------------------. | |||
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| | |||
@@ -167,7 +167,7 @@ You can find other keymap definitions in file `keymap.c` located on project dire | |||
LGUI,LALT, BTN1, RALT,TRNS), | |||
}; | |||
static const uint16_t PROGMEM fn_actions[] = { | |||
const action_t PROGMEM fn_actions[] = { | |||
ACTION_LAYER_MOMENTARY(1), // FN0 | |||
ACTION_LAYER_TAP_KEY(2, KC_SCLN), // FN1 | |||
ACTION_LAYER_TOGGLE(2), // FN2 | |||
@@ -214,7 +214,7 @@ There are 8 modifiers which has discrimination between left and right. | |||
- `KC_WSCH`, `KC_WHOM`, `KC_WBAK`, `KC_WFWD`, `KC_WSTP`, `KC_WREF`, `KC_WFAV` for web browser operation | |||
### 1.5 Fn key | |||
`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** | |||
`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `action_t fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** | |||
### 1.6 Keycode Table | |||
See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes. | |||
@@ -379,19 +379,33 @@ Default Layer also has bitwise operations, they are executed when key is release | |||
ACTION_DEFAULT_LAYER_BIT_SET(part, bits) | |||
### 2.3 Macro action | |||
***TBD*** | |||
`Macro` actions allow you to register a complex sequence of keystrokes when a key is pressed, where macros are simple sequences of keypresses. | |||
ACTION_MACRO(id) | |||
ACTION_MACRO_TAP(id) | |||
`id` is an 8-bit user-defined value the macro getter function can use to pick the specific macro. | |||
#### 2.3.1 Implementing Macro getter function | |||
To implement `macro` functions, the macro lookup list must be implemented: | |||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt); | |||
`Macro` action indicates complex key strokes. | |||
MACRO( D(LSHIFT), D(D), END ) | |||
MACRO( U(D), U(LSHIFT), END ) | |||
MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ) | |||
The function must always return a valid macro, and default implementation of `action_get_macro` always returns `MACRO_NONE` which has no effect. | |||
#### 2.3.1.1 Limitations | |||
Similar to the Function Action system, the selector functions is passed a `keyrecord_t` object, so it can inspect the key state (e.g. different macros on key press or release), and key itself. | |||
Unlike the Function Action system,`macros` are pre-recorded key sequences, so you can only select from a list. If you want to use dynamic macros then you should look at the more complex function action system. | |||
#### 2.3.1 Macro Commands | |||
- **MACRO()** | |||
- **MACRO_NONE** | |||
#### 2.3.2 Implementing/Defining Macro sequences | |||
Macros are of the form (must be wrapped by the `MACRO` function, and end with an `END` mark) | |||
MACRO( ..., END ) | |||
Within each macro, the following commands can be used: | |||
- **I()** change interval of stroke. | |||
- **D()** press key | |||
@@ -401,19 +415,25 @@ Default Layer also has bitwise operations, they are executed when key is release | |||
- **SM()** store modifier state | |||
- **RM()** restore modifier state | |||
- **CM()** clear modifier state | |||
- **END** end mark | |||
e.g.: | |||
MACRO( D(LSHIFT), D(D), END ) // hold down LSHIFT and D - will print 'D' | |||
MACRO( U(D), U(LSHIFT), END ) // release U and LSHIFT keys (an event.pressed == False counterpart for the one above) | |||
MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ) // slowly print out h-e-l-l---o | |||
#### 2.3.2 Examples | |||
***TBD*** | |||
in keymap.c, define `action_get_macro` | |||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
{ | |||
switch (id) { | |||
case HELLO: | |||
case 0: | |||
return (record->event.pressed ? | |||
MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) : | |||
MACRO_NONE ); | |||
case ALT_TAB: | |||
case 1: | |||
return (record->event.pressed ? | |||
MACRO( D(LALT), D(TAB), END ) : | |||
MACRO( U(TAB), END )); | |||
@@ -421,7 +441,12 @@ Default Layer also has bitwise operations, they are executed when key is release | |||
return MACRO_NONE; | |||
} | |||
in keymap.c, bind items in `fn_actions` to the macro function | |||
const action_t PROGMEM fn_actions[] = { | |||
[0] = ACTION_MACRO(0), // will print 'hello' for example | |||
[1] = ACTION_MACRO(1), | |||
}; | |||
### 2.4 Function action | |||
@@ -443,7 +468,7 @@ To define tappable `Function` action in keymap use this. | |||
#### 2.4.3 Implement user function | |||
`Function` actions can be defined freely with C by user in callback function: | |||
void keymap_call_function(keyrecord_t *event, uint8_t id, uint8_t opt) | |||
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt); | |||
This C function is called every time key is operated, argument `id` selects action to be performed and `opt` can be used for option. Function `id` can be 0-255 and `opt` can be 0-15. | |||
@@ -544,6 +569,7 @@ This registers modifier key(s) simultaneously with layer switching. | |||
ACTION_LAYER_MODS(2, MOD_LSFT | MOD_LALT) | |||
This function can only register left-sided modifiers. The handedness of the modifier (left/right) is an extra bit that is not able to be passed through into the layer system. See: [`common/action_code.h`](../common/action_code.h), the spec for ACT_LAYER_TAP only allows four bits for the mods, whereas the mods themselves require five bits, with the high bit being the left/right handedness. | |||
## 4. Tapping | |||
@@ -598,13 +624,13 @@ Legacy Keymap uses two arrays `fn_layer[]` and `fn_keycode[]` to define Fn key. | |||
In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tapping while `Fn0` and `Fn1` doesn't send any key. | |||
static const uint8_t PROGMEM fn_layer[] = { | |||
const uint8_t PROGMEM fn_layer[] = { | |||
1, // Fn0 | |||
2, // Fn1 | |||
2, // Fn2 | |||
}; | |||
static const uint8_t PROGMEM fn_keycode[] = { | |||
const uint8_t PROGMEM fn_keycode[] = { | |||
KC_NO, // Fn0 | |||
KC_NO, // Fn1 | |||
KC_SPC, // Fn2 |
@@ -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]; |
@@ -1,52 +1,59 @@ | |||
PROTOCOL_DIR = protocol | |||
ifdef PS2_MOUSE_ENABLE | |||
ifeq (yes,$(strip $(PS2_MOUSE_ENABLE))) | |||
SRC += $(PROTOCOL_DIR)/ps2_mouse.c | |||
OPT_DEFS += -DPS2_MOUSE_ENABLE | |||
OPT_DEFS += -DMOUSE_ENABLE | |||
endif | |||
ifdef PS2_USE_BUSYWAIT | |||
ifeq (yes,$(strip $(PS2_USE_BUSYWAIT))) | |||
SRC += protocol/ps2_busywait.c | |||
SRC += protocol/ps2_io_avr.c | |||
OPT_DEFS += -DPS2_USE_BUSYWAIT | |||
endif | |||
ifdef PS2_USE_INT | |||
ifeq (yes,$(strip $(PS2_USE_INT))) | |||
SRC += protocol/ps2_interrupt.c | |||
SRC += protocol/ps2_io_avr.c | |||
OPT_DEFS += -DPS2_USE_INT | |||
endif | |||
ifdef PS2_USE_USART | |||
ifeq (yes,$(strip $(PS2_USE_USART))) | |||
SRC += protocol/ps2_usart.c | |||
SRC += protocol/ps2_io_avr.c | |||
OPT_DEFS += -DPS2_USE_USART | |||
endif | |||
ifdef SERIAL_MOUSE_MICROSOFT_ENABLE | |||
ifeq (yes,$(strip $(XT_USE_INT))) | |||
SRC += protocol/xt_interrupt.c | |||
SRC += protocol/xt_io_avr.c | |||
OPT_DEFS += -DXT_USE_INT | |||
endif | |||
ifeq (yes,$(strip $(SERIAL_MOUSE_MICROSOFT_ENABLE))) | |||
SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c | |||
OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \ | |||
-DMOUSE_ENABLE | |||
endif | |||
ifdef SERIAL_MOUSE_MOUSESYSTEMS_ENABLE | |||
ifeq (yes,$(strip $(SERIAL_MOUSE_MOUSESYSTEMS_ENABLE))) | |||
SRC += $(PROTOCOL_DIR)/serial_mouse_mousesystems.c | |||
OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MOUSESYSTEMS \ | |||
-DMOUSE_ENABLE | |||
endif | |||
ifdef SERIAL_MOUSE_USE_SOFT | |||
ifeq (yes,$(strip $(SERIAL_MOUSE_USE_SOFT))) | |||
SRC += $(PROTOCOL_DIR)/serial_soft.c | |||
endif | |||
ifdef SERIAL_MOUSE_USE_UART | |||
ifeq (yes,$(strip $(SERIAL_MOUSE_USE_UART))) | |||
SRC += $(PROTOCOL_DIR)/serial_uart.c | |||
endif | |||
ifdef ADB_MOUSE_ENABLE | |||
ifeq (yes,$(strip $(ADB_MOUSE_ENABLE))) | |||
OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE | |||
endif | |||
@@ -60,7 +60,6 @@ static inline void place_bit1(void); | |||
static inline void send_byte(uint8_t data); | |||
static inline uint16_t wait_data_lo(uint16_t us); | |||
static inline uint16_t wait_data_hi(uint16_t us); | |||
static inline uint16_t adb_host_dev_recv(uint8_t device); | |||
void adb_host_init(void) | |||
@@ -87,49 +86,9 @@ bool adb_host_psw(void) | |||
* <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> | |||
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> | |||
*/ | |||
// ADB Bit Cells | |||
// | |||
// bit cell time: 70-130us | |||
// low part of bit0: 60-70% of bit cell | |||
// low part of bit1: 30-40% of bit cell | |||
// | |||
// bit cell time 70us 130us | |||
// -------------------------------------------- | |||
// low part of bit0 42-49 78-91 | |||
// high part of bit0 21-28 39-52 | |||
// low part of bit1 21-28 39-52 | |||
// high part of bit1 42-49 78-91 | |||
// | |||
// | |||
// bit0: | |||
// 70us bit cell: | |||
// ____________~~~~~~ | |||
// 42-49 21-28 | |||
// | |||
// 130us bit cell: | |||
// ____________~~~~~~ | |||
// 78-91 39-52 | |||
// | |||
// bit1: | |||
// 70us bit cell: | |||
// ______~~~~~~~~~~~~ | |||
// 21-28 42-49 | |||
// | |||
// 130us bit cell: | |||
// ______~~~~~~~~~~~~ | |||
// 39-52 78-91 | |||
// | |||
// [from Apple IIgs Hardware Reference Second Edition] | |||
enum { | |||
ADDR_KEYB = 0x20, | |||
ADDR_MOUSE = 0x30 | |||
}; | |||
uint16_t adb_host_kbd_recv(void) | |||
uint16_t adb_host_kbd_recv(uint8_t addr) | |||
{ | |||
return adb_host_dev_recv(ADDR_KEYB); | |||
return adb_host_talk(addr, ADB_REG_0); | |||
} | |||
#ifdef ADB_MOUSE_ENABLE | |||
@@ -139,16 +98,16 @@ void adb_mouse_init(void) { | |||
uint16_t adb_host_mouse_recv(void) | |||
{ | |||
return adb_host_dev_recv(ADDR_MOUSE); | |||
return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); | |||
} | |||
#endif | |||
static inline uint16_t adb_host_dev_recv(uint8_t device) | |||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg) | |||
{ | |||
uint16_t data = 0; | |||
cli(); | |||
attention(); | |||
send_byte(device|0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00) | |||
send_byte((addr<<4) | (ADB_CMD_TALK<<2) | reg); | |||
place_bit0(); // Stopbit(0) | |||
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored | |||
sei(); | |||
@@ -158,20 +117,20 @@ static inline uint16_t adb_host_dev_recv(uint8_t device) | |||
sei(); | |||
return 0; // No data to send | |||
} | |||
uint8_t n = 17; // start bit + 16 data bits | |||
do { | |||
uint8_t lo = (uint8_t) wait_data_hi(130); | |||
if (!lo) | |||
goto error; | |||
uint8_t hi = (uint8_t) wait_data_lo(lo); | |||
if (!hi) | |||
goto error; | |||
hi = lo - hi; | |||
lo = 130 - lo; | |||
data <<= 1; | |||
if (lo < hi) { | |||
data |= 1; | |||
@@ -197,27 +156,27 @@ error: | |||
return -n; | |||
} | |||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) | |||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) | |||
{ | |||
cli(); | |||
attention(); | |||
send_byte(cmd); | |||
send_byte((addr<<4) | (ADB_CMD_LISTEN<<2) | reg); | |||
place_bit0(); // Stopbit(0) | |||
_delay_us(200); // Tlt/Stop to Start | |||
place_bit1(); // Startbit(1) | |||
send_byte(data_h); | |||
send_byte(data_h); | |||
send_byte(data_l); | |||
place_bit0(); // Stopbit(0); | |||
sei(); | |||
} | |||
// send state of LEDs | |||
void adb_host_kbd_led(uint8_t led) | |||
void adb_host_kbd_led(uint8_t addr, uint8_t led) | |||
{ | |||
// Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) | |||
// send upper byte (not used) | |||
// send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: | |||
adb_host_listen(0x2A,0,led&0x07); | |||
// Listen Register2 | |||
// upper byte: not used | |||
// lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock | |||
adb_host_listen(addr, 2, 0, led & 0x07); | |||
} | |||
@@ -366,7 +325,7 @@ Commands | |||
bits commands | |||
------------------------------------------------------ | |||
- - - - 0 0 0 0 Send Request(reset all devices) | |||
- - - - 0 0 0 0 Send Reset(reset all devices) | |||
A A A A 0 0 0 1 Flush(reset a device) | |||
- - - - 0 0 1 0 Reserved | |||
- - - - 0 0 1 1 Reserved | |||
@@ -375,7 +334,7 @@ Commands | |||
A A A A 1 1 R R Talk(read from a device) | |||
The command to read keycodes from keyboard is 0x2C which | |||
consist of keyboard address 2 and Talk against register 0. | |||
consist of keyboard address 2 and Talk against register 0. | |||
Address: | |||
2: keyboard | |||
@@ -457,7 +416,7 @@ Keyboard Data(Register0) | |||
Keyboard LEDs & state of keys(Register2) | |||
This register hold current state of three LEDs and nine keys. | |||
The state of LEDs can be changed by sending Listen command. | |||
1514 . . . . . . 7 6 5 . 3 2 1 0 | |||
| | | | | | | | | | | | | | | +- LED1(NumLock) | |||
| | | | | | | | | | | | | | +--- LED2(CapsLock) | |||
@@ -474,5 +433,56 @@ Keyboard LEDs & state of keys(Register2) | |||
| +----------------------------- Delete | |||
+------------------------------- Reserved | |||
Address, Handler ID and bits(Register3) | |||
1514131211 . . 8 7 . . . . . . 0 | |||
| | | | | | | | | | | | | | | | | |||
| | | | | | | | +-+-+-+-+-+-+-+- Handler ID | |||
| | | | +-+-+-+----------------- Address | |||
| | | +------------------------- 0 | |||
| | +--------------------------- Service request enable(1 = enabled) | |||
| +----------------------------- Exceptional event(alwyas 1 if not used) | |||
+------------------------------- 0 | |||
ADB Bit Cells | |||
bit cell time: 70-130us | |||
low part of bit0: 60-70% of bit cell | |||
low part of bit1: 30-40% of bit cell | |||
bit cell time 70us 130us | |||
-------------------------------------------- | |||
low part of bit0 42-49 78-91 | |||
high part of bit0 21-28 39-52 | |||
low part of bit1 21-28 39-52 | |||
high part of bit1 42-49 78-91 | |||
bit0: | |||
70us bit cell: | |||
____________~~~~~~ | |||
42-49 21-28 | |||
130us bit cell: | |||
____________~~~~~~ | |||
78-91 39-52 | |||
bit1: | |||
70us bit cell: | |||
______~~~~~~~~~~~~ | |||
21-28 42-49 | |||
130us bit cell: | |||
______~~~~~~~~~~~~ | |||
39-52 78-91 | |||
[from Apple IIgs Hardware Reference Second Edition] | |||
Keyboard Handle ID | |||
Apple Standard Keyboard M0116: 0x01 | |||
Apple Extended Keyboard M0115: 0x02 | |||
Apple Extended Keyboard II M3501: 0x02 | |||
Apple Adjustable Keybaord: 0x10 | |||
http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802 | |||
END_OF_ADB | |||
*/ |
@@ -52,13 +52,41 @@ POSSIBILITY OF SUCH DAMAGE. | |||
#define ADB_CAPS 0x39 | |||
/* ADB commands */ | |||
// Default Address | |||
#define ADB_ADDR_DONGLE 1 | |||
#define ADB_ADDR_KEYBOARD 2 | |||
#define ADB_ADDR_MOUSE 3 | |||
#define ADB_ADDR_TABLET 4 | |||
#define ADB_ADDR_APPLIANCE 7 | |||
// Command Type | |||
#define ADB_CMD_RESET 0 | |||
#define ADB_CMD_FLUSH 1 | |||
#define ADB_CMD_LISTEN 2 | |||
#define ADB_CMD_TALK 3 | |||
// Register | |||
#define ADB_REG_0 0 | |||
#define ADB_REG_1 1 | |||
#define ADB_REG_2 2 | |||
#define ADB_REG_3 3 | |||
/* ADB keyboard handler id */ | |||
#define ADB_HANDLER_M0116 0x01 | |||
#define ADB_HANDLER_IIGS 0x01 | |||
#define ADB_HANDLER_M0115 0x02 | |||
#define ADB_HANDLER_M3501 0x02 | |||
#define ADB_HANDLER_M1242_ANSI 0x10 | |||
#define ADB_HANDLER_EXTENDED_PROTOCOL 0x03 | |||
// ADB host | |||
void adb_host_init(void); | |||
bool adb_host_psw(void); | |||
uint16_t adb_host_kbd_recv(void); | |||
uint16_t adb_host_kbd_recv(uint8_t addr); | |||
uint16_t adb_host_mouse_recv(void); | |||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); | |||
void adb_host_kbd_led(uint8_t led); | |||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg); | |||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l); | |||
void adb_host_kbd_led(uint8_t addr, uint8_t led); | |||
void adb_mouse_task(void); | |||
void adb_mouse_init(void); | |||
@@ -150,25 +150,25 @@ static void send_system(uint16_t data) | |||
+-------------------------------------+-------+ | |||
*/ | |||
#define CONSUMER2BLUEFRUIT(usage) \ | |||
(usage == AUDIO_MUTE ? 0x0000 : \ | |||
(usage == AUDIO_VOL_UP ? 0x1000 : \ | |||
(usage == AUDIO_VOL_DOWN ? 0x2000 : \ | |||
(usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \ | |||
(usage == TRANSPORT_PREV_TRACK ? 0x0004 : \ | |||
(usage == TRANSPORT_STOP ? 0x0010 : \ | |||
(usage == TRANSPORT_STOP_EJECT ? 0x0000 : \ | |||
(usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \ | |||
(usage == AL_CC_CONFIG ? 0x0000 : \ | |||
(usage == AL_EMAIL ? 0x0000 : \ | |||
(usage == AL_CALCULATOR ? 0x0000 : \ | |||
(usage == AL_LOCAL_BROWSER ? 0x0000 : \ | |||
(usage == AC_SEARCH ? 0x0400 : \ | |||
(usage == AC_HOME ? 0x0100 : \ | |||
(usage == AC_BACK ? 0x0000 : \ | |||
(usage == AC_FORWARD ? 0x0000 : \ | |||
(usage == AC_STOP ? 0x0000 : \ | |||
(usage == AC_REFRESH ? 0x0000 : \ | |||
(usage == AC_BOOKMARKS ? 0x0000 : 0))))))))))))))))))) | |||
(usage == AUDIO_MUTE ? 0x0000 : \ | |||
(usage == AUDIO_VOL_UP ? 0x1000 : \ | |||
(usage == AUDIO_VOL_DOWN ? 0x2000 : \ | |||
(usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \ | |||
(usage == TRANSPORT_PREV_TRACK ? 0x0004 : \ | |||
(usage == TRANSPORT_STOP ? 0x0010 : \ | |||
(usage == TRANSPORT_STOP_EJECT ? 0x0000 : \ | |||
(usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \ | |||
(usage == APPLAUNCH_CC_CONFIG ? 0x0000 : \ | |||
(usage == APPLAUNCH_EMAIL ? 0x0000 : \ | |||
(usage == APPLAUNCH_CALCULATOR ? 0x0000 : \ | |||
(usage == APPLAUNCH_LOCAL_BROWSER ? 0x0000 : \ | |||
(usage == APPCONTROL_SEARCH ? 0x0400 : \ | |||
(usage == APPCONTROL_HOME ? 0x0100 : \ | |||
(usage == APPCONTROL_BACK ? 0x0000 : \ | |||
(usage == APPCONTROL_FORWARD ? 0x0000 : \ | |||
(usage == APPCONTROL_STOP ? 0x0000 : \ | |||
(usage == APPCONTROL_REFRESH ? 0x0000 : \ | |||
(usage == APPCONTROL_BOOKMARKS ? 0x0000 : 0))))))))))))))))))) | |||
static void send_consumer(uint16_t data) | |||
{ |
@@ -1,16 +1,16 @@ | |||
## TMK running on top of ChibiOS | |||
This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever [ChibiOS] supports. The notable examples are ARM-based Teensies (3.x and LC) and on the boards with STM32 MCUs. | |||
This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever ChibiOS supports. The notable examples are PJRC Teensies(3.x and LC) with NXP Kinetis and dev boards with ST Micro STM32 MCUs. | |||
### Usage | |||
- To use, [get a zip of chibios](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip) and unpack/rename it to `tmk_core/tool/chibios/chibios`; or you can just clone [the repo](https://github.com/ChibiOS/ChibiOS) there. For Freescale/NXP Kinetis support (meaning ARM Teensies and the Infinity keyboard), you'll also need [a zip of chibios-contrib](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip), unpacked/renamed to `tmk_core/tool/chibios/chibios-contrib`. Likewise, for git-savvy people, just clone [the repo](https://github.com/ChibiOS/ChibiOS-Contrib) there. | |||
- Note: the abovementioned directories are the defaults. You can have the two chibios repositories wherever you want, just define their location in `CHIBIOS` and `CHIBIOS_CONTRIB` variables in your `Makefile`. | |||
- To use, get a [zip file](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip) of ChibiOS and unpack/rename it to `tmk_core/tool/chibios/ChibiOS`; or you can just clone [ChibiOS repo](https://github.com/ChibiOS/ChibiOS) there. For Freescale/NXP Kinetis support (meaning Teensies 3.x/LC and the Infinity keyboard), you'll also need a [zip](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip) of ChibiOS-Contrib, unpacked/renamed to `tmk_core/tool/chibios/ChibiOS-Contrib`. Likewise, for git-savvy people, just clone [ChibiOS-Contrib repo](https://github.com/ChibiOS/ChibiOS-Contrib) there. | |||
- Note: the above mentioned directories are the defaults. You can have the two ChibiOS repositories wherever you want, just define their location in `CHIBIOS` and `CHIBIOS_CONTRIB` variables in your `Makefile`. | |||
- You will also need to install an ARM toolchain, for instance from [here](https://launchpad.net/gcc-arm-embedded). On linux, this is usually also present as a package for your distribution (as `gcc-arm` or something similar). On OS X, you can use [homebrew](http://brew.sh/) with an appropriate tap. | |||
### Notes | |||
- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for ARM Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md). | |||
- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md). | |||
- For gcc options, inspect `tmk_core/tool/chibios/chibios.mk`. For instance, I enabled `-Wno-missing-field-initializers`, because TMK common bits generated a lot of warnings on that. | |||
- For debugging, it is sometimes useful disable gcc optimisations, you can do that by adding `-O0` to `OPT_DEFS` in your `Makefile`. | |||
- USB string descriptors are messy. I did not find a way to cleanly generate the right structures from actual strings, so the definitions in individual keyboards' `config.h` are ugly as heck. |
@@ -153,7 +153,7 @@ static const uint8_t keyboard_hid_report_desc_data[] = { | |||
0x95, KBD_REPORT_KEYS, // Report Count (), | |||
0x75, 0x08, // Report Size (8), | |||
0x15, 0x00, // Logical Minimum (0), | |||
0x25, 0xFF, // Logical Maximum(255), | |||
0x26, 0xFF, 0x00, // Logical Maximum(255), | |||
0x05, 0x07, // Usage Page (Key Codes), | |||
0x19, 0x00, // Usage Minimum (0), | |||
0x29, 0xFF, // Usage Maximum (255), | |||
@@ -299,7 +299,7 @@ static const uint8_t extra_hid_report_desc_data[] = { | |||
0xa1, 0x01, // COLLECTION (Application) | |||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | |||
0x15, 0x01, // LOGICAL_MINIMUM (0x1) | |||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) | |||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7) | |||
0x19, 0x01, // USAGE_MINIMUM (0x1) | |||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | |||
0x75, 0x10, // REPORT_SIZE (16) |
@@ -37,6 +37,10 @@ LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABL | |||
#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT | |||
LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 | |||
LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1 | |||
# Remote wakeup fix for ATmega32U2 https://github.com/tmk/tmk_keyboard/issues/361 | |||
ifeq ($(MCU),atmega32u2) | |||
LUFA_OPTS += -DNO_LIMITED_CONTROLLER_CONNECT | |||
endif | |||
OPT_DEFS += -DF_USB=$(F_USB)UL | |||
OPT_DEFS += -DARCH=ARCH_$(ARCH) | |||
@@ -44,3 +48,8 @@ OPT_DEFS += $(LUFA_OPTS) | |||
# This indicates using LUFA stack | |||
OPT_DEFS += -DPROTOCOL_LUFA | |||
ifeq (yes,$(strip $(LUFA_DEBUG_SUART))) | |||
SRC += common/avr/suart.S | |||
LUFA_OPTS += -DLUFA_DEBUG_SUART | |||
endif |
@@ -73,10 +73,10 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = | |||
HID_RI_OUTPUT(8, HID_IOF_CONSTANT), | |||
HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */ | |||
HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */ | |||
HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */ | |||
HID_RI_USAGE_MINIMUM(8, 0x00), | |||
HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Usage ID 0x00-0xFF */ | |||
HID_RI_LOGICAL_MINIMUM(8, 0x00), | |||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), | |||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), /* needs 16 bit to indicate positive value */ | |||
HID_RI_REPORT_COUNT(8, 0x06), | |||
HID_RI_REPORT_SIZE(8, 0x08), | |||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), | |||
@@ -140,9 +140,9 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] = | |||
HID_RI_USAGE(8, 0x80), /* System Control */ | |||
HID_RI_COLLECTION(8, 0x01), /* Application */ | |||
HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM), | |||
HID_RI_LOGICAL_MINIMUM(16, 0x0001), | |||
HID_RI_LOGICAL_MINIMUM(16, 0x0081), | |||
HID_RI_LOGICAL_MAXIMUM(16, 0x00B7), | |||
HID_RI_USAGE_MINIMUM(16, 0x0001), /* System Power Down */ | |||
HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */ | |||
HID_RI_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */ | |||
HID_RI_REPORT_SIZE(8, 16), | |||
HID_RI_REPORT_COUNT(8, 1), | |||
@@ -172,13 +172,13 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = | |||
HID_RI_COLLECTION(8, 0x01), /* Application */ | |||
HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */ | |||
HID_RI_LOGICAL_MINIMUM(8, 0x00), | |||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), | |||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), | |||
HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), | |||
HID_RI_REPORT_SIZE(8, 0x08), | |||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), | |||
HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */ | |||
HID_RI_LOGICAL_MINIMUM(8, 0x00), | |||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), | |||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), | |||
HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), | |||
HID_RI_REPORT_SIZE(8, 0x08), | |||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), |
@@ -155,7 +155,7 @@ typedef struct | |||
#define MOUSE_EPSIZE 8 | |||
#define EXTRAKEY_EPSIZE 8 | |||
#define CONSOLE_EPSIZE 32 | |||
#define NKRO_EPSIZE 16 | |||
#define NKRO_EPSIZE 32 | |||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, |
@@ -1,4 +1,4 @@ | |||
/* | |||
/* | |||
* Copyright 2012 Jun Wako <[email protected]> | |||
* This file is based on: | |||
* LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse | |||
@@ -50,9 +50,18 @@ | |||
#include "suspend.h" | |||
#include "hook.h" | |||
#ifdef LUFA_DEBUG_SUART | |||
#include "avr/suart.h" | |||
#endif | |||
#include "matrix.h" | |||
#include "descriptor.h" | |||
#include "lufa.h" | |||
//#define LUFA_DEBUG | |||
uint8_t keyboard_idle = 0; | |||
/* 0: Boot Protocol, 1: Report Protocol(default) */ | |||
uint8_t keyboard_protocol = 1; | |||
@@ -100,10 +109,10 @@ static void Console_Task(void) | |||
{ | |||
/* Create a temporary buffer to hold the read in report from the host */ | |||
uint8_t ConsoleData[CONSOLE_EPSIZE]; | |||
/* Read Console Report Data */ | |||
Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL); | |||
/* Process Console Report Data */ | |||
//ProcessConsoleHIDReport(ConsoleData); | |||
} | |||
@@ -164,7 +173,7 @@ void EVENT_USB_Device_Disconnect(void) | |||
print("[D]"); | |||
/* For battery powered device */ | |||
USB_IsInitialized = false; | |||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated. | |||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated. | |||
if (USB_IsInitialized) { | |||
USB_Disable(); // Disable all interrupts | |||
USB_Controller_Enable(); | |||
@@ -175,18 +184,24 @@ void EVENT_USB_Device_Disconnect(void) | |||
void EVENT_USB_Device_Reset(void) | |||
{ | |||
#ifdef LUFA_DEBUG | |||
print("[R]"); | |||
#endif | |||
} | |||
void EVENT_USB_Device_Suspend() | |||
{ | |||
#ifdef LUFA_DEBUG | |||
print("[S]"); | |||
#endif | |||
hook_usb_suspend_entry(); | |||
} | |||
void EVENT_USB_Device_WakeUp() | |||
{ | |||
#ifdef LUFA_DEBUG | |||
print("[W]"); | |||
#endif | |||
hook_usb_wakeup(); | |||
} | |||
@@ -217,6 +232,9 @@ void EVENT_USB_Device_StartOfFrame(void) | |||
*/ | |||
void EVENT_USB_Device_ConfigurationChanged(void) | |||
{ | |||
#ifdef LUFA_DEBUG | |||
print("[c]"); | |||
#endif | |||
bool ConfigSuccess = true; | |||
/* Setup Keyboard HID Report Endpoints */ | |||
@@ -293,6 +311,9 @@ void EVENT_USB_Device_ControlRequest(void) | |||
/* Write the report data to the control endpoint */ | |||
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); | |||
Endpoint_ClearOUT(); | |||
#ifdef LUFA_DEBUG | |||
xprintf("[r%d]", USB_ControlRequest.wIndex); | |||
#endif | |||
} | |||
break; | |||
@@ -316,6 +337,9 @@ void EVENT_USB_Device_ControlRequest(void) | |||
Endpoint_ClearOUT(); | |||
Endpoint_ClearStatusStage(); | |||
#ifdef LUFA_DEBUG | |||
xprintf("[L%d]", USB_ControlRequest.wIndex); | |||
#endif | |||
break; | |||
} | |||
@@ -332,6 +356,9 @@ void EVENT_USB_Device_ControlRequest(void) | |||
Endpoint_Write_8(keyboard_protocol); | |||
Endpoint_ClearIN(); | |||
Endpoint_ClearStatusStage(); | |||
#ifdef LUFA_DEBUG | |||
print("[p]"); | |||
#endif | |||
} | |||
} | |||
@@ -345,6 +372,9 @@ void EVENT_USB_Device_ControlRequest(void) | |||
keyboard_protocol = (USB_ControlRequest.wValue & 0xFF); | |||
clear_keyboard(); | |||
#ifdef LUFA_DEBUG | |||
print("[P]"); | |||
#endif | |||
} | |||
} | |||
@@ -356,6 +386,9 @@ void EVENT_USB_Device_ControlRequest(void) | |||
Endpoint_ClearStatusStage(); | |||
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); | |||
#ifdef LUFA_DEBUG | |||
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8); | |||
#endif | |||
} | |||
break; | |||
@@ -367,6 +400,9 @@ void EVENT_USB_Device_ControlRequest(void) | |||
Endpoint_Write_8(keyboard_idle); | |||
Endpoint_ClearIN(); | |||
Endpoint_ClearStatusStage(); | |||
#ifdef LUFA_DEBUG | |||
print("[i]"); | |||
#endif | |||
} | |||
break; | |||
@@ -374,7 +410,7 @@ void EVENT_USB_Device_ControlRequest(void) | |||
} | |||
/******************************************************************************* | |||
* Host driver | |||
* Host driver | |||
******************************************************************************/ | |||
static uint8_t keyboard_leds(void) | |||
{ | |||
@@ -494,6 +530,9 @@ static void send_consumer(uint16_t data) | |||
#define SEND_TIMEOUT 5 | |||
int8_t sendchar(uint8_t c) | |||
{ | |||
#ifdef LUFA_DEBUG_SUART | |||
xmit(c); | |||
#endif | |||
// Not wait once timeouted. | |||
// Because sendchar() is called so many times, waiting each call causes big lag. | |||
static bool timeouted = false; | |||
@@ -551,6 +590,9 @@ ERROR_EXIT: | |||
#else | |||
int8_t sendchar(uint8_t c) | |||
{ | |||
#ifdef LUFA_DEBUG_SUART | |||
xmit(c); | |||
#endif | |||
return 0; | |||
} | |||
#endif | |||
@@ -578,13 +620,20 @@ static void setup_usb(void) | |||
// for Console_Task | |||
USB_Device_EnableSOFEvents(); | |||
print_set_sendchar(sendchar); | |||
} | |||
int main(void) __attribute__ ((weak)); | |||
int main(void) | |||
{ | |||
setup_mcu(); | |||
#ifdef LUFA_DEBUG_SUART | |||
SUART_OUT_DDR |= (1<<SUART_OUT_BIT); | |||
SUART_OUT_PORT |= (1<<SUART_OUT_BIT); | |||
#endif | |||
print_set_sendchar(sendchar); | |||
print("\r\ninit\n"); | |||
hook_early_init(); | |||
keyboard_setup(); | |||
setup_usb(); | |||
@@ -611,7 +660,9 @@ int main(void) | |||
hook_late_init(); | |||
while (1) { | |||
while (USB_DeviceState == DEVICE_STATE_Suspended) { | |||
#ifdef LUFA_DEBUG | |||
print("[s]"); | |||
#endif | |||
hook_usb_suspend_loop(); | |||
} | |||
@@ -631,9 +682,19 @@ void hook_early_init(void) {} | |||
__attribute__((weak)) | |||
void hook_late_init(void) {} | |||
static uint8_t _led_stats = 0; | |||
__attribute__((weak)) | |||
void hook_usb_suspend_entry(void) | |||
{ | |||
// Turn LED off to save power | |||
// Set 0 with putting aside status before suspend and restore | |||
// it after wakeup, then LED is updated at keyboard_task() in main loop | |||
_led_stats = keyboard_led_stats; | |||
keyboard_led_stats = 0; | |||
led_set(keyboard_led_stats); | |||
matrix_clear(); | |||
clear_keyboard(); | |||
#ifdef SLEEP_LED_ENABLE | |||
sleep_led_enable(); | |||
#endif | |||
@@ -644,7 +705,7 @@ void hook_usb_suspend_loop(void) | |||
{ | |||
suspend_power_down(); | |||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | |||
USB_Device_SendRemoteWakeup(); | |||
USB_Device_SendRemoteWakeup(); | |||
} | |||
} | |||
@@ -654,7 +715,12 @@ void hook_usb_wakeup(void) | |||
suspend_wakeup_init(); | |||
#ifdef SLEEP_LED_ENABLE | |||
sleep_led_disable(); | |||
// NOTE: converters may not accept this | |||
led_set(host_keyboard_leds()); | |||
#endif | |||
// Restore LED status | |||
// BIOS/grub won't recognize/enumerate if led_set() takes long(around 40ms?) | |||
// Converters fall into the case and miss wakeup event(timeout to reply?) in the end. | |||
//led_set(host_keyboard_leds()); | |||
// Instead, restore stats and update at keyboard_task() in main loop | |||
keyboard_led_stats = _led_stats; | |||
} |
@@ -97,7 +97,7 @@ uint8_t * HIDKeyboard::reportDesc() { | |||
REPORT_COUNT(1), 0x06, | |||
REPORT_SIZE(1), 0x08, | |||
LOGICAL_MINIMUM(1), 0x00, | |||
LOGICAL_MAXIMUM(1), 0xFF, | |||
LOGICAL_MAXIMUM(2), 0xFF, 0x00, | |||
USAGE_PAGE(1), 0x07, // Key Codes | |||
USAGE_MINIMUM(1), 0x00, | |||
USAGE_MAXIMUM(1), 0xFF, |
@@ -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 |
@@ -184,7 +184,7 @@ static const uint8_t PROGMEM keyboard_hid_report_desc[] = { | |||
0x95, KBD_REPORT_KEYS, // Report Count (), | |||
0x75, 0x08, // Report Size (8), | |||
0x15, 0x00, // Logical Minimum (0), | |||
0x25, 0xFF, // Logical Maximum(255), | |||
0x26, 0xFF, 0x00, // Logical Maximum(255), | |||
0x05, 0x07, // Usage Page (Key Codes), | |||
0x19, 0x00, // Usage Minimum (0), | |||
0x29, 0xFF, // Usage Maximum (255), | |||
@@ -307,7 +307,7 @@ static const uint8_t PROGMEM extra_hid_report_desc[] = { | |||
0xa1, 0x01, // COLLECTION (Application) | |||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | |||
0x15, 0x01, // LOGICAL_MINIMUM (0x1) | |||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) | |||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7) | |||
0x19, 0x01, // USAGE_MINIMUM (0x1) | |||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | |||
0x75, 0x10, // REPORT_SIZE (16) |
@@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. | |||
#include <stdbool.h> | |||
#include <avr/interrupt.h> | |||
#include <util/delay.h> | |||
#include "pbuff.h" | |||
#include "ps2.h" | |||
#include "ps2_io.h" | |||
#include "print.h" | |||
@@ -57,13 +58,6 @@ POSSIBILITY OF SUCH DAMAGE. | |||
uint8_t ps2_error = PS2_ERR_NONE; | |||
static inline uint8_t pbuf_dequeue(void); | |||
static inline void pbuf_enqueue(uint8_t data); | |||
static inline bool pbuf_has_data(void); | |||
static inline void pbuf_clear(void); | |||
void ps2_host_init(void) | |||
{ | |||
idle(); | |||
@@ -225,55 +219,3 @@ void ps2_host_set_led(uint8_t led) | |||
ps2_host_send(0xED); | |||
ps2_host_send(led); | |||
} | |||
/*-------------------------------------------------------------------- | |||
* Ring buffer to store scan codes from keyboard | |||
*------------------------------------------------------------------*/ | |||
#define PBUF_SIZE 32 | |||
static uint8_t pbuf[PBUF_SIZE]; | |||
static uint8_t pbuf_head = 0; | |||
static uint8_t pbuf_tail = 0; | |||
static inline void pbuf_enqueue(uint8_t data) | |||
{ | |||
uint8_t sreg = SREG; | |||
cli(); | |||
uint8_t next = (pbuf_head + 1) % PBUF_SIZE; | |||
if (next != pbuf_tail) { | |||
pbuf[pbuf_head] = data; | |||
pbuf_head = next; | |||
} else { | |||
print("pbuf: full\n"); | |||
} | |||
SREG = sreg; | |||
} | |||
static inline uint8_t pbuf_dequeue(void) | |||
{ | |||
uint8_t val = 0; | |||
uint8_t sreg = SREG; | |||
cli(); | |||
if (pbuf_head != pbuf_tail) { | |||
val = pbuf[pbuf_tail]; | |||
pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; | |||
} | |||
SREG = sreg; | |||
return val; | |||
} | |||
static inline bool pbuf_has_data(void) | |||
{ | |||
uint8_t sreg = SREG; | |||
cli(); | |||
bool has_data = (pbuf_head != pbuf_tail); | |||
SREG = sreg; | |||
return has_data; | |||
} | |||
static inline void pbuf_clear(void) | |||
{ | |||
uint8_t sreg = SREG; | |||
cli(); | |||
pbuf_head = pbuf_tail = 0; | |||
SREG = sreg; | |||
} | |||
@@ -4,30 +4,14 @@ | |||
#include "debug.h" | |||
report_keyboard_t usb_hid_keyboard_report; | |||
uint16_t usb_hid_time_stamp; | |||
void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) | |||
{ | |||
bool is_error = false; | |||
report_keyboard_t *report = (report_keyboard_t *)buf; | |||
::memcpy(&report, buf, sizeof(report_keyboard_t)); | |||
time_stamp = millis(); | |||
dprintf("keyboard input: %02X %02X", report->mods, report->reserved); | |||
dprintf("input %d: %02X %02X", hid->GetAddress(), report.mods, report.reserved); | |||
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { | |||
if (IS_ERROR(report->keys[i])) { | |||
is_error = true; | |||
} | |||
dprintf(" %02X", report->keys[i]); | |||
dprintf(" %02X", report.keys[i]); | |||
} | |||
dprint("\r\n"); | |||
// ignore error and not send report to computer | |||
if (is_error) { | |||
dprint("Error usage! \r\n"); | |||
return; | |||
} | |||
::memcpy(&usb_hid_keyboard_report, buf, sizeof(report_keyboard_t)); | |||
usb_hid_time_stamp = millis(); | |||
} |
@@ -2,11 +2,14 @@ | |||
#define PARSER_H | |||
#include "hid.h" | |||
#include "report.h" | |||
class KBDReportParser : public HIDReportParser | |||
{ | |||
public: | |||
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf); | |||
report_keyboard_t report; | |||
uint16_t time_stamp; | |||
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf); | |||
}; | |||
#endif |
@@ -20,6 +20,7 @@ | |||
#include "timer.h" | |||
#include "uart.h" | |||
#include "debug.h" | |||
#include "suspend.h" | |||
#define UART_BAUD_RATE 115200 | |||
@@ -41,6 +42,23 @@ static void initForUsbConnectivity(void) | |||
sei(); | |||
} | |||
void usb_remote_wakeup(void) { | |||
cli(); | |||
int8_t ddr_orig = USBDDR; | |||
USBOUT |= (1 << USBMINUS); | |||
USBDDR = ddr_orig | USBMASK; | |||
USBOUT ^= USBMASK; | |||
_delay_ms(25); | |||
USBOUT ^= USBMASK; | |||
USBDDR = ddr_orig; | |||
USBOUT &= ~(1 << USBMINUS); | |||
sei(); | |||
} | |||
int main(void) | |||
{ | |||
bool suspended = false; | |||
@@ -70,19 +88,6 @@ int main(void) | |||
// Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1) | |||
if (timer_elapsed(last_timer) > 5) { | |||
suspended = true; | |||
/* | |||
uart_putchar('S'); | |||
_delay_ms(1); | |||
cli(); | |||
set_sleep_mode(SLEEP_MODE_PWR_DOWN); | |||
sleep_enable(); | |||
sleep_bod_disable(); | |||
sei(); | |||
sleep_cpu(); | |||
sleep_disable(); | |||
_delay_ms(10); | |||
uart_putchar('W'); | |||
*/ | |||
} | |||
} | |||
#endif | |||
@@ -95,6 +100,8 @@ int main(void) | |||
keyboard_task(); | |||
} | |||
vusb_transfer_keyboard(); | |||
} else if (suspend_wakeup_condition()) { | |||
usb_remote_wakeup(); | |||
} | |||
} | |||
} |
@@ -266,7 +266,7 @@ const PROGMEM uchar keyboard_hid_report[] = { | |||
0x95, 0x06, // Report Count (6), | |||
0x75, 0x08, // Report Size (8), | |||
0x15, 0x00, // Logical Minimum (0), | |||
0x25, 0xFF, // Logical Maximum(255), | |||
0x26, 0xFF, 0x00, // Logical Maximum(255), | |||
0x05, 0x07, // Usage Page (Key Codes), | |||
0x19, 0x00, // Usage Minimum (0), | |||
0x29, 0xFF, // Usage Maximum (255), | |||
@@ -336,7 +336,7 @@ const PROGMEM uchar mouse_hid_report[] = { | |||
0xa1, 0x01, // COLLECTION (Application) | |||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | |||
0x15, 0x01, // LOGICAL_MINIMUM (0x1) | |||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) | |||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7) | |||
0x19, 0x01, // USAGE_MINIMUM (0x1) | |||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | |||
0x75, 0x10, // REPORT_SIZE (16) |
@@ -0,0 +1,75 @@ | |||
/* | |||
Copyright 2010,2011,2012,2013 Jun WAKO <[email protected]> | |||
Copyright 2016 Ethan Apodaca <[email protected]> | |||
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 |
@@ -0,0 +1,94 @@ | |||
/* | |||
Copyright 2010,2011,2012,2013 Jun WAKO <[email protected]> | |||
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; | |||
} |
@@ -0,0 +1,7 @@ | |||
#ifndef XT_IO_H | |||
#define XT_IO_H | |||
bool clock_in(void); | |||
bool data_in(void); | |||
#endif |
@@ -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); | |||
} |
@@ -420,6 +420,13 @@ flip: $(TARGET).hex | |||
batchisp -hardware usb -device $(MCU) -operation start reset 0 | |||
dfu: $(TARGET).hex | |||
@echo -n dfu-programmer: waiting | |||
@until dfu-programmer $(MCU) get bootloader-version > /dev/null 2>&1; do \ | |||
echo -n "."; \ | |||
sleep 1; \ | |||
done | |||
@echo | |||
ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1))) | |||
dfu-programmer $(MCU) erase --force | |||
else |
@@ -1,2 +1,2 @@ | |||
chibios | |||
chibios-contrib | |||
ChibiOS | |||
ChibiOS-Contrib |
@@ -83,8 +83,8 @@ endif | |||
# | |||
# Imported source files and paths | |||
CHIBIOS ?= $(TMK_DIR)/tool/chibios/chibios | |||
CHIBIOS_CONTRIB ?= $(TMK_DIR)/tool/chibios/chibios-contrib | |||
CHIBIOS ?= $(TMK_DIR)/tool/chibios/ChibiOS | |||
CHIBIOS_CONTRIB ?= $(TMK_DIR)/tool/chibios/ChibiOS-Contrib | |||
# Startup files. Try a few different locations, for compability with old versions and | |||
# for things hardware in the contrib repository | |||
STARTUP_MK = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk |
@@ -23,6 +23,7 @@ CC_FLAGS += \ | |||
-fdata-sections \ | |||
-fomit-frame-pointer | |||
CC_FLAGS += -MMD -MP | |||
CC_FLAGS += $(OPT_DEFS) | |||
LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs | |||
#LD_FLAGS += -u _printf_float -u _scanf_float |