Browse Source

Remove core library and build files

tags/v2.0
tmk 7 years ago
parent
commit
6746e37088
100 changed files with 0 additions and 12285 deletions
  1. 0
    6
      .gitmodules
  2. 0
    77
      common.mk
  3. 0
    565
      common/action.c
  4. 0
    82
      common/action.h
  5. 0
    315
      common/action_code.h
  6. 0
    138
      common/action_layer.c
  7. 0
    77
      common/action_layer.h
  8. 0
    83
      common/action_macro.c
  9. 0
    102
      common/action_macro.h
  10. 0
    376
      common/action_tapping.c
  11. 0
    39
      common/action_tapping.h
  12. 0
    307
      common/action_util.c
  13. 0
    66
      common/action_util.h
  14. 0
    148
      common/avr/bootloader.c
  15. 0
    45
      common/avr/eeconfig.c
  16. 0
    122
      common/avr/suspend.c
  17. 0
    27
      common/avr/suspend_avr.h
  18. 0
    117
      common/avr/timer.c
  19. 0
    42
      common/avr/timer_avr.h
  20. 0
    500
      common/avr/xprintf.S
  21. 0
    111
      common/avr/xprintf.h
  22. 0
    85
      common/backlight.c
  23. 0
    40
      common/backlight.h
  24. 0
    25
      common/bootloader.h
  25. 0
    128
      common/bootmagic.c
  26. 0
    100
      common/bootmagic.h
  27. 0
    644
      common/command.c
  28. 0
    35
      common/command.h
  29. 0
    24
      common/debug.c
  30. 0
    117
      common/debug.h
  31. 0
    75
      common/eeconfig.h
  32. 0
    97
      common/host.c
  33. 0
    57
      common/host.h
  34. 0
    33
      common/host_driver.h
  35. 0
    150
      common/keyboard.c
  36. 0
    72
      common/keyboard.h
  37. 0
    489
      common/keycode.h
  38. 0
    185
      common/keymap.c
  39. 0
    71
      common/keymap.h
  40. 0
    33
      common/led.h
  41. 0
    68
      common/matrix.h
  42. 0
    4
      common/mbed/bootloader.c
  43. 0
    6
      common/mbed/suspend.c
  44. 0
    41
      common/mbed/timer.c
  45. 0
    51
      common/mbed/xprintf.cpp
  46. 0
    17
      common/mbed/xprintf.h
  47. 0
    196
      common/mousekey.c
  48. 0
    77
      common/mousekey.h
  49. 0
    25
      common/nodebug.h
  50. 0
    48
      common/print.c
  51. 0
    137
      common/print.h
  52. 0
    12
      common/progmem.h
  53. 0
    183
      common/report.h
  54. 0
    35
      common/sendchar.h
  55. 0
    23
      common/sendchar_null.c
  56. 0
    25
      common/sendchar_uart.c
  57. 0
    95
      common/sleep_led.c
  58. 0
    21
      common/sleep_led.h
  59. 0
    13
      common/suspend.h
  60. 0
    53
      common/timer.h
  61. 0
    129
      common/uart.c
  62. 0
    11
      common/uart.h
  63. 0
    101
      common/util.c
  64. 0
    43
      common/util.h
  65. 0
    20
      common/wait.h
  66. 0
    268
      ldscript_keymap_avr5.x
  67. 0
    50
      protocol.mk
  68. 0
    456
      protocol/adb.c
  69. 0
    62
      protocol/adb.h
  70. 0
    27
      protocol/bluefruit.mk
  71. 0
    202
      protocol/bluefruit/bluefruit.c
  72. 0
    28
      protocol/bluefruit/bluefruit.h
  73. 0
    116
      protocol/bluefruit/main.c
  74. 0
    169
      protocol/ibm4704.c
  75. 0
    110
      protocol/ibm4704.h
  76. 0
    26
      protocol/iwrap.mk
  77. 0
    376
      protocol/iwrap/iWRAP4.txt
  78. 0
    356
      protocol/iwrap/iWRAP5.txt
  79. 0
    469
      protocol/iwrap/iwrap.c
  80. 0
    49
      protocol/iwrap/iwrap.h
  81. 0
    376
      protocol/iwrap/main.c
  82. 0
    7
      protocol/iwrap/mux_exit.rb
  83. 0
    156
      protocol/iwrap/suart.S
  84. 0
    8
      protocol/iwrap/suart.h
  85. 0
    159
      protocol/iwrap/wd.h
  86. 0
    50
      protocol/lufa.mk
  87. 0
    61
      protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/HID_EEPROM_Loader.c
  88. 0
    40
      protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/makefile
  89. 0
    101
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_atprogram.mk
  90. 0
    84
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_avrdude.mk
  91. 0
    296
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_build.mk
  92. 0
    152
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_core.mk
  93. 0
    104
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_cppcheck.mk
  94. 0
    93
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_dfu.mk
  95. 0
    81
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_doxygen.mk
  96. 0
    88
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_hid.mk
  97. 0
    116
      protocol/lufa/LUFA-120730/LUFA/Build/lufa_sources.mk
  98. 0
    90
      protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Buttons.h
  99. 0
    220
      protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Dataflash.h
  100. 0
    0
      protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Joystick.h

+ 0
- 6
.gitmodules View File

@@ -1,6 +0,0 @@
[submodule "protocol/lufa/LUFA-git"]
path = protocol/lufa/LUFA-git
url = https://github.com/abcminiuser/lufa.git
[submodule "protocol/usb_hid/USB_Host_Shield_2.0"]
path = protocol/usb_hid/USB_Host_Shield_2.0
url = https://github.com/felis/USB_Host_Shield_2.0.git

+ 0
- 77
common.mk View File

@@ -1,77 +0,0 @@
COMMON_DIR = common
SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/keyboard.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 \
$(COMMON_DIR)/avr/suspend.c \
$(COMMON_DIR)/avr/xprintf.S \
$(COMMON_DIR)/avr/timer.c \
$(COMMON_DIR)/avr/bootloader.c


# Option modules
ifdef BOOTMAGIC_ENABLE
SRC += $(COMMON_DIR)/bootmagic.c
SRC += $(COMMON_DIR)/avr/eeconfig.c
OPT_DEFS += -DBOOTMAGIC_ENABLE
endif

ifdef MOUSEKEY_ENABLE
SRC += $(COMMON_DIR)/mousekey.c
OPT_DEFS += -DMOUSEKEY_ENABLE
OPT_DEFS += -DMOUSE_ENABLE
endif

ifdef EXTRAKEY_ENABLE
OPT_DEFS += -DEXTRAKEY_ENABLE
endif

ifdef CONSOLE_ENABLE
OPT_DEFS += -DCONSOLE_ENABLE
else
OPT_DEFS += -DNO_PRINT
OPT_DEFS += -DNO_DEBUG
endif

ifdef COMMAND_ENABLE
SRC += $(COMMON_DIR)/command.c
OPT_DEFS += -DCOMMAND_ENABLE
endif

ifdef NKRO_ENABLE
OPT_DEFS += -DNKRO_ENABLE
endif

ifdef USB_6KRO_ENABLE
OPT_DEFS += -DUSB_6KRO_ENABLE
endif

ifdef SLEEP_LED_ENABLE
SRC += $(COMMON_DIR)/sleep_led.c
OPT_DEFS += -DSLEEP_LED_ENABLE
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
endif

