From e9de2f16634b2d3c156e270eb267eb01a34b4d75 Mon Sep 17 00:00:00 2001 From: tmk Date: Thu, 14 Feb 2013 15:22:59 +0900 Subject: [PATCH 01/25] Add layer stack --- common/action.c | 259 +++++++++++++++++++++++++++++++++++++++--------- common/action.h | 133 ++++++++++++++----------- 2 files changed, 286 insertions(+), 106 deletions(-) diff --git a/common/action.c b/common/action.c index 6528cd46..d0c9ddb0 100644 --- a/common/action.c +++ b/common/action.c @@ -163,6 +163,85 @@ static void oneshot_toggle(void) } +/* + * Layer stack + */ +#define LAYER_STACK_SIZE 8 +typedef struct { + uint8_t layer:4; + uint8_t next:3; + bool used; +} layer_item_t; + +static uint8_t top_layer = 0; +// [0] is sentinel and not used. [0] is null item. +static layer_item_t layer_stack[LAYER_STACK_SIZE] = {}; + +static bool layer_push(uint8_t layer) +{ + for (uint8_t i = 1; i < LAYER_STACK_SIZE; i++) { + if (!layer_stack[i].used) { + layer_stack[i] = (layer_item_t){ .layer = layer, + .next = top_layer, + .used = true }; + top_layer = i; + return true; + } + } + return false; +} +static bool layer_pop(void) +{ + if (layer_stack[top_layer].used) { + uint8_t popped = top_layer; + top_layer = layer_stack[popped].next; + layer_stack[popped] = (layer_item_t){}; + return true; + } + return false; +} +static bool layer_remove(uint8_t layer) +{ + if (layer_stack[top_layer].used && layer_stack[top_layer].layer == layer) { + layer_pop(); + debug("layer_remove: top_layer\n"); + return true; + } + + for (uint8_t i = top_layer; layer_stack[i].used; i = layer_stack[i].next) { + debug("layer_remove: ["); debug_dec(i); debug("]"); + debug_dec(layer_stack[i].layer); debug("\n"); + uint8_t removed = layer_stack[i].next; + if (layer_stack[removed].used && layer_stack[removed].layer == layer) { + layer_stack[i].next = layer_stack[removed].next; + layer_stack[removed] = (layer_item_t){}; + debug("layer_remove: removed.\n"); + return true; + } + } + return false; +} +static bool layer_remove_then_push(uint8_t layer) +{ + layer_remove(layer); + return layer_push(layer); +} +static bool layer_remove_or_push(uint8_t layer) +{ + return (layer_remove(layer)) || layer_push(layer); +} +static void debug_layer_stack(void) +{ + debug("layer_stack: "); + layer_item_t item = layer_stack[top_layer]; + while (item.used) { + debug_dec(item.layer); + debug("["); debug_dec(item.next); debug("]"); + item = layer_stack[item.next]; + } + debug("\n"); +} + void action_exec(keyevent_t event) { @@ -209,13 +288,26 @@ void action_exec(keyevent_t event) static action_t get_action(key_t key) { - action_t action = action_for_key(current_layer, key); + action_t action; - /* Transparently use default layer */ + /* layer stack */ + for (layer_item_t i = layer_stack[top_layer]; i.used; i = layer_stack[i.next]) { + action = action_for_key(i.layer, key); + if (action.code != ACTION_TRANSPARENT) { + debug_layer_stack(); + debug("layer_stack: used. "); debug_dec(i.layer); debug("\n"); + return action; + } + debug("layer_stack: through. "); debug_dec(i.layer); debug("\n"); + } + + /* current layer */ + action = action_for_key(current_layer, key); + + /* default layer */ if (action.code == ACTION_TRANSPARENT) { - // TODO: layer stacking - action = action_for_key(default_layer, key); debug("TRNASPARENT: "); debug_hex16(action.code); debug("\n"); + action = action_for_key(default_layer, key); } return action; } @@ -287,7 +379,7 @@ static void process_action(keyrecord_t *record) } else { if (tap_count == 0) { debug("MODS_TAP: Oneshot: cancel/del_mods\n"); - // cancel oneshot by holding. + // cancel oneshot on hold oneshot_cancel(); del_mods(mods); } @@ -390,22 +482,8 @@ static void process_action(keyrecord_t *record) layer_switch(action.layer.val); } break; - case LAYER_DEFAULT: /* default layer */ - switch (action.layer.val) { - case DEFAULT_ON_BOTH: - layer_switch(default_layer); - break; - case DEFAULT_ON_PRESS: - if (event.pressed) { - layer_switch(default_layer); - } - break; - case DEFAULT_ON_RELEASE: - if (!event.pressed) { - layer_switch(default_layer); - } - break; - } + case LAYER_ON_BOTH: + layer_switch(action.layer.val); break; case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ if (event.pressed) { @@ -419,29 +497,39 @@ static void process_action(keyrecord_t *record) } } break; - case LAYER_CHANGE_DEFAULT: /* change default layer */ + case LAYER_SET_DEFAULT_ON_PRESS: if (event.pressed) { default_layer = action.layer.val; layer_switch(default_layer); } break; - default: /* switch layer on hold and key on tap*/ + case LAYER_SET_DEFAULT_ON_RELEASE: + if (!event.pressed) { + default_layer = action.layer.val; + layer_switch(default_layer); + } + break; + case LAYER_SET_DEFAULT_ON_BOTH: + default_layer = action.layer.val; + layer_switch(default_layer); + break; + default: + /* tap key */ if (event.pressed) { - if (tap_count > 0) { - debug("LAYER_PRESSED: Tap: register_code\n"); - register_code(action.layer.code); - } else { - debug("LAYER_PRESSED: No tap: layer_switch\n"); - layer_switch(action.layer.val); - } + if (IS_TAPPING_KEY(event.key) && tap_count > 0) { + debug("LAYER_SET: Tap: register_code\n"); + register_code(action.layer.code); + } else { + debug("LAYER_SET: No tap: layer_set(on press)\n"); + layer_switch(action.layer.val); + } } else { - if (tap_count > 0) { - debug("LAYER_PRESSED: Tap: unregister_code\n"); + if (IS_TAPPING_KEY(event.key) && tap_count > 0) { + debug("LAYER_SET: Tap: unregister_code\n"); unregister_code(action.layer.code); } else { - //debug("LAYER_PRESSED: No tap: NO ACTION\n"); // NOTE: This is needed by legacy keymap support - debug("LAYER_PRESSED: No tap: return to default layer\n"); + debug("LAYER_SET: No tap: return to default layer(on release)\n"); layer_switch(default_layer); } } @@ -452,9 +540,9 @@ static void process_action(keyrecord_t *record) switch (action.layer.code) { case LAYER_MOMENTARY: /* momentary */ if (event.pressed) { - layer_switch(current_layer ^ action.layer.val); + layer_switch(current_layer | action.layer.val); } else { - layer_switch(current_layer ^ action.layer.val); + layer_switch(current_layer & ~action.layer.val); } break; case LAYER_ON_PRESS: @@ -467,6 +555,9 @@ static void process_action(keyrecord_t *record) layer_switch(current_layer ^ action.layer.val); } break; + case LAYER_ON_BOTH: + layer_switch(current_layer ^ action.layer.val); + break; case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ if (event.pressed) { if (tap_count < TAPPING_TOGGLE) { @@ -480,24 +571,30 @@ static void process_action(keyrecord_t *record) } } break; - case 0xFF: - // change default layer + case LAYER_SET_DEFAULT_ON_PRESS: if (event.pressed) { default_layer = current_layer ^ action.layer.val; layer_switch(default_layer); - } else { - default_layer = current_layer ^ action.layer.val; - layer_switch(default_layer); } break; + case LAYER_SET_DEFAULT_ON_RELEASE: + if (!event.pressed) { + default_layer = current_layer ^ action.layer.val; + layer_switch(default_layer); + } + break; + case LAYER_SET_DEFAULT_ON_BOTH: + default_layer = current_layer ^ action.layer.val; + layer_switch(default_layer); + break; default: - // with tap key + // tap key if (event.pressed) { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { debug("LAYER_BIT: Tap: register_code\n"); register_code(action.layer.code); } else { - debug("LAYER_BIT: No tap: layer_switch(bit on)\n"); + debug("LAYER_BIT: No tap: layer_bit(on press)\n"); layer_switch(current_layer ^ action.layer.val); } } else { @@ -505,13 +602,79 @@ static void process_action(keyrecord_t *record) debug("LAYER_BIT: Tap: unregister_code\n"); unregister_code(action.layer.code); } else { - debug("LAYER_BIT: No tap: layer_switch(bit off)\n"); + debug("LAYER_BIT: No tap: layer_bit(on release)\n"); layer_switch(current_layer ^ action.layer.val); } } break; } break; + case ACT_LAYER_STACK: + switch (action.layer.code) { + case LAYER_MOMENTARY: /* momentary */ + if (event.pressed) { + layer_remove_then_push(action.layer.val); + debug_layer_stack(); + } else { + layer_remove(action.layer.val); + debug_layer_stack(); + } + break; + case LAYER_ON_PRESS: + if (event.pressed) { + layer_remove_or_push(action.layer.val); + debug_layer_stack(); + } + break; + case LAYER_ON_RELEASE: + if (!event.pressed) { + layer_remove_or_push(action.layer.val); + debug_layer_stack(); + } + break; + case LAYER_ON_BOTH: + layer_remove_or_push(action.layer.val); + debug_layer_stack(); + break; + case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ + if (event.pressed) { + if (tap_count < TAPPING_TOGGLE) { + debug("LAYER_STACK: tap toggle(press).\n"); + layer_remove_or_push(action.layer.val); + debug_layer_stack(); + } + } else { + if (tap_count <= TAPPING_TOGGLE) { + debug("LAYER_STACK: tap toggle(release).\n"); + layer_remove_or_push(action.layer.val); + debug_layer_stack(); + } + } + break; + default: + // tap key + if (event.pressed) { + if (IS_TAPPING_KEY(event.key) && tap_count > 0) { + debug("LAYER_STACK: Tap: register_code\n"); + register_code(action.layer.code); + } else { + debug("LAYER_STACK: No tap: layer_stack(on press)\n"); + layer_remove_or_push(action.layer.val); + debug_layer_stack(); + } + } else { + if (IS_TAPPING_KEY(event.key) && tap_count > 0) { + debug("LAYER_STACK: Tap: unregister_code\n"); + unregister_code(action.layer.code); + } else { + debug("LAYER_STACK: No tap: layer_stack(on release)\n"); + layer_remove_or_push(action.layer.val); + debug_layer_stack(); + } + } + break; + } + break; /* Extentions */ case ACT_MACRO: @@ -839,7 +1002,10 @@ bool is_tap_key(key_t key) case LAYER_MOMENTARY: case LAYER_ON_PRESS: case LAYER_ON_RELEASE: - case LAYER_DEFAULT: + case LAYER_ON_BOTH: + case LAYER_SET_DEFAULT_ON_PRESS: + case LAYER_SET_DEFAULT_ON_RELEASE: + case LAYER_SET_DEFAULT_ON_BOTH: return false; case LAYER_TAP_TOGGLE: default: /* tap key */ @@ -876,8 +1042,9 @@ static void debug_action(action_t action) case ACT_RMODS_TAP: debug("ACT_RMODS_TAP"); break; case ACT_USAGE: debug("ACT_USAGE"); break; case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break; - case ACT_LAYER: debug("ACT_LAYER"); break; + case ACT_LAYER: debug("ACT_LAYER"); break; case ACT_LAYER_BIT: debug("ACT_LAYER_BIT"); break; + case ACT_LAYER_STACK: debug("ACT_LAYER_STACK"); break; case ACT_MACRO: debug("ACT_MACRO"); break; case ACT_COMMAND: debug("ACT_COMMAND"); break; case ACT_FUNCTION: debug("ACT_FUNCTION"); break; diff --git a/common/action.h b/common/action.h index b9a6cb5b..96b8ba2e 100644 --- a/common/action.h +++ b/common/action.h @@ -162,25 +162,34 @@ bool waiting_buffer_has_anykey_pressed(void); * * Layer Actions * ------------- - * ACT_LAYER(1000): Set layer - * ACT_LAYER_BIT(1001): Bit-op layer + * ACT_LAYER(1000): Set layer + * ACT_LAYER_BIT(1001): Bit-op layer + * ACT_LAYER_STACK: Layer stack * - * 1000|LLLL|0000 0000 set L to layer on press and set default on release(momentary) - * 1000|LLLL|0000 0001 set L to layer on press - * 1000|LLLL|0000 0010 set L to layer on release - * 1000|----|0000 0011 set default to layer on both(return to default layer) - * 1000|LLLL| keycode set L to layer while hold and send key on tap - * 1000|LLLL|1111 0000 set L to layer while hold and toggle on several taps - * 1000|LLLL|1111 1111 set L to default and layer(on press) + * 1000|LLLL|0000 0000 set current layer on press and return to default on release(momentary) + * 1000|LLLL|0000 0001 set current layer on press + * 1000|LLLL|0000 0010 set current layer on release + * 1000|LLLL|0000 0011 set current layer on both + * 1000|LLLL| keycode set current layer on hold and send key on tap + * 1000|LLLL|1111 0000 set current layer on hold and toggle on several taps + * 1000|DDDD|1111 1111 set default layer on press + * L: 0 means default layer * - * 1001|BBBB|0000 0000 (not used) - * 1001|BBBB|0000 0001 bit-xor layer with B on press - * 1001|BBBB|0000 0010 bit-xor layer with B on release - * 1001|BBBB|0000 0011 bit-xor layer with B on both(momentary) - * 1001|BBBB| keycode bit-xor layer with B while hold and send key on tap - * 1001|BBBB|1111 0000 bit-xor layer with B while hold and toggle on several taps - * 1001|BBBB|1111 1111 bit-xor default with B and set layer(on press) + * 1001|BBBB|0000 0000 bit-on current layer on press and bit-off on release(momentary) + * 1001|BBBB|0000 0001 bit-xor current layer on press + * 1001|BBBB|0000 0010 bit-xor current layer on release + * 1001|BBBB|0000 0011 bit-xor current layer on both + * 1001|BBBB| keycode bit-xor current layer on hold and send key on tap + * 1001|BBBB|1111 0000 bit-xor current layer on hold and toggle on several taps + * 1001|BBBB|1111 1111 bit-xor default layer on both * + * 1011|LLLL|0000 0000 push on press and remove on release(momentary) + * 1011|LLLL|0000 0001 push or remove on press + * 1011|LLLL|0000 0010 push or remove on release + * 1011|LLLL|0000 0011 push or remove on both + * 1011|LLLL| keycode push or remove on hold and send key on tap + * 1011|LLLL|1111 0000 push or remove on hold and toggle on several taps + * 1011|LLLL|1111 1111 (not used) * * * Extensions(11XX) @@ -210,6 +219,7 @@ enum action_kind_id { ACT_LAYER = 0b1000, ACT_LAYER_BIT = 0b1001, + ACT_LAYER_STACK = 0b1011, ACT_MACRO = 0b1100, ACT_COMMAND = 0b1110, @@ -223,20 +233,20 @@ enum action_kind_id { #define ACTION(kind, param) ((kind)<<12 | (param)) #define MODS4(mods) (((mods)>>4 | (mods)) & 0x0F) -/* Key */ +/* + * Key + */ #define ACTION_KEY(key) ACTION(ACT_LMODS, key) /* Mods & key */ #define ACTION_LMODS(mods) ACTION(ACT_LMODS, MODS4(mods)<<8 | 0x00) #define ACTION_LMODS_KEY(mods, key) ACTION(ACT_LMODS, MODS4(mods)<<8 | (key)) #define ACTION_RMODS(mods) ACTION(ACT_RMODS, MODS4(mods)<<8 | 0x00) #define ACTION_RMODS_KEY(mods, key) ACTION(ACT_RMODS, MODS4(mods)<<8 | (key)) -/* Mod & key */ #define ACTION_LMOD(mod) ACTION(ACT_LMODS, MODS4(MOD_BIT(mod))<<8 | 0x00) #define ACTION_LMOD_KEY(mod, key) ACTION(ACT_LMODS, MODS4(MOD_BIT(mod))<<8 | (key)) #define ACTION_RMOD(mod) ACTION(ACT_RMODS, MODS4(MOD_BIT(mod))<<8 | 0x00) #define ACTION_RMOD_KEY(mod, key) ACTION(ACT_RMODS, MODS4(MOD_BIT(mod))<<8 | (key)) - -/* Mods + Tap key */ +/* Tap key */ enum mods_codes { MODS_ONESHOT = 0x00, }; @@ -244,7 +254,6 @@ enum mods_codes { #define ACTION_LMODS_ONESHOT(mods) ACTION(ACT_LMODS_TAP, MODS4(mods)<<8 | MODS_ONESHOT) #define ACTION_RMODS_TAP_KEY(mods, key) ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | (key)) #define ACTION_RMODS_ONESHOT(mods) ACTION(ACT_RMODS_TAP, MODS4(mods)<<8 | MODS_ONESHOT) -/* Mod + Tap key */ #define ACTION_LMOD_TAP_KEY(mod, key) ACTION(ACT_LMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key)) #define ACTION_LMOD_ONESHOT(mod) ACTION(ACT_LMODS_TAP, MODS4(MOD_BIT(mod))<<8 | MODS_ONESHOT) #define ACTION_RMOD_TAP_KEY(mod, key) ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key)) @@ -252,73 +261,77 @@ enum mods_codes { /* - * Switch layer + * Layer switching */ enum layer_codes { LAYER_MOMENTARY = 0, LAYER_ON_PRESS = 1, LAYER_ON_RELEASE = 2, - LAYER_DEFAULT =3, + LAYER_ON_BOTH =3, LAYER_TAP_TOGGLE = 0xF0, - LAYER_CHANGE_DEFAULT = 0xFF + LAYER_SET_DEFAULT_ON_PRESS = 0xFD, + LAYER_SET_DEFAULT_ON_RELEASE = 0xFE, + LAYER_SET_DEFAULT_ON_BOTH = 0xFF }; -enum layer_vals_default { - DEFAULT_ON_PRESS = 1, - DEFAULT_ON_RELEASE = 2, - DEFAULT_ON_BOTH = 3, -}; - /* - * return to default layer + * Default layer + */ +/* set default layer */ +#define ACTION_LAYER_SET_DEFAULT(layer) ACTION_LAYER_SET_DEFAULT_R(layer) +#define ACTION_LAYER_SET_DEFAULT_P(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_SET_DEFAULT_ON_PRESS) +#define ACTION_LAYER_SET_DEFAULT_R(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_SET_DEFAULT_ON_RELEASE) +#define ACTION_LAYER_SET_DEFAULT_B(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_SET_DEFAULT_ON_BOTH) +/* bit-xor default layer */ +#define ACTION_LAYER_BIT_DEFAULT(bits) ACTION_LAYER_BIT_DEFAULT_R(bits) +#define ACTION_LAYER_BIT_DEFAULT_P(bits) ACTION(ACT_LAYER, (bits)<<8 | LAYER_SET_DEFAULT_ON_PRESS) +#define ACTION_LAYER_BIT_DEFAULT_R(bits) ACTION(ACT_LAYER, (bits)<<8 | LAYER_SET_DEFAULT_ON_RELEASE) +#define ACTION_LAYER_BIT_DEFAULT_B(bits) ACTION(ACT_LAYER, (bits)<<8 | LAYER_SET_DEFAULT_ON_BOTH) +/* + * Current layer: Return to default layer */ #define ACTION_LAYER_DEFAULT ACTION_LAYER_DEFAULT_R -/* set default layer on press */ -#define ACTION_LAYER_DEFAULT_P ACTION(ACT_LAYER, DEFAULT_ON_PRESS<<8 | LAYER_DEFAULT) -/* set default layer on release */ -#define ACTION_LAYER_DEFAULT_R ACTION(ACT_LAYER, DEFAULT_ON_RELEASE<<8 | LAYER_DEFAULT) -/* change default layer and set layer */ - +#define ACTION_LAYER_DEFAULT_P ACTION_LAYER_SET_P(0) +#define ACTION_LAYER_DEFAULT_R ACTION_LAYER_SET_R(0) +#define ACTION_LAYER_DEFAULT_B ACTION_LAYER_SET_B(0) /* - * Set layer + * Current layer: Set */ -/* set layer on press and none on release */ #define ACTION_LAYER_SET(layer) ACTION_LAYER_SET_P(layer) -/* set layer on press and set default on release (This is needed by legacy keymap support.) */ #define ACTION_LAYER_SET_MOMENTARY(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_MOMENTARY) -/* set layer on press and none on release */ #define ACTION_LAYER_SET_TOGGLE(layer) ACTION_LAYER_SET_R(layer) -/* set layer while hold and send key on tap */ -#define ACTION_LAYER_SET_TAP_KEY(layer, key) ACTION(ACT_LAYER, (layer)<<8 | (key)) -/* set layer on press */ #define ACTION_LAYER_SET_P(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_ON_PRESS) -/* set layer on release */ #define ACTION_LAYER_SET_R(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_ON_RELEASE) -/* set layer on hold and toggle on several taps */ +#define ACTION_LAYER_SET_B(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_ON_BOTH) #define ACTION_LAYER_SET_TAP_TOGGLE(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_TAP_TOGGLE) -/* set default layer on both press and release */ -#define ACTION_LAYER_SET_DEFAULT(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_CHANGE_DEFAULT) - +#define ACTION_LAYER_SET_TAP_KEY(layer, key) ACTION(ACT_LAYER, (layer)<<8 | (key)) /* - * Bit-op layer + * Current layer: Bit-op */ -/* bit-xor on both press and release */ #define ACTION_LAYER_BIT(bits) ACTION_LAYER_BIT_MOMENTARY(bits) #define ACTION_LAYER_BIT_MOMENTARY(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_MOMENTARY) -/* bit-xor on press */ #define ACTION_LAYER_BIT_TOGGLE(bits) ACTION_LAYER_BIT_R(bits) -/* bit-xor while hold and send key on tap */ -#define ACTION_LAYER_BIT_TAP_KEY(bits, key) ACTION(ACT_LAYER_BIT, (bits)<<8 | (key)) -/* bit-xor on press */ #define ACTION_LAYER_BIT_P(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_ON_PRESS) -/* bit-xor on release */ #define ACTION_LAYER_BIT_R(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_ON_RELEASE) -/* bit-xor while hold and toggle on several taps */ +#define ACTION_LAYER_BIT_B(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_ON_BOTH) #define ACTION_LAYER_BIT_TAP_TOGGLE(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_TAP_TOGGLE) -/* bit-xor default layer and set layer */ -#define ACTION_LAYER_BIT_DEFAULT(bits) ACTION(ACT_LAYER, (bits)<<8 | LAYER_CHANGE_DEFAULT) +#define ACTION_LAYER_BIT_TAP_KEY(bits, key) ACTION(ACT_LAYER_BIT, (bits)<<8 | (key)) +/* + * Layer Stack + */ +/* momentary */ +#define ACTION_LAYER_STACK(layer) ACTION_LAYER_STACK_MOMENTARY(layer) +#define ACTION_LAYER_STACK_MOMENTARY(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_MOMENTARY) +#define ACTION_LAYER_STACK_TOGGLE(layer) ACTION_LAYER_STACK_R(layer) +#define ACTION_LAYER_STACK_P(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_ON_PRESS) +#define ACTION_LAYER_STACK_R(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_ON_RELEASE) +#define ACTION_LAYER_STACK_B(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_ON_BOTH) +#define ACTION_LAYER_STACK_TAP_TOGGLE(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_TAP_TOGGLE) +#define ACTION_LAYER_STACK_TAP_KEY(layer, key) ACTION(ACT_LAYER_STACK, (layer)<<8 | (key)) -/* HID Usage */ +/* + * HID Usage + */ enum usage_pages { PAGE_SYSTEM, PAGE_CONSUMER From 8b8b79e039e8ded035cf8c21383be0174b1f7f60 Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 15 Feb 2013 12:17:03 +0900 Subject: [PATCH 02/25] Change: 0 means default_layer in current_layer now - current_layer indicates active layer at the time - default_layer indicates base layer - default_layer is used when current_layer is 0 - with this LAYER_BIT action works as overlay even if default_layer varies other than layer 0. --- common/action.c | 39 ++++++++++++++++++++++----------------- common/command.c | 7 ++++--- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/common/action.c b/common/action.c index d0c9ddb0..38c5933e 100644 --- a/common/action.c +++ b/common/action.c @@ -289,6 +289,7 @@ void action_exec(keyevent_t event) static action_t get_action(key_t key) { action_t action; + action.code = ACTION_NO; /* layer stack */ for (layer_item_t i = layer_stack[top_layer]; i.used; i = layer_stack[i.next]) { @@ -301,14 +302,18 @@ static action_t get_action(key_t key) debug("layer_stack: through. "); debug_dec(i.layer); debug("\n"); } - /* current layer */ - action = action_for_key(current_layer, key); + /* current layer: 0 means default layer */ + if (current_layer) { + action = action_for_key(current_layer, key); + if (action.code != ACTION_TRANSPARENT) { + debug("current layer: used. "); debug_dec(current_layer); debug("\n"); + return action; + } + } /* default layer */ - if (action.code == ACTION_TRANSPARENT) { - debug("TRNASPARENT: "); debug_hex16(action.code); debug("\n"); - action = action_for_key(default_layer, key); - } + debug("default layer: used. \n"); + action = action_for_key(default_layer, key); return action; } @@ -469,7 +474,7 @@ static void process_action(keyrecord_t *record) } else { // NOTE: This is needed by legacy keymap support - layer_switch(default_layer); + layer_switch(0); } break; case LAYER_ON_PRESS: @@ -500,18 +505,18 @@ static void process_action(keyrecord_t *record) case LAYER_SET_DEFAULT_ON_PRESS: if (event.pressed) { default_layer = action.layer.val; - layer_switch(default_layer); + layer_switch(0); } break; case LAYER_SET_DEFAULT_ON_RELEASE: if (!event.pressed) { default_layer = action.layer.val; - layer_switch(default_layer); + layer_switch(0); } break; case LAYER_SET_DEFAULT_ON_BOTH: default_layer = action.layer.val; - layer_switch(default_layer); + layer_switch(0); break; default: /* tap key */ @@ -530,7 +535,7 @@ static void process_action(keyrecord_t *record) } else { // NOTE: This is needed by legacy keymap support debug("LAYER_SET: No tap: return to default layer(on release)\n"); - layer_switch(default_layer); + layer_switch(0); } } break; @@ -573,19 +578,19 @@ static void process_action(keyrecord_t *record) break; case LAYER_SET_DEFAULT_ON_PRESS: if (event.pressed) { - default_layer = current_layer ^ action.layer.val; - layer_switch(default_layer); + default_layer = default_layer ^ action.layer.val; + layer_switch(0); } break; case LAYER_SET_DEFAULT_ON_RELEASE: if (!event.pressed) { - default_layer = current_layer ^ action.layer.val; - layer_switch(default_layer); + default_layer = default_layer ^ action.layer.val; + layer_switch(0); } break; case LAYER_SET_DEFAULT_ON_BOTH: - default_layer = current_layer ^ action.layer.val; - layer_switch(default_layer); + default_layer = default_layer ^ action.layer.val; + layer_switch(0); break; default: // tap key diff --git a/common/command.c b/common/command.c index 7bb2a23f..4c874b10 100644 --- a/common/command.c +++ b/common/command.c @@ -261,8 +261,9 @@ static bool command_common(uint8_t code) #endif break; #endif + case KC_ESC: + case KC_GRV: case KC_0: - case KC_F10: clear_keyboard(); switch_layer(0); break; @@ -270,7 +271,7 @@ static bool command_common(uint8_t code) clear_keyboard(); switch_layer((code - KC_1) + 1); break; - case KC_F1 ... KC_F9: + case KC_F1 ... KC_F12: clear_keyboard(); switch_layer((code - KC_F1) + 1); break; @@ -545,7 +546,7 @@ static void switch_layer(uint8_t layer) { print_val_hex8(current_layer); print_val_hex8(default_layer); - current_layer = layer; default_layer = layer; + current_layer = 0; print("switch to "); print_val_hex8(layer); } From 510e5a2ee462764ded9644230f0223756cbed841 Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 15 Feb 2013 13:45:59 +0900 Subject: [PATCH 03/25] Fix Make dependency file names --- rules.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules.mk b/rules.mk index 2e4fce51..7a40d1de 100644 --- a/rules.mk +++ b/rules.mk @@ -340,7 +340,8 @@ LST = $(patsubst %.c,$(OBJDIR)/%.lst,$(patsubst %.cpp,$(OBJDIR)/%.lst,$(patsubst # Compiler flags to generate dependency files. -GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d +#GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d +GENDEPFLAGS = -MMD -MP -MF .dep/$(subst /,_,$@).d # Combine all necessary flags and optional flags. From 064a11528f24e36c5dbac4678db1ed0bc32b87c0 Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 15 Feb 2013 13:47:41 +0900 Subject: [PATCH 04/25] Add layer_stack files taking apart from action.c --- common.mk | 1 + common/action.c | 127 ++++++++----------------------------------- common/layer_stack.c | 100 ++++++++++++++++++++++++++++++++++ common/layer_stack.h | 44 +++++++++++++++ 4 files changed, 167 insertions(+), 105 deletions(-) create mode 100644 common/layer_stack.c create mode 100644 common/layer_stack.h diff --git a/common.mk b/common.mk index 86518f03..de22f2c8 100644 --- a/common.mk +++ b/common.mk @@ -3,6 +3,7 @@ SRC += $(COMMON_DIR)/host.c \ $(COMMON_DIR)/keyboard.c \ $(COMMON_DIR)/action.c \ $(COMMON_DIR)/action_macro.c \ + $(COMMON_DIR)/layer_stack.c \ $(COMMON_DIR)/keymap.c \ $(COMMON_DIR)/command.c \ $(COMMON_DIR)/timer.c \ diff --git a/common/action.c b/common/action.c index 38c5933e..9a8d7559 100644 --- a/common/action.c +++ b/common/action.c @@ -24,6 +24,7 @@ along with this program. If not, see . #include "util.h" #include "debug.h" #include "action.h" +#include "layer_stack.h" /* default layer indicates base layer */ @@ -163,85 +164,6 @@ static void oneshot_toggle(void) } -/* - * Layer stack - */ -#define LAYER_STACK_SIZE 8 -typedef struct { - uint8_t layer:4; - uint8_t next:3; - bool used; -} layer_item_t; - -static uint8_t top_layer = 0; -// [0] is sentinel and not used. [0] is null item. -static layer_item_t layer_stack[LAYER_STACK_SIZE] = {}; - -static bool layer_push(uint8_t layer) -{ - for (uint8_t i = 1; i < LAYER_STACK_SIZE; i++) { - if (!layer_stack[i].used) { - layer_stack[i] = (layer_item_t){ .layer = layer, - .next = top_layer, - .used = true }; - top_layer = i; - return true; - } - } - return false; -} -static bool layer_pop(void) -{ - if (layer_stack[top_layer].used) { - uint8_t popped = top_layer; - top_layer = layer_stack[popped].next; - layer_stack[popped] = (layer_item_t){}; - return true; - } - return false; -} -static bool layer_remove(uint8_t layer) -{ - if (layer_stack[top_layer].used && layer_stack[top_layer].layer == layer) { - layer_pop(); - debug("layer_remove: top_layer\n"); - return true; - } - - for (uint8_t i = top_layer; layer_stack[i].used; i = layer_stack[i].next) { - debug("layer_remove: ["); debug_dec(i); debug("]"); - debug_dec(layer_stack[i].layer); debug("\n"); - uint8_t removed = layer_stack[i].next; - if (layer_stack[removed].used && layer_stack[removed].layer == layer) { - layer_stack[i].next = layer_stack[removed].next; - layer_stack[removed] = (layer_item_t){}; - debug("layer_remove: removed.\n"); - return true; - } - } - return false; -} -static bool layer_remove_then_push(uint8_t layer) -{ - layer_remove(layer); - return layer_push(layer); -} -static bool layer_remove_or_push(uint8_t layer) -{ - return (layer_remove(layer)) || layer_push(layer); -} -static void debug_layer_stack(void) -{ - debug("layer_stack: "); - layer_item_t item = layer_stack[top_layer]; - while (item.used) { - debug_dec(item.layer); - debug("["); debug_dec(item.next); debug("]"); - item = layer_stack[item.next]; - } - debug("\n"); -} - void action_exec(keyevent_t event) { @@ -292,14 +214,9 @@ static action_t get_action(key_t key) action.code = ACTION_NO; /* layer stack */ - for (layer_item_t i = layer_stack[top_layer]; i.used; i = layer_stack[i.next]) { - action = action_for_key(i.layer, key); - if (action.code != ACTION_TRANSPARENT) { - debug_layer_stack(); - debug("layer_stack: used. "); debug_dec(i.layer); debug("\n"); - return action; - } - debug("layer_stack: through. "); debug_dec(i.layer); debug("\n"); + action = layer_stack_get_action(key); + if (action.code != ACTION_TRANSPARENT) { + return action; } /* current layer: 0 means default layer */ @@ -618,41 +535,41 @@ static void process_action(keyrecord_t *record) switch (action.layer.code) { case LAYER_MOMENTARY: /* momentary */ if (event.pressed) { - layer_remove_then_push(action.layer.val); - debug_layer_stack(); + layer_stack_remove_then_push(action.layer.val); + layer_stack_debug(); } else { - layer_remove(action.layer.val); - debug_layer_stack(); + layer_stack_remove(action.layer.val); + layer_stack_debug(); } break; case LAYER_ON_PRESS: if (event.pressed) { - layer_remove_or_push(action.layer.val); - debug_layer_stack(); + layer_stack_remove_or_push(action.layer.val); + layer_stack_debug(); } break; case LAYER_ON_RELEASE: if (!event.pressed) { - layer_remove_or_push(action.layer.val); - debug_layer_stack(); + layer_stack_remove_or_push(action.layer.val); + layer_stack_debug(); } break; case LAYER_ON_BOTH: - layer_remove_or_push(action.layer.val); - debug_layer_stack(); + layer_stack_remove_or_push(action.layer.val); + layer_stack_debug(); break; case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ if (event.pressed) { if (tap_count < TAPPING_TOGGLE) { debug("LAYER_STACK: tap toggle(press).\n"); - layer_remove_or_push(action.layer.val); - debug_layer_stack(); + layer_stack_remove_or_push(action.layer.val); + layer_stack_debug(); } } else { if (tap_count <= TAPPING_TOGGLE) { debug("LAYER_STACK: tap toggle(release).\n"); - layer_remove_or_push(action.layer.val); - debug_layer_stack(); + layer_stack_remove_or_push(action.layer.val); + layer_stack_debug(); } } break; @@ -664,8 +581,8 @@ static void process_action(keyrecord_t *record) register_code(action.layer.code); } else { debug("LAYER_STACK: No tap: layer_stack(on press)\n"); - layer_remove_or_push(action.layer.val); - debug_layer_stack(); + layer_stack_remove_or_push(action.layer.val); + layer_stack_debug(); } } else { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { @@ -673,8 +590,8 @@ static void process_action(keyrecord_t *record) unregister_code(action.layer.code); } else { debug("LAYER_STACK: No tap: layer_stack(on release)\n"); - layer_remove_or_push(action.layer.val); - debug_layer_stack(); + layer_stack_remove_or_push(action.layer.val); + layer_stack_debug(); } } break; diff --git a/common/layer_stack.c b/common/layer_stack.c new file mode 100644 index 00000000..07c84870 --- /dev/null +++ b/common/layer_stack.c @@ -0,0 +1,100 @@ +#include +#include "keyboard.h" +#include "layer_stack.h" +#include "debug.h" + + +static uint8_t top_layer = 0; + +/* [0] always works as sentinel and not used for store.*/ +static layer_item_t layer_stack[LAYER_STACK_SIZE] = {}; + +bool layer_stack_push(uint8_t layer) +{ + for (uint8_t i = 1; i < LAYER_STACK_SIZE; i++) { + if (!layer_stack[i].used) { + layer_stack[i] = (layer_item_t){ .layer = layer, + .next = top_layer, + .used = true }; + top_layer = i; + return true; + } + } + return false; +} + +bool layer_stack_pop(void) +{ + if (layer_stack[top_layer].used) { + uint8_t popped = top_layer; + top_layer = layer_stack[popped].next; + layer_stack[popped] = (layer_item_t){}; + return true; + } + return false; +} + +bool layer_stack_remove(uint8_t layer) +{ + if (layer_stack[top_layer].used && layer_stack[top_layer].layer == layer) { + layer_stack_pop(); + debug("layer_stack_remove: top_layer\n"); + return true; + } + + for (uint8_t i = top_layer; layer_stack[i].used; i = layer_stack[i].next) { + debug("layer_stack_remove: ["); debug_dec(i); debug("]"); + debug_dec(layer_stack[i].layer); debug("\n"); + uint8_t removed = layer_stack[i].next; + if (layer_stack[removed].used && layer_stack[removed].layer == layer) { + layer_stack[i].next = layer_stack[removed].next; + layer_stack[removed] = (layer_item_t){}; + debug("layer_stack_remove: removed.\n"); + return true; + } + } + return false; +} + +bool layer_stack_remove_then_push(uint8_t layer) +{ + layer_stack_remove(layer); + return layer_stack_push(layer); +} + +bool layer_stack_remove_or_push(uint8_t layer) +{ + return (layer_stack_remove(layer)) || layer_stack_push(layer); +} + +void layer_stack_debug(void) +{ + debug("layer_stack: "); + layer_item_t item = layer_stack[top_layer]; + while (item.used) { + debug_dec(item.layer); + debug("["); debug_dec(item.next); debug("]"); + item = layer_stack[item.next]; + } + debug("\n"); +} + + + +action_t layer_stack_get_action(key_t key) +{ + action_t action; + action.code = ACTION_TRANSPARENT; + + /* layer stack */ + for (layer_item_t i = layer_stack[top_layer]; i.used; i = layer_stack[i.next]) { + action = action_for_key(i.layer, key); + if (action.code != ACTION_TRANSPARENT) { + layer_stack_debug(); + debug("layer_stack: used. "); debug_dec(i.layer); debug("\n"); + return action; + } + debug("layer_stack: through. "); debug_dec(i.layer); debug("\n"); + } + return action; +} diff --git a/common/layer_stack.h b/common/layer_stack.h new file mode 100644 index 00000000..c88eaffc --- /dev/null +++ b/common/layer_stack.h @@ -0,0 +1,44 @@ +/* +Copyright 2013 Jun Wako + +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 . +*/ +#ifndef LAYER_STACK_H +#define LAYER_STACK_H + +#include +#include "action.h" + + +/* + * Layer stack + */ +#define LAYER_STACK_SIZE 8 +typedef struct { + uint8_t layer:4; + uint8_t next:3; + bool used; +} layer_item_t; + + +bool layer_stack_push(uint8_t layer); +bool layer_stack_pop(void); +bool layer_stack_remove(uint8_t layer); +bool layer_stack_remove_then_push(uint8_t layer); +bool layer_stack_remove_or_push(uint8_t layer); +void layer_stack_debug(void); +action_t layer_stack_get_action(key_t key); + +#endif + From a15de8f9a931e905d1a15ba269cd6997486a632b Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 15 Feb 2013 15:27:19 +0900 Subject: [PATCH 05/25] Fix switch_default_layer command --- common/command.c | 22 ++++++++++++---------- common/layer_stack.c | 18 +++++++++++++----- common/layer_stack.h | 1 + 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/common/command.c b/common/command.c index 4c874b10..c5b9f043 100644 --- a/common/command.c +++ b/common/command.c @@ -27,6 +27,8 @@ along with this program. If not, see . #include "keyboard.h" #include "bootloader.h" #include "command.h" +#include "layer_stack.h" + #ifdef MOUSEKEY_ENABLE #include "mousekey.h" #endif @@ -53,7 +55,7 @@ static void mousekey_console_help(void); #endif static uint8_t numkey2num(uint8_t code); -static void switch_layer(uint8_t layer); +static void switch_default_layer(uint8_t layer); typedef enum { ONESHOT, CONSOLE, MOUSEKEY } cmdstate_t; @@ -264,16 +266,13 @@ static bool command_common(uint8_t code) case KC_ESC: case KC_GRV: case KC_0: - clear_keyboard(); - switch_layer(0); + switch_default_layer(0); break; case KC_1 ... KC_9: - clear_keyboard(); - switch_layer((code - KC_1) + 1); + switch_default_layer((code - KC_1) + 1); break; case KC_F1 ... KC_F12: - clear_keyboard(); - switch_layer((code - KC_F1) + 1); + switch_default_layer((code - KC_F1) + 1); break; default: print("?"); @@ -542,11 +541,14 @@ static uint8_t numkey2num(uint8_t code) return 0; } -static void switch_layer(uint8_t layer) +static void switch_default_layer(uint8_t layer) { print_val_hex8(current_layer); print_val_hex8(default_layer); - default_layer = layer; - current_layer = 0; print("switch to "); print_val_hex8(layer); + + default_layer = layer; + current_layer = 0; /* 0 means default_layer */ + layer_stack_clear(); + clear_keyboard(); } diff --git a/common/layer_stack.c b/common/layer_stack.c index 07c84870..0076bf77 100644 --- a/common/layer_stack.c +++ b/common/layer_stack.c @@ -9,13 +9,23 @@ static uint8_t top_layer = 0; /* [0] always works as sentinel and not used for store.*/ static layer_item_t layer_stack[LAYER_STACK_SIZE] = {}; + +void layer_stack_clear(void) +{ + for (uint8_t i = 0; i < LAYER_STACK_SIZE; i++) { + layer_stack[i] = (layer_item_t){ .layer = 0, + .next = 0, + .used = false }; + } +} + bool layer_stack_push(uint8_t layer) { for (uint8_t i = 1; i < LAYER_STACK_SIZE; i++) { if (!layer_stack[i].used) { layer_stack[i] = (layer_item_t){ .layer = layer, - .next = top_layer, - .used = true }; + .next = top_layer, + .used = true }; top_layer = i; return true; } @@ -73,14 +83,12 @@ void layer_stack_debug(void) layer_item_t item = layer_stack[top_layer]; while (item.used) { debug_dec(item.layer); - debug("["); debug_dec(item.next); debug("]"); + debug("["); debug_dec(item.next); debug("] "); item = layer_stack[item.next]; } debug("\n"); } - - action_t layer_stack_get_action(key_t key) { action_t action; diff --git a/common/layer_stack.h b/common/layer_stack.h index c88eaffc..25bf37a5 100644 --- a/common/layer_stack.h +++ b/common/layer_stack.h @@ -32,6 +32,7 @@ typedef struct { } layer_item_t; +void layer_stack_clear(void); bool layer_stack_push(uint8_t layer); bool layer_stack_pop(void); bool layer_stack_remove(uint8_t layer); From 4039537bceba27cc834302dcf8a936cbb73aa10e Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 15 Feb 2013 18:48:36 +0900 Subject: [PATCH 06/25] Replace layer_stack with layer_switch --- common.mk | 2 +- common/action.c | 50 +++++------ common/action.h | 39 ++++---- common/command.c | 4 +- common/layer_stack.c | 108 ----------------------- common/layer_switch.c | 68 ++++++++++++++ common/{layer_stack.h => layer_switch.h} | 35 +++----- 7 files changed, 124 insertions(+), 182 deletions(-) delete mode 100644 common/layer_stack.c create mode 100644 common/layer_switch.c rename common/{layer_stack.h => layer_switch.h} (59%) diff --git a/common.mk b/common.mk index de22f2c8..5fb76e73 100644 --- a/common.mk +++ b/common.mk @@ -3,7 +3,7 @@ SRC += $(COMMON_DIR)/host.c \ $(COMMON_DIR)/keyboard.c \ $(COMMON_DIR)/action.c \ $(COMMON_DIR)/action_macro.c \ - $(COMMON_DIR)/layer_stack.c \ + $(COMMON_DIR)/layer_switch.c \ $(COMMON_DIR)/keymap.c \ $(COMMON_DIR)/command.c \ $(COMMON_DIR)/timer.c \ diff --git a/common/action.c b/common/action.c index 9a8d7559..4f0a5f90 100644 --- a/common/action.c +++ b/common/action.c @@ -24,7 +24,7 @@ along with this program. If not, see . #include "util.h" #include "debug.h" #include "action.h" -#include "layer_stack.h" +#include "layer_switch.h" /* default layer indicates base layer */ @@ -213,8 +213,8 @@ static action_t get_action(key_t key) action_t action; action.code = ACTION_NO; - /* layer stack */ - action = layer_stack_get_action(key); + /* layer_switch */ + action = layer_switch_get_action(key); if (action.code != ACTION_TRANSPARENT) { return action; } @@ -531,45 +531,38 @@ static void process_action(keyrecord_t *record) break; } break; - case ACT_LAYER_STACK: + case ACT_LAYER_SWITCH: switch (action.layer.code) { case LAYER_MOMENTARY: /* momentary */ if (event.pressed) { - layer_stack_remove_then_push(action.layer.val); - layer_stack_debug(); + layer_switch_on(action.layer.val); } else { - layer_stack_remove(action.layer.val); - layer_stack_debug(); + layer_switch_off(action.layer.val); } break; case LAYER_ON_PRESS: if (event.pressed) { - layer_stack_remove_or_push(action.layer.val); - layer_stack_debug(); + layer_switch_inv(action.layer.val); } break; case LAYER_ON_RELEASE: if (!event.pressed) { - layer_stack_remove_or_push(action.layer.val); - layer_stack_debug(); + layer_switch_inv(action.layer.val); } break; case LAYER_ON_BOTH: - layer_stack_remove_or_push(action.layer.val); - layer_stack_debug(); + layer_switch_inv(action.layer.val); break; case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ if (event.pressed) { if (tap_count < TAPPING_TOGGLE) { - debug("LAYER_STACK: tap toggle(press).\n"); - layer_stack_remove_or_push(action.layer.val); - layer_stack_debug(); + debug("LAYER_SWITCH: tap toggle(press).\n"); + layer_switch_inv(action.layer.val); } } else { if (tap_count <= TAPPING_TOGGLE) { - debug("LAYER_STACK: tap toggle(release).\n"); - layer_stack_remove_or_push(action.layer.val); - layer_stack_debug(); + debug("LAYER_SWITCH: tap toggle(release).\n"); + layer_switch_inv(action.layer.val); } } break; @@ -577,21 +570,19 @@ static void process_action(keyrecord_t *record) // tap key if (event.pressed) { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { - debug("LAYER_STACK: Tap: register_code\n"); + debug("LAYER_SWITCH: Tap: register_code\n"); register_code(action.layer.code); } else { - debug("LAYER_STACK: No tap: layer_stack(on press)\n"); - layer_stack_remove_or_push(action.layer.val); - layer_stack_debug(); + debug("LAYER_SWITCH: No tap: layer_switch(on press)\n"); + layer_switch_inv(action.layer.val); } } else { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { - debug("LAYER_STACK: Tap: unregister_code\n"); + debug("LAYER_SWITCH: Tap: unregister_code\n"); unregister_code(action.layer.code); } else { - debug("LAYER_STACK: No tap: layer_stack(on release)\n"); - layer_stack_remove_or_push(action.layer.val); - layer_stack_debug(); + debug("LAYER_SWITCH: No tap: layer_switch(on release)\n"); + layer_switch_inv(action.layer.val); } } break; @@ -898,6 +889,7 @@ bool sending_anykey(void) host_last_sysytem_report() || host_last_consumer_report()); } +// TODO: rename or reinpl with new layer_switch.c void layer_switch(uint8_t new_layer) { if (current_layer != new_layer) { @@ -966,7 +958,7 @@ static void debug_action(action_t action) case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break; case ACT_LAYER: debug("ACT_LAYER"); break; case ACT_LAYER_BIT: debug("ACT_LAYER_BIT"); break; - case ACT_LAYER_STACK: debug("ACT_LAYER_STACK"); break; + case ACT_LAYER_SWITCH: debug("ACT_LAYER_SWITCH"); break; case ACT_MACRO: debug("ACT_MACRO"); break; case ACT_COMMAND: debug("ACT_COMMAND"); break; case ACT_FUNCTION: debug("ACT_FUNCTION"); break; diff --git a/common/action.h b/common/action.h index 96b8ba2e..1d00e02d 100644 --- a/common/action.h +++ b/common/action.h @@ -163,9 +163,6 @@ bool waiting_buffer_has_anykey_pressed(void); * Layer Actions * ------------- * ACT_LAYER(1000): Set layer - * ACT_LAYER_BIT(1001): Bit-op layer - * ACT_LAYER_STACK: Layer stack - * * 1000|LLLL|0000 0000 set current layer on press and return to default on release(momentary) * 1000|LLLL|0000 0001 set current layer on press * 1000|LLLL|0000 0010 set current layer on release @@ -175,6 +172,7 @@ bool waiting_buffer_has_anykey_pressed(void); * 1000|DDDD|1111 1111 set default layer on press * L: 0 means default layer * + * ACT_LAYER_BIT(1001): Bit-op layer * 1001|BBBB|0000 0000 bit-on current layer on press and bit-off on release(momentary) * 1001|BBBB|0000 0001 bit-xor current layer on press * 1001|BBBB|0000 0010 bit-xor current layer on release @@ -183,12 +181,13 @@ bool waiting_buffer_has_anykey_pressed(void); * 1001|BBBB|1111 0000 bit-xor current layer on hold and toggle on several taps * 1001|BBBB|1111 1111 bit-xor default layer on both * - * 1011|LLLL|0000 0000 push on press and remove on release(momentary) - * 1011|LLLL|0000 0001 push or remove on press - * 1011|LLLL|0000 0010 push or remove on release - * 1011|LLLL|0000 0011 push or remove on both - * 1011|LLLL| keycode push or remove on hold and send key on tap - * 1011|LLLL|1111 0000 push or remove on hold and toggle on several taps + * ACT_LAYER_SWITCH: Switch + * 1011|LLLL|0000 0000 On on press and Off on release(momentary) + * 1011|LLLL|0000 0001 Invert on press + * 1011|LLLL|0000 0010 Invert on release + * 1011|LLLL|0000 0011 Invert on both + * 1011|LLLL| keycode Invert on hold and send key on tap + * 1011|LLLL|1111 0000 Invert on hold and toggle on several taps * 1011|LLLL|1111 1111 (not used) * * @@ -219,7 +218,7 @@ enum action_kind_id { ACT_LAYER = 0b1000, ACT_LAYER_BIT = 0b1001, - ACT_LAYER_STACK = 0b1011, + ACT_LAYER_SWITCH = 0b1011, ACT_MACRO = 0b1100, ACT_COMMAND = 0b1110, @@ -233,7 +232,7 @@ enum action_kind_id { #define ACTION(kind, param) ((kind)<<12 | (param)) #define MODS4(mods) (((mods)>>4 | (mods)) & 0x0F) -/* +/* * Key */ #define ACTION_KEY(key) ACTION(ACT_LMODS, key) @@ -316,17 +315,17 @@ enum layer_codes { #define ACTION_LAYER_BIT_TAP_TOGGLE(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_TAP_TOGGLE) #define ACTION_LAYER_BIT_TAP_KEY(bits, key) ACTION(ACT_LAYER_BIT, (bits)<<8 | (key)) /* - * Layer Stack + * Layer SWITCH */ /* momentary */ -#define ACTION_LAYER_STACK(layer) ACTION_LAYER_STACK_MOMENTARY(layer) -#define ACTION_LAYER_STACK_MOMENTARY(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_MOMENTARY) -#define ACTION_LAYER_STACK_TOGGLE(layer) ACTION_LAYER_STACK_R(layer) -#define ACTION_LAYER_STACK_P(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_ON_PRESS) -#define ACTION_LAYER_STACK_R(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_ON_RELEASE) -#define ACTION_LAYER_STACK_B(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_ON_BOTH) -#define ACTION_LAYER_STACK_TAP_TOGGLE(layer) ACTION(ACT_LAYER_STACK, (layer)<<8 | LAYER_TAP_TOGGLE) -#define ACTION_LAYER_STACK_TAP_KEY(layer, key) ACTION(ACT_LAYER_STACK, (layer)<<8 | (key)) +#define ACTION_LAYER_SWITCH(layer) ACTION_LAYER_SWITCH_MOMENTARY(layer) +#define ACTION_LAYER_SWITCH_MOMENTARY(layer) ACTION(ACT_LAYER_SWITCH, (layer)<<8 | LAYER_MOMENTARY) +#define ACTION_LAYER_SWITCH_TOGGLE(layer) ACTION_LAYER_SWITCH_R(layer) +#define ACTION_LAYER_SWITCH_P(layer) ACTION(ACT_LAYER_SWITCH, (layer)<<8 | LAYER_ON_PRESS) +#define ACTION_LAYER_SWITCH_R(layer) ACTION(ACT_LAYER_SWITCH, (layer)<<8 | LAYER_ON_RELEASE) +#define ACTION_LAYER_SWITCH_B(layer) ACTION(ACT_LAYER_SWITCH, (layer)<<8 | LAYER_ON_BOTH) +#define ACTION_LAYER_SWITCH_TAP_TOGGLE(layer) ACTION(ACT_LAYER_SWITCH, (layer)<<8 | LAYER_TAP_TOGGLE) +#define ACTION_LAYER_SWITCH_TAP_KEY(layer, key) ACTION(ACT_LAYER_SWITCH, (layer)<<8 | (key)) /* diff --git a/common/command.c b/common/command.c index c5b9f043..82f647c8 100644 --- a/common/command.c +++ b/common/command.c @@ -26,8 +26,8 @@ along with this program. If not, see . #include "timer.h" #include "keyboard.h" #include "bootloader.h" +#include "layer_switch.h" #include "command.h" -#include "layer_stack.h" #ifdef MOUSEKEY_ENABLE #include "mousekey.h" @@ -549,6 +549,6 @@ static void switch_default_layer(uint8_t layer) default_layer = layer; current_layer = 0; /* 0 means default_layer */ - layer_stack_clear(); + layer_switch_clear(); clear_keyboard(); } diff --git a/common/layer_stack.c b/common/layer_stack.c deleted file mode 100644 index 0076bf77..00000000 --- a/common/layer_stack.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include "keyboard.h" -#include "layer_stack.h" -#include "debug.h" - - -static uint8_t top_layer = 0; - -/* [0] always works as sentinel and not used for store.*/ -static layer_item_t layer_stack[LAYER_STACK_SIZE] = {}; - - -void layer_stack_clear(void) -{ - for (uint8_t i = 0; i < LAYER_STACK_SIZE; i++) { - layer_stack[i] = (layer_item_t){ .layer = 0, - .next = 0, - .used = false }; - } -} - -bool layer_stack_push(uint8_t layer) -{ - for (uint8_t i = 1; i < LAYER_STACK_SIZE; i++) { - if (!layer_stack[i].used) { - layer_stack[i] = (layer_item_t){ .layer = layer, - .next = top_layer, - .used = true }; - top_layer = i; - return true; - } - } - return false; -} - -bool layer_stack_pop(void) -{ - if (layer_stack[top_layer].used) { - uint8_t popped = top_layer; - top_layer = layer_stack[popped].next; - layer_stack[popped] = (layer_item_t){}; - return true; - } - return false; -} - -bool layer_stack_remove(uint8_t layer) -{ - if (layer_stack[top_layer].used && layer_stack[top_layer].layer == layer) { - layer_stack_pop(); - debug("layer_stack_remove: top_layer\n"); - return true; - } - - for (uint8_t i = top_layer; layer_stack[i].used; i = layer_stack[i].next) { - debug("layer_stack_remove: ["); debug_dec(i); debug("]"); - debug_dec(layer_stack[i].layer); debug("\n"); - uint8_t removed = layer_stack[i].next; - if (layer_stack[removed].used && layer_stack[removed].layer == layer) { - layer_stack[i].next = layer_stack[removed].next; - layer_stack[removed] = (layer_item_t){}; - debug("layer_stack_remove: removed.\n"); - return true; - } - } - return false; -} - -bool layer_stack_remove_then_push(uint8_t layer) -{ - layer_stack_remove(layer); - return layer_stack_push(layer); -} - -bool layer_stack_remove_or_push(uint8_t layer) -{ - return (layer_stack_remove(layer)) || layer_stack_push(layer); -} - -void layer_stack_debug(void) -{ - debug("layer_stack: "); - layer_item_t item = layer_stack[top_layer]; - while (item.used) { - debug_dec(item.layer); - debug("["); debug_dec(item.next); debug("] "); - item = layer_stack[item.next]; - } - debug("\n"); -} - -action_t layer_stack_get_action(key_t key) -{ - action_t action; - action.code = ACTION_TRANSPARENT; - - /* layer stack */ - for (layer_item_t i = layer_stack[top_layer]; i.used; i = layer_stack[i.next]) { - action = action_for_key(i.layer, key); - if (action.code != ACTION_TRANSPARENT) { - layer_stack_debug(); - debug("layer_stack: used. "); debug_dec(i.layer); debug("\n"); - return action; - } - debug("layer_stack: through. "); debug_dec(i.layer); debug("\n"); - } - return action; -} diff --git a/common/layer_switch.c b/common/layer_switch.c new file mode 100644 index 00000000..9bc804e6 --- /dev/null +++ b/common/layer_switch.c @@ -0,0 +1,68 @@ +#include +#include "keyboard.h" +#include "action.h" +#include "debug.h" +#include "layer_switch.h" + + +uint16_t layer_switch_stat = 0; + + +uint16_t layer_switch_stat_get(void) +{ + return layer_switch_stat; +} + +void layer_switch_stat_set(uint16_t stat) +{ + layer_switch_stat = stat; + layer_switch_debug(); +} + +void layer_switch_clear(void) +{ + layer_switch_stat = 0; + layer_switch_debug(); +} + +void layer_switch_on(uint8_t layer) +{ + layer_switch_stat |= (1<= 0; i--) { + if (layer_switch_stat & (1<. */ -#ifndef LAYER_STACK_H -#define LAYER_STACK_H +#ifndef LAYER_SWITCH_H +#define LAYER_SWITCH_H #include +#include "keyboard.h" #include "action.h" +uint16_t layer_switch_stat; -/* - * Layer stack - */ -#define LAYER_STACK_SIZE 8 -typedef struct { - uint8_t layer:4; - uint8_t next:3; - bool used; -} layer_item_t; - - -void layer_stack_clear(void); -bool layer_stack_push(uint8_t layer); -bool layer_stack_pop(void); -bool layer_stack_remove(uint8_t layer); -bool layer_stack_remove_then_push(uint8_t layer); -bool layer_stack_remove_or_push(uint8_t layer); -void layer_stack_debug(void); -action_t layer_stack_get_action(key_t key); +uint16_t layer_switch_stat_get(void); +void layer_switch_stat_set(uint16_t stat); +void layer_switch_clear(void); +void layer_switch_on(uint8_t layer); +void layer_switch_off(uint8_t layer); +/* invert state */ +void layer_switch_inv(uint8_t layer); +void layer_switch_debug(void); +action_t layer_switch_get_action(key_t key); #endif - From 58a0845d6ad4c26cf7fd8a828c9fd5559ea31be2 Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 16 Feb 2013 04:05:58 +0900 Subject: [PATCH 07/25] Rewrite layer action with layer_switch --- common/action.c | 107 ++++++++++++++++-------------------------- common/action.h | 35 ++++++-------- common/command.c | 7 +-- common/layer_switch.c | 66 ++++++++++++++++++++------ common/layer_switch.h | 33 +++++++++++-- common/util.c | 11 +++++ common/util.h | 1 + 7 files changed, 148 insertions(+), 112 deletions(-) diff --git a/common/action.c b/common/action.c index 4f0a5f90..246fd99d 100644 --- a/common/action.c +++ b/common/action.c @@ -27,12 +27,6 @@ along with this program. If not, see . #include "layer_switch.h" -/* default layer indicates base layer */ -uint8_t default_layer = 0; -/* current layer indicates active layer at this time */ -uint8_t current_layer = 0; - - static void process_action(keyrecord_t *record); static bool process_tapping(keyrecord_t *record); static void waiting_buffer_scan_tap(void); @@ -219,17 +213,8 @@ static action_t get_action(key_t key) return action; } - /* current layer: 0 means default layer */ - if (current_layer) { - action = action_for_key(current_layer, key); - if (action.code != ACTION_TRANSPARENT) { - debug("current layer: used. "); debug_dec(current_layer); debug("\n"); - return action; - } - } - /* default layer */ - debug("default layer: used. \n"); + //debug("get_aciton: default layer: "); debug_dec(default_layer); debug("\n"); action = action_for_key(default_layer, key); return action; } @@ -242,7 +227,8 @@ static void process_action(keyrecord_t *record) if (IS_NOEVENT(event)) { return; } action_t action = get_action(event.key); - debug("ACTION: "); debug_action(action); debug("\n"); + debug("ACTION: "); debug_action(action); debug(" "); + layer_switch_debug(); debug("["); debug_dec(default_layer); debug("]\n"); switch (action.kind.id) { /* Key and Mods */ @@ -383,57 +369,57 @@ static void process_action(keyrecord_t *record) break; /* Layer key */ - case ACT_LAYER: + case ACT_LAYER_SET: switch (action.layer.code) { case LAYER_MOMENTARY: /* momentary */ if (event.pressed) { - layer_switch(action.layer.val); + layer_switch_move(action.layer.val); } else { // NOTE: This is needed by legacy keymap support - layer_switch(0); + layer_switch_move(0); } break; case LAYER_ON_PRESS: if (event.pressed) { - layer_switch(action.layer.val); + layer_switch_move(action.layer.val); } break; case LAYER_ON_RELEASE: if (!event.pressed) { - layer_switch(action.layer.val); + layer_switch_move(action.layer.val); } break; case LAYER_ON_BOTH: - layer_switch(action.layer.val); + layer_switch_move(action.layer.val); break; case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ if (event.pressed) { if (tap_count < TAPPING_TOGGLE) { - layer_switch(action.layer.val); + layer_switch_move(action.layer.val); } } else { if (tap_count >= TAPPING_TOGGLE) { debug("LAYER_PRESSED: tap toggle.\n"); - layer_switch(action.layer.val); + layer_switch_move(action.layer.val); } } break; case LAYER_SET_DEFAULT_ON_PRESS: if (event.pressed) { default_layer = action.layer.val; - layer_switch(0); + layer_switch_move(0); } break; case LAYER_SET_DEFAULT_ON_RELEASE: if (!event.pressed) { default_layer = action.layer.val; - layer_switch(0); + layer_switch_move(0); } break; case LAYER_SET_DEFAULT_ON_BOTH: default_layer = action.layer.val; - layer_switch(0); + layer_switch_move(0); break; default: /* tap key */ @@ -443,7 +429,7 @@ static void process_action(keyrecord_t *record) register_code(action.layer.code); } else { debug("LAYER_SET: No tap: layer_set(on press)\n"); - layer_switch(action.layer.val); + layer_switch_move(action.layer.val); } } else { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { @@ -452,7 +438,7 @@ static void process_action(keyrecord_t *record) } else { // NOTE: This is needed by legacy keymap support debug("LAYER_SET: No tap: return to default layer(on release)\n"); - layer_switch(0); + layer_switch_move(0); } } break; @@ -462,52 +448,52 @@ static void process_action(keyrecord_t *record) switch (action.layer.code) { case LAYER_MOMENTARY: /* momentary */ if (event.pressed) { - layer_switch(current_layer | action.layer.val); + layer_switch_move(layer_switch_get_layer() | action.layer.val); } else { - layer_switch(current_layer & ~action.layer.val); + layer_switch_move(layer_switch_get_layer() & ~action.layer.val); } break; case LAYER_ON_PRESS: if (event.pressed) { - layer_switch(current_layer ^ action.layer.val); + layer_switch_move(layer_switch_get_layer() ^ action.layer.val); } break; case LAYER_ON_RELEASE: if (!event.pressed) { - layer_switch(current_layer ^ action.layer.val); + layer_switch_move(layer_switch_get_layer() ^ action.layer.val); } break; case LAYER_ON_BOTH: - layer_switch(current_layer ^ action.layer.val); + layer_switch_move(layer_switch_get_layer() ^ action.layer.val); break; case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ if (event.pressed) { if (tap_count < TAPPING_TOGGLE) { debug("LAYER_BIT: tap toggle(press).\n"); - layer_switch(current_layer ^ action.layer.val); + layer_switch_move(layer_switch_get_layer() ^ action.layer.val); } } else { if (tap_count <= TAPPING_TOGGLE) { debug("LAYER_BIT: tap toggle(release).\n"); - layer_switch(current_layer ^ action.layer.val); + layer_switch_move(layer_switch_get_layer() ^ action.layer.val); } } break; case LAYER_SET_DEFAULT_ON_PRESS: if (event.pressed) { default_layer = default_layer ^ action.layer.val; - layer_switch(0); + layer_switch_move(default_layer); } break; case LAYER_SET_DEFAULT_ON_RELEASE: if (!event.pressed) { default_layer = default_layer ^ action.layer.val; - layer_switch(0); + layer_switch_move(default_layer); } break; case LAYER_SET_DEFAULT_ON_BOTH: default_layer = default_layer ^ action.layer.val; - layer_switch(0); + layer_switch_move(default_layer); break; default: // tap key @@ -517,7 +503,7 @@ static void process_action(keyrecord_t *record) register_code(action.layer.code); } else { debug("LAYER_BIT: No tap: layer_bit(on press)\n"); - layer_switch(current_layer ^ action.layer.val); + layer_switch_move(layer_switch_get_layer() ^ action.layer.val); } } else { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { @@ -525,7 +511,7 @@ static void process_action(keyrecord_t *record) unregister_code(action.layer.code); } else { debug("LAYER_BIT: No tap: layer_bit(on release)\n"); - layer_switch(current_layer ^ action.layer.val); + layer_switch_move(layer_switch_get_layer() ^ action.layer.val); } } break; @@ -542,27 +528,27 @@ static void process_action(keyrecord_t *record) break; case LAYER_ON_PRESS: if (event.pressed) { - layer_switch_inv(action.layer.val); + layer_switch_invert(action.layer.val); } break; case LAYER_ON_RELEASE: if (!event.pressed) { - layer_switch_inv(action.layer.val); + layer_switch_invert(action.layer.val); } break; case LAYER_ON_BOTH: - layer_switch_inv(action.layer.val); + layer_switch_invert(action.layer.val); break; case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ if (event.pressed) { if (tap_count < TAPPING_TOGGLE) { debug("LAYER_SWITCH: tap toggle(press).\n"); - layer_switch_inv(action.layer.val); + layer_switch_invert(action.layer.val); } } else { if (tap_count <= TAPPING_TOGGLE) { debug("LAYER_SWITCH: tap toggle(release).\n"); - layer_switch_inv(action.layer.val); + layer_switch_invert(action.layer.val); } } break; @@ -573,16 +559,16 @@ static void process_action(keyrecord_t *record) debug("LAYER_SWITCH: Tap: register_code\n"); register_code(action.layer.code); } else { - debug("LAYER_SWITCH: No tap: layer_switch(on press)\n"); - layer_switch_inv(action.layer.val); + debug("LAYER_SWITCH: No tap: layer_switch on press\n"); + layer_switch_invert(action.layer.val); } } else { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { debug("LAYER_SWITCH: Tap: unregister_code\n"); unregister_code(action.layer.code); } else { - debug("LAYER_SWITCH: No tap: layer_switch(on release)\n"); - layer_switch_inv(action.layer.val); + debug("LAYER_SWITCH: No tap: layer_switch on release\n"); + layer_switch_invert(action.layer.val); } } break; @@ -889,19 +875,6 @@ bool sending_anykey(void) host_last_sysytem_report() || host_last_consumer_report()); } -// TODO: rename or reinpl with new layer_switch.c -void layer_switch(uint8_t new_layer) -{ - if (current_layer != new_layer) { - debug("Layer Switch: "); debug_hex(current_layer); - debug(" -> "); debug_hex(new_layer); debug("\n"); - - current_layer = new_layer; - clear_keyboard_but_mods(); // To avoid stuck keys - // NOTE: update mods with full scan of matrix? if modifier changes between layers - } -} - bool is_tap_key(key_t key) { action_t action = get_action(key); @@ -910,7 +883,7 @@ bool is_tap_key(key_t key) case ACT_LMODS_TAP: case ACT_RMODS_TAP: return true; - case ACT_LAYER: + case ACT_LAYER_SET: case ACT_LAYER_BIT: switch (action.layer.code) { case LAYER_MOMENTARY: @@ -956,9 +929,9 @@ static void debug_action(action_t action) case ACT_RMODS_TAP: debug("ACT_RMODS_TAP"); break; case ACT_USAGE: debug("ACT_USAGE"); break; case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break; - case ACT_LAYER: debug("ACT_LAYER"); break; + case ACT_LAYER_SET: debug("ACT_LAYER_SET"); break; case ACT_LAYER_BIT: debug("ACT_LAYER_BIT"); break; - case ACT_LAYER_SWITCH: debug("ACT_LAYER_SWITCH"); break; + case ACT_LAYER_SWITCH: debug("ACT_LAYER_SWITCH"); break; case ACT_MACRO: debug("ACT_MACRO"); break; case ACT_COMMAND: debug("ACT_COMMAND"); break; case ACT_FUNCTION: debug("ACT_FUNCTION"); break; diff --git a/common/action.h b/common/action.h index 1d00e02d..46ae809c 100644 --- a/common/action.h +++ b/common/action.h @@ -76,11 +76,6 @@ typedef union { -/* layer used currently */ -extern uint8_t current_layer; -/* layer to return or start with */ -extern uint8_t default_layer; - /* Execute action per keyevent */ void action_exec(keyevent_t event); @@ -155,14 +150,14 @@ bool waiting_buffer_has_anykey_pressed(void); * * Mouse Keys * ---------- - * TODO: can be combined with 'Other HID Usage'? to save action kind id. + * NOTE: can be combined with 'Other HID Usage'? to save action kind id. * ACT_MOUSEKEY(0110): * 0101|XXXX| keycode Mouse key * * * Layer Actions * ------------- - * ACT_LAYER(1000): Set layer + * ACT_LAYER_SET(1000): Set layer * 1000|LLLL|0000 0000 set current layer on press and return to default on release(momentary) * 1000|LLLL|0000 0001 set current layer on press * 1000|LLLL|0000 0010 set current layer on release @@ -216,7 +211,7 @@ enum action_kind_id { ACT_USAGE = 0b0100, ACT_MOUSEKEY = 0b0101, - ACT_LAYER = 0b1000, + ACT_LAYER_SET = 0b1000, ACT_LAYER_BIT = 0b1001, ACT_LAYER_SWITCH = 0b1011, @@ -277,14 +272,14 @@ enum layer_codes { */ /* set default layer */ #define ACTION_LAYER_SET_DEFAULT(layer) ACTION_LAYER_SET_DEFAULT_R(layer) -#define ACTION_LAYER_SET_DEFAULT_P(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_SET_DEFAULT_ON_PRESS) -#define ACTION_LAYER_SET_DEFAULT_R(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_SET_DEFAULT_ON_RELEASE) -#define ACTION_LAYER_SET_DEFAULT_B(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_SET_DEFAULT_ON_BOTH) +#define ACTION_LAYER_SET_DEFAULT_P(layer) ACTION(ACT_LAYER_SET, (layer)<<8 | LAYER_SET_DEFAULT_ON_PRESS) +#define ACTION_LAYER_SET_DEFAULT_R(layer) ACTION(ACT_LAYER_SET, (layer)<<8 | LAYER_SET_DEFAULT_ON_RELEASE) +#define ACTION_LAYER_SET_DEFAULT_B(layer) ACTION(ACT_LAYER_SET, (layer)<<8 | LAYER_SET_DEFAULT_ON_BOTH) /* bit-xor default layer */ #define ACTION_LAYER_BIT_DEFAULT(bits) ACTION_LAYER_BIT_DEFAULT_R(bits) -#define ACTION_LAYER_BIT_DEFAULT_P(bits) ACTION(ACT_LAYER, (bits)<<8 | LAYER_SET_DEFAULT_ON_PRESS) -#define ACTION_LAYER_BIT_DEFAULT_R(bits) ACTION(ACT_LAYER, (bits)<<8 | LAYER_SET_DEFAULT_ON_RELEASE) -#define ACTION_LAYER_BIT_DEFAULT_B(bits) ACTION(ACT_LAYER, (bits)<<8 | LAYER_SET_DEFAULT_ON_BOTH) +#define ACTION_LAYER_BIT_DEFAULT_P(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_SET_DEFAULT_ON_PRESS) +#define ACTION_LAYER_BIT_DEFAULT_R(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_SET_DEFAULT_ON_RELEASE) +#define ACTION_LAYER_BIT_DEFAULT_B(bits) ACTION(ACT_LAYER_BIT, (bits)<<8 | LAYER_SET_DEFAULT_ON_BOTH) /* * Current layer: Return to default layer */ @@ -296,13 +291,13 @@ enum layer_codes { * Current layer: Set */ #define ACTION_LAYER_SET(layer) ACTION_LAYER_SET_P(layer) -#define ACTION_LAYER_SET_MOMENTARY(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_MOMENTARY) +#define ACTION_LAYER_SET_MOMENTARY(layer) ACTION(ACT_LAYER_SET, (layer)<<8 | LAYER_MOMENTARY) #define ACTION_LAYER_SET_TOGGLE(layer) ACTION_LAYER_SET_R(layer) -#define ACTION_LAYER_SET_P(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_ON_PRESS) -#define ACTION_LAYER_SET_R(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_ON_RELEASE) -#define ACTION_LAYER_SET_B(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_ON_BOTH) -#define ACTION_LAYER_SET_TAP_TOGGLE(layer) ACTION(ACT_LAYER, (layer)<<8 | LAYER_TAP_TOGGLE) -#define ACTION_LAYER_SET_TAP_KEY(layer, key) ACTION(ACT_LAYER, (layer)<<8 | (key)) +#define ACTION_LAYER_SET_P(layer) ACTION(ACT_LAYER_SET, (layer)<<8 | LAYER_ON_PRESS) +#define ACTION_LAYER_SET_R(layer) ACTION(ACT_LAYER_SET, (layer)<<8 | LAYER_ON_RELEASE) +#define ACTION_LAYER_SET_B(layer) ACTION(ACT_LAYER_SET, (layer)<<8 | LAYER_ON_BOTH) +#define ACTION_LAYER_SET_TAP_TOGGLE(layer) ACTION(ACT_LAYER_SET, (layer)<<8 | LAYER_TAP_TOGGLE) +#define ACTION_LAYER_SET_TAP_KEY(layer, key) ACTION(ACT_LAYER_SET, (layer)<<8 | (key)) /* * Current layer: Bit-op */ diff --git a/common/command.c b/common/command.c index 82f647c8..2d01c95e 100644 --- a/common/command.c +++ b/common/command.c @@ -543,12 +543,9 @@ static uint8_t numkey2num(uint8_t code) static void switch_default_layer(uint8_t layer) { - print_val_hex8(current_layer); - print_val_hex8(default_layer); - print("switch to "); print_val_hex8(layer); - + // TODO check existence of layer or whether it can be used as default layer + print("switch_default_layer: "); print_dec(default_layer); print(" to "); print_dec(layer); default_layer = layer; - current_layer = 0; /* 0 means default_layer */ layer_switch_clear(); clear_keyboard(); } diff --git a/common/layer_switch.c b/common/layer_switch.c index 9bc804e6..22bfb34f 100644 --- a/common/layer_switch.c +++ b/common/layer_switch.c @@ -2,50 +2,88 @@ #include "keyboard.h" #include "action.h" #include "debug.h" +#include "util.h" #include "layer_switch.h" +uint8_t default_layer = 0; + uint16_t layer_switch_stat = 0; -uint16_t layer_switch_stat_get(void) +uint16_t layer_switch_get_stat(void) { return layer_switch_stat; } -void layer_switch_stat_set(uint16_t stat) +/* return highest layer whose state is on */ +uint8_t layer_switch_get_layer(void) { + return biton16(layer_switch_stat); +} + +static inline void stat_set(uint16_t stat) +{ + debug("layer_switch: "); + layer_switch_debug(); debug(" to "); + layer_switch_stat = stat; - layer_switch_debug(); + + layer_switch_debug(); debug("\n"); + + clear_keyboard_but_mods(); // To avoid stuck keys } void layer_switch_clear(void) { - layer_switch_stat = 0; - layer_switch_debug(); + stat_set(0); +} + + +void layer_switch_set(uint16_t stat) +{ + stat_set(stat); +} + +void layer_switch_move(uint8_t layer) +{ + if (layer) + stat_set(1<. #include "keyboard.h" #include "action.h" -uint16_t layer_switch_stat; -uint16_t layer_switch_stat_get(void); -void layer_switch_stat_set(uint16_t stat); +/* base layer to fall back */ +extern uint8_t default_layer; + +/* layer status */ +extern uint16_t layer_switch_stat; + +/* return layer status */ +uint16_t layer_switch_get_stat(void); +/* return current active layer */ +uint8_t layer_switch_get_layer(void); + +/* switch off all layers */ void layer_switch_clear(void); +/* set layer status */ +void layer_switch_set(uint16_t stat); +/* move to layer */ +void layer_switch_move(uint8_t layer); +/* switch on layer */ void layer_switch_on(uint8_t layer); +/* switch off layer */ void layer_switch_off(uint8_t layer); -/* invert state */ -void layer_switch_inv(uint8_t layer); +/* switch state of layer */ +void layer_switch_invert(uint8_t layer); + +/* bitwise operation against layer status */ +void layer_switch_or(uint16_t stat); +void layer_switch_and(uint16_t stat); +void layer_switch_xor(uint16_t stat); + void layer_switch_debug(void); + +/* return action depending on current layer status */ action_t layer_switch_get_action(key_t key); #endif diff --git a/common/util.c b/common/util.c index 9d8fb932..ff1926d7 100644 --- a/common/util.c +++ b/common/util.c @@ -39,6 +39,7 @@ uint8_t bitpop16(uint16_t bits) } // most significant on-bit - return highest location of on-bit +// NOTE: return 0 when bit0 is on or all bits are off uint8_t biton(uint8_t bits) { uint8_t n = 0; @@ -47,3 +48,13 @@ uint8_t biton(uint8_t bits) if (bits >> 1) { bits >>= 1; n += 1;} return n; } + +uint8_t biton16(uint16_t bits) +{ + uint8_t n = 0; + if (bits >> 8) { bits >>= 8; n += 8;} + if (bits >> 4) { bits >>= 4; n += 4;} + if (bits >> 2) { bits >>= 2; n += 2;} + if (bits >> 1) { bits >>= 1; n += 1;} + return n; +} diff --git a/common/util.h b/common/util.h index c3734487..58b7fdf1 100644 --- a/common/util.h +++ b/common/util.h @@ -31,5 +31,6 @@ along with this program. If not, see . uint8_t bitpop(uint8_t bits); uint8_t bitpop16(uint16_t bits); uint8_t biton(uint8_t bits); +uint8_t biton16(uint16_t bits); #endif From e023ca517cf43ffbc2cb0d75acd4a9080a2c801a Mon Sep 17 00:00:00 2001 From: tmk Date: Wed, 20 Feb 2013 11:16:13 +0900 Subject: [PATCH 08/25] Add overlay framework --- common/action.c | 398 ++++++++++++++++++++++++------------------ common/action.h | 217 +++++++++++++---------- common/command.c | 7 +- common/keymap.c | 91 ++++++---- common/keymap.h | 17 +- common/layer_switch.c | 185 +++++++++++++++----- common/layer_switch.h | 65 ++++--- 7 files changed, 612 insertions(+), 368 deletions(-) diff --git a/common/action.c b/common/action.c index 246fd99d..3703b4e8 100644 --- a/common/action.c +++ b/common/action.c @@ -202,23 +202,6 @@ void action_exec(keyevent_t event) } } -static action_t get_action(key_t key) -{ - action_t action; - action.code = ACTION_NO; - - /* layer_switch */ - action = layer_switch_get_action(key); - if (action.code != ACTION_TRANSPARENT) { - return action; - } - - /* default layer */ - //debug("get_aciton: default layer: "); debug_dec(default_layer); debug("\n"); - action = action_for_key(default_layer, key); - return action; -} - static void process_action(keyrecord_t *record) { keyevent_t event = record->event; @@ -226,9 +209,11 @@ static void process_action(keyrecord_t *record) if (IS_NOEVENT(event)) { return; } - action_t action = get_action(event.key); - debug("ACTION: "); debug_action(action); debug(" "); - layer_switch_debug(); debug("["); debug_dec(default_layer); debug("]\n"); + action_t action = layer_switch_get_action(event.key); + debug("ACTION: "); debug_action(action); + debug(" overlays: "); overlay_debug(); + debug(" keymaps: "); keymap_debug(); + debug(" default_layer: "); debug_dec(default_layer); debug("\n"); switch (action.kind.id) { /* Key and Mods */ @@ -368,207 +353,292 @@ static void process_action(keyrecord_t *record) #endif break; - /* Layer key */ - case ACT_LAYER_SET: + case ACT_KEYMAP: switch (action.layer.code) { - case LAYER_MOMENTARY: /* momentary */ + /* Keymap Reset */ + case OP_RESET: + default_layer_set(action.layer.val); + break; + /* Keymap Reset default layer */ + case (OP_RESET | ON_PRESS): if (event.pressed) { - layer_switch_move(action.layer.val); - } - else { - // NOTE: This is needed by legacy keymap support - layer_switch_move(0); + default_layer_set(action.layer.val); + overlay_clear(); } break; - case LAYER_ON_PRESS: - if (event.pressed) { - layer_switch_move(action.layer.val); - } - break; - case LAYER_ON_RELEASE: + case (OP_RESET | ON_RELEASE): if (!event.pressed) { - layer_switch_move(action.layer.val); + default_layer_set(action.layer.val); + overlay_clear(); } break; - case LAYER_ON_BOTH: - layer_switch_move(action.layer.val); + case (OP_RESET | ON_BOTH): + default_layer_set(action.layer.val); + overlay_clear(); break; - case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ + + /* Keymap Bit invert */ + case OP_INV: + /* with tap toggle */ if (event.pressed) { if (tap_count < TAPPING_TOGGLE) { - layer_switch_move(action.layer.val); + debug("KEYMAP_INV: tap toggle(press).\n"); + keymap_invert(action.layer.val); } } else { - if (tap_count >= TAPPING_TOGGLE) { - debug("LAYER_PRESSED: tap toggle.\n"); - layer_switch_move(action.layer.val); + if (tap_count <= TAPPING_TOGGLE) { + debug("KEYMAP_INV: tap toggle(release).\n"); + keymap_invert(action.layer.val); } } break; - case LAYER_SET_DEFAULT_ON_PRESS: + case (OP_INV | ON_PRESS): if (event.pressed) { - default_layer = action.layer.val; - layer_switch_move(0); + keymap_invert(action.layer.val); } break; - case LAYER_SET_DEFAULT_ON_RELEASE: + case (OP_INV | ON_RELEASE): if (!event.pressed) { - default_layer = action.layer.val; - layer_switch_move(0); + keymap_invert(action.layer.val); } break; - case LAYER_SET_DEFAULT_ON_BOTH: - default_layer = action.layer.val; - layer_switch_move(0); + case (OP_INV | ON_BOTH): + keymap_invert(action.layer.val); break; + + /* Keymap Bit on */ + case OP_ON: + if (event.pressed) { + keymap_on(action.layer.val); + } else { + keymap_off(action.layer.val); + } + break; + case (OP_ON | ON_PRESS): + if (event.pressed) { + keymap_on(action.layer.val); + } + break; + case (OP_ON | ON_RELEASE): + if (!event.pressed) { + keymap_on(action.layer.val); + } + break; + case (OP_ON | ON_BOTH): + keymap_on(action.layer.val); + break; + + /* Keymap Bit off */ + case OP_OFF: + if (event.pressed) { + keymap_off(action.layer.val); + } else { + keymap_on(action.layer.val); + } + break; + case (OP_OFF | ON_PRESS): + if (event.pressed) { + keymap_off(action.layer.val); + } + break; + case (OP_OFF | ON_RELEASE): + if (!event.pressed) { + keymap_off(action.layer.val); + } + break; + case (OP_OFF | ON_BOTH): + keymap_off(action.layer.val); + break; + + /* Keymap Bit set */ + case OP_SET: + if (event.pressed) { + keymap_set(action.layer.val); + } else { + keymap_clear(); + } + break; + case (OP_SET | ON_PRESS): + if (event.pressed) { + keymap_set(action.layer.val); + } + break; + case (OP_SET | ON_RELEASE): + if (!event.pressed) { + keymap_set(action.layer.val); + } + break; + case (OP_SET | ON_BOTH): + keymap_set(action.layer.val); + break; + + /* Keymap Bit invert with tap key */ default: - /* tap key */ if (event.pressed) { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { - debug("LAYER_SET: Tap: register_code\n"); - register_code(action.layer.code); + debug("KEYMAP_TAP_KEY: Tap: register_code\n"); + register_code(action.layer.code); } else { - debug("LAYER_SET: No tap: layer_set(on press)\n"); - layer_switch_move(action.layer.val); + debug("KEYMAP_TAP_KEY: No tap: invert on press\n"); + keymap_invert(action.layer.val); } } else { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { - debug("LAYER_SET: Tap: unregister_code\n"); + debug("KEYMAP_TAP_KEY: Tap: unregister_code\n"); unregister_code(action.layer.code); } else { - // NOTE: This is needed by legacy keymap support - debug("LAYER_SET: No tap: return to default layer(on release)\n"); - layer_switch_move(0); + debug("KEYMAP_TAP_KEY: No tap: invert on release\n"); + keymap_invert(action.layer.val); } } break; } break; - case ACT_LAYER_BIT: + + case ACT_OVERLAY: switch (action.layer.code) { - case LAYER_MOMENTARY: /* momentary */ - if (event.pressed) { - layer_switch_move(layer_switch_get_layer() | action.layer.val); + // Overlay Invert bit4 + case OP_INV4 | 0: + if (action.layer.val == 0) { + overlay_clear(); } else { - layer_switch_move(layer_switch_get_layer() & ~action.layer.val); + overlay_set(overlay_stat ^ action.layer.val); } break; - case LAYER_ON_PRESS: - if (event.pressed) { - layer_switch_move(layer_switch_get_layer() ^ action.layer.val); + case OP_INV4 | 1: + if (action.layer.val == 0) { + if (event.pressed) overlay_clear(); + } else { + overlay_set(overlay_stat ^ action.layer.val<<4); } break; - case LAYER_ON_RELEASE: - if (!event.pressed) { - layer_switch_move(layer_switch_get_layer() ^ action.layer.val); + case OP_INV4 | 2: + if (action.layer.val == 0) { + if (!event.pressed) overlay_clear(); + } else { + overlay_set(overlay_stat ^ action.layer.val<<8); } break; - case LAYER_ON_BOTH: - layer_switch_move(layer_switch_get_layer() ^ action.layer.val); + case OP_INV4 | 3: + if (action.layer.val == 0) { + overlay_clear(); + } else { + overlay_set(overlay_stat ^ action.layer.val<<12); + } break; - case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ + + /* Overlay Bit invert */ + case OP_INV: + /* with tap toggle */ if (event.pressed) { if (tap_count < TAPPING_TOGGLE) { - debug("LAYER_BIT: tap toggle(press).\n"); - layer_switch_move(layer_switch_get_layer() ^ action.layer.val); + debug("OVERLAY_INV: tap toggle(press).\n"); + overlay_invert(action.layer.val); } } else { if (tap_count <= TAPPING_TOGGLE) { - debug("LAYER_BIT: tap toggle(release).\n"); - layer_switch_move(layer_switch_get_layer() ^ action.layer.val); + debug("OVERLAY_INV: tap toggle(release).\n"); + overlay_invert(action.layer.val); } } break; - case LAYER_SET_DEFAULT_ON_PRESS: + case (OP_INV | ON_PRESS): if (event.pressed) { - default_layer = default_layer ^ action.layer.val; - layer_switch_move(default_layer); + overlay_invert(action.layer.val); } break; - case LAYER_SET_DEFAULT_ON_RELEASE: + case (OP_INV | ON_RELEASE): if (!event.pressed) { - default_layer = default_layer ^ action.layer.val; - layer_switch_move(default_layer); + overlay_invert(action.layer.val); } break; - case LAYER_SET_DEFAULT_ON_BOTH: - default_layer = default_layer ^ action.layer.val; - layer_switch_move(default_layer); + case (OP_INV | ON_BOTH): + overlay_invert(action.layer.val); break; + + /* Overlay Bit on */ + case OP_ON: + if (event.pressed) { + overlay_on(action.layer.val); + } else { + overlay_off(action.layer.val); + } + break; + case (OP_ON | ON_PRESS): + if (event.pressed) { + overlay_on(action.layer.val); + } + break; + case (OP_ON | ON_RELEASE): + if (!event.pressed) { + overlay_on(action.layer.val); + } + break; + case (OP_ON | ON_BOTH): + overlay_on(action.layer.val); + break; + + /* Overlay Bit off */ + case OP_OFF: + if (event.pressed) { + overlay_off(action.layer.val); + } else { + overlay_on(action.layer.val); + } + break; + case (OP_OFF | ON_PRESS): + if (event.pressed) { + overlay_off(action.layer.val); + } + break; + case (OP_OFF | ON_RELEASE): + if (!event.pressed) { + overlay_off(action.layer.val); + } + break; + case (OP_OFF | ON_BOTH): + overlay_off(action.layer.val); + break; + + /* Overlay Bit set */ + case OP_SET: + if (event.pressed) { + overlay_move(action.layer.val); + } else { + overlay_clear(); + } + break; + case (OP_SET | ON_PRESS): + if (event.pressed) { + overlay_move(action.layer.val); + } + break; + case (OP_SET | ON_RELEASE): + if (!event.pressed) { + overlay_move(action.layer.val); + } + break; + case (OP_SET | ON_BOTH): + overlay_move(action.layer.val); + break; + + /* Overlay Bit invert with tap key */ default: - // tap key if (event.pressed) { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { - debug("LAYER_BIT: Tap: register_code\n"); + debug("OVERLAY_TAP_KEY: Tap: register_code\n"); register_code(action.layer.code); } else { - debug("LAYER_BIT: No tap: layer_bit(on press)\n"); - layer_switch_move(layer_switch_get_layer() ^ action.layer.val); + debug("OVERLAY_TAP_KEY: No tap: invert on press\n"); + overlay_invert(action.layer.val); } } else { if (IS_TAPPING_KEY(event.key) && tap_count > 0) { - debug("LAYER_BIT: Tap: unregister_code\n"); + debug("OVERLAY_TAP_KEY: Tap: unregister_code\n"); unregister_code(action.layer.code); } else { - debug("LAYER_BIT: No tap: layer_bit(on release)\n"); - layer_switch_move(layer_switch_get_layer() ^ action.layer.val); - } - } - break; - } - break; - case ACT_LAYER_SWITCH: - switch (action.layer.code) { - case LAYER_MOMENTARY: /* momentary */ - if (event.pressed) { - layer_switch_on(action.layer.val); - } else { - layer_switch_off(action.layer.val); - } - break; - case LAYER_ON_PRESS: - if (event.pressed) { - layer_switch_invert(action.layer.val); - } - break; - case LAYER_ON_RELEASE: - if (!event.pressed) { - layer_switch_invert(action.layer.val); - } - break; - case LAYER_ON_BOTH: - layer_switch_invert(action.layer.val); - break; - case LAYER_TAP_TOGGLE: /* switch on hold and toggle on several taps */ - if (event.pressed) { - if (tap_count < TAPPING_TOGGLE) { - debug("LAYER_SWITCH: tap toggle(press).\n"); - layer_switch_invert(action.layer.val); - } - } else { - if (tap_count <= TAPPING_TOGGLE) { - debug("LAYER_SWITCH: tap toggle(release).\n"); - layer_switch_invert(action.layer.val); - } - } - break; - default: - // tap key - if (event.pressed) { - if (IS_TAPPING_KEY(event.key) && tap_count > 0) { - debug("LAYER_SWITCH: Tap: register_code\n"); - register_code(action.layer.code); - } else { - debug("LAYER_SWITCH: No tap: layer_switch on press\n"); - layer_switch_invert(action.layer.val); - } - } else { - if (IS_TAPPING_KEY(event.key) && tap_count > 0) { - debug("LAYER_SWITCH: Tap: unregister_code\n"); - unregister_code(action.layer.code); - } else { - debug("LAYER_SWITCH: No tap: layer_switch on release\n"); - layer_switch_invert(action.layer.val); + debug("OVERLAY_TAP_KEY: No tap: invert on release\n"); + overlay_invert(action.layer.val); } } break; @@ -877,28 +947,21 @@ bool sending_anykey(void) bool is_tap_key(key_t key) { - action_t action = get_action(key); + action_t action = layer_switch_get_action(key); switch (action.kind.id) { case ACT_LMODS_TAP: case ACT_RMODS_TAP: return true; - case ACT_LAYER_SET: - case ACT_LAYER_BIT: + case ACT_KEYMAP: + case ACT_OVERLAY: switch (action.layer.code) { - case LAYER_MOMENTARY: - case LAYER_ON_PRESS: - case LAYER_ON_RELEASE: - case LAYER_ON_BOTH: - case LAYER_SET_DEFAULT_ON_PRESS: - case LAYER_SET_DEFAULT_ON_RELEASE: - case LAYER_SET_DEFAULT_ON_BOTH: - return false; - case LAYER_TAP_TOGGLE: - default: /* tap key */ + case 0x04 ... 0xEF: /* tap key */ + case OP_INV: return true; + default: + return false; } - return false; case ACT_FUNCTION: if (action.func.opt & FUNC_TAP) { return true; } return false; @@ -929,9 +992,8 @@ static void debug_action(action_t action) case ACT_RMODS_TAP: debug("ACT_RMODS_TAP"); break; case ACT_USAGE: debug("ACT_USAGE"); break; case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break; - case ACT_LAYER_SET: debug("ACT_LAYER_SET"); break; - case ACT_LAYER_BIT: debug("ACT_LAYER_BIT"); break; - case ACT_LAYER_SWITCH: debug("ACT_LAYER_SWITCH"); break; + case ACT_KEYMAP: debug("ACT_KEYMAP"); break; + case ACT_OVERLAY: debug("ACT_OVERLAY"); break; case ACT_MACRO: debug("ACT_MACRO"); break; case ACT_COMMAND: debug("ACT_COMMAND"); break; case ACT_FUNCTION: debug("ACT_FUNCTION"); break; diff --git a/common/action.h b/common/action.h index 46ae809c..c02a2e71 100644 --- a/common/action.h +++ b/common/action.h @@ -150,40 +150,41 @@ bool waiting_buffer_has_anykey_pressed(void); * * Mouse Keys * ---------- - * NOTE: can be combined with 'Other HID Usage'? to save action kind id. * ACT_MOUSEKEY(0110): * 0101|XXXX| keycode Mouse key * * * Layer Actions * ------------- - * ACT_LAYER_SET(1000): Set layer - * 1000|LLLL|0000 0000 set current layer on press and return to default on release(momentary) - * 1000|LLLL|0000 0001 set current layer on press - * 1000|LLLL|0000 0010 set current layer on release - * 1000|LLLL|0000 0011 set current layer on both - * 1000|LLLL| keycode set current layer on hold and send key on tap - * 1000|LLLL|1111 0000 set current layer on hold and toggle on several taps - * 1000|DDDD|1111 1111 set default layer on press - * L: 0 means default layer + * ACT_KEYMAP: + * 1000|LLLL|0000 0000 Reset default layer + * 1000|LLLL|0000 00xx Reset default layer and clear overlay + * 1000|LLLL| keycode Invert with tap key + * 1000|LLLL|1111 0000 Invert with tap toggle + * 1000|LLLL|1111 00xx Invert[^= L] + * 1000|LLLL|1111 0100 On/Off + * 1000|LLLL|1111 01xx On[|= L] + * 1000|LLLL|1111 1000 Off/On + * 1000|LLLL|1111 10xx Off[&= ~L] + * 1000|LLLL|1111 1100 Set/Set(0) + * 1000|LLLL|1111 11xx Set[= L] + * default layer: 0-15(4bit) + * xx: On {00:for special use, 01:press, 10:release, 11:both} * - * ACT_LAYER_BIT(1001): Bit-op layer - * 1001|BBBB|0000 0000 bit-on current layer on press and bit-off on release(momentary) - * 1001|BBBB|0000 0001 bit-xor current layer on press - * 1001|BBBB|0000 0010 bit-xor current layer on release - * 1001|BBBB|0000 0011 bit-xor current layer on both - * 1001|BBBB| keycode bit-xor current layer on hold and send key on tap - * 1001|BBBB|1111 0000 bit-xor current layer on hold and toggle on several taps - * 1001|BBBB|1111 1111 bit-xor default layer on both - * - * ACT_LAYER_SWITCH: Switch - * 1011|LLLL|0000 0000 On on press and Off on release(momentary) - * 1011|LLLL|0000 0001 Invert on press - * 1011|LLLL|0000 0010 Invert on release - * 1011|LLLL|0000 0011 Invert on both - * 1011|LLLL| keycode Invert on hold and send key on tap - * 1011|LLLL|1111 0000 Invert on hold and toggle on several taps - * 1011|LLLL|1111 1111 (not used) + * ACT_OVERLAY: + * 1011|0000|0000 0000 Clear overlay + * 1011|LLLL|0000 00ss Invert 4-bit chunk [^= L<<(4*ss)] + * 1011|LLLL| keycode Invert with tap key + * 1011|LLLL|1111 0000 Invert with tap toggle + * 1011|LLLL|1111 00xx Invert[^= 1<. */ +#include #include "keymap.h" #include "report.h" #include "keycode.h" +#include "layer_switch.h" #include "action.h" +#include "debug.h" -action_t keymap_keycode_to_action(uint8_t keycode) +static action_t keycode_to_action(uint8_t keycode); + +#ifdef USE_KEYMAP_V2 +/* converts key to action */ +action_t action_for_key(uint8_t layer, key_t key) +{ + uint8_t keycode = keymap_key_to_keycode(layer, key); + switch (keycode) { + case KC_FN0 ... KC_FN31: + return keymap_fn_to_action(keycode); + default: + return keycode_to_action(keycode); + } +} + +__attribute__ ((weak)) +void action_function(keyrecord_t *event, uint8_t id, uint8_t opt) +{ +} +#else +/* + * legacy keymap support + */ +/* translation for legacy keymap */ +action_t action_for_key(uint8_t layer, key_t key) +{ + /* convert from legacy keycode to action */ + /* layer 16-31 indicate 'overlay' but not supported in legacy keymap */ + uint8_t keycode = keymap_get_keycode((layer & OVERLAY_MASK), key.row, key.col); + action_t action; + 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_KEYMAP_TAP_KEY(layer, key); + } else { + action.code = ACTION_KEYMAP_MOMENTARY(layer); + } + } + return action; + default: + return keycode_to_action(keycode); + } +} +/* not used for legacy keymap */ +void action_function(keyrecord_t *event, uint8_t id, uint8_t opt) +{ +} +#endif + + + +/* translates keycode to action */ +static action_t keycode_to_action(uint8_t keycode) { action_t action; switch (keycode) { @@ -51,34 +109,3 @@ action_t keymap_keycode_to_action(uint8_t keycode) } return action; } - -#ifndef NO_LEGACY_KEYMAP_SUPPORT -/* legacy support with weak reference */ -__attribute__ ((weak)) -action_t action_for_key(uint8_t layer, key_t key) -{ - /* convert from legacy keycode to action */ - uint8_t keycode = keymap_get_keycode(layer, key.row, key.col); - action_t action; - 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_SET_TAP_KEY(layer, key); - } else { - action.code = ACTION_LAYER_SET_MOMENTARY(layer); - } - } - return action; - default: - return keymap_keycode_to_action(keycode); - } -} -#endif - -__attribute__ ((weak)) -void action_function(keyrecord_t *event, uint8_t id, uint8_t opt) -{ -} diff --git a/common/keymap.h b/common/keymap.h index 63bf1448..0c483483 100644 --- a/common/keymap.h +++ b/common/keymap.h @@ -23,16 +23,19 @@ along with this program. If not, see . #include "action.h" -/* translates key_t to keycode */ +#ifdef USE_KEYMAP_V2 +/* translates key to keycode + * layer: 0-15 for base layers + * 16-31 for overlays + */ uint8_t keymap_key_to_keycode(uint8_t layer, key_t key); -/* translates keycode to action */ -action_t keymap_keycode_to_action(uint8_t keycode); /* translates Fn keycode to action */ action_t keymap_fn_to_action(uint8_t keycode); - - - -#ifndef NO_LEGACY_KEYMAP_SUPPORT +#else +#warning "You are using LEGACY KEYAMP. Consider using NEW KEYMAP." +/* + * legacy keymap support + */ /* keycode of key */ uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col); /* layer to move during press Fn key */ diff --git a/common/layer_switch.c b/common/layer_switch.c index 22bfb34f..19e286f8 100644 --- a/common/layer_switch.c +++ b/common/layer_switch.c @@ -6,84 +6,168 @@ #include "layer_switch.h" +/* + * Default Layer (0-15) + */ uint8_t default_layer = 0; -uint16_t layer_switch_stat = 0; - - -uint16_t layer_switch_get_stat(void) +void default_layer_set(uint8_t layer) { - return layer_switch_stat; -} + debug("default_layer_set: "); + debug_dec(default_layer); debug(" to "); -/* return highest layer whose state is on */ -uint8_t layer_switch_get_layer(void) -{ - return biton16(layer_switch_stat); -} + default_layer = layer; -static inline void stat_set(uint16_t stat) -{ - debug("layer_switch: "); - layer_switch_debug(); debug(" to "); - - layer_switch_stat = stat; - - layer_switch_debug(); debug("\n"); + debug_dec(default_layer); debug("\n"); clear_keyboard_but_mods(); // To avoid stuck keys } -void layer_switch_clear(void) + +/* + * Keymap Layer (0-15) + */ +uint16_t keymap_stat = 0; + +/* return highest layer whose state is on */ +uint8_t keymap_get_layer(void) { - stat_set(0); + return biton16(keymap_stat); +} + +static void keymap_stat_set(uint16_t stat) +{ + debug("keymap: "); + keymap_debug(); debug(" to "); + + keymap_stat = stat; + + keymap_debug(); debug("\n"); + + clear_keyboard_but_mods(); // To avoid stuck keys +} + +void keymap_clear(void) +{ + keymap_stat_set(0); } -void layer_switch_set(uint16_t stat) +void keymap_set(uint16_t stat) { - stat_set(stat); + keymap_stat_set(stat); } -void layer_switch_move(uint8_t layer) +void keymap_move(uint8_t layer) { - if (layer) - stat_set(1<= 0; i--) { - if (layer_switch_stat & (1<= 0; i--) { + if (keymap_stat & (1<. #include "action.h" +/* overlays are asigned at layer 16-31 */ +#define OVERLAY_BIT 0x10 +#define OVERLAY_MASK 0x0F + + +/* + * Default Layer + */ /* base layer to fall back */ extern uint8_t default_layer; +void default_layer_set(uint8_t layer); -/* layer status */ -extern uint16_t layer_switch_stat; -/* return layer status */ -uint16_t layer_switch_get_stat(void); +/* + * Keymap Layer + */ +extern uint16_t keymap_stat; /* return current active layer */ -uint8_t layer_switch_get_layer(void); +uint8_t keymap_get_layer(void); +void keymap_clear(void); +void keymap_set(uint16_t stat); +void keymap_move(uint8_t layer); +void keymap_on(uint8_t layer); +void keymap_off(uint8_t layer); +void keymap_invert(uint8_t layer); +/* bitwise operation */ +void keymap_or(uint16_t stat); +void keymap_and(uint16_t stat); +void keymap_xor(uint16_t stat); +void keymap_debug(void); -/* switch off all layers */ -void layer_switch_clear(void); -/* set layer status */ -void layer_switch_set(uint16_t stat); -/* move to layer */ -void layer_switch_move(uint8_t layer); -/* switch on layer */ -void layer_switch_on(uint8_t layer); -/* switch off layer */ -void layer_switch_off(uint8_t layer); -/* switch state of layer */ -void layer_switch_invert(uint8_t layer); -/* bitwise operation against layer status */ -void layer_switch_or(uint16_t stat); -void layer_switch_and(uint16_t stat); -void layer_switch_xor(uint16_t stat); +/* + * Overlay Layer + */ +extern uint16_t overlay_stat; +/* return current active layer */ +uint8_t overlay_get_layer(void); +void overlay_clear(void); +void overlay_set(uint16_t stat); +void overlay_move(uint8_t layer); +void overlay_on(uint8_t layer); +void overlay_off(uint8_t layer); +void overlay_invert(uint8_t layer); +/* bitwise operation */ +void overlay_or(uint16_t stat); +void overlay_and(uint16_t stat); +void overlay_xor(uint16_t stat); +void overlay_debug(void); + -void layer_switch_debug(void); /* return action depending on current layer status */ action_t layer_switch_get_action(key_t key); From 4c8f2bbfa27c14de3eb634f016c3c8e6261c9074 Mon Sep 17 00:00:00 2001 From: tmk Date: Wed, 20 Feb 2013 15:52:32 +0900 Subject: [PATCH 09/25] Add keymap clear/reset action --- common/action.c | 34 +++++++++++++++++++++++++++++----- common/action.h | 23 +++++++++++++---------- common/keymap.c | 4 ++-- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/common/action.c b/common/action.c index 3703b4e8..844a35b3 100644 --- a/common/action.c +++ b/common/action.c @@ -355,26 +355,50 @@ static void process_action(keyrecord_t *record) case ACT_KEYMAP: switch (action.layer.code) { - /* Keymap Reset */ + /* Keymap clear */ case OP_RESET: - default_layer_set(action.layer.val); + switch (action.layer.val & 0x03) { + case 0: + overlay_clear(); + keymap_clear(); + break; + case ON_PRESS: + if (event.pressed) { + overlay_clear(); + keymap_clear(); + } + break; + case ON_RELEASE: + if (!event.pressed) { + overlay_clear(); + keymap_clear(); + } + break; + case ON_BOTH: + overlay_clear(); + keymap_clear(); + break; + } break; /* Keymap Reset default layer */ case (OP_RESET | ON_PRESS): if (event.pressed) { - default_layer_set(action.layer.val); overlay_clear(); + keymap_clear(); + default_layer_set(action.layer.val); } break; case (OP_RESET | ON_RELEASE): if (!event.pressed) { - default_layer_set(action.layer.val); overlay_clear(); + keymap_clear(); + default_layer_set(action.layer.val); } break; case (OP_RESET | ON_BOTH): - default_layer_set(action.layer.val); overlay_clear(); + keymap_clear(); + default_layer_set(action.layer.val); break; /* Keymap Bit invert */ diff --git a/common/action.h b/common/action.h index c02a2e71..611490eb 100644 --- a/common/action.h +++ b/common/action.h @@ -157,8 +157,8 @@ bool waiting_buffer_has_anykey_pressed(void); * Layer Actions * ------------- * ACT_KEYMAP: - * 1000|LLLL|0000 0000 Reset default layer - * 1000|LLLL|0000 00xx Reset default layer and clear overlay + * 1000|--xx|0000 0000 Clear keyamp and overlay + * 1000|LLLL|0000 00xx Reset default layer and clear keymap and overlay * 1000|LLLL| keycode Invert with tap key * 1000|LLLL|1111 0000 Invert with tap toggle * 1000|LLLL|1111 00xx Invert[^= L] @@ -274,22 +274,25 @@ enum layer_params { OP_SET = 0xFC, }; -/* +/* * Default Layer */ -#define ACTION_KEYMAP(layer) ACTION_KEYMAP_MOMENTARY(layer) -#define ACTION_KEYMAP_MOMENTARY(layer) ACTION_KEYMAP_INV_B(layer) -#define ACTION_KEYMAP_TOGGLE(layer) ACTION_KEYMAP_INV_R(layer) -/* Set default layer */ +#define ACTION_DEFAULT_LAYER ACTION(ACT_KEYMAP, 0<<8 | OP_RESET | 0) #define ACTION_SET_DEFAULT_LAYER(layer) ACTION_KEYMAP_RESET(layer) #define ACTION_SET_DEFAULT_LAYER_P(layer) ACTION_KEYMAP_RESET_P(layer) #define ACTION_SET_DEFAULT_LAYER_R(layer) ACTION_KEYMAP_RESET_R(layer) #define ACTION_SET_DEFAULT_LAYER_B(layer) ACTION_KEYMAP_RESET_B(layer) +/* + * Keymap Layer + */ +#define ACTION_KEYMAP(layer) ACTION_KEYMAP_MOMENTARY(layer) +#define ACTION_KEYMAP_MOMENTARY(layer) ACTION_KEYMAP_ON_OFF(layer) +#define ACTION_KEYMAP_TOGGLE(layer) ACTION_KEYMAP_INV_R(layer) /* Keymap Set and clear overaly */ -#define ACTION_KEYMAP_RESET(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | 0) +#define ACTION_KEYMAP_RESET(layer) ACTION_KEYMAP_RESET_R(layer) #define ACTION_KEYMAP_RESET_P(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | ON_PRESS) -#define ACTION_KEYMAP_RESET_R(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | ON_PRESS) -#define ACTION_KEYMAP_RESET_B(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | ON_PRESS) +#define ACTION_KEYMAP_RESET_R(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | ON_RELEASE) +#define ACTION_KEYMAP_RESET_B(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | ON_BOTH) /* Keymap Invert */ #define ACTION_KEYMAP_INV(layer) ACTION_KEYMAP_INV_B(layer) #define ACTION_KEYMAP_TAP_TOGGLE(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | 0) diff --git a/common/keymap.c b/common/keymap.c index 3f13d449..ddc32105 100644 --- a/common/keymap.c +++ b/common/keymap.c @@ -39,7 +39,7 @@ action_t action_for_key(uint8_t layer, key_t key) } __attribute__ ((weak)) -void action_function(keyrecord_t *event, uint8_t id, uint8_t opt) +void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } #else @@ -70,7 +70,7 @@ action_t action_for_key(uint8_t layer, key_t key) } } /* not used for legacy keymap */ -void action_function(keyrecord_t *event, uint8_t id, uint8_t opt) +void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } #endif From b0558b5f77b460a9161c37fe5b5a0f5729848291 Mon Sep 17 00:00:00 2001 From: tmk Date: Wed, 20 Feb 2013 16:53:55 +0900 Subject: [PATCH 10/25] Fix tap key bug: layer stuck - Can't use Invert action for tap key, use On/Off insted. --- common/action.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/common/action.c b/common/action.c index 844a35b3..294ce00f 100644 --- a/common/action.c +++ b/common/action.c @@ -499,20 +499,20 @@ static void process_action(keyrecord_t *record) /* Keymap Bit invert with tap key */ default: if (event.pressed) { - if (IS_TAPPING_KEY(event.key) && tap_count > 0) { + if (tap_count > 0) { debug("KEYMAP_TAP_KEY: Tap: register_code\n"); register_code(action.layer.code); } else { - debug("KEYMAP_TAP_KEY: No tap: invert on press\n"); - keymap_invert(action.layer.val); + debug("KEYMAP_TAP_KEY: No tap: On on press\n"); + keymap_on(action.layer.val); } } else { - if (IS_TAPPING_KEY(event.key) && tap_count > 0) { + if (tap_count > 0) { debug("KEYMAP_TAP_KEY: Tap: unregister_code\n"); unregister_code(action.layer.code); } else { - debug("KEYMAP_TAP_KEY: No tap: invert on release\n"); - keymap_invert(action.layer.val); + debug("KEYMAP_TAP_KEY: No tap: Off on release\n"); + keymap_off(action.layer.val); } } break; @@ -649,20 +649,20 @@ static void process_action(keyrecord_t *record) /* Overlay Bit invert with tap key */ default: if (event.pressed) { - if (IS_TAPPING_KEY(event.key) && tap_count > 0) { + if (tap_count > 0) { debug("OVERLAY_TAP_KEY: Tap: register_code\n"); register_code(action.layer.code); } else { - debug("OVERLAY_TAP_KEY: No tap: invert on press\n"); - overlay_invert(action.layer.val); + debug("OVERLAY_TAP_KEY: No tap: On on press\n"); + overlay_on(action.layer.val); } } else { - if (IS_TAPPING_KEY(event.key) && tap_count > 0) { + if (tap_count > 0) { debug("OVERLAY_TAP_KEY: Tap: unregister_code\n"); unregister_code(action.layer.code); } else { - debug("OVERLAY_TAP_KEY: No tap: invert on release\n"); - overlay_invert(action.layer.val); + debug("OVERLAY_TAP_KEY: No tap: Off on release\n"); + overlay_off(action.layer.val); } } break; From 6f55cbee1d6d73fd86967d4b9bc554fb4bb63827 Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 22 Feb 2013 09:53:46 +0900 Subject: [PATCH 11/25] Add initial files for PC98 --- protocol/serial_soft.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c index beddc353..e0661c3a 100644 --- a/protocol/serial_soft.c +++ b/protocol/serial_soft.c @@ -106,11 +106,19 @@ ISR(SERIAL_RXD_VECT) SERIAL_RXD_INT_ENTER() uint8_t data = 0; + #ifdef SERIAL_BIT_ORDER_MSB uint8_t mask = 0x80; #else uint8_t mask = 0x01; #endif + +#ifdef SERIAL_PARITY_ODD + uint8_t parity = 0; +#else + uint8_t parity = 1; +#endif + /* to center of start bit */ _delay_us(WAIT_US/2); do { @@ -119,6 +127,7 @@ ISR(SERIAL_RXD_VECT) if (SERIAL_RXD_READ()) { data |= mask; + parity ^= 1; } #ifdef SERIAL_BIT_ORDER_MSB mask >>= 1; @@ -126,11 +135,18 @@ ISR(SERIAL_RXD_VECT) mask <<= 1; #endif } while (mask); + + /* to center of parity bit */ + _delay_us(WAIT_US); + parity ^= SERIAL_RXD_READ(); + /* to center of stop bit */ _delay_us(WAIT_US); + _delay_us(WAIT_US/2); + parity = 1; uint8_t next = (rbuf_head + 1) % RBUF_SIZE; - if (next != rbuf_tail) { + if (parity && next != rbuf_tail) { rbuf[rbuf_head] = data; rbuf_head = next; } From 11b25580cb333eabc4dba799dc6a687cda7fba72 Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 22 Feb 2013 15:48:35 +0900 Subject: [PATCH 12/25] Quick Fix: read scan code from PC98 --- protocol/serial_soft.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c index e0661c3a..47b1e457 100644 --- a/protocol/serial_soft.c +++ b/protocol/serial_soft.c @@ -48,6 +48,23 @@ POSSIBILITY OF SUCH DAMAGE. #define WAIT_US (1000000/SERIAL_BAUD) +#if 1 +#define WAIT_TICK (1000000/SERIAL_BAUD) +#define WAIT4(tick) _delay_us(tick) +#else +#define WAIT_TICK ((16000000/SERIAL_BAUD)/4 - 5) +static inline void WAIT4(uint8_t tick) +{ + __asm__ __volatile__ ( + "1: dec %0" "\n\t" + "nop" "\n\t" + "brne 1b" + : + : "r" (tick) + ); +} +#endif + void serial_init(void) { SERIAL_RXD_INIT(); @@ -60,6 +77,7 @@ static uint8_t rbuf[RBUF_SIZE]; static uint8_t rbuf_head = 0; static uint8_t rbuf_tail = 0; + uint8_t serial_recv(void) { uint8_t data = 0; @@ -103,6 +121,7 @@ void serial_send(uint8_t data) /* detect edge of start bit */ ISR(SERIAL_RXD_VECT) { +PORTD ^= 1<<7; SERIAL_RXD_INT_ENTER() uint8_t data = 0; @@ -120,11 +139,15 @@ ISR(SERIAL_RXD_VECT) #endif /* to center of start bit */ - _delay_us(WAIT_US/2); + //_delay_us(WAIT_US/2); + WAIT4(WAIT_TICK/2); +PORTD ^= 1<<7; do { /* to center of next bit */ - _delay_us(WAIT_US); + //_delay_us(WAIT_US); + WAIT4(WAIT_TICK); +PORTD ^= 1<<7; if (SERIAL_RXD_READ()) { data |= mask; parity ^= 1; @@ -137,19 +160,22 @@ ISR(SERIAL_RXD_VECT) } while (mask); /* to center of parity bit */ - _delay_us(WAIT_US); - parity ^= SERIAL_RXD_READ(); + //_delay_us(WAIT_US); + WAIT4(WAIT_TICK); + if (SERIAL_RXD_READ()) { parity ^= 1; } +PORTD ^= 1<<7; /* to center of stop bit */ - _delay_us(WAIT_US); - _delay_us(WAIT_US/2); + //_delay_us(WAIT_US); + WAIT4(WAIT_TICK); - parity = 1; uint8_t next = (rbuf_head + 1) % RBUF_SIZE; - if (parity && next != rbuf_tail) { + //if (parity && next != rbuf_tail) { + if (next != rbuf_tail) { rbuf[rbuf_head] = data; rbuf_head = next; } SERIAL_RXD_INT_EXIT(); +PORTD ^= 1<<7; } From deebebf6144f57acd94d0b261e88c2e1e4b433ff Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 22 Feb 2013 19:38:06 +0900 Subject: [PATCH 13/25] Fix softwere serial --- protocol/serial.h | 1 + protocol/serial_soft.c | 44 ++++++++++++++++-------------------------- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/protocol/serial.h b/protocol/serial.h index bd071bec..96913c86 100644 --- a/protocol/serial.h +++ b/protocol/serial.h @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. /* host role */ void serial_init(void); uint8_t serial_recv(void); +int16_t serial_recv2(void); void serial_send(uint8_t data); #endif diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c index 47b1e457..af5110b4 100644 --- a/protocol/serial_soft.c +++ b/protocol/serial_soft.c @@ -48,23 +48,6 @@ POSSIBILITY OF SUCH DAMAGE. #define WAIT_US (1000000/SERIAL_BAUD) -#if 1 -#define WAIT_TICK (1000000/SERIAL_BAUD) -#define WAIT4(tick) _delay_us(tick) -#else -#define WAIT_TICK ((16000000/SERIAL_BAUD)/4 - 5) -static inline void WAIT4(uint8_t tick) -{ - __asm__ __volatile__ ( - "1: dec %0" "\n\t" - "nop" "\n\t" - "brne 1b" - : - : "r" (tick) - ); -} -#endif - void serial_init(void) { SERIAL_RXD_INIT(); @@ -90,6 +73,18 @@ uint8_t serial_recv(void) return data; } +int16_t serial_recv2(void) +{ + uint8_t data = 0; + if (rbuf_head == rbuf_tail) { + return -1; + } + + data = rbuf[rbuf_tail]; + rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; + return data; +} + void serial_send(uint8_t data) { /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */ @@ -139,13 +134,11 @@ PORTD ^= 1<<7; #endif /* to center of start bit */ - //_delay_us(WAIT_US/2); - WAIT4(WAIT_TICK/2); + _delay_us(WAIT_US/2); PORTD ^= 1<<7; do { /* to center of next bit */ - //_delay_us(WAIT_US); - WAIT4(WAIT_TICK); + _delay_us(WAIT_US); PORTD ^= 1<<7; if (SERIAL_RXD_READ()) { @@ -160,18 +153,15 @@ PORTD ^= 1<<7; } while (mask); /* to center of parity bit */ - //_delay_us(WAIT_US); - WAIT4(WAIT_TICK); + _delay_us(WAIT_US); if (SERIAL_RXD_READ()) { parity ^= 1; } PORTD ^= 1<<7; /* to center of stop bit */ - //_delay_us(WAIT_US); - WAIT4(WAIT_TICK); + _delay_us(WAIT_US); uint8_t next = (rbuf_head + 1) % RBUF_SIZE; - //if (parity && next != rbuf_tail) { - if (next != rbuf_tail) { + if (parity && next != rbuf_tail) { rbuf[rbuf_head] = data; rbuf_head = next; } From 22a91bf9ab6c28e2452ddfaeca651bc36fd252b8 Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 23 Feb 2013 13:42:59 +0900 Subject: [PATCH 14/25] Fix README and comments in action.h --- README.md | 125 +++++++++++++++++++++++++++++------------------- common/action.h | 14 +++--- 2 files changed, 82 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index b9238922..d4fee96c 100644 --- a/README.md +++ b/README.md @@ -211,26 +211,34 @@ Many of existent projects offer keymap framework to define your own keymap easil This is keymap example for [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard. Keymap is defined in `keymaps[]` array. static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* Layer 0: Default Layer + /* Keymap 0: Default Layer * ,-----------------------------------------------------------. * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| * |-----------------------------------------------------------| * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Backs| * |-----------------------------------------------------------| - * |Contro| A| S| D| F| G| H| J| K| L| ;| '|Enter | + * |Contro| A| S| D| F| G| H| J| K| L|Fn1| '|Enter | * |-----------------------------------------------------------| - * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn1| + * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn0| * `-----------------------------------------------------------' * |Gui|Alt |Space |Alt |Fn2| * `-------------------------------------------' */ KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \ TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \ - LCTL,A, S, D, F, G, H, J, K, L, FN2, QUOT,ENT, \ - LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT,FN1, \ + LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT,ENT, \ + LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT,FN0, \ LGUI,LALT, SPC, RALT,FN3), + /* Keymap 1: colemak */ + KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \ + TAB, Q, W, F, P, G, J, L, U, Y, SCLN,LBRC,RBRC,BSPC, \ + BSPC,A, R, S, T, D, H, N, E, I, O, QUOT,ENT, \ + LSFT,Z, X, C, V, B, K, M, COMM,DOT, SLSH,RSFT,FN0, \ + LGUI,LALT, SPC, RALT,FN2), + }; - /* Layer 1: HHKB mode (HHKB Fn) + static const uint8_t PROGMEM overlays[][MATRIX_ROWS][MATRIX_COLS] = { + /* Overlay 0: HHKB mode (HHKB Fn) * ,-----------------------------------------------------------. * |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| * |-----------------------------------------------------------| @@ -238,42 +246,41 @@ This is keymap example for [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Key * |-----------------------------------------------------------| * |Contro|VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | * |-----------------------------------------------------------| - * |Shift | | | | | | +| -|End|PgD|Dow|Shift |Fn1| + * |Shift | | | | | | +| -|End|PgD|Dow|Shift | | * `-----------------------------------------------------------' * |Gui |Alt |Space |Alt |Gui| * `--------------------------------------------' */ KEYMAP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ - CAPS,NO, NO, NO, NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, NO, BSPC, \ - LCTL,VOLD,VOLU,MUTE,NO, NO, PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \ - LSFT,NO, NO, NO, NO, NO, PPLS,PMNS,END, PGDN,DOWN,RSFT,FN0, \ + CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, TRNS,BSPC, \ + LCTL,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \ + LSFT,TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN,RSFT,TRNS, \ LGUI,LALT, SPC, RALT,RGUI), - /* Layer 2: Mouse mode (Semicolon) + /* Overlay 1: Mouse mode (Semicolon) * ,-----------------------------------------------------------. * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| * |-----------------------------------------------------------| * |Tab | | | | | |MwL|MwD|MwU|MwR| | | |Backs| * |-----------------------------------------------------------| - * |Contro| | | | | |McL|McD|McU|McR|Fn0| |Return | + * |Contro| | | | | |McL|McD|McU|McR| | |Return | * |-----------------------------------------------------------| * |Shift | | | | |Mb3|Mb2|Mb1|Mb4|Mb5| |Shift | | * `-----------------------------------------------------------' - * |Gui |Alt |Mb1 |Alt |Fn0| + * |Gui |Alt |Mb1 |Alt | | * `--------------------------------------------' * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel */ KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ - TAB, NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, BSPC, \ - LCTL,NO, ACL0,ACL1,ACL2,NO, MS_L,MS_D,MS_U,MS_R,FN0, QUOT,ENT, \ - LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,BTN4,BTN5,SLSH,RSFT,NO, \ - LGUI,LALT, BTN1, RALT,FN0), + TAB, TRNS,TRNS,TRNS,TRNS,TRNS,WH_L,WH_D,WH_U,WH_R,TRNS,TRNS,TRNS,BSPC, \ + LCTL,TRNS,ACL0,ACL1,ACL2,TRNS,MS_L,MS_D,MS_U,MS_R,TRNS,QUOT,ENT, \ + LSFT,TRNS,TRNS,TRNS,TRNS,BTN3,BTN2,BTN1,BTN4,BTN5,SLSH,RSFT,TRNS, \ + LGUI,LALT, BTN1, RALT,TRNS), }; static const uint16_t PROGMEM fn_actions[] = { - ACTION_LAYER_DEFAULT, // FN0 - ACTION_LAYER_SET(1), // FN1 - ACTION_LAYER_SET_TAP_KEY(2, KC_SCLN), // FN2 - ACTION_LAYER_BIT_TOGGLE(2), // FN3 + ACTION_OVERLAY(0), // FN0 + ACTION_OVERLAY_TAP_KEY(1, KC_SCLN), // FN1 + ACTION_OVERLAY_TOGGLE(1), // FN2 }; @@ -303,21 +310,21 @@ There are 8 modifiers which has discrimination between left and right. - `KC_LALT` and `KC_RALT` for Alt - `KC_LGUI` and `KC_RGUI` for Windows key or Command key in Mac -#### 1.3 Fn key -`KC_FNnn` are `Fn` keys which not given any action at the beginning unlike most of keycodes has its own action. To use these keys in `KEYMAP` you need to assign action you want at first. Action of `Fn` is defined in `fn_actions[]` and index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` designates action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** - -#### 1.4 Mousekey +#### 1.3 Mousekey - `KC_MS_U`, `KC_MS_D`, `KC_MS_L`, `KC_MS_R` for mouse cursor - `KC_WH_U`, `KC_WH_D`, `KC_WH_L`, `KC_WH_R` for mouse wheel - `KC_BTN1`, `KC_BTN2`, `KC_BTN3`, `KC_BTN4`, `KC_BTN5` for mouse buttons -#### 1.5 System & Media key +#### 1.4 System & Media key - `KC_PWR`, `KC_SLEP`, `KC_WAKE` for Power, Sleep, Wake - `KC_MUTE`, `KC_VOLU`, `KC_VOLD` for audio volume control - `KC_MNXT`, `KC_MPRV`, `KC_MSTP`, `KC_MPLY`, `KC_MSEL` for media control - `KC_MAIL`, `KC_CALC`, `KC_MYCM` for application launch - `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 `Fn` keys which not given any action at the beginning unlike most of keycodes has its own action. To use these keys in `KEYMAP` you need to assign action you want at first. Action of `Fn` is defined in `fn_actions[]` and index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` designates action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** + #### Keycode Table See [keycode table](doc/keycode.txt) in `doc/keycode.txt` or `common/keycode.h` for the detail or other keycodes. @@ -329,16 +336,23 @@ There are 8 modifiers which has discrimination between left and right. ### 2. Action See `common/action.h`. Action is a 16bit code and defines function to perform on events of a key like press, release, hold and tap. You can define various actions to use various action codes. -Most of keys just register 8bit keycode as HID usage(or scan code) to host, but to support other complex features needs 16bit extended action codes internally. But using 16bit action codes in keymap results in double size in memory against keycodes. To avoid this waste 8bit keycodes are used in `KEYMAP` to define instead of action codes. ***Keycodes can be considered as subset of action codes.*** Like `KC_A`(0x04) is equal to a `Key` action(0x0004) that transmit keycode of *'A'*. +Most of keys just register 8bit keycodes(HID usage) to host, while to support other complex features needs 16bit extended action codes internally. But using 16bit action codes in keymap results in double size in memory against keycodes. To avoid this waste 8bit keycodes are used in `KEYMAP` to define instead of action codes. + +You can just use keycodes of `Normal key`, `Modifier`, `Mousekey` and `System & Media key` in keymap to indicate corresponding actions, instead of action code itself. In the end you can map most of keys just with 8bit keycodes. + +To use other special actions you should use `Fn key` keycode defined with such action yourself. + #### 2.1 Key action -Key is simple action that registers keycode on press of key and unregister on release. +Key is simple action that registers keycode on press event of key and unregister on release. + +##### 2.1.1 Normal key and Modifier You can define `Key` action on *'A'* key with: ACTION_KEY(KC_A) + ACTION_KEY(KC_LSHIFT) -But you don't need to use this expression directly because you can just put symbol `A` in `KEYMAP` definition. - +***** 2.1.2 Key with modifiers Say you want to assign a key to `Shift + 1` to get charactor *'!'* or `Alt + Tab` to switch windows. ACTION_MOD_KEY(KC_LSHIFT, KC_1) @@ -351,31 +365,38 @@ Or `Alt,Shift + Tab` can be defined. These actions are comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes. #### 2.2 Layer Actions + +##### 2.2.0 Return to Default Layer This sets `default layer` into `current layer`. With this action you can return to `default layer`. +with clear other layers. - ACTION_LAYER_DEFAULT + ACTION_DEFAULT_LAYER -`Layer Set` action sets given layer argument to `current layer`. `Layer Set` action can take 0 to 15 as argument. +##### 2.2.1 Keymap +`Keymap` action validate given layer which ranges from 0 to 15. - ACTION_LAYER_SET(layer) - ACTION_LAYER_SET_TOGGLE(layer) - ACTION_LAYER_SET_TAP_KEY(layer, key) - ACTION_LAYER_SET_TAP_TOGGLE(layer) + ACTION_KEYMAP_MOMENTARY(layer) + ACTION_KEYMAP_TOGGLE(layer) + ACTION_KEYMAP_TAP_KEY(layer, key) + ACTION_KEYMAP_TAP_TOGGLE(layer) -`Layer Bit` action XOR given bits with `current layer`. `Layer Bit` action can take 0 to 15 as argument. +##### 2.2.2 Overlay +`Overlay` action validate - ACTION_LAYER_BIT(bits) - ACTION_LAYER_BIT_TOGGLE(bits) - ACTION_LAYER_BIT_TAP_KEY(bits, key) - ACTION_LAYER_BIT_TAP_TOGGLE(bits) + ACTION_KEYMAP_MOMENTARY(layer) + ACTION_KEYMAP_TOGGLE(layer) + ACTION_KEYMAP_TAP_KEY(layer, key) + ACTION_KEYMAP_TAP_TOGGLE(layer) -These acitons change `default layer`. - ACTION_LAYER_SET_DEFAULT(layer) - ACTION_LAYER_BIT_DEFAULT(bits) +##### 2.2.3 Set Default layer +These acitons change `default layer` to given layer. + + ACTION_SET_DEFAULT_LAYER(layer) #### 2.3 Macro action -***NOT FIXED*** +***TBD*** + `Macro` action indicates complex key strokes. MACRO( MD(LSHIFT), D(D), END ) @@ -399,7 +420,8 @@ See `keyboard/hhkb/keymap.c` for sample. #### 2.4 Function action -***NOT FIXED*** +***TBD*** + There are two type of action, normal `Function` and tappable `Function`. These actions call user defined function with `id`, `opt`, and key event information as arguments. @@ -446,9 +468,11 @@ See `keyboard/hhkb/keymap.c` for sample. ### 3. Layer - Layer is key-action map to assign action to every physical key. You can define multiple layers in keymap and select a layer out of keymap during operation at will. + Layer is key-action map to assign action to every physical key. You can define multiple layers in keymap and make layers active out of keymap during operation at will. - First layer is indexed by `Layer 0` which usually become **`default layer`** and active in initial state. **`current layer`** is active layer at that time and can be changed with user interaction. You can define **16 layers** at most in default keymap framework. + First layer is indexed by `0` which usually become **`default layer`** and active in initial state. + +You can define **16 layers** at most in each keymaps[] and overlays[]. you can define a layer with placing keycode symbols separated with `comma` in `KEYMAP`, which is formed with resemblance to physical keyboard layout so as you can easily put keycode on place you want to map. ***You can define most of keys with just using keycodes*** except for `Fn` key serving special actions. @@ -462,9 +486,10 @@ There are two kind of layer switch action `Layer Set` and `Layer Bit` and two ty Momentary switching changes layer only while holding Fn key. ##### 4.1.1 Momentary Set -This `Layer Set` action sets new layer `Layer 1` to `current layer` on key press event. +This action makes `Layer 1` active on key press event and inactive on release event.. + + ACTION_KEYMAP_MOMENTARY(1) - ACTION_LAYER_SET(1) It switches to destination layer immediately when key is pressed, after that actions on keymap of destination layer is perfomed. ***Thus you shall need to place action to come back on destination layer***, or you will be stuck in destination layer without way to get back. To get back to `default layer` you can use this action. diff --git a/common/action.h b/common/action.h index 611490eb..4892cc7f 100644 --- a/common/action.h +++ b/common/action.h @@ -161,13 +161,13 @@ bool waiting_buffer_has_anykey_pressed(void); * 1000|LLLL|0000 00xx Reset default layer and clear keymap and overlay * 1000|LLLL| keycode Invert with tap key * 1000|LLLL|1111 0000 Invert with tap toggle - * 1000|LLLL|1111 00xx Invert[^= L] + * 1000|LLLL|1111 00xx Invert[^= 1< Date: Sat, 23 Feb 2013 14:32:34 +0900 Subject: [PATCH 15/25] Fix debug code of serial_soft.c --- protocol/serial_soft.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c index af5110b4..3c9c914e 100644 --- a/protocol/serial_soft.c +++ b/protocol/serial_soft.c @@ -48,8 +48,20 @@ POSSIBILITY OF SUCH DAMAGE. #define WAIT_US (1000000/SERIAL_BAUD) +/* debug for signal timing, see debug pin with oscilloscope */ +#ifdef SERIAL_SOFT_DEBUG + #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7) + #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7) +#else + #define SERIAL_SOFT_DEBUG_INIT() + #define SERIAL_SOFT_DEBUG_TGL() +#endif + + void serial_init(void) { + SERIAL_SOFT_DEBUG_INIT(); + SERIAL_RXD_INIT(); SERIAL_TXD_INIT(); } @@ -116,7 +128,7 @@ void serial_send(uint8_t data) /* detect edge of start bit */ ISR(SERIAL_RXD_VECT) { -PORTD ^= 1<<7; + SERIAL_SOFT_DEBUG_TGL() SERIAL_RXD_INT_ENTER() uint8_t data = 0; @@ -129,21 +141,23 @@ PORTD ^= 1<<7; #ifdef SERIAL_PARITY_ODD uint8_t parity = 0; -#else +#elif defined(SERIAL_PARITY_EVEN) uint8_t parity = 1; #endif /* to center of start bit */ _delay_us(WAIT_US/2); -PORTD ^= 1<<7; + SERIAL_SOFT_DEBUG_TGL() do { /* to center of next bit */ _delay_us(WAIT_US); -PORTD ^= 1<<7; + SERIAL_SOFT_DEBUG_TGL() if (SERIAL_RXD_READ()) { data |= mask; +#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) parity ^= 1; +#endif } #ifdef SERIAL_BIT_ORDER_MSB mask >>= 1; @@ -152,20 +166,26 @@ PORTD ^= 1<<7; #endif } while (mask); +#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) /* to center of parity bit */ _delay_us(WAIT_US); if (SERIAL_RXD_READ()) { parity ^= 1; } -PORTD ^= 1<<7; + SERIAL_SOFT_DEBUG_TGL() +#endif /* to center of stop bit */ _delay_us(WAIT_US); uint8_t next = (rbuf_head + 1) % RBUF_SIZE; +#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) if (parity && next != rbuf_tail) { +#else + if (next != rbuf_tail) { +#endif rbuf[rbuf_head] = data; rbuf_head = next; } SERIAL_RXD_INT_EXIT(); -PORTD ^= 1<<7; + SERIAL_SOFT_DEBUG_TGL() } From 025c2ba31254820d4ccbe4f5b6e5f452508aef5b Mon Sep 17 00:00:00 2001 From: tmk Date: Mon, 25 Feb 2013 01:02:14 +0900 Subject: [PATCH 16/25] Add parity option in serial_soft.c --- protocol/serial_soft.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c index 3c9c914e..c906c664 100644 --- a/protocol/serial_soft.c +++ b/protocol/serial_soft.c @@ -46,7 +46,7 @@ POSSIBILITY OF SUCH DAMAGE. * is still useful for negative logic signal like Sun protocol not supported by hardware USART. */ -#define WAIT_US (1000000/SERIAL_BAUD) +#define WAIT_US (1000000L/SERIAL_BAUD) /* debug for signal timing, see debug pin with oscilloscope */ #ifdef SERIAL_SOFT_DEBUG @@ -100,18 +100,33 @@ int16_t serial_recv2(void) void serial_send(uint8_t data) { /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */ - /* start bit */ - SERIAL_TXD_OFF(); - _delay_us(WAIT_US); #ifdef SERIAL_BIT_ORDER_MSB uint8_t mask = 0x80; #else uint8_t mask = 0x01; #endif + +#ifdef SERIAL_PARITY_ODD + uint8_t parity = 1; +#elif defined(SERIAL_PARITY_EVEN) + uint8_t parity = 0; +#endif + + /* start bit */ + SERIAL_TXD_OFF(); + _delay_us(WAIT_US-2); + while (mask) { - if (data&mask) { SERIAL_TXD_ON(); } else { SERIAL_TXD_OFF(); } - _delay_us(WAIT_US); + if (data&mask) { + SERIAL_TXD_ON(); +#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) + parity ^= 1; +#endif + } else { + SERIAL_TXD_OFF(); + } + _delay_us(WAIT_US-2); #ifdef SERIAL_BIT_ORDER_MSB mask >>= 1; @@ -120,9 +135,19 @@ void serial_send(uint8_t data) #endif } +#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) + /* to center of parity bit */ + if (parity) { + SERIAL_TXD_ON(); + } else { + SERIAL_TXD_OFF(); + } + _delay_us(WAIT_US-2); +#endif + /* stop bit */ SERIAL_TXD_ON(); - _delay_us(WAIT_US); + _delay_us(WAIT_US-2); } /* detect edge of start bit */ From be3dd3c3729e2ac3d16f6293846ef29c13fc6fc5 Mon Sep 17 00:00:00 2001 From: tmk Date: Mon, 25 Feb 2013 03:09:10 +0900 Subject: [PATCH 17/25] Add serial_uart.c and use it for PC98 --- protocol/serial_uart.c | 93 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 protocol/serial_uart.c diff --git a/protocol/serial_uart.c b/protocol/serial_uart.c new file mode 100644 index 00000000..6c0af881 --- /dev/null +++ b/protocol/serial_uart.c @@ -0,0 +1,93 @@ +/* +Copyright 2013 Jun WAKO + +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. +*/ + +#include +#include +#include +#include "serial.h" + + +void serial_init(void) +{ + SERIAL_UART_INIT(); +} + +// RX ring buffer +#define RBUF_SIZE 8 +static uint8_t rbuf[RBUF_SIZE]; +static uint8_t rbuf_head = 0; +static uint8_t rbuf_tail = 0; + +uint8_t serial_recv(void) +{ + uint8_t data = 0; + if (rbuf_head == rbuf_tail) { + return 0; + } + + data = rbuf[rbuf_tail]; + rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; + return data; +} + +int16_t serial_recv2(void) +{ + uint8_t data = 0; + if (rbuf_head == rbuf_tail) { + return -1; + } + + data = rbuf[rbuf_tail]; + rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; + return data; +} + +void serial_send(uint8_t data) +{ + while (!SERIAL_UART_TXD_READY) ; + SERIAL_UART_DATA = data; +} + +// USART RX complete interrupt +ISR(SERIAL_UART_RXD_VECT) +{ + uint8_t next = (rbuf_head + 1) % RBUF_SIZE; + if (next != rbuf_tail) { + rbuf[rbuf_head] = SERIAL_UART_DATA; + rbuf_head = next; + } +} From 1e829faed06df03f3d04a9a1caa1c6b2df83e90a Mon Sep 17 00:00:00 2001 From: tmk Date: Mon, 25 Feb 2013 08:40:15 +0900 Subject: [PATCH 18/25] Fix software serial configure --- protocol/serial_soft.c | 98 +++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c index c906c664..e8870bcd 100644 --- a/protocol/serial_soft.c +++ b/protocol/serial_soft.c @@ -43,12 +43,32 @@ POSSIBILITY OF SUCH DAMAGE. /* * Stupid Inefficient Busy-wait Software Serial - * is still useful for negative logic signal like Sun protocol not supported by hardware USART. + * which is still useful for negative logic signal like Sun protocol + * if it is not supported by hardware UART. + * + * TODO: delay is not accurate enough. Instruction cycle should be counted and inline assemby is needed. */ -#define WAIT_US (1000000L/SERIAL_BAUD) +#define WAIT_US (1000000L/SERIAL_SOFT_BAUD) + +#ifdef SERIAL_SOFT_LOGIC_NEGATIVE + #define SERIAL_SOFT_RXD_IN() !(SERIAL_SOFT_RXD_READ()) + #define SERIAL_SOFT_TXD_ON() SERIAL_SOFT_TXD_LO() + #define SERIAL_SOFT_TXD_OFF() SERIAL_SOFT_TXD_HI() +#else + #define SERIAL_SOFT_RXD_IN() !!(SERIAL_SOFT_RXD_READ()) + #define SERIAL_SOFT_TXD_ON() SERIAL_SOFT_TXD_HI() + #define SERIAL_SOFT_TXD_OFF() SERIAL_SOFT_TXD_LO() +#endif + +#ifdef SERIAL_SOFT_PARITY_EVEN + #define SERIAL_SOFT_PARITY_VAL 0 +#elif defined(SERIAL_SOFT_PARITY_ODD) + #define SERIAL_SOFT_PARITY_VAL 1 +#endif /* debug for signal timing, see debug pin with oscilloscope */ +#define SERIAL_SOFT_DEBUG #ifdef SERIAL_SOFT_DEBUG #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7) #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7) @@ -62,8 +82,8 @@ void serial_init(void) { SERIAL_SOFT_DEBUG_INIT(); - SERIAL_RXD_INIT(); - SERIAL_TXD_INIT(); + SERIAL_SOFT_RXD_INIT(); + SERIAL_SOFT_TXD_INIT(); } /* RX ring buffer */ @@ -101,109 +121,97 @@ void serial_send(uint8_t data) { /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */ -#ifdef SERIAL_BIT_ORDER_MSB +#ifdef SERIAL_SOFT_BIT_ORDER_MSB uint8_t mask = 0x80; #else uint8_t mask = 0x01; #endif -#ifdef SERIAL_PARITY_ODD - uint8_t parity = 1; -#elif defined(SERIAL_PARITY_EVEN) uint8_t parity = 0; -#endif /* start bit */ - SERIAL_TXD_OFF(); - _delay_us(WAIT_US-2); + SERIAL_SOFT_TXD_OFF(); + _delay_us(WAIT_US); while (mask) { if (data&mask) { - SERIAL_TXD_ON(); -#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) + SERIAL_SOFT_TXD_ON(); parity ^= 1; -#endif } else { - SERIAL_TXD_OFF(); + SERIAL_SOFT_TXD_OFF(); } - _delay_us(WAIT_US-2); + _delay_us(WAIT_US); -#ifdef SERIAL_BIT_ORDER_MSB +#ifdef SERIAL_SOFT_BIT_ORDER_MSB mask >>= 1; #else mask <<= 1; #endif } -#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) +#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) /* to center of parity bit */ - if (parity) { - SERIAL_TXD_ON(); + if (parity != SERIAL_SOFT_PARITY_VAL) { + SERIAL_SOFT_TXD_ON(); } else { - SERIAL_TXD_OFF(); + SERIAL_SOFT_TXD_OFF(); } - _delay_us(WAIT_US-2); + _delay_us(WAIT_US); #endif /* stop bit */ - SERIAL_TXD_ON(); - _delay_us(WAIT_US-2); + SERIAL_SOFT_TXD_ON(); + _delay_us(WAIT_US); } /* detect edge of start bit */ -ISR(SERIAL_RXD_VECT) +ISR(SERIAL_SOFT_RXD_VECT) { - SERIAL_SOFT_DEBUG_TGL() - SERIAL_RXD_INT_ENTER() + SERIAL_SOFT_DEBUG_TGL(); + SERIAL_SOFT_RXD_INT_ENTER() uint8_t data = 0; -#ifdef SERIAL_BIT_ORDER_MSB +#ifdef SERIAL_SOFT_BIT_ORDER_MSB uint8_t mask = 0x80; #else uint8_t mask = 0x01; #endif -#ifdef SERIAL_PARITY_ODD uint8_t parity = 0; -#elif defined(SERIAL_PARITY_EVEN) - uint8_t parity = 1; -#endif /* to center of start bit */ _delay_us(WAIT_US/2); - SERIAL_SOFT_DEBUG_TGL() + SERIAL_SOFT_DEBUG_TGL(); do { /* to center of next bit */ _delay_us(WAIT_US); - SERIAL_SOFT_DEBUG_TGL() - if (SERIAL_RXD_READ()) { + SERIAL_SOFT_DEBUG_TGL(); + if (SERIAL_SOFT_RXD_IN()) { data |= mask; -#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) parity ^= 1; -#endif } -#ifdef SERIAL_BIT_ORDER_MSB +#ifdef SERIAL_SOFT_BIT_ORDER_MSB mask >>= 1; #else mask <<= 1; #endif } while (mask); -#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) +#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) /* to center of parity bit */ _delay_us(WAIT_US); - if (SERIAL_RXD_READ()) { parity ^= 1; } - SERIAL_SOFT_DEBUG_TGL() + if (SERIAL_SOFT_RXD_IN()) { parity ^= 1; } + SERIAL_SOFT_DEBUG_TGL(); #endif /* to center of stop bit */ _delay_us(WAIT_US); uint8_t next = (rbuf_head + 1) % RBUF_SIZE; -#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) - if (parity && next != rbuf_tail) { +#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) + if ((parity == SERIAL_SOFT_PARITY_VAL) && next != rbuf_tail) { #else if (next != rbuf_tail) { #endif @@ -211,6 +219,6 @@ ISR(SERIAL_RXD_VECT) rbuf_head = next; } - SERIAL_RXD_INT_EXIT(); - SERIAL_SOFT_DEBUG_TGL() + SERIAL_SOFT_RXD_INT_EXIT(); + SERIAL_SOFT_DEBUG_TGL(); } From 664796855b3681403d122faf05de3dd03cf6f245 Mon Sep 17 00:00:00 2001 From: tmk Date: Mon, 25 Feb 2013 15:30:37 +0900 Subject: [PATCH 19/25] Add MACRO action --- common/action.c | 5 +++-- common/action.h | 52 ++++++++++++++++++++++--------------------- common/action_macro.h | 4 ++++ common/keymap.c | 8 ++++--- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/common/action.c b/common/action.c index 294ce00f..fc881803 100644 --- a/common/action.c +++ b/common/action.c @@ -23,8 +23,9 @@ along with this program. If not, see . #include "command.h" #include "util.h" #include "debug.h" -#include "action.h" #include "layer_switch.h" +#include "action_macro.h" +#include "action.h" static void process_action(keyrecord_t *record); @@ -671,7 +672,7 @@ static void process_action(keyrecord_t *record) /* Extentions */ case ACT_MACRO: - // TODO + action_macro_play(action_get_macro(record, action.func.id, action.func.opt)); break; case ACT_COMMAND: break; diff --git a/common/action.h b/common/action.h index 4892cc7f..9dea4b0a 100644 --- a/common/action.h +++ b/common/action.h @@ -19,6 +19,7 @@ along with this program. If not, see . #include "keyboard.h" #include "keycode.h" +#include "action_macro.h" /* Struct to record event and tap count */ @@ -82,6 +83,9 @@ void action_exec(keyevent_t event); /* action for key */ action_t action_for_key(uint8_t layer, key_t key); +/* macro */ +const prog_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); @@ -107,8 +111,8 @@ bool waiting_buffer_has_anykey_pressed(void); * ============ * 16bit code: action_kind(4bit) + action_parameter(12bit) * - * Keyboard Keys - * ------------- + * Keyboard Keys(00XX) + * ------------------- * ACT_LMODS(0000): * 0000|0000|000000|00 No action * 0000|0000|000000|01 Transparent @@ -138,8 +142,8 @@ bool waiting_buffer_has_anykey_pressed(void); * 0011|mods| keycode Right mods + tap Key * * - * Other HID Usage - * --------------- + * Other keys(01XX) + * -------------------- * This action handles other usages than keyboard. * ACT_USAGE(0100): * 0100|00| usage(10) System control(0x80) - General Desktop page(0x01) @@ -147,15 +151,12 @@ bool waiting_buffer_has_anykey_pressed(void); * 0100|10| usage(10) (reserved) * 0100|11| usage(10) (reserved) * - * - * Mouse Keys - * ---------- * ACT_MOUSEKEY(0110): * 0101|XXXX| keycode Mouse key * * - * Layer Actions - * ------------- + * Layer Actions(10XX) + * ------------------- * ACT_KEYMAP: * 1000|--xx|0000 0000 Clear keyamp and overlay * 1000|LLLL|0000 00xx Reset default layer and clear keymap and overlay @@ -189,8 +190,6 @@ bool waiting_buffer_has_anykey_pressed(void); * * Extensions(11XX) * ---------------- - * NOTE: NOT FIXED - * * ACT_MACRO(1100): * 1100|opt | id(8) Macro play? * 1100|1111| id(8) Macro record? @@ -253,8 +252,20 @@ enum mods_codes { #define ACTION_RMOD_TAP_KEY(mod, key) ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | (key)) #define ACTION_RMOD_ONESHOT(mod) ACTION(ACT_RMODS_TAP, MODS4(MOD_BIT(mod))<<8 | MODS_ONESHOT) +/* HID Usage */ +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)) -/* Layer Operation: +/* Mousekey */ +#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key) + + + +/* Layer Actions: * Invert layer ^= (1<. #include +#define MACRO_NONE 0 +#define MACRO(...) ({ static prog_macro_t _m[] PROGMEM = { __VA_ARGS__ }; _m; }) + + typedef uint8_t macro_t; typedef macro_t prog_macro_t PROGMEM; diff --git a/common/keymap.c b/common/keymap.c index ddc32105..f72be577 100644 --- a/common/keymap.c +++ b/common/keymap.c @@ -20,6 +20,7 @@ along with this program. If not, see . #include "keycode.h" #include "layer_switch.h" #include "action.h" +#include "action_macro.h" #include "debug.h" @@ -39,9 +40,10 @@ action_t action_for_key(uint8_t layer, key_t key) } __attribute__ ((weak)) -void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) -{ -} +const prog_macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { return MACRO_NONE; } + +__attribute__ ((weak)) +void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {} #else /* * legacy keymap support From 71bd9a72fbf67aa9893cdc7f0a40ccff1d7ca9eb Mon Sep 17 00:00:00 2001 From: tmk Date: Tue, 26 Feb 2013 16:27:09 +0900 Subject: [PATCH 20/25] Add tap flags on record_t --- common/action.c | 46 +++++++++++++++++++++++-------------------- common/action.h | 18 ++++++++++++++--- common/action_macro.c | 1 - 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/common/action.c b/common/action.c index fc881803..7f3e236f 100644 --- a/common/action.c +++ b/common/action.c @@ -206,7 +206,7 @@ void action_exec(keyevent_t event) static void process_action(keyrecord_t *record) { keyevent_t event = record->event; - uint8_t tap_count = record->tap_count; + uint8_t tap_count = record->tap.count; if (IS_NOEVENT(event)) { return; } @@ -295,7 +295,7 @@ static void process_action(keyrecord_t *record) if (waiting_buffer_has_anykey_pressed()) { debug("MODS_TAP: Tap: Cancel: add_mods\n"); // ad hoc: set 0 to cancel tap - record->tap_count = 0; + record->tap.count = 0; add_mods(mods); } else { debug("MODS_TAP: Tap: register_code\n"); @@ -697,16 +697,17 @@ static bool process_tapping(keyrecord_t *keyp) // if tapping if (IS_TAPPING_PRESSED()) { if (WITHIN_TAPPING_TERM(event)) { - if (tapping_key.tap_count == 0) { + 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; + tapping_key.tap.count = 1; + tapping_key.tap.interrupted = (waiting_buffer_has_anykey_pressed() ? true : false); debug_tapping_key(); process_action(&tapping_key); // enqueue - keyp->tap_count = tapping_key.tap_count; + keyp->tap = tapping_key.tap; return false; } #if TAPPING_TERM >= 500 @@ -730,19 +731,19 @@ static bool process_tapping(keyrecord_t *keyp) // 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_count = tapping_key.tap_count; + 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(keyp->event.key) && event.pressed) { - if (tapping_key.tap_count > 1) { + if (tapping_key.tap.count > 1) { debug("Tapping: Start new tap with releasing last tap(>1).\n"); // unregister key process_action(&(keyrecord_t){ - .tap_count = tapping_key.tap_count, + .tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false @@ -766,7 +767,7 @@ static bool process_tapping(keyrecord_t *keyp) } // after TAPPING_TERM else { - if (tapping_key.tap_count == 0) { + if (tapping_key.tap.count == 0) { debug("Tapping: End. Timeout. Not tap(0): "); debug_event(event); debug("\n"); process_action(&tapping_key); @@ -776,17 +777,17 @@ static bool process_tapping(keyrecord_t *keyp) } else { if (IS_TAPPING_KEY(event.key) && !event.pressed) { debug("Tapping: End. last timeout tap release(>0)."); - keyp->tap_count = tapping_key.tap_count; + keyp->tap = tapping_key.tap; process_action(keyp); tapping_key = (keyrecord_t){}; return true; } else if (is_tap_key(keyp->event.key) && event.pressed) { - if (tapping_key.tap_count > 1) { + 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_count = tapping_key.tap_count, + .tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false @@ -810,10 +811,11 @@ static bool process_tapping(keyrecord_t *keyp) } } else if (IS_TAPPING_RELEASED()) { if (WITHIN_TAPPING_TERM(event)) { - if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) { + if (tapping_key.tap.count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) { // sequential tap. - keyp->tap_count = tapping_key.tap_count + 1; - debug("Tapping: Tap press("); debug_dec(keyp->tap_count); debug(")\n"); + keyp->tap = tapping_key.tap; + keyp->tap.count += 1; + debug("Tapping: Tap press("); debug_dec(keyp->tap.count); debug(")\n"); process_action(keyp); tapping_key = *keyp; debug_tapping_key(); @@ -858,16 +860,16 @@ static bool process_tapping(keyrecord_t *keyp) static 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.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; + 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"); @@ -987,6 +989,7 @@ bool is_tap_key(key_t key) default: return false; } + case ACT_MACRO: case ACT_FUNCTION: if (action.func.opt & FUNC_TAP) { return true; } return false; @@ -1006,7 +1009,8 @@ static void debug_event(keyevent_t event) } static void debug_record(keyrecord_t record) { - debug_event(record.event); debug(":"); debug_dec(record.tap_count); + debug_event(record.event); debug(":"); debug_dec(record.tap.count); + if (record.tap.interrupted) debug("-"); } static void debug_action(action_t action) { diff --git a/common/action.h b/common/action.h index 9dea4b0a..39e0ae32 100644 --- a/common/action.h +++ b/common/action.h @@ -23,9 +23,19 @@ along with this program. If not, see . /* Struct to record event and tap count */ +typedef union { + struct { + bool interrupted :1; + bool reserved2 :1; + bool reserved1 :1; + bool reserved0 :1; + uint8_t count :4; + }; +} tap_t; + typedef struct { keyevent_t event; - uint8_t tap_count; + tap_t tap; } keyrecord_t; /* Action struct. @@ -377,6 +387,7 @@ enum layer_params { */ /* 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)) /* Command */ @@ -386,7 +397,8 @@ enum layer_params { enum function_opts { FUNC_TAP = 0x8, /* indciates function is tappable */ }; -#define ACTION_FUNCTION(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | id) -#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | id) +#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_H */ diff --git a/common/action_macro.c b/common/action_macro.c index 72859c0d..ca7ffa82 100644 --- a/common/action_macro.c +++ b/common/action_macro.c @@ -41,7 +41,6 @@ void action_macro_play(const prog_macro_t *macro_p) case MODS_DOWN: MACRO_READ(); debug("MODS_DOWN("); debug_hex(macro); debug(")\n"); - debug("MODS_UP("); debug_hex(macro); debug(")\n"); add_mods(macro); break; case MODS_UP: From d193a6d2efde78b957adbcde65392c9db75a46b3 Mon Sep 17 00:00:00 2001 From: tmk Date: Wed, 27 Feb 2013 10:32:46 +0900 Subject: [PATCH 21/25] Fix SET_DEFAULT_LAYER action and keymap of gh60 --- README.md | 2 +- common/action.c | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index d4fee96c..7ceffce7 100644 --- a/README.md +++ b/README.md @@ -470,7 +470,7 @@ See `keyboard/hhkb/keymap.c` for sample. ### 3. Layer Layer is key-action map to assign action to every physical key. You can define multiple layers in keymap and make layers active out of keymap during operation at will. - First layer is indexed by `0` which usually become **`default layer`** and active in initial state. + First layer is indexed by `0` which usually become `default layer` and active in initial state. You can define **16 layers** at most in each keymaps[] and overlays[]. diff --git a/common/action.c b/common/action.c index 7f3e236f..7ca481fb 100644 --- a/common/action.c +++ b/common/action.c @@ -384,21 +384,15 @@ static void process_action(keyrecord_t *record) /* Keymap Reset default layer */ case (OP_RESET | ON_PRESS): if (event.pressed) { - overlay_clear(); - keymap_clear(); default_layer_set(action.layer.val); } break; case (OP_RESET | ON_RELEASE): if (!event.pressed) { - overlay_clear(); - keymap_clear(); default_layer_set(action.layer.val); } break; case (OP_RESET | ON_BOTH): - overlay_clear(); - keymap_clear(); default_layer_set(action.layer.val); break; From 792a794fde6606badf7ece8be8da3fce5d85e543 Mon Sep 17 00:00:00 2001 From: tmk Date: Mon, 4 Mar 2013 16:37:19 +0900 Subject: [PATCH 22/25] Create keymap.md --- README.md | 359 +-------------------------------- common/action.h | 4 + doc/keymap.md | 522 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 532 insertions(+), 353 deletions(-) create mode 100644 doc/keymap.md diff --git a/README.md b/README.md index 7ceffce7..14d55ea3 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,10 @@ Features Projects -------- +You can find some keyboard specific projects under `converter` and `keyboard` directory. + ### converter -* ps2_usb - [PS/2 keyboard to USB][GH_ps2] +* [ps2_usb](converter/ps2_usb/) - [PS/2 keyboard to USB][GH_ps2] * adb_usb - [ADB keyboard to USB][GH_adb] * m0110_usb - [Machintosh 128K/512K/Plus keyboard to USB][GH_m0110] * terminal_usb - [IBM Model M terminal keyboard(PS/2 scancode set3) to USB][GH_terminal] @@ -203,359 +205,10 @@ Config.h Options #define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT))) -Keymap ------- -Many of existent projects offer keymap framework to define your own keymap easily. The following will explain how you can define keymap using this framework. - Instead, you can also implement your own `keymap_get_action()` to return action code for each key if you want. +Change your keymap +------------------ +[keymap.md](doc/keymap.md) -This is keymap example for [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard. Keymap is defined in `keymaps[]` array. - - static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* Keymap 0: Default Layer - * ,-----------------------------------------------------------. - * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| - * |-----------------------------------------------------------| - * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Backs| - * |-----------------------------------------------------------| - * |Contro| A| S| D| F| G| H| J| K| L|Fn1| '|Enter | - * |-----------------------------------------------------------| - * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn0| - * `-----------------------------------------------------------' - * |Gui|Alt |Space |Alt |Fn2| - * `-------------------------------------------' - */ - KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \ - TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \ - LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT,ENT, \ - LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT,FN0, \ - LGUI,LALT, SPC, RALT,FN3), - /* Keymap 1: colemak */ - KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \ - TAB, Q, W, F, P, G, J, L, U, Y, SCLN,LBRC,RBRC,BSPC, \ - BSPC,A, R, S, T, D, H, N, E, I, O, QUOT,ENT, \ - LSFT,Z, X, C, V, B, K, M, COMM,DOT, SLSH,RSFT,FN0, \ - LGUI,LALT, SPC, RALT,FN2), - }; - - static const uint8_t PROGMEM overlays[][MATRIX_ROWS][MATRIX_COLS] = { - /* Overlay 0: HHKB mode (HHKB Fn) - * ,-----------------------------------------------------------. - * |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| - * |-----------------------------------------------------------| - * |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| - * |-----------------------------------------------------------| - * |Contro|VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | - * |-----------------------------------------------------------| - * |Shift | | | | | | +| -|End|PgD|Dow|Shift | | - * `-----------------------------------------------------------' - * |Gui |Alt |Space |Alt |Gui| - * `--------------------------------------------' - */ - KEYMAP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ - CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, TRNS,BSPC, \ - LCTL,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \ - LSFT,TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN,RSFT,TRNS, \ - LGUI,LALT, SPC, RALT,RGUI), - /* Overlay 1: Mouse mode (Semicolon) - * ,-----------------------------------------------------------. - * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| - * |-----------------------------------------------------------| - * |Tab | | | | | |MwL|MwD|MwU|MwR| | | |Backs| - * |-----------------------------------------------------------| - * |Contro| | | | | |McL|McD|McU|McR| | |Return | - * |-----------------------------------------------------------| - * |Shift | | | | |Mb3|Mb2|Mb1|Mb4|Mb5| |Shift | | - * `-----------------------------------------------------------' - * |Gui |Alt |Mb1 |Alt | | - * `--------------------------------------------' - * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel - */ - KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ - TAB, TRNS,TRNS,TRNS,TRNS,TRNS,WH_L,WH_D,WH_U,WH_R,TRNS,TRNS,TRNS,BSPC, \ - LCTL,TRNS,ACL0,ACL1,ACL2,TRNS,MS_L,MS_D,MS_U,MS_R,TRNS,QUOT,ENT, \ - LSFT,TRNS,TRNS,TRNS,TRNS,BTN3,BTN2,BTN1,BTN4,BTN5,SLSH,RSFT,TRNS, \ - LGUI,LALT, BTN1, RALT,TRNS), - }; - - static const uint16_t PROGMEM fn_actions[] = { - ACTION_OVERLAY(0), // FN0 - ACTION_OVERLAY_TAP_KEY(1, KC_SCLN), // FN1 - ACTION_OVERLAY_TOGGLE(1), // FN2 - }; - - - -### 1. Keycode -See `common/keycode.h`. Keycode is 8bit internal code to inidicate action performed on key in keymap. Keycode has `KC_` prefixed symbol respectively. Most of keycodes like `KC_A` have simple action register key on press and unregister on release, on the other some of keycodes has some special actions like Fn keys, Media contorl keys, System control keys and Mouse keys. - - ***In `KEYMAP` definition you need to omit prefix part `KC_` of keycode to keep keymap compact.*** For example, just use `A` instead you place `KC_A` in `KEYMAP`. Some keycodes has 4-letter short name in addition to descriptive name, you'll prefer short one in `KEYMAP`. - -#### 1.0 Other key -- `KC_NO` for no aciton -- `KC_TRNS` for transparent layer - -#### 1.1 Normal key -- `KC_A` to `KC_Z`, `KC_1` to `KC_0` for alpha numeric key -- `KC_MINS`, `KC_EQL`, `KC_GRV`, `KC_RBRC`, `KC_LBRC`, `KC_COMM`, `KC_DOT`, `KC_BSLS`, `KC_SLSH`, `KC_SCLN`, `KC_QUOT` -- `KC_ESC`, `KC_TAB`, `KC_SPC`, `KC_BSPC`, `KC_ENT`, `KC_DEL`, `KC_INS` -- `KC_UP`, `KC_DOWN`, `KC_RGHT`, `KC_LEFT`, `KC_PGUP`, `KC_PGDN`, `KC_HOME`, `KC_END` -- `KC_CAPS`, `KC_NLCK`, `KC_SLCK`, `KC_PSCR`, `KC_PAUS`, `KC_APP`, `KC_F1` to `KC_F24` -- `KC_P1` to `KC_P0`, `KC_PDOT`, `KC_PCMM`, `KC_PSLS`, `KC_PAST`, `KC_PMNS`, `KC_PPLS`, `KC_PEQL`, `KC_PENT` for keypad. - -#### 1.2 Modifier -There are 8 modifiers which has discrimination between left and right. - -- `KC_LCTL` and `KC_RCTL` for Control -- `KC_LSFT` and `KC_RSFT` for Shift -- `KC_LALT` and `KC_RALT` for Alt -- `KC_LGUI` and `KC_RGUI` for Windows key or Command key in Mac - -#### 1.3 Mousekey -- `KC_MS_U`, `KC_MS_D`, `KC_MS_L`, `KC_MS_R` for mouse cursor -- `KC_WH_U`, `KC_WH_D`, `KC_WH_L`, `KC_WH_R` for mouse wheel -- `KC_BTN1`, `KC_BTN2`, `KC_BTN3`, `KC_BTN4`, `KC_BTN5` for mouse buttons - -#### 1.4 System & Media key -- `KC_PWR`, `KC_SLEP`, `KC_WAKE` for Power, Sleep, Wake -- `KC_MUTE`, `KC_VOLU`, `KC_VOLD` for audio volume control -- `KC_MNXT`, `KC_MPRV`, `KC_MSTP`, `KC_MPLY`, `KC_MSEL` for media control -- `KC_MAIL`, `KC_CALC`, `KC_MYCM` for application launch -- `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 `Fn` keys which not given any action at the beginning unlike most of keycodes has its own action. To use these keys in `KEYMAP` you need to assign action you want at first. Action of `Fn` is defined in `fn_actions[]` and index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` designates action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** - -#### Keycode Table - See [keycode table](doc/keycode.txt) in `doc/keycode.txt` or `common/keycode.h` for the detail or other keycodes. - - In regard to implementation side most of keycodes are identical with [HID usage] sent to host for real and some virtual keycodes are defined to support special actions. -[HID usage]: http://www.usb.org/developers/devclass_docs/Hut1_11.pdf - - - -### 2. Action -See `common/action.h`. Action is a 16bit code and defines function to perform on events of a key like press, release, hold and tap. You can define various actions to use various action codes. - -Most of keys just register 8bit keycodes(HID usage) to host, while to support other complex features needs 16bit extended action codes internally. But using 16bit action codes in keymap results in double size in memory against keycodes. To avoid this waste 8bit keycodes are used in `KEYMAP` to define instead of action codes. - -You can just use keycodes of `Normal key`, `Modifier`, `Mousekey` and `System & Media key` in keymap to indicate corresponding actions, instead of action code itself. In the end you can map most of keys just with 8bit keycodes. - -To use other special actions you should use `Fn key` keycode defined with such action yourself. - - -#### 2.1 Key action -Key is simple action that registers keycode on press event of key and unregister on release. - -##### 2.1.1 Normal key and Modifier -You can define `Key` action on *'A'* key with: - - ACTION_KEY(KC_A) - ACTION_KEY(KC_LSHIFT) - -***** 2.1.2 Key with modifiers - Say you want to assign a key to `Shift + 1` to get charactor *'!'* or `Alt + Tab` to switch windows. - - ACTION_MOD_KEY(KC_LSHIFT, KC_1) - ACTION_MOD_KEY(KC_LALT, KC_TAB) - -Or `Alt,Shift + Tab` can be defined. - - ACTION_MODS_KEY((MOD_BIT(KC_LALT) | MOD_BIT(KC_LSHIFT)), KC_TAB) - -These actions are comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes. - -#### 2.2 Layer Actions - -##### 2.2.0 Return to Default Layer -This sets `default layer` into `current layer`. With this action you can return to `default layer`. -with clear other layers. - - ACTION_DEFAULT_LAYER - -##### 2.2.1 Keymap -`Keymap` action validate given layer which ranges from 0 to 15. - - ACTION_KEYMAP_MOMENTARY(layer) - ACTION_KEYMAP_TOGGLE(layer) - ACTION_KEYMAP_TAP_KEY(layer, key) - ACTION_KEYMAP_TAP_TOGGLE(layer) - -##### 2.2.2 Overlay -`Overlay` action validate - - ACTION_KEYMAP_MOMENTARY(layer) - ACTION_KEYMAP_TOGGLE(layer) - ACTION_KEYMAP_TAP_KEY(layer, key) - ACTION_KEYMAP_TAP_TOGGLE(layer) - -##### 2.2.3 Set Default layer -These acitons change `default layer` to given layer. - - ACTION_SET_DEFAULT_LAYER(layer) - - -#### 2.3 Macro action -***TBD*** - -`Macro` action indicates complex key strokes. - - MACRO( MD(LSHIFT), D(D), END ) - MACRO( U(D), MU(LSHIFT), END ) - MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ) - -##### 2.3.1 Normal mode -- **I()** change interavl of stroke. -- **D()** press key -- **U()** release key -- **T()** type key(press and release) -- **W()** wait -- **MD()** modifier down -- **MU()** modifier up -- **END** end mark - -##### 2.3.2 Extended mode - -***TODO: sample impl*** -See `keyboard/hhkb/keymap.c` for sample. - - -#### 2.4 Function action -***TBD*** - -There are two type of action, normal `Function` and tappable `Function`. -These actions call user defined function with `id`, `opt`, and key event information as arguments. - -##### 2.4.1 Function -To define normal `Function` action in keymap use this. - - ACTION_FUNCTION(id, opt) - -##### 2.4.2 Function with tap -To define tappable `Function` action in keymap use this. - - ACTION_FUNCTION_TAP(id, opt) - -##### 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) - -This C function is called every time key is operated, argument `id` selects action to be performed and `opt` can be used for option. Functon `id` can be 0-255 and `opt` can be 0-15. - - `keyrecord_t` is comprised of key event and tap count. `keyevent_t` indicates which and when key is pressed or released. From `tap_count` you can know tap state, 0 means no tap. These information will be used in user function to decide how action of key is performed. - - typedef struct { - keyevent_t event; - uint8_t tap_count; - } keyrecord_t; - - typedef struct { - key_t key; - bool pressed; - uint16_t time; - } keyevent_t; - - typedef struct { - uint8_t col; - uint8_t row; - } key_t; - -***TODO: sample impl*** -See `keyboard/hhkb/keymap.c` for sample. - - - - - -### 3. Layer - Layer is key-action map to assign action to every physical key. You can define multiple layers in keymap and make layers active out of keymap during operation at will. - - First layer is indexed by `0` which usually become `default layer` and active in initial state. - -You can define **16 layers** at most in each keymaps[] and overlays[]. - - you can define a layer with placing keycode symbols separated with `comma` in `KEYMAP`, which is formed with resemblance to physical keyboard layout so as you can easily put keycode on place you want to map. ***You can define most of keys with just using keycodes*** except for `Fn` key serving special actions. - - - -### 4. Layer switching -You can have some ways to switch layer with these actions. -There are two kind of layer switch action `Layer Set` and `Layer Bit` and two type of switching behaviour **Momentary** and **Toggle**. - -#### 4.1 Momentary switching -Momentary switching changes layer only while holding Fn key. - -##### 4.1.1 Momentary Set -This action makes `Layer 1` active on key press event and inactive on release event.. - - ACTION_KEYMAP_MOMENTARY(1) - - -It switches to destination layer immediately when key is pressed, after that actions on keymap of destination layer is perfomed. ***Thus you shall need to place action to come back on destination layer***, or you will be stuck in destination layer without way to get back. To get back to `default layer` you can use this action. - - ACTION_LAYER_DEFAULT - -##### 4.1.2 Momentary Bit -This `Layer Bit` action performs XOR `1` with `current layer` on both press and release event. If you are on `Layer 0` now next layer to switch will be `Layer 1`. To come back to previous layer you need to place same action on destination layer. - - ACTION_LAYER_BIT(1) - -#### 4.2 Toggle switching -Toggle switching changes layer after press then release. You keep being on the layer until you press key to return. - -##### 4.2.1 Toggle Set -This `Layer Set Toggle` action is to set `Layer 1` to `current layer` on release and do none on press. - - ACTION_LAYER_SET_TOGGLE(1) - -To get back to `default layer` you can use this action. - - ACTION_LAYER_DEFAULT - -##### 4.2.2 Toggle Bit -This `Layer Bit Toggle` action is to XOR `1` with `current layer` on release and do none on press. If you are on `Layer 2` you'll switch to `Layer 3` on press. To come back to previous layer you need to place same action on destination layer. - - ACTION_LAYER_BIT_TOGGLE(1) - - -#### 4.3 Momentary switching with Tap key -These actions switch to layer only while holding `Fn` key and register key on tap. **Tap** means to press and release key quickly. - - ACTION_LAYER_SET_TAP_KEY(2, KC_SCLN) - ACTION_LAYER_SET_BIT_KEY(2, KC_SCLN) - -With these you can place layer switching function on normal alphabet key like `;` without losing its original register function. - -#### 4.4 Momentary switching with Tap Toggle -This changes layer only while holding `Fn` key and toggle layer after several taps. **Tap** means to press and release key quickly. - - ACTION_LAYER_SET_TAP_TOGGLE(layer) - ACTION_LAYER_BIT_TAP_TOGGLE(layer) - -Number of taps can be defined with `TAPPING_TOGGLE` in `config.h`, `5` by default. - - - - -Legacy Keymap -------------- -This was used in prior version and still works due to legacy support code in `common/keymap.c`. Legacy keymap doesn't support many of features that new keymap offers. - -In comparison with new keymap how to define Fn key is different. It uses two arrays `fn_layer[]` and `fn_keycode[]`. The index of arrays corresponds with postfix number of `Fn` key. Array `fn_layer[]` indicates destination layer to switch and `fn_keycode[]` has keycodes to send when tapping `Fn` key. - -In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tap while `Fn0` and `Fn1` doesn't send any key. - - static const uint8_t PROGMEM fn_layer[] = { - 1, // Fn0 - 2, // Fn1 - 2, // Fn2 - }; - - static const uint8_t PROGMEM fn_keycode[] = { - KC_NO, // Fn0 - KC_NO, // Fn1 - KC_SPC, // Fn2 - }; diff --git a/common/action.h b/common/action.h index 39e0ae32..a8c56a61 100644 --- a/common/action.h +++ b/common/action.h @@ -299,6 +299,10 @@ enum layer_params { * Default Layer */ #define ACTION_DEFAULT_LAYER ACTION(ACT_KEYMAP, 0<<8 | OP_RESET | 0) +#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_KEYMAP_RESET(layer) +#define ACTION_DEFAULT_LAYER_SET_P(layer) ACTION_KEYMAP_RESET_P(layer) +#define ACTION_DEFAULT_LAYER_SET_R(layer) ACTION_KEYMAP_RESET_R(layer) +#define ACTION_DEFAULT_LAYER_SET_B(layer) ACTION_KEYMAP_RESET_B(layer) #define ACTION_SET_DEFAULT_LAYER(layer) ACTION_KEYMAP_RESET(layer) #define ACTION_SET_DEFAULT_LAYER_P(layer) ACTION_KEYMAP_RESET_P(layer) #define ACTION_SET_DEFAULT_LAYER_R(layer) ACTION_KEYMAP_RESET_R(layer) diff --git a/doc/keymap.md b/doc/keymap.md new file mode 100644 index 00000000..132975e1 --- /dev/null +++ b/doc/keymap.md @@ -0,0 +1,522 @@ +Keymap framework - how to define your keymap +============================================ +***NOTE: This is not final version, may be inconsistent with source code and changed occasionally for a while.*** + +## Keymap +**Keymap** is comprised of multiple layers of key layout, you can define **16** layers at most. +**Layer** is an array of **keycodes** to define **actions** on each physical keys. +respective layers can be validated simultaneously. Layers are indexed with 0 to 15 and higher layer has precedence. + + Keymap with 16 Layers Layer: array of Keycodes + --------------------- ------------------------ + stack of layers content of layer + ____________ precedence _______________________ + / / | high / ESC / F1 / F2 / F3 .... + 15 /___________// | /-----/-----/-----/----- + 14 /___________// | / TAB / / / .... + 13 /___________/_ | /-----/-----/-----/----- + : / : : : : : / | /LCtrl/ / / .... + 3 /___________// | : / : : : : + 2 /___________// | 2 `-------------------------- + 1 /___________// | 1 `-------------------------- + 0 /___________/ V low 0 `-------------------------- + + +### Keymap status +Keymap has its state in two parameters: +**`default_layer`** indicates a base keymap layer(0-15) which is always valid and to be referred, **`keymap_stat`** is 16bit variable which has current on/off status of layers on its each bit. + +Keymap layer '0' is usually `default_layer` and which is the only valid layer and other layers is initially off after boot up firmware, though, you can configured them in `config.h`. +To change `default_layer` will be useful when you want to switch key layout completely, say you use Colmak instead of Qwerty. + + Initial state of Keymap Change base layout + ----------------------- ------------------ + + 15 15 + 14 14 + 13 13 + : : + 3 3 ____________ + 2 ____________ 2 / / + 1 / / ,->1 /___________/ + ,->0 /___________/ | 0 + | | + `--- default_layer = 0 `--- default_layer = 1 + keymap_stat = 0x0001 keymap_stat = 0x0002 + + +On the other hand, you shall change `keymap_state` to overlay base layer with some layers for feature such as navigation keys, function key(F1-F12), media keys or special actions. + + Overlay feature layer + --------------------- bit|status + ____________ ---+------ + 15 / / 15 | 0 + 14 /___________// -----> 14 | 1 + 13 /___________/ -----> 13 | 1 + : : | + 3 ____________ 3 | 0 + 2 / / 2 | 0 + ,->1 /___________/ -----> 1 | 1 + | 0 0 | 0 + | | + `--- default_layer = 1 | + keymap_stat = 0x6002 <-----' + + +### Layer Precedence and Transparency +Note that ***higher layer has higher priority on stack of layers***, namely firmware falls down from top layer to bottom to look up keycode. Once it spots keycode other than **`KC_TRNS`**(transparent) on a layer it stops searching and lower layers aren't referred. + +You can place `KC_TRNS` on overlay layer changes just part of layout to fall back on lower or base layer. +Key with `KC_TRANS` doen't has its own keycode and refers to its lower layers for keycode, instead. +See layer 1 or 2 below for example. + + +### Keymap Example +Keymap is **`keymaps[]`** C array in fact and you can define layers in it with **`KEYMAP()`** C macro and keycodes. To use complex actions you need to define `Fn` keycode in **`fn_actions[]`** array. + +This is a keymap example for [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard. +This example has three layers, 'Qwerty' as base layer, 'Cursor' and 'Mousekey'. +In this example, + + `Fn0` is a **momentary layer switching** key, you can use keys on Cursor layer while holding the key. + + `Fn1` is a momentary layer switching key with tapping feature, you can get semicolon **';'** with taping the key and switch layers while holding the key. The word **'tap'** or **'tapping'** mean to press and release a key quickly. + + `Fn2` is a **toggle layer switch** key, you can stay switched layer after releasing the key unlike momentary switching. + +You can find other keymap definitions in file `keymap.c` located on project directories. + + static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* 0: Qwerty + * ,-----------------------------------------------------------. + * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| + * |-----------------------------------------------------------| + * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Backs| + * |-----------------------------------------------------------| + * |Contro| A| S| D| F| G| H| J| K| L|Fn1| '|Enter | + * |-----------------------------------------------------------| + * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn0| + * `-----------------------------------------------------------' + * |Gui|Alt |Space |Alt |Fn2| + * `-------------------------------------------' + */ + KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \ + TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \ + LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT,ENT, \ + LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT,FN0, \ + LGUI,LALT, SPC, RALT,FN2), + /* 1: Cursor(HHKB mode) + * ,-----------------------------------------------------------. + * |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| + * |-----------------------------------------------------------| + * |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| + * |-----------------------------------------------------------| + * |Contro|VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | + * |-----------------------------------------------------------| + * |Shift | | | | | | +| -|End|PgD|Dow|Shift | | + * `-----------------------------------------------------------' + * |Gui |Alt |Space |Alt |Gui| + * `--------------------------------------------' + */ + KEYMAP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, TRNS,BSPC, \ + LCTL,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \ + LSFT,TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN,RSFT,TRNS, \ + LGUI,LALT, SPC, RALT,RGUI), + /* 2: Mousekey + * ,-----------------------------------------------------------. + * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| + * |-----------------------------------------------------------| + * |Tab | | | | | |MwL|MwD|MwU|MwR| | | |Backs| + * |-----------------------------------------------------------| + * |Contro| | | | | |McL|McD|McU|McR| | |Return | + * |-----------------------------------------------------------| + * |Shift | | | | |Mb3|Mb2|Mb1|Mb4|Mb5| |Shift | | + * `-----------------------------------------------------------' + * |Gui |Alt |Mb1 |Alt | | + * `--------------------------------------------' + * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel + */ + KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + TAB, TRNS,TRNS,TRNS,TRNS,TRNS,WH_L,WH_D,WH_U,WH_R,TRNS,TRNS,TRNS,BSPC, \ + LCTL,TRNS,ACL0,ACL1,ACL2,TRNS,MS_L,MS_D,MS_U,MS_R,TRNS,QUOT,ENT, \ + LSFT,TRNS,TRNS,TRNS,TRNS,BTN3,BTN2,BTN1,BTN4,BTN5,SLSH,RSFT,TRNS, \ + LGUI,LALT, BTN1, RALT,TRNS), + }; + + static const uint16_t PROGMEM fn_actions[] = { + ACTION_KEYMAP(1), // FN0 + ACTION_KEYMAP_TAP_KEY(2, KC_SCLN), // FN1 + ACTION_KEYMAP_TOGGLE(2), // FN2 + }; + + + + +## 1. Keycode +See [`common/keycode.h`](common/keycode.h) or keycode table below. Keycode is internal **8bit code** to inidicate action performed on key in keymap. Keycode has `KC_` prefixed symbol respectively. Most of keycodes like `KC_A` have simple action registers key to host on press and unregister on release, while some of other keycodes has some special actions like `Fn` keys, Media contorl keys, System control keys and Mousekeys. + + ***In `KEYMAP()` macro you should omit prefix part `KC_` of keycode to keep keymap compact.*** For example, just use `A` instead you place `KC_A` in `KEYMAP()`. Some keycodes has 4-letter **short name** in addition to descriptive name, you'll prefer short one in `KEYMAP()`. + +### 1.0 Other key +- `KC_NO` for no aciton +- `KC_TRNS` for layer transparency (See above) + +### 1.1 Normal key +- `KC_A` to `KC_Z`, `KC_1` to `KC_0` for alpha numeric key +- `KC_MINS`, `KC_EQL`, `KC_GRV`, `KC_RBRC`, `KC_LBRC`, `KC_COMM`, `KC_DOT`, `KC_BSLS`, `KC_SLSH`, `KC_SCLN`, `KC_QUOT` +- `KC_ESC`, `KC_TAB`, `KC_SPC`, `KC_BSPC`, `KC_ENT`, `KC_DEL`, `KC_INS` +- `KC_UP`, `KC_DOWN`, `KC_RGHT`, `KC_LEFT`, `KC_PGUP`, `KC_PGDN`, `KC_HOME`, `KC_END` +- `KC_CAPS`, `KC_NLCK`, `KC_SLCK`, `KC_PSCR`, `KC_PAUS`, `KC_APP`, `KC_F1` to `KC_F24` +- `KC_P1` to `KC_P0`, `KC_PDOT`, `KC_PCMM`, `KC_PSLS`, `KC_PAST`, `KC_PMNS`, `KC_PPLS`, `KC_PEQL`, `KC_PENT` for keypad. + +### 1.2 Modifier +There are 8 modifiers which has discrimination between left and right. + +- `KC_LCTL` and `KC_RCTL` for Control +- `KC_LSFT` and `KC_RSFT` for Shift +- `KC_LALT` and `KC_RALT` for Alt +- `KC_LGUI` and `KC_RGUI` for Windows key or Command key in Mac + +### 1.3 Mousekey +- `KC_MS_U`, `KC_MS_D`, `KC_MS_L`, `KC_MS_R` for mouse cursor +- `KC_WH_U`, `KC_WH_D`, `KC_WH_L`, `KC_WH_R` for mouse wheel +- `KC_BTN1`, `KC_BTN2`, `KC_BTN3`, `KC_BTN4`, `KC_BTN5` for mouse buttons + +### 1.4 System & Media key +- `KC_PWR`, `KC_SLEP`, `KC_WAKE` for Power, Sleep, Wake +- `KC_MUTE`, `KC_VOLU`, `KC_VOLD` for audio volume control +- `KC_MNXT`, `KC_MPRV`, `KC_MSTP`, `KC_MPLY`, `KC_MSEL` for media control +- `KC_MAIL`, `KC_CALC`, `KC_MYCM` for application launch +- `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` keyocde 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`](doc/keycode.txt) for description of keycodes. + + In regard to implementation side most of keycodes are identical with [HID usage][HID_usage](pdf) sent to host for real and some virtual keycodes are defined to support special actions. +[HID_usage]: http://www.usb.org/developers/devclass_docs/Hut1_11.pdf + + + +## 2. Action +See [`common/action.h`](common/action.h). Action is a **16bit code** and defines function to perform on events of a key like press, release, holding and tapping. + +Most of keys just register 8bit scancode to host, but to support other complex features needs 16bit extended action codes internally. However, using 16bit action codes in keymap results in double size in memory against using jsut keycodes. To avoid this waste 8bit keycodes are used in `KEYMAP` instead of action codes. + +***You can just use keycodes of `Normal key`, `Modifier`, `Mousekey` and `System & Media key` in keymap*** to indicate corresponding actions instead of using action codes. While ***to use other special actions you should use keycode of `Fn` key defined in `fn_actions[]`.*** + +Usually action codes are needed only when you want to use layer switching, or + +### 2.1 Key action +This is a simple action that registers scancodes(HID usage in fact) to host on press event of key and unregister on release. + +#### 2.1.1 Normal key and Modifier +This action usually won't be used expressly because you can use keycodes in `KEYMAP()` instead. +You can define `Key` action on *'A'* key and *'left shift'* modifier with: + + ACTION_KEY(KC_A) + ACTION_KEY(KC_LSHIFT) + +#### 2.1.2 Key with modifiers +This action is comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes. +Say you want to assign a key to `Shift + 1` to get charactor *'!'* or `Alt + Tab` to switch application windows. + + ACTION_LMOD_KEY(KC_LSHIFT, KC_1) + ACTION_LMOD_KEY(KC_LALT, KC_TAB) + +Or `Alt,Shift + Tab` can be defined. `ACTION_LMODS_KEY()` requires **4-bit modifier state** and a **keycode** as arguments. See `keycode.h` for `MOD_BIT()` macro. + + ACTION_LMODS_KEY((MOD_BIT(KC_LALT) | MOD_BIT(KC_LSHIFT)), KC_TAB) + + + +### 2.2 Layer Actions + +#### 2.2.0 Default Layer +`default_layer` is layer which always is on and refered to when actions is not defined on other layers. + +##### Return to Default Layer +Turns on `default layer` only with clearing other all layers. + + ACTION_DEFAULT_LAYER + +##### Set Default Layer +Sets 'default layer' to layer and turn it on without clear any other layers. + + ACTION_DEFAULT_LAYER_SET(layer) + +This does it on { press | release | both }. + + ACTION_DEFAULT_LAYER_SET(layer, on) + + +#### 2.2.1 Keymap +These actions operate given layer argument which ranges from 0 to 15. + +##### Switch to layer +Turns on layer momentary while holding, in other words turn on when key is pressed and off when released. + + ACTION_KEYMAP_MOMENTARY(layer) + + +##### Toggle layer +Turns on layer on first type and turns off on next. + + ACTION_KEYMAP_TOGGLE(layer) + + +##### Switch to layer with tap key +Turns on layer momentary while holding but registers key on tap. + + ACTION_KEYMAP_TAP_KEY(layer, key) + + +##### Switch to layer with tap toggle +Turns on layer momentary while holding but toggles it with serial taps. + + ACTION_KEYMAP_TAP_TOGGLE(layer) + + +##### Invert layer +Inverts current layer state. If the layer is on it becomes off with this action. + + ACTION_KEYMAP_INV(layer, on) + + +##### Turn On layer +Turns on layer state. + + ACTION_KEYMAP_ON(layer, on) + +Turns on layer state on press and turn off on release. This is identical to **'Switch to layer'** action. + + ACTION_KEYMAP_ON_OFF(layer) + + +##### Turn Off layer +Turns off layer state. + + ACTION_KEYMAP_OFF(layer, on) + + +##### Set layer +Turn on layer only. +`keymap_stat = (1<0 /___________/ + `--- default_layer = 0 + + you can define a layer with placing keycode symbols separated with `comma` in `KEYMAP`, which is formed with resemblance to physical keyboard layout so as you can easily put keycode on place you want to map. ***You can define most of keys with just using keycodes*** except for `Fn` key serving special actions. + +### 3.0 Transparency +With KC_TRNS you can define transparent key which itself doesn't have action but refer to lower valid layer. Transparent key is useful when you want to change part of layout not over all. + + + +## 4. Layer switching +You can have some ways to switch layer with these actions. +There are two kind of layer switch action `Layer Set` and `Layer Bit` and two type of switching behaviour **Momentary** and **Toggle**. + +### 4.1 Momentary switching +Momentary switching changes layer only while holding Fn key. + +#### 4.1.1 Momentary Set +This action makes `Layer 1` active on key press event and inactive on release event.. + + ACTION_KEYMAP_MOMENTARY(1) + + +It switches to destination layer immediately when key is pressed, after that actions on keymap of destination layer is perfomed. ***Thus you shall need to place action to come back on destination layer***, or you will be stuck in destination layer without way to get back. To get back to `default layer` you can use this action. + + ACTION_LAYER_DEFAULT + +#### 4.1.2 Momentary Bit +This `Layer Bit` action performs XOR `1` with `current layer` on both press and release event. If you are on `Layer 0` now next layer to switch will be `Layer 1`. To come back to previous layer you need to place same action on destination layer. + + ACTION_LAYER_BIT(1) + +### 4.2 Toggle switching +Toggle switching changes layer after press then release. You keep being on the layer until you press key to return. + +#### 4.2.1 Toggle Set +This `Layer Set Toggle` action is to set `Layer 1` to `current layer` on release and do none on press. + + ACTION_LAYER_SET_TOGGLE(1) + +To get back to `default layer` you can use this action. + + ACTION_LAYER_DEFAULT + +#### 4.2.2 Toggle Bit +This `Layer Bit Toggle` action is to XOR `1` with `current layer` on release and do none on press. If you are on `Layer 2` you'll switch to `Layer 3` on press. To come back to previous layer you need to place same action on destination layer. + + ACTION_LAYER_BIT_TOGGLE(1) + + +### 4.3 Momentary switching with Tap key +These actions switch to layer only while holding `Fn` key and register key on tap. **Tap** means to press and release key quickly. + + ACTION_LAYER_SET_TAP_KEY(2, KC_SCLN) + ACTION_LAYER_SET_BIT_KEY(2, KC_SCLN) + +With these you can place layer switching function on normal alphabet key like `;` without losing its original register function. + +### 4.4 Momentary switching with Tap Toggle +This changes layer only while holding `Fn` key and toggle layer after several taps. **Tap** means to press and release key quickly. + + ACTION_LAYER_SET_TAP_TOGGLE(layer) + ACTION_LAYER_BIT_TAP_TOGGLE(layer) + +Number of taps can be defined with `TAPPING_TOGGLE` in `config.h`, `5` by default. + + +## Tapping +### Tap Key +### One Shot Modifier + + +## Legacy Keymap +This was used in prior version and still works due to legacy support code in `common/keymap.c`. Legacy keymap doesn't support many of features that new keymap offers. + +In comparison with new keymap how to define Fn key is different. It uses two arrays `fn_layer[]` and `fn_keycode[]`. The index of arrays corresponds with postfix number of `Fn` key. Array `fn_layer[]` indicates destination layer to switch and `fn_keycode[]` has keycodes to send when tapping `Fn` key. + +In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tap while `Fn0` and `Fn1` doesn't send any key. + + static const uint8_t PROGMEM fn_layer[] = { + 1, // Fn0 + 2, // Fn1 + 2, // Fn2 + }; + + static const uint8_t PROGMEM fn_keycode[] = { + KC_NO, // Fn0 + KC_NO, // Fn1 + KC_SPC, // Fn2 + }; + + +## Terminology +- keymap +- layer +- layout +- key +- keycode +- scancode +- action +- layer transparency +- layer precedence +- register +- tap +- Fn key From f5db7ec5389bbcfa6461086c7a74691c01df87dc Mon Sep 17 00:00:00 2001 From: tmk Date: Tue, 5 Mar 2013 02:42:28 +0900 Subject: [PATCH 23/25] Clean action.h and add keymap doc --- README.md | 30 +++++----- common/action.c | 6 ++ common/action.h | 68 +++++---------------- doc/keymap.md | 153 +++++++++++++++++++++++------------------------- 4 files changed, 107 insertions(+), 150 deletions(-) diff --git a/README.md b/README.md index 14d55ea3..e349ee61 100644 --- a/README.md +++ b/README.md @@ -25,23 +25,23 @@ Projects You can find some keyboard specific projects under `converter` and `keyboard` directory. ### converter -* [ps2_usb](converter/ps2_usb/) - [PS/2 keyboard to USB][GH_ps2] -* adb_usb - [ADB keyboard to USB][GH_adb] -* m0110_usb - [Machintosh 128K/512K/Plus keyboard to USB][GH_m0110] -* terminal_usb - [IBM Model M terminal keyboard(PS/2 scancode set3) to USB][GH_terminal] -* news_usb - [Sony NEWS keyboard to USB][GH_news] -* x68k_usb - [Sharp X68000 keyboard to USB][GH_x68k] -* sun_usb - Sun to USB(type4, 5 and 3?) -* usb_usb - USB to USB(experimental) +* [ps2_usb](converter/ps2_usb/) - [PS/2 keyboard to USB][GH_ps2] +* [adb_usb](converter/adb_usb/) - [ADB keyboard to USB][GH_adb] +* [m0110_usb](converter/m0110_usb) - [Machintosh 128K/512K/Plus keyboard to USB][GH_m0110] +* [terminal_usb](converter/terminal_usb/) - [IBM Model M terminal keyboard(PS/2 scancode set3) to USB][GH_terminal] +* [news_usb](converter/news_usb/) - [Sony NEWS keyboard to USB][GH_news] +* [x68k_usb](converter/x68k_usb/) - [Sharp X68000 keyboard to USB][GH_x68k] +* [sun_usb](converter/sun_usb/) - Sun to USB(type4, 5 and 3?) +* [usb_usb](converter/usb_usb/) - USB to USB(experimental) ### keyboard -* hhkb - [Happy Hacking Keyboard professional][GH_hhkb] -* macway - [Compact keyboard mod][GH_macway] -* hbkb - [Happy Buckling sprint keyboard(IBM Model M mod)][GH_hbkb] -* IIgs_Standard - Apple IIGS keyboard mod(by JeffreySung) -* hid_liber - [HID liberation controller][HID_liber](by alaricljs) -* phantom - [Phantom keyboard][PHANTOM] (by Tranquilite) -* gh60 - [GH60 keyboard][GH60] +* [hhkb](keyboard/hhkb/) - [Happy Hacking Keyboard professional][GH_hhkb] +* [macway](keyboard/macway/) - [Compact keyboard mod][GH_macway] +* [hbkb](keyboard/hbkb/) - [Happy Buckling sprint keyboard(IBM Model M mod)][GH_hbkb] +* [IIgs_Standard](keyboard/IIgs_Standard/) - Apple IIGS keyboard mod(by JeffreySung) +* [hid_liber](keyboard/hid_liber/) - [HID liberation controller][HID_liber](by alaricljs) +* [phantom](keyboard/phantom/) - [Phantom keyboard][PHANTOM] (by Tranquilite) +* [gh60](keyboard/gh60/) - [GH60 keyboard][GH60] [GH_macway]: http://geekhack.org/showwiki.php?title=Island:11930 [GH_hhkb]: http://geekhack.org/showwiki.php?title=Island:12047 diff --git a/common/action.c b/common/action.c index 7ca481fb..15e125a3 100644 --- a/common/action.c +++ b/common/action.c @@ -360,6 +360,7 @@ static void process_action(keyrecord_t *record) case OP_RESET: switch (action.layer.val & 0x03) { case 0: + // NOTE: reserved overlay_clear(); keymap_clear(); break; @@ -379,6 +380,7 @@ static void process_action(keyrecord_t *record) overlay_clear(); keymap_clear(); break; + /* NOTE: 4-7 rserved */ } break; /* Keymap Reset default layer */ @@ -519,6 +521,7 @@ static void process_action(keyrecord_t *record) // Overlay Invert bit4 case OP_INV4 | 0: if (action.layer.val == 0) { + // NOTE: reserved for future use overlay_clear(); } else { overlay_set(overlay_stat ^ action.layer.val); @@ -526,6 +529,7 @@ static void process_action(keyrecord_t *record) break; case OP_INV4 | 1: if (action.layer.val == 0) { + // on pressed if (event.pressed) overlay_clear(); } else { overlay_set(overlay_stat ^ action.layer.val<<4); @@ -533,6 +537,7 @@ static void process_action(keyrecord_t *record) break; case OP_INV4 | 2: if (action.layer.val == 0) { + // on released if (!event.pressed) overlay_clear(); } else { overlay_set(overlay_stat ^ action.layer.val<<8); @@ -540,6 +545,7 @@ static void process_action(keyrecord_t *record) break; case OP_INV4 | 3: if (action.layer.val == 0) { + // on both overlay_clear(); } else { overlay_set(overlay_stat ^ action.layer.val<<12); diff --git a/common/action.h b/common/action.h index a8c56a61..ead91798 100644 --- a/common/action.h +++ b/common/action.h @@ -298,90 +298,50 @@ enum layer_params { /* * Default Layer */ -#define ACTION_DEFAULT_LAYER ACTION(ACT_KEYMAP, 0<<8 | OP_RESET | 0) -#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_KEYMAP_RESET(layer) -#define ACTION_DEFAULT_LAYER_SET_P(layer) ACTION_KEYMAP_RESET_P(layer) -#define ACTION_DEFAULT_LAYER_SET_R(layer) ACTION_KEYMAP_RESET_R(layer) -#define ACTION_DEFAULT_LAYER_SET_B(layer) ACTION_KEYMAP_RESET_B(layer) -#define ACTION_SET_DEFAULT_LAYER(layer) ACTION_KEYMAP_RESET(layer) -#define ACTION_SET_DEFAULT_LAYER_P(layer) ACTION_KEYMAP_RESET_P(layer) -#define ACTION_SET_DEFAULT_LAYER_R(layer) ACTION_KEYMAP_RESET_R(layer) -#define ACTION_SET_DEFAULT_LAYER_B(layer) ACTION_KEYMAP_RESET_B(layer) +#define ACTION_DEFAULT_LAYER ACTION(ACT_KEYMAP, ON_RELEASE<<8 | OP_RESET | 0) +#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_TO(layer, ON_RELEASE) +#define ACTION_DEFAULT_LAYER_TO(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | (on)) /* * Keymap Layer */ -#define ACTION_KEYMAP(layer) ACTION_KEYMAP_MOMENTARY(layer) #define ACTION_KEYMAP_MOMENTARY(layer) ACTION_KEYMAP_ON_OFF(layer) -#define ACTION_KEYMAP_TOGGLE(layer) ACTION_KEYMAP_INV_R(layer) -/* Keymap Set and clear overaly */ -#define ACTION_KEYMAP_RESET(layer) ACTION_KEYMAP_RESET_R(layer) -#define ACTION_KEYMAP_RESET_P(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | ON_PRESS) -#define ACTION_KEYMAP_RESET_R(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | ON_RELEASE) -#define ACTION_KEYMAP_RESET_B(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_RESET | ON_BOTH) +#define ACTION_KEYMAP_TOGGLE(layer) ACTION_KEYMAP_INV(layer, ON_RELEASE) /* Keymap Invert */ -#define ACTION_KEYMAP_INV(layer) ACTION_KEYMAP_INV_B(layer) +#define ACTION_KEYMAP_INV(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | (on)) #define ACTION_KEYMAP_TAP_TOGGLE(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | 0) -#define ACTION_KEYMAP_INV_P(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | ON_PRESS) -#define ACTION_KEYMAP_INV_R(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | ON_RELEASE) -#define ACTION_KEYMAP_INV_B(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_INV | ON_BOTH) /* Keymap On */ -#define ACTION_KEYMAP_ON(layer) ACTION_KEYMAP_ON_OFF(layer) +#define ACTION_KEYMAP_ON(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | (on)) #define ACTION_KEYMAP_ON_OFF(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | 0) -#define ACTION_KEYMAP_ON_P(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | ON_PRESS) -#define ACTION_KEYMAP_ON_R(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | ON_RELEASE) -#define ACTION_KEYMAP_ON_B(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_ON | ON_BOTH) /* Keymap Off */ -#define ACTION_KEYMAP_OFF(layer) ACTION_KEYMAP_OFF_ON(layer) +#define ACTION_KEYMAP_OFF(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | (on)) #define ACTION_KEYMAP_OFF_ON(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | 0) -#define ACTION_KEYMAP_OFF_P(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | ON_PRESS) -#define ACTION_KEYMAP_OFF_R(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | ON_RELEASE) -#define ACTION_KEYMAP_OFF_B(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_OFF | ON_BOTH) /* Keymap Set */ -#define ACTION_KEYMAP_SET(layer) ACTION_KEYMAP_SET_CLEAR(layer) +#define ACTION_KEYMAP_SET(layer, on) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | (on)) #define ACTION_KEYMAP_SET_CLEAR(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | 0) -#define ACTION_KEYMAP_SET_P(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | ON_PRESS) -#define ACTION_KEYMAP_SET_R(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | ON_RELEASE) -#define ACTION_KEYMAP_SET_B(layer) ACTION(ACT_KEYMAP, (layer)<<8 | OP_SET | ON_BOTH) /* Keymap Invert with tap key */ #define ACTION_KEYMAP_TAP_KEY(layer, key) ACTION(ACT_KEYMAP, (layer)<<8 | (key)) /* * Overlay Layer */ -#define ACTION_OVERLAY(layer) ACTION_OVERLAY_MOMENTARY(layer) #define ACTION_OVERLAY_MOMENTARY(layer) ACTION_OVERLAY_ON_OFF(layer) -#define ACTION_OVERLAY_TOGGLE(layer) ACTION_OVERLAY_INV_R(layer) +#define ACTION_OVERLAY_TOGGLE(layer) ACTION_OVERLAY_INV(layer, ON_RELEASE) /* Overlay Clear */ -#define ACTION_OVERLAY_CLEAR ACTION(ACT_OVERLAY, 0<<8 | OP_INV4 | 0) -#define ACTION_OVERLAY_CLEAR_P ACTION(ACT_OVERLAY, 0<<8 | OP_INV4 | ON_PRESS) -#define ACTION_OVERLAY_CLEAR_R ACTION(ACT_OVERLAY, 0<<8 | OP_INV4 | ON_RELEASE) -#define ACTION_OVERLAY_CLEAR_B ACTION(ACT_OVERLAY, 0<<8 | OP_INV4 | ON_BOTH) +#define ACTION_OVERLAY_CLEAR(on) ACTION(ACT_OVERLAY, 0<<8 | OP_INV4 | (on)) /* Overlay Invert 4-bit chunk */ #define ACTION_OVERLAY_INV4(bits, shift) ACTION(ACT_OVERLAY, (bits)<<8 | OP_INV4 | shift) /* Overlay Invert */ -#define ACTION_OVERLAY_INV(layer) ACTION_OVERLAY_INV_B(layer) +#define ACTION_OVERLAY_INV(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | (on)) #define ACTION_OVERLAY_TAP_TOGGLE(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | 0) -#define ACTION_OVERLAY_INV_P(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | ON_PRESS) -#define ACTION_OVERLAY_INV_R(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | ON_RELEASE) -#define ACTION_OVERLAY_INV_B(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_INV | ON_BOTH) /* Overlay On */ -#define ACTION_OVERLAY_ON(layer) ACTION_OVERLAY_ON_OFF(layer) +#define ACTION_OVERLAY_ON(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | (on)) #define ACTION_OVERLAY_ON_OFF(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | 0) -#define ACTION_OVERLAY_ON_P(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | ON_PRESS) -#define ACTION_OVERLAY_ON_R(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | ON_RELEASE) -#define ACTION_OVERLAY_ON_B(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_ON | ON_BOTH) /* Overlay Off */ -#define ACTION_OVERLAY_OFF(layer) ACTION_OVERLAY_OFF_ON(layer) +#define ACTION_OVERLAY_OFF(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | (on)) #define ACTION_OVERLAY_OFF_ON(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | 0) -#define ACTION_OVERLAY_OFF_P(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | ON_PRESS) -#define ACTION_OVERLAY_OFF_R(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | ON_RELEASE) -#define ACTION_OVERLAY_OFF_B(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_OFF | ON_BOTH) /* Overlay Set */ -#define ACTION_OVERLAY_SET(layer) ACTION_OVERLAY_SET_CLEAR(layer) +#define ACTION_OVERLAY_SET(layer, on) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | (on)) #define ACTION_OVERLAY_SET_CLEAR(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | 0) -#define ACTION_OVERLAY_SET_P(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | ON_PRESS) -#define ACTION_OVERLAY_SET_R(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | ON_RELEASE) -#define ACTION_OVERLAY_SET_B(layer) ACTION(ACT_OVERLAY, (layer)<<8 | OP_SET | ON_BOTH) /* Overlay Invert with tap key */ #define ACTION_OVERLAY_TAP_KEY(layer, key) ACTION(ACT_OVERLAY, (layer)<<8 | (key)) diff --git a/doc/keymap.md b/doc/keymap.md index 132975e1..a20ac18a 100644 --- a/doc/keymap.md +++ b/doc/keymap.md @@ -2,7 +2,7 @@ Keymap framework - how to define your keymap ============================================ ***NOTE: This is not final version, may be inconsistent with source code and changed occasionally for a while.*** -## Keymap +## 0. Keymap and layers **Keymap** is comprised of multiple layers of key layout, you can define **16** layers at most. **Layer** is an array of **keycodes** to define **actions** on each physical keys. respective layers can be validated simultaneously. Layers are indexed with 0 to 15 and higher layer has precedence. @@ -22,7 +22,7 @@ respective layers can be validated simultaneously. Layers are indexed with 0 to 0 /___________/ V low 0 `-------------------------- -### Keymap status +### 0.1 Keymap status Keymap has its state in two parameters: **`default_layer`** indicates a base keymap layer(0-15) which is always valid and to be referred, **`keymap_stat`** is 16bit variable which has current on/off status of layers on its each bit. @@ -63,15 +63,15 @@ On the other hand, you shall change `keymap_state` to overlay base layer with so keymap_stat = 0x6002 <-----' -### Layer Precedence and Transparency +### 0.2 Layer Precedence and Transparency Note that ***higher layer has higher priority on stack of layers***, namely firmware falls down from top layer to bottom to look up keycode. Once it spots keycode other than **`KC_TRNS`**(transparent) on a layer it stops searching and lower layers aren't referred. You can place `KC_TRNS` on overlay layer changes just part of layout to fall back on lower or base layer. -Key with `KC_TRANS` doen't has its own keycode and refers to its lower layers for keycode, instead. -See layer 1 or 2 below for example. +Key with `KC_TRANS` doen't has its own keycode and refers to lower valid layers for keycode, instead. +See example below. -### Keymap Example +### 0.3 Keymap Example Keymap is **`keymaps[]`** C array in fact and you can define layers in it with **`KEYMAP()`** C macro and keycodes. To use complex actions you need to define `Fn` keycode in **`fn_actions[]`** array. This is a keymap example for [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard. @@ -145,7 +145,7 @@ You can find other keymap definitions in file `keymap.c` located on project dire }; static const uint16_t PROGMEM fn_actions[] = { - ACTION_KEYMAP(1), // FN0 + ACTION_KEYMAP_MOMENTARY(1), // FN0 ACTION_KEYMAP_TAP_KEY(2, KC_SCLN), // FN1 ACTION_KEYMAP_TOGGLE(2), // FN2 }; @@ -154,7 +154,7 @@ You can find other keymap definitions in file `keymap.c` located on project dire ## 1. Keycode -See [`common/keycode.h`](common/keycode.h) or keycode table below. Keycode is internal **8bit code** to inidicate action performed on key in keymap. Keycode has `KC_` prefixed symbol respectively. Most of keycodes like `KC_A` have simple action registers key to host on press and unregister on release, while some of other keycodes has some special actions like `Fn` keys, Media contorl keys, System control keys and Mousekeys. +See [`common/keycode.h`](../common/keycode.h) or keycode table below for the detail. Keycode is internal **8bit code** to inidicate action performed on key in keymap. Keycode has `KC_` prefixed symbol respectively. Most of keycodes like `KC_A` have simple action registers key to host on press and unregister on release, while some of other keycodes has some special actions like `Fn` keys, Media contorl keys, System control keys and Mousekeys. ***In `KEYMAP()` macro you should omit prefix part `KC_` of keycode to keep keymap compact.*** For example, just use `A` instead you place `KC_A` in `KEYMAP()`. Some keycodes has 4-letter **short name** in addition to descriptive name, you'll prefer short one in `KEYMAP()`. @@ -194,7 +194,7 @@ There are 8 modifiers which has discrimination between left and right. `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` keyocde 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`](doc/keycode.txt) for description of keycodes. + See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes. In regard to implementation side most of keycodes are identical with [HID usage][HID_usage](pdf) sent to host for real and some virtual keycodes are defined to support special actions. [HID_usage]: http://www.usb.org/developers/devclass_docs/Hut1_11.pdf @@ -202,7 +202,7 @@ There are 8 modifiers which has discrimination between left and right. ## 2. Action -See [`common/action.h`](common/action.h). Action is a **16bit code** and defines function to perform on events of a key like press, release, holding and tapping. +See [`common/action.h`](../common/action.h). Action is a **16bit code** and defines function to perform on events of a key like press, release, holding and tapping. Most of keys just register 8bit scancode to host, but to support other complex features needs 16bit extended action codes internally. However, using 16bit action codes in keymap results in double size in memory against using jsut keycodes. To avoid this waste 8bit keycodes are used in `KEYMAP` instead of action codes. @@ -233,48 +233,51 @@ Or `Alt,Shift + Tab` can be defined. `ACTION_LMODS_KEY()` requires **4-bit modif -### 2.2 Layer Actions +### 2.2 Layer Action +These actions operate layers of keymap. + +Parameters: +- layer: 0-15 +- on: { press | release | both } + #### 2.2.0 Default Layer -`default_layer` is layer which always is on and refered to when actions is not defined on other layers. +`default_layer` is layer which always is valid and referred to when actions is not defined on other layers. ##### Return to Default Layer -Turns on `default layer` only with clearing other all layers. +Turns on only `default layer` with clearing other all layers. ACTION_DEFAULT_LAYER ##### Set Default Layer -Sets 'default layer' to layer and turn it on without clear any other layers. - - ACTION_DEFAULT_LAYER_SET(layer) - -This does it on { press | release | both }. +Sets 'default layer' to layer and turn it on. + ACTION_DEFAULT_LAYER_SET_TO(layer) ACTION_DEFAULT_LAYER_SET(layer, on) #### 2.2.1 Keymap -These actions operate given layer argument which ranges from 0 to 15. +These actions operate layer status of keymap. -##### Switch to layer +##### Momentary Switch Turns on layer momentary while holding, in other words turn on when key is pressed and off when released. ACTION_KEYMAP_MOMENTARY(layer) -##### Toggle layer +##### Toggle Switch Turns on layer on first type and turns off on next. ACTION_KEYMAP_TOGGLE(layer) -##### Switch to layer with tap key +##### Momentary Switch with tap key Turns on layer momentary while holding but registers key on tap. ACTION_KEYMAP_TAP_KEY(layer, key) -##### Switch to layer with tap toggle +##### Momentary Switch with tap toggle Turns on layer momentary while holding but toggles it with serial taps. ACTION_KEYMAP_TAP_TOGGLE(layer) @@ -325,6 +328,7 @@ Invert 4bits out of 16bits of overlay status on both press and release. ACTION_OVERLAY_INV4(bits, shift) + ### 2.3 Macro action ***TBD*** @@ -398,93 +402,80 @@ See `keyboard/hhkb/keymap.c` for sample. -## 3. Layer - Layer is key-action map to assign action to every physical key. You can define multiple layers in keymap and make layers active out of keymap during operation at will. - - First layer is indexed by `0` which usually become `default layer` and active in initial state. - -You can define **16 layers** at most in each keymaps and overlays. - - ____________ - / / - / // - 15 /___________/// - 14 /___________//_ - 13 /___________/ / - /: : : : : // - 3 /___________/// - 2 /___________/// - 1 /___________// - .->0 /___________/ - `--- default_layer = 0 - - you can define a layer with placing keycode symbols separated with `comma` in `KEYMAP`, which is formed with resemblance to physical keyboard layout so as you can easily put keycode on place you want to map. ***You can define most of keys with just using keycodes*** except for `Fn` key serving special actions. - -### 3.0 Transparency -With KC_TRNS you can define transparent key which itself doesn't have action but refer to lower valid layer. Transparent key is useful when you want to change part of layout not over all. - - - -## 4. Layer switching -You can have some ways to switch layer with these actions. -There are two kind of layer switch action `Layer Set` and `Layer Bit` and two type of switching behaviour **Momentary** and **Toggle**. +## 4. Layer switching Example +There are some ways to switch layer with 'Layer' actions. ### 4.1 Momentary switching Momentary switching changes layer only while holding Fn key. -#### 4.1.1 Momentary Set -This action makes `Layer 1` active on key press event and inactive on release event.. +This action makes 'Layer 1' active(valid) on key press event and inactive on release event. Namely you can overlay a layer on base layer temporarily with this. ACTION_KEYMAP_MOMENTARY(1) -It switches to destination layer immediately when key is pressed, after that actions on keymap of destination layer is perfomed. ***Thus you shall need to place action to come back on destination layer***, or you will be stuck in destination layer without way to get back. To get back to `default layer` you can use this action. +After switch actions of destination layer are perfomed. +***Thus you shall need to place action to come back on destination layer***, or you will be stuck in destination layer without way to get back. Usually you need to palce same action or 'KC_TRNS` on destination layer to get back. - ACTION_LAYER_DEFAULT - -#### 4.1.2 Momentary Bit -This `Layer Bit` action performs XOR `1` with `current layer` on both press and release event. If you are on `Layer 0` now next layer to switch will be `Layer 1`. To come back to previous layer you need to place same action on destination layer. - - ACTION_LAYER_BIT(1) ### 4.2 Toggle switching -Toggle switching changes layer after press then release. You keep being on the layer until you press key to return. +Toggle switching changes layer after press then release. With this you can keep staying on the layer until you press the key again to return. -#### 4.2.1 Toggle Set -This `Layer Set Toggle` action is to set `Layer 1` to `current layer` on release and do none on press. +This is toggle action of 'Layer 2'. - ACTION_LAYER_SET_TOGGLE(1) + ACTION_KEYMAP_TOGGLE(2) -To get back to `default layer` you can use this action. - - ACTION_LAYER_DEFAULT - -#### 4.2.2 Toggle Bit -This `Layer Bit Toggle` action is to XOR `1` with `current layer` on release and do none on press. If you are on `Layer 2` you'll switch to `Layer 3` on press. To come back to previous layer you need to place same action on destination layer. - - ACTION_LAYER_BIT_TOGGLE(1) ### 4.3 Momentary switching with Tap key -These actions switch to layer only while holding `Fn` key and register key on tap. **Tap** means to press and release key quickly. +These actions switch layer only while holding `Fn` key and register key on tap. **Tap** means to press and release key quickly. + + ACTION_KEYMAP_TAP_KEY(2, KC_SCLN) + +With this you can place layer switching function on normal key like ';' without losing its original key register function. - ACTION_LAYER_SET_TAP_KEY(2, KC_SCLN) - ACTION_LAYER_SET_BIT_KEY(2, KC_SCLN) -With these you can place layer switching function on normal alphabet key like `;` without losing its original register function. ### 4.4 Momentary switching with Tap Toggle -This changes layer only while holding `Fn` key and toggle layer after several taps. **Tap** means to press and release key quickly. +This switches layer only while holding `Fn` key and toggle layer after several taps. **Tap** means to press and release key quickly. - ACTION_LAYER_SET_TAP_TOGGLE(layer) - ACTION_LAYER_BIT_TAP_TOGGLE(layer) + ACTION_KEYMAP_TAP_TOGGLE(1) Number of taps can be defined with `TAPPING_TOGGLE` in `config.h`, `5` by default. + ## Tapping +Tapping is to press and release key quickly. Tapping speed is determined with setting of `TAPPING_TERM`, which can be defined in `config.h`, 200ms by default. + ### Tap Key +This is feature to assign normal key action and modifier including `Fn` to just one physical key. This is a kind of [Dual role modifier][dual_role]. It works as modifier or `Fn` when holding a key but registers normal key when tapping. + +Action for modifier with tap key. + + ACTION_LMODS_TAP_KEY(mods, key) + +Action for `Fn` with tap key. + + ACTION_KEYMAP_TAP_KEY(layer, key) + +[dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_modifier_keys + + +### Tap Toggle +This is feature to assign both toggle layer and momentary switch layer action to just one physical key. It works as mementary switch when holding a key but toggle switch when tapping. + + ACTION_KEYMAP_TAP_TOGGLE(layer) + + ### One Shot Modifier +This adds oneshot feature to modifier key. 'One Shot Modifier' is one time modifier which has effect only on following one alpha key. +It works as normal modifier key when holding but oneshot modifier when tapping. + + ACTION_LMODS_ONESHOT(mods) + +Say you want to type 'The', you have to push and hold Shift before type 't' then release Shift before type 'h' and 'e' or you'll get 'THe'. With One Shot Modifier you can tap Shift then type 't', 'h' and 'e' normally, you don't need to holding Shift key properly here. + + ## Legacy Keymap From e97488a1ab794144ab25738e1cbe1e4798a1a0d5 Mon Sep 17 00:00:00 2001 From: tmk Date: Tue, 5 Mar 2013 14:57:24 +0900 Subject: [PATCH 24/25] Fix README.md and doc/keymap.md --- README.md | 10 +++++++--- doc/keymap.md | 7 ++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e349ee61..b85e03dd 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Source code is available here: Features -------- -* Multi-layer Keymap - Multiple keyboard layouts with layer switching. +* Multi-layer Keymap - Multiple keyboard layouts with layer switching * Mouse key - Mouse control with keyboard * System Control Key - Power Down, Sleep, Wake Up and USB Remote Wake up * Media Control Key - Volume Down/Up, Mute, Next/Prev track, Play, Stop and etc @@ -31,14 +31,15 @@ You can find some keyboard specific projects under `converter` and `keyboard` di * [terminal_usb](converter/terminal_usb/) - [IBM Model M terminal keyboard(PS/2 scancode set3) to USB][GH_terminal] * [news_usb](converter/news_usb/) - [Sony NEWS keyboard to USB][GH_news] * [x68k_usb](converter/x68k_usb/) - [Sharp X68000 keyboard to USB][GH_x68k] -* [sun_usb](converter/sun_usb/) - Sun to USB(type4, 5 and 3?) +* [sun_usb](converter/sun_usb/) - [Sun] to USB(type4, 5 and 3?) +* [pc98_usb](converter/pc98_usb/) - [PC98] to USB * [usb_usb](converter/usb_usb/) - USB to USB(experimental) ### keyboard * [hhkb](keyboard/hhkb/) - [Happy Hacking Keyboard professional][GH_hhkb] * [macway](keyboard/macway/) - [Compact keyboard mod][GH_macway] * [hbkb](keyboard/hbkb/) - [Happy Buckling sprint keyboard(IBM Model M mod)][GH_hbkb] -* [IIgs_Standard](keyboard/IIgs_Standard/) - Apple IIGS keyboard mod(by JeffreySung) +* [IIgs_Standard](keyboard/IIgs_Standard/) - Apple [IIGS] keyboard mod(by JeffreySung) * [hid_liber](keyboard/hid_liber/) - [HID liberation controller][HID_liber](by alaricljs) * [phantom](keyboard/phantom/) - [Phantom keyboard][PHANTOM] (by Tranquilite) * [gh60](keyboard/gh60/) - [GH60 keyboard][GH60] @@ -56,6 +57,9 @@ You can find some keyboard specific projects under `converter` and `keyboard` di [HID_liber]: http://deskthority.net/wiki/HID_Liberation_Device_-_DIY_Instructions [PHANTOM]: http://geekhack.org/index.php?topic=26742 [GH60]: http://geekhack.org/index.php?topic=34959 +[PC98]: http://en.wikipedia.org/wiki/NEC_PC-9801 +[Sun]: http://en.wikipedia.org/wiki/Sun-3 +[IIGS]: http://en.wikipedia.org/wiki/Apple_IIGS diff --git a/doc/keymap.md b/doc/keymap.md index a20ac18a..ca48c6e5 100644 --- a/doc/keymap.md +++ b/doc/keymap.md @@ -20,7 +20,8 @@ respective layers can be validated simultaneously. Layers are indexed with 0 to 2 /___________// | 2 `-------------------------- 1 /___________// | 1 `-------------------------- 0 /___________/ V low 0 `-------------------------- - + + ### 0.1 Keymap status Keymap has its state in two parameters: @@ -43,7 +44,6 @@ To change `default_layer` will be useful when you want to switch key layout comp | | `--- default_layer = 0 `--- default_layer = 1 keymap_stat = 0x0001 keymap_stat = 0x0002 - On the other hand, you shall change `keymap_state` to overlay base layer with some layers for feature such as navigation keys, function key(F1-F12), media keys or special actions. @@ -62,7 +62,8 @@ On the other hand, you shall change `keymap_state` to overlay base layer with so `--- default_layer = 1 | keymap_stat = 0x6002 <-----' - + + ### 0.2 Layer Precedence and Transparency Note that ***higher layer has higher priority on stack of layers***, namely firmware falls down from top layer to bottom to look up keycode. Once it spots keycode other than **`KC_TRNS`**(transparent) on a layer it stops searching and lower layers aren't referred. From 88d6bb0b3650ecfb0e7a58a37e69f36c3671633c Mon Sep 17 00:00:00 2001 From: tmk Date: Tue, 5 Mar 2013 15:41:21 +0900 Subject: [PATCH 25/25] Fix keymap for new framework --- README.md | 2 +- common/keymap.c | 18 ++++++++---------- protocol/vusb/vusb.c | 4 ++++ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b85e03dd..e9dad457 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ You can find some keyboard specific projects under `converter` and `keyboard` di * [hhkb](keyboard/hhkb/) - [Happy Hacking Keyboard professional][GH_hhkb] * [macway](keyboard/macway/) - [Compact keyboard mod][GH_macway] * [hbkb](keyboard/hbkb/) - [Happy Buckling sprint keyboard(IBM Model M mod)][GH_hbkb] -* [IIgs_Standard](keyboard/IIgs_Standard/) - Apple [IIGS] keyboard mod(by JeffreySung) +* [IIgs_Standard](keyboard/IIgs/) - Apple [IIGS] keyboard mod(by JeffreySung) * [hid_liber](keyboard/hid_liber/) - [HID liberation controller][HID_liber](by alaricljs) * [phantom](keyboard/phantom/) - [Phantom keyboard][PHANTOM] (by Tranquilite) * [gh60](keyboard/gh60/) - [GH60 keyboard][GH60] diff --git a/common/keymap.c b/common/keymap.c index f72be577..aa8d944a 100644 --- a/common/keymap.c +++ b/common/keymap.c @@ -38,12 +38,6 @@ action_t action_for_key(uint8_t layer, key_t key) return keycode_to_action(keycode); } } - -__attribute__ ((weak)) -const prog_macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { return MACRO_NONE; } - -__attribute__ ((weak)) -void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {} #else /* * legacy keymap support @@ -71,13 +65,17 @@ action_t action_for_key(uint8_t layer, key_t key) return keycode_to_action(keycode); } } -/* not used for legacy keymap */ -void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) -{ -} #endif +__attribute__ ((weak)) +const prog_macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { return MACRO_NONE; } + +__attribute__ ((weak)) +void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {} + + + /* translates keycode to action */ static action_t keycode_to_action(uint8_t keycode) diff --git a/protocol/vusb/vusb.c b/protocol/vusb/vusb.c index 1d5f4a85..328885a9 100644 --- a/protocol/vusb/vusb.c +++ b/protocol/vusb/vusb.c @@ -88,6 +88,10 @@ static void send_keyboard(report_keyboard_t *report) } else { debug("kbuf: full\n"); } + + // NOTE: send key strokes of Macro + usbPoll(); + vusb_transfer_keyboard(); }