~ruther/qmk_firmware

854c803fdda30d7f7905c18d777ea85cac9b74d9 — tmk 12 years ago bfd7fe5
Add tap toggle feature to action.
3 files changed, 145 insertions(+), 49 deletions(-)

M common/action.c
M common/action.h
M keyboard/hhkb/keymap.c
M common/action.c => common/action.c +127 -35
@@ 19,6 19,8 @@ uint8_t current_layer = 0;

/* tap term(ms) */
#define TAP_TERM    200
/* number of tap which fires toggle feature */
#define TAP_TOGGLE  5

/* This counts up when tap occurs */
uint8_t tap_count = 0;


@@ 59,10 61,11 @@ static bool waiting_buffer_enq(keyrecord_t record)
    waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
    return true;
}
/*
static keyrecord_t waiting_buffer_deq(void)
{
    if (waiting_buffer_head == waiting_buffer_tail) {
        return (keyrecord_t){};
        return (keyrecord_t){}; // ???
    }
    uint8_t last_tail = waiting_buffer_tail;
    waiting_buffer_tail = waiting_buffer_tail + 1 % WAITING_BUFFER_SIZE;


@@ 72,6 75,7 @@ static bool waiting_buffer_is_empty(void)
{
    return (waiting_buffer_head == waiting_buffer_tail);
}
*/
static void waiting_buffer_clear(void)
{
    waiting_buffer_head = 0;


@@ 93,9 97,7 @@ static bool waiting_buffer_has_anykey_pressed(void)
    }
    return false;
}
static void waiting_buffer_process(void)
{
}


/* Oneshot modifier
 *


@@ 270,6 272,7 @@ void action_exec(keyevent_t event)
        if (!IS_NOEVENT(record.event)) debug("processed.\n");
    } else {
        if (!IS_NOEVENT(record.event)) debug("enqueued.\n");
        // enqueue
        if (!waiting_buffer_enq(record)) {
            // clear all in case of overflow.
            clear_keyboard();


@@ 278,7 281,6 @@ void action_exec(keyevent_t event)
        }
    }

    // TODO: need to process every time?
    // process waiting_buffer
    for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
        if (process_tap(&waiting_buffer[waiting_buffer_tail])) {


@@ 292,7 294,6 @@ void action_exec(keyevent_t event)

static void process(keyrecord_t *record)
{
    // TODO: use record
    keyevent_t event = record->event;
    uint8_t tap_count = record->tap_count;



@@ 450,9 451,20 @@ static void process(keyrecord_t *record)
                    }
                    break;
                case 0xF0:
                    // TODO: tap toggle
                    // tap toggle
                    if (event.pressed) {
                        if (tap_count < TAP_TOGGLE) {
                            layer_switch(action.layer.opt);
                        }
                    } else {
                        if (tap_count >= TAP_TOGGLE) {
                            debug("LAYER_PRESSED: tap toggle.\n");
                            layer_switch(action.layer.opt);
                        }
                    }
                    break;
                case 0xFF:
                    // change default layer
                    if (event.pressed) {
                        default_layer = action.layer.opt;
                        layer_switch(default_layer);


@@ 461,30 473,15 @@ static void process(keyrecord_t *record)
                default:
                    // with tap key
                    if (event.pressed) {
                        if (IS_TAPPING_KEY(event.key)) {
                           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.opt);
                           }
                        } else {
                            // TODO: while other key tapping
                                debug("LAYER_PRESSED: No tap: layer_switch\n");
                                layer_switch(action.layer.opt);
                        }
/*
                        if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
                       if (tap_count > 0) {
                            debug("LAYER_PRESSED: Tap: register_code\n");
                            register_code(action.layer.code);
                        } else {
                       } else {
                            debug("LAYER_PRESSED: No tap: layer_switch\n");
                            layer_switch(action.layer.opt);
                        }
*/
                       }
                    } else {
                        if (IS_TAPPING_KEY(event.key) && tap_count > 0) {
                        if (tap_count > 0) {
                            debug("LAYER_PRESSED: Tap: unregister_code\n");
                            unregister_code(action.layer.code);
                        } else {


@@ 502,16 499,43 @@ static void process(keyrecord_t *record)
                    }
                    break;
                case 0xF0:
                    // Ignored. LAYER_RELEASED with tap toggle is invalid action.
                    // tap toggle
                    if (event.pressed) {
                        if (tap_count >= TAP_TOGGLE) {
                            debug("LAYER_RELEASED: tap toggle.\n");
                            layer_switch(action.layer.opt);
                        }
                    } else {
                        if (tap_count < TAP_TOGGLE) {
                            layer_switch(action.layer.opt);
                        }
                    }
                    break;
                case 0xFF:
                    // change default layer
                    if (!event.pressed) {
                        default_layer = action.layer.opt;
                        layer_switch(default_layer);
                    }
                    break;
                default:
                    // Ignored. LAYER_RELEASED with tap key is invalid action.
                    // with tap key
                    if (event.pressed) {
                       if (tap_count > 0) {
                            debug("LAYER_RELEASED: Tap: register_code\n");
                            register_code(action.layer.code);
                       } else {
                            debug("LAYER_RELEASED: No tap: NO ACTION\n");
                       }
                    } else {
                        if (tap_count > 0) {
                            debug("LAYER_RELEASED: Tap: unregister_code\n");
                            unregister_code(action.layer.code);
                        } else {
                            debug("LAYER_RELEASED: No tap: layer_switch\n");
                            layer_switch(action.layer.opt);
                        }
                    }
                    break;
            }
            break;


@@ 525,7 549,21 @@ static void process(keyrecord_t *record)
                    }
                    break;
                case 0xF0:
                    // TODO: tap toggle
                    // tap toggle
                    if (event.pressed) {
                        if (tap_count < TAP_TOGGLE) {
                            debug("LAYER_BIT: tap toggle(press).\n");
                            layer_switch(current_layer | action.layer.opt);
                        }
                    } else {
                        if (tap_count < TAP_TOGGLE) {
                            debug("LAYER_BIT: tap toggle(release).\n");
                            layer_switch(current_layer & ~action.layer.opt);
                        } else {
                            debug("LAYER_BIT: tap toggle.\n");
                            layer_switch(current_layer | action.layer.opt);
                        }
                    }
                    break;
                case 0xFF:
                    // change default layer