ifdef BACKLIGHT_ENABLE
SRC += $(COMMON_DIR)/backlight.c
OPT_DEFS += -DBACKLIGHT_ENABLE
endif

ifdef KEYMAP_SECTION_ENABLE
OPT_DEFS += -DKEYMAP_SECTION_ENABLE
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr5.x
endif

# Version string
OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null)


# Search Path
VPATH += $(TMK_DIR)/common

+ 0
- 565
common/action.c View File

@@ -1,565 +0,0 @@
/*
Copyright 2012,2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "host.h"
#include "keycode.h"
#include "keyboard.h"
#include "mousekey.h"
#include "command.h"
#include "led.h"
#include "backlight.h"
#include "action_layer.h"
#include "action_tapping.h"
#include "action_macro.h"
#include "action_util.h"
#include "action.h"

#ifdef DEBUG_ACTION
#include "debug.h"
#else
#include "nodebug.h"
#endif


void action_exec(keyevent_t event)
{
if (!IS_NOEVENT(event)) {
dprint("\n---- action_exec: start -----\n");
dprint("EVENT: "); debug_event(event); dprintln();
}

keyrecord_t record = { .event = event };

#ifndef NO_ACTION_TAPPING
action_tapping_process(record);
#else
process_action(&record);
if (!IS_NOEVENT(record.event)) {
dprint("processed: "); debug_record(record); dprintln();
}
#endif
}

void process_action(keyrecord_t *record)
{
keyevent_t event = record->event;
#ifndef NO_ACTION_TAPPING
uint8_t tap_count = record->tap.count;
#endif

if (IS_NOEVENT(event)) { return; }

action_t action = layer_switch_get_action(event.key);
dprint("ACTION: "); debug_action(action);
#ifndef NO_ACTION_LAYER
dprint(" layer_state: "); layer_debug();
dprint(" default_layer_state: "); default_layer_debug();
#endif
dprintln();

switch (action.kind.id) {
/* Key and Mods */
case ACT_LMODS:
case ACT_RMODS:
{
uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods :
action.key.mods<<4;
if (event.pressed) {
if (mods) {
add_weak_mods(mods);
send_keyboard_report();
}
register_code(action.key.code);
} else {
unregister_code(action.key.code);
if (mods) {
del_weak_mods(mods);
send_keyboard_report();
}
}
}
break;
#ifndef NO_ACTION_TAPPING
case ACT_LMODS_TAP:
case ACT_RMODS_TAP:
{
uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods :
action.key.mods<<4;
switch (action.layer_tap.code) {
#ifndef NO_ACTION_ONESHOT
case MODS_ONESHOT:
// Oneshot modifier
if (event.pressed) {
if (tap_count == 0) {
register_mods(mods);
}
else if (tap_count == 1) {
dprint("MODS_TAP: Oneshot: start\n");
set_oneshot_mods(mods);
}
else {
register_mods(mods);
}
} else {
if (tap_count == 0) {
clear_oneshot_mods();
unregister_mods(mods);
}
else if (tap_count == 1) {
// Retain Oneshot mods
}
else {
clear_oneshot_mods();
unregister_mods(mods);
}
}
break;
#endif
case MODS_TAP_TOGGLE:
if (event.pressed) {
if (tap_count <= TAPPING_TOGGLE) {
register_mods(mods);
}
} else {
if (tap_count < TAPPING_TOGGLE) {
unregister_mods(mods);
}
}
break;
default:
if (event.pressed) {
if (tap_count > 0) {
if (record->tap.interrupted) {
dprint("MODS_TAP: Tap: Cancel: add_mods\n");
// ad hoc: set 0 to cancel tap
record->tap.count = 0;
register_mods(mods);
} else {
dprint("MODS_TAP: Tap: register_code\n");
register_code(action.key.code);
}
} else {
dprint("MODS_TAP: No tap: add_mods\n");
register_mods(mods);
}
} else {
if (tap_count > 0) {
dprint("MODS_TAP: Tap: unregister_code\n");
unregister_code(action.key.code);
} else {
dprint("MODS_TAP: No tap: add_mods\n");
unregister_mods(mods);
}
}
break;
}
}
break;
#endif
#ifdef EXTRAKEY_ENABLE
/* other HID usage */
case ACT_USAGE:
switch (action.usage.page) {
case PAGE_SYSTEM:
if (event.pressed) {
host_system_send(action.usage.code);
} else {
host_system_send(0);
}
break;
case PAGE_CONSUMER:
if (event.pressed) {
host_consumer_send(action.usage.code);
} else {
host_consumer_send(0);
}
break;
}
break;
#endif
#ifdef MOUSEKEY_ENABLE
/* Mouse key */
case ACT_MOUSEKEY:
if (event.pressed) {
mousekey_on(action.key.code);
mousekey_send();
} else {
mousekey_off(action.key.code);
mousekey_send();
}
break;
#endif
#ifndef NO_ACTION_LAYER
case ACT_LAYER:
if (action.layer_bitop.on == 0) {
/* Default Layer Bitwise Operation */
if (!event.pressed) {
uint8_t shift = action.layer_bitop.part*4;
uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
switch (action.layer_bitop.op) {
case OP_BIT_AND: default_layer_and(bits | mask); break;
case OP_BIT_OR: default_layer_or(bits | mask); break;
case OP_BIT_XOR: default_layer_xor(bits | mask); break;
case OP_BIT_SET: default_layer_and(mask); default_layer_or(bits); break;
}
}
} else {
/* Layer Bitwise Operation */
if (event.pressed ? (action.layer_bitop.on & ON_PRESS) :
(action.layer_bitop.on & ON_RELEASE)) {
uint8_t shift = action.layer_bitop.part*4;
uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
switch (action.layer_bitop.op) {
case OP_BIT_AND: layer_and(bits | mask); break;
case OP_BIT_OR: layer_or(bits | mask); break;
case OP_BIT_XOR: layer_xor(bits | mask); break;
case OP_BIT_SET: layer_and(mask); layer_or(bits); break;
}
}
}
break;
#ifndef NO_ACTION_TAPPING
case ACT_LAYER_TAP:
case ACT_LAYER_TAP_EXT:
switch (action.layer_tap.code) {
case 0xe0 ... 0xef:
/* layer On/Off with modifiers(left only) */
if (event.pressed) {
layer_on(action.layer_tap.val);
register_mods(action.layer_tap.code & 0x0f);
} else {
layer_off(action.layer_tap.val);
unregister_mods(action.layer_tap.code & 0x0f);
}
break;
case OP_TAP_TOGGLE:
/* tap toggle */
if (event.pressed) {
if (tap_count < TAPPING_TOGGLE) {
layer_invert(action.layer_tap.val);
}
} else {
if (tap_count <= TAPPING_TOGGLE) {
layer_invert(action.layer_tap.val);
}
}
break;
case OP_ON_OFF:
event.pressed ? layer_on(action.layer_tap.val) :
layer_off(action.layer_tap.val);
break;
case OP_OFF_ON:
event.pressed ? layer_off(action.layer_tap.val) :
layer_on(action.layer_tap.val);
break;
case OP_SET_CLEAR:
event.pressed ? layer_move(action.layer_tap.val) :
layer_clear();
break;
default:
/* tap key */
if (event.pressed) {
if (tap_count > 0) {
dprint("KEYMAP_TAP_KEY: Tap: register_code\n");
register_code(action.layer_tap.code);
} else {
dprint("KEYMAP_TAP_KEY: No tap: On on press\n");
layer_on(action.layer_tap.val);
}
} else {
if (tap_count > 0) {
dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
unregister_code(action.layer_tap.code);
} else {
dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
layer_off(action.layer_tap.val);
}
}
break;
}
break;
#endif
#endif
/* Extentions */
#ifndef NO_ACTION_MACRO
case ACT_MACRO:
action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
break;
#endif
#ifdef BACKLIGHT_ENABLE
case ACT_BACKLIGHT:
if (!event.pressed) {
switch (action.backlight.opt) {
case BACKLIGHT_INCREASE:
backlight_increase();
break;
case BACKLIGHT_DECREASE:
backlight_decrease();
break;
case BACKLIGHT_TOGGLE:
backlight_toggle();
break;
case BACKLIGHT_STEP:
backlight_step();
break;
case BACKLIGHT_LEVEL:
backlight_level(action.backlight.level);
break;
}
}
break;
#endif
case ACT_COMMAND:
break;
#ifndef NO_ACTION_FUNCTION
case ACT_FUNCTION:
action_function(record, action.func.id, action.func.opt);
break;
#endif
default:
break;
}
}




