Code: Select all
#include QMK_KEYBOARD_H
// Defines names for use in layer keycodes and the keymap
enum layer_names {
_BASE,
_FN,
_FN2
};
typedef struct {
bool is_press_action;
uint8_t state;
} tap;
// Define a type for as many tap dance states I need
enum {
SINGLE_TAP = 1,
SINGLE_HOLD,
};
enum {
TD_DOT_COMM,
INS_LAYR,
TD_ESC,
};
// Declare the functions to be used with my tap dance key(s)
// Function associated with all tap dances
uint8_t cur_dance(qk_tap_dance_state_t *state);
// Functions associated with individual tap dances
void ql_finished(qk_tap_dance_state_t *state, void *user_data);
void ql_reset(qk_tap_dance_state_t *state, void *user_data);
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Base */
[_BASE] = LAYOUT_ansi_hhkb_split_shift_regular_backspace(
TD(TD_ESC), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, K
C_BSPC, KC_INS, KC_HOME, KC_PGUP,
KC_TAB, LCTL_T(KC_Q), KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, K
C_BSLS, KC_DEL, KC_END, KC_PGDN,
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, K
C_ENT, KC_VOLD, KC_MUTE, KC_VOLU,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, T
G(_FN2), KC_F5, KC_UP, KC_F12,
KC_LALT, MO(_FN), KC_LGUI, KC_SPC, KC_RGUI, MO(_FN), KC_RALT, KC_LEFT, KC_DOWN, KC_RGHT
),
[_FN] = LAYOUT_ansi_hhkb_split_shift_regular_backspace(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, _______, _______, _______,
KC_TAB, _______, _______, _______, _______, HPT_ON, HPT_OFF, HPT_TOG, HPT_RST, HPT_FBK, HPT_BUZ, HPT_CONT, HPT_DWLD, HPT_TOG, _______, _______, KC_6,
KC_CAPS, _______, _______, DEBUG, _______, _______, _______, _______, RESET, _______, KC_BRMD, KC_BRMU, KC_ENT, _______, _______, KC_3,
KC_LSFT, KC_F13, KC_F14, KC_F15, KC_MPLY, KC_MPRV, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, _______, KC_RSFT, TG(_FN2), KC_0, KC_UP, TD(TD_DOT_COMM),
_______, KC_TRNS, KC_LGUI, KC_SPC, KC_RGUI, KC_TRNS, KC_RALT, KC_LEFT, KC_DOWN, KC_ENT
),
[_FN2] = LAYOUT_ansi_hhkb_split_shift_regular_backspace(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_7, KC_8, KC_9,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_4, KC_5, KC_6,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_1, KC_2, KC_3,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_0, _______, TD(TD_DOT_COMM),
_______, KC_TRNS, _______, KC_SPC, _______, KC_TRNS, _______, _______, _______, _______
)
};
void keyboard_pre_init_user(void) {
// Call the post init code: flash the LEDs
setPinOutput(B5);
writePin(B5, 1);
setPinOutput(B4);
writePin(B4, 1);
_delay_ms(50);
setPinOutput(B5);
writePin(B5, 0);
setPinOutput(B4);
writePin(B4, 0);
}
// Determine the current tap dance state
uint8_t cur_dance(qk_tap_dance_state_t *state) {
if (state->count == 1) {
if (!state->pressed) return SINGLE_TAP;
else return SINGLE_HOLD;
}
else return 8;
}
// Initialize tap structure associated with example tap dance key
static tap ql_tap_state = {
.is_press_action = true,
.state = 0
};
// Functions that control what our tap dance key does
void ql_finished(qk_tap_dance_state_t *state, void *user_data) {
ql_tap_state.state = cur_dance(state);
switch (ql_tap_state.state) {
case SINGLE_TAP:
// Toggle Layer 2 on or off
if (layer_state_is(_FN2)) {
// If already set, then switch it off
layer_off(_FN2);
setPinOutput(B5);
writePin(B5, 0);
} else {
// If not already set, then switch the layer on
layer_on(_FN2);
setPinOutput(B5);
writePin(B5, 1);
}
break;
case SINGLE_HOLD:
// Momentary set Layer 1 on or off while key pressed
layer_on(_FN);
setPinOutput(B4);
writePin(B4, 1);
break;
}
}
// If the Fn key was held down and now is released then switch off layer 1
void ql_reset(qk_tap_dance_state_t *state, void *user_data) {
if (ql_tap_state.state == SINGLE_HOLD) {
layer_off(_FN);
setPinOutput(B4);
writePin(B4, 0);
}
ql_tap_state.state = 0;
}
// Associate our tap dance key with its functionality
qk_tap_dance_action_t tap_dance_actions[] = {
[INS_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 175),
[TD_DOT_COMM] = ACTION_TAP_DANCE_DOUBLE(KC_DOT, KC_COMM),
[TD_ESC] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_GRV),
};
// Since solenoid support is enabled by default, the above lock light pin
// assignments are disabled by default.
// Instead the more common Num Lock and Caps Lock are assigned the following
// way by default, and this can be used in combination with the solenoid:
// #define LED_NUM_LOCK_PIN B4
// #define LED_CAPS_LOCK_PIN B5
// darkcruix: I have de-activated both in config.h (undef) and use them for layers
// darkcruix: The light activation is done in the tab dance functions - here it is reset
layer_state_t layer_state_set_user(layer_state_t state) {
if (get_highest_layer(state) == 2) {
setPinOutput(B5);
writePin(B5, 1);
} else {
setPinOutput(B5);
writePin(B5, 0);
}
/*
switch (get_highest_layer(state)) {
case 0:
setPinOutput(B5);
writePin(B5, 0);
break;
case 1:
setPinOutput(B5);
writePin(B5, 0);
break;
case 2:
setPinOutput(B5);
writePin(B5, 1);
break;
default: // for any other layers, or the default layer
break;
} */
return state;
}