@@ 558,6 596,7 @@ static void process(keyrecord_t *record)
                    }
                    break;
            }
            break;
        case ACT_LAYER_EXT:
            switch (action.layer.opt) {
                case 0x00:


@@ 569,16 608,43 @@ static void process(keyrecord_t *record)
                            }
                            break;
                        case 0xF0:
                            // TODO: tap toggle
                            // tap toggle
                            if (event.pressed) {
                                if (tap_count < TAP_TOGGLE) {
                                    layer_switch(default_layer);
                                }
                            } else {
                                if (tap_count >= TAP_TOGGLE) {
                                    debug("LAYER_EXT_PRESSED: tap toggle.\n");
                                    layer_switch(default_layer);
                                }
                            }
                            break;
                        case 0xFF:
                            // change default layer
                            if (event.pressed) {
                                default_layer = current_layer;
                                layer_switch(default_layer);
                            }
                            break;
                        default:
                            // TODO: tap key
                            // with tap key
                            if (event.pressed) {
                               if (tap_count > 0) {
                                    debug("LAYER_EXT_PRESSED: Tap: register_code\n");
                                    register_code(action.layer.code);
                               } else {
                                    debug("LAYER_EXT_PRESSED: No tap: layer_switch\n");
                                    layer_switch(default_layer);
                               }
                            } else {
                                if (tap_count > 0) {
                                    debug("LAYER_EXT_PRESSED: Tap: unregister_code\n");
                                    unregister_code(action.layer.code);
                                } else {
                                    debug("LAYER_EXT_PRESSED: No tap: NO ACTION\n");
                                }
                            }
                            break;
                    }
                    break;