/*
* Utilities for actions.
*/
void register_code(uint8_t code)
{
if (code == KC_NO) {
return;
}

#ifdef LOCKING_SUPPORT_ENABLE
else if (KC_LOCKING_CAPS == code) {
#ifdef LOCKING_RESYNC_ENABLE
// Resync: ignore if caps lock already is on
if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
#endif
add_key(KC_CAPSLOCK);
send_keyboard_report();
del_key(KC_CAPSLOCK);
send_keyboard_report();
}

else if (KC_LOCKING_NUM == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) return;
#endif
add_key(KC_NUMLOCK);
send_keyboard_report();
del_key(KC_NUMLOCK);
send_keyboard_report();
}

else if (KC_LOCKING_SCROLL == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) return;
#endif
add_key(KC_SCROLLLOCK);
send_keyboard_report();
del_key(KC_SCROLLLOCK);
send_keyboard_report();
}
#endif

else if IS_KEY(code) {
// TODO: should push command_proc out of this block?
if (command_proc(code)) return;

#ifndef NO_ACTION_ONESHOT
/* TODO: remove
if (oneshot_state.mods && !oneshot_state.disabled) {
uint8_t tmp_mods = get_mods();
add_mods(oneshot_state.mods);

add_key(code);
send_keyboard_report();

set_mods(tmp_mods);
send_keyboard_report();
oneshot_cancel();
} else
*/
#endif
{
add_key(code);
send_keyboard_report();
}
}
else if IS_MOD(code) {
add_mods(MOD_BIT(code));
send_keyboard_report();
}
else if IS_SYSTEM(code) {
host_system_send(KEYCODE2SYSTEM(code));
}
else if IS_CONSUMER(code) {
host_consumer_send(KEYCODE2CONSUMER(code));
}
}

void unregister_code(uint8_t code)
{
if (code == KC_NO) {
return;
}

#ifdef LOCKING_SUPPORT_ENABLE
else if (KC_LOCKING_CAPS == code) {
#ifdef LOCKING_RESYNC_ENABLE
// Resync: ignore if caps lock already is off
if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
#endif
add_key(KC_CAPSLOCK);
send_keyboard_report();
del_key(KC_CAPSLOCK);
send_keyboard_report();
}

else if (KC_LOCKING_NUM == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) return;
#endif
add_key(KC_NUMLOCK);
send_keyboard_report();
del_key(KC_NUMLOCK);
send_keyboard_report();
}

else if (KC_LOCKING_SCROLL == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (!(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK))) return;
#endif
add_key(KC_SCROLLLOCK);
send_keyboard_report();
del_key(KC_SCROLLLOCK);
send_keyboard_report();
}
#endif

else if IS_KEY(code) {
del_key(code);
send_keyboard_report();
}
else if IS_MOD(code) {
del_mods(MOD_BIT(code));
send_keyboard_report();
}
else if IS_SYSTEM(code) {
host_system_send(0);
}
else if IS_CONSUMER(code) {
host_consumer_send(0);
}
}

void register_mods(uint8_t mods)
{
if (mods) {
add_mods(mods);
send_keyboard_report();
}
}

void unregister_mods(uint8_t mods)
{
if (mods) {
del_mods(mods);
send_keyboard_report();
}
}

void clear_keyboard(void)
{
clear_mods();
clear_keyboard_but_mods();
}

void clear_keyboard_but_mods(void)
{
clear_weak_mods();
clear_keys();
send_keyboard_report();
#ifdef MOUSEKEY_ENABLE
mousekey_clear();
mousekey_send();
#endif
#ifdef EXTRAKEY_ENABLE
host_system_send(0);
host_consumer_send(0);
#endif
}

bool is_tap_key(keypos_t key)
{
action_t action = layer_switch_get_action(key);

switch (action.kind.id) {
case ACT_LMODS_TAP:
case ACT_RMODS_TAP:
case ACT_LAYER_TAP:
case ACT_LAYER_TAP_EXT:
return true;
case ACT_MACRO:
case ACT_FUNCTION:
if (action.func.opt & FUNC_TAP) { return true; }
return false;
}
return false;
}


/*
* debug print
*/
void debug_event(keyevent_t event)
{
dprintf("%04X%c(%u)", (event.key.row<<8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time);
}

void debug_record(keyrecord_t record)
{
debug_event(record.event);
#ifndef NO_ACTION_TAPPING
dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' '));
#endif
}

void debug_action(action_t action)
{
switch (action.kind.id) {
case ACT_LMODS: dprint("ACT_LMODS"); break;
case ACT_RMODS: dprint("ACT_RMODS"); break;
case ACT_LMODS_TAP: dprint("ACT_LMODS_TAP"); break;
case ACT_RMODS_TAP: dprint("ACT_RMODS_TAP"); break;
case ACT_USAGE: dprint("ACT_USAGE"); break;
case ACT_MOUSEKEY: dprint("ACT_MOUSEKEY"); break;
case ACT_LAYER: dprint("ACT_LAYER"); break;
case ACT_LAYER_TAP: dprint("ACT_LAYER_TAP"); break;
case ACT_LAYER_TAP_EXT: dprint("ACT_LAYER_TAP_EXT"); break;
case ACT_MACRO: dprint("ACT_MACRO"); break;
case ACT_COMMAND: dprint("ACT_COMMAND"); break;
case ACT_FUNCTION: dprint("ACT_FUNCTION"); break;
default: dprint("UNKNOWN"); break;
}
dprintf("[%X:%02X]", action.kind.param>>8, action.kind.param&0xff);
}

+ 0
- 82
common/action.h View File

@@ -1,82 +0,0 @@
/*
Copyright 2012,2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTION_H
#define ACTION_H

#include <stdint.h>
#include <stdbool.h>
#include "keyboard.h"
#include "keycode.h"
#include "action_code.h"
#include "action_macro.h"


#ifdef __cplusplus
extern "C" {
#endif

/* tapping count and state */
typedef struct {
bool interrupted :1;
bool reserved2 :1;
bool reserved1 :1;
bool reserved0 :1;
uint8_t count :4;
} tap_t;

