@ -0,0 +1,336 @@ | |||
/* Copyright 2022 @daliusd | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "flow.h" | |||
extern const uint16_t flow_config[FLOW_COUNT][2]; | |||
extern const uint16_t flow_layers_config[FLOW_LAYERS_COUNT][2]; | |||
// Represents the states a flow key can be in | |||
typedef enum { | |||
flow_up_unqueued, | |||
flow_up_queued, | |||
flow_up_queued_used, | |||
flow_down_unused, | |||
flow_down_used, | |||
} flow_state_t; | |||
#ifdef FLOW_ONESHOT_TERM | |||
const int g_flow_oneshot_term = FLOW_ONESHOT_TERM; | |||
#else | |||
const int g_flow_oneshot_term = 500; | |||
#endif | |||
#ifdef FLOW_ONESHOT_WAIT_TERM | |||
const int g_flow_oneshot_wait_term = FLOW_ONESHOT_WAIT_TERM; | |||
#else | |||
const int g_flow_oneshot_wait_term = 500; | |||
#endif | |||
flow_state_t flow_state[FLOW_COUNT] = { [0 ... FLOW_COUNT - 1] = flow_up_unqueued }; | |||
bool flow_pressed[FLOW_COUNT][2] = { [0 ... FLOW_COUNT - 1] = {false, false} }; | |||
uint16_t flow_timers[FLOW_COUNT] = { [0 ... FLOW_COUNT - 1] = 0 }; | |||
bool flow_timeout_timers_active[FLOW_COUNT] = { [0 ... FLOW_COUNT - 1] = false }; | |||
uint16_t flow_timeout_timers_value[FLOW_COUNT] = { [0 ... FLOW_COUNT - 1] = 0 }; | |||
uint16_t flow_timeout_wait_timers_value[FLOW_COUNT] = { [0 ... FLOW_COUNT - 1] = 0 }; | |||
flow_state_t flow_layers_state[FLOW_LAYERS_COUNT] = { | |||
[0 ... FLOW_LAYERS_COUNT - 1] = flow_up_unqueued | |||
}; | |||
bool flow_layer_timeout_timers_active[FLOW_LAYERS_COUNT] = { [0 ... FLOW_LAYERS_COUNT - 1] = false }; | |||
uint16_t flow_layer_timeout_timers_value[FLOW_LAYERS_COUNT] = { [0 ... FLOW_LAYERS_COUNT - 1] = 0 }; | |||
uint16_t flow_layer_timeout_wait_timers_value[FLOW_LAYERS_COUNT] = { [0 ... FLOW_LAYERS_COUNT - 1] = 0 }; | |||
bool is_flow_ignored_key(uint16_t keycode) { | |||
for (int i = 0; i < FLOW_COUNT; i++) { | |||
if (flow_config[i][0] == keycode) { | |||
return true; | |||
} | |||
} | |||
for (int i = 0; i < FLOW_LAYERS_COUNT; i++) { | |||
if (flow_layers_config[i][0] == keycode) { | |||
return true; | |||
} | |||
} | |||
if (keycode == KC_LSFT || keycode == KC_RSFT | |||
|| keycode == KC_LCTL || keycode == KC_RCTL | |||
|| keycode == KC_LALT || keycode == KC_RALT | |||
|| keycode == KC_LGUI || keycode == KC_RGUI) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool update_flow_mods( | |||
uint16_t keycode, | |||
bool pressed | |||
) { | |||
bool pass = true; | |||
bool flow_key_list_triggered[FLOW_COUNT] = { [0 ... FLOW_COUNT - 1] = false }; | |||
bool flow_key_list_pressed[FLOW_COUNT] = { [0 ... FLOW_COUNT - 1] = false }; | |||
bool flow_triggered = false; | |||
for (uint8_t i = 0; i < FLOW_COUNT; i++) { | |||
// Layer key | |||
if (keycode == flow_config[i][0]) { | |||
if (pressed) { | |||
flow_pressed[i][0] = true; | |||
} else { | |||
flow_pressed[i][0] = false; | |||
} | |||
// KC mod key | |||
} else if (keycode == flow_config[i][1]) { | |||
if (pressed) { | |||
if (flow_pressed[i][0]) { | |||
flow_pressed[i][1] = true; | |||
flow_key_list_triggered[i] = true; | |||
flow_triggered = true; | |||
flow_key_list_pressed[i] = true; | |||
pass = false; | |||
} | |||
} else if (flow_pressed[i][1]) { | |||
flow_pressed[i][1] = false; | |||
if (flow_pressed[i][0]) { | |||
flow_key_list_triggered[i] = true; | |||
flow_triggered = true; | |||
pass = false; | |||
} else if ((flow_state[i] == flow_down_unused) | |||
|| (flow_state[i] == flow_down_used)) { | |||
flow_key_list_triggered[i] = true; | |||
flow_triggered = true; | |||
pass = false; | |||
} | |||
} | |||
} | |||
} | |||
for (uint8_t i = 0; i < FLOW_COUNT; i++) { | |||
if (flow_key_list_triggered[i]) { | |||
if (flow_key_list_pressed[i]) { | |||
if (flow_state[i] == flow_up_unqueued) { | |||
register_code(flow_config[i][1]); | |||
} | |||
flow_timeout_wait_timers_value[i] = timer_read(); | |||
flow_state[i] = flow_down_unused; | |||
} else { | |||
// Trigger keyup | |||
switch (flow_state[i]) { | |||
case flow_down_unused: | |||
if (!flow_pressed[i][1]) { | |||
if (timer_elapsed(flow_timeout_wait_timers_value[i]) > g_flow_oneshot_wait_term) { | |||
flow_state[i] = flow_up_unqueued; | |||
unregister_code(flow_config[i][1]); | |||
} else { | |||
// If we didn't use the mod while trigger was held, queue it. | |||
flow_state[i] = flow_up_queued; | |||
flow_timeout_timers_active[i] = true; | |||
flow_timeout_timers_value[i] = timer_read(); | |||
} | |||
} | |||
break; | |||
case flow_down_used: | |||
// If we did use the mod while trigger was held, unregister it. | |||
if (!flow_pressed[i][1]) { | |||
flow_state[i] = flow_up_unqueued; | |||
unregister_code(flow_config[i][1]); | |||
} | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} else if (!flow_triggered) { | |||
if (pressed) { | |||
if (!is_flow_ignored_key(keycode)) { | |||
switch (flow_state[i]) { | |||
case flow_up_queued: | |||
flow_state[i] = flow_up_queued_used; | |||
flow_timeout_timers_active[i] = false; | |||
break; | |||
case flow_up_queued_used: | |||
flow_state[i] = flow_up_unqueued; | |||
unregister_code(flow_config[i][1]); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} else { | |||
if (!is_flow_ignored_key(keycode)) { | |||
// On non-ignored keyup, consider the oneshot used. | |||
switch (flow_state[i]) { | |||
case flow_down_unused: | |||
flow_state[i] = flow_down_used; | |||
break; | |||
case flow_up_queued: | |||
flow_state[i] = flow_up_unqueued; | |||
unregister_code(flow_config[i][1]); | |||
break; | |||
case flow_up_queued_used: | |||
flow_state[i] = flow_up_unqueued; | |||
unregister_code(flow_config[i][1]); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
return pass; | |||
} | |||
void change_pressed_status(uint16_t keycode, bool pressed) { | |||
for (int i = 0; i < FLOW_COUNT; i++) { | |||
if (flow_config[i][0] == keycode) { | |||
flow_pressed[i][0] = pressed; | |||
} | |||
} | |||
} | |||
bool update_flow_layers( | |||
uint16_t keycode, | |||
bool pressed, | |||
keypos_t key_position | |||
) { | |||
uint8_t key_layer = read_source_layers_cache(key_position); | |||
bool pass = true; | |||
for (int i = 0; i < FLOW_LAYERS_COUNT; i++) { | |||
uint16_t trigger = flow_layers_config[i][0]; | |||
uint16_t layer = flow_layers_config[i][1]; | |||
if (keycode == trigger) { | |||
if (pressed) { | |||
// Trigger keydown | |||
if (flow_layers_state[i] == flow_up_unqueued) { | |||
layer_on(layer); | |||
change_pressed_status(trigger, true); | |||
} | |||
flow_layer_timeout_wait_timers_value[i] = timer_read(); | |||
flow_layers_state[i] = flow_down_unused; | |||
pass = false; | |||
} else { | |||
// Trigger keyup | |||
switch (flow_layers_state[i]) { | |||
case flow_down_unused: | |||
if (timer_elapsed(flow_layer_timeout_wait_timers_value[i]) > g_flow_oneshot_wait_term) { | |||
flow_layers_state[i] = flow_up_unqueued; | |||
layer_off(layer); | |||
change_pressed_status(trigger, false); | |||
pass = false; | |||
} else { | |||
// If we didn't use the layer while trigger was held, queue it. | |||
flow_layers_state[i] = flow_up_queued; | |||
flow_layer_timeout_timers_active[i] = true; | |||
flow_layer_timeout_timers_value[i] = timer_read(); | |||
pass = false; | |||
change_pressed_status(trigger, true); | |||
} | |||
break; | |||
case flow_down_used: | |||
// If we did use the layer while trigger was held, turn off it. | |||
flow_layers_state[i] = flow_up_unqueued; | |||
layer_off(layer); | |||
change_pressed_status(trigger, false); | |||
pass = false; | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} else { | |||
if (pressed) { | |||
if (key_layer == layer) { | |||
// On non-ignored keyup, consider the oneshot used. | |||
switch (flow_layers_state[i]) { | |||
case flow_down_unused: | |||
flow_layers_state[i] = flow_down_used; | |||
break; | |||
case flow_up_queued: | |||
flow_layers_state[i] = flow_up_queued_used; | |||
flow_layer_timeout_timers_active[i] = false; | |||
break; | |||
case flow_up_queued_used: | |||
flow_layers_state[i] = flow_up_unqueued; | |||
layer_off(layer); | |||
change_pressed_status(trigger, false); | |||
pass = false; | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} else { | |||
// Ignore key ups from other layers | |||
if (key_layer == layer) { | |||
// On non-ignored keyup, consider the oneshot used. | |||
switch (flow_layers_state[i]) { | |||
case flow_up_queued: | |||
flow_layers_state[i] = flow_up_unqueued; | |||
layer_off(layer); | |||
change_pressed_status(trigger, false); | |||
break; | |||
case flow_up_queued_used: | |||
flow_layers_state[i] = flow_up_unqueued; | |||
layer_off(layer); | |||
change_pressed_status(trigger, false); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
return pass; | |||
} | |||
bool update_flow( | |||
uint16_t keycode, | |||
bool pressed, | |||
keypos_t key_position | |||
) { | |||
bool pass = update_flow_mods(keycode, pressed); | |||
pass = update_flow_layers(keycode, pressed, key_position) & pass; | |||
return pass; | |||
} | |||
void flow_matrix_scan(void) { | |||
for (int i = 0; i < FLOW_COUNT; i++) { | |||
if (flow_timeout_timers_active[i] | |||
&& timer_elapsed(flow_timeout_timers_value[i]) > g_flow_oneshot_term) { | |||
flow_timeout_timers_active[i] = false; | |||
flow_state[i] = flow_up_unqueued; | |||
unregister_code(flow_config[i][1]); | |||
} | |||
} | |||
for (int i = 0; i < FLOW_LAYERS_COUNT; i++) { | |||
if (flow_layer_timeout_timers_active[i] | |||
&& timer_elapsed(flow_layer_timeout_timers_value[i]) > g_flow_oneshot_term) { | |||
flow_layer_timeout_timers_active[i] = false; | |||
flow_layers_state[i] = flow_up_unqueued; | |||
layer_off(flow_layers_config[i][1]); | |||
change_pressed_status(flow_layers_config[i][0], false); | |||
} | |||
} | |||
} |
@ -0,0 +1,27 @@ | |||
/* | |||
Copyright 2022 Dalius Dobravolskas <dalius.dobravolskas@gmail.com> | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include QMK_KEYBOARD_H | |||
bool update_flow( | |||
uint16_t keycode, | |||
bool pressed, | |||
keypos_t key_position | |||
); | |||
void flow_matrix_scan(void); |
@ -1,195 +0,0 @@ | |||
/* Copyright 2021 @daliusd | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "print.h" | |||
#include "oneshot.h" | |||
void update_oneshot( | |||
oneshot_state *state, | |||
uint16_t mod, | |||
uint16_t trigger, | |||
uint16_t keycode, | |||
keyrecord_t *record | |||
) { | |||
if (keycode == trigger) { | |||
if (record->event.pressed) { | |||
// Trigger keydown | |||
if (*state == os_up_unqueued) { | |||
register_code(mod); | |||
} | |||
*state = os_down_unused; | |||
dprintf("trigger down (on?), mod: %d, ? -> os_down_unused\n", mod); | |||
} else { | |||
// Trigger keyup | |||
switch (*state) { | |||
case os_down_unused: | |||
// If we didn't use the mod while trigger was held, queue it. | |||
*state = os_up_queued; | |||
dprintf("trigger up, mod: %d, os_down_unused -> os_up_queued\n", mod); | |||
break; | |||
case os_down_used: | |||
// If we did use the mod while trigger was held, unregister it. | |||
*state = os_up_unqueued; | |||
unregister_code(mod); | |||
dprintf("trigger up (off), mod: %d, os_down_used -> os_up_unqueued\n", mod); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} else { | |||
if (record->event.pressed) { | |||
if (is_oneshot_cancel_key(keycode) && *state != os_up_unqueued) { | |||
// Cancel oneshot on designated cancel keydown. | |||
*state = os_up_unqueued; | |||
unregister_code(mod); | |||
dprintf("cancel (off), mod: %d, ? -> os_up_unqueued\n", mod); | |||
} | |||
if (!is_oneshot_ignored_key(keycode)) { | |||
switch (*state) { | |||
case os_up_queued: | |||
*state = os_up_queued_used; | |||
dprintf("key up (off), mod: %d, os_up_queued -> os_up_queued_used\n", mod); | |||
break; | |||
case os_up_queued_used: | |||
*state = os_up_unqueued; | |||
unregister_code(mod); | |||
dprintf("key up (off), mod: %d, os_up_queued_used -> os_up_unqueued\n", mod); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} else { | |||
if (!is_oneshot_ignored_key(keycode)) { | |||
// On non-ignored keyup, consider the oneshot used. | |||
switch (*state) { | |||
case os_down_unused: | |||
*state = os_down_used; | |||
dprintf("key up, mod: %d, os_down_unused -> os_down_used\n", mod); | |||
break; | |||
case os_up_queued: | |||
*state = os_up_unqueued; | |||
unregister_code(mod); | |||
dprintf("key up (off), mod: %d, os_up_queued -> os_up_unqueued\n", mod); | |||
break; | |||
case os_up_queued_used: | |||
*state = os_up_unqueued; | |||
unregister_code(mod); | |||
dprintf("key up (off), mod: %d, os_up_queued_used -> os_up_unqueued\n", mod); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
bool update_oneshot_layer( | |||
oneshot_state *state, | |||
uint16_t layer, | |||
uint16_t trigger, | |||
uint16_t keycode, | |||
keyrecord_t *record | |||
) { | |||
if (keycode == trigger) { | |||
if (record->event.pressed) { | |||
// Trigger keydown | |||
if (*state == os_up_unqueued) { | |||
layer_on(layer); | |||
} | |||
*state = os_down_unused; | |||
dprintf("trigger down (on?), layer: %d, ? -> os_down_unused\n", layer); | |||
return false; | |||
} else { | |||
// Trigger keyup | |||
switch (*state) { | |||
case os_down_unused: | |||
// If we didn't use the layer while trigger was held, queue it. | |||
*state = os_up_queued; | |||
dprintf("trigger up, layer: %d, os_down_unused -> os_up_queued\n", layer); | |||
return false; | |||
case os_down_used: | |||
// If we did use the layer while trigger was held, turn off it. | |||
*state = os_up_unqueued; | |||
layer_off(layer); | |||
dprintf("trigger up (off), layer: %d, os_down_used -> os_up_unqueued\n", layer); | |||
return false; | |||
default: | |||
break; | |||
} | |||
} | |||
} else { | |||
if (record->event.pressed) { | |||
if (is_oneshot_layer_cancel_key(keycode) && *state != os_up_unqueued) { | |||
// Cancel oneshot layer on designated cancel keydown. | |||
*state = os_up_unqueued; | |||
layer_off(layer); | |||
dprintf("cancel (off), layer: %d, ? -> os_up_unqueued\n", layer); | |||
return false; | |||
} | |||
uint8_t key_layer = read_source_layers_cache(record->event.key); | |||
if (key_layer == layer) { | |||
// On non-ignored keyup, consider the oneshot used. | |||
switch (*state) { | |||
case os_down_unused: | |||
*state = os_down_used; | |||
dprintf("key down, layer: %d, os_down_unused -> os_down_used\n", layer); | |||
return true; | |||
case os_up_queued: | |||
if (is_oneshot_mod_key(keycode)) { | |||
*state = os_up_unqueued; | |||
layer_off(layer); | |||
dprintf("key down, layer: %d, os_up_queued -> os_up_unqueued\n", layer); | |||
return false; | |||
} else { | |||
*state = os_up_queued_used; | |||
dprintf("key down, layer: %d, os_up_queued -> os_up_queued_used\n", layer); | |||
} | |||
return true; | |||
case os_up_queued_used: | |||
*state = os_up_unqueued; | |||
layer_off(layer); | |||
dprintf("key down (off), layer: %d, os_up_queued_used -> os_up_unqueued\n", layer); | |||
return false; | |||
default: | |||
break; | |||
} | |||
} | |||
} else { | |||
// Ignore key ups from other layers | |||
uint8_t key_layer = read_source_layers_cache(record->event.key); | |||
if (key_layer == layer) { | |||
// On non-ignored keyup, consider the oneshot used. | |||
switch (*state) { | |||
case os_up_queued: | |||
*state = os_up_unqueued; | |||
layer_off(layer); | |||
dprintf("key up (off), layer: %d, os_up_queued -> os_up_unqueued\n", layer); | |||
return true; | |||
case os_up_queued_used: | |||
*state = os_up_unqueued; | |||
layer_off(layer); | |||
dprintf("key up (off), layer: %d, os_up_queued_used -> os_up_unqueued\n", layer); | |||
return true; | |||
default: | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
return true; | |||
} |
@ -1,65 +0,0 @@ | |||
/* Copyright 2021 @daliusd | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include QMK_KEYBOARD_H | |||
// Represents the four states a oneshot key can be in | |||
typedef enum { | |||
os_up_unqueued, | |||
os_up_queued, | |||
os_up_queued_used, | |||
os_down_unused, | |||
os_down_used, | |||
} oneshot_state; | |||
// Custom oneshot mod implementation that doesn't rely on timers. If a mod is | |||
// used while it is held it will be unregistered on keyup as normal, otherwise | |||
// it will be queued and only released after the next non-mod keyup. | |||
void update_oneshot( | |||
oneshot_state *state, | |||
uint16_t mod, | |||
uint16_t trigger, | |||
uint16_t keycode, | |||
keyrecord_t *record | |||
); | |||
// Oneshot implementation for layers | |||
bool update_oneshot_layer( | |||
oneshot_state *state, | |||
uint16_t layer, | |||
uint16_t trigger, | |||
uint16_t keycode, | |||
keyrecord_t *record | |||
); | |||
// To be implemented by the consumer. Layers one shot implementation needs to | |||
// know which keys are used as oneshot mods | |||
bool is_oneshot_mod_key( | |||
uint16_t keycode | |||
); | |||
// To be implemented by the consumer. Defines keys to cancel oneshot mods. | |||
bool is_oneshot_cancel_key(uint16_t keycode); | |||
// To be implemented by the consumer. Defines keys to cancel oneshot layers. | |||
bool is_oneshot_layer_cancel_key(uint16_t keycode); | |||
// To be implemented by the consumer. Defines keys to ignore when determining | |||
// whether a oneshot mod has been used. Setting this to modifiers and layer | |||
// change keys allows stacking multiple oneshot modifiers, and carrying them | |||
// between layers. | |||
bool is_oneshot_ignored_key(uint16_t keycode); |
@ -1,21 +1,306 @@ | |||
# My 34 keys layout | |||
This are my principles for layout: | |||
This is my principles for layout: | |||
* I am using Callum style layout. Here you can read explanation by | |||
Callum himself and his reasoning for not using mod-tap: | |||
[here](../../../../users/callum/readme.md) | |||
* There should be only one way to type key. Key can be on | |||
different layer but it must maintain its physical location. | |||
different layer but it must maintain its physical location. I | |||
broke this rule for Shift key only. | |||
* The less features are used the better. | |||
* trilayer is cool. | |||
* There is simple TMUX layer. | |||
* There is 🐍 key for no reason. | |||
* Common keys must be accessible using two keys if possible. | |||
As well I have added one shot layers compatible with Callum's one | |||
shot keys. | |||
* It should be possible to work with left keyboard side and mouse | |||
in right hand without lifting hands for some scenarios (that's | |||
why I had to duplicate Shift key). | |||
There is simple TMUX layer as well. | |||
## Improvements over Callum | |||
* I have added one shot layers compatible with Callum's one shot | |||
keys. | |||
* There is one issue with accidental uppercase characters fixed | |||
that exists in original Callum layout's implementation. | |||
* Another annoying feature of Callum layer is one shot keys are | |||
frozen until you cancel them. This is problem when you use one | |||
hand for keyboard and another for mouse. E.g. you click Ctrl and | |||
mouse to get some menu (on Mac OS X), and then you want to click | |||
some item in that menu. You have to remember to cancel one shot in such | |||
situation. I have added two settings two handle situations like | |||
this: | |||
* `FLOW_ONESHOT_WAIT_TERM` - if hold one shot key longer than | |||
`FLOW_ONESHOT_WAIT_TERM` ms then mod key / layer key is not | |||
treated as one shot key (defaults to 500ms). | |||
* `FLOW_ONESHOT_TERM` - if you do not click another key in | |||
`FLOW_ONESHOT_TERM` ms then one shot key / layer key is treated | |||
as normal key. Therefore if you lift it after `FLOW_ONESHOT_TERM` | |||
it will not be treated as one shot (defaults to 500ms). | |||
After adding those two settings I have found out that I don't | |||
need one shot cancel key anymore so I have removed it. | |||
Since differences are significant I named this layout `flow`. | |||
## Using flow with your keyboard | |||
Copy `flow.c` and `flow.h` to keyboard folder. | |||
Add following line to `rules.mk`: | |||
```make | |||
SRC += flow.c | |||
``` | |||
Define following in `config.h` for modifiers and layers: | |||
```c | |||
#define FLOW_COUNT 7 | |||
#define FLOW_LAYERS_COUNT 3 | |||
``` | |||
In your `keymap.c` add and configure like this: | |||
```c | |||
#include "flow.h" | |||
... | |||
// flow_config should correspond to following format: | |||
// * layer keycode | |||
// * modifier keycode | |||
const uint16_t flow_config[FLOW_COUNT][2] = { | |||
{L_NAV, KC_LALT}, | |||
{L_NAV, KC_LGUI}, | |||
{L_NAV, KC_LCTL}, | |||
{L_NAV, KC_LSFT}, | |||
{L_SYM, KC_LCTL}, | |||
{L_SYM, KC_LGUI}, | |||
{L_SYM, KC_LALT}, | |||
}; | |||
// for layers configuration follow this format: | |||
// * custom layer key | |||
// * layer name | |||
const uint16_t flow_layers_config[FLOW_LAYERS_COUNT][2] = { | |||
{OS_TMUX, _TMUX}, | |||
{OS_MISC, _MISC}, | |||
{OS_FUNC, _FUNC}, | |||
}; | |||
... | |||
// Add following to handle flow | |||
bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
if (!update_flow(keycode, record->event.pressed, record->event.key)) return false; | |||
return true; | |||
} | |||
void matrix_scan_user(void) { | |||
flow_matrix_scan(); | |||
} | |||
``` | |||
## Lithuanian letters | |||
There are at least two ways how to enter Lithuanian letters: to | |||
use Unicode support from QMK or to switch OS language when | |||
necessary. Unicode support has some problems: | |||
* it is OS specific (you need to change Unicode input mode based | |||
on your OS and I sometimes switch between Mac OS X and Ubuntu). | |||
This is minor issue but it is still issue. | |||
* There is bug in Mac OS X and I can't enter `Š` using unicode | |||
input method. | |||
* Unicode Hex Input in Mac OS X is not perfect and there are some | |||
minor issue while using it. | |||
On Linux Unicode support meanwhile works perfectly. | |||
This leaves us with other option to use OS language switching as | |||
you most probably have done before. Still there is space for | |||
improvement. E.g. I have added Lithuanian letters to trilayer and | |||
trilayer activation toggles OS language (this works because I use | |||
only two languages). Check `layer_state_set_user` implementation | |||
for details. | |||
# Rejected ideas | |||
## Mods as combos | |||
Sometimes when I press `NAV (layer key) + S + Tab` to get `Command | |||
+ Tab` I ended up with `S + Nav + Tab`. This happened because I | |||
did that really fast and sometimes clicked S slightly earlier than | |||
NAV layer key. Initially I have solved this problem using Combo | |||
keys, but that's additional dependency and combo keys are not | |||
ideal for Callum layer. You need to release both keys to trigger | |||
Combo key release. Therefore I have written custom code that | |||
allows pressing S some milliseconds earlier. This is controlled by | |||
FLOW_TERM and defaults to 10. I do not recommend setting this to | |||
higher than 30. | |||
This idea was rejected because it looks like 10ms did not made | |||
that big difference. | |||
## Swapper | |||
Idea of swapper is to have key that registers Mode key (e.g. | |||
Command while layer and some key is pressed) to simulate two key | |||
combo, e.g. Command + Tab. Overall I found that 3 keys combo that | |||
I have currently for swapping windows is equally good as 2 keys | |||
swapper. Another problem with swapper is that it is OS specific. | |||
Still if you want here is swapper implementation I have used: | |||
```c | |||
bool active; | |||
void update_swapper( | |||
uint16_t trigger, | |||
uint16_t keycode, | |||
bool pressed | |||
) { | |||
if (keycode == trigger) { | |||
if (pressed) { | |||
if (!active) { | |||
active = true; | |||
register_code(KC_LGUI); | |||
} | |||
register_code(KC_TAB); | |||
} else { | |||
unregister_code(KC_TAB); | |||
} | |||
} else if (active && keycode != KC_LSFT && keycode != KC_LEFT && keycode != KC_RIGHT) { | |||
unregister_code(KC_LGUI); | |||
active = false; | |||
} | |||
} | |||
``` | |||
## Combos | |||
I have seen that some people use two letter horizontal combos for | |||
some actions, e.g. XC for Command+C, CV for Command+V, JK for ESC | |||
and etc. I found that this kind of kicks me out of the flow when | |||
working as it requires different kind of action and I need to | |||
pause to make that action. | |||
## Comma-space | |||
I have noticed that I put space after comma `,` usually. That | |||
means I can use comma + letter for something else with backspace, | |||
e.g. for Lithuanian letters. Performance wise that works OK, but | |||
practically that does not feel really good. Trilayer with language | |||
layer switch works better. | |||
Still if you are interested here is comma-space implementation: | |||
```c | |||
void swap_layout(void) { | |||
uint8_t saved_mods = get_mods(); | |||
clear_mods(); | |||
tap_code16(LCTL(KC_SPC)); | |||
set_mods(saved_mods); | |||
} | |||
void press_with_layout_swap(uint16_t keycode) { | |||
tap_code16(KC_BSPC); | |||
swap_layout(); | |||
tap_code16(keycode); | |||
swap_layout(); | |||
} | |||
bool comma_pressed = false; | |||
bool update_commaspace( | |||
uint16_t keycode, | |||
bool pressed | |||
) { | |||
if (keycode == KC_COMM) { | |||
if (!(get_mods() & MOD_MASK_SHIFT)) { | |||
comma_pressed = true; | |||
} | |||
} else if (comma_pressed) { | |||
if (keycode != KC_LSFT) { | |||
comma_pressed = false; | |||
} | |||
switch(keycode) { | |||
case KC_Q: | |||
if (pressed) { | |||
press_with_layout_swap(KC_1); | |||
return false; | |||
} | |||
break; | |||
case KC_W: | |||
if (pressed) { | |||
press_with_layout_swap(KC_2); | |||
return false; | |||
} | |||
break; | |||
case KC_E: | |||
if (pressed) { | |||
press_with_layout_swap(KC_3); | |||
return false; | |||
} | |||
break; | |||
case KC_R: | |||
if (pressed) { | |||
press_with_layout_swap(KC_4); | |||
return false; | |||
} | |||
break; | |||
case KC_T: | |||
if (pressed) { | |||
press_with_layout_swap(KC_5); | |||
return false; | |||
} | |||
break; | |||
case KC_Y: | |||
if (pressed) { | |||
press_with_layout_swap(KC_6); | |||
return false; | |||
} | |||
break; | |||
case KC_U: | |||
if (pressed) { | |||
press_with_layout_swap(KC_7); | |||
return false; | |||
} | |||
break; | |||
case KC_I: | |||
if (pressed) { | |||
press_with_layout_swap(KC_8); | |||
return false; | |||
} | |||
break; | |||
case KC_O: | |||
if (pressed) { | |||
press_with_layout_swap(KC_EQL); | |||
return false; | |||
} | |||
break; | |||
} | |||
} | |||
return true; | |||
}; | |||
``` | |||
## Using one shot layers on top layer keys (NAV and SYM) | |||
While this looked promising and fun it was really easy to get lost | |||
in which layer you actually are. You can still use it as `flow` | |||
supports this scenario, but I do not recommend it. |
@ -1 +1,33 @@ | |||
# Default layout desc TODO | |||
# Ghost Squid Default Keymap | |||
## Base Layer | |||
``` | |||
┌───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐ ┌───────────┐ | |||
│ESC│ │F1 │F2 │F3 │F4 │ │F5 │F6 │F7 │F8 │ │F9 │F10│F11│F12│ │PRT│SCR│PAU│ │Ghost Squid│ | |||
└───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘ └───────────┘ | |||
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐ | |||
│ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│ │INS│HOM│PgU│ │NUM│ / │ * │ - │ | |||
├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤ | |||
│ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ │ │DEL│END│PgD│ │ 7 │ 8 │ 9 │ │ | |||
├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ Ent│ └───┴───┴───┘ ├───┼───┼───┤ + │ | |||
│ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ \ │ │ │ 7 │ 8 │ 9 │ │ | |||
├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ ┌───┐ ├───┼───┼───┼───┤ | |||
│Shif│ # │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift │ │ ↑ │ │ 1 │ 2 │ 3 │ │ | |||
├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤Ent│ | |||
│Ctrl│GUI │Alt │ │ Alt│ GUI│Fn │Ctrl│ │ ← │ ↓ │ → │ │ 0 │ , │ │ | |||
└────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘ | |||
``` | |||
## Function Layer | |||
* `Fn` + `F5` = Play | |||
* `Fn` + `F6` = Stop | |||
* `Fn` + `F7` = Previous Track | |||
* `Fn` + `F8` = Next Track | |||
* `Fn` + `F9` = Toggle GUI key | |||
* `Fn` + `F10` = Mute | |||
* `Fn` + `F11` = Volume Down | |||
* `Fn` + `F12` = Volume Up | |||
* `Fn` + `Pause` = Reset to Bootloader |
@ -0,0 +1,20 @@ | |||
/* Copyright 2022 Andrew Kannan | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#define BACKLIGHT_PWM_DRIVER PWMD3 | |||
#define BACKLIGHT_PWM_CHANNEL 1 | |||
#define BACKLIGHT_PAL_MODE 1 |
@ -0,0 +1,27 @@ | |||
/* Copyright 2020 QMK | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
/* | |||
* This file was auto-generated by: | |||
* `qmk chibios-confmigrate -i keyboards/cannonkeys/an_c/halconf.h -r platforms/chibios/common/configs/halconf.h` | |||
*/ | |||
#pragma once | |||
#define HAL_USE_PWM TRUE | |||
#include_next <halconf.h> | |||
@ -0,0 +1,108 @@ | |||
{ | |||
"manufacturer": "CannonKeys", | |||
"keyboard_name": "Ellipse", | |||
"maintainer": "awkannan", | |||
"bootloader": "stm32-dfu", | |||
"diode_direction": "COL2ROW", | |||
"features": { | |||
"bootmagic": true, | |||
"command": false, | |||
"console": false, | |||
"extrakey": true, | |||
"mousekey": true, | |||
"nkro": true, | |||
"backlight": true, | |||
}, | |||
"matrix_pins": { | |||
"cols": ["B11", "B10", "B2", "A9", "A15", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "C13", "C14", "C15"], | |||
"rows": ["B1", "B0", "A7", "A5", "A4"] | |||
}, | |||
"backlight": { | |||
"breathing": true, | |||
"breathing_period": 5, | |||
"levels": 15, | |||
"pin": "A6" | |||
}, | |||
"indicators": { | |||
"caps_lock": "A3", | |||
"on_state": 0 | |||
}, | |||
"processor": "STM32F072", | |||
"url": "https://cannonkeys.com/", | |||
"usb": { | |||
"device_version": "1.0.0", | |||
"vid": "0xCA04", | |||
"pid": "0x0015" | |||
}, | |||
"layouts": { | |||
"LAYOUT_all": { | |||
"layout": [ | |||
{ "label": "Esc", "matrix": [0, 0], "x": 0.0, "y": 0.0 }, | |||
{ "label": "!", "matrix": [0, 1], "x": 1.0, "y": 0.0 }, | |||
{ "label": "@", "matrix": [0, 2], "x": 2.0, "y": 0.0 }, | |||
{ "label": "#", "matrix": [0, 3], "x": 3.0, "y": 0.0 }, | |||
{ "label": "$", "matrix": [0, 4], "x": 4.0, "y": 0.0 }, | |||
{ "label": "%", "matrix": [0, 5], "x": 5.0, "y": 0.0 }, | |||
{ "label": "^", "matrix": [0, 6], "x": 6.0, "y": 0.0 }, | |||
{ "label": "&", "matrix": [0, 7], "x": 7.0, "y": 0.0 }, | |||
{ "label": "*", "matrix": [0, 8], "x": 8.0, "y": 0.0 }, | |||
{ "label": "(", "matrix": [0, 9], "x": 9.0, "y": 0.0 }, | |||
{ "label": ")", "matrix": [0, 10], "x": 10.0, "y": 0.0 }, | |||
{ "label": "_", "matrix": [0, 11], "x": 11.0, "y": 0.0 }, | |||
{ "label": "+", "matrix": [0, 12], "x": 12.0, "y": 0.0 }, | |||
{ "label": "Bksp", "matrix": [0, 13], "x": 13.0, "y": 0.0 }, | |||
{ "label": "Del", "matrix": [0, 14], "x": 14.0, "y": 0.0 }, | |||
{ "label": "Tab", "matrix": [1, 0], "w": 1.5, "x": 0.0, "y": 1.0 }, | |||
{ "label": "Q", "matrix": [1, 1], "x": 1.5, "y": 1.0 }, | |||
{ "label": "W", "matrix": [1, 2], "x": 2.5, "y": 1.0 }, | |||
{ "label": "E", "matrix": [1, 3], "x": 3.5, "y": 1.0 }, | |||
{ "label": "R", "matrix": [1, 4], "x": 4.5, "y": 1.0 }, | |||
{ "label": "T", "matrix": [1, 5], "x": 5.5, "y": 1.0 }, | |||
{ "label": "Y", "matrix": [1, 6], "x": 6.5, "y": 1.0 }, | |||
{ "label": "U", "matrix": [1, 7], "x": 7.5, "y": 1.0 }, | |||
{ "label": "I", "matrix": [1, 8], "x": 8.5, "y": 1.0 }, | |||
{ "label": "O", "matrix": [1, 9], "x": 9.5, "y": 1.0 }, | |||
{ "label": "P", "matrix": [1, 10], "x": 10.5, "y": 1.0 }, | |||
{ "label": "{", "matrix": [1, 11], "x": 11.5, "y": 1.0 }, | |||
{ "label": "}", "matrix": [1, 12], "x": 12.5, "y": 1.0 }, | |||
{ "label": "|", "matrix": [1, 14], "w": 1.5, "x": 13.5, "y": 1.0 }, | |||
{ "label": "Caps Lock", "matrix": [2, 0], "w": 1.75, "x": 0.0, "y": 2.0 }, | |||
{ "label": "A", "matrix": [2, 1], "x": 1.75, "y": 2.0 }, | |||
{ "label": "S", "matrix": [2, 2], "x": 2.75, "y": 2.0 }, | |||
{ "label": "D", "matrix": [2, 3], "x": 3.75, "y": 2.0 }, | |||
{ "label": "F", "matrix": [2, 4], "x": 4.75, "y": 2.0 }, | |||
{ "label": "G", "matrix": [2, 5], "x": 5.75, "y": 2.0 }, | |||
{ "label": "H", "matrix": [2, 6], "x": 6.75, "y": 2.0 }, | |||
{ "label": "J", "matrix": [2, 7], "x": 7.75, "y": 2.0 }, | |||
{ "label": "K", "matrix": [2, 8], "x": 8.75, "y": 2.0 }, | |||
{ "label": "L", "matrix": [2, 9], "x": 9.75, "y": 2.0 }, | |||
{ "label": ":", "matrix": [2, 10], "x": 10.75, "y": 2.0 }, | |||
{ "label": "\"", "matrix": [2, 11], "x": 11.75, "y": 2.0 }, | |||
{ "label": "\\", "matrix": [2, 12], "x": 12.75, "y": 2.0 }, | |||
{ "label": "Enter", "matrix": [2, 14], "w": 2.25, "x": 12.75, "y": 2.0 }, | |||
{ "label": "Shift", "matrix": [3, 0], "w": 1.25, "x": 0.0, "y": 3.0 }, | |||
{ "label": "|", "matrix": [3, 1], "x": 1.25, "y": 3.0 }, | |||
{ "label": "Z", "matrix": [3, 2], "x": 2.25, "y": 3.0 }, | |||
{ "label": "X", "matrix": [3, 3], "x": 3.25, "y": 3.0 }, | |||
{ "label": "C", "matrix": [3, 4], "x": 4.25, "y": 3.0 }, | |||
{ "label": "V", "matrix": [3, 5], "x": 5.25, "y": 3.0 }, | |||
{ "label": "B", "matrix": [3, 6], "x": 6.25, "y": 3.0 }, | |||
{ "label": "N", "matrix": [3, 7], "x": 7.25, "y": 3.0 }, | |||
{ "label": "M", "matrix": [3, 8], "x": 8.25, "y": 3.0 }, | |||
{ "label": "<", "matrix": [3, 9], "x": 9.25, "y": 3.0 }, | |||
{ "label": ">", "matrix": [3, 10], "x": 10.25, "y": 3.0 }, | |||
{ "label": "?", "matrix": [3, 11], "x": 11.25, "y": 3.0 }, | |||
{ "label": "Shift", "matrix": [3, 12], "w": 1.75, "x": 12.25, "y": 3.0 }, | |||
{ "label": "Fn", "matrix": [3, 14], "x": 14.0, "y": 3.0 }, | |||
{ "label": "Ctrl", "matrix": [4, 0], "w": 1.25, "x": 0.0, "y": 4.0 }, | |||
{ "label": "Win", "matrix": [4, 1], "w": 1.25, "x": 1.25, "y": 4.0 }, | |||
{ "label": "Alt", "matrix": [4, 2], "w": 1.25, "x": 2.5, "y": 4.0 }, | |||
{ "matrix": [4, 6], "w": 6.25, "x": 3.75, "y": 4.0 }, | |||
{ "label": "Alt", "matrix": [4, 10], "w": 1.25, "x": 10.0, "y": 4.0 }, | |||
{ "label": "Win", "matrix": [4, 11], "w": 1.25, "x": 11.25, "y": 4.0 }, | |||
{ "label": "Fn", "matrix": [4, 12], "w": 1.25, "x": 12.5, "y": 4.0 }, | |||
{ "label": "Menu", "matrix": [4, 14], "w": 1.25, "x": 13.75, "y": 4.0 } | |||
] | |||
} | |||
} | |||
} |
@ -0,0 +1,45 @@ | |||
// Copyright 2022 Andrew Kannan (@awkannan) | |||
// SPDX-License-Identifier: GPL-2.0-or-later | |||
#include QMK_KEYBOARD_H | |||
enum layer_names { | |||
_BASE, | |||
_FN1, | |||
_FN2, | |||
_FN3 | |||
}; | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_BASE] = LAYOUT_all( | |||
QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_BSLS, KC_ENT, | |||
KC_LSFT, KC_BSLS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FN1), | |||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FN1), KC_RGUI, KC_RCTL | |||
), | |||
[_FN1] = LAYOUT_all( | |||
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_DEL, | |||
RGB_TOG, RGB_MOD, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
BL_BRTG, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
BL_INC, BL_DEC, BL_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, QK_BOOT | |||
), | |||
[_FN2] = LAYOUT_all( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______ | |||
), | |||
[_FN3] = LAYOUT_all( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______ | |||
) | |||
}; |
@ -0,0 +1,45 @@ | |||
// Copyright 2022 Andrew Kannan (@awkannan) | |||
// SPDX-License-Identifier: GPL-2.0-or-later | |||
#include QMK_KEYBOARD_H | |||
enum layer_names { | |||
_BASE, | |||
_FN1, | |||
_FN2, | |||
_FN3 | |||
}; | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_BASE] = LAYOUT_all( | |||
QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_BSLS, KC_ENT, | |||
KC_LSFT, KC_BSLS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FN1), | |||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FN1), KC_RGUI, KC_RCTL | |||
), | |||
[_FN1] = LAYOUT_all( | |||
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_DEL, | |||
RGB_TOG, RGB_MOD, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
BL_BRTG, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
BL_INC, BL_DEC, BL_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, QK_BOOT | |||
), | |||
[_FN2] = LAYOUT_all( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______ | |||
), | |||
[_FN3] = LAYOUT_all( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______ | |||
) | |||
}; |
@ -0,0 +1 @@ | |||
VIA_ENABLE = yes |
@ -0,0 +1,28 @@ | |||
/* Copyright 2020 QMK | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
/* | |||
* This file was auto-generated by: | |||
* `qmk chibios-confmigrate -i keyboards/cannonkeys/an_c/mcuconf.h -r platforms/chibios/GENERIC_STM32_F072XB/configs/mcuconf.h` | |||
*/ | |||
#pragma once | |||
#include_next <mcuconf.h> | |||
#undef STM32_PWM_USE_TIM3 | |||
#define STM32_PWM_USE_TIM3 TRUE | |||
@ -0,0 +1,25 @@ | |||
# Ellipse | |||
*An ellipse inspired 60% keyboard with 3 mounting styles from Skepur* | |||
* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan) | |||
* Hardware Supported: STM32F072CBT6 | |||
* Hardware Availability: [CannonKeys](https://cannonkeys.com) | |||
Make example for this keyboard (after setting up your build environment): | |||
make cannonkeys/ellipse:default | |||
Flashing example for this keyboard: | |||
make cannonkeys/ellipse:default:flash | |||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). | |||
## Bootloader | |||
Enter the bootloader in 3 ways: | |||
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard | |||
* **Physical reset button**: Swap the boot switch on the back of the PCB to "1" and hit the reset button | |||
* **Keycode in layout**: Press the key mapped to `RESET` if it is available |
@ -0,0 +1,2 @@ | |||
# Wildcard to allow APM32 MCU | |||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF |
@ -0,0 +1,94 @@ | |||
{ | |||
"manufacturer": "CannonKeys", | |||
"keyboard_name": "Ellipse HS", | |||
"maintainer": "awkannan", | |||
"bootloader": "stm32-dfu", | |||
"diode_direction": "COL2ROW", | |||
"features": { | |||
"bootmagic": true, | |||
"command": false, | |||
"console": false, | |||
"extrakey": true, | |||
"mousekey": true, | |||
"nkro": true | |||
}, | |||
"matrix_pins": { | |||
"cols": ["B11", "B10", "B2", "A9", "A15", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "C13", "C14", "C15"], | |||
"rows": ["B1", "B0", "A7", "A5", "A4"] | |||
}, | |||
"processor": "STM32F072", | |||
"url": "https://cannonkeys.com/", | |||
"usb": { | |||
"device_version": "1.0.0", | |||
"vid": "0xCA04", | |||
"pid": "0x0016" | |||
}, | |||
"layouts": { | |||
"LAYOUT_all": { | |||
"layout": [ | |||
{ "label": "Esc", "matrix": [0, 0], "x": 0.0, "y": 0.0 }, | |||
{ "label": "!", "matrix": [0, 1], "x": 1.0, "y": 0.0 }, | |||
{ "label": "@", "matrix": [0, 2], "x": 2.0, "y": 0.0 }, | |||
{ "label": "#", "matrix": [0, 3], "x": 3.0, "y": 0.0 }, | |||
{ "label": "$", "matrix": [0, 4], "x": 4.0, "y": 0.0 }, | |||
{ "label": "%", "matrix": [0, 5], "x": 5.0, "y": 0.0 }, | |||
{ "label": "^", "matrix": [0, 6], "x": 6.0, "y": 0.0 }, | |||
{ "label": "&", "matrix": [0, 7], "x": 7.0, "y": 0.0 }, | |||
{ "label": "*", "matrix": [0, 8], "x": 8.0, "y": 0.0 }, | |||
{ "label": "(", "matrix": [0, 9], "x": 9.0, "y": 0.0 }, | |||
{ "label": ")", "matrix": [0, 10], "x": 10.0, "y": 0.0 }, | |||
{ "label": "_", "matrix": [0, 11], "x": 11.0, "y": 0.0 }, | |||
{ "label": "+", "matrix": [0, 12], "x": 12.0, "y": 0.0 }, | |||
{ "label": "Del", "matrix": [0, 13], "x": 13.0, "y": 0.0 }, | |||
{ "label": "Bksp", "matrix": [0, 14], "x": 14.0, "y": 0.0 }, | |||
{ "label": "Tab", "matrix": [1, 0], "w": 1.5, "x": 0.0, "y": 1.0 }, | |||
{ "label": "Q", "matrix": [1, 1], "x": 1.5, "y": 1.0 }, | |||
{ "label": "W", "matrix": [1, 2], "x": 2.5, "y": 1.0 }, | |||
{ "label": "E", "matrix": [1, 3], "x": 3.5, "y": 1.0 }, | |||
{ "label": "R", "matrix": [1, 4], "x": 4.5, "y": 1.0 }, | |||
{ "label": "T", "matrix": [1, 5], "x": 5.5, "y": 1.0 }, | |||
{ "label": "Y", "matrix": [1, 6], "x": 6.5, "y": 1.0 }, | |||
{ "label": "U", "matrix": [1, 7], "x": 7.5, "y": 1.0 }, | |||
{ "label": "I", "matrix": [1, 8], "x": 8.5, "y": 1.0 }, | |||
{ "label": "O", "matrix": [1, 9], "x": 9.5, "y": 1.0 }, | |||
{ "label": "P", "matrix": [1, 10], "x": 10.5, "y": 1.0 }, | |||
{ "label": "{", "matrix": [1, 11], "x": 11.5, "y": 1.0 }, | |||
{ "label": "}", "matrix": [1, 12], "x": 12.5, "y": 1.0 }, | |||
{ "label": "|", "matrix": [1, 14], "w": 1.5, "x": 13.5, "y": 1.0 }, | |||
{ "label": "Caps Lock", "matrix": [2, 0], "w": 1.75, "x": 0.0, "y": 2.0 }, | |||
{ "label": "A", "matrix": [2, 1], "x": 1.75, "y": 2.0 }, | |||
{ "label": "S", "matrix": [2, 2], "x": 2.75, "y": 2.0 }, | |||
{ "label": "D", "matrix": [2, 3], "x": 3.75, "y": 2.0 }, | |||
{ "label": "F", "matrix": [2, 4], "x": 4.75, "y": 2.0 }, | |||
{ "label": "G", "matrix": [2, 5], "x": 5.75, "y": 2.0 }, | |||
{ "label": "H", "matrix": [2, 6], "x": 6.75, "y": 2.0 }, | |||
{ "label": "J", "matrix": [2, 7], "x": 7.75, "y": 2.0 }, | |||
{ "label": "K", "matrix": [2, 8], "x": 8.75, "y": 2.0 }, | |||
{ "label": "L", "matrix": [2, 9], "x": 9.75, "y": 2.0 }, | |||
{ "label": ":", "matrix": [2, 10], "x": 10.75, "y": 2.0 }, | |||
{ "label": "\"", "matrix": [2, 11], "x": 11.75, "y": 2.0 }, | |||
{ "label": "Enter", "matrix": [2, 14], "w": 2.25, "x": 12.75, "y": 2.0 }, | |||
{ "label": "Shift", "matrix": [3, 0], "w": 2.25, "x": 0.0, "y": 3.0 }, | |||
{ "label": "Z", "matrix": [3, 2], "x": 2.25, "y": 3.0 }, | |||
{ "label": "X", "matrix": [3, 3], "x": 3.25, "y": 3.0 }, | |||
{ "label": "C", "matrix": [3, 4], "x": 4.25, "y": 3.0 }, | |||
{ "label": "V", "matrix": [3, 5], "x": 5.25, "y": 3.0 }, | |||
{ "label": "B", "matrix": [3, 6], "x": 6.25, "y": 3.0 }, | |||
{ "label": "N", "matrix": [3, 7], "x": 7.25, "y": 3.0 }, | |||
{ "label": "M", "matrix": [3, 8], "x": 8.25, "y": 3.0 }, | |||
{ "label": "<", "matrix": [3, 9], "x": 9.25, "y": 3.0 }, | |||
{ "label": ">", "matrix": [3, 10], "x": 10.25, "y": 3.0 }, | |||
{ "label": "?", "matrix": [3, 11], "x": 11.25, "y": 3.0 }, | |||
{ "label": "Shift", "matrix": [3, 12], "w": 1.75, "x": 12.25, "y": 3.0 }, | |||
{ "label": "Fn", "matrix": [3, 14], "x": 14.0, "y": 3.0 }, | |||
{ "label": "Ctrl", "matrix": [4, 0], "w": 1.5, "x": 0.0, "y": 4.0 }, | |||
{ "label": "Win", "matrix": [4, 1], "x": 1.5, "y": 4.0 }, | |||
{ "label": "Alt", "matrix": [4, 2], "w": 1.5, "x": 2.5, "y": 4.0 }, | |||
{ "matrix": [4, 6], "w": 7.0, "x": 4.0, "y": 4.0 }, | |||
{ "label": "Alt", "matrix": [4, 11], "w": 1.5, "x": 11.0, "y": 4.0 }, | |||
{ "label": "Win", "matrix": [4, 12], "x": 12.5, "y": 4.0 }, | |||
{ "label": "Menu", "matrix": [4, 14], "w": 1.5, "x": 13.5, "y": 4.0 } | |||
] | |||
} | |||
} | |||
} |
@ -0,0 +1,45 @@ | |||
// Copyright 2022 Andrew Kannan (@awkannan) | |||
// SPDX-License-Identifier: GPL-2.0-or-later | |||
#include QMK_KEYBOARD_H | |||
enum layer_names { | |||
_BASE, | |||
_FN1, | |||
_FN2, | |||
_FN3 | |||
}; | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_BASE] = LAYOUT_all( | |||
QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, | |||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FN1), | |||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL | |||
), | |||
[_FN1] = LAYOUT_all( | |||
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_DEL, | |||
RGB_TOG, RGB_MOD, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
BL_BRTG, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
BL_INC, BL_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, QK_BOOT | |||
), | |||
[_FN2] = LAYOUT_all( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______ | |||
), | |||
[_FN3] = LAYOUT_all( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______ | |||
) | |||
}; |
@ -0,0 +1,45 @@ | |||
// Copyright 2022 Andrew Kannan (@awkannan) | |||
// SPDX-License-Identifier: GPL-2.0-or-later | |||
#include QMK_KEYBOARD_H | |||
enum layer_names { | |||
_BASE, | |||
_FN1, | |||
_FN2, | |||
_FN3 | |||
}; | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_BASE] = LAYOUT_all( | |||
QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, | |||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FN1), | |||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL | |||
), | |||
[_FN1] = LAYOUT_all( | |||
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_DEL, | |||
_______, _______, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, QK_BOOT | |||
), | |||
[_FN2] = LAYOUT_all( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______ | |||
), | |||
[_FN3] = LAYOUT_all( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______ | |||
) | |||
}; |
@ -0,0 +1 @@ | |||
VIA_ENABLE = yes |
@ -0,0 +1,25 @@ | |||
# Ellipse Hotswap | |||
*A ellipse inspired 60% keyboard with 3 mounting styles from Skepur* | |||
* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan) | |||
* Hardware Supported: STM32F072CBT6 | |||
* Hardware Availability: [CannonKeys](https://cannonkeys.com) | |||
Make example for this keyboard (after setting up your build environment): | |||
make cannonkeys/ellipse_hs:default | |||
Flashing example for this keyboard: | |||
make cannonkeys/ellipse_hs:default:flash | |||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). | |||
## Bootloader | |||
Enter the bootloader in 3 ways: | |||
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard | |||
* **Physical reset button**: Swap the boot switch on the back of the PCB to "1" and hit the reset button | |||
* **Keycode in layout**: Press the key mapped to `RESET` if it is available |
@ -0,0 +1,2 @@ | |||
# Wildcard to allow APM32 MCU | |||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF |
@ -0,0 +1,64 @@ | |||
/* | |||
* Copyright 2022 Kevin Gee <info@controller.works> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include "config_common.h" | |||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ | |||
/* #define DEBOUNCE 5 */ | |||
#define WS2812_PIO_USE_PIO1 | |||
#define RGBLED_NUM 48 | |||
#define DRIVER_LED_TOTAL RGBLED_NUM | |||
#define RGB_MATRIX_SPLIT \ | |||
{ 24, 24 } | |||
#define SPLIT_TRANSPORT_MIRROR | |||
#define SPLIT_LAYER_STATE_ENABLE | |||
#define SPLIT_LED_STATE_ENABLE | |||
#define SPLIT_MODS_ENABLE | |||
#define I2C_DRIVER I2CD1 | |||
#define I2C1_SCL_PIN GP25 | |||
#define I2C1_SDA_PIN GP24 | |||
/* #define EE_HANDS */ | |||
/* #define MASTER_LEFT */ | |||
/* #define MASTER_RIGHT */ | |||
/* Top left key on left half */ | |||
#define BOOTMAGIC_LITE_ROW 0 | |||
#define BOOTMAGIC_LITE_COLUMN 0 | |||
/* Top right key on right half */ | |||
#define BOOTMAGIC_LITE_ROW_RIGHT 0 | |||
#define BOOTMAGIC_LITE_COLUMN_RIGHT 0 | |||
/* | |||
* Feature disable options | |||
* These options are also useful to firmware size reduction. | |||
*/ | |||
/* disable debug print */ | |||
//#define NO_DEBUG | |||
/* disable print */ | |||
//#define NO_PRINT | |||
/* disable action features */ | |||
//#define NO_ACTION_LAYER | |||
//#define NO_ACTION_TAPPING | |||
//#define NO_ACTION_ONESHOT |
@ -0,0 +1,22 @@ | |||
/* | |||
* Copyright 2022 Kevin Gee <info@controller.works> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#define HAL_USE_I2C TRUE | |||
#include_next "halconf.h" |
@ -0,0 +1,154 @@ | |||
{ | |||
"manufacturer": "Controller Works", | |||
"keyboard_name": "mini36", | |||
"maintainer": "controller-works", | |||
"processor": "RP2040", | |||
"url": "https://controller.works/products/mini36-low-profile-ergonomic-keyboard", | |||
"tags": ["split", "RP2040", "choc v1", "choc spaced" ], | |||
"usb": { | |||
"device_version": "1.0.0", | |||
"pid": "0x0004", | |||
"vid": "0x4357" | |||
}, | |||
"bootloader": "rp2040", | |||
"diode_direction": "COL2ROW", | |||
"build": { | |||
"lto":true | |||
}, | |||
"matrix_pins": { | |||
"direct": [ | |||
["GP3", "GP4", "GP5", "GP6", "GP7"], | |||
["GP9", "GP10", "GP11", "GP12", "GP13"], | |||
["GP15", "GP16", "GP17", "GP18", "GP19"], | |||
["GP20", "GP21", "GP22", null, null] | |||
] | |||
}, | |||
"rgblight": { | |||
"pin": "GP0" | |||
}, | |||
"split": { | |||
"enabled": true, | |||
"matrix_pins": { | |||
"right": { | |||
"direct": [ | |||
["GP7", "GP6", "GP5", "GP4", "GP3"], | |||
["GP13", "GP12", "GP11", "GP10", "GP9"], | |||
["GP19", "GP18", "GP17", "GP16", "GP15"], | |||
["GP22", "GP21", "GP20", null, null] | |||
] | |||
} | |||
}, | |||
"soft_serial_pin": "GP1", | |||
"transport": { | |||
"protocol": "serial" | |||
} | |||
}, | |||
"features": { | |||
"bootmagic": true, | |||
"command": false, | |||
"console": false, | |||
"extrakey": true, | |||
"mousekey": true, | |||
"nkro": true, | |||
"rgb_matrix": true, | |||
"oled": true | |||
}, | |||
"rgb_matrix": { | |||
"driver": "WS2812", | |||
"layout": [ | |||
{ "flags": 2, "x": 71, "y": 4 }, | |||
{ "flags": 2, "x": 32, "y": 2 }, | |||
{ "flags": 2, "x": 0, "y": 24 }, | |||
{ "flags": 2, "x": 16, "y": 51 }, | |||
{ "flags": 2, "x": 63, "y": 58 }, | |||
{ "flags": 2, "x": 94, "y": 55 }, | |||
{ "flags": 1, "matrix": [3, 2], "x": 90, "y": 64 }, | |||
{ "flags": 4, "matrix": [2, 4], "x": 79, "y": 39 }, | |||
{ "flags": 4, "matrix": [1, 4], "x": 79, "y": 22 }, | |||
{ "flags": 4, "matrix": [0, 4], "x": 79, "y": 5 }, | |||
{ "flags": 4, "matrix": [0, 3], "x": 61, "y": 2 }, | |||
{ "flags": 4, "matrix": [1, 3], "x": 61, "y": 19 }, | |||
{ "flags": 4, "matrix": [2, 3], "x": 61, "y": 37 }, | |||
{ "flags": 1, "matrix": [3, 1], "x": 74, "y": 58 }, | |||
{ "flags": 1, "matrix": [3, 0], "x": 53, "y": 55 }, | |||
{ "flags": 4, "matrix": [2, 2], "x": 43, "y": 34 }, | |||
{ "flags": 4, "matrix": [1, 2], "x": 43, "y": 17 }, | |||
{ "flags": 4, "matrix": [0, 2], "x": 43, "y": 0 }, | |||
{ "flags": 4, "matrix": [0, 1], "x": 25, "y": 2 }, | |||
{ "flags": 4, "matrix": [1, 1], "x": 25, "y": 19 }, | |||
{ "flags": 4, "matrix": [2, 1], "x": 25, "y": 37 }, | |||
{ "flags": 4, "matrix": [2, 0], "x": 7, "y": 41 }, | |||
{ "flags": 4, "matrix": [1, 0], "x": 7, "y": 24 }, | |||
{ "flags": 4, "matrix": [0, 0], "x": 7, "y": 7 }, | |||
{ "flags": 2, "x": 153, "y": 4 }, | |||
{ "flags": 2, "x": 192, "y": 2 }, | |||
{ "flags": 2, "x": 224, "y": 24 }, | |||
{ "flags": 2, "x": 204, "y": 53 }, | |||
{ "flags": 2, "x": 161, "y": 57 }, | |||
{ "flags": 2, "x": 130, "y": 55 }, | |||
{ "flags": 1, "matrix": [7, 0], "x": 134, "y": 64 }, | |||
{ "flags": 4, "matrix": [6, 0], "x": 145, "y": 39 }, | |||
{ "flags": 4, "matrix": [5, 0], "x": 145, "y": 22 }, | |||
{ "flags": 4, "matrix": [4, 0], "x": 145, "y": 5 }, | |||
{ "flags": 4, "matrix": [4, 1], "x": 163, "y": 2 }, | |||
{ "flags": 4, "matrix": [5, 1], "x": 163, "y": 19 }, | |||
{ "flags": 4, "matrix": [6, 1], "x": 163, "y": 37 }, | |||
{ "flags": 1, "matrix": [7, 1], "x": 150, "y": 58 }, | |||
{ "flags": 1, "matrix": [7, 2], "x": 171, "y": 55 }, | |||
{ "flags": 4, "matrix": [6, 2], "x": 181, "y": 34 }, | |||
{ "flags": 4, "matrix": [5, 2], "x": 181, "y": 17 }, | |||
{ "flags": 4, "matrix": [4, 2], "x": 181, "y": 0 }, | |||
{ "flags": 4, "matrix": [4, 3], "x": 199, "y": 2 }, | |||
{ "flags": 4, "matrix": [5, 3], "x": 199, "y": 19 }, | |||
{ "flags": 4, "matrix": [6, 3], "x": 199, "y": 37 }, | |||
{ "flags": 4, "matrix": [6, 4], "x": 217, "y": 41 }, | |||
{ "flags": 4, "matrix": [5, 4], "x": 217, "y": 24 }, | |||
{ "flags": 4, "matrix": [4, 4], "x": 217, "y": 7 } | |||
] | |||
}, | |||
"community_layouts": ["split_3x5_3"], | |||
"layouts": { | |||
"LAYOUT_split_3x5_3": { | |||
"layout": [ | |||
{ "matrix": [0, 0], "x": 0, "y": 0.25 }, | |||
{ "matrix": [0, 1], "x": 1, "y": 0.125 }, | |||
{ "matrix": [0, 2], "x": 2, "y": 0 }, | |||
{ "matrix": [0, 3], "x": 3, "y": 0.125 }, | |||
{ "matrix": [0, 4], "x": 4, "y": 0.25 }, | |||
{ "matrix": [4, 0], "x": 7, "y": 0.25 }, | |||
{ "matrix": [4, 1], "x": 8, "y": 0.125 }, | |||
{ "matrix": [4, 2], "x": 9, "y": 0 }, | |||
{ "matrix": [4, 3], "x": 10, "y": 0.125 }, | |||
{ "matrix": [4, 4], "x": 11, "y": 0.25 }, | |||
{ "matrix": [1, 0], "x": 0, "y": 1.25 }, | |||
{ "matrix": [1, 1], "x": 1, "y": 1.125 }, | |||
{ "matrix": [1, 2], "x": 2, "y": 1 }, | |||
{ "matrix": [1, 3], "x": 3, "y": 1.125 }, | |||
{ "matrix": [1, 4], "x": 4, "y": 1.25 }, | |||
{ "matrix": [5, 0], "x": 7, "y": 1.25 }, | |||
{ "matrix": [5, 1], "x": 8, "y": 1.125 }, | |||
{ "matrix": [5, 2], "x": 9, "y": 1 }, | |||
{ "matrix": [5, 3], "x": 10, "y": 1.125 }, | |||
{ "matrix": [5, 4], "x": 11, "y": 1.25 }, | |||
{ "matrix": [2, 0], "x": 0, "y": 2.25 }, | |||
{ "matrix": [2, 1], "x": 1, "y": 2.125 }, | |||
{ "matrix": [2, 2], "x": 2, "y": 2 }, | |||
{ "matrix": [2, 3], "x": 3, "y": 2.125 }, | |||
{ "matrix": [2, 4], "x": 4, "y": 2.25 }, | |||
{ "matrix": [6, 0], "x": 7, "y": 2.25 }, | |||
{ "matrix": [6, 1], "x": 8, "y": 2.125 }, | |||
{ "matrix": [6, 2], "x": 9, "y": 2 }, | |||
{ "matrix": [6, 3], "x": 10, "y": 2.125 }, | |||
{ "matrix": [6, 4], "x": 11, "y": 2.25 }, | |||
{ "matrix": [3, 0], "x": 2.5, "y": 3.25 }, | |||
{ "matrix": [3, 1], "x": 3.5, "y": 3.5 }, | |||
{ "matrix": [3, 2], "x": 4.5, "y": 3.75, "h":1.5 }, | |||
{ "matrix": [7, 0], "x": 6.5, "y": 3.75, "h":1.5 }, | |||
{ "matrix": [7, 1], "x": 7.5, "y": 3.5 }, | |||
{ "matrix": [7, 2], "x": 8.5, "y": 3.25 } | |||
] | |||
} | |||
} | |||
} |
@ -0,0 +1,79 @@ | |||
/* | |||
* Copyright 2022 Kevin Gee <info@controller.works> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#ifdef RGB_MATRIX_ENABLE | |||
//# define SPLIT_TRANSPORT_MIRROR | |||
# define RGB_MATRIX_KEYPRESSES // reacts to keypresses | |||
// # define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses) | |||
// # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects | |||
# define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended | |||
# define RGB_MATRIX_FRAMEBUFFER_EFFECTS | |||
// # define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness) | |||
// # define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness) | |||
# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150 // limits maximum brightness of LEDs to 150 out of 255. Higher may cause the controller to crash. | |||
# define RGB_MATRIX_HUE_STEP 8 | |||
# define RGB_MATRIX_SAT_STEP 8 | |||
# define RGB_MATRIX_VAL_STEP 8 | |||
# define RGB_MATRIX_SPD_STEP 10 | |||
# define ENABLE_RGB_MATRIX_ALPHAS_MODS | |||
# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN | |||
# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT | |||
# define ENABLE_RGB_MATRIX_BREATHING | |||
# define ENABLE_RGB_MATRIX_BAND_SAT | |||
# define ENABLE_RGB_MATRIX_BAND_VAL | |||
# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT | |||
# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL | |||
# define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT | |||
# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL | |||
# define ENABLE_RGB_MATRIX_CYCLE_ALL | |||
# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT | |||
# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN | |||
# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON | |||
# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN | |||
# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL | |||
# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL | |||
# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL | |||
# define ENABLE_RGB_MATRIX_DUAL_BEACON | |||
# define ENABLE_RGB_MATRIX_RAINBOW_BEACON | |||
# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS | |||
# define ENABLE_RGB_MATRIX_RAINDROPS | |||
# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS | |||
# define ENABLE_RGB_MATRIX_HUE_BREATHING | |||
# define ENABLE_RGB_MATRIX_HUE_PENDULUM | |||
# define ENABLE_RGB_MATRIX_HUE_WAVE | |||
# define ENABLE_RGB_MATRIX_PIXEL_RAIN | |||
# define ENABLE_RGB_MATRIX_PIXEL_FLOW | |||
# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL | |||
// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined | |||
# define ENABLE_RGB_MATRIX_TYPING_HEATMAP | |||
# define ENABLE_RGB_MATRIX_DIGITAL_RAIN | |||
// enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS | |||
# define ENABLE_RGB_MATRIX_SPLASH | |||
# define ENABLE_RGB_MATRIX_MULTISPLASH | |||
# define ENABLE_RGB_MATRIX_SOLID_SPLASH | |||
# define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH | |||
#endif |
@ -0,0 +1,68 @@ | |||
/* | |||
* Copyright 2022 Kevin Gee <info@controller.works> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT_split_3x5_3( | |||
//,--------------------------------------------. ,--------------------------------------------. | |||
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
LCTL_T(KC_A), KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, | |||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| | |||
KC_LGUI, MO(1), KC_SPC, KC_SPC, MO(2), GUI_T(KC_TAB) | |||
//`--------------------------' `--------------------------' | |||
), | |||
[1] = LAYOUT_split_3x5_3( | |||
//,--------------------------------------------. ,--------------------------------------------. | |||
KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
KC_TAB, XXXXXXX, XXXXXXX, XXXXXXX, KC_PGUP, XXXXXXX, KC_UP, XXXXXXX, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
KC_MPRV, KC_MPLY, KC_MNXT, XXXXXXX, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| | |||
KC_LGUI, _______, KC_ESC, KC_ENT, MO(3), KC_RALT | |||
//`--------------------------' `--------------------------' | |||
), | |||
[2] = LAYOUT_split_3x5_3( | |||
//,--------------------------------------------. ,--------------------------------------------. | |||
KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, | |||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| | |||
KC_LGUI, MO(3), KC_ESC, KC_DEL, _______, KC_RALT | |||
//`--------------------------' `--------------------------' | |||
), | |||
[3] = LAYOUT_split_3x5_3( | |||
//,--------------------------------------------. ,--------------------------------------------. | |||
QK_BOOT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| | |||
KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT | |||
//`--------------------------' `--------------------------' | |||
) | |||
}; |
@ -0,0 +1,79 @@ | |||
/* | |||
* Copyright 2022 Kevin Gee <info@controller.works> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#ifdef RGB_MATRIX_ENABLE | |||
//# define SPLIT_TRANSPORT_MIRROR | |||
# define RGB_MATRIX_KEYPRESSES // reacts to keypresses | |||
// # define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses) | |||
// # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects | |||
# define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended | |||
# define RGB_MATRIX_FRAMEBUFFER_EFFECTS | |||
// # define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness) | |||
// # define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness) | |||
# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150 // limits maximum brightness of LEDs to 150 out of 255. Higher may cause the controller to crash. | |||
# define RGB_MATRIX_HUE_STEP 8 | |||
# define RGB_MATRIX_SAT_STEP 8 | |||
# define RGB_MATRIX_VAL_STEP 8 | |||
# define RGB_MATRIX_SPD_STEP 10 | |||
# define ENABLE_RGB_MATRIX_ALPHAS_MODS | |||
# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN | |||
# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT | |||
# define ENABLE_RGB_MATRIX_BREATHING | |||
# define ENABLE_RGB_MATRIX_BAND_SAT | |||
# define ENABLE_RGB_MATRIX_BAND_VAL | |||
# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT | |||
# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL | |||
# define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT | |||
# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL | |||
# define ENABLE_RGB_MATRIX_CYCLE_ALL | |||
# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT | |||
# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN | |||
# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON | |||
# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN | |||
# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL | |||
# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL | |||
# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL | |||
# define ENABLE_RGB_MATRIX_DUAL_BEACON | |||
# define ENABLE_RGB_MATRIX_RAINBOW_BEACON | |||
# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS | |||
# define ENABLE_RGB_MATRIX_RAINDROPS | |||
# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS | |||
# define ENABLE_RGB_MATRIX_HUE_BREATHING | |||
# define ENABLE_RGB_MATRIX_HUE_PENDULUM | |||
# define ENABLE_RGB_MATRIX_HUE_WAVE | |||
# define ENABLE_RGB_MATRIX_PIXEL_RAIN | |||
# define ENABLE_RGB_MATRIX_PIXEL_FLOW | |||
# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL | |||
// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined | |||
# define ENABLE_RGB_MATRIX_TYPING_HEATMAP | |||
# define ENABLE_RGB_MATRIX_DIGITAL_RAIN | |||
// enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS | |||
# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS | |||
# define ENABLE_RGB_MATRIX_SPLASH | |||
# define ENABLE_RGB_MATRIX_MULTISPLASH | |||
# define ENABLE_RGB_MATRIX_SOLID_SPLASH | |||
# define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH | |||
#endif |
@ -0,0 +1,68 @@ | |||
/* | |||
* Copyright 2022 Kevin Gee <info@controller.works> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT_split_3x5_3( | |||
//,--------------------------------------------. ,--------------------------------------------. | |||
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
LCTL_T(KC_A), KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, | |||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| | |||
KC_LGUI, MO(1), KC_SPC, KC_SPC, MO(2), GUI_T(KC_TAB) | |||
//`--------------------------' `--------------------------' | |||
), | |||
[1] = LAYOUT_split_3x5_3( | |||
//,--------------------------------------------. ,--------------------------------------------. | |||
KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
KC_TAB, XXXXXXX, XXXXXXX, XXXXXXX, KC_PGUP, XXXXXXX, KC_UP, XXXXXXX, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
KC_MPRV, KC_MPLY, KC_MNXT, XXXXXXX, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| | |||
KC_LGUI, _______, KC_ESC, KC_ENT, MO(3), KC_RALT | |||
//`--------------------------' `--------------------------' | |||
), | |||
[2] = LAYOUT_split_3x5_3( | |||
//,--------------------------------------------. ,--------------------------------------------. | |||
KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, | |||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| | |||
KC_LGUI, MO(3), KC_ESC, KC_DEL, _______, KC_RALT | |||
//`--------------------------' `--------------------------' | |||
), | |||
[3] = LAYOUT_split_3x5_3( | |||
//,--------------------------------------------. ,--------------------------------------------. | |||
QK_BOOT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------| | |||
RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| | |||
KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT | |||
//`--------------------------' `--------------------------' | |||
) | |||
}; |
@ -0,0 +1 @@ | |||
VIA_ENABLE = yes |
@ -0,0 +1,23 @@ | |||
/* | |||
* Copyright 2022 Kevin Gee <info@controller.works> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include_next "mcuconf.h" | |||
#undef RP_I2C_USE_I2C0 | |||
#define RP_I2C_USE_I2C0 TRUE |
@ -0,0 +1,82 @@ | |||
/* | |||
* Copyright 2022 Kevin Gee <info@controller.works> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "quantum.h" | |||
#ifdef OLED_ENABLE | |||
static void render_logo(void) { | |||
static const char PROGMEM raw_logo[] = { | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6,134,230,126, 30, 6, 0, 0, 0, 0, 0,128,192, 96, 56, 28, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,252, 6, 3, 3, 3, 3, 7,254,252, 6, 3, 3, 3, 3, 6,252,248, 0, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 0, 0,248,252, 6, 3, 3, 3, 3, 3, 3, 6,252,248, 0, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 31, 27, 24, 48,224,192, 0, 0,240,252, 62, 27, 25, 24, 24, 24, 24, 48,224,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127,127, 0, 0, 0, 0, 0, 0,127,127, 0, 0, 0, 0, 0, 0,127,127, 0, 0, 0, 0, 0, 0,127,127, 0, 0, 0, 0, 0, 0,127,127, 0, 0, 0, 0, 0, 0, 0, 0,127,127, 0, 0, 0, 0, 0, 0,127,127, 0, 0, 0, 0, 0, 12, 24, 48, 96, 96, 96, 96, 96, 96, 48, 31, 15, 0, 0, 15, 31, 48, 96, 96, 96, 96, 96, 96, 48, 31, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
}; | |||
oled_write_raw_P(raw_logo, sizeof(raw_logo)); | |||
} | |||
oled_rotation_t oled_init_kb(oled_rotation_t rotation) { | |||
if (!is_keyboard_master()) { | |||
return OLED_ROTATION_180; // flips the display 180 degrees if offhand | |||
} | |||
return rotation; | |||
} | |||
bool render_status(void) { | |||
// Host Keyboard Layer Status | |||
oled_write_P(PSTR("Layer: "), false); | |||
switch (get_highest_layer(layer_state)) { | |||
case 0: | |||
oled_write_P(PSTR("BASE\n"), false); | |||
break; | |||
case 1: | |||
oled_write_P(PSTR("LOWER\n"), false); | |||
break; | |||
case 2: | |||
oled_write_P(PSTR("RAISE\n"), false); | |||
break; | |||
case 3: | |||
oled_write_P(PSTR("ADJUST\n"), false); | |||
break; | |||
default: | |||
// Or use the write_ln shortcut over adding '\n' to the end of your string | |||
oled_write_ln_P(PSTR("Undefined"), false); | |||
} | |||
// Host Keyboard LED Status | |||
led_t led_state = host_keyboard_led_state(); | |||
oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false); | |||
oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false); | |||
oled_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false); | |||
return false; | |||
} | |||
bool oled_task_kb(void) { | |||
if (!oled_task_user()) { | |||
return false; | |||
} | |||
if (is_keyboard_master()) { | |||
render_status(); // Renders the current keyboard state (layer, lock, caps, scroll, etc) | |||
} else { | |||
render_logo(); // Renders a static logo | |||
oled_scroll_left(); // Turns on scrolling | |||
} | |||
return false; | |||
} | |||
#endif |
@ -0,0 +1,43 @@ | |||
# mini36 | |||
![mini36](https://i.imgur.com/JwhiE9ll.png) | |||
![mini36PCB](https://i.imgur.com/6NjZ8Cql.jpg) | |||
*A pre-built, low profile, split mechanical keyboard with 36 keys based on the RP2040 processor* | |||
* Keyboard Maintainer: [Kevin Gee](https://github.com/controller-works) | |||
* Hardware Supported: *mini36 split ergonomic keyboard* | |||
* Hardware Availability: *https://controller.works/products/mini36-low-profile-ergonomic-keyboard* Hardware is available as pre-built units only. | |||
Make example for this keyboard (after setting up your build environment): | |||
```sh | |||
make controllerworks/mini36:default | |||
``` | |||
Flashing example for this keyboard: | |||
```sh | |||
make controllerworks/mini36:default:flash | |||
``` | |||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). | |||
## Features | |||
- Highly integrated design with microcontroller, USB and TRRS connectors, and OLED all integrated on the main board with no secondary modules | |||
- RP2040 processor by Raspberry Pi Foundation running at 130 MHz with 16MB flash memory | |||
- CNC milled aluminum case with only 8mm thickness | |||
- "PCB art" shine through back plate with gold surface finish | |||
- 128x32 OLED on each keyboard half | |||
- 36 per-key RGB LEDs and 12 backlight RGB LEDS are individually addressable | |||
- ESD and over-current protection on USB and TRRS connectors | |||
- Reset and boot tactile switches | |||
- USB C host connection | |||
- Hot swap connectors for Kailh Chocolate PG1350 switches | |||
- Chocolate key spacing (18mm horizontal x 17mm vertical) | |||
## Bootloader | |||
Enter the bootloader in 3 ways: | |||
* **Bootmagic reset**: Hold down the upper left key on the left hand keyboard half or the upper right key on the right hand keyboard half while plugging in USB | |||
* **Physical reset button**: Press the RST button twice, rapidly | |||
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available |
@ -0,0 +1,3 @@ | |||
SERIAL_DRIVER = vendor | |||
WS2812_DRIVER = vendor | |||
OLED_DRIVER = SSD1306 |
@ -0,0 +1,35 @@ | |||
/* Copyright 2021 farhandsome | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
/* BASE */ | |||
[0] = LAYOUT_60_ansi_tsangan_arrowkeys( | |||
QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, | |||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_RSFT, KC_UP, KC_SLSH, | |||
KC_LCTL, KC_LCMD, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RGHT | |||
), | |||
/* FN */ | |||
[1] = LAYOUT_60_ansi_tsangan_arrowkeys( | |||
QK_BOOT, 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, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, MO(1), _______, _______, _______ | |||
) | |||
}; |
@ -0,0 +1,35 @@ | |||
/* Copyright 2021 farhandsome | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
/* BASE */ | |||
[0] = LAYOUT_60_ansi_tsangan( | |||
QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, | |||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, | |||
KC_LCTL, KC_LCMD, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL | |||
), | |||
/* FN */ | |||
[1] = LAYOUT_60_ansi_tsangan( | |||
QK_BOOT, 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_UP, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, | |||
_______, _______, _______, _______, _______, MO(1), _______ | |||
) | |||
}; |
@ -0,0 +1,35 @@ | |||
/* Copyright 2021 farhandsome | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
/* BASE */ | |||
[0] = LAYOUT_60_iso_tsangan_arrowkeys( | |||
QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, | |||
KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_RSFT, KC_UP, KC_SLSH, | |||
KC_LCTL, KC_LCMD, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RGHT | |||
), | |||
/* FN */ | |||
[1] = LAYOUT_60_iso_tsangan_arrowkeys( | |||
QK_BOOT, 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, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, MO(1), _______, _______, _______ | |||
) | |||
}; |
@ -0,0 +1,35 @@ | |||
/* Copyright 2021 farhandsome | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
/* BASE */ | |||
[0] = LAYOUT_60_iso_tsangan( | |||
QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, | |||
KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, | |||
KC_LCTL, KC_LCMD, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL | |||
), | |||
/* FN */ | |||
[1] = LAYOUT_60_iso_tsangan( | |||
QK_BOOT, 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_UP, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, | |||
_______, _______, _______, _______, _______, MO(1), _______ | |||
) | |||
}; |
@ -0,0 +1,42 @@ | |||
/* Copyright 2022 Huy Ta (@huytbt) | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include "config_common.h" | |||
/* key matrix size */ | |||
#define MATRIX_ROWS 4 | |||
#define MATRIX_COLS 14 | |||
/* | |||
* Keyboard Matrix Assignments | |||
* COLS: AVR pins used for columns, left to right | |||
* ROWS: AVR pins used for rows, top to bottom | |||
*/ | |||
#define MATRIX_ROW_PINS { D1, D0, D4, C6 } | |||
#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2, B6, D7, E6, B4, B5, D2, D3 } | |||
#define LED_CAPS_LOCK_PIN D5 | |||
/* COL2ROW or ROW2COL */ | |||
#define DIODE_DIRECTION COL2ROW | |||
/* define if matrix has ghost */ | |||
// #define MATRIX_HAS_GHOST | |||
/* Set 0 if debouncing isn't needed */ | |||
#define DEBOUNCE 5 |
@ -0,0 +1,17 @@ | |||
/* Copyright 2022 Huy Ta (@huytbt) | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "h50.h" |
@ -0,0 +1,35 @@ | |||
/* Copyright 2022 Huy Ta (@huytbt) | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include "quantum.h" | |||
#define XXX KC_NO | |||
/* h50 keymap definition macro | |||
*/ | |||
#define LAYOUT( \ | |||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, \ | |||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, \ | |||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, \ | |||
k30, k31, k32, k33, k35, k37, k39, k3A, k3B, k3C, k3D \ | |||
) { \ | |||
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D }, \ | |||
{ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D }, \ | |||
{ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D }, \ | |||
{ k30, k31, k32, k33, XXX, k35, XXX, k37, XXX, k39, k3A, k3B, k3C, k3D } \ | |||
} |
@ -0,0 +1,72 @@ | |||
{ | |||
"keyboard_name": "H50", | |||
"url": "https://github.com/huytbt/h50-keyboard", | |||
"maintainer": "huytbt", | |||
"usb": { | |||
"vid": "0x4859", | |||
"pid": "0x0002", | |||
"device_version": "0.0.1" | |||
}, | |||
"layouts": { | |||
"LAYOUT": { | |||
"layout": [ | |||
{ "label": "Tab", "x": 0, "y": 0 }, | |||
{ "label": "Q", "x": 1, "y": 0 }, | |||
{ "label": "W", "x": 2, "y": 0 }, | |||
{ "label": "E", "x": 3, "y": 0 }, | |||
{ "label": "R", "x": 4, "y": 0 }, | |||
{ "label": "T", "x": 5, "y": 0 }, | |||
{ "label": "Y", "x": 6, "y": 0 }, | |||
{ "label": "U", "x": 7, "y": 0 }, | |||
{ "label": "I", "x": 8, "y": 0 }, | |||
{ "label": "O", "x": 9, "y": 0 }, | |||
{ "label": "P", "x": 10, "y": 0 }, | |||
{ "label": "[", "x": 11, "y": 0 }, | |||
{ "label": "]", "x": 12, "y": 0 }, | |||
{ "label": "Back<br>Space", "x": 13, "y": 0 }, | |||
{ "label": "Caps", "x": 0, "y": 1, "w": 1.25 }, | |||
{ "label": "A", "x": 1.25, "y": 1 }, | |||
{ "label": "S", "x": 2.25, "y": 1 }, | |||
{ "label": "D", "x": 3.25, "y": 1 }, | |||
{ "label": "F", "x": 4.25, "y": 1 }, | |||
{ "label": "G", "x": 5.25, "y": 1 }, | |||
{ "label": "H", "x": 6.25, "y": 1 }, | |||
{ "label": "J", "x": 7.25, "y": 1 }, | |||
{ "label": "K", "x": 8.25, "y": 1 }, | |||
{ "label": "L", "x": 9.25, "y": 1 }, | |||
{ "label": ";", "x": 10.25, "y": 1 }, | |||
{ "label": "'", "x": 11.25, "y": 1 }, | |||
{ "label": "Enter", "x": 12.25, "y": 1, "w": 1.75 }, | |||
{ "label": "PGUP", "x": 14, "y": 1 }, | |||
{ "label": "Shift", "x": 0, "y": 2, "w": 1.75 }, | |||
{ "label": "Z", "x": 1.75, "y": 2 }, | |||
{ "label": "X", "x": 2.75, "y": 2 }, | |||
{ "label": "C", "x": 3.75, "y": 2 }, | |||
{ "label": "V", "x": 4.75, "y": 2 }, | |||
{ "label": "B", "x": 5.75, "y": 2 }, | |||
{ "label": "N", "x": 6.75, "y": 2 }, | |||
{ "label": "M", "x": 7.75, "y": 2 }, | |||
{ "label": ",", "x": 8.75, "y": 2 }, | |||
{ "label": ".", "x": 9.75, "y": 2 }, | |||
{ "label": "/", "x": 10.75, "y": 2 }, | |||
{ "label": "Shift", "x": 11.75, "y": 2, "w": 1.25 }, | |||
{ "label": "Up", "x": 13, "y": 2 }, | |||
{ "label": "PGDN", "x": 14, "y": 2 }, | |||
{ "label": "Ctrl", "x": 0, "y": 3, "w": 1.25 }, | |||
{ "label": "Alt", "x": 1.25, "y": 3, "w": 1.25 }, | |||
{ "label": "Super", "x": 2.5, "y": 3, "w": 1.25 }, | |||
{ "x": 3.75, "y": 3, "w": 1.75 }, | |||
{ "x": 5.5, "y": 3, "w": 1.75 }, | |||
{ "label": "Fn1", "x": 7.25, "y": 3, "w": 1.75 }, | |||
{ "label": "Fn2", "x": 9, "y": 3, "w": 1.25 }, | |||
{ "label": "Fn3", "x": 10.25, "y": 3, "w": 1.25 }, | |||
{ "label": "Left", "x": 12, "y": 3 }, | |||
{ "label": "Down", "x": 13, "y": 3 }, | |||
{ "label": "Right", "x": 14, "y": 3 } | |||
] | |||
} | |||
} | |||
} |
@ -0,0 +1,51 @@ | |||
/* Copyright 2022 Huy Ta (@huytbt) | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
/* this keymap is to provide a basic keyboard layout for testing the matrix | |||
* for more practical and complicated keymap refer to other keymaps in the same folder | |||
*/ | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT( | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, | |||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, | |||
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_SPC, MO(1), MO(2), MO(3), KC_LEFT, KC_DOWN, KC_RGHT | |||
), | |||
[1] = LAYOUT( | |||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS | |||
), | |||
[2] = LAYOUT( | |||
KC_ESC, 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS | |||
), | |||
[3] = LAYOUT( | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS | |||
), | |||
}; |
@ -0,0 +1,51 @@ | |||
/* Copyright 2022 Huy Ta (@huytbt) | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
/* this keymap is to provide a basic keyboard layout for testing the matrix | |||
* for more practical and complicated keymap refer to other keymaps in the same folder | |||
*/ | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT( | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, | |||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, | |||
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_SPC, MO(1), MO(2), MO(3), KC_LEFT, KC_DOWN, KC_RGHT | |||
), | |||
[1] = LAYOUT( | |||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS | |||
), | |||
[2] = LAYOUT( | |||
KC_ESC, 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS | |||
), | |||
[3] = LAYOUT( | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS | |||
), | |||
}; |
@ -0,0 +1 @@ | |||
VIA_ENABLE = yes |
@ -0,0 +1,27 @@ | |||
# H50 | |||
![h50](https://i.imgur.com/1dB2mfMh.jpeg) | |||
The H50 is a mini keyboard with a 50 percent layout. The keyboard consists of 53 keys. | |||
* Keyboard Maintainer: [huytbt](https://github.com/huytbt) | |||
* Hardware Supported: Handwired | |||
* Hardware Availability: You can follow the build guide here <https://github.com/huytbt/h50-keyboard> | |||
Make example for this keyboard (after setting up your build environment): | |||
make huytbt/h50:default | |||
Flashing example for this keyboard: | |||
make huytbt/h50:default:flash | |||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). | |||
## Bootloader | |||
Enter the bootloader in 3 ways: | |||
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard | |||
* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead | |||
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available |
@ -0,0 +1,16 @@ | |||
# MCU name | |||
MCU = atmega32u4 | |||
# Bootloader selection | |||
BOOTLOADER = atmel-dfu | |||
# Build Options | |||
# change yes to no to disable | |||
# | |||
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite | |||
MOUSEKEY_ENABLE = yes # Mouse keys | |||
EXTRAKEY_ENABLE = yes # Audio control and System control | |||
CONSOLE_ENABLE = no # Console for debug | |||
COMMAND_ENABLE = no # Commands for debug and configuration | |||
NKRO_ENABLE = no # Enable N-Key Rollover | |||
BACKLIGHT_ENABLE = no # Disable keyboard backlight functionality |
@ -0,0 +1,7 @@ | |||
// Copyright 2021 Dan Kim (@syntax-magic) | |||
// SPDX-License-Identifier: GPL-2.0-or-later | |||
#pragma once | |||
#define TAPPING_TERM 168 | |||
#define TAPPING_TERM_PER_KEY |
@ -0,0 +1 @@ | |||
TAP_DANCE_ENABLE = yes |
@ -1,4 +1,4 @@ | |||
# Keymap by tuananhnguyen204, supported by thaoOil, phamMinhThuy, nguyenHuyenTrang | |||
ANSI layout with split backspace. | |||
Made with `LAYOUT_65_ansi_blocker_tsangan` | |||
Made with `LAYOUT_65_ansi_blocker_tsangan_split_bs` |