@@ 590,17 656,43 @@ static void process(keyrecord_t *record)
                                layer_switch(default_layer);
                            }
                            break;
                        case 0xF0:
                            // tap toggle
                            if (event.pressed) {
                                if (tap_count >= TAP_TOGGLE) {
                                    debug("LAYER_EXT_RELEASED: tap toggle.\n");
                                    layer_switch(default_layer);
                                }
                            } else {
                                if (tap_count < TAP_TOGGLE) {
                                    layer_switch(default_layer);
                                }
                            }
                            break;
                        case 0xFF:
                            // change default layer
                            if (!event.pressed) {
                                default_layer = current_layer;
                                layer_switch(default_layer);
                            }
                            break;
                        case 0xF0:
                        default:
                            // Ignore tap.
                            if (!event.pressed) {
                                layer_switch(default_layer);
                            // with tap key
                            if (event.pressed) {
                               if (tap_count > 0) {
                                    debug("LAYER_EXT_RELEASED: Tap: register_code\n");
                                    register_code(action.layer.code);
                               } else {
                                    debug("LAYER_EXT_RELEASED: No tap: NO ACTION\n");
                               }
                            } else {
                                if (tap_count > 0) {
                                    debug("LAYER_EXT_RELEASED: Tap: unregister_code\n");
                                    unregister_code(action.layer.code);
                                } else {
                                    debug("LAYER_EXT_RELEASED: No tap: layer_switch\n");
                                    layer_switch(default_layer);
                                }
                            }
                            break;
                    }

M common/action.h => common/action.h +14 -12
@@ 157,10 157,10 @@ ACT_LAYER_EXT(1011):        Extentions
1011|0001|0000 0000   set default layer when released

1000|LLLL|1111 0000   set layer L when pressed + tap toggle
1001|LLLL|1111 0000   set layer L when released[tap is ignored/not used]
1001|LLLL|1111 0000   set layer L when released + tap toggle
1010|BBBB|1111 0000   on/off bit B when pressed/released + tap toggle
1011|0000|1111 0000   set default layer when pressed + tap toggle
1011|0001|1111 0000   set default layer when released[tap is ignored/not used]
1011|0001|1111 0000   set default layer when released + tap toggle

1000|LLLL|1111 1111   set L to default layer when pressed
1001|LLLL|1111 1111   set L to default layer when released


@@ 169,10 169,10 @@ ACT_LAYER_EXT(1011):        Extentions
1011|0001|1111 1111   set current to default layer when released

1000|LLLL| keycode    set layer L when pressed + tap key
1001|LLLL| keyocde    set layer L when released[tap is ignored/not used]
1001|LLLL| keyocde    set layer L when released + tap key
1010|BBBB| keyocde    on/off bit B when pressed/released + tap key
1011|0000| keyocde    set default layer when pressed + tap key
1011|0001| keyocde    set default layer when released[tap is ignored/not used]
1011|0001| keyocde    set default layer when released + tap key
 

Extensions(11XX)