/* Key event container for recording */
typedef struct {
keyevent_t event;
#ifndef NO_ACTION_TAPPING
tap_t tap;
#endif
} keyrecord_t;

/* Execute action per keyevent */
void action_exec(keyevent_t event);

/* action for key */
action_t action_for_key(uint8_t layer, keypos_t key);

/* macro */
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);

/* user defined special function */
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);

/* Utilities for actions. */
void process_action(keyrecord_t *record);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
void register_mods(uint8_t mods);
void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
void layer_switch(uint8_t new_layer);
bool is_tap_key(keypos_t key);

/* debug */
void debug_event(keyevent_t event);
void debug_record(keyrecord_t record);
void debug_action(action_t action);

#ifdef __cplusplus
}
#endif

#endif /* ACTION_H */

+ 0
- 315
common/action_code.h View File

@@ -1,315 +0,0 @@
/*
Copyright 2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTION_CODE_H
#define ACTION_CODE_H

/* Action codes
* ============
* 16bit code: action_kind(4bit) + action_parameter(12bit)
*
*
* Key Actions(00xx)
* -----------------
* ACT_MODS(000r):
* 000r|0000|0000 0000 No action code
* 000r|0000|0000 0001 Transparent code
* 000r|0000| keycode Key
* 000r|mods|0000 0000 Modifiers
* 000r|mods| keycode Modifiers+Key(Modified key)
* r: Left/Right flag(Left:0, Right:1)
*
* ACT_MODS_TAP(001r):
* 001r|mods|0000 0000 Modifiers with OneShot
* 001r|mods|0000 0001 Modifiers with tap toggle
* 001r|mods|0000 00xx (reserved)
* 001r|mods| keycode Modifiers with Tap Key(Dual role)
*
*
* Other Keys(01xx)
* ----------------
* ACT_USAGE(0100): TODO: Not needed?
* 0100|00| usage(10) System control(0x80) - General Desktop page(0x01)
* 0100|01| usage(10) Consumer control(0x01) - Consumer page(0x0C)
* 0100|10| usage(10) (reserved)
* 0100|11| usage(10) (reserved)
*
* ACT_MOUSEKEY(0110): TODO: Not needed?
* 0101|xxxx| keycode Mouse key
*
* 011x|xxxx xxxx xxxx (reseved)
*
*
* Layer Actions(10xx)
* -------------------
* ACT_LAYER(1000):
* 1000|oo00|pppE BBBB Default Layer Bitwise operation
* oo: operation(00:AND, 01:OR, 10:XOR, 11:SET)
* ppp: 4-bit chunk part(0-7)
* EBBBB: bits and extra bit
* 1000|ooee|pppE BBBB Layer Bitwise Operation
* oo: operation(00:AND, 01:OR, 10:XOR, 11:SET)
* ppp: 4-bit chunk part(0-7)
* EBBBB: bits and extra bit
* ee: on event(01:press, 10:release, 11:both)
*
* 1001|xxxx|xxxx xxxx (reserved)
* 1001|oopp|BBBB BBBB 8-bit Bitwise Operation???
*
* ACT_LAYER_TAP(101x):
* 101E|LLLL| keycode On/Off with tap key
* 101E|LLLL|1110 mods On/Off with modifiers(0xE0-EF)
* 101E|LLLL|1111 0000 Invert with tap toggle(0xF0)
* 101E|LLLL|1111 0001 On/Off
* 101E|LLLL|1111 0010 Off/On
* 101E|LLLL|1111 0011 Set/Clear
* 101E|LLLL|1111 xxxx Reserved(0xF4-FF)
* ELLLL: layer 0-31(E: extra bit for layer 16-31)
*
*
* Extensions(11xx)
* ----------------
* ACT_MACRO(1100):
* 1100|opt | id(8) Macro play?
* 1100|1111| id(8) Macro record?
*
* ACT_BACKLIGHT(1101):
* 1101|opt |level(8) Backlight commands
*
* ACT_COMMAND(1110):
* 1110|opt | id(8) Built-in Command exec
*
* ACT_FUNCTION(1111):
* 1111| address(12) Function?
* 1111|opt | id(8) Function?
*/
enum action_kind_id {
/* Key Actions */
ACT_MODS = 0b0000,
ACT_LMODS = 0b0000,
ACT_RMODS = 0b0001,
ACT_MODS_TAP = 0b0010,
ACT_LMODS_TAP = 0b0010,
ACT_RMODS_TAP = 0b0011,
/* Other Keys */
ACT_USAGE = 0b0100,
ACT_MOUSEKEY = 0b0101,
/* Layer Actions */
ACT_LAYER = 0b1000,
ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */
ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */
/* Extensions */
ACT_MACRO = 0b1100,
ACT_BACKLIGHT = 0b1101,
ACT_COMMAND = 0b1110,
ACT_FUNCTION = 0b1111
};


/* Action Code Struct
*
* NOTE:
* In avr-gcc bit field seems to be assigned from LSB(bit0) to MSB(bit15).
* AVR looks like a little endian in avr-gcc.
* Not portable across compiler/endianness?
*
* Byte order and bit order of 0x1234:
* Big endian: Little endian:
* -------------------- --------------------
* FEDC BA98 7654 3210 0123 4567 89AB CDEF
* 0001 0010 0011 0100 0010 1100 0100 1000
* 0x12 0x34 0x34 0x12
*/
typedef union {
uint16_t code;
struct action_kind {
uint16_t param :12;
uint8_t id :4;
} kind;
struct action_key {
uint8_t code :8;
uint8_t mods :4;
uint8_t kind :4;
} key;
struct action_layer_bitop {
uint8_t bits :4;
uint8_t xbit :1;
uint8_t part :3;
uint8_t on :2;
uint8_t op :2;
uint8_t kind :4;
} layer_bitop;
struct action_layer_tap {
uint8_t code :8;
uint8_t val :5;
uint8_t kind :3;
} layer_tap;
struct action_usage {
uint16_t code :10;
uint8_t page :2;
uint8_t kind :4;
} usage;
struct action_backlight {
uint8_t level :8;
uint8_t opt :4;
uint8_t kind :4;
} backlight;
struct action_command {
uint8_t id :8;
uint8_t opt :4;
uint8_t kind :4;
} command;
struct action_function {
uint8_t id :8;
uint8_t opt :4;
uint8_t kind :4;
} func;
} action_t;


/* action utility */
#define ACTION_NO 0
#define ACTION_TRANSPARENT 1
#define ACTION(kind, param) ((kind)<<12 | (param))


/*
* Key Actions
*/
/* Mod bits: 43210
* bit 0 ||||+- Control
* bit 1 |||+-- Shift
* bit 2 ||+--- Alt
* bit 3 |+---- Gui
* bit 4 +----- LR flag(Left:0, Right:1)
*/
enum mods_bit {
MOD_LCTL = 0x01,
MOD_LSFT = 0x02,
MOD_LALT = 0x04,
MOD_LGUI = 0x08,
MOD_RCTL = 0x11,
MOD_RSFT = 0x12,
MOD_RALT = 0x14,
MOD_RGUI = 0x18,
};
enum mods_codes {
MODS_ONESHOT = 0x00,
MODS_TAP_TOGGLE = 0x01,
};
#define ACTION_KEY(key) ACTION(ACT_MODS, (key))
#define ACTION_MODS(mods) ACTION(ACT_MODS, ((mods)&0x1f)<<8 | 0)
#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, ((mods)&0x1f)<<8 | (key))
#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, ((mods)&0x1f)<<8 | (key))
#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f)<<8 | MODS_ONESHOT)
#define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f)<<8 | MODS_TAP_TOGGLE)


