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
Updates | Updates | ||||
------- | ------- | ||||
#### 2016/06/26 | |||||
Keymap framework was updated. `fn_actions[]` should be defined as `action_t` instead of `uint16_t`. And default code for keymap handling is now included in core you just need define `uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]` and `action_t fn_actions[]`. | |||||
#### 2016/02/10 | #### 2016/02/10 | ||||
flabbergast's Chibios protocol was merged from <https://github.com/flabbergast/tmk_keyboard/tree/chibios>. See [protocol/chibios/README.md](protocol/chibios/README.md). Chibios protocol supports Cortex-M such as STM32 and Kinetis. | flabbergast's Chibios protocol was merged from <https://github.com/flabbergast/tmk_keyboard/tree/chibios>. See [protocol/chibios/README.md](protocol/chibios/README.md). Chibios protocol supports Cortex-M such as STM32 and Kinetis. | ||||
COMMON_DIR = common | COMMON_DIR = common | ||||
SRC += $(COMMON_DIR)/host.c \ | SRC += $(COMMON_DIR)/host.c \ | ||||
$(COMMON_DIR)/keyboard.c \ | $(COMMON_DIR)/keyboard.c \ | ||||
$(COMMON_DIR)/matrix.c \ | |||||
$(COMMON_DIR)/action.c \ | $(COMMON_DIR)/action.c \ | ||||
$(COMMON_DIR)/action_tapping.c \ | $(COMMON_DIR)/action_tapping.c \ | ||||
$(COMMON_DIR)/action_macro.c \ | $(COMMON_DIR)/action_macro.c \ | ||||
$(COMMON_DIR)/action_layer.c \ | $(COMMON_DIR)/action_layer.c \ | ||||
$(COMMON_DIR)/action_util.c \ | $(COMMON_DIR)/action_util.c \ | ||||
$(COMMON_DIR)/keymap.c \ | |||||
$(COMMON_DIR)/print.c \ | $(COMMON_DIR)/print.c \ | ||||
$(COMMON_DIR)/debug.c \ | $(COMMON_DIR)/debug.c \ | ||||
$(COMMON_DIR)/util.c \ | $(COMMON_DIR)/util.c \ | ||||
# Option modules | # Option modules | ||||
ifdef BOOTMAGIC_ENABLE | |||||
ifeq (yes,$(strip $(UNIMAP_ENABLE))) | |||||
SRC += $(COMMON_DIR)/unimap.c | |||||
OPT_DEFS += -DUNIMAP_ENABLE | |||||
else | |||||
ifeq (yes,$(strip $(ACTIONMAP_ENABLE))) | |||||
SRC += $(COMMON_DIR)/actionmap.c | |||||
OPT_DEFS += -DACTIONMAP_ENABLE | |||||
else | |||||
SRC += $(COMMON_DIR)/keymap.c | |||||
endif | |||||
endif | |||||
ifeq (yes,$(strip $(BOOTMAGIC_ENABLE))) | |||||
SRC += $(COMMON_DIR)/bootmagic.c | SRC += $(COMMON_DIR)/bootmagic.c | ||||
SRC += $(COMMON_DIR)/avr/eeconfig.c | SRC += $(COMMON_DIR)/avr/eeconfig.c | ||||
OPT_DEFS += -DBOOTMAGIC_ENABLE | OPT_DEFS += -DBOOTMAGIC_ENABLE | ||||
endif | endif | ||||
ifdef MOUSEKEY_ENABLE | |||||
ifeq (yes,$(strip $(MOUSEKEY_ENABLE))) | |||||
SRC += $(COMMON_DIR)/mousekey.c | SRC += $(COMMON_DIR)/mousekey.c | ||||
OPT_DEFS += -DMOUSEKEY_ENABLE | OPT_DEFS += -DMOUSEKEY_ENABLE | ||||
OPT_DEFS += -DMOUSE_ENABLE | OPT_DEFS += -DMOUSE_ENABLE | ||||
endif | endif | ||||
ifdef EXTRAKEY_ENABLE | |||||
ifeq (yes,$(strip $(EXTRAKEY_ENABLE))) | |||||
OPT_DEFS += -DEXTRAKEY_ENABLE | OPT_DEFS += -DEXTRAKEY_ENABLE | ||||
endif | endif | ||||
ifdef CONSOLE_ENABLE | |||||
ifeq (yes,$(strip $(CONSOLE_ENABLE))) | |||||
OPT_DEFS += -DCONSOLE_ENABLE | OPT_DEFS += -DCONSOLE_ENABLE | ||||
else | else | ||||
OPT_DEFS += -DNO_PRINT | OPT_DEFS += -DNO_PRINT | ||||
OPT_DEFS += -DNO_DEBUG | OPT_DEFS += -DNO_DEBUG | ||||
endif | endif | ||||
ifdef COMMAND_ENABLE | |||||
ifeq (yes,$(strip $(COMMAND_ENABLE))) | |||||
SRC += $(COMMON_DIR)/command.c | SRC += $(COMMON_DIR)/command.c | ||||
OPT_DEFS += -DCOMMAND_ENABLE | OPT_DEFS += -DCOMMAND_ENABLE | ||||
endif | endif | ||||
ifdef NKRO_ENABLE | |||||
ifeq (yes,$(strip $(NKRO_ENABLE))) | |||||
OPT_DEFS += -DNKRO_ENABLE | OPT_DEFS += -DNKRO_ENABLE | ||||
endif | endif | ||||
ifdef USB_6KRO_ENABLE | |||||
ifeq (yes,$(strip $(USB_6KRO_ENABLE))) | |||||
OPT_DEFS += -DUSB_6KRO_ENABLE | OPT_DEFS += -DUSB_6KRO_ENABLE | ||||
endif | endif | ||||
ifdef KEYBOARD_LOCK_ENABLE | |||||
ifeq (yes, $(strip $(KEYBOARD_LOCK_ENABLE))) | |||||
OPT_DEFS += -DKEYBOARD_LOCK_ENABLE | OPT_DEFS += -DKEYBOARD_LOCK_ENABLE | ||||
endif | endif | ||||
ifdef SLEEP_LED_ENABLE | |||||
ifeq (yes,$(strip $(SLEEP_LED_ENABLE))) | |||||
SRC += $(COMMON_DIR)/avr/sleep_led.c | SRC += $(COMMON_DIR)/avr/sleep_led.c | ||||
OPT_DEFS += -DSLEEP_LED_ENABLE | OPT_DEFS += -DSLEEP_LED_ENABLE | ||||
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN | OPT_DEFS += -DNO_SUSPEND_POWER_DOWN | ||||
endif | endif | ||||
ifdef BACKLIGHT_ENABLE | |||||
ifeq (yes,$(strip $(BACKLIGHT_ENABLE))) | |||||
SRC += $(COMMON_DIR)/backlight.c | SRC += $(COMMON_DIR)/backlight.c | ||||
OPT_DEFS += -DBACKLIGHT_ENABLE | OPT_DEFS += -DBACKLIGHT_ENABLE | ||||
endif | endif | ||||
ifdef KEYMAP_SECTION_ENABLE | |||||
ifeq (yes,$(strip $(KEYMAP_SECTION_ENABLE))) | |||||
OPT_DEFS += -DKEYMAP_SECTION_ENABLE | OPT_DEFS += -DKEYMAP_SECTION_ENABLE | ||||
ifeq ($(strip $(MCU)),atmega32u2) | ifeq ($(strip $(MCU)),atmega32u2) |
#include "action_util.h" | #include "action_util.h" | ||||
#include "action.h" | #include "action.h" | ||||
#include "hook.h" | #include "hook.h" | ||||
#include "wait.h" | |||||
#ifdef DEBUG_ACTION | #ifdef DEBUG_ACTION | ||||
#include "debug.h" | #include "debug.h" | ||||
#endif | #endif | ||||
add_key(KC_CAPSLOCK); | add_key(KC_CAPSLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
wait_ms(100); | |||||
del_key(KC_CAPSLOCK); | del_key(KC_CAPSLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
} | } | ||||
#endif | #endif | ||||
add_key(KC_NUMLOCK); | add_key(KC_NUMLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
wait_ms(100); | |||||
del_key(KC_NUMLOCK); | del_key(KC_NUMLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
} | } | ||||
#endif | #endif | ||||
add_key(KC_SCROLLLOCK); | add_key(KC_SCROLLLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
wait_ms(100); | |||||
del_key(KC_SCROLLLOCK); | del_key(KC_SCROLLLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
} | } | ||||
#endif | #endif | ||||
add_key(KC_CAPSLOCK); | add_key(KC_CAPSLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
wait_ms(100); | |||||
del_key(KC_CAPSLOCK); | del_key(KC_CAPSLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
} | } | ||||
#endif | #endif | ||||
add_key(KC_NUMLOCK); | add_key(KC_NUMLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
wait_ms(100); | |||||
del_key(KC_NUMLOCK); | del_key(KC_NUMLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
} | } | ||||
#endif | #endif | ||||
add_key(KC_SCROLLLOCK); | add_key(KC_SCROLLLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
wait_ms(100); | |||||
del_key(KC_SCROLLLOCK); | del_key(KC_SCROLLLOCK); | ||||
send_keyboard_report(); | send_keyboard_report(); | ||||
} | } |
/* action utility */ | /* 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)) } | |||||
/* | /* | ||||
OP_OFF_ON, | OP_OFF_ON, | ||||
OP_SET_CLEAR, | OP_SET_CLEAR, | ||||
}; | }; | ||||
#define ACTION_LAYER_BITOP(op, part, bits, on) (ACT_LAYER<<12 | (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f)) | |||||
#define ACTION_LAYER_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 */ | /* Default Layer */ | ||||
#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer)/4, 1<<((layer)%4)) | #define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer)/4, 1<<((layer)%4)) | ||||
#define ACTION_DEFAULT_LAYER_TOGGLE(layer) ACTION_DEFAULT_LAYER_BIT_XOR((layer)/4, 1<<((layer)%4)) | #define ACTION_DEFAULT_LAYER_TOGGLE(layer) ACTION_DEFAULT_LAYER_BIT_XOR((layer)/4, 1<<((layer)%4)) |
action_t layer_switch_get_action(keypos_t key) | 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 | #ifndef NO_ACTION_LAYER | ||||
uint32_t layers = layer_state | default_layer_state; | uint32_t layers = layer_state | default_layer_state; | ||||
for (int8_t i = 31; i >= 0; i--) { | for (int8_t i = 31; i >= 0; i--) { | ||||
if (layers & (1UL<<i)) { | if (layers & (1UL<<i)) { | ||||
action = action_for_key(i, key); | action = action_for_key(i, key); | ||||
if (action.code != ACTION_TRANSPARENT) { | |||||
if (action.code != (action_t)ACTION_TRANSPARENT.code) { | |||||
return action; | return action; | ||||
} | } | ||||
} | } |
/* | |||||
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) | |||||
{ | |||||
} |
/* | |||||
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 |
TIMSK1 &= ~_BV(OCIE1A); | 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); | |||||
} | } | ||||
// LED on | // LED on | ||||
if (timer.pwm.count == 0) { | if (timer.pwm.count == 0) { | ||||
led_set(1<<USB_LED_CAPS_LOCK); | |||||
sleep_led_on(); | |||||
} | } | ||||
// LED off | // LED off | ||||
if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) { | if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) { | ||||
led_set(0); | |||||
sleep_led_off(); | |||||
} | } | ||||
} | } |
;---------------------------------------------------------------------------; | |||||
; 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 |
#ifndef SUART | |||||
#define SUART | |||||
void xmit(uint8_t); | |||||
uint8_t rcvr(void); | |||||
uint8_t recv(void); | |||||
#endif /* SUART */ |
) | ) | ||||
void suspend_idle(uint8_t time) | |||||
{ | |||||
cli(); | |||||
set_sleep_mode(SLEEP_MODE_IDLE); | |||||
sleep_enable(); | |||||
sei(); | |||||
sleep_cpu(); | |||||
sleep_disable(); | |||||
} | |||||
/* Power down MCU with watchdog timer | /* Power down MCU with watchdog timer | ||||
* wdto: watchdog timer timeout defined in <avr/wdt.h> | * wdto: watchdog timer timeout defined in <avr/wdt.h> | ||||
* WDTO_15MS | * WDTO_15MS | ||||
wdt_disable(); | 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) | 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); | power_down(WDTO_15MS); | ||||
#endif | |||||
} | } | ||||
__attribute__ ((weak)) void matrix_power_up(void) {} | |||||
__attribute__ ((weak)) void matrix_power_down(void) {} | |||||
bool suspend_wakeup_condition(void) | bool suspend_wakeup_condition(void) | ||||
{ | { | ||||
matrix_power_up(); | matrix_power_up(); | ||||
void suspend_wakeup_init(void) | void suspend_wakeup_init(void) | ||||
{ | { | ||||
// clear keyboard state | // clear keyboard state | ||||
matrix_clear(); | |||||
clear_keyboard(); | clear_keyboard(); | ||||
#ifdef BACKLIGHT_ENABLE | #ifdef BACKLIGHT_ENABLE | ||||
backlight_init(); | backlight_init(); |
#include "bootloader.h" | #include "bootloader.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "keymap.h" | #include "keymap.h" | ||||
#include "actionmap.h" | |||||
#include "host.h" | #include "host.h" | ||||
#include "action_layer.h" | #include "action_layer.h" | ||||
#include "eeconfig.h" | #include "eeconfig.h" | ||||
print("done.\n"); | print("done.\n"); | ||||
/* bootmagic skip */ | /* bootmagic skip */ | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SKIP)) { | |||||
return; | return; | ||||
} | } | ||||
/* eeconfig clear */ | /* eeconfig clear */ | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EEPROM_CLEAR)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_EEPROM_CLEAR)) { | |||||
eeconfig_init(); | eeconfig_init(); | ||||
} | } | ||||
/* bootloader */ | /* bootloader */ | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_BOOTLOADER)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_BOOTLOADER)) { | |||||
bootloader_jump(); | bootloader_jump(); | ||||
} | } | ||||
/* debug enable */ | /* debug enable */ | ||||
debug_config.raw = eeconfig_read_debug(); | debug_config.raw = eeconfig_read_debug(); | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_ENABLE)) { | |||||
if (bootmagic_scan_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; | debug_config.matrix = !debug_config.matrix; | ||||
} else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) { | |||||
} else if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) { | |||||
debug_config.keyboard = !debug_config.keyboard; | debug_config.keyboard = !debug_config.keyboard; | ||||
} else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MOUSE)) { | |||||
} else if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_MOUSE)) { | |||||
debug_config.mouse = !debug_config.mouse; | debug_config.mouse = !debug_config.mouse; | ||||
} else { | } else { | ||||
debug_config.enable = !debug_config.enable; | debug_config.enable = !debug_config.enable; | ||||
/* keymap config */ | /* keymap config */ | ||||
keymap_config.raw = eeconfig_read_keymap(); | keymap_config.raw = eeconfig_read_keymap(); | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) { | |||||
keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock; | keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock; | ||||
} | } | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) { | |||||
keymap_config.capslock_to_control = !keymap_config.capslock_to_control; | keymap_config.capslock_to_control = !keymap_config.capslock_to_control; | ||||
} | } | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) { | |||||
keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; | keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; | ||||
} | } | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) { | |||||
keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui; | keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui; | ||||
} | } | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_NO_GUI)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_NO_GUI)) { | |||||
keymap_config.no_gui = !keymap_config.no_gui; | keymap_config.no_gui = !keymap_config.no_gui; | ||||
} | } | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) { | |||||
keymap_config.swap_grave_esc = !keymap_config.swap_grave_esc; | keymap_config.swap_grave_esc = !keymap_config.swap_grave_esc; | ||||
} | } | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) { | |||||
keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace; | keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace; | ||||
} | } | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_HOST_NKRO)) { | |||||
if (bootmagic_scan_key(BOOTMAGIC_HOST_NKRO)) { | |||||
keymap_config.nkro = !keymap_config.nkro; | keymap_config.nkro = !keymap_config.nkro; | ||||
} | } | ||||
eeconfig_write_keymap(keymap_config.raw); | eeconfig_write_keymap(keymap_config.raw); | ||||
/* default layer */ | /* default layer */ | ||||
uint8_t default_layer = 0; | uint8_t default_layer = 0; | ||||
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); } | |||||
if (bootmagic_scan_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) { | if (default_layer) { | ||||
eeconfig_write_default_layer(default_layer); | eeconfig_write_default_layer(default_layer); | ||||
default_layer_set((uint32_t)default_layer); | default_layer_set((uint32_t)default_layer); | ||||
} | } | ||||
} | } | ||||
static bool scan_keycode(uint8_t keycode) | |||||
static bool scan_key(uint16_t code) | |||||
{ | { | ||||
for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | ||||
matrix_row_t matrix_row = matrix_get_row(r); | matrix_row_t matrix_row = matrix_get_row(r); | ||||
for (uint8_t c = 0; c < MATRIX_COLS; c++) { | for (uint8_t c = 0; c < MATRIX_COLS; c++) { | ||||
if (matrix_row & ((matrix_row_t)1<<c)) { | if (matrix_row & ((matrix_row_t)1<<c)) { | ||||
if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) { | |||||
// read key from Layer 0 | |||||
action_t action = action_for_key(0, (keypos_t){ .row = r, .col = c }); | |||||
if (action.code == code || | |||||
((action.kind.id == ACT_LMODS || | |||||
action.kind.id == ACT_RMODS || | |||||
action.kind.id == ACT_LMODS_TAP || | |||||
action.kind.id == ACT_RMODS_TAP || | |||||
action.kind.id == ACT_LAYER_TAP || | |||||
action.kind.id == ACT_LAYER_TAP_EXT) && | |||||
action.key.code == code)) { | |||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
bool bootmagic_scan_keycode(uint8_t keycode) | |||||
bool bootmagic_scan_key(uint16_t code) | |||||
{ | { | ||||
if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false; | |||||
if (!scan_key(BOOTMAGIC_KEY_SALT)) return false; | |||||
return scan_keycode(keycode); | |||||
return scan_key(code); | |||||
} | } |
void bootmagic(void); | void bootmagic(void); | ||||
bool bootmagic_scan_keycode(uint8_t keycode); | |||||
bool bootmagic_scan_key(uint16_t action); | |||||
#endif | #endif |
{ | { | ||||
#ifdef KEYBOARD_LOCK_ENABLE | #ifdef KEYBOARD_LOCK_ENABLE | ||||
static host_driver_t *host_driver = 0; | static host_driver_t *host_driver = 0; | ||||
#endif | |||||
#ifdef SLEEP_LED_ENABLE | |||||
static bool sleep_led_test = false; | |||||
#endif | #endif | ||||
switch (code) { | switch (code) { | ||||
#ifdef SLEEP_LED_ENABLE | #ifdef SLEEP_LED_ENABLE | ||||
case KC_Z: | case KC_Z: | ||||
// test breathing sleep LED | // test breathing sleep LED | ||||
print("Sleep LED test\n"); | print("Sleep LED test\n"); | ||||
sleep_led_toggle(); | |||||
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; | break; | ||||
#endif | #endif | ||||
#ifdef BOOTMAGIC_ENABLE | #ifdef BOOTMAGIC_ENABLE |
(*driver->send_keyboard)(report); | (*driver->send_keyboard)(report); | ||||
if (debug_keyboard) { | if (debug_keyboard) { | ||||
dprint("keyboard_report: "); | |||||
dprint("keyboard: "); | |||||
for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) { | for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) { | ||||
dprintf("%02X ", report->raw[i]); | dprintf("%02X ", report->raw[i]); | ||||
} | } | ||||
if (!driver) return; | if (!driver) return; | ||||
(*driver->send_system)(report); | (*driver->send_system)(report); | ||||
if (debug_keyboard) { | |||||
dprintf("system: %04X\n", report); | |||||
} | |||||
} | } | ||||
void host_consumer_send(uint16_t report) | void host_consumer_send(uint16_t report) | ||||
if (!driver) return; | if (!driver) return; | ||||
(*driver->send_consumer)(report); | (*driver->send_consumer)(report); | ||||
if (debug_keyboard) { | |||||
dprintf("consumer: %04X\n", report); | |||||
} | |||||
} | } | ||||
uint16_t host_last_sysytem_report(void) | |||||
uint16_t host_last_system_report(void) | |||||
{ | { | ||||
return last_system_report; | return last_system_report; | ||||
} | } |
void host_system_send(uint16_t data); | void host_system_send(uint16_t data); | ||||
void host_consumer_send(uint16_t data); | void host_consumer_send(uint16_t data); | ||||
uint16_t host_last_sysytem_report(void); | |||||
uint16_t host_last_system_report(void); | |||||
uint16_t host_last_consumer_report(void); | uint16_t host_last_consumer_report(void); | ||||
#ifdef __cplusplus | #ifdef __cplusplus |
#endif | #endif | ||||
__attribute__ ((weak)) void matrix_setup(void) {} | |||||
void keyboard_setup(void) | void keyboard_setup(void) | ||||
{ | { | ||||
matrix_setup(); | matrix_setup(); |
#define KC_MRWD KC_MEDIA_REWIND | #define KC_MRWD KC_MEDIA_REWIND | ||||
#define KC_MSTP KC_MEDIA_STOP | #define KC_MSTP KC_MEDIA_STOP | ||||
#define KC_MPLY KC_MEDIA_PLAY_PAUSE | #define KC_MPLY KC_MEDIA_PLAY_PAUSE | ||||
#define KC_MSEL KC_MEDIA_SELECT | |||||
#define KC_EJCT KC_MEDIA_EJECT | #define KC_EJCT KC_MEDIA_EJECT | ||||
#define KC_MSEL KC_MEDIA_SELECT | |||||
#define KC_MAIL KC_MAIL | #define KC_MAIL KC_MAIL | ||||
#define KC_CALC KC_CALCULATOR | #define KC_CALC KC_CALCULATOR | ||||
#define KC_MYCM KC_MY_COMPUTER | #define KC_MYCM KC_MY_COMPUTER | ||||
KC_AUDIO_VOL_DOWN, | KC_AUDIO_VOL_DOWN, | ||||
KC_MEDIA_NEXT_TRACK, | KC_MEDIA_NEXT_TRACK, | ||||
KC_MEDIA_PREV_TRACK, | KC_MEDIA_PREV_TRACK, | ||||
KC_MEDIA_FAST_FORWARD, | |||||
KC_MEDIA_REWIND, | |||||
KC_MEDIA_STOP, | KC_MEDIA_STOP, | ||||
KC_MEDIA_PLAY_PAUSE, | KC_MEDIA_PLAY_PAUSE, | ||||
KC_MEDIA_SELECT, | |||||
KC_MEDIA_EJECT, | KC_MEDIA_EJECT, | ||||
KC_MEDIA_SELECT, | |||||
KC_MAIL, | KC_MAIL, | ||||
KC_CALCULATOR, | KC_CALCULATOR, | ||||
KC_MY_COMPUTER, | KC_MY_COMPUTER, | ||||
KC_WWW_FORWARD, | KC_WWW_FORWARD, | ||||
KC_WWW_STOP, | KC_WWW_STOP, | ||||
KC_WWW_REFRESH, | KC_WWW_REFRESH, | ||||
KC_WWW_FAVORITES, | |||||
KC_MEDIA_FAST_FORWARD, | |||||
KC_MEDIA_REWIND, /* 0xBC */ | |||||
KC_WWW_FAVORITES, /* 0xBC */ | |||||
/* Jump to bootloader */ | /* Jump to bootloader */ | ||||
KC_BOOTLOADER = 0xBF, | KC_BOOTLOADER = 0xBF, |
/* | /* | ||||
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 | This program is free software: you can redistribute it and/or modify | ||||
it under the terms of the GNU General Public License as published by | it under the terms of the GNU General Public License as published by | ||||
#include "wait.h" | #include "wait.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "bootloader.h" | #include "bootloader.h" | ||||
#if defined(__AVR__) | |||||
#include <avr/pgmspace.h> | |||||
#endif | |||||
#ifdef BOOTMAGIC_ENABLE | #ifdef BOOTMAGIC_ENABLE | ||||
extern keymap_config_t keymap_config; | extern keymap_config_t keymap_config; | ||||
/* converts key to action */ | /* converts key to action */ | ||||
__attribute__ ((weak)) | |||||
action_t action_for_key(uint8_t layer, keypos_t key) | action_t action_for_key(uint8_t layer, keypos_t key) | ||||
{ | { | ||||
uint8_t keycode = keymap_key_to_keycode(layer, key); | uint8_t keycode = keymap_key_to_keycode(layer, key); | ||||
case KC_LALT: | case KC_LALT: | ||||
if (keymap_config.swap_lalt_lgui) { | if (keymap_config.swap_lalt_lgui) { | ||||
if (keymap_config.no_gui) { | if (keymap_config.no_gui) { | ||||
return keycode_to_action(ACTION_NO); | |||||
return keycode_to_action(KC_NO); | |||||
} | } | ||||
return keycode_to_action(KC_LGUI); | return keycode_to_action(KC_LGUI); | ||||
} | } | ||||
return keycode_to_action(KC_LALT); | return keycode_to_action(KC_LALT); | ||||
} | } | ||||
if (keymap_config.no_gui) { | if (keymap_config.no_gui) { | ||||
return keycode_to_action(ACTION_NO); | |||||
return keycode_to_action(KC_NO); | |||||
} | } | ||||
return keycode_to_action(KC_LGUI); | return keycode_to_action(KC_LGUI); | ||||
case KC_RALT: | case KC_RALT: | ||||
if (keymap_config.swap_ralt_rgui) { | if (keymap_config.swap_ralt_rgui) { | ||||
if (keymap_config.no_gui) { | if (keymap_config.no_gui) { | ||||
return keycode_to_action(ACTION_NO); | |||||
return keycode_to_action(KC_NO); | |||||
} | } | ||||
return keycode_to_action(KC_RGUI); | return keycode_to_action(KC_RGUI); | ||||
} | } | ||||
return keycode_to_action(KC_RALT); | return keycode_to_action(KC_RALT); | ||||
} | } | ||||
if (keymap_config.no_gui) { | if (keymap_config.no_gui) { | ||||
return keycode_to_action(ACTION_NO); | |||||
return keycode_to_action(KC_NO); | |||||
} | } | ||||
return keycode_to_action(KC_RGUI); | return keycode_to_action(KC_RGUI); | ||||
case KC_GRAVE: | case KC_GRAVE: | ||||
/* translates keycode to action */ | /* translates keycode to action */ | ||||
static action_t keycode_to_action(uint8_t keycode) | static action_t keycode_to_action(uint8_t keycode) | ||||
{ | { | ||||
action_t action = {}; | |||||
switch (keycode) { | switch (keycode) { | ||||
case KC_A ... KC_EXSEL: | case KC_A ... KC_EXSEL: | ||||
case KC_LCTRL ... KC_RGUI: | case KC_LCTRL ... KC_RGUI: | ||||
action.code = ACTION_KEY(keycode); | |||||
return (action_t)ACTION_KEY(keycode); | |||||
break; | break; | ||||
case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: | case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: | ||||
action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); | |||||
return (action_t)ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); | |||||
break; | break; | ||||
case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: | case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: | ||||
action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); | |||||
return (action_t)ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); | |||||
break; | break; | ||||
case KC_MS_UP ... KC_MS_ACCEL2: | case KC_MS_UP ... KC_MS_ACCEL2: | ||||
action.code = ACTION_MOUSEKEY(keycode); | |||||
return (action_t)ACTION_MOUSEKEY(keycode); | |||||
break; | break; | ||||
case KC_TRNS: | case KC_TRNS: | ||||
action.code = ACTION_TRANSPARENT; | |||||
return (action_t)ACTION_TRANSPARENT; | |||||
break; | break; | ||||
case KC_BOOTLOADER: | case KC_BOOTLOADER: | ||||
clear_keyboard(); | clear_keyboard(); | ||||
bootloader_jump(); // not return | bootloader_jump(); // not return | ||||
break; | break; | ||||
default: | default: | ||||
action.code = ACTION_NO; | |||||
return (action_t)ACTION_NO; | |||||
break; | break; | ||||
} | } | ||||
return action; | |||||
return (action_t)ACTION_NO; | |||||
} | } | ||||
* Legacy keymap support | * Legacy keymap support | ||||
* Consider using new keymap API instead. | * Consider using new keymap API instead. | ||||
*/ | */ | ||||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | |||||
extern const uint8_t fn_layer[]; | |||||
extern const uint8_t fn_keycode[]; | |||||
__attribute__ ((weak)) | |||||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | |||||
{ | |||||
return pgm_read_byte(&keymaps[(layer)][(row)][(col)]); | |||||
} | |||||
__attribute__ ((weak)) | |||||
uint8_t keymap_fn_layer(uint8_t index) | |||||
{ | |||||
return pgm_read_byte(&fn_layer[index]); | |||||
} | |||||
__attribute__ ((weak)) | |||||
uint8_t keymap_fn_keycode(uint8_t index) | |||||
{ | |||||
return pgm_read_byte(&fn_keycode[index]); | |||||
} | |||||
__attribute__ ((weak)) | __attribute__ ((weak)) | ||||
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key) | uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key) | ||||
{ | { | ||||
__attribute__ ((weak)) | __attribute__ ((weak)) | ||||
action_t keymap_fn_to_action(uint8_t keycode) | action_t keymap_fn_to_action(uint8_t keycode) | ||||
{ | { | ||||
action_t action = { .code = ACTION_NO }; | |||||
switch (keycode) { | switch (keycode) { | ||||
case KC_FN0 ... KC_FN31: | case KC_FN0 ... KC_FN31: | ||||
{ | { | ||||
uint8_t layer = keymap_fn_layer(FN_INDEX(keycode)); | uint8_t layer = keymap_fn_layer(FN_INDEX(keycode)); | ||||
uint8_t key = keymap_fn_keycode(FN_INDEX(keycode)); | uint8_t key = keymap_fn_keycode(FN_INDEX(keycode)); | ||||
if (key) { | if (key) { | ||||
action.code = ACTION_LAYER_TAP_KEY(layer, key); | |||||
return (action_t)ACTION_LAYER_TAP_KEY(layer, key); | |||||
} else { | } else { | ||||
action.code = ACTION_LAYER_MOMENTARY(layer); | |||||
return (action_t)ACTION_LAYER_MOMENTARY(layer); | |||||
} | } | ||||
} | } | ||||
return action; | |||||
return (action_t)ACTION_NO; | |||||
default: | default: | ||||
return action; | |||||
return (action_t)ACTION_NO; | |||||
} | } | ||||
} | } | ||||
#else | |||||
/* user keymaps should be defined somewhere */ | |||||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | |||||
extern const action_t fn_actions[]; | |||||
__attribute__ ((weak)) | |||||
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key) | |||||
{ | |||||
#if defined(__AVR__) | |||||
return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]); | |||||
#else | |||||
return keymaps[(layer)][(key.row)][(key.col)]; | |||||
#endif | |||||
} | |||||
__attribute__ ((weak)) | |||||
action_t keymap_fn_to_action(uint8_t keycode) | |||||
{ | |||||
#if defined(__AVR__) | |||||
return (action_t)pgm_read_word(&fn_actions[FN_INDEX(keycode)]); | |||||
#else | |||||
return fn_actions[FN_INDEX(keycode)]; | |||||
#endif | |||||
} | |||||
#endif | #endif |
/* | |||||
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) {} |
#error "MATRIX_COLS: invalid value" | #error "MATRIX_COLS: invalid value" | ||||
#endif | #endif | ||||
#if (MATRIX_ROWS > 255) | |||||
#error "MATRIX_ROWS must not exceed 255" | |||||
#endif | |||||
#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1<<col)) | #define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1<<col)) | ||||
matrix_row_t matrix_get_row(uint8_t row); | matrix_row_t matrix_get_row(uint8_t row); | ||||
/* print matrix for debug */ | /* print matrix for debug */ | ||||
void matrix_print(void); | void matrix_print(void); | ||||
/* clear matrix */ | |||||
void matrix_clear(void); | |||||
#ifdef MATRIX_HAS_GHOST | |||||
bool matrix_has_ghost_in_row(uint8_t row); | |||||
#endif | |||||
/* power control */ | /* power control */ | ||||
void matrix_power_up(void); | void matrix_power_up(void); |
#define TRANSPORT_STOP_EJECT 0x00CC | #define TRANSPORT_STOP_EJECT 0x00CC | ||||
#define TRANSPORT_PLAY_PAUSE 0x00CD | #define TRANSPORT_PLAY_PAUSE 0x00CD | ||||
/* application launch */ | /* application launch */ | ||||
#define AL_CC_CONFIG 0x0183 | |||||
#define 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 */ | /* 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?) */ | /* supplement for Bluegiga iWRAP HID(not supported by Windows?) */ | ||||
#define AL_LOCK 0x019E | |||||
#define APPLAUNCH_LOCK 0x019E | |||||
#define TRANSPORT_RECORD 0x00B2 | #define TRANSPORT_RECORD 0x00B2 | ||||
#define TRANSPORT_FAST_FORWARD 0x00B3 | #define TRANSPORT_FAST_FORWARD 0x00B3 | ||||
#define TRANSPORT_REWIND 0x00B4 | #define TRANSPORT_REWIND 0x00B4 | ||||
#define TRANSPORT_EJECT 0x00B8 | #define TRANSPORT_EJECT 0x00B8 | ||||
#define AC_MINIMIZE 0x0206 | |||||
#define APPCONTROL_MINIMIZE 0x0206 | |||||
/* Generic Desktop Page(0x01) - system power control */ | /* Generic Desktop Page(0x01) - system power control */ | ||||
#define SYSTEM_POWER_DOWN 0x0081 | #define SYSTEM_POWER_DOWN 0x0081 | ||||
/* keycode to consumer usage */ | /* keycode to consumer usage */ | ||||
#define KEYCODE2CONSUMER(key) \ | #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 | #ifdef __cplusplus | ||||
} | } |
#define SLEEP_LED_H | #define SLEEP_LED_H | ||||
#ifdef SLEEP_LED_ENABLE | |||||
void sleep_led_init(void); | void sleep_led_init(void); | ||||
void sleep_led_enable(void); | void sleep_led_enable(void); | ||||
void sleep_led_disable(void); | void sleep_led_disable(void); | ||||
void sleep_led_toggle(void); | |||||
#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 | #endif |
#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) | |||||
{ | |||||
} |
/* | |||||
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 |
#define XSTR(s) #s | #define XSTR(s) #s | ||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
uint8_t bitpop(uint8_t bits); | uint8_t bitpop(uint8_t bits); | ||||
uint8_t bitpop16(uint16_t bits); | uint8_t bitpop16(uint16_t bits); | ||||
uint8_t bitpop32(uint32_t bits); | uint8_t bitpop32(uint32_t bits); | ||||
uint16_t bitrev16(uint16_t bits); | uint16_t bitrev16(uint16_t bits); | ||||
uint32_t bitrev32(uint32_t bits); | uint32_t bitrev32(uint32_t bits); | ||||
#ifdef __cplusplus | |||||
} | |||||
#endif | |||||
#endif | #endif |
Keycode Symbol Table | Keycode Symbol Table | ||||
==================== | ==================== | ||||
Keycodes are defined in `common/keycode.h`. | Keycodes are defined in `common/keycode.h`. | ||||
Range of 00-A4 and E0-E7 are identical with HID Usage: | |||||
Range of 00-A4 and E0-E7 are identical with HID Usage of Keyboard/Keypad Page(0x07): | |||||
<http://www.usb.org/developers/devclass_docs/Hut1_11.pdf> | <http://www.usb.org/developers/devclass_docs/Hut1_11.pdf> | ||||
Virtual keycodes are defined out of above range to support special actions. | Virtual keycodes are defined out of above range to support special actions. | ||||
/* | /* | ||||
* Virtual keycodes | * Virtual keycodes | ||||
*/ | */ | ||||
/* System Control */ | |||||
/* Generic Desktop Page(0x01) - System Control */ | |||||
KC_SYSTEM_POWER KC_PWR System Power Down | KC_SYSTEM_POWER KC_PWR System Power Down | ||||
KC_SYSTEM_SLEEP KC_SLEP System Sleep | KC_SYSTEM_SLEEP KC_SLEP System Sleep | ||||
KC_SYSTEM_WAKE KC_WAKE System Wake | KC_SYSTEM_WAKE KC_WAKE System Wake | ||||
/* Consumer Page */ | |||||
KC_AUDIO_MUTE KC_MUTE | |||||
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_UP KC_MS_U Mouse Cursor Up | ||||
KC_MS_DOWN KC_MS_D Mouse Cursor Down | KC_MS_DOWN KC_MS_D Mouse Cursor Down | ||||
KC_MS_LEFT KC_MS_L Mouse Cursor Left | KC_MS_LEFT KC_MS_L Mouse Cursor Left | ||||
KC_MS_ACCEL0 KC_ACL0 Mouse Acceleration 0 | KC_MS_ACCEL0 KC_ACL0 Mouse Acceleration 0 | ||||
KC_MS_ACCEL1 KC_ACL1 Mouse Acceleration 1 | KC_MS_ACCEL1 KC_ACL1 Mouse Acceleration 1 | ||||
KC_MS_ACCEL2 KC_ACL2 Mouse Acceleration 2 | KC_MS_ACCEL2 KC_ACL2 Mouse Acceleration 2 | ||||
/* Fn key */ | |||||
/* Fn key - TMK specific */ | |||||
KC_FN0 | KC_FN0 | ||||
KC_FN1 | KC_FN1 | ||||
KC_FN2 | KC_FN2 |
### 0.3 Keymap Example | ### 0.3 Keymap Example | ||||
The keymap is defined in the **`keymaps[]`** array, a 2-dimensional array of rows and columns corresponding to positions in the keyboard matrix. But most often the layers are defined using C macros to allow for easier reading and editing of the keymap files. To use complex actions you need to define `Fn` keycodes in the **`fn_actions[]`** array. | |||||
The keymap is defined in the **`uint8_t keymaps[]`** array, a 2-dimensional array of rows and columns corresponding to positions in the keyboard matrix. But most often the layers are defined using C macros to allow for easier reading and editing of the keymap files. To use complex actions you need to define `Fn` action in the **`action_t fn_actions[]`** array. | |||||
This is a keymap example for the [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard. | This is a keymap example for the [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard. | ||||
This example has three layers: the QWERTY base layer, and two overlay layers for cursor and mousekey control, respectively. | This example has three layers: the QWERTY base layer, and two overlay layers for cursor and mousekey control, respectively. | ||||
You can find other keymap definitions in file `keymap.c` located on project directories. | You can find other keymap definitions in file `keymap.c` located on project directories. | ||||
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||||
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||||
/* 0: Qwerty | /* 0: Qwerty | ||||
* ,-----------------------------------------------------------. | * ,-----------------------------------------------------------. | ||||
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| | * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| | ||||
LGUI,LALT, BTN1, RALT,TRNS), | LGUI,LALT, BTN1, RALT,TRNS), | ||||
}; | }; | ||||
static const uint16_t PROGMEM fn_actions[] = { | |||||
const action_t PROGMEM fn_actions[] = { | |||||
ACTION_LAYER_MOMENTARY(1), // FN0 | ACTION_LAYER_MOMENTARY(1), // FN0 | ||||
ACTION_LAYER_TAP_KEY(2, KC_SCLN), // FN1 | ACTION_LAYER_TAP_KEY(2, KC_SCLN), // FN1 | ||||
ACTION_LAYER_TOGGLE(2), // FN2 | ACTION_LAYER_TOGGLE(2), // FN2 | ||||
- `KC_WSCH`, `KC_WHOM`, `KC_WBAK`, `KC_WFWD`, `KC_WSTP`, `KC_WREF`, `KC_WFAV` for web browser operation | - `KC_WSCH`, `KC_WHOM`, `KC_WBAK`, `KC_WFWD`, `KC_WSTP`, `KC_WREF`, `KC_WFAV` for web browser operation | ||||
### 1.5 Fn key | ### 1.5 Fn key | ||||
`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** | |||||
`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `action_t fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** | |||||
### 1.6 Keycode Table | ### 1.6 Keycode Table | ||||
See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes. | See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes. | ||||
ACTION_DEFAULT_LAYER_BIT_SET(part, bits) | ACTION_DEFAULT_LAYER_BIT_SET(part, bits) | ||||
### 2.3 Macro action | ### 2.3 Macro action | ||||
***TBD*** | |||||
`Macro` actions allow you to register a complex sequence of keystrokes when a key is pressed, where macros are simple sequences of keypresses. | |||||
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. | - **I()** change interval of stroke. | ||||
- **D()** press key | - **D()** press key | ||||
- **SM()** store modifier state | - **SM()** store modifier state | ||||
- **RM()** restore modifier state | - **RM()** restore modifier state | ||||
- **CM()** clear modifier state | - **CM()** clear modifier state | ||||
- **END** end mark | |||||
e.g.: | |||||
MACRO( D(LSHIFT), D(D), END ) // hold down LSHIFT and D - will print 'D' | |||||
MACRO( U(D), U(LSHIFT), END ) // release U and LSHIFT keys (an event.pressed == False counterpart for the one above) | |||||
MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ) // slowly print out h-e-l-l---o | |||||
#### 2.3.2 Examples | #### 2.3.2 Examples | ||||
***TBD*** | |||||
in keymap.c, define `action_get_macro` | |||||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | ||||
{ | { | ||||
switch (id) { | switch (id) { | ||||
case HELLO: | |||||
case 0: | |||||
return (record->event.pressed ? | return (record->event.pressed ? | ||||
MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) : | MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) : | ||||
MACRO_NONE ); | MACRO_NONE ); | ||||
case ALT_TAB: | |||||
case 1: | |||||
return (record->event.pressed ? | return (record->event.pressed ? | ||||
MACRO( D(LALT), D(TAB), END ) : | MACRO( D(LALT), D(TAB), END ) : | ||||
MACRO( U(TAB), END )); | MACRO( U(TAB), END )); | ||||
return MACRO_NONE; | return MACRO_NONE; | ||||
} | } | ||||
in keymap.c, bind items in `fn_actions` to the macro function | |||||
const action_t PROGMEM fn_actions[] = { | |||||
[0] = ACTION_MACRO(0), // will print 'hello' for example | |||||
[1] = ACTION_MACRO(1), | |||||
}; | |||||
### 2.4 Function action | ### 2.4 Function action | ||||
#### 2.4.3 Implement user function | #### 2.4.3 Implement user function | ||||
`Function` actions can be defined freely with C by user in callback function: | `Function` actions can be defined freely with C by user in callback function: | ||||
void keymap_call_function(keyrecord_t *event, uint8_t id, uint8_t opt) | |||||
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt); | |||||
This C function is called every time key is operated, argument `id` selects action to be performed and `opt` can be used for option. Function `id` can be 0-255 and `opt` can be 0-15. | This C function is called every time key is operated, argument `id` selects action to be performed and `opt` can be used for option. Function `id` can be 0-255 and `opt` can be 0-15. | ||||
ACTION_LAYER_MODS(2, MOD_LSFT | MOD_LALT) | ACTION_LAYER_MODS(2, MOD_LSFT | MOD_LALT) | ||||
This function can only register left-sided modifiers. The handedness of the modifier (left/right) is an extra bit that is not able to be passed through into the layer system. See: [`common/action_code.h`](../common/action_code.h), the spec for ACT_LAYER_TAP only allows four bits for the mods, whereas the mods themselves require five bits, with the high bit being the left/right handedness. | |||||
## 4. Tapping | ## 4. Tapping | ||||
In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tapping while `Fn0` and `Fn1` doesn't send any key. | In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tapping while `Fn0` and `Fn1` doesn't send any key. | ||||
static const uint8_t PROGMEM fn_layer[] = { | |||||
const uint8_t PROGMEM fn_layer[] = { | |||||
1, // Fn0 | 1, // Fn0 | ||||
2, // Fn1 | 2, // Fn1 | ||||
2, // Fn2 | 2, // Fn2 | ||||
}; | }; | ||||
static const uint8_t PROGMEM fn_keycode[] = { | |||||
const uint8_t PROGMEM fn_keycode[] = { | |||||
KC_NO, // Fn0 | KC_NO, // Fn0 | ||||
KC_NO, // Fn1 | KC_NO, // Fn1 | ||||
KC_SPC, // Fn2 | KC_SPC, // Fn2 |
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]; |
PROTOCOL_DIR = protocol | PROTOCOL_DIR = protocol | ||||
ifdef PS2_MOUSE_ENABLE | |||||
ifeq (yes,$(strip $(PS2_MOUSE_ENABLE))) | |||||
SRC += $(PROTOCOL_DIR)/ps2_mouse.c | SRC += $(PROTOCOL_DIR)/ps2_mouse.c | ||||
OPT_DEFS += -DPS2_MOUSE_ENABLE | OPT_DEFS += -DPS2_MOUSE_ENABLE | ||||
OPT_DEFS += -DMOUSE_ENABLE | OPT_DEFS += -DMOUSE_ENABLE | ||||
endif | endif | ||||
ifdef PS2_USE_BUSYWAIT | |||||
ifeq (yes,$(strip $(PS2_USE_BUSYWAIT))) | |||||
SRC += protocol/ps2_busywait.c | SRC += protocol/ps2_busywait.c | ||||
SRC += protocol/ps2_io_avr.c | SRC += protocol/ps2_io_avr.c | ||||
OPT_DEFS += -DPS2_USE_BUSYWAIT | OPT_DEFS += -DPS2_USE_BUSYWAIT | ||||
endif | endif | ||||
ifdef PS2_USE_INT | |||||
ifeq (yes,$(strip $(PS2_USE_INT))) | |||||
SRC += protocol/ps2_interrupt.c | SRC += protocol/ps2_interrupt.c | ||||
SRC += protocol/ps2_io_avr.c | SRC += protocol/ps2_io_avr.c | ||||
OPT_DEFS += -DPS2_USE_INT | OPT_DEFS += -DPS2_USE_INT | ||||
endif | endif | ||||
ifdef PS2_USE_USART | |||||
ifeq (yes,$(strip $(PS2_USE_USART))) | |||||
SRC += protocol/ps2_usart.c | SRC += protocol/ps2_usart.c | ||||
SRC += protocol/ps2_io_avr.c | SRC += protocol/ps2_io_avr.c | ||||
OPT_DEFS += -DPS2_USE_USART | OPT_DEFS += -DPS2_USE_USART | ||||
endif | endif | ||||
ifdef SERIAL_MOUSE_MICROSOFT_ENABLE | |||||
ifeq (yes,$(strip $(XT_USE_INT))) | |||||
SRC += protocol/xt_interrupt.c | |||||
SRC += protocol/xt_io_avr.c | |||||
OPT_DEFS += -DXT_USE_INT | |||||
endif | |||||
ifeq (yes,$(strip $(SERIAL_MOUSE_MICROSOFT_ENABLE))) | |||||
SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c | SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c | ||||
OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \ | OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \ | ||||
-DMOUSE_ENABLE | -DMOUSE_ENABLE | ||||
endif | endif | ||||
ifdef SERIAL_MOUSE_MOUSESYSTEMS_ENABLE | |||||
ifeq (yes,$(strip $(SERIAL_MOUSE_MOUSESYSTEMS_ENABLE))) | |||||
SRC += $(PROTOCOL_DIR)/serial_mouse_mousesystems.c | SRC += $(PROTOCOL_DIR)/serial_mouse_mousesystems.c | ||||
OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MOUSESYSTEMS \ | OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MOUSESYSTEMS \ | ||||
-DMOUSE_ENABLE | -DMOUSE_ENABLE | ||||
endif | endif | ||||
ifdef SERIAL_MOUSE_USE_SOFT | |||||
ifeq (yes,$(strip $(SERIAL_MOUSE_USE_SOFT))) | |||||
SRC += $(PROTOCOL_DIR)/serial_soft.c | SRC += $(PROTOCOL_DIR)/serial_soft.c | ||||
endif | endif | ||||
ifdef SERIAL_MOUSE_USE_UART | |||||
ifeq (yes,$(strip $(SERIAL_MOUSE_USE_UART))) | |||||
SRC += $(PROTOCOL_DIR)/serial_uart.c | SRC += $(PROTOCOL_DIR)/serial_uart.c | ||||
endif | endif | ||||
ifdef ADB_MOUSE_ENABLE | |||||
ifeq (yes,$(strip $(ADB_MOUSE_ENABLE))) | |||||
OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE | OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE | ||||
endif | endif | ||||
static inline void send_byte(uint8_t data); | static inline void send_byte(uint8_t data); | ||||
static inline uint16_t wait_data_lo(uint16_t us); | static inline uint16_t wait_data_lo(uint16_t us); | ||||
static inline uint16_t wait_data_hi(uint16_t us); | static inline uint16_t wait_data_hi(uint16_t us); | ||||
static inline uint16_t adb_host_dev_recv(uint8_t device); | |||||
void adb_host_init(void) | void adb_host_init(void) | ||||
* <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> | * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> | ||||
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> | * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> | ||||
*/ | */ | ||||
// 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 | #ifdef ADB_MOUSE_ENABLE | ||||
uint16_t adb_host_mouse_recv(void) | uint16_t adb_host_mouse_recv(void) | ||||
{ | { | ||||
return adb_host_dev_recv(ADDR_MOUSE); | |||||
return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); | |||||
} | } | ||||
#endif | #endif | ||||
static inline uint16_t adb_host_dev_recv(uint8_t device) | |||||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg) | |||||
{ | { | ||||
uint16_t data = 0; | uint16_t data = 0; | ||||
cli(); | cli(); | ||||
attention(); | attention(); | ||||
send_byte(device|0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00) | |||||
send_byte((addr<<4) | (ADB_CMD_TALK<<2) | reg); | |||||
place_bit0(); // Stopbit(0) | place_bit0(); // Stopbit(0) | ||||
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored | if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored | ||||
sei(); | sei(); | ||||
sei(); | sei(); | ||||
return 0; // No data to send | return 0; // No data to send | ||||
} | } | ||||
uint8_t n = 17; // start bit + 16 data bits | uint8_t n = 17; // start bit + 16 data bits | ||||
do { | do { | ||||
uint8_t lo = (uint8_t) wait_data_hi(130); | uint8_t lo = (uint8_t) wait_data_hi(130); | ||||
if (!lo) | if (!lo) | ||||
goto error; | goto error; | ||||
uint8_t hi = (uint8_t) wait_data_lo(lo); | uint8_t hi = (uint8_t) wait_data_lo(lo); | ||||
if (!hi) | if (!hi) | ||||
goto error; | goto error; | ||||
hi = lo - hi; | hi = lo - hi; | ||||
lo = 130 - lo; | lo = 130 - lo; | ||||
data <<= 1; | data <<= 1; | ||||
if (lo < hi) { | if (lo < hi) { | ||||
data |= 1; | data |= 1; | ||||
return -n; | return -n; | ||||
} | } | ||||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) | |||||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) | |||||
{ | { | ||||
cli(); | cli(); | ||||
attention(); | attention(); | ||||
send_byte(cmd); | |||||
send_byte((addr<<4) | (ADB_CMD_LISTEN<<2) | reg); | |||||
place_bit0(); // Stopbit(0) | place_bit0(); // Stopbit(0) | ||||
_delay_us(200); // Tlt/Stop to Start | _delay_us(200); // Tlt/Stop to Start | ||||
place_bit1(); // Startbit(1) | place_bit1(); // Startbit(1) | ||||
send_byte(data_h); | |||||
send_byte(data_h); | |||||
send_byte(data_l); | send_byte(data_l); | ||||
place_bit0(); // Stopbit(0); | place_bit0(); // Stopbit(0); | ||||
sei(); | sei(); | ||||
} | } | ||||
// send state of LEDs | // send state of LEDs | ||||
void adb_host_kbd_led(uint8_t led) | |||||
void adb_host_kbd_led(uint8_t addr, uint8_t led) | |||||
{ | { | ||||
// Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) | |||||
// 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); | |||||
} | } | ||||
bits commands | bits commands | ||||
------------------------------------------------------ | ------------------------------------------------------ | ||||
- - - - 0 0 0 0 Send Request(reset all devices) | |||||
- - - - 0 0 0 0 Send Reset(reset all devices) | |||||
A A A A 0 0 0 1 Flush(reset a device) | A A A A 0 0 0 1 Flush(reset a device) | ||||
- - - - 0 0 1 0 Reserved | - - - - 0 0 1 0 Reserved | ||||
- - - - 0 0 1 1 Reserved | - - - - 0 0 1 1 Reserved | ||||
A A A A 1 1 R R Talk(read from a device) | A A A A 1 1 R R Talk(read from a device) | ||||
The command to read keycodes from keyboard is 0x2C which | The command to read keycodes from keyboard is 0x2C which | ||||
consist of keyboard address 2 and Talk against register 0. | |||||
consist of keyboard address 2 and Talk against register 0. | |||||
Address: | Address: | ||||
2: keyboard | 2: keyboard | ||||
Keyboard LEDs & state of keys(Register2) | Keyboard LEDs & state of keys(Register2) | ||||
This register hold current state of three LEDs and nine keys. | This register hold current state of three LEDs and nine keys. | ||||
The state of LEDs can be changed by sending Listen command. | The state of LEDs can be changed by sending Listen command. | ||||
1514 . . . . . . 7 6 5 . 3 2 1 0 | 1514 . . . . . . 7 6 5 . 3 2 1 0 | ||||
| | | | | | | | | | | | | | | +- LED1(NumLock) | | | | | | | | | | | | | | | | +- LED1(NumLock) | ||||
| | | | | | | | | | | | | | +--- LED2(CapsLock) | | | | | | | | | | | | | | | +--- LED2(CapsLock) | ||||
| +----------------------------- Delete | | +----------------------------- Delete | ||||
+------------------------------- Reserved | +------------------------------- Reserved | ||||
Address, Handler ID and bits(Register3) | |||||
1514131211 . . 8 7 . . . . . . 0 | |||||
| | | | | | | | | | | | | | | | | |||||
| | | | | | | | +-+-+-+-+-+-+-+- Handler ID | |||||
| | | | +-+-+-+----------------- Address | |||||
| | | +------------------------- 0 | |||||
| | +--------------------------- Service request enable(1 = enabled) | |||||
| +----------------------------- Exceptional event(alwyas 1 if not used) | |||||
+------------------------------- 0 | |||||
ADB Bit Cells | |||||
bit cell time: 70-130us | |||||
low part of bit0: 60-70% of bit cell | |||||
low part of bit1: 30-40% of bit cell | |||||
bit cell time 70us 130us | |||||
-------------------------------------------- | |||||
low part of bit0 42-49 78-91 | |||||
high part of bit0 21-28 39-52 | |||||
low part of bit1 21-28 39-52 | |||||
high part of bit1 42-49 78-91 | |||||
bit0: | |||||
70us bit cell: | |||||
____________~~~~~~ | |||||
42-49 21-28 | |||||
130us bit cell: | |||||
____________~~~~~~ | |||||
78-91 39-52 | |||||
bit1: | |||||
70us bit cell: | |||||
______~~~~~~~~~~~~ | |||||
21-28 42-49 | |||||
130us bit cell: | |||||
______~~~~~~~~~~~~ | |||||
39-52 78-91 | |||||
[from Apple IIgs Hardware Reference Second Edition] | |||||
Keyboard Handle ID | |||||
Apple Standard Keyboard M0116: 0x01 | |||||
Apple Extended Keyboard M0115: 0x02 | |||||
Apple Extended Keyboard II M3501: 0x02 | |||||
Apple Adjustable Keybaord: 0x10 | |||||
http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802 | |||||
END_OF_ADB | END_OF_ADB | ||||
*/ | */ |
#define ADB_CAPS 0x39 | #define ADB_CAPS 0x39 | ||||
/* ADB commands */ | |||||
// Default Address | |||||
#define ADB_ADDR_DONGLE 1 | |||||
#define ADB_ADDR_KEYBOARD 2 | |||||
#define ADB_ADDR_MOUSE 3 | |||||
#define ADB_ADDR_TABLET 4 | |||||
#define ADB_ADDR_APPLIANCE 7 | |||||
// Command Type | |||||
#define ADB_CMD_RESET 0 | |||||
#define ADB_CMD_FLUSH 1 | |||||
#define ADB_CMD_LISTEN 2 | |||||
#define ADB_CMD_TALK 3 | |||||
// Register | |||||
#define ADB_REG_0 0 | |||||
#define ADB_REG_1 1 | |||||
#define ADB_REG_2 2 | |||||
#define ADB_REG_3 3 | |||||
/* ADB keyboard handler id */ | |||||
#define ADB_HANDLER_M0116 0x01 | |||||
#define ADB_HANDLER_IIGS 0x01 | |||||
#define ADB_HANDLER_M0115 0x02 | |||||
#define ADB_HANDLER_M3501 0x02 | |||||
#define ADB_HANDLER_M1242_ANSI 0x10 | |||||
#define ADB_HANDLER_EXTENDED_PROTOCOL 0x03 | |||||
// ADB host | // ADB host | ||||
void adb_host_init(void); | void adb_host_init(void); | ||||
bool adb_host_psw(void); | bool adb_host_psw(void); | ||||
uint16_t adb_host_kbd_recv(void); | |||||
uint16_t adb_host_kbd_recv(uint8_t addr); | |||||
uint16_t adb_host_mouse_recv(void); | uint16_t adb_host_mouse_recv(void); | ||||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); | |||||
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_task(void); | ||||
void adb_mouse_init(void); | void adb_mouse_init(void); | ||||
+-------------------------------------+-------+ | +-------------------------------------+-------+ | ||||
*/ | */ | ||||
#define CONSUMER2BLUEFRUIT(usage) \ | #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) | static void send_consumer(uint16_t data) | ||||
{ | { |
## TMK running on top of ChibiOS | ## TMK running on top of ChibiOS | ||||
This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever [ChibiOS] supports. The notable examples are ARM-based Teensies (3.x and LC) and on the boards with STM32 MCUs. | |||||
This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever ChibiOS supports. The notable examples are PJRC Teensies(3.x and LC) with NXP Kinetis and dev boards with ST Micro STM32 MCUs. | |||||
### Usage | ### Usage | ||||
- To use, [get a zip of chibios](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip) and unpack/rename it to `tmk_core/tool/chibios/chibios`; or you can just clone [the repo](https://github.com/ChibiOS/ChibiOS) there. For Freescale/NXP Kinetis support (meaning ARM Teensies and the Infinity keyboard), you'll also need [a zip of chibios-contrib](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip), unpacked/renamed to `tmk_core/tool/chibios/chibios-contrib`. Likewise, for git-savvy people, just clone [the repo](https://github.com/ChibiOS/ChibiOS-Contrib) there. | |||||
- 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. | - You will also need to install an ARM toolchain, for instance from [here](https://launchpad.net/gcc-arm-embedded). On linux, this is usually also present as a package for your distribution (as `gcc-arm` or something similar). On OS X, you can use [homebrew](http://brew.sh/) with an appropriate tap. | ||||
### Notes | ### Notes | ||||
- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for ARM Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md). | |||||
- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md). | |||||
- For gcc options, inspect `tmk_core/tool/chibios/chibios.mk`. For instance, I enabled `-Wno-missing-field-initializers`, because TMK common bits generated a lot of warnings on that. | - For gcc options, inspect `tmk_core/tool/chibios/chibios.mk`. For instance, I enabled `-Wno-missing-field-initializers`, because TMK common bits generated a lot of warnings on that. | ||||
- For debugging, it is sometimes useful disable gcc optimisations, you can do that by adding `-O0` to `OPT_DEFS` in your `Makefile`. | - For debugging, it is sometimes useful disable gcc optimisations, you can do that by adding `-O0` to `OPT_DEFS` in your `Makefile`. | ||||
- USB string descriptors are messy. I did not find a way to cleanly generate the right structures from actual strings, so the definitions in individual keyboards' `config.h` are ugly as heck. | - USB string descriptors are messy. I did not find a way to cleanly generate the right structures from actual strings, so the definitions in individual keyboards' `config.h` are ugly as heck. |
0x95, KBD_REPORT_KEYS, // Report Count (), | 0x95, KBD_REPORT_KEYS, // Report Count (), | ||||
0x75, 0x08, // Report Size (8), | 0x75, 0x08, // Report Size (8), | ||||
0x15, 0x00, // Logical Minimum (0), | 0x15, 0x00, // Logical Minimum (0), | ||||
0x25, 0xFF, // Logical Maximum(255), | |||||
0x26, 0xFF, 0x00, // Logical Maximum(255), | |||||
0x05, 0x07, // Usage Page (Key Codes), | 0x05, 0x07, // Usage Page (Key Codes), | ||||
0x19, 0x00, // Usage Minimum (0), | 0x19, 0x00, // Usage Minimum (0), | ||||
0x29, 0xFF, // Usage Maximum (255), | 0x29, 0xFF, // Usage Maximum (255), | ||||
0xa1, 0x01, // COLLECTION (Application) | 0xa1, 0x01, // COLLECTION (Application) | ||||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | ||||
0x15, 0x01, // LOGICAL_MINIMUM (0x1) | 0x15, 0x01, // LOGICAL_MINIMUM (0x1) | ||||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) | |||||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7) | |||||
0x19, 0x01, // USAGE_MINIMUM (0x1) | 0x19, 0x01, // USAGE_MINIMUM (0x1) | ||||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | 0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | ||||
0x75, 0x10, // REPORT_SIZE (16) | 0x75, 0x10, // REPORT_SIZE (16) |
#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT | #LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT | ||||
LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 | LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 | ||||
LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1 | LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1 | ||||
# Remote wakeup fix for ATmega32U2 https://github.com/tmk/tmk_keyboard/issues/361 | |||||
ifeq ($(MCU),atmega32u2) | |||||
LUFA_OPTS += -DNO_LIMITED_CONTROLLER_CONNECT | |||||
endif | |||||
OPT_DEFS += -DF_USB=$(F_USB)UL | OPT_DEFS += -DF_USB=$(F_USB)UL | ||||
OPT_DEFS += -DARCH=ARCH_$(ARCH) | OPT_DEFS += -DARCH=ARCH_$(ARCH) | ||||
# This indicates using LUFA stack | # This indicates using LUFA stack | ||||
OPT_DEFS += -DPROTOCOL_LUFA | OPT_DEFS += -DPROTOCOL_LUFA | ||||
ifeq (yes,$(strip $(LUFA_DEBUG_SUART))) | |||||
SRC += common/avr/suart.S | |||||
LUFA_OPTS += -DLUFA_DEBUG_SUART | |||||
endif |
HID_RI_OUTPUT(8, HID_IOF_CONSTANT), | HID_RI_OUTPUT(8, HID_IOF_CONSTANT), | ||||
HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */ | HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */ | ||||
HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */ | |||||
HID_RI_USAGE_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_MINIMUM(8, 0x00), | ||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), | |||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), /* needs 16 bit to indicate positive value */ | |||||
HID_RI_REPORT_COUNT(8, 0x06), | HID_RI_REPORT_COUNT(8, 0x06), | ||||
HID_RI_REPORT_SIZE(8, 0x08), | HID_RI_REPORT_SIZE(8, 0x08), | ||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), | ||||
HID_RI_USAGE(8, 0x80), /* System Control */ | HID_RI_USAGE(8, 0x80), /* System Control */ | ||||
HID_RI_COLLECTION(8, 0x01), /* Application */ | HID_RI_COLLECTION(8, 0x01), /* Application */ | ||||
HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM), | HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM), | ||||
HID_RI_LOGICAL_MINIMUM(16, 0x0001), | |||||
HID_RI_LOGICAL_MINIMUM(16, 0x0081), | |||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00B7), | HID_RI_LOGICAL_MAXIMUM(16, 0x00B7), | ||||
HID_RI_USAGE_MINIMUM(16, 0x0001), /* System Power Down */ | |||||
HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */ | |||||
HID_RI_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */ | HID_RI_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */ | ||||
HID_RI_REPORT_SIZE(8, 16), | HID_RI_REPORT_SIZE(8, 16), | ||||
HID_RI_REPORT_COUNT(8, 1), | HID_RI_REPORT_COUNT(8, 1), | ||||
HID_RI_COLLECTION(8, 0x01), /* Application */ | HID_RI_COLLECTION(8, 0x01), /* Application */ | ||||
HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */ | HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */ | ||||
HID_RI_LOGICAL_MINIMUM(8, 0x00), | HID_RI_LOGICAL_MINIMUM(8, 0x00), | ||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), | |||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), | |||||
HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), | HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), | ||||
HID_RI_REPORT_SIZE(8, 0x08), | HID_RI_REPORT_SIZE(8, 0x08), | ||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), | ||||
HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */ | HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */ | ||||
HID_RI_LOGICAL_MINIMUM(8, 0x00), | HID_RI_LOGICAL_MINIMUM(8, 0x00), | ||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), | |||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), | |||||
HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), | HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), | ||||
HID_RI_REPORT_SIZE(8, 0x08), | HID_RI_REPORT_SIZE(8, 0x08), | ||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), | HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), |
#define MOUSE_EPSIZE 8 | #define MOUSE_EPSIZE 8 | ||||
#define EXTRAKEY_EPSIZE 8 | #define EXTRAKEY_EPSIZE 8 | ||||
#define CONSOLE_EPSIZE 32 | #define CONSOLE_EPSIZE 32 | ||||
#define NKRO_EPSIZE 16 | |||||
#define NKRO_EPSIZE 32 | |||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, |
/* | |||||
/* | |||||
* Copyright 2012 Jun Wako <[email protected]> | * Copyright 2012 Jun Wako <[email protected]> | ||||
* This file is based on: | * This file is based on: | ||||
* LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse | * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse | ||||
#include "suspend.h" | #include "suspend.h" | ||||
#include "hook.h" | #include "hook.h" | ||||
#ifdef LUFA_DEBUG_SUART | |||||
#include "avr/suart.h" | |||||
#endif | |||||
#include "matrix.h" | |||||
#include "descriptor.h" | #include "descriptor.h" | ||||
#include "lufa.h" | #include "lufa.h" | ||||
//#define LUFA_DEBUG | |||||
uint8_t keyboard_idle = 0; | uint8_t keyboard_idle = 0; | ||||
/* 0: Boot Protocol, 1: Report Protocol(default) */ | /* 0: Boot Protocol, 1: Report Protocol(default) */ | ||||
uint8_t keyboard_protocol = 1; | uint8_t keyboard_protocol = 1; | ||||
{ | { | ||||
/* Create a temporary buffer to hold the read in report from the host */ | /* Create a temporary buffer to hold the read in report from the host */ | ||||
uint8_t ConsoleData[CONSOLE_EPSIZE]; | uint8_t ConsoleData[CONSOLE_EPSIZE]; | ||||
/* Read Console Report Data */ | /* Read Console Report Data */ | ||||
Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL); | Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL); | ||||
/* Process Console Report Data */ | /* Process Console Report Data */ | ||||
//ProcessConsoleHIDReport(ConsoleData); | //ProcessConsoleHIDReport(ConsoleData); | ||||
} | } | ||||
print("[D]"); | print("[D]"); | ||||
/* For battery powered device */ | /* For battery powered device */ | ||||
USB_IsInitialized = false; | USB_IsInitialized = false; | ||||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated. | |||||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated. | |||||
if (USB_IsInitialized) { | if (USB_IsInitialized) { | ||||
USB_Disable(); // Disable all interrupts | USB_Disable(); // Disable all interrupts | ||||
USB_Controller_Enable(); | USB_Controller_Enable(); | ||||
void EVENT_USB_Device_Reset(void) | void EVENT_USB_Device_Reset(void) | ||||
{ | { | ||||
#ifdef LUFA_DEBUG | |||||
print("[R]"); | print("[R]"); | ||||
#endif | |||||
} | } | ||||
void EVENT_USB_Device_Suspend() | void EVENT_USB_Device_Suspend() | ||||
{ | { | ||||
#ifdef LUFA_DEBUG | |||||
print("[S]"); | print("[S]"); | ||||
#endif | |||||
hook_usb_suspend_entry(); | hook_usb_suspend_entry(); | ||||
} | } | ||||
void EVENT_USB_Device_WakeUp() | void EVENT_USB_Device_WakeUp() | ||||
{ | { | ||||
#ifdef LUFA_DEBUG | |||||
print("[W]"); | print("[W]"); | ||||
#endif | |||||
hook_usb_wakeup(); | hook_usb_wakeup(); | ||||
} | } | ||||
*/ | */ | ||||
void EVENT_USB_Device_ConfigurationChanged(void) | void EVENT_USB_Device_ConfigurationChanged(void) | ||||
{ | { | ||||
#ifdef LUFA_DEBUG | |||||
print("[c]"); | |||||
#endif | |||||
bool ConfigSuccess = true; | bool ConfigSuccess = true; | ||||
/* Setup Keyboard HID Report Endpoints */ | /* Setup Keyboard HID Report Endpoints */ | ||||
/* Write the report data to the control endpoint */ | /* Write the report data to the control endpoint */ | ||||
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); | Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); | ||||
Endpoint_ClearOUT(); | Endpoint_ClearOUT(); | ||||
#ifdef LUFA_DEBUG | |||||
xprintf("[r%d]", USB_ControlRequest.wIndex); | |||||
#endif | |||||
} | } | ||||
break; | break; | ||||
Endpoint_ClearOUT(); | Endpoint_ClearOUT(); | ||||
Endpoint_ClearStatusStage(); | Endpoint_ClearStatusStage(); | ||||
#ifdef LUFA_DEBUG | |||||
xprintf("[L%d]", USB_ControlRequest.wIndex); | |||||
#endif | |||||
break; | break; | ||||
} | } | ||||
Endpoint_Write_8(keyboard_protocol); | Endpoint_Write_8(keyboard_protocol); | ||||
Endpoint_ClearIN(); | Endpoint_ClearIN(); | ||||
Endpoint_ClearStatusStage(); | Endpoint_ClearStatusStage(); | ||||
#ifdef LUFA_DEBUG | |||||
print("[p]"); | |||||
#endif | |||||
} | } | ||||
} | } | ||||
keyboard_protocol = (USB_ControlRequest.wValue & 0xFF); | keyboard_protocol = (USB_ControlRequest.wValue & 0xFF); | ||||
clear_keyboard(); | clear_keyboard(); | ||||
#ifdef LUFA_DEBUG | |||||
print("[P]"); | |||||
#endif | |||||
} | } | ||||
} | } | ||||
Endpoint_ClearStatusStage(); | Endpoint_ClearStatusStage(); | ||||
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); | keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); | ||||
#ifdef LUFA_DEBUG | |||||
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8); | |||||
#endif | |||||
} | } | ||||
break; | break; | ||||
Endpoint_Write_8(keyboard_idle); | Endpoint_Write_8(keyboard_idle); | ||||
Endpoint_ClearIN(); | Endpoint_ClearIN(); | ||||
Endpoint_ClearStatusStage(); | Endpoint_ClearStatusStage(); | ||||
#ifdef LUFA_DEBUG | |||||
print("[i]"); | |||||
#endif | |||||
} | } | ||||
break; | break; | ||||
} | } | ||||
/******************************************************************************* | /******************************************************************************* | ||||
* Host driver | |||||
* Host driver | |||||
******************************************************************************/ | ******************************************************************************/ | ||||
static uint8_t keyboard_leds(void) | static uint8_t keyboard_leds(void) | ||||
{ | { | ||||
#define SEND_TIMEOUT 5 | #define SEND_TIMEOUT 5 | ||||
int8_t sendchar(uint8_t c) | int8_t sendchar(uint8_t c) | ||||
{ | { | ||||
#ifdef LUFA_DEBUG_SUART | |||||
xmit(c); | |||||
#endif | |||||
// Not wait once timeouted. | // Not wait once timeouted. | ||||
// Because sendchar() is called so many times, waiting each call causes big lag. | // Because sendchar() is called so many times, waiting each call causes big lag. | ||||
static bool timeouted = false; | static bool timeouted = false; | ||||
#else | #else | ||||
int8_t sendchar(uint8_t c) | int8_t sendchar(uint8_t c) | ||||
{ | { | ||||
#ifdef LUFA_DEBUG_SUART | |||||
xmit(c); | |||||
#endif | |||||
return 0; | return 0; | ||||
} | } | ||||
#endif | #endif | ||||
// for Console_Task | // for Console_Task | ||||
USB_Device_EnableSOFEvents(); | USB_Device_EnableSOFEvents(); | ||||
print_set_sendchar(sendchar); | |||||
} | } | ||||
int main(void) __attribute__ ((weak)); | int main(void) __attribute__ ((weak)); | ||||
int main(void) | int main(void) | ||||
{ | { | ||||
setup_mcu(); | setup_mcu(); | ||||
#ifdef LUFA_DEBUG_SUART | |||||
SUART_OUT_DDR |= (1<<SUART_OUT_BIT); | |||||
SUART_OUT_PORT |= (1<<SUART_OUT_BIT); | |||||
#endif | |||||
print_set_sendchar(sendchar); | |||||
print("\r\ninit\n"); | |||||
hook_early_init(); | hook_early_init(); | ||||
keyboard_setup(); | keyboard_setup(); | ||||
setup_usb(); | setup_usb(); | ||||
hook_late_init(); | hook_late_init(); | ||||
while (1) { | while (1) { | ||||
while (USB_DeviceState == DEVICE_STATE_Suspended) { | while (USB_DeviceState == DEVICE_STATE_Suspended) { | ||||
#ifdef LUFA_DEBUG | |||||
print("[s]"); | print("[s]"); | ||||
#endif | |||||
hook_usb_suspend_loop(); | hook_usb_suspend_loop(); | ||||
} | } | ||||
__attribute__((weak)) | __attribute__((weak)) | ||||
void hook_late_init(void) {} | void hook_late_init(void) {} | ||||
static uint8_t _led_stats = 0; | |||||
__attribute__((weak)) | __attribute__((weak)) | ||||
void hook_usb_suspend_entry(void) | void hook_usb_suspend_entry(void) | ||||
{ | { | ||||
// Turn LED off to save power | |||||
// Set 0 with putting aside status before suspend and restore | |||||
// it after wakeup, then LED is updated at keyboard_task() in main loop | |||||
_led_stats = keyboard_led_stats; | |||||
keyboard_led_stats = 0; | |||||
led_set(keyboard_led_stats); | |||||
matrix_clear(); | |||||
clear_keyboard(); | |||||
#ifdef SLEEP_LED_ENABLE | #ifdef SLEEP_LED_ENABLE | ||||
sleep_led_enable(); | sleep_led_enable(); | ||||
#endif | #endif | ||||
{ | { | ||||
suspend_power_down(); | suspend_power_down(); | ||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | ||||
USB_Device_SendRemoteWakeup(); | |||||
USB_Device_SendRemoteWakeup(); | |||||
} | } | ||||
} | } | ||||
suspend_wakeup_init(); | suspend_wakeup_init(); | ||||
#ifdef SLEEP_LED_ENABLE | #ifdef SLEEP_LED_ENABLE | ||||
sleep_led_disable(); | sleep_led_disable(); | ||||
// NOTE: converters may not accept this | |||||
led_set(host_keyboard_leds()); | |||||
#endif | #endif | ||||
// Restore LED status | |||||
// BIOS/grub won't recognize/enumerate if led_set() takes long(around 40ms?) | |||||
// Converters fall into the case and miss wakeup event(timeout to reply?) in the end. | |||||
//led_set(host_keyboard_leds()); | |||||
// Instead, restore stats and update at keyboard_task() in main loop | |||||
keyboard_led_stats = _led_stats; | |||||
} | } |
REPORT_COUNT(1), 0x06, | REPORT_COUNT(1), 0x06, | ||||
REPORT_SIZE(1), 0x08, | REPORT_SIZE(1), 0x08, | ||||
LOGICAL_MINIMUM(1), 0x00, | LOGICAL_MINIMUM(1), 0x00, | ||||
LOGICAL_MAXIMUM(1), 0xFF, | |||||
LOGICAL_MAXIMUM(2), 0xFF, 0x00, | |||||
USAGE_PAGE(1), 0x07, // Key Codes | USAGE_PAGE(1), 0x07, // Key Codes | ||||
USAGE_MINIMUM(1), 0x00, | USAGE_MINIMUM(1), 0x00, | ||||
USAGE_MAXIMUM(1), 0xFF, | USAGE_MAXIMUM(1), 0xFF, |
/*-------------------------------------------------------------------- | |||||
* 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 |
0x95, KBD_REPORT_KEYS, // Report Count (), | 0x95, KBD_REPORT_KEYS, // Report Count (), | ||||
0x75, 0x08, // Report Size (8), | 0x75, 0x08, // Report Size (8), | ||||
0x15, 0x00, // Logical Minimum (0), | 0x15, 0x00, // Logical Minimum (0), | ||||
0x25, 0xFF, // Logical Maximum(255), | |||||
0x26, 0xFF, 0x00, // Logical Maximum(255), | |||||
0x05, 0x07, // Usage Page (Key Codes), | 0x05, 0x07, // Usage Page (Key Codes), | ||||
0x19, 0x00, // Usage Minimum (0), | 0x19, 0x00, // Usage Minimum (0), | ||||
0x29, 0xFF, // Usage Maximum (255), | 0x29, 0xFF, // Usage Maximum (255), | ||||
0xa1, 0x01, // COLLECTION (Application) | 0xa1, 0x01, // COLLECTION (Application) | ||||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | ||||
0x15, 0x01, // LOGICAL_MINIMUM (0x1) | 0x15, 0x01, // LOGICAL_MINIMUM (0x1) | ||||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) | |||||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7) | |||||
0x19, 0x01, // USAGE_MINIMUM (0x1) | 0x19, 0x01, // USAGE_MINIMUM (0x1) | ||||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | 0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | ||||
0x75, 0x10, // REPORT_SIZE (16) | 0x75, 0x10, // REPORT_SIZE (16) |
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <avr/interrupt.h> | #include <avr/interrupt.h> | ||||
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "pbuff.h" | |||||
#include "ps2.h" | #include "ps2.h" | ||||
#include "ps2_io.h" | #include "ps2_io.h" | ||||
#include "print.h" | #include "print.h" | ||||
uint8_t ps2_error = PS2_ERR_NONE; | uint8_t ps2_error = PS2_ERR_NONE; | ||||
static inline uint8_t pbuf_dequeue(void); | |||||
static inline void pbuf_enqueue(uint8_t data); | |||||
static inline bool pbuf_has_data(void); | |||||
static inline void pbuf_clear(void); | |||||
void ps2_host_init(void) | void ps2_host_init(void) | ||||
{ | { | ||||
idle(); | idle(); | ||||
ps2_host_send(0xED); | ps2_host_send(0xED); | ||||
ps2_host_send(led); | ps2_host_send(led); | ||||
} | } | ||||
/*-------------------------------------------------------------------- | |||||
* Ring buffer to store scan codes from keyboard | |||||
*------------------------------------------------------------------*/ | |||||
#define PBUF_SIZE 32 | |||||
static uint8_t pbuf[PBUF_SIZE]; | |||||
static uint8_t pbuf_head = 0; | |||||
static uint8_t pbuf_tail = 0; | |||||
static inline void pbuf_enqueue(uint8_t data) | |||||
{ | |||||
uint8_t sreg = SREG; | |||||
cli(); | |||||
uint8_t next = (pbuf_head + 1) % PBUF_SIZE; | |||||
if (next != pbuf_tail) { | |||||
pbuf[pbuf_head] = data; | |||||
pbuf_head = next; | |||||
} else { | |||||
print("pbuf: full\n"); | |||||
} | |||||
SREG = sreg; | |||||
} | |||||
static inline uint8_t pbuf_dequeue(void) | |||||
{ | |||||
uint8_t val = 0; | |||||
uint8_t sreg = SREG; | |||||
cli(); | |||||
if (pbuf_head != pbuf_tail) { | |||||
val = pbuf[pbuf_tail]; | |||||
pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; | |||||
} | |||||
SREG = sreg; | |||||
return val; | |||||
} | |||||
static inline bool pbuf_has_data(void) | |||||
{ | |||||
uint8_t sreg = SREG; | |||||
cli(); | |||||
bool has_data = (pbuf_head != pbuf_tail); | |||||
SREG = sreg; | |||||
return has_data; | |||||
} | |||||
static inline void pbuf_clear(void) | |||||
{ | |||||
uint8_t sreg = SREG; | |||||
cli(); | |||||
pbuf_head = pbuf_tail = 0; | |||||
SREG = sreg; | |||||
} | |||||
#include "debug.h" | #include "debug.h" | ||||
report_keyboard_t usb_hid_keyboard_report; | |||||
uint16_t usb_hid_time_stamp; | |||||
void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) | void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) | ||||
{ | { | ||||
bool is_error = false; | |||||
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++) { | 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"); | 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(); | |||||
} | } |
#define PARSER_H | #define PARSER_H | ||||
#include "hid.h" | #include "hid.h" | ||||
#include "report.h" | |||||
class KBDReportParser : public HIDReportParser | class KBDReportParser : public HIDReportParser | ||||
{ | { | ||||
public: | public: | ||||
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf); | |||||
report_keyboard_t report; | |||||
uint16_t time_stamp; | |||||
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf); | |||||
}; | }; | ||||
#endif | #endif |
#include "timer.h" | #include "timer.h" | ||||
#include "uart.h" | #include "uart.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "suspend.h" | |||||
#define UART_BAUD_RATE 115200 | #define UART_BAUD_RATE 115200 | ||||
sei(); | sei(); | ||||
} | } | ||||
void usb_remote_wakeup(void) { | |||||
cli(); | |||||
int8_t ddr_orig = USBDDR; | |||||
USBOUT |= (1 << USBMINUS); | |||||
USBDDR = ddr_orig | USBMASK; | |||||
USBOUT ^= USBMASK; | |||||
_delay_ms(25); | |||||
USBOUT ^= USBMASK; | |||||
USBDDR = ddr_orig; | |||||
USBOUT &= ~(1 << USBMINUS); | |||||
sei(); | |||||
} | |||||
int main(void) | int main(void) | ||||
{ | { | ||||
bool suspended = false; | bool suspended = false; | ||||
// Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1) | // Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1) | ||||
if (timer_elapsed(last_timer) > 5) { | if (timer_elapsed(last_timer) > 5) { | ||||
suspended = true; | suspended = true; | ||||
/* | |||||
uart_putchar('S'); | |||||
_delay_ms(1); | |||||
cli(); | |||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN); | |||||
sleep_enable(); | |||||
sleep_bod_disable(); | |||||
sei(); | |||||
sleep_cpu(); | |||||
sleep_disable(); | |||||
_delay_ms(10); | |||||
uart_putchar('W'); | |||||
*/ | |||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
keyboard_task(); | keyboard_task(); | ||||
} | } | ||||
vusb_transfer_keyboard(); | vusb_transfer_keyboard(); | ||||
} else if (suspend_wakeup_condition()) { | |||||
usb_remote_wakeup(); | |||||
} | } | ||||
} | } | ||||
} | } |
0x95, 0x06, // Report Count (6), | 0x95, 0x06, // Report Count (6), | ||||
0x75, 0x08, // Report Size (8), | 0x75, 0x08, // Report Size (8), | ||||
0x15, 0x00, // Logical Minimum (0), | 0x15, 0x00, // Logical Minimum (0), | ||||
0x25, 0xFF, // Logical Maximum(255), | |||||
0x26, 0xFF, 0x00, // Logical Maximum(255), | |||||
0x05, 0x07, // Usage Page (Key Codes), | 0x05, 0x07, // Usage Page (Key Codes), | ||||
0x19, 0x00, // Usage Minimum (0), | 0x19, 0x00, // Usage Minimum (0), | ||||
0x29, 0xFF, // Usage Maximum (255), | 0x29, 0xFF, // Usage Maximum (255), | ||||
0xa1, 0x01, // COLLECTION (Application) | 0xa1, 0x01, // COLLECTION (Application) | ||||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) | ||||
0x15, 0x01, // LOGICAL_MINIMUM (0x1) | 0x15, 0x01, // LOGICAL_MINIMUM (0x1) | ||||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) | |||||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7) | |||||
0x19, 0x01, // USAGE_MINIMUM (0x1) | 0x19, 0x01, // USAGE_MINIMUM (0x1) | ||||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | 0x29, 0xb7, // USAGE_MAXIMUM (0xb7) | ||||
0x75, 0x10, // REPORT_SIZE (16) | 0x75, 0x10, // REPORT_SIZE (16) |
/* | |||||
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 |
/* | |||||
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; | |||||
} |
#ifndef XT_IO_H | |||||
#define XT_IO_H | |||||
bool clock_in(void); | |||||
bool data_in(void); | |||||
#endif |
#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); | |||||
} |
batchisp -hardware usb -device $(MCU) -operation start reset 0 | batchisp -hardware usb -device $(MCU) -operation start reset 0 | ||||
dfu: $(TARGET).hex | dfu: $(TARGET).hex | ||||
@echo -n dfu-programmer: waiting | |||||
@until dfu-programmer $(MCU) get bootloader-version > /dev/null 2>&1; do \ | |||||
echo -n "."; \ | |||||
sleep 1; \ | |||||
done | |||||
@echo | |||||
ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1))) | ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1))) | ||||
dfu-programmer $(MCU) erase --force | dfu-programmer $(MCU) erase --force | ||||
else | else |
chibios | |||||
chibios-contrib | |||||
ChibiOS | |||||
ChibiOS-Contrib |
# | # | ||||
# Imported source files and paths | # 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 | # Startup files. Try a few different locations, for compability with old versions and | ||||
# for things hardware in the contrib repository | # for things hardware in the contrib repository | ||||
STARTUP_MK = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk | STARTUP_MK = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk |
-fdata-sections \ | -fdata-sections \ | ||||
-fomit-frame-pointer | -fomit-frame-pointer | ||||
CC_FLAGS += -MMD -MP | CC_FLAGS += -MMD -MP | ||||
CC_FLAGS += $(OPT_DEFS) | |||||
LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs | LD_FLAGS = $(CPU) -Wl,--gc-sections --specs=nano.specs | ||||
#LD_FLAGS += -u _printf_float -u _scanf_float | #LD_FLAGS += -u _printf_float -u _scanf_float |