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