/*
* Other Keys
*/
enum usage_pages {
PAGE_SYSTEM,
PAGE_CONSUMER
};
#define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM<<10 | (id))
#define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER<<10 | (id))
#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key)



/*
* Layer Actions
*/
enum layer_param_on {
ON_PRESS = 1,
ON_RELEASE = 2,
ON_BOTH = 3,
};
enum layer_param_bit_op {
OP_BIT_AND = 0,
OP_BIT_OR = 1,
OP_BIT_XOR = 2,
OP_BIT_SET = 3,
};
enum layer_pram_tap_op {
OP_TAP_TOGGLE = 0xF0,
OP_ON_OFF,
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))
/* Default Layer */
#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer)/4, 1<<((layer)%4))
/* Layer Operation */
#define ACTION_LAYER_CLEAR(on) ACTION_LAYER_BIT_AND(0, 0, (on))
#define ACTION_LAYER_MOMENTARY(layer) ACTION_LAYER_ON_OFF(layer)
#define ACTION_LAYER_TOGGLE(layer) ACTION_LAYER_INVERT(layer, ON_RELEASE)
#define ACTION_LAYER_INVERT(layer, on) ACTION_LAYER_BIT_XOR((layer)/4, 1<<((layer)%4), (on))
#define ACTION_LAYER_ON(layer, on) ACTION_LAYER_BIT_OR( (layer)/4, 1<<((layer)%4), (on))
#define ACTION_LAYER_OFF(layer, on) ACTION_LAYER_BIT_AND((layer)/4, ~(1<<((layer)%4)), (on))
#define ACTION_LAYER_SET(layer, on) ACTION_LAYER_BIT_SET((layer)/4, 1<<((layer)%4), (on))
#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
#define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xe0 | (mods)&0x0f)
/* With Tapping */
#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)
/* Bitwise Operation */
#define ACTION_LAYER_BIT_AND(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), (on))
#define ACTION_LAYER_BIT_OR( part, bits, on) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), (on))
#define ACTION_LAYER_BIT_XOR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), (on))
#define ACTION_LAYER_BIT_SET(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), (on))
/* Default Layer Bitwise Operation */
#define ACTION_DEFAULT_LAYER_BIT_AND(part, bits) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_OR( part, bits) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0)


/*
* Extensions
*/
enum backlight_opt {
BACKLIGHT_INCREASE = 0,
BACKLIGHT_DECREASE = 1,
BACKLIGHT_TOGGLE = 2,
BACKLIGHT_STEP = 3,
BACKLIGHT_LEVEL = 4,
};
/* Macro */
#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id))
#define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt)<<8 | (id))
/* Backlight */
#define ACTION_BACKLIGHT_INCREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_INCREASE << 8)
#define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE << 8)
#define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE << 8)
#define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP << 8)
#define ACTION_BACKLIGHT_LEVEL(level) ACTION(ACT_BACKLIGHT, BACKLIGHT_LEVEL << 8 | level)
/* Command */
#define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (addr))
/* Function */
enum function_opts {
FUNC_TAP = 0x8, /* indciates function is tappable */
};
#define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id))
#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id))
#define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | (id))

#endif /* ACTION_CODE_H */

+ 0
- 138
common/action_layer.c View File

@@ -1,138 +0,0 @@
#include <stdint.h>
#include "keyboard.h"
#include "action.h"
#include "util.h"
#include "action_layer.h"

#ifdef DEBUG_ACTION
#include "debug.h"
#else
#include "nodebug.h"
#endif


/*
* Default Layer State
*/
uint32_t default_layer_state = 0;

static void default_layer_state_set(uint32_t state)
{
debug("default_layer_state: ");
default_layer_debug(); debug(" to ");
default_layer_state = state;
default_layer_debug(); debug("\n");
clear_keyboard_but_mods(); // To avoid stuck keys
}

void default_layer_debug(void)
{
dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state));
}

void default_layer_set(uint32_t state)
{
default_layer_state_set(state);
}

#ifndef NO_ACTION_LAYER
void default_layer_or(uint32_t state)
{
default_layer_state_set(default_layer_state | state);
}
void default_layer_and(uint32_t state)
{
default_layer_state_set(default_layer_state & state);
}
void default_layer_xor(uint32_t state)
{
default_layer_state_set(default_layer_state ^ state);
}
#endif


#ifndef NO_ACTION_LAYER
/*
* Keymap Layer State
*/
uint32_t layer_state = 0;

static void layer_state_set(uint32_t state)
{
dprint("layer_state: ");
layer_debug(); dprint(" to ");
layer_state = state;
layer_debug(); dprintln();
clear_keyboard_but_mods(); // To avoid stuck keys
}

void layer_clear(void)
{
layer_state_set(0);
}

void layer_move(uint8_t layer)
{
layer_state_set(1UL<<layer);
}

void layer_on(uint8_t layer)
{
layer_state_set(layer_state | (1UL<<layer));
}

void layer_off(uint8_t layer)
{
layer_state_set(layer_state & ~(1UL<<layer));
}

void layer_invert(uint8_t layer)
{
layer_state_set(layer_state ^ (1UL<<layer));
}

void layer_or(uint32_t state)
{
layer_state_set(layer_state | state);
}
void layer_and(uint32_t state)
{
layer_state_set(layer_state & state);
}
void layer_xor(uint32_t state)
{
layer_state_set(layer_state ^ state);
}

void layer_debug(void)
{
dprintf("%08lX(%u)", layer_state, biton32(layer_state));
}
#endif



action_t layer_switch_get_action(keypos_t key)
{
action_t action;
action.code = ACTION_TRANSPARENT;

#ifndef NO_ACTION_LAYER
uint32_t layers = layer_state | default_layer_state;
/* check top layer first */
for (int8_t i = 31; i >= 0; i--) {
if (layers & (1UL<<i)) {
action = action_for_key(i, key);
if (action.code != ACTION_TRANSPARENT) {
return action;
}
}
}
/* fall back to layer 0 */
action = action_for_key(0, key);
return action;
#else
action = action_for_key(biton32(default_layer_state), key);
return action;
#endif
}

+ 0
- 77
common/action_layer.h View File

@@ -1,77 +0,0 @@
/*
Copyright 2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTION_LAYER_H
#define ACTION_LAYER_H

#include <stdint.h>
#include "keyboard.h"
#include "action.h"


/*
* Default Layer
*/
extern uint32_t default_layer_state;
void default_layer_debug(void);
void default_layer_set(uint32_t state);

#ifndef NO_ACTION_LAYER
/* bitwise operation */
void default_layer_or(uint32_t state);
void default_layer_and(uint32_t state);
void default_layer_xor(uint32_t state);
#else
#define default_layer_or(state)
#define default_layer_and(state)
#define default_layer_xor(state)
#endif


