aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2022-12-27 02:19:10 +0100
committerLouis Burda <quent.burda@gmail.com>2022-12-27 02:19:10 +0100
commit8069562a2f7b530cd190cf06e0d88f1350d8d41d (patch)
tree8ced6a9073e9216fce79fb7feb144690aca35814 /src
parent878eb23b8394109aeb32cd505f79b96c74ec97f6 (diff)
downloadsxkbd-8069562a2f7b530cd190cf06e0d88f1350d8d41d.tar.gz
sxkbd-8069562a2f7b530cd190cf06e0d88f1350d8d41d.zip
Implement more keysym functions
Diffstat (limited to 'src')
-rw-r--r--src/hid.c328
-rw-r--r--src/hid.h3
-rw-r--r--src/keymap.c53
-rw-r--r--src/keymap.h4
-rw-r--r--src/keysym.h55
-rw-r--r--src/keysym/consumer.h2
-rw-r--r--src/keysym/system.h2
-rw-r--r--src/tusb_config.h16
-rw-r--r--src/usb_descriptors.c8
9 files changed, 360 insertions, 111 deletions
diff --git a/src/hid.c b/src/hid.c
index 96de5ea..a348caa 100644
--- a/src/hid.c
+++ b/src/hid.c
@@ -52,8 +52,8 @@ struct hid_gamepad_report {
static uint32_t keysyms[KEY_ROWS][KEY_COLS] = { 0 };
-static struct layerkey active_stack[16] = { 0 };
-static uint active_top = 0;
+static struct layerkey active_layers[16] = { 0 };
+static uint active_layers_top = 0;
static struct hid_keyboard_report keyboard_report_prev = { 0 };
static struct hid_keyboard_report keyboard_report = { 0 };
@@ -77,39 +77,117 @@ static uint64_t bounce_mat[KEY_ROWS][KEY_COLS] = { 0 };
static bool seen_mat[KEY_ROWS][KEY_COLS] = { 0 };
-static void active_pop(uint layer);
-static void active_push(uint layer, uint key);
+static uint32_t macro_held_stack[MACRO_HOLD_MAX] = { 0 };
+static uint macro_held_cnt = 0;
+
+static bool macro_running = false;
+
+/* TODO replace these two with stack method primitives (added to util) */
+
+static void active_layers_reset(void);
+static void active_layers_pop(uint layer);
+static void active_layers_push(uint layer, uint key);
+
+static void macro_held_reset(void);
+static void macro_held_pop(uint32_t keysym);
+static void macro_held_push(uint32_t keysym);
+static bool macro_held_find(uint32_t keysym);
+
static void add_keycode(uint8_t keycode);
void
-active_pop(uint layer)
+active_layers_reset(void)
+{
+ active_layers_top = 0;
+}
+
+bool
+active_layers_find(uint layer)
+{
+ uint i;
+
+ for (i = 0; i <= active_layers_top; i++) {
+ if (active_layers[i].layer == layer)
+ return true;
+ }
+
+ return false;
+}
+
+void
+active_layers_pop(uint layer)
{
uint i;
- for (i = layer + 1; i <= active_top; i++)
- active_stack[i-1] = active_stack[i];
- if (layer <= active_top)
- active_top--;
+ for (i = layer + 1; i <= active_layers_top; i++)
+ active_layers[i-1] = active_layers[i];
+ if (layer <= active_layers_top)
+ active_layers_top--;
}
void
-active_push(uint layer, uint key)
+active_layers_push(uint layer, uint key)
{
uint i;
- if (active_top == ARRLEN(active_stack) - 1) {
+ if (active_layers_top == ARRLEN(active_layers) - 1) {
WARN("Active stack overflow");
return;
}
- active_top += 1;
- active_stack[active_top].layer = layer;
- active_stack[active_top].key = key;
+ active_layers_top += 1;
+ active_layers[active_layers_top].layer = layer;
+ active_layers[active_layers_top].key = key;
- for (i = 0; i <= active_top; i++) {
+ for (i = 0; i <= active_layers_top; i++) {
INFO("%i. ACTIVE %u %u", i,
- active_stack[i].layer, active_stack[i].key);
+ active_layers[i].layer, active_layers[i].key);
+ }
+}
+
+void
+macro_held_reset(void)
+{
+ macro_held_cnt = 0;
+}
+
+void
+macro_held_pop(uint32_t keysym)
+{
+ uint i, cnt;
+
+ for (i = cnt = 0; i < macro_held_cnt; i++) {
+ if (macro_held_stack[i] != keysym) {
+ macro_held_stack[cnt] = macro_held_stack[i];
+ cnt++;
+ }
+ }
+ macro_held_cnt = cnt;
+}
+
+void
+macro_held_push(uint32_t keysym)
+{
+ if (macro_held_cnt == MACRO_HOLD_MAX) {
+ WARN("Macro help keys overflow");
+ return;
+ }
+
+ macro_held_stack[macro_held_cnt] = keysym;
+ macro_held_cnt++;
+}
+
+bool
+macro_held_find(uint32_t keysym)
+{
+ uint i;
+
+ for (i = 0; i < macro_held_cnt; i++) {
+ if (macro_held_stack[i] == keysym)
+ return true;
}
+
+ return false;
}
void
@@ -158,75 +236,107 @@ parse_modifiers(uint32_t keysym)
return mods;
}
-void
-handle_keypress_new(uint x, uint y)
+uint32_t
+determine_keysym(uint x, uint y)
{
- uint32_t ksym;
+ uint32_t keysym;
int i;
- for (i = (int) active_top; i >= 0; i--) {
- ksym = keymap_layers[active_stack[i].layer][y][x];
- if (ksym == KC_NO) return;
- if (ksym != KC_TRNS)
+ keysym = KC_NO;
+ for (i = (int) active_layers_top; i >= 0; i--) {
+ keysym = keymap_layers[active_layers[i].layer][y][x];
+ if (keysym != KC_TRNS && keysym != KC_NO)
break;
}
- if (i < 0) return;
- keysyms[y][x] = ksym;
-
- if (IS_SWITCH(keysyms[y][x])) {
- active_push(TO_LAYER(keysyms[y][x]), y * KEY_COLS + x);
- } else if (IS_USER(keysyms[y][x])) {
- process_user_keypress_new(TO_SYM(keysyms[y][x]), x, y);
- } else if (IS_KC(keysyms[y][x]) && IS_KEY_KC(TO_KC(keysyms[y][x]))) {
+
+ return keysym;
+}
+
+void
+process_keypress(uint32_t keysym, uint x, uint y)
+{
+ if (IS_SWITCH(keysym)) {
+ active_layers_push(TO_LAYER(keysym), y * KEY_COLS + x);
+ } else if (IS_TOGGLE(keysym)) {
+ if (active_layers_find(TO_LAYER(keysym)))
+ active_layers_pop(TO_LAYER(keysym));
+ else
+ active_layers_push(TO_LAYER(keysym), y * KEY_COLS + x);
+ } else if (IS_REBASE(keysym)) {
+ active_layers_reset();
+ active_layers[0].layer = TO_LAYER(keysym);
+ } else if (IS_USER(keysym)) {
+ process_user_keypress(TO_SYM(keysym), x, y);
+ } else if (IS_KC(keysym) && IS_KEY_KC(TO_KC(keysym))) {
/* FIXME: two keys pressed at the exact same time with
* different weak modifiers will not be reported correctly */
- active_weak_mods = parse_modifiers(keysyms[y][x]);
- } else if (IS_CONSUMER(keysyms[y][x])) {
- consumer_report.code = keysym_to_consumer(keysyms[y][x]);
- INFO("CONSUMER KEY %i", consumer_report.code);
+ active_weak_mods = parse_modifiers(keysym);
+ } else if (IS_CONSUMER(keysym)) {
+ consumer_report.code = keysym_to_consumer(keysym);
}
}
void
-handle_keypress(uint x, uint y)
+process_keydown(uint32_t keysym, uint x, uint y)
{
- if (!keymat_prev[y][x])
- handle_keypress_new(x, y);
-
if (seen_mat[y][x]) return;
seen_mat[y][x] = true;
- if (IS_KC(keysyms[y][x]) && IS_KEY_KC(TO_KC(keysyms[y][x]))) {
- add_keycode(TO_KC(keysyms[y][x]));
- INFO("CODE %u %u", active_top, keysyms[y][x]);
- } else if (IS_KC(keysyms[y][x]) && IS_MOD_KC(TO_KC(keysyms[y][x]))) {
- active_mods |= MOD_BIT(TO_KC(keysyms[y][x]));
- } else if (IS_MOD(keysyms[y][x])) {
- active_mods |= parse_modifiers(keysyms[y][x]);
+ if (IS_KC(keysym) && IS_KEY_KC(TO_KC(keysym))) {
+ add_keycode(TO_KC(keysym));
+ } else if (IS_KC(keysym) && IS_MOD_KC(TO_KC(keysym))) {
+ active_mods |= MOD_BIT(TO_KC(keysym));
+ } else if (IS_MOD(keysym)) {
+ active_mods |= parse_modifiers(keysym);
}
}
void
-handle_keyrelease_new(uint x, uint y)
+process_keyrelease(uint32_t keysym, uint x, uint y)
{
uint i;
- if (IS_USER(keysyms[y][x]))
- process_user_keyrelease_new(TO_SYM(keysyms[y][x]), x, y);
+ if (IS_USER(keysym))
+ process_user_keyrelease(TO_SYM(keysym), x, y);
- for (i = 1; i <= active_top; i++) {
- if (active_stack[i].key == y * KEY_COLS + x) {
- active_pop(i);
+ for (i = 1; i <= active_layers_top; i++) {
+ if (active_layers[i].key == y * KEY_COLS + x) {
+ active_layers_pop(i);
break;
}
}
}
void
-handle_keyrelease(uint x, uint y)
+process_keyup(uint32_t keysym, uint x, uint y)
+{
+}
+
+void
+process_key(uint x, uint y, uint64_t now_us)
{
- if (keymat_prev[y][x])
- handle_keyrelease_new(x, y);
+ if (keymat[y][x] != keymat_prev[y][x]) {
+ if (bounce_mat[y][x] > now_us - 50000) {
+ DEBUG("Bouncing prevented %i vs %i",
+ keymat[y][x], keymat_prev[y][x]);
+ keymat[y][x] = keymat_prev[y][x];
+ } else {
+ bounce_mat[y][x] = now_us;
+ }
+ }
+
+ if (keymat[y][x] && !keymat_prev[y][x])
+ keysyms[y][x] = determine_keysym(x, y);
+
+ if (keymat[y][x]) {
+ if (!keymat_prev[y][x])
+ process_keypress(keysyms[y][x], x, y);
+ process_keydown(keysyms[y][x], x, y);
+ } else {
+ if (keymat_prev[y][x])
+ process_keyrelease(keysyms[y][x], x, y);
+ process_keyup(keysyms[y][x], x, y);
+ }
}
void
@@ -238,21 +348,7 @@ update_report(void)
now_us = time_us_64();
for (y = 0; y < KEY_ROWS; y++) {
for (x = 0; x < KEY_COLS; x++) {
- if (keymat[y][x] != keymat_prev[y][x]) {
- if (bounce_mat[y][x] > now_us - 50000) {
- DEBUG("Bouncing prevented %i vs %i",
- keymat[y][x], keymat_prev[y][x]);
- keymat[y][x] = keymat_prev[y][x];
- } else {
- bounce_mat[y][x] = now_us;
- }
- }
-
- if (keymat[y][x]) {
- handle_keypress(x, y);
- } else {
- handle_keyrelease(x, y);
- }
+ process_key(x, y, now_us);
}
}
}
@@ -264,6 +360,11 @@ send_keyboard_report(void)
sent = false;
keyboard_report.mods = active_weak_mods | active_mods;
+
+ if (macro_running)
+ INFO("REPORT %u %u", keyboard_report.mods,
+ keyboard_report.codes[0]);
+
if (memcmp(&keyboard_report, &keyboard_report_prev,
sizeof(keyboard_report))) {
tud_hid_keyboard_report(REPORT_ID_KEYBOARD,
@@ -271,6 +372,8 @@ send_keyboard_report(void)
memcpy(&keyboard_report_prev, &keyboard_report,
sizeof(keyboard_report));
sent = true;
+
+ active_weak_mods = 0;
}
memset(&keyboard_report, 0, sizeof(keyboard_report));
@@ -285,8 +388,6 @@ send_consumer_report(void)
{
bool sent;
- INFO("CONSUMER %u", consumer_report.code);
-
sent = false;
if (memcmp(&consumer_report, &consumer_report_prev,
sizeof(consumer_report))) {
@@ -411,22 +512,101 @@ hid_init(void)
void
hid_force_release(uint x, uint y)
{
- handle_keyrelease_new(x, y);
+ process_keyrelease(keysyms[y][x], x, y);
keysyms[y][x] = KC_NO;
}
void
hid_switch_layer_with_key(uint8_t layer, uint x, uint y)
{
- active_push(layer, y * KEY_COLS + x);
+ active_layers_push(layer, y * KEY_COLS + x);
keysyms[y][x] = SW(layer);
seen_mat[y][x] = true;
}
void
+hid_send_macro(const uint32_t *keysyms, uint cnt)
+{
+ /* TODO: replace macro x y with less hacky alternative */
+ static const uint mx = 0, my = 7;
+ struct hid_keyboard_report tmp;
+ uint32_t start_ms;
+ uint i, k;
+
+ /* NOTE: layer switching is not supported for macros (not needed),
+ * to preserve the current layers we reference a key which is not
+ * in-use to prevent accidentally unmapping layers on release */
+
+ macro_held_reset();
+
+ active_mods = 0;
+ active_weak_mods = 0;
+ memset(&keyboard_report, 0, sizeof(keyboard_report));
+ memset(&keyboard_report_prev, 0, sizeof(keyboard_report));
+ memset(&seen_mat, 0, sizeof(seen_mat));
+
+ macro_running = true;
+ for (i = 0; i < cnt; i++) {
+ if (IS_MACRO_DELAY(keysyms[i])) {
+ start_ms = board_millis();
+ while (board_millis() - start_ms < TO_DELAY(keysyms[i]))
+ tud_task();
+ continue;
+ }
+
+ memset(&keyboard_report, 0, sizeof(keyboard_report));
+
+ if (IS_MACRO_RELEASE(keysyms[i]))
+ macro_held_pop(keysyms[i]);
+
+ for (k = 0; k < i; k++) {
+ if (macro_held_find(keysyms[k])) {
+ seen_mat[my][mx] = false;
+ process_keydown(keysyms[k], mx, my);
+ }
+ }
+
+ if (IS_MACRO_HOLD(keysyms[i]))
+ macro_held_push(keysyms[i]);
+
+ if (IS_MACRO_PRESS(keysyms[i])) {
+ keyboard_report.mods = active_weak_mods | active_mods;
+ memcpy(&tmp, &keyboard_report, sizeof(keyboard_report));
+ }
+
+ if (IS_MACRO_RELEASE(keysyms[i])) {
+ process_keyrelease(keysyms[i], mx, my);
+ process_keyup(keysyms[i], mx, my);
+ } else {
+ process_keypress(keysyms[i], mx, my);
+ process_keydown(keysyms[i], mx, my);
+ }
+
+ while (!tud_hid_ready())
+ tud_task();
+ send_next_hid_report(REPORT_ID_MIN);
+
+ if (IS_MACRO_PRESS(keysyms[i])) {
+ memcpy(&keyboard_report, &tmp, sizeof(keyboard_report));
+ while (!tud_hid_ready())
+ tud_task();
+ send_next_hid_report(REPORT_ID_MIN);
+ }
+ }
+
+ memset(&keyboard_report, 0, sizeof(keyboard_report));
+ send_next_hid_report(REPORT_ID_MIN);
+ while (!tud_hid_ready())
+ tud_task();
+
+ macro_running = false;
+}
+
+void
hid_task(void)
{
update_report();
if (tud_hid_ready())
send_next_hid_report(REPORT_ID_MIN);
}
+
diff --git a/src/hid.h b/src/hid.h
index 7046724..16ac53e 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -5,6 +5,8 @@
#include <stdbool.h>
#include <stdint.h>
+#define MACRO_HOLD_MAX 32
+
#define REPORT_ID_MIN REPORT_ID_KEYBOARD
enum {
REPORT_ID_KEYBOARD = 1,
@@ -18,4 +20,5 @@ enum {
void hid_init(void);
void hid_force_release(uint x, uint y);
void hid_switch_layer_with_key(uint8_t layer, uint x, uint y);
+void hid_send_macro(const uint32_t *keysyms, uint cnt);
void hid_task(void);
diff --git a/src/keymap.c b/src/keymap.c
index bf7fa91..2e37a2e 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1,4 +1,5 @@
#include "keymap.h"
+#include "hid/keyboard.h"
#include "keysym.h"
#include "keysym/consumer.h"
#include "keysym/keyboard_de.h"
@@ -79,7 +80,7 @@
#define LAYER_SHRT_DE KEYMAP( \
_______ , G(KC_1) , G(KC_2) , G(KC_3) , G(KC_4) , G(KC_5) , \
CS(BASE), A(KC_1) , A(KC_2) , A(KC_3) , A(KC_4) , A(KC_5) , \
- _______ ,G(KC_TAB),G(DE_DOT), A(DE_B) , A(DE_F) ,A(KC_SPC), \
+ _______ ,G(KC_TAB),G(DE_DOT), A(DE_B) , A(DE_F) , KC_SPC , \
_______ , _______ , _______ , \
\
G(KC_6) , G(KC_7) , G(KC_8) , G(KC_9) , G(KC_0) , _______ , \
@@ -116,7 +117,7 @@
_______ , SX(KVM1), SX(KVM2), _______ , _______ , _______ , \
_______ , _______ , _______ , _______ , _______ , _______ , \
KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , \
- _______ , _______ , _______ , \
+ RB(BASE), _______ , RB(GAME), \
\
_______ , KS_VOLD , KS_VOLU , KS_MUTE , _______ , _______ , \
_______ , KS_MPRV , KS_MNXT , KS_MPLY , _______ , _______ , \
@@ -124,6 +125,30 @@
_______ , _______ , _______ \
)
+#define LAYER_GAME_DE KEYMAP( \
+ KC_ESC , DE_Q , DE_W , DE_E , DE_R , DE_T , \
+ SW(GNUM), DE_A , DE_S , DE_D , DE_F , DE_G , \
+ KC_LCTL , DE_Z , DE_X , DE_C , DE_V , DE_B , \
+ KC_LSFT , KC_LALT , KC_SPC , \
+ \
+ XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , \
+ XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , \
+ XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , \
+ XXXXXXX , XXXXXXX , XXXXXXX \
+)
+
+#define LAYER_GNUM_DE KEYMAP( \
+ SW(META), KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , \
+ XXXXXXX , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , \
+ XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , \
+ XXXXXXX , KC_TAB , XXXXXXX , \
+ \
+ XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , \
+ XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , \
+ XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , \
+ XXXXXXX , XXXXXXX , XXXXXXX \
+)
+
enum {
BASE, /* base */
QUIK, /* symbols + nav */
@@ -133,6 +158,8 @@ enum {
NUMS, /* numbers */
SPEC, /* specials */
META, /* functions */
+ GAME, /* gaming base */
+ GNUM, /* gaming nums */
};
enum {
@@ -148,7 +175,9 @@ const uint32_t keymap_layers_de[][KEY_ROWS][KEY_COLS] = {
[SHRT] = LAYER_SHRT_DE,
[NUMS] = LAYER_NUMS_DE,
[SPEC] = LAYER_SPEC_DE,
- [META] = LAYER_META_DE
+ [META] = LAYER_META_DE,
+ [GAME] = LAYER_GAME_DE,
+ [GNUM] = LAYER_GNUM_DE
};
const uint32_t keymap_layers_de_count = ARRLEN(keymap_layers_de);
@@ -156,13 +185,27 @@ const uint32_t keymap_layers_de_count = ARRLEN(keymap_layers_de);
const uint32_t (*keymap_layers)[KEY_ROWS][KEY_COLS] = keymap_layers_de;
uint32_t keymap_layers_count = keymap_layers_de_count;
+const uint32_t macro_kvm1[] = {
+ KC_LEFT_CTRL, DELAY(100),
+ KC_LEFT_CTRL, DELAY(100),
+ KC_1
+};
+
+const uint32_t macro_kvm2[] = {
+ KC_LEFT_CTRL, DELAY(100),
+ KC_LEFT_CTRL, DELAY(100),
+ KC_2
+};
+
void
-process_user_keypress_new(uint8_t sym, uint x, uint y)
+process_user_keypress(uint8_t sym, uint x, uint y)
{
switch (sym) {
case KVM1:
+ hid_send_macro(macro_kvm1, ARRLEN(macro_kvm1));
break;
case KVM2:
+ hid_send_macro(macro_kvm2, ARRLEN(macro_kvm2));
break;
case QUSW:
if (keymat[7][3]) {
@@ -177,7 +220,7 @@ process_user_keypress_new(uint8_t sym, uint x, uint y)
}
void
-process_user_keyrelease_new(uint8_t sym, uint x, uint y)
+process_user_keyrelease(uint8_t sym, uint x, uint y)
{
}
diff --git a/src/keymap.h b/src/keymap.h
index 7f78e8b..c816e38 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -6,8 +6,8 @@
#include <stdint.h>
-void process_user_keypress_new(uint8_t sym, uint x, uint y);
-void process_user_keyrelease_new(uint8_t sym, uint x, uint y);
+void process_user_keypress(uint8_t sym, uint x, uint y);
+void process_user_keyrelease(uint8_t sym, uint x, uint y);
extern const uint32_t keymap_layers_de[][KEY_ROWS][KEY_COLS];
extern const uint32_t keymap_layers_de_count;
diff --git a/src/keysym.h b/src/keysym.h
index 79dce3a..7e3f6f2 100644
--- a/src/keysym.h
+++ b/src/keysym.h
@@ -12,17 +12,19 @@
#define IS_GUI(x) ((x) & (1U << B_GUI))
#define IS_RIGHT(x) ((x) & (1U << B_RIGHT))
#define IS_TOGGLE(x) ((x) & (1U << B_TOGGLE))
+#define IS_REBASE(x) ((x) & (1U << B_REBASE))
#define IS_SWITCH(x) ((x) & (1U << B_SWITCH))
#define IS_SPECIAL(x) ((x) & (1U << B_SPECIAL))
#define IS_USER(x) ((x) & (1U << B_USER))
-#define KEYSYM_MOUSE_MASK ((1U << B_SPECIAL) | (0b01 << B_SPECIAL_SEL))
-#define KEYSYM_SYSTEM_MASK ((1U << B_SPECIAL) | (0b10 << B_SPECIAL_SEL))
-#define KEYSYM_CONSUMER_MASK ((1U << B_SPECIAL) | (0b11 << B_SPECIAL_SEL))
+#define IS_MOUSE(x) (IS_SPECIAL(x) && (TO_SPECIAL(x) == S_MOUSE))
+#define IS_SYSTEM(x) (IS_SPECIAL(x) && (TO_SPECIAL(x) == S_SYSTEM))
+#define IS_CONSUMER(x) (IS_SPECIAL(x) && (TO_SPECIAL(x) == S_CONSUMER))
-#define IS_MOUSE(x) ((x) & (KEYSYM_MOUSE_MASK))
-#define IS_SYSTEM(x) ((x) & (KEYSYM_SYSTEM_MASK))
-#define IS_CONSUMER(x) ((x) & (KEYSYM_CONSUMER_MASK))
+#define IS_MACRO_HOLD(x) ((x) & (1U << B_MACRO_HOLD))
+#define IS_MACRO_RELEASE(x) ((x) & (1U << B_MACRO_RELEASE))
+#define IS_MACRO_PRESS(x) (!IS_MACRO_HOLD(x) && !IS_MACRO_RELEASE(x))
+#define IS_MACRO_DELAY(x) ((x) & (1U << B_MACRO_DELAY))
#define IS_LEFT_CTRL(x) (IS_CTRL(x) && !IS_RIGHT(x))
#define IS_RIGHT_CTRL(x) (IS_CTRL(x) && IS_RIGHT(x))
@@ -35,23 +37,34 @@
#define IS_MOD(x) ((x) & MASK(B_TOGGLE, B_CTRL))
-#define TO_KC(x) ((x) & 0xFF)
-#define TO_SYM(x) ((x) & 0xFF)
+#define TO_SPECIAL(x) (((x) >> B_SPECIAL_SEL) & 0b11)
+#define TO_KC(x) ((x) & 0xFF)
+#define TO_SYM(x) ((x) & 0xFF)
#define TO_LAYER(x) ((x) & 0xFF)
+#define TO_DELAY(x) ((x) & 0xFFFF)
+
+#define SPECIAL(x, g) ((x) | (1U << B_SPECIAL) | ((g) << B_SPECIAL_SEL))
#define LCTL(x) ((x) | (1 << B_CTRL))
#define LSFT(x) ((x) | (1 << B_SHIFT))
#define LALT(x) ((x) | (1 << B_ALT))
#define LGUI(x) ((x) | (1 << B_GUI))
-#define RCTL(x) (LCTL(x) | (1 << B_RIGHT))
-#define RSFT(x) (LSFT(x) | (1 << B_RIGHT))
-#define RALT(x) (LALT(x) | (1 << B_RIGHT))
-#define RGUI(x) (LGUI(x) | (1 << B_RIGHT))
+#define RIGH(x) ((x) | (1 << B_RIGHT))
+
+#define HOLD(x) ((x) | (1 << B_MACRO_HOLD))
+#define RELEASE(x) ((x) | (1 << B_MACRO_RELEASE))
+#define DELAY(x) ((x) | (1 << B_MACRO_DELAY))
#define SW(x) ((x) | (1 << B_SWITCH))
#define TO(x) ((x) | (1 << B_TOGGLE))
+#define RB(x) ((x) | (1 << B_REBASE))
#define SX(x) ((x) | (1 << B_USER))
+#define RCTL(x) RIGH(LCTL(x))
+#define RSFT(x) RIGH(LSFT(x))
+#define RALT(x) RIGH(LALT(x))
+#define RGUI(x) RIGH(LGUI(x))
+
#define LOPT(x) LALT(x)
#define LCMD(x) LGUI(x)
#define LWIN(x) LGUI(x)
@@ -59,14 +72,20 @@
#define ROPT(x) RALT(x)
#define RCMD(x) RGUI(x)
+#define CS(x) C(SW(x))
+#define AS(x) A(SW(x))
+#define GS(x) G(SW(x))
+
#define C(x) LCTL(x)
#define S(x) LSFT(x)
#define A(x) LALT(x)
#define G(x) LGUI(x)
-#define CS(x) C(SW(x))
-#define AS(x) A(SW(x))
-#define GS(x) G(SW(x))
+enum {
+ S_CONSUMER,
+ S_MOUSE,
+ S_SYSTEM
+};
enum {
B_SPECIAL_SEL = 6,
@@ -76,8 +95,12 @@ enum {
B_GUI,
B_RIGHT,
B_TOGGLE,
+ B_REBASE,
B_SWITCH,
B_SPECIAL,
- B_USER
+ B_USER,
+ B_MACRO_HOLD,
+ B_MACRO_RELEASE,
+ B_MACRO_DELAY /* >= 16 */
};
diff --git a/src/keysym/consumer.h b/src/keysym/consumer.h
index c760649..30a8f68 100644
--- a/src/keysym/consumer.h
+++ b/src/keysym/consumer.h
@@ -29,7 +29,7 @@
#define KS_BRID KS_BRIGHTNESS_DOWN
enum keysym_consumer {
- KS_AUDIO_MUTE = KEYSYM_CONSUMER_MASK,
+ KS_AUDIO_MUTE = SPECIAL(0, S_CONSUMER),
KS_AUDIO_VOL_UP,
KS_AUDIO_VOL_DOWN,
KS_MEDIA_NEXT_TRACK,
diff --git a/src/keysym/system.h b/src/keysym/system.h
index f0174f5..f3a955b 100644
--- a/src/keysym/system.h
+++ b/src/keysym/system.h
@@ -10,7 +10,7 @@
#define KS_WAKE KS_SYSTEM_WAKE
enum keysym_system {
- KS_SYSTEM_POWER = KEYSYM_SYSTEM_MASK,
+ KS_SYSTEM_POWER = SPECIAL(0, S_SYSTEM),
KS_SYSTEM_SLEEP,
KS_SYSTEM_WAKE,
};
diff --git a/src/tusb_config.h b/src/tusb_config.h
index 31bdac7..54378b0 100644
--- a/src/tusb_config.h
+++ b/src/tusb_config.h
@@ -5,11 +5,11 @@ extern "C" {
#endif
#ifndef BOARD_TUD_RHPORT
-#define BOARD_TUD_RHPORT 0
+#define BOARD_TUD_RHPORT 0
#endif
#ifndef BOARD_TUD_MAX_SPEED
-#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
+#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
#endif
#ifndef CFG_TUSB_MCU
@@ -17,27 +17,27 @@ extern "C" {
#endif
#ifndef CFG_TUSB_OS
-#define CFG_TUSB_OS OPT_OS_NONE
+#define CFG_TUSB_OS OPT_OS_NONE
#endif
#ifndef CFG_TUSB_DEBUG
-#define CFG_TUSB_DEBUG 0
+#define CFG_TUSB_DEBUG 0
#endif
-#define CFG_TUD_ENABLED 1
+#define CFG_TUD_ENABLED 1
-#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
+#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif
#ifndef CFG_TUSB_MEM_ALIGN
-#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
+#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#endif
#ifndef CFG_TUD_ENDPOINT0_SIZE
-#define CFG_TUD_ENDPOINT0_SIZE 64
+#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
#define CFG_TUD_CDC 1
diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c
index 9b70e2a..45019fc 100644
--- a/src/usb_descriptors.c
+++ b/src/usb_descriptors.c
@@ -93,7 +93,7 @@ uint8_t const desc_hs_configuration[] = {
/* Interface number, string index, protocol, report descriptor len,
* EP In address, size & polling interval */
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 5, HID_ITF_PROTOCOL_NONE,
- sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5)
+ sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 1)
};
uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
@@ -104,9 +104,9 @@ tusb_desc_device_qualifier_t const desc_device_qualifier =
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
.bcdUSB = USB_BCD,
- .bDeviceClass = TUSB_CLASS_MISC,
- .bDeviceSubClass = MISC_SUBCLASS_COMMON,
- .bDeviceProtocol = MISC_PROTOCOL_IAD,
+ .bDeviceClass = 0x00,
+ .bDeviceSubClass = 0x00,
+ .bDeviceProtocol = 0x00,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.bNumConfigurations = 0x01,