@@ 235,27 235,29 @@ enum acion_param {
#define ACTION_LMODS_TAP(mods, key)     ACTION(ACT_LMODS_TAP, MOD_BITS(mods)<<8 | (key))
#define ACTION_LMODS_ONESHOT(mods)      ACTION(ACT_LMODS_TAP, MOD_BITS(mods)<<8 | ONE_SHOT)
#define ACTION_RMODS_TAP(mods, key)     ACTION(ACT_RMODS_TAP, MOD_BITS(mods)<<8 | (key))
#define ACTION_RMODS_ONESHOT(mods)      ACTION(ACT_RMODS_TAP, MOD_BITS(mods)<<8 | ONE_SHOT)

/* Layer Switch */
/* Switch current layer */
#define ACTION_LAYER_SET_ON_PRESSED(layer)   ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0x00)
#define ACTION_LAYER_SET_ON_RELEASED(layer)  ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0x00)
#define ACTION_LAYER_BIT(bits)               ACTION(ACT_LAYER_BIT,      (layer)<<8 | 0x00)
#define ACTION_LAYER_TO_DEFAULT_ON_PRESSED   ACTION(ACT_LAYER_EXT,      0x0<<8     | 0x00)
#define ACTION_LAYER_TO_DEFAULT_ON_RELEASED  ACTION(ACT_LAYER_EXT,      0x1<<8     | 0x00)

#define ACTION_LAYER_TAP_TOGGLE(layer)      ACTION(ACT_LAYER_PRESSED, (layer)<<8 | 0xF0)
#define ACTION_LAYER_BIT_TAP_TOGGLE(layer)  ACTION(ACT_LAYER_BIT,     (layer)<<8 | 0xF0)
#define ACTION_LAYER_DEFAULT_TAP_TOGGLE     ACTION(ACT_LAYER_EXT,     0x0<<8     | 0xF0)

#define ACTION_LAYER_DEFAULT_SET_ON_PRESSED(layer)   ACTION(ACT_LAYER_PRESSED, (layer)<<8 | 0xFF)
/* Switch default layer */
#define ACTION_LAYER_DEFAULT_SET_ON_PRESSED(layer)   ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_ON_RELEASED(layer)  ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_BIT(bits)               ACTION(ACT_LAYER_BIT, (bits)<<8 | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_CURRENT_ON_PRESSED  ACTION(ACT_LAYER_EXT, 0x0<<8    | 0xFF)
#define ACTION_LAYER_DEFAULT_SET_CURRENT_ON_RELEASED ACTION(ACT_LAYER_EXT, 0x1<<8    | 0xFF)

/* Layer switch with tap key */
#define ACTION_LAYER_SET_TAP_KEY(layer, key)  ACTION(ACT_LAYER_PRESSED, (layer)<<8 | (key))
#define ACTION_LAYER_BIT_TAP_KEY(bits, key)   ACTION(ACT_LAYER_BIT,     (layer)<<8 | (key))
#define ACTION_LAYER_DEFAULT_SET_TAP_KEY(key) ACTION(ACT_LAYER_EXT,     0x0<<8     | (key))
/* with tap toggle */
#define ACTION_LAYER_SET_ON_PRESSED_TAP_TOGGLE(layer)   ACTION(ACT_LAYER_PRESSED,  (layer)<<8 | 0xF0)
#define ACTION_LAYER_SET_ON_RELEASED_TAP_TOGGLE(layer)  ACTION(ACT_LAYER_RELEASED, (layer)<<8 | 0xF0)
#define ACTION_LAYER_BIT_TAP_TOGGLE(layer)  ACTION(ACT_LAYER_BIT,     (layer)<<8 | 0xF0)
#define ACTION_LAYER_DEFAULT_TAP_TOGGLE     ACTION(ACT_LAYER_EXT,     0x0<<8     | 0xF0)

/* HID Usage */
#define ACTION_USAGE_PAGE_SYSTEM        0

M keyboard/hhkb/keymap.c => keyboard/hhkb/keymap.c +4 -2
@@ 63,6 63,8 @@ static const uint16_t PROGMEM fn_actions[] = {
    ACTION_RMODS_TAP(MOD_BIT(KC_RCTL), KC_ENT), // Fn7

    ACTION_LMODS_TAP(MOD_BIT(KC_LSFT), ONE_SHOT),   // Fn8
    ACTION_LAYER_SET_ON_RELEASED_TAP_TOGGLE(1),                     // Fn9
    ACTION_LAYER_BIT_TAP_TOGGLE(1),                 // Fn10
};




@@ 83,7 85,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    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, \
           FN6, A,   S,   D,   F,   G,   H,   J,   K,   L,   FN3, QUOT,FN7, \
           FN8, Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN2, RSFT,FN1, \
           FN8, Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN2, RSFT,FN10, \
                LGUI,LALT,          FN5,                RALT,FN4),

    /* Layer 1: HHKB mode (HHKB Fn)


@@ 102,7 104,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    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,BRK, 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, \
           LSFT,NO,  NO,  NO,  NO,  NO,  PPLS,PMNS,END, PGDN,DOWN,RSFT,FN10, \
                LGUI,LALT,          SPC,                RALT,RGUI),

    /* Layer 2: Vi mode (Slash)