/*
* Keymap Layer
*/
#ifndef NO_ACTION_LAYER
extern uint32_t layer_state;
void layer_debug(void);
void layer_clear(void);
void layer_move(uint8_t layer);
void layer_on(uint8_t layer);
void layer_off(uint8_t layer);
void layer_invert(uint8_t layer);
/* bitwise operation */
void layer_or(uint32_t state);
void layer_and(uint32_t state);
void layer_xor(uint32_t state);
#else
#define layer_state 0
#define layer_clear()
#define layer_move(layer)
#define layer_on(layer)
#define layer_off(layer)
#define layer_invert(layer)

#define layer_or(state)
#define layer_and(state)
#define layer_xor(state)
#define layer_debug()
#endif


/* return action depending on current layer status */
action_t layer_switch_get_action(keypos_t key);

#endif

+ 0
- 83
common/action_macro.c View File

@@ -1,83 +0,0 @@
/*
Copyright 2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "action.h"
#include "action_util.h"
#include "action_macro.h"
#include "wait.h"

#ifdef DEBUG_ACTION
#include "debug.h"
#else
#include "nodebug.h"
#endif


#ifndef NO_ACTION_MACRO

#define MACRO_READ() (macro = MACRO_GET(macro_p++))
void action_macro_play(const macro_t *macro_p)
{
macro_t macro = END;
uint8_t interval = 0;

if (!macro_p) return;
while (true) {
switch (MACRO_READ()) {
case KEY_DOWN:
MACRO_READ();
dprintf("KEY_DOWN(%02X)\n", macro);
if (IS_MOD(macro)) {
add_weak_mods(MOD_BIT(macro));
} else {
register_code(macro);
}
break;
case KEY_UP:
MACRO_READ();
dprintf("KEY_UP(%02X)\n", macro);
if (IS_MOD(macro)) {
del_weak_mods(MOD_BIT(macro));
} else {
unregister_code(macro);
}
break;
case WAIT:
MACRO_READ();
dprintf("WAIT(%u)\n", macro);
{ uint8_t ms = macro; while (ms--) wait_ms(1); }
break;
case INTERVAL:
interval = MACRO_READ();
dprintf("INTERVAL(%u)\n", interval);
break;
case 0x04 ... 0x73:
dprintf("DOWN(%02X)\n", macro);
register_code(macro);
break;
case 0x84 ... 0xF3:
dprintf("UP(%02X)\n", macro);
unregister_code(macro&0x7F);
break;
case END:
default:
return;
}
// interval
{ uint8_t ms = interval; while (ms--) wait_ms(1); }
}
}
#endif

+ 0
- 102
common/action_macro.h View File

@@ -1,102 +0,0 @@
/*
Copyright 2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTION_MACRO_H
#define ACTION_MACRO_H
#include <stdint.h>
#include "progmem.h"


#define MACRO_NONE 0
#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
#define MACRO_GET(p) pgm_read_byte(p)

typedef uint8_t macro_t;


#ifndef NO_ACTION_MACRO
void action_macro_play(const macro_t *macro_p);
#else
#define action_macro_play(macro)
#endif



/* Macro commands
* code(0x04-73) // key down(1byte)
* code(0x04-73) | 0x80 // key up(1byte)
* { KEY_DOWN, code(0x04-0xff) } // key down(2bytes)
* { KEY_UP, code(0x04-0xff) } // key up(2bytes)
* WAIT // wait milli-seconds
* INTERVAL // set interval between macro commands
* END // stop macro execution
*
* Ideas(Not implemented):
* modifiers
* system usage
* consumer usage
* unicode usage
* function call
* conditionals
* loop
*/
enum macro_command_id{
/* 0x00 - 0x03 */
END = 0x00,
KEY_DOWN,
KEY_UP,

/* 0x04 - 0x73 (reserved for keycode down) */

/* 0x74 - 0x83 */
WAIT = 0x74,
INTERVAL,

/* 0x84 - 0xf3 (reserved for keycode up) */

/* 0xf4 - 0xff */
};


/* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed
* if keycode between 0x04 and 0x73
* keycode / (keycode|0x80)
* else
* {KEY_DOWN, keycode} / {KEY_UP, keycode}
*/
#define DOWN(key) KEY_DOWN, (key)
#define UP(key) KEY_UP, (key)
#define TYPE(key) DOWN(key), UP(key)
#define WAIT(ms) WAIT, (ms)
#define INTERVAL(ms) INTERVAL, (ms)

/* key down */
#define D(key) DOWN(KC_##key)
/* key up */
#define U(key) UP(KC_##key)
/* key type */
#define T(key) TYPE(KC_##key)
/* wait */
#define W(ms) WAIT(ms)
/* interval */
#define I(ms) INTERVAL(ms)

/* for backward comaptibility */
#define MD(key) DOWN(KC_##key)
#define MU(key) UP(KC_##key)


#endif /* ACTION_MACRO_H */

+ 0
- 376
common/action_tapping.c View File

@@ -1,376 +0,0 @@
#include <stdint.h>
#include <stdbool.h>
#include "action.h"
#include "action_layer.h"
#include "action_tapping.h"
#include "keycode.h"
#include "timer.h"

#ifdef DEBUG_ACTION
#include "debug.h"
#else
#include "nodebug.h"
#endif

#ifndef NO_ACTION_TAPPING

#define IS_TAPPING() !IS_NOEVENT(tapping_key.event)
#define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
#define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
#define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
#define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)


static keyrecord_t tapping_key = {};
static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
static uint8_t waiting_buffer_head = 0;
static uint8_t waiting_buffer_tail = 0;

static bool process_tapping(keyrecord_t *record);
static bool waiting_buffer_enq(keyrecord_t record);
static void waiting_buffer_clear(void);
static bool waiting_buffer_typed(keyevent_t event);
static bool waiting_buffer_has_anykey_pressed(void);
static void waiting_buffer_scan_tap(void);
static void debug_tapping_key(void);
static void debug_waiting_buffer(void);


void action_tapping_process(keyrecord_t record)
{
if (process_tapping(&record)) {
if (!IS_NOEVENT(record.event)) {
debug("processed: "); debug_record(record); debug("\n");
}
} else {
if (!waiting_buffer_enq(record)) {
// clear all in case of overflow.
debug("OVERFLOW: CLEAR ALL STATES\n");
clear_keyboard();
waiting_buffer_clear();
tapping_key = (keyrecord_t){};
}
}

// process waiting_buffer
if (!IS_NOEVENT(record.event) && waiting_buffer_head != waiting_buffer_tail) {
debug("---- action_exec: process waiting_buffer -----\n");
}
for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
if (process_tapping(&waiting_buffer[waiting_buffer_tail])) {
debug("processed: waiting_buffer["); debug_dec(waiting_buffer_tail); debug("] = ");
debug_record(waiting_buffer[waiting_buffer_tail]); debug("\n\n");
} else {
break;
}
}
if (!IS_NOEVENT(record.event)) {
debug("\n");
}
}


/* Tapping
*
* Rule: Tap key is typed(pressed and released) within TAPPING_TERM.
* (without interfering by typing other key)
*/
/* return true when key event is processed or consumed. */
bool process_tapping(keyrecord_t *keyp)
{
keyevent_t event = keyp->event;

// if tapping
if (IS_TAPPING_PRESSED()) {
if (WITHIN_TAPPING_TERM(event)) {
if (tapping_key.tap.count == 0) {
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
// first tap!
debug("Tapping: First tap(0->1).\n");
tapping_key.tap.count = 1;
debug_tapping_key();
process_action(&tapping_key);

// copy tapping state
keyp->tap = tapping_key.tap;
// enqueue
return false;
}
#if TAPPING_TERM >= 500
/* Process a key typed within TAPPING_TERM
* This can register the key before settlement of tapping,
* useful for long TAPPING_TERM but may prevent fast typing.
*/
else if (IS_RELEASED(event) && waiting_buffer_typed(event)) {
debug("Tapping: End. No tap. Interfered by typing key\n");
process_action(&tapping_key);
tapping_key = (keyrecord_t){};
debug_tapping_key();
// enqueue
return false;
}
#endif
/* Process release event of a key pressed before tapping starts
* Without this unexpected repeating will occur with having fast repeating setting
* https://github.com/tmk/tmk_keyboard/issues/60
*/
else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) {
// Modifier should be retained till end of this tapping.
action_t action = layer_switch_get_action(event.key);
switch (action.kind.id) {
case ACT_LMODS:
case ACT_RMODS:
if (action.key.mods && !action.key.code) return false;
if (IS_MOD(action.key.code)) return false;
break;
case ACT_LMODS_TAP:
case ACT_RMODS_TAP:
if (action.key.mods && keyp->tap.count == 0) return false;
if (IS_MOD(action.key.code)) return false;
break;
}
// Release of key should be process immediately.
debug("Tapping: release event of a key pressed before tapping\n");
process_action(keyp);
return true;
}
else {
// set interrupted flag when other key preesed during tapping
if (event.pressed) {
tapping_key.tap.interrupted = true;
}
// enqueue
return false;
}
}
// tap_count > 0
else {
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
debug("Tapping: Tap release("); debug_dec(tapping_key.tap.count); debug(")\n");
keyp->tap = tapping_key.tap;
process_action(keyp);
tapping_key = *keyp;
debug_tapping_key();
return true;
}
else if (is_tap_key(event.key) && event.pressed) {
if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last tap(>1).\n");
// unregister key
process_action(&(keyrecord_t){
.tap = tapping_key.tap,
.event.key = tapping_key.event.key,
.event.time = event.time,
.event.pressed = false
});
} else {
debug("Tapping: Start while last tap(1).\n");
}
tapping_key = *keyp;
waiting_buffer_scan_tap();
debug_tapping_key();
return true;
}
else {
if (!IS_NOEVENT(event)) {
debug("Tapping: key event while last tap(>0).\n");
}
process_action(keyp);
return true;
}
}
}
// after TAPPING_TERM
else {
if (tapping_key.tap.count == 0) {
debug("Tapping: End. Timeout. Not tap(0): ");
debug_event(event); debug("\n");
process_action(&tapping_key);
tapping_key = (keyrecord_t){};
debug_tapping_key();
return false;
} else {
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
debug("Tapping: End. last timeout tap release(>0).");
keyp->tap = tapping_key.tap;
process_action(keyp);
tapping_key = (keyrecord_t){};
return true;
}
else if (is_tap_key(event.key) && event.pressed) {
if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last timeout tap(>1).\n");
// unregister key
process_action(&(keyrecord_t){
.tap = tapping_key.tap,
.event.key = tapping_key.event.key,
.event.time = event.time,
.event.pressed = false
});
} else {
debug("Tapping: Start while last timeout tap(1).\n");
}
tapping_key = *keyp;
waiting_buffer_scan_tap();
debug_tapping_key();
return true;
}
else {
if (!IS_NOEVENT(event)) {
debug("Tapping: key event while last timeout tap(>0).\n");
}
process_action(keyp);
return true;
}
}
}
} else if (IS_TAPPING_RELEASED()) {
if (WITHIN_TAPPING_TERM(event)) {
if (event.pressed) {
if (IS_TAPPING_KEY(event.key)) {
if (!tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
// sequential tap.
keyp->tap = tapping_key.tap;
if (keyp->tap.count < 15) keyp->tap.count += 1;
debug("Tapping: Tap press("); debug_dec(keyp->tap.count); debug(")\n");
process_action(keyp);
tapping_key = *keyp;
debug_tapping_key();
return true;
} else {
// FIX: start new tap again
tapping_key = *keyp;
return true;
}
} else if (is_tap_key(event.key)) {
// Sequential tap can be interfered with other tap key.
debug("Tapping: Start with interfering other tap.\n");
tapping_key = *keyp;
waiting_buffer_scan_tap();
debug_tapping_key();
return true;
} else {
// should none in buffer
// FIX: interrupted when other key is pressed
tapping_key.tap.interrupted = true;
process_action(keyp);
return true;
}
} else {
if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n");
process_action(keyp);
return true;
}
} else {
// FIX: process_aciton here?
// timeout. no sequential tap.
debug("Tapping: End(Timeout after releasing last tap): ");
debug_event(event); debug("\n");
tapping_key = (keyrecord_t){};
debug_tapping_key();
return false;
}
}
// not tapping state
else {
if (event.pressed && is_tap_key(event.key)) {
debug("Tapping: Start(Press tap key).\n");
tapping_key = *keyp;
waiting_buffer_scan_tap();
debug_tapping_key();
return true;
} else {
process_action(keyp);
return true;
}
}
}


/*
* Waiting buffer
*/
bool waiting_buffer_enq(keyrecord_t record)
{
if (IS_NOEVENT(record.event)) {
return true;
}

if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) {
debug("waiting_buffer_enq: Over flow.\n");
return false;
}

waiting_buffer[waiting_buffer_head] = record;
waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;

debug("waiting_buffer_enq: "); debug_waiting_buffer();
return true;
}

void waiting_buffer_clear(void)
{
waiting_buffer_head = 0;
waiting_buffer_tail = 0;
}

bool waiting_buffer_typed(keyevent_t event)
{
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
return true;
}
}
return false;
}

bool waiting_buffer_has_anykey_pressed(void)
{
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
if (waiting_buffer[i].event.pressed) return true;
}
return false;
}

/* scan buffer for tapping */
void waiting_buffer_scan_tap(void)
{
// tapping already is settled
if (tapping_key.tap.count > 0) return;
// invalid state: tapping_key released && tap.count == 0
if (!tapping_key.event.pressed) return;

for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
if (IS_TAPPING_KEY(waiting_buffer[i].event.key) &&
!waiting_buffer[i].event.pressed &&
WITHIN_TAPPING_TERM(waiting_buffer[i].event)) {
tapping_key.tap.count = 1;
waiting_buffer[i].tap.count = 1;
process_action(&tapping_key);

debug("waiting_buffer_scan_tap: found at ["); debug_dec(i); debug("]\n");
debug_waiting_buffer();
return;
}
}
}


/*
* debug print
*/
static void debug_tapping_key(void)
{
debug("TAPPING_KEY="); debug_record(tapping_key); debug("\n");
}

static void debug_waiting_buffer(void)
{
debug("{ ");
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
debug("["); debug_dec(i); debug("]="); debug_record(waiting_buffer[i]); debug(" ");
}
debug("}\n");
}

#endif

+ 0
- 39
common/action_tapping.h View File

@@ -1,39 +0,0 @@
/*
Copyright 2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTION_TAPPING_H
#define ACTION_TAPPING_H



/* period of tapping(ms) */
#ifndef TAPPING_TERM
#define TAPPING_TERM 200
#endif

/* tap count needed for toggling a feature */
#ifndef TAPPING_TOGGLE
#define TAPPING_TOGGLE 5
#endif

#define WAITING_BUFFER_SIZE 8


#ifndef NO_ACTION_TAPPING
void action_tapping_process(keyrecord_t record);
#endif

#endif

+ 0
- 307
common/action_util.c View File

@@ -1,307 +0,0 @@
/*
Copyright 2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "host.h"
#include "report.h"
#include "debug.h"
#include "action_util.h"
#include "timer.h"

static inline void add_key_byte(uint8_t code);
static inline void del_key_byte(uint8_t code);
#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code);
static inline void del_key_bit(uint8_t code);
#endif

static uint8_t real_mods = 0;
static uint8_t weak_mods = 0;

#ifdef USB_6KRO_ENABLE
#define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
#define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
#define RO_INC(a) RO_ADD(a, 1)
#define RO_DEC(a) RO_SUB(a, 1)
static int8_t cb_head = 0;
static int8_t cb_tail = 0;
static int8_t cb_count = 0;
#endif

// TODO: pointer variable is not needed
//report_keyboard_t keyboard_report = {};
report_keyboard_t *keyboard_report = &(report_keyboard_t){};

#ifndef NO_ACTION_ONESHOT
static int8_t oneshot_mods = 0;
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
static int16_t oneshot_time = 0;
#endif
#endif


void send_keyboard_report(void) {
keyboard_report->mods = real_mods;
keyboard_report->mods |= weak_mods;
#ifndef NO_ACTION_ONESHOT
if (oneshot_mods) {
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) {
dprintf("Oneshot: timeout\n");
clear_oneshot_mods();
}
#endif
keyboard_report->mods |= oneshot_mods;
if (has_anykey()) {
clear_oneshot_mods();
}
}
#endif
host_keyboard_send(keyboard_report);
}

/* key */
void add_key(uint8_t key)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
add_key_bit(key);
return;
}
#endif
add_key_byte(key);
}

void del_key(uint8_t key)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
del_key_bit(key);
return;
}
#endif
del_key_byte(key);
}

void clear_keys(void)
{
// not clear mods
for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
keyboard_report->raw[i] = 0;
}
}


/* modifier */
uint8_t get_mods(void) { return real_mods; }
void add_mods(uint8_t mods) { real_mods |= mods; }
void del_mods(uint8_t mods) { real_mods &= ~mods; }
void set_mods(uint8_t mods) { real_mods = mods; }
void clear_mods(void) { real_mods = 0; }

/* weak modifier */
uint8_t get_weak_mods(void) { return weak_mods; }
void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
void set_weak_mods(uint8_t mods) { weak_mods = mods; }
void clear_weak_mods(void) { weak_mods = 0; }

/* Oneshot modifier */
#ifndef NO_ACTION_ONESHOT
void set_oneshot_mods(uint8_t mods)
{
oneshot_mods = mods;
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = timer_read();
#endif
}
void clear_oneshot_mods(void)
{
oneshot_mods = 0;
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = 0;
#endif
}
#endif




/*
* inspect keyboard state
*/
uint8_t has_anykey(void)
{
uint8_t cnt = 0;
for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
if (keyboard_report->raw[i])
cnt++;
}
return cnt;
}

uint8_t has_anymod(void)
{
return bitpop(real_mods);
}

uint8_t get_first_key(void)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
uint8_t i = 0;
for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
;
return i<<3 | biton(keyboard_report->nkro.bits[i]);
}
#endif
#ifdef USB_6KRO_ENABLE
uint8_t i = cb_head;
do {
if (keyboard_report->keys[i] != 0) {
break;
}
i = RO_INC(i);
} while (i != cb_tail);
return keyboard_report->keys[i];
#else
return keyboard_report->keys[0];
#endif
}



/* local functions */
static inline void add_key_byte(uint8_t code)
{
#ifdef USB_6KRO_ENABLE
int8_t i = cb_head;
int8_t empty = -1;
if (cb_count) {
do {
if (keyboard_report->keys[i] == code) {
return;
}
if (empty == -1 && keyboard_report->keys[i] == 0) {
empty = i;
}
i = RO_INC(i);
} while (i != cb_tail);
if (i == cb_tail) {
if (cb_tail == cb_head) {
// buffer is full
if (empty == -1) {
// pop head when has no empty space
cb_head = RO_INC(cb_head);
cb_count--;
}
else {
// left shift when has empty space
uint8_t offset = 1;
i = RO_INC(empty);
do {
if (keyboard_report->keys[i] != 0) {
keyboard_report->keys[empty] = keyboard_report->keys[i];
keyboard_report->keys[i] = 0;
empty = RO_INC(empty);
}
else {
offset++;
}
i = RO_INC(i);
} while (i != cb_tail);
cb_tail = RO_SUB(cb_tail, offset);
}
}
}
}
// add to tail
keyboard_report->keys[cb_tail] = code;
cb_tail = RO_INC(cb_tail);
cb_count++;
#else
int8_t i = 0;
int8_t empty = -1;
for (; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
break;
}
if (empty == -1 && keyboard_report->keys[i] == 0) {
empty = i;
}
}
if (i == KEYBOARD_REPORT_KEYS) {
if (empty != -1) {
keyboard_report->keys[empty] = code;
}
}
#endif
}

static inline void del_key_byte(uint8_t code)
{
#ifdef USB_6KRO_ENABLE
uint8_t i = cb_head;
if (cb_count) {
do {
if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0;
cb_count--;
if (cb_count == 0) {
// reset head and tail
cb_tail = cb_head = 0;
}
if (i == RO_DEC(cb_tail)) {
// left shift when next to tail
do {
cb_tail = RO_DEC(cb_tail);
if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
break;
}
} while (cb_tail != cb_head);
}
break;
}
i = RO_INC(i);
} while (i != cb_tail);
}
#else
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0;
}
}
#endif
}

#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code)
{
if ((code>>3) < KEYBOARD_REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
} else {
dprintf("add_key_bit: can't add: %02X\n", code);
}
}

static inline void del_key_bit(uint8_t code)
{
if ((code>>3) < KEYBOARD_REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
} else {
dprintf("del_key_bit: can't del: %02X\n", code);
}
}
#endif

+ 0
- 66
common/action_util.h View File

@@ -1,66 +0,0 @@
/*
Copyright 2013 Jun Wako <[email protected]>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTION_UTIL_H
#define ACTION_UTIL_H

#include <stdint.h>
#include "report.h"

#ifdef __cplusplus
extern "C" {
#endif

extern report_keyboard_t *keyboard_report;

void send_keyboard_report(void);

/* key */
void add_key(uint8_t key);
void del_key(uint8_t key);
void clear_keys(void);

/* modifier */
uint8_t get_mods(void);
void add_mods(uint8_t mods);
void del_mods(uint8_t mods);
void set_mods(uint8_t mods);
void clear_mods(void);

/* weak modifier */
uint8_t get_weak_mods(void);
void add_weak_mods(uint8_t mods);
void del_weak_mods(uint8_t mods);