1
0
Fork 0

[Keyboard] Georgi FW updates (#5609)

* Working on chording

* Working on chording

* Got layouts in order

* Initial Georgi support

* forgot to add keymaps

* Updated readme

* Update keyboards/georgi/keymaps/template/readme.md

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/georgi.h

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/keymaps/default/keymap.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/keymaps/default/keymap.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/rules.mk

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/rules.mk

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/matrix.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/georgi.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/georgi.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/rules.mk

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/keymaps/default/keymap.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/keymaps/template/keymap.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/matrix.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Disabled features, updated info

* Update keyboards/georgi/config.h

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/config.h

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Fixed info.json

* Split the number button and fixed gaming mode.

* started work on history feature

* Working history/multikeyfuckery

* type

* inital code reduction refactor

* Got multikey patched up, optimizing for size

* Forgot to remove stuff

* fixed key repeat

* Key repeat added.

* Symshift locking

* Midchord Sym shenanigans.

* Added only QWERTY mode

* Split out header

* Added stickybits, minimal layour

* Fixing user layout

* Whitespace fixing

* Fixing Version name
This commit is contained in:
Jeremy Bernhardt 2019-04-14 12:01:52 -06:00 committed by Drashna Jaelre
parent a6857d18e1
commit 61a7aebd16
19 changed files with 1426 additions and 674 deletions

View file

@ -23,15 +23,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Defaults */
#define VERSION "Alpha 01: Ted "
#define VERSION "v1.0: Stenoknight"
#define VERBOSE
#define FORCE_NKRO
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
#define NO_DEBUG
#define NO_ACTION_ONESHOT
#define NO_ACTION_FUNCTION
#define NO_ACTION_MACRO
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED

View file

@ -15,52 +15,56 @@
#include "keymap_steno.h"
#define IGNORE_MOD_TAP_INTERRUPT
int getKeymapCount(void);
// Proper Layers
#define FUNCT (LSD | LK | LP | LH)
#define MEDIA (LSD | LK | LW | LR)
#define MOVE (ST1 | ST2)
// QMK Layers
#define STENO_LAYER 0
#define GAMING 1
#define GAMING_2 2
/* Keyboard Layout
* ,---------------------------------. ,------------------------------.
* | FN | LSU | LFT | LP | LH | ST1 | | ST3 | RF | RP | RL | RT | RD |
* |-----+-----+-----+----+----|-----| |-----|----+----+----+----+----|
* | PWR | LSD | LK | LW | LR | ST2 | | ST4 | RR | RG | RB | RS | RZ |
* | PWR | LSD | LK | LW | LR | ST2 | | ST4 | RR | BB | RG | RS | RZ |
* `---------------------------------' `------------------------------'
* ,---------------, .---------------.
* | NUM | LA | LO | | RE | RU | NUM |
* | LNO | LA | LO | | RE | RU | RNO |
* `---------------' `---------------'
*/
// YOU MUST ORDER THIS!
// P Will return from processing on the first match it finds. Therefore
// PJ Will run the requested action, remove the matched chord and continue
//
// First any chords that would conflict with PJs need to be checked, then PJs, lastly Ps.
// For all chords should be ordered by length in their section!
// Note: You can only use basic keycodes here!
// P() is just a wrapper to make your life easier.
//
// http://docs.gboards.ca
bool processQwerty(void) {
// Place P's that would be trashed by PJ's here
P( RT | RS | RD | RZ | NUM, SEND_STRING(VERSION); SEND_STRING(__DATE__));
P( NUM | LA | LO | RE | RU, SEND(KC_MPLY));
P( ST1 | ST2 | ST3 | ST4, SEND(KC_BSPC));
uint32_t processQwerty(bool lookup) {
// Specials
P( RT | RS | RD | RZ | LNO, SEND_STRING(VERSION); SEND_STRING(__DATE__));
P( LNO | RNO | LA | LO | RE | RU, SEND(KC_MPLY));
P( LFT | LK | LP | LW, REPEAT());
P( ST1 | ST2 | LW | ST4, SEND(KC_BSPC));
// Mouse Keys
P( LO | LSD | LK, CLICK_MOUSE(KC_MS_BTN2));
P( LO | LR | LW, CLICK_MOUSE(KC_MS_BTN1));
// Thumb Chords
P( LA | LO | RE | RU, SEND(KC_CAPS));
P( LA | RU, SEND(KC_ESC));
PJ( LO | RE, SEND(KC_LCTL));
PJ( NUM | LA | RU, SEND(KC_LCTL); SEND(KC_LSFT));
PJ( NUM | LA | RE, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));
P( LO | RE, SEND(KC_LCTL));
P( LNO | RNO | LA | RU, SEND(KC_LCTL); SEND(KC_LSFT));
P( LNO | LA | RE, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));
// Mods
PJ( RT | RD | RS | RZ, SEND(KC_LGUI));
PJ( RT | RD, SEND(KC_LCTL));
PJ( RS | RZ, SEND(KC_LALT));
PJ( LA | NUM, SEND(KC_LCTL));
PJ( LA | LO, SEND(KC_LALT));
PJ( LO, SEND(KC_LSFT));
P( RT | RD | RS | RZ, SEND(KC_LGUI));
P( RT | RD, SEND(KC_LCTL));
P( RS | RZ, SEND(KC_LALT));
P( LA | LNO, SEND(KC_LCTL));
P( LA | LO, SEND(KC_LALT));
P( LO, SEND(KC_LSFT));
// Function Layer
P( FUNCT | RF | RR, SEND(KC_F5));
@ -93,68 +97,43 @@ bool processQwerty(void) {
P( MEDIA | RZ, SEND(KC_VOLD));
P( MEDIA | RS, SEND(KC_MUTE));
// Mouse Keys
P( LP | LH, clickMouse(KC_MS_BTN1));
P( LW | LR, clickMouse(KC_MS_BTN2));
// Number Row, Left
P( LNO | LSU, SEND(KC_1));
P( LNO | LFT, SEND(KC_2));
P( LNO | LP, SEND(KC_3));
P( LNO | LH, SEND(KC_4));
P( LNO | ST1, SEND(KC_5));
P( LNO | ST3, SEND(KC_6));
P( LNO | RF, SEND(KC_7));
P( LNO | RP, SEND(KC_8));
P( LNO | RL, SEND(KC_9));
P( LNO | RT, SEND(KC_0));
// Number Row
P( NUM | LSU, SEND(KC_1));
P( NUM | LFT, SEND(KC_2));
P( NUM | LP, SEND(KC_3));
P( NUM | LH, SEND(KC_4));
P( NUM | ST1, SEND(KC_5));
P( NUM | ST3, SEND(KC_6));
P( NUM | RF, SEND(KC_7));
P( NUM | RP, SEND(KC_8));
P( NUM | RL, SEND(KC_9));
P( NUM | RT, SEND(KC_0));
P( NUM | LA, SEND(KC_5));
P( NUM | RT, SEND(KC_0));
// Number Row, Right
P( RNO | LSU, SEND(KC_1));
P( RNO | LFT, SEND(KC_2));
P( RNO | LP, SEND(KC_3));
P( RNO | LH, SEND(KC_4));
P( RNO | ST1, SEND(KC_5));
P( RNO | ST3, SEND(KC_6));
P( RNO | RF, SEND(KC_7));
P( RNO | RP, SEND(KC_8));
P( RNO | RL, SEND(KC_9));
P( RNO | RT, SEND(KC_0));
P( RNO | LA, SEND(KC_5));
// Specials
P( LA | NUM, SEND(KC_ESC));
P( RU | NUM, SEND(KC_TAB));
P( RU | RNO, SEND(KC_TAB));
P( RE | RU, SEND(KC_BSPC));
P( RD | RZ, SEND(KC_ENT));
P( RE, SEND(KC_ENT));
P( RD, SEND(KC_BSPC));
P( NUM, SEND(KC_BSPC));
P( LNO, SEND(KC_BSPC));
P( RNO, SEND(KC_BSPC));
P( LA, SEND(KC_SPC));
P( RU, SEND(KC_SPC));
P( RZ, SEND(KC_ESC));
// Letters
P( LSU | LSD, SEND(KC_A));
P( LFT | LK, SEND(KC_S));
P( LP | LW, SEND(KC_D));
P( LH | LR, SEND(KC_F));
P( ST1 | ST2, SEND(KC_G));
P( ST3 | ST4, SEND(KC_H));
P( RF | RR, SEND(KC_J));
P( RT | RS, SEND(KC_SCLN))
P( RG | RL, SEND(KC_L));
P( RP | RB, SEND(KC_K));
P( LSU, SEND(KC_Q));
P( LSD, SEND(KC_Z));
P( LFT, SEND(KC_W));
P( LK, SEND(KC_X));
P( LP, SEND(KC_E));
P( LW, SEND(KC_C));
P( LH, SEND(KC_R));
P( LR, SEND(KC_V));
P( ST1, SEND(KC_T));
P( ST2, SEND(KC_B));
P( ST3, SEND(KC_Y));
P( ST4, SEND(KC_N));
P( RF, SEND(KC_U));
P( RR, SEND(KC_M));
P( RP, SEND(KC_I));
P( RB, SEND(KC_COMM));
P( RL, SEND(KC_O));
P( RG, SEND(KC_DOT));
P( RT, SEND(KC_P));
P( RS, SEND(KC_SLSH));
// Symbols and Numbers
P( PWR | RE | RU, SEND(KC_ENT));
P( PWR | LA | LO, SEND(KC_SPC));
@ -185,45 +164,75 @@ bool processQwerty(void) {
P( PWR | RT, SEND(KC_PAST));
P( PWR | RS, SEND(KC_DOT));
P( PWR | RD, SEND(KC_TAB));
P( PWR | LA, SEND(KC_SCLN));
P( PWR | LA, SEND(KC_LSFT));
P( PWR | LO, SEND(KC_SLSH));
P( PWR | RE, SEND(KC_SCLN));
P( PWR | RU, SEND(KC_SLSH));
P( PWR | RU, SEND(KC_BSLS));
P( PWR | LNO, SEND(KC_BSLS));
// Letters
P( LSU | LSD, SEND(KC_A));
P( LFT | LK, SEND(KC_S));
P( LP | LW, SEND(KC_D));
P( LH | LR, SEND(KC_F));
P( ST1 | ST2, SEND(KC_G));
P( ST3 | ST4, SEND(KC_H));
P( RF | RR, SEND(KC_J));
P( RT | RS, SEND(KC_SCLN));
P( RG | RL, SEND(KC_L));
P( RP | RB, SEND(KC_K));
P( LSU, SEND(KC_Q));
P( LSD, SEND(KC_Z));
P( LFT, SEND(KC_W));
P( LK, SEND(KC_X));
P( LP, SEND(KC_E));
P( LW, SEND(KC_C));
P( LH, SEND(KC_R));
P( LR, SEND(KC_V));
P( ST1, SEND(KC_T));
P( ST2, SEND(KC_B));
P( ST3, SEND(KC_Y));
P( ST4, SEND(KC_N));
P( RF, SEND(KC_U));
P( RR, SEND(KC_M));
P( RP, SEND(KC_I));
P( RB, SEND(KC_COMM));
P( RL, SEND(KC_O));
P( RG, SEND(KC_DOT));
P( RT, SEND(KC_P));
P( RS, SEND(KC_SLSH));
P( RNO, SEND(KC_BSPC));
P( LNO, SEND(KC_BSPC));
// If we make here, send as a steno chord
// If plover is running we can hook that host side
return false;
return 0;
}
#define STENO_LAYER 0
#define GAMING 1
#define GAMING_2 2
// "Layers"
// Steno layer should be first in your map.
// When PWR | FN | RR | RG | RB | RS is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you have only a single layer, you must set SINGLELAYER = yes in your rules.mk, otherwise you may experince undefined behaviour
// When PWR | FN | ST3 | ST4 is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you need more space for chords, remove the two gaming layers.
// Note: If using NO_ACTION_TAPPING, LT will not work!
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Main layer, everything goes through here
[STENO_LAYER] = LAYOUT_georgi(
STN_FN, STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1, STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR,
STN_PWR, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2, STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR,
STN_N1, STN_A, STN_O, STN_E, STN_U, STN_N1)
,
STN_N1, STN_A, STN_O, STN_E, STN_U, STN_N7
),
// Gaming layer with Numpad, Very limited
[GAMING] = LAYOUT_georgi(
KC_LSFT, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_ENT,
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_DQUO,
KC_LALT, KC_SPC, LT(GAMING_2, KC_ENT), KC_DEL, KC_ASTR, TO(STENO_LAYER)),
KC_LALT, KC_SPC, LT(GAMING_2, KC_ENT), KC_DEL, KC_ASTR, TO(STENO_LAYER)
),
[GAMING_2] = LAYOUT_georgi(
KC_LSFT, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_LT, KC_GT, KC_QUES, KC_RSFT,
KC_LALT, KC_SPC, KC_ENT, KC_DEL, KC_ASTR, TO(STENO_LAYER))
KC_LALT, KC_SPC, KC_ENT, KC_DEL, KC_ASTR, TO(STENO_LAYER)
)
};
int getKeymapCount(void) {
return sizeof(keymaps)/sizeof(keymaps[0]);
}
// Don't fuck with this, thanks.
size_t keymapsCount = sizeof(keymaps)/sizeof(keymaps[0]);

View file

@ -1,18 +1,23 @@
#----------------------------------------------------------------------------
# make georgi:extrakey:dfu
# make georgi:default:dfu
# Make sure you have dfu-programmer installed!
#----------------------------------------------------------------------------
#Debug options
NO_REPEAT = no
VERBOSE = yes
CONSOLE_ENABLE = yes
DEBUG_MATRIX_SCAN_RATE = no
DEBUG_MATRIX = no
KEYBOARD_SHARED_EP = yes
CUSTOM_MATRIX = yes
MOUSEKEY_ENABLE = yes
SINGLE_LAYER = no
#Firmware reduction options
MOUSEKEY_ENABLE = yes # 1500 bytes
NO_TAPPING = no # 2000 bytes
NO_PRINT = yes
#Debug options
CONSOLE_ENABLE = no
DEBUG_MATRIX_SCAN_RATE = no
DEBUG_MATRIX = no
ONLY_QWERTY = no
# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.
@ -22,6 +27,15 @@ SRC += matrix.c i2c_master.c
ifeq ($(strip $(DEBUG_MATRIX)), yes)
OPT_DEFS += -DDEBUG_MATRIX
endif
ifeq ($(strip $(SINGLE_LAYER)), yes)
OPT_DEFS += -DSINGLE_LAYER
ifeq ($(strip $(NO_REPEAT)), yes)
OPT_DEFS += -DNO_REPEAT
endif
ifeq ($(strip $(NO_PRINT)), yes)
OPT_DEFS += -DNO_PRINT -DNO_DEBUG
endif
ifeq ($(strip $(ONLY_QWERTY)), yes)
OPT_DEFS += -DONLYQWERTY
endif
ifeq ($(strip $(NO_TAPPING)), yes)
OPT_DEFS += -DNO_ACTION_TAPPING
endif

View file

@ -0,0 +1,223 @@
/*
* Good on you for modifying your layout, this is the most nonQMK layout you will come across
* There are three modes, Steno (the default), QWERTY (Toggleable) and a Momentary symbol layer
*
* Don't modify the steno layer directly, instead add chords using the keycodes and macros
* from sten.h to the layout you want to modify.
*
* Observe the comment above processQWERTY!
*
* http://docs.gboards.ca
*/
#include QMK_KEYBOARD_H
#include "sten.h"
#include "keymap_steno.h"
#define IGNORE_MOD_TAP_INTERRUPT
// Proper Layers
#define FUNCT (LSD | LK | LP | LH)
#define MEDIA (LSD | LK | LW | LR)
#define MOVE (ST1 | ST2)
// QMK Layers
#define STENO_LAYER 0
/* Keyboard Layout
* ,---------------------------------. ,------------------------------.
* | FN | LSU | LFT | LP | LH | ST1 | | ST3 | RF | RP | RL | RT | RD |
* |-----+-----+-----+----+----|-----| |-----|----+----+----+----+----|
* | PWR | LSD | LK | LW | LR | ST2 | | ST4 | RR | BB | RG | RS | RZ |
* `---------------------------------' `------------------------------'
* ,---------------, .---------------.
* | LNO | LA | LO | | RE | RU | RNO |
* `---------------' `---------------'
*/
// Note: You can only use basic keycodes here!
// P() is just a wrapper to make your life easier.
//
// http://docs.gboards.ca
uint32_t processQwerty(bool lookup) {
// Specials
P( RT | RS | RD | RZ | LNO, SEND_STRING(VERSION); SEND_STRING(__DATE__));
P( LNO | RNO | LA | LO | RE | RU, SEND(KC_MPLY));
P( LFT | LK | LP | LW, REPEAT());
P( ST1 | ST2 | LW | ST4, SEND(KC_BSPC));
// Mouse Keys
P( LO | LSD | LK, CLICK_MOUSE(KC_MS_BTN2));
P( LO | LR | LW, CLICK_MOUSE(KC_MS_BTN1));
// Thumb Chords
P( LA | LO | RE | RU, SEND(KC_CAPS));
P( LA | RU, SEND(KC_ESC));
P( LO | RE, SEND(KC_LCTL));
P( LNO | RNO | LA | RU, SEND(KC_LCTL); SEND(KC_LSFT));
P( LNO | LA | RE, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));
// Mods
P( RT | RD | RS | RZ, SEND(KC_LGUI));
P( RT | RD, SEND(KC_LCTL));
P( RS | RZ, SEND(KC_LALT));
P( LA | LNO, SEND(KC_LCTL));
P( LA | LO, SEND(KC_LALT));
P( LO, SEND(KC_LSFT));
// Function Layer
P( FUNCT | RF | RR, SEND(KC_F5));
P( FUNCT | RP | RB, SEND(KC_F6));
P( FUNCT | RL | RG, SEND(KC_F7));
P( FUNCT | RT | RS, SEND(KC_F8));
P( FUNCT | RF, SEND(KC_F1));
P( FUNCT | RP, SEND(KC_F2));
P( FUNCT | RL, SEND(KC_F3));
P( FUNCT | RT, SEND(KC_F4));
P( FUNCT | RR, SEND(KC_F9));
P( FUNCT | RG, SEND(KC_F10));
P( FUNCT | RB, SEND(KC_F11));
P( FUNCT | RS, SEND(KC_F12));
// Movement Layer
P( MOVE | RF, SEND(KC_LEFT));
P( MOVE | RP, SEND(KC_DOWN));
P( MOVE | RL, SEND(KC_UP));
P( MOVE | RT, SEND(KC_RIGHT));
P( MOVE | ST3, SEND(KC_PGUP));
P( MOVE | ST4, SEND(KC_PGDN));
// Media Layer
P( MEDIA | RF, SEND(KC_MPRV));
P( MEDIA | RP, SEND(KC_MPLY));
P( MEDIA | RL, SEND(KC_MPLY));
P( MEDIA | RT, SEND(KC_MNXT));
P( MEDIA | RD, SEND(KC_VOLU));
P( MEDIA | RZ, SEND(KC_VOLD));
P( MEDIA | RS, SEND(KC_MUTE));
// Number Row, Left
P( LNO | LSU, SEND(KC_1));
P( LNO | LFT, SEND(KC_2));
P( LNO | LP, SEND(KC_3));
P( LNO | LH, SEND(KC_4));
P( LNO | ST1, SEND(KC_5));
P( LNO | ST3, SEND(KC_6));
P( LNO | RF, SEND(KC_7));
P( LNO | RP, SEND(KC_8));
P( LNO | RL, SEND(KC_9));
P( LNO | RT, SEND(KC_0));
// Number Row, Right
P( RNO | LSU, SEND(KC_1));
P( RNO | LFT, SEND(KC_2));
P( RNO | LP, SEND(KC_3));
P( RNO | LH, SEND(KC_4));
P( RNO | ST1, SEND(KC_5));
P( RNO | ST3, SEND(KC_6));
P( RNO | RF, SEND(KC_7));
P( RNO | RP, SEND(KC_8));
P( RNO | RL, SEND(KC_9));
P( RNO | RT, SEND(KC_0));
P( RNO | LA, SEND(KC_5));
// Specials
P( RU | RNO, SEND(KC_TAB));
P( RE | RU, SEND(KC_BSPC));
P( RD | RZ, SEND(KC_ENT));
P( RE, SEND(KC_ENT));
P( RD, SEND(KC_BSPC));
P( LNO, SEND(KC_BSPC));
P( RNO, SEND(KC_BSPC));
P( LA, SEND(KC_SPC));
P( RU, SEND(KC_SPC));
P( RZ, SEND(KC_ESC));
// Symbols and Numbers
P( PWR | RE | RU, SEND(KC_ENT));
P( PWR | LA | LO, SEND(KC_SPC));
P( PWR | LP | LW, SEND(KC_LSFT); SEND(KC_9)); // (
P( PWR | LH | LR, SEND(KC_LSFT); SEND(KC_0)); // )
P( PWR | ST1 | ST2, SEND(KC_GRV)); // `
P( PWR | RD | RZ, SEND(KC_ESC));
P( PWR | LSU | LSD, SEND(KC_LSFT); SEND(KC_3)); // #
P( PWR | LFT | LK, SEND(KC_LSFT); SEND(KC_4)); // $
P( PWR | LSU, SEND(KC_LSFT); SEND(KC_1)); // !
P( PWR | LSD, SEND(KC_LSFT); SEND(KC_5)); // %
P( PWR | LFT, SEND(KC_LSFT); SEND(KC_2)); // @
P( PWR | LK, SEND(KC_LSFT); SEND(KC_6)); // ^
P( PWR | LP, SEND(KC_LSFT); SEND(KC_LBRC)); // {
P( PWR | LW, SEND(KC_LBRC));
P( PWR | LH, SEND(KC_LSFT); SEND(KC_RBRC)); // }
P( PWR | LR, SEND(KC_RBRC));
P( PWR | ST1, SEND(KC_LSFT); SEND(KC_BSLS)); // |
P( PWR | ST2, SEND(KC_LSFT); SEND(KC_GRV)); // ~
P( PWR | ST3, SEND(KC_QUOT));
P( PWR | ST4, SEND(KC_LSFT); SEND(KC_QUOT)); // "
P( PWR | RF, SEND(KC_KP_PLUS));
P( PWR | RR, SEND(KC_LSFT); SEND(KC_7)); // &
P( PWR | RP, SEND(KC_MINS));
P( PWR | RB, SEND(KC_EQL));
P( PWR | RL, SEND(KC_SLSH));
P( PWR | RG, SEND(KC_COMM));
P( PWR | RT, SEND(KC_PAST));
P( PWR | RS, SEND(KC_DOT));
P( PWR | RD, SEND(KC_TAB));
P( PWR | LA, SEND(KC_LSFT));
P( PWR | LO, SEND(KC_SLSH));
P( PWR | RE, SEND(KC_SCLN));
P( PWR | RU, SEND(KC_BSLS));
P( PWR | LNO, SEND(KC_BSLS));
// Letters
P( LSU | LSD, SEND(KC_A));
P( LFT | LK, SEND(KC_S));
P( LP | LW, SEND(KC_D));
P( LH | LR, SEND(KC_F));
P( ST1 | ST2, SEND(KC_G));
P( ST3 | ST4, SEND(KC_H));
P( RF | RR, SEND(KC_J));
P( RT | RS, SEND(KC_SCLN));
P( RG | RL, SEND(KC_L));
P( RP | RB, SEND(KC_K));
P( LSU, SEND(KC_Q));
P( LSD, SEND(KC_Z));
P( LFT, SEND(KC_W));
P( LK, SEND(KC_X));
P( LP, SEND(KC_E));
P( LW, SEND(KC_C));
P( LH, SEND(KC_R));
P( LR, SEND(KC_V));
P( ST1, SEND(KC_T));
P( ST2, SEND(KC_B));
P( ST3, SEND(KC_Y));
P( ST4, SEND(KC_N));
P( RF, SEND(KC_U));
P( RR, SEND(KC_M));
P( RP, SEND(KC_I));
P( RB, SEND(KC_COMM));
P( RL, SEND(KC_O));
P( RG, SEND(KC_DOT));
P( RT, SEND(KC_P));
P( RS, SEND(KC_SLSH));
P( RNO, SEND(KC_BSPC));
P( LNO, SEND(KC_BSPC));
return 0;
}
// "Layers"
// Steno layer should be first in your map.
// When PWR | FN | ST3 | ST4 is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you need more space for chords, remove the two gaming layers.
// Note: If using NO_ACTION_TAPPING, LT will not work!
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Main layer, everything goes through here
[STENO_LAYER] = LAYOUT_georgi(
STN_FN, STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1, STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR,
STN_PWR, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2, STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR,
STN_N1, STN_A, STN_O, STN_E, STN_U, STN_N7
)
};
// Don't fuck with this, thanks.
size_t keymapsCount = sizeof(keymaps)/sizeof(keymaps[0]);

View file

@ -0,0 +1,11 @@
# Georgi QWERTY/Steno firmware
This is the default keymap for Georgi, it's based heavily off of the naps62 ErgoDox and the Gergo layout.
It is both a ergonomic and programmer friendly keymap.
Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!
## Space issues
If you find yourself running out of space for dictionary entries, disabling mousekeys in rules.mk will save
you about 4k for entries!
Get a free 1k by deleting the Gaming layers from the keymap!

View file

@ -0,0 +1,41 @@
#----------------------------------------------------------------------------
# make georgi:default:dfu
# Make sure you have dfu-programmer installed!
#----------------------------------------------------------------------------
NO_REPEAT = no
VERBOSE = yes
KEYBOARD_SHARED_EP = yes
CUSTOM_MATRIX = yes
#Firmware reduction options
MOUSEKEY_ENABLE = no # 1500 bytes
NO_TAPPING = yes # 2000 bytes
NO_PRINT = yes
#Debug options
CONSOLE_ENABLE = no
DEBUG_MATRIX_SCAN_RATE = no
DEBUG_MATRIX = no
ONLY_QWERTY = no
# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.
#
# No touchy, capiche?
SRC += matrix.c i2c_master.c
ifeq ($(strip $(DEBUG_MATRIX)), yes)
OPT_DEFS += -DDEBUG_MATRIX
endif
ifeq ($(strip $(NO_REPEAT)), yes)
OPT_DEFS += -DNO_REPEAT
endif
ifeq ($(strip $(NO_PRINT)), yes)
OPT_DEFS += -DNO_PRINT -DNO_DEBUG
endif
ifeq ($(strip $(ONLY_QWERTY)), yes)
OPT_DEFS += -DONLYQWERTY
endif
ifeq ($(strip $(NO_TAPPING)), yes)
OPT_DEFS += -DNO_ACTION_TAPPING
endif

View file

@ -0,0 +1,267 @@
/*
* Good on you for modifying your layout, this is the most nonQMK layout you will come across
* There are three modes, Steno (the default), QWERTY (Toggleable) and a Momentary symbol layer
*
* Don't modify the steno layer directly, instead add chords using the keycodes and macros
* from sten.h to the layout you want to modify.
*
* Observe the comment above processQWERTY!
*
* http://docs.gboards.ca
*/
#include QMK_KEYBOARD_H
#include "sten.h"
#include "keymap_steno.h"
#define IGNORE_MOD_TAP_INTERRUPT
// Proper Layers
#define FUNCT (LSD | LK | LP | LH)
#define MEDIA (LSD | LK | LW | LR)
#define MOVE (LH | ST2)
/* Keyboard Layout
* ,---------------------------------. ,------------------------------.
* | FN | LSU | LFT | LP | LH | ST1 | | ST3 | RF | RP | RL | RT | RD |
* |-----+-----+-----+----+----|-----| |-----|----+----+----+----+----|
* | PWR | LSD | LK | LW | LR | ST2 | | ST4 | RR | RB | RG | RS | RZ |
* `---------------------------------' `------------------------------'
* ,---------------, .---------------.
* | LNO | LA | LO | | RE | RU | RNO |
* `---------------' `---------------'
*/
// YOU MUST ORDER THIS!
// Order your chords from longest to shortest!
// You can only use basic keycodes here!
//
// P() is just a wrapper to make your life easier.
//
// http://docs.gboards.ca
uint32_t processQwerty(bool lookup) {
// Specials
P( RT | RS | RD | RZ | LNO, SEND_STRING(VERSION); SEND_STRING(__DATE__));
P( LNO | LA | LO | RE | RU, SEND(KC_MPLY));
P( ST1 | ST2 | ST3 | ST4, SEND(KC_BSPC));
// Thumb Chords
P( LA | LO | RE | RU, SEND(KC_CAPS));
P( LA | RU, SEND(KC_ESC));
P( LO | RE, SEND(KC_LCTL));
P( LNO | LA | RU, SEND(KC_LCTL); SEND(KC_LSFT));
P( LNO | LA | RE, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));
// Mods
P( RT | RD | RS | RZ, SEND(KC_LGUI));
P( RT | RD, SEND(KC_LCTL));
P( RS | RZ, SEND(KC_LALT));
P( LA | LNO, SEND(KC_LCTL));
P( LA | LO, SEND(KC_LALT));
P( LO, SEND(KC_LSFT));
// Function Layer
P( FUNCT | RF | RR, SEND(KC_F6));
P( FUNCT | RP | RB, SEND(KC_F7));
P( FUNCT | RL | RG, SEND(KC_F8));
P( FUNCT | ST3 | ST4, SEND(KC_F5));
P( FUNCT| ST3, SEND(KC_F1));
P( FUNCT| ST4, SEND(KC_F9));
P( FUNCT | RF, SEND(KC_F2));
P( FUNCT | RP, SEND(KC_F3));
P( FUNCT | RL, SEND(KC_F4));
P( FUNCT | RR, SEND(KC_F10));
P( FUNCT | RG, SEND(KC_F12));
P( FUNCT | RB, SEND(KC_F11));
P( FUNCT | RD, SEND(KC_RALT); SEND(KC_T); SEND(KC_H); SEND(KC_U); SEND(KC_P));
P( FUNCT | RZ, SEND(KC_RALT); SEND(KC_T); SEND(KC_H); SEND(KC_D); SEND(KC_N));
P( FUNCT | RT, SEND(KC_RALT); SEND(KC_S); SEND(KC_F));
P( FUNCT | RS, SEND(KC_LALT); SEND(KC_SPC));
P( FUNCT | RE, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_ESC));
P( FUNCT | RU, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_0));
// Movement Layer
P( MOVE | RF, SEND(KC_LGUI); SEND(KC_LSFT); SEND(KC_LEFT));
P( MOVE | RP, SEND(KC_UP));
P( MOVE | RL, SEND(KC_LGUI); SEND(KC_LSFT); SEND(KC_RGHT));
P( MOVE | RT, SEND(KC_LALT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_C));
P( MOVE | ST3, SEND(KC_PGUP));
P( MOVE | ST4, SEND(KC_PGDN));
P( MOVE | RD, SEND(KC_HOME));
P( MOVE | RZ, SEND(KC_END));
P( MOVE | RG, SEND(KC_RIGHT));
P( MOVE | RB, SEND(KC_DOWN));
P( MOVE | RR, SEND(KC_LEFT));
P( MOVE | RS, SEND(KC_LSFT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_T));
P( MOVE | RE, SEND(KC_LSFT); SEND(KC_LALT); SEND(KC_LGUI); SEND(KC_S));
P( MOVE | RU, SEND(KC_LSFT); SEND(KC_LCTL); SEND(KC_1));
// Media Layer
P( MEDIA | RF, SEND(KC_MEDIA_PREV_TRACK));
P( MEDIA | RP, SEND(KC_MPLY));
P( MEDIA | RL, SEND(KC_MPLY));
P( MEDIA | RT, SEND(KC_MEDIA_NEXT_TRACK));
P( MEDIA | RD, SEND(KC_VOLU));
P( MEDIA | RZ, SEND(KC_VOLD));
P( MEDIA | RS, SEND(KC_MUTE));
P( MEDIA | ST3, SEND(KC_LALT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_4));
P( MEDIA | ST4, SEND(KC_LALT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_2));
P( MEDIA | RR, SEND(KC_LALT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_3));
P( MEDIA | RB, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_GRV));
P( MEDIA | RG, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_8));
P( MEDIA | RE, SEND(KC_RALT); SEND(KC_F); SEND(KC_I); SEND(KC_R); SEND(KC_E));
P( MEDIA | RU, SEND(KC_RALT); SEND(KC_T); SEND(KC_A); SEND(KC_D));
// Mouse Keys and Printscreen
P( LFT | LH, CLICK_MOUSE(KC_MS_BTN1));
P( LK | LR, CLICK_MOUSE(KC_MS_BTN2));
P( RF | RT, SEND(KC_PSCR););
// Number Row Left
P( LNO | LSU, SEND(KC_1));
P( LNO | LFT, SEND(KC_2));
P( LNO | LP, SEND(KC_3));
P( LNO | LH, SEND(KC_4));
P( LNO | ST1, SEND(KC_5));
P( LNO | ST3, SEND(KC_6));
P( LNO | RF, SEND(KC_7));
P( LNO | RP, SEND(KC_8));
P( LNO | RL, SEND(KC_9));
P( LNO | RT, SEND(KC_0));
P( LNO | LA, SEND(KC_5));
P( LNO | RT, SEND(KC_0));
// Number Row Right
P( RNO | LSU, SEND(KC_1));
P( RNO | LFT, SEND(KC_2));
P( RNO | LP, SEND(KC_3));
P( RNO | LH, SEND(KC_4));
P( RNO | ST1, SEND(KC_5));
P( RNO | ST3, SEND(KC_6));
P( RNO | RF, SEND(KC_7));
P( RNO | RP, SEND(KC_8));
P( RNO | RL, SEND(KC_9));
P( RNO | RT, SEND(KC_0));
P( RNO | LA, SEND(KC_5));
P( RNO | RT, SEND(KC_0));
// Specials
P( LA | LNO, SEND(KC_ESC));
P( RU | RNO, SEND(KC_TAB));
P( RE | RU, SEND(KC_LSFT); SEND(KC_SLSH));
P( RD | RZ, SEND(KC_ENT));
P( RE, SEND(KC_ENT));
//P( RD, SEND(KC_BSPC));
P( LNO, SEND(KC_BSPC));
P( RD, SEND(KC_DEL));
P( LA, SEND(KC_SPC));
P( RU, SEND(KC_SPC));
P( RZ, SEND(KC_ESC));
//P( RNO, REPEAT());
// Letters
P( LSU | LSD, SEND(KC_A));
P( LFT | LK, SEND(KC_S));
P( LP | LW, SEND(KC_E));
P( LH | LR, SEND(KC_T));
P( ST1 | ST2, SEND(KC_G));
P( ST3 | ST4, SEND(KC_Y));
P( RF | RR, SEND(KC_N));
P( RT | RS, SEND(KC_H))
P( RG | RL, SEND(KC_O));
P( RP | RB, SEND(KC_I));
P( LSU, SEND(KC_Q));
P( LSD, SEND(KC_Z));
P( LFT, SEND(KC_W));
P( LK, SEND(KC_X));
P( LP, SEND(KC_D));
P( LW, SEND(KC_C));
P( LH, SEND(KC_F));
P( LR, SEND(KC_V));
P( ST1, SEND(KC_K));
P( ST2, SEND(KC_B));
P( ST3, SEND(KC_J));
P( ST4, SEND(KC_P));
P( RF, SEND(KC_U));
P( RR, SEND(KC_M));
P( RP, SEND(KC_R));
P( RB, SEND(KC_COMM));
P( RL, SEND(KC_L));
P( RG, SEND(KC_DOT));
P( RT, SEND(KC_SCLN));
P( RS, SEND(KC_SLSH));
// Symbols and Numbers
P( PWR | RE | RU, SEND(KC_ENT));
P( PWR | LA | LO, SEND(KC_SPC));
P( PWR | LP | LW, SEND(KC_LSFT); SEND(KC_9)); // (
P( PWR | LH | LR, SEND(KC_LSFT); SEND(KC_0)); // )
P( PWR | ST1 | ST2, SEND(KC_GRV)); // `
P( PWR | RD | RZ, SEND(KC_ESC));
P( PWR | LSU | LSD, SEND(KC_LSFT); SEND(KC_3)); // #
P( PWR | LFT | LK, SEND(KC_LSFT); SEND(KC_4)); // $
P( PWR | LSU, SEND(KC_LSFT); SEND(KC_1)); // !
P( PWR | LSD, SEND(KC_LSFT); SEND(KC_5)); // %
P( PWR | LFT, SEND(KC_LSFT); SEND(KC_2)); // @
P( PWR | LK, SEND(KC_LSFT); SEND(KC_6)); // ^
P( PWR | LP, SEND(KC_LSFT); SEND(KC_LBRC)); // {
P( PWR | LW, SEND(KC_LBRC));
P( PWR | LH, SEND(KC_LSFT); SEND(KC_RBRC)); // }
P( PWR | LR, SEND(KC_RBRC));
P( PWR | ST1, SEND(KC_LSFT); SEND(KC_BSLS)); // |
P( PWR | ST2, SEND(KC_LSFT); SEND(KC_GRV)); // ~
P( PWR | ST3, SEND(KC_QUOT));
P( PWR | ST4, SEND(KC_LSFT); SEND(KC_QUOT)); // "
P( PWR | RF, SEND(KC_KP_PLUS));
P( PWR | RR, SEND(KC_LSFT); SEND(KC_7)); // &
P( PWR | RP, SEND(KC_MINS));
P( PWR | RB, SEND(KC_EQL));
P( PWR | RL, SEND(KC_SLSH));
P( PWR | RG, SEND(KC_LSFT); SEND(KC_MINS));
P( PWR | RT, SEND(KC_PAST));
P( PWR | RS, SEND(KC_DOT));
P( PWR | RD, SEND(KC_TAB));
P( PWR | LA, SEND(KC_LSFT); SEND(KC_SCLN));
P( PWR | LO, SEND(KC_BSLS));
P( PWR | RE, SEND(KC_SCLN));
P( PWR | RU, SEND(KC_BSLS));
P( PWR | RZ, SEND(KC_LSFT));
return 0;
}
#define STENO_LAYER 0
#define GAMING 1
#define GAMING_2 2
#define MOVEMENT 3
// "Layers"
// Steno layer should be first in your map.
// When PWR | FN | ST3 | ST4 is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you need more space for chords, remove the two gaming layers.
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Main layer, everything goes through here
[STENO_LAYER] = LAYOUT_georgi(
STN_FN, STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1, STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR,
STN_PWR, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2, STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR,
STN_N1, STN_A, STN_O, STN_E, STN_U, STN_N7)
,
// Gaming layer with Numpad, Very limited
[GAMING] = LAYOUT_georgi(
KC_LSFT, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_ENT,
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_DQUO,
KC_LALT, KC_SPC, LT(GAMING_2, KC_ENT), KC_DEL, KC_ASTR, TO(STENO_LAYER)),
[GAMING_2] = LAYOUT_georgi(
KC_LSFT, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_LT, KC_GT, KC_QUES, KC_RSFT,
KC_LALT, KC_SPC, KC_NO, KC_DEL, KC_ASTR, TO(STENO_LAYER)),
[MOVEMENT] = LAYOUT_georgi(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, KC_PGUP, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_HOME,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS, KC_END,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
};
// Don't fuck with this, thanks.
size_t keymapsCount = sizeof(keymaps)/sizeof(keymaps[0]);

View file

@ -0,0 +1,11 @@
# Georgi QWERTY/Steno firmware
This is the default keymap for Georgi, it's based heavily off of the naps62 ErgoDox and the Gergo layout.
It is both a ergonomic and programmer friendly keymap.
Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!
## Space issues
If you find yourself running out of space for dictionary entries, disabling mousekeys in rules.mk will save
you about 4k for entries!
Get a free 1k by deleting the Gaming layers from the keymap!

View file

@ -1,18 +1,20 @@
#----------------------------------------------------------------------------
# make georgi:extrakey:dfu
# make georgi:default:dfu
# Make sure you have dfu-programmer installed!
#----------------------------------------------------------------------------
#Debug options
NO_REPEAT = yes
VERBOSE = yes
CONSOLE_ENABLE = yes
DEBUG_MATRIX_SCAN_RATE = no
DEBUG_MATRIX = no
KEYBOARD_SHARED_EP = yes
CUSTOM_MATRIX = yes
MOUSEKEY_ENABLE = no
SINGLE_LAYER = no
MOUSEKEY_ENABLE = yes
#Debug options
CONSOLE_ENABLE = no
DEBUG_MATRIX_SCAN_RATE = no
DEBUG_MATRIX = no
NO_PRINT = yes
ONLY_QWERTY = no
# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.
@ -22,6 +24,12 @@ SRC += matrix.c i2c_master.c
ifeq ($(strip $(DEBUG_MATRIX)), yes)
OPT_DEFS += -DDEBUG_MATRIX
endif
ifeq ($(strip $(SINGLE_LAYER)), yes)
OPT_DEFS += -DSINGLE_LAYER
ifeq ($(strip $(NO_REPEAT)), yes)
OPT_DEFS += -DNO_REPEAT
endif
ifeq ($(strip $(NO_PRINT)), yes)
OPT_DEFS += -DNO_PRINT -DNO_DEBUG
endif
ifeq ($(strip $(ONLY_QWERTY)), yes)
OPT_DEFS += -DONLYQWERTY
endif

View file

@ -1,216 +0,0 @@
/*
* Good on you for modifying your layout, this is the most nonQMK layout you will come across
* There are three modes, Steno (the default), QWERTY (Toggleable) and a Momentary symbol layer
*
* Don't modify the steno layer directly, instead add chords using the keycodes and macros
* from sten.h to the layout you want to modify.
*
* Observe the comment above processQWERTY!
*
* http://docs.gboards.ca
*/
#include QMK_KEYBOARD_H
#include "sten.h"
#include "keymap_steno.h"
#define IGNORE_MOD_TAP_INTERRUPT
int getKeymapCount(void);
// Proper Layers
#define FUNCT (LSD | LK | LP | LH)
#define MEDIA (LSD | LK | LW | LR)
#define MOVE (ST1 | ST2)
/* Keyboard Layout
* ,---------------------------------. ,------------------------------.
* | FN | LSU | LFT | LP | LH | ST1 | | ST3 | RF | RP | RL | RT | RD |
* |-----+-----+-----+----+----|-----| |-----|----+----+----+----+----|
* | PWR | LSD | LK | LW | LR | ST2 | | ST4 | RR | RG | RB | RS | RZ |
* `---------------------------------' `------------------------------'
* ,---------------, .---------------.
* | NUM | LA | LO | | RE | RU | NUM |
* `---------------' `---------------'
*/
// YOU MUST ORDER THIS!
// P Will return from processing on the first match it finds. Therefore
// PJ Will run the requested action, remove the matched chord and continue
//
// First any chords that would conflict with PJs need to be checked, then PJs, lastly Ps.
// For all chords should be ordered by length in their section!
//
// http://docs.gboards.ca
bool processQwerty(void) {
// Place P's that would be trashed by PJ's here
P( RT | RS | RD | RZ | NUM, SEND_STRING(VERSION); SEND_STRING(__DATE__));
P( NUM | LA | LO | RE | RU, SEND(KC_MPLY));
P( ST1 | ST2 | ST3 | ST4, SEND(KC_BSPC));
// Thumb Chords
P( LA | LO | RE | RU, SEND(KC_CAPS));
P( LA | RU, SEND(KC_ESC));
PJ( LO | RE, SEND(KC_LCTL));
PJ( NUM | LA | RU, SEND(KC_LCTL); SEND(KC_LSFT));
PJ( NUM | LA | RE, SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));
// Mods
PJ( RT | RD | RS | RZ, SEND(KC_LGUI));
PJ( RT | RD, SEND(KC_LCTL));
PJ( RS | RZ, SEND(KC_LALT));
PJ( LA | NUM, SEND(KC_LCTL));
PJ( LA | LO, SEND(KC_LALT));
PJ( LO, SEND(KC_LSFT));
// Function Layer
P( FUNCT | RF | RR, SEND(KC_F5));
P( FUNCT | RP | RB, SEND(KC_F6));
P( FUNCT | RL | RG, SEND(KC_F7));
P( FUNCT | RT | RS, SEND(KC_F8));
P( FUNCT | RF, SEND(KC_F1));
P( FUNCT | RP, SEND(KC_F2));
P( FUNCT | RL, SEND(KC_F3));
P( FUNCT | RT, SEND(KC_F4));
P( FUNCT | RR, SEND(KC_F9));
P( FUNCT | RG, SEND(KC_F10));
P( FUNCT | RB, SEND(KC_F11));
P( FUNCT | RS, SEND(KC_F12));
// Movement Layer
P( MOVE | RF, SEND(KC_LEFT));
P( MOVE | RP, SEND(KC_DOWN));
P( MOVE | RL, SEND(KC_UP));
P( MOVE | RT, SEND(KC_RIGHT));
P( MOVE | ST3, SEND(KC_PGUP));
P( MOVE | ST4, SEND(KC_PGDN));
// Media Layer
P( MEDIA | RF, SEND(KC_MPRV));
P( MEDIA | RP, SEND(KC_MPLY));
P( MEDIA | RL, SEND(KC_MPLY));
P( MEDIA | RT, SEND(KC_MNXT));
P( MEDIA | RD, SEND(KC_VOLU));
P( MEDIA | RZ, SEND(KC_VOLD));
P( MEDIA | RS, SEND(KC_MUTE));
// Mouse Keys
P( LP | LH, clickMouse(KC_MS_BTN1));
P( LW | LR, clickMouse(KC_MS_BTN2));
// Number Row
P( NUM | LSU, SEND(KC_1));
P( NUM | LFT, SEND(KC_2));
P( NUM | LP, SEND(KC_3));
P( NUM | LH, SEND(KC_4));
P( NUM | ST1, SEND(KC_5));
P( NUM | ST3, SEND(KC_6));
P( NUM | RF, SEND(KC_7));
P( NUM | RP, SEND(KC_8));
P( NUM | RL, SEND(KC_9));
P( NUM | RT, SEND(KC_0));
P( NUM | LA, SEND(KC_5));
P( NUM | RT, SEND(KC_0));
// Specials
P( LA | NUM, SEND(KC_ESC));
P( RU | NUM, SEND(KC_TAB));
P( RE | RU, SEND(KC_BSPC));
P( RD | RZ, SEND(KC_ENT));
P( RE, SEND(KC_ENT));
P( RD, SEND(KC_BSPC));
P( NUM, SEND(KC_BSPC));
P( LA, SEND(KC_SPC));
P( RU, SEND(KC_SPC));
P( RZ, SEND(KC_ESC));
// Letters
P( LSU | LSD, SEND(KC_A));
P( LFT | LK, SEND(KC_S));
P( LP | LW, SEND(KC_D));
P( LH | LR, SEND(KC_F));
P( ST1 | ST2, SEND(KC_G));
P( ST3 | ST4, SEND(KC_H));
P( RF | RR, SEND(KC_J));
P( RT | RS, SEND(KC_SCLN))
P( RG | RL, SEND(KC_L));
P( RP | RB, SEND(KC_K));
P( LSU, SEND(KC_Q));
P( LSD, SEND(KC_Z));
P( LFT, SEND(KC_W));
P( LK, SEND(KC_X));
P( LP, SEND(KC_E));
P( LW, SEND(KC_C));
P( LH, SEND(KC_R));
P( LR, SEND(KC_V));
P( ST1, SEND(KC_T));
P( ST2, SEND(KC_B));
P( ST3, SEND(KC_Y));
P( ST4, SEND(KC_N));
P( RF, SEND(KC_U));
P( RR, SEND(KC_M));
P( RP, SEND(KC_I));
P( RB, SEND(KC_COMM));
P( RL, SEND(KC_O));
P( RG, SEND(KC_DOT));
P( RT, SEND(KC_P));
P( RS, SEND(KC_SLSH));
// Symbols and Numbers
P( PWR | RE | RU, SEND(KC_ENT));
P( PWR | LA | LO, SEND(KC_SPC));
P( PWR | LP | LW, SEND(KC_LSFT); SEND(KC_9)); // (
P( PWR | LH | LR, SEND(KC_LSFT); SEND(KC_0)); // )
P( PWR | ST1 | ST2, SEND(KC_GRV)); // `
P( PWR | RD | RZ, SEND(KC_ESC));
P( PWR | LSU | LSD, SEND(KC_LSFT); SEND(KC_3)); // #
P( PWR | LFT | LK, SEND(KC_LSFT); SEND(KC_4)); // $
P( PWR | LSU, SEND(KC_LSFT); SEND(KC_1)); // !
P( PWR | LSD, SEND(KC_LSFT); SEND(KC_5)); // %
P( PWR | LFT, SEND(KC_LSFT); SEND(KC_2)); // @
P( PWR | LK, SEND(KC_LSFT); SEND(KC_6)); // ^
P( PWR | LP, SEND(KC_LSFT); SEND(KC_LBRC)); // {
P( PWR | LW, SEND(KC_LBRC));
P( PWR | LH, SEND(KC_LSFT); SEND(KC_RBRC)); // }
P( PWR | LR, SEND(KC_RBRC));
P( PWR | ST1, SEND(KC_LSFT); SEND(KC_BSLS)); // |
P( PWR | ST2, SEND(KC_LSFT); SEND(KC_GRV)); // ~
P( PWR | ST3, SEND(KC_QUOT));
P( PWR | ST4, SEND(KC_LSFT); SEND(KC_QUOT)); // "
P( PWR | RF, SEND(KC_KP_PLUS));
P( PWR | RR, SEND(KC_LSFT); SEND(KC_7)); // &
P( PWR | RP, SEND(KC_MINS));
P( PWR | RB, SEND(KC_EQL));
P( PWR | RL, SEND(KC_SLSH));
P( PWR | RG, SEND(KC_COMM));
P( PWR | RT, SEND(KC_PAST));
P( PWR | RS, SEND(KC_DOT));
P( PWR | RD, SEND(KC_TAB));
P( PWR | LA, SEND(KC_SCLN));
P( PWR | LO, SEND(KC_SLSH));
P( PWR | RE, SEND(KC_SCLN));
P( PWR | RU, SEND(KC_SLSH));
// If we make here, send as a steno chord
// If plover is running we can hook that host side
return false;
}
#define STENO_LAYER 0
// "Layers"
// Steno layer should be first in your map.
// When PWR | FN | RR | RG | RB | RS is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you have only a single layer, you must set SINGLELAYER = yes in your rules.mk, otherwise you may experince undefined behaviour
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Main layer, everything goes through here
[STENO_LAYER] = LAYOUT_georgi(
STN_FN, STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1, STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR,
STN_PWR, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2, STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR,
STN_N1, STN_A, STN_O, STN_E, STN_U, STN_N1)
};
int getKeymapCount(void) {
return sizeof(keymaps)/sizeof(keymaps[0]);
}

View file

@ -1,6 +0,0 @@
# Georgi QWERTY/Steno firmware
This is a blank template configured with 5K of free space for your onboard dictionary!
Read the docs over at [gBoards](http://docs.gboards.ca)
Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!

View file

@ -21,8 +21,11 @@ To just test your build with the default keymap
Build options can be enabled/disabled in keyboards/georgi/keymaps/default/rules.mk . Copy the default directory and make any changes to your layout, if you think they're worth sharing submit a PR!
## Documentation
Is hosted over on [docs.gboards.ca](http://docs.gboards.ca/). Please take a look at the docs for customizing your firmware!
# Space
The stock firmware uses nearly all of the flash avalible. For custom dictionary modifications, disable mousekeys in your keymaps rules.mk (4K of space) and remove the Gaming layers. I've done this already in the provided keymap 'template'.
The stock firmware leaves 7K free for custom entries. For extra space disable mousekeys in your keymaps rules.mk (3K of space) and remove the Gaming layers (1k).
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).

View file

@ -4,7 +4,7 @@
# Do not edit this file! Make a copy of keymaps/default and modify that!
#----------------------------------------------------------------------------
# Source includes
SRC += matrix.c i2c_master.c
SRC += matrix.c i2c_master.c sten.c
# Hardware info
MCU = atmega32u4
@ -15,8 +15,9 @@ F_USB = $(F_CPU)
EXTRAFLAGS += -flto
CUSTOM_MATRIX = yes
MOUSEKEY_ENABLE = no
STENO_ENABLE = yes
EXTRAKEY_ENABLE = yes
CONSOLE_ENABLE = no
CONSOLE_ENABLE = yes
COMMAND_ENABLE = no
NKRO_ENABLE = yes

View file

@ -1,2 +1,406 @@
#include "sten.h"
// Chord state
uint32_t cChord = 0; // Current Chord
int chordIndex = 0; // Keys in previousachord
int32_t chordState[32]; // Full Chord history
#define QWERBUF 24 // Size of chords to buffer for output
bool repeatFlag = false; // Should we repeat?
uint32_t pChord = 0; // Previous Chord
int pChordIndex = 0; // Keys in previousachord
uint32_t pChordState[32]; // Previous chord sate
uint32_t stickyBits = 0; // Or'd with every incoming press
// Mode state
enum MODE { STENO = 0, QWERTY, COMMAND };
enum MODE pMode;
bool QWERSTENO = false;
#ifdef ONLYQWERTY
enum MODE cMode = QWERTY;
#else
enum MODE cMode = STENO;
#endif
// Command State
#define MAX_CMD_BUF 20
uint8_t CMDLEN = 0;
uint8_t CMDBUF[MAX_CMD_BUF];
// Key Repeat state
bool inChord = false;
bool repEngaged = false;
uint16_t repTimer = 0;
#define REP_INIT_DELAY 750
#define REP_DELAY 25
// Mousekeys state
bool inMouse = false;
int8_t mousePress;
// All processing done at chordUp goes through here
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]) {
// Check for mousekeys, this is release
#ifdef MOUSEKEY_ENABLE
if (inMouse) {
inMouse = false;
mousekey_off(mousePress);
mousekey_send();
}
#endif
// Toggle Serial/QWERTY steno
if (cChord == (PWR | FN | ST1 | ST2)) {
#ifndef NO_DEBUG
uprintf("Fallback Toggle\n");
#endif
QWERSTENO = !QWERSTENO;
goto out;
}
// handle command mode
if (cChord == (PWR | FN | RD | RZ)) {
#ifndef NO_DEBUG
uprintf("COMMAND Toggle\n");
#endif
if (cMode != COMMAND) { // Entering Command Mode
CMDLEN = 0;
pMode = cMode;
cMode = COMMAND;
} else { // Exiting Command Mode
cMode = pMode;
// Press all and release all
for (int i = 0; i < CMDLEN; i++) {
register_code(CMDBUF[i]);
}
clear_keyboard();
}
goto out;
}
// Handle Gaming Toggle,
if (cChord == (PWR | FN | ST4 | ST3) && keymapsCount > 1) {
#ifndef NO_DEBUG
uprintf("Switching to QMK\n");
#endif
layer_on(1);
goto out;
}
// Lone FN press, toggle QWERTY
#ifndef ONLYQWERTY
if (cChord == FN) {
(cMode == STENO) ? (cMode = QWERTY) : (cMode = STENO);
goto out;
}
#endif
// Check for Plover momentary
if (cMode == QWERTY && (cChord & FN)) {
cChord ^= FN;
goto steno;
}
// Do QWERTY and Momentary QWERTY
if (cMode == QWERTY || (cMode == COMMAND) || (cChord & (FN | PWR))) {
processChord(false);
goto out;
}
// Fallback NKRO Steno
if (cMode == STENO && QWERSTENO) {
processChord(true);
goto out;
}
steno:
// Hey that's a steno chord!
inChord = false;
chordIndex = 0;
cChord = 0;
return true;
out:
cChord = 0;
inChord = false;
chordIndex = 0;
clear_keyboard();
repEngaged = false;
for (int i = 0; i < 32; i++)
chordState[i] = 0xFFFF;
return false;
}
// Update Chord State
bool process_steno_user(uint16_t keycode, keyrecord_t *record) {
// Everything happens in here when steno keys come in.
// Bail on keyup
if (!record->event.pressed) return true;
// Update key repeat timers
repTimer = timer_read();
inChord = true;
// Switch on the press adding to chord
bool pr = record->event.pressed;
switch (keycode) {
// Mods and stuff
case STN_ST1: pr ? (cChord |= (ST1)): (cChord &= ~(ST1)); break;
case STN_ST2: pr ? (cChord |= (ST2)): (cChord &= ~(ST2)); break;
case STN_ST3: pr ? (cChord |= (ST3)): (cChord &= ~(ST3)); break;
case STN_ST4: pr ? (cChord |= (ST4)): (cChord &= ~(ST4)); break;
case STN_FN: pr ? (cChord |= (FN)) : (cChord &= ~(FN)); break;
case STN_PWR: pr ? (cChord |= (PWR)): (cChord &= ~(PWR)); break;
case STN_N1...STN_N6: pr ? (cChord |= (LNO)): (cChord &= ~(LNO)); break;
case STN_N7...STN_NC: pr ? (cChord |= (RNO)): (cChord &= ~(RNO)); break;
// All the letter keys
case STN_S1: pr ? (cChord |= (LSU)) : (cChord &= ~(LSU)); break;
case STN_S2: pr ? (cChord |= (LSD)) : (cChord &= ~(LSD)); break;
case STN_TL: pr ? (cChord |= (LFT)) : (cChord &= ~(LFT)); break;
case STN_KL: pr ? (cChord |= (LK)) : (cChord &= ~(LK)); break;
case STN_PL: pr ? (cChord |= (LP)) : (cChord &= ~(LP)); break;
case STN_WL: pr ? (cChord |= (LW)) : (cChord &= ~(LW)); break;
case STN_HL: pr ? (cChord |= (LH)) : (cChord &= ~(LH)); break;
case STN_RL: pr ? (cChord |= (LR)) : (cChord &= ~(LR)); break;
case STN_A: pr ? (cChord |= (LA)) : (cChord &= ~(LA)); break;
case STN_O: pr ? (cChord |= (LO)) : (cChord &= ~(LO)); break;
case STN_E: pr ? (cChord |= (RE)) : (cChord &= ~(RE)); break;
case STN_U: pr ? (cChord |= (RU)) : (cChord &= ~(RU)); break;
case STN_FR: pr ? (cChord |= (RF)) : (cChord &= ~(RF)); break;
case STN_RR: pr ? (cChord |= (RR)) : (cChord &= ~(RR)); break;
case STN_PR: pr ? (cChord |= (RP)) : (cChord &= ~(RP)); break;
case STN_BR: pr ? (cChord |= (RB)) : (cChord &= ~(RB)); break;
case STN_LR: pr ? (cChord |= (RL)) : (cChord &= ~(RL)); break;
case STN_GR: pr ? (cChord |= (RG)) : (cChord &= ~(RG)); break;
case STN_TR: pr ? (cChord |= (RT)) : (cChord &= ~(RT)); break;
case STN_SR: pr ? (cChord |= (RS)) : (cChord &= ~(RS)); break;
case STN_DR: pr ? (cChord |= (RD)) : (cChord &= ~(RD)); break;
case STN_ZR: pr ? (cChord |= (RZ)) : (cChord &= ~(RZ)); break;
}
// Store previous state for fastQWER
if (pr) {
chordState[chordIndex] = cChord;
chordIndex++;
}
return true;
}
void matrix_scan_user(void) {
// We abuse this for early sending of key
// Key repeat only on QWER/SYMB layers
if (cMode != QWERTY || !inChord) return;
// Check timers
#ifndef NO_REPEAT
if (repEngaged && timer_elapsed(repTimer) > REP_DELAY) {
// Process Key for report
processChord(false);
// Send report to host
send_keyboard_report();
clear_keyboard();
repTimer = timer_read();
}
if (!repEngaged && timer_elapsed(repTimer) > REP_INIT_DELAY) {
repEngaged = true;
}
#endif
};
// For Plover NKRO
uint32_t processFakeSteno(bool lookup) {
P( LSU, SEND(KC_Q););
P( LSD, SEND(KC_A););
P( LFT, SEND(KC_W););
P( LP, SEND(KC_E););
P( LH, SEND(KC_R););
P( LK, SEND(KC_S););
P( LW, SEND(KC_D););
P( LR, SEND(KC_F););
P( ST1, SEND(KC_T););
P( ST2, SEND(KC_G););
P( LA, SEND(KC_C););
P( LO, SEND(KC_V););
P( RE, SEND(KC_N););
P( RU, SEND(KC_M););
P( ST3, SEND(KC_Y););
P( ST4, SEND(KC_H););
P( RF, SEND(KC_U););
P( RP, SEND(KC_I););
P( RL, SEND(KC_O););
P( RT, SEND(KC_P););
P( RD, SEND(KC_LBRC););
P( RR, SEND(KC_J););
P( RB, SEND(KC_K););
P( RG, SEND(KC_L););
P( RS, SEND(KC_SCLN););
P( RZ, SEND(KC_COMM););
P( LNO, SEND(KC_1););
P( RNO, SEND(KC_1););
return 0;
}
// Traverse the chord history to a given point
// Returns the mask to use
void processChord(bool useFakeSteno) {
// Save the clean chord state
uint32_t savedChord = cChord;
// Apply Stick Bits if needed
if (stickyBits != 0) {
cChord |= stickyBits;
for (int i = 0; i <= chordIndex; i++)
chordState[i] |= stickyBits;
}
// Strip FN
if (cChord & FN) cChord ^= FN;
// First we test if a whole chord was passsed
// If so we just run it handling repeat logic
if (useFakeSteno && processFakeSteno(true) == cChord) {
processFakeSteno(false);
return;
} else if (processQwerty(true) == cChord) {
processQwerty(false);
// Repeat logic
if (repeatFlag) {
restoreState();
repeatFlag = false;
processChord(false);
} else {
saveState(cChord);
}
return;
}
// Iterate through chord picking out the individual
// and longest chords
uint32_t bufChords[QWERBUF];
int bufLen = 0;
uint32_t mask = 0;
// We iterate over it multiple times to catch the longest
// chord. Then that gets addded to the mask and re run.
while (savedChord != mask) {
uint32_t test = 0;
uint32_t longestChord = 0;
for (int i = 0; i <= chordIndex; i++) {
cChord = chordState[i] & ~mask;
if (cChord == 0)
continue;
// Assume mid parse Sym is new chord
if (i != 0 && test != 0 && (cChord ^ test) == PWR) {
longestChord = test;
break;
}
// Lock SYM layer in once detected
if (mask & PWR)
cChord |= PWR;
// Testing for keycodes
if (useFakeSteno) {
test = processFakeSteno(true);
} else {
test = processQwerty(true);
}
if (test != 0) {
longestChord = test;
}
}
mask |= longestChord;
bufChords[bufLen] = longestChord;
bufLen++;
// That's a loop of sorts, halt processing
if (bufLen >= QWERBUF) {
return;
}
}
// Now that the buffer is populated, we run it
for (int i = 0; i < bufLen ; i++) {
cChord = bufChords[i];
if (useFakeSteno) {
processFakeSteno(false);
} else {
processQwerty(false);
}
}
// Save state in case of repeat
if (!repeatFlag) {
saveState(savedChord);
}
// Restore cChord for held repeat
cChord = savedChord;
return;
}
void saveState(uint32_t cleanChord) {
pChord = cleanChord;
pChordIndex = chordIndex;
for (int i = 0; i < 32; i++)
pChordState[i] = chordState[i];
}
void restoreState() {
cChord = pChord;
chordIndex = pChordIndex;
for (int i = 0; i < 32; i++)
chordState[i] = pChordState[i];
}
// Macros for calling from keymap.c
void SEND(uint8_t kc) {
// Send Keycode, Does not work for Quantum Codes
if (cMode == COMMAND && CMDLEN < MAX_CMD_BUF) {
#ifndef NO_DEBUG
uprintf("CMD LEN: %d BUF: %d\n", CMDLEN, MAX_CMD_BUF);
#endif
CMDBUF[CMDLEN] = kc;
CMDLEN++;
}
if (cMode != COMMAND) register_code(kc);
return;
}
void REPEAT(void) {
if (cMode != QWERTY)
return;
repeatFlag = true;
return;
}
void SET_STICKY(uint32_t stick) {
stickyBits = stick;
return;
}
void SWITCH_LAYER(int layer) {
if (keymapsCount >= layer)
layer_on(layer);
}
void CLICK_MOUSE(uint8_t kc) {
#ifdef MOUSEKEY_ENABLE
mousekey_on(kc);
mousekey_send();
// Store state for later use
inMouse = true;
mousePress = kc;
#endif
}

View file

@ -1,28 +1,43 @@
// 2019, g Heavy Industries
// Blessed mother of Christ, please keep this readable
// and protect us from segfaults. For thine is the clock,
// the slave and the master. Until we return from main.
//
// Amen.
#include QMK_KEYBOARD_H
#include "mousekey.h"
#include "keymap.h"
#include "keymap_steno.h"
#include "wait.h"
// Bitfield representing the current chord
uint32_t cChord = 0;
extern size_t keymapsCount; // Total keymaps
extern uint32_t cChord; // Current Chord
// See if a given chord is pressed.
// P will return
// PJ will continue processing, removing the found chord
#define P(chord, act) if (cChord == (chord)) { act; return true; }
#define PJ(chord, act) if ((cChord & (chord)) == (chord)) { cChord ^= chord; act; }
// Function defs
void processChord(bool useFakeSteno);
uint32_t processQwerty(bool lookup);
uint32_t processFakeSteno(bool lookup);
void saveState(uint32_t cChord);
void restoreState(void);
// Macros for use in keymap.c
void SEND(uint8_t kc);
void REPEAT(void);
void SET_STICKY(uint32_t);
void SWITCH_LAYER(int);
void CLICK_MOUSE(uint8_t);
// Keymap helper
#define P(chord, act) if (cChord == (chord)) { if (!lookup) {act;} return chord;}
// All Steno Codes
// Shift to internal representation
#define STN(n) (1L<<n)
// i.e) S(teno)R(ight)F
#define STN(n) (1L<<n)
enum ORDER {
SFN = 0, SPWR, SST1, SST2, SST3, SST4, SNUM,
SFN = 0, SPWR, SST1, SST2, SST3, SST4, SNUML, SNUMR,
SLSU, SLSD, SLT, SLK, SLP, SLW, SLH, SLR, SLA, SLO,
SRE, SRU, SRF, SRR, SRP, SRB, SRL, SRG, SRT, SRS, SRD, SRZ
SRE, SRU, SRF, SRR, SRP, SRB, SRL, SRG, SRT, SRS, SRD, SRZ, SRES1, SRES2
};
// Break it all out
@ -32,7 +47,10 @@ enum ORDER {
#define ST2 STN(SST2)
#define ST3 STN(SST3)
#define ST4 STN(SST4)
#define NUM STN(SNUM) // No distinction between left and right
#define LNO STN(SNUML) // STN1-6
#define RNO STN(SNUMR) // STN7-C
#define RES1 STN(SRES1) // Use reserved for sticky state
#define RES2 STN(SRES2)
#define LSU STN(SLSU)
#define LSD STN(SLSD)
@ -57,234 +75,3 @@ enum ORDER {
#define RS STN(SRS)
#define RD STN(SRD)
#define RZ STN(SRZ)
bool processQwerty(void);
bool processFakeSteno(void);
void clickMouse(uint8_t kc);
void SEND(uint8_t kc);
extern int getKeymapCount(void);
// Mode state
enum MODE { STENO = 0, QWERTY, COMMAND };
enum MODE cMode = STENO;
enum MODE pMode;
bool QWERSTENO = false;
// Command State
#define MAX_CMD_BUF 20
uint8_t CMDBUF[MAX_CMD_BUF];
uint8_t CMDLEN = 0;
// Key Repeat state
bool inChord = false;
uint16_t repTimer = 0;
#define REP_DELAY 300
// Mousekeys state
bool inMouse = false;
int8_t mousePress;
// All processing done at chordUp goes through here
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]) {
// Check for mousekeys, this is release
#ifdef MOUSEKEY_ENABLE
if (inMouse) {
inMouse = false;
mousekey_off(mousePress);
mousekey_send();
}
#endif
// Toggle Serial/QWERTY steno
if (cChord == (PWR | FN | ST1 | ST2)) {
uprintf("Fallback Toggle\n");
QWERSTENO = !QWERSTENO;
goto out;
}
// handle command mode
if (cChord == (PWR | FN | RD | RZ)) {
uprintf("COMMAND Toggle\n");
if (cMode != COMMAND) { // Entering Command Mode
CMDLEN = 0;
pMode = cMode;
cMode = COMMAND;
} else { // Exiting Command Mode
cMode = pMode;
// Press all and release all
for (int i = 0; i < CMDLEN; i++) {
register_code(CMDBUF[i]);
}
clear_keyboard();
}
goto out;
}
// Handle Gaming Toggle,
if (cChord == (PWR | FN | ST2 | ST3) && getKeymapCount() > 1) {
uprintf("Switching to QMK\n");
layer_on(1);
goto out;
}
// Lone FN press, toggle QWERTY
if (cChord == FN) {
(cMode == STENO) ? (cMode = QWERTY) : (cMode = STENO);
goto out;
}
// Check for Plover momentary
if (cMode == QWERTY && (cChord & FN)) {
cChord ^= FN;
goto steno;
}
// Do QWERTY and Momentary QWERTY
if (cMode == QWERTY || (cMode == COMMAND) || (cChord & (FN | PWR))) {
if (cChord & FN) cChord ^= FN;
processQwerty();
goto out;
}
// Fallback NKRO Steno
if (cMode == STENO && QWERSTENO) {
processFakeSteno();
goto out;
}
steno:
// Hey that's a steno chord!
inChord = false;
cChord = 0;
return true;
out:
inChord = false;
clear_keyboard();
cChord = 0;
return false;
}
// Update Chord State
bool process_steno_user(uint16_t keycode, keyrecord_t *record) {
// Everything happens in here when steno keys come in.
// Bail on keyup
if (!record->event.pressed) return true;
// Update key repeat timers
repTimer = timer_read();
inChord = true;
// Switch on the press adding to chord
bool pr = record->event.pressed;
switch (keycode) {
// Mods and stuff
case STN_ST1: pr ? (cChord |= (ST1)): (cChord &= ~(ST1)); break;
case STN_ST2: pr ? (cChord |= (ST2)): (cChord &= ~(ST2)); break;
case STN_ST3: pr ? (cChord |= (ST3)): (cChord &= ~(ST3)); break;
case STN_ST4: pr ? (cChord |= (ST4)): (cChord &= ~(ST4)); break;
case STN_FN: pr ? (cChord |= (FN)) : (cChord &= ~(FN)); break;
case STN_PWR: pr ? (cChord |= (PWR)): (cChord &= ~(PWR)); break;
case STN_N1...STN_N6:
case STN_N7...STN_NC: pr ? (cChord |= (NUM)): (cChord &= ~(NUM)); break;
// All the letter keys
case STN_S1: pr ? (cChord |= (LSU)) : (cChord &= ~(LSU)); break;
case STN_S2: pr ? (cChord |= (LSD)) : (cChord &= ~(LSD)); break;
case STN_TL: pr ? (cChord |= (LFT)) : (cChord &= ~(LFT)); break;
case STN_KL: pr ? (cChord |= (LK)) : (cChord &= ~(LK)); break;
case STN_PL: pr ? (cChord |= (LP)) : (cChord &= ~(LP)); break;
case STN_WL: pr ? (cChord |= (LW)) : (cChord &= ~(LW)); break;
case STN_HL: pr ? (cChord |= (LH)) : (cChord &= ~(LH)); break;
case STN_RL: pr ? (cChord |= (LR)) : (cChord &= ~(LR)); break;
case STN_A: pr ? (cChord |= (LA)) : (cChord &= ~(LA)); break;
case STN_O: pr ? (cChord |= (LO)) : (cChord &= ~(LO)); break;
case STN_E: pr ? (cChord |= (RE)) : (cChord &= ~(RE)); break;
case STN_U: pr ? (cChord |= (RU)) : (cChord &= ~(RU)); break;
case STN_FR: pr ? (cChord |= (RF)) : (cChord &= ~(RF)); break;
case STN_RR: pr ? (cChord |= (RR)) : (cChord &= ~(RR)); break;
case STN_PR: pr ? (cChord |= (RP)) : (cChord &= ~(RP)); break;
case STN_BR: pr ? (cChord |= (RB)) : (cChord &= ~(RB)); break;
case STN_LR: pr ? (cChord |= (RL)) : (cChord &= ~(RL)); break;
case STN_GR: pr ? (cChord |= (RG)) : (cChord &= ~(RG)); break;
case STN_TR: pr ? (cChord |= (RT)) : (cChord &= ~(RT)); break;
case STN_SR: pr ? (cChord |= (RS)) : (cChord &= ~(RS)); break;
case STN_DR: pr ? (cChord |= (RD)) : (cChord &= ~(RD)); break;
case STN_ZR: pr ? (cChord |= (RZ)) : (cChord &= ~(RZ)); break;
}
// Check for key repeat in QWERTY mode
return true;
}
void matrix_scan_user(void) {
// We abuse this for early sending of key
// Key repeat only on QWER/SYMB layers
if (cMode != QWERTY) return;
// Check timers
if (timer_elapsed(repTimer) > REP_DELAY) {
// Process Key for report
processQwerty();
// Send report to host
send_keyboard_report();
repTimer = timer_read();
}
};
// Helpers
bool processFakeSteno(void) {
PJ( LSU, SEND(KC_Q););
PJ( LSD, SEND(KC_A););
PJ( LFT, SEND(KC_W););
PJ( LP, SEND(KC_E););
PJ( LH, SEND(KC_R););
PJ( LK, SEND(KC_S););
PJ( LW, SEND(KC_D););
PJ( LR, SEND(KC_F););
PJ( ST1, SEND(KC_T););
PJ( ST2, SEND(KC_G););
PJ( LA, SEND(KC_C););
PJ( LO, SEND(KC_V););
PJ( RE, SEND(KC_N););
PJ( RU, SEND(KC_M););
PJ( ST3, SEND(KC_Y););
PJ( ST4, SEND(KC_H););
PJ( RF, SEND(KC_U););
PJ( RP, SEND(KC_I););
PJ( RL, SEND(KC_O););
PJ( RT, SEND(KC_P););
PJ( RD, SEND(KC_LBRC););
PJ( RR, SEND(KC_J););
PJ( RB, SEND(KC_K););
PJ( RG, SEND(KC_L););
PJ( RS, SEND(KC_SCLN););
PJ( RZ, SEND(KC_COMM););
PJ( NUM, SEND(KC_1););
return false;
}
void clickMouse(uint8_t kc) {
#ifdef MOUSEKEY_ENABLE
mousekey_on(kc);
mousekey_send();
// Store state for later use
inMouse = true;
mousePress = kc;
#endif
}
void SEND(uint8_t kc) {
// Send Keycode, Does not work for Quantum Codes
if (cMode == COMMAND && CMDLEN < MAX_CMD_BUF) {
uprintf("CMD LEN: %d BUF: %d\n", CMDLEN, MAX_CMD_BUF);
CMDBUF[CMDLEN] = kc;
CMDLEN++;
}
if (cMode != COMMAND) register_code(kc);
return;
}

View file

@ -12,7 +12,7 @@ MOUSEKEY_ENABLE = yes # Mouse keys(+4700), needed for baller
VERBOSE = yes
DEBUG_MATRIX_SCAN_RATE = no
DEBUG_BALLER = no
DEBUG_MATRIX = no
DEBUG_MATRIX = yes
# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.

View file

@ -0,0 +1,151 @@
/* Good on you for modifying your layout! if you don't have
* time to read the QMK docs, a list of keycodes can be found at
*
* https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes.md
*
* There's also a template for adding new layers at the bottom of this file!
*/
#include QMK_KEYBOARD_H
#define IGNORE_MOD_TAP_INTERRUPT
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define NUMB 2 // numbers/motion
// Blank template at the bottom
enum customKeycodes {
URL = 1
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,-------------------------------------------. ,-------------------------------------------.
* | L1/ESC | Q | W | E | R | T | | Y | U | I | O | P | | \ |
* |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
* |Ctrl/BS | A | S | D | F | G | RMB | | | H | J | K | L | ; : | ' " |
* |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
* | LShift | Z | X | C | V | B | LMB | | | N | M | , < | . > | / ? | - _ |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* .----------. .-------. .------. .-----.
* | Super/Del| |Ent/ALT| | Tab | |BKSP |
* '----------' '-------' `------. '-----'
* ,-------. ,-------.
* | MMB | | PgDn |
* ,------|-------| |-------|------.
* | SYMB | NUMB | | SYMB | NUMB |
* | Space| Escape| | Mod |Space |
* | | | | | |
* `--------------' `--------------'
*/
[BASE] = LAYOUT_GERGO(
LT(NUMB, KC_ESC), KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_PIPE,
MT(MOD_LCTL, KC_BSPC), KC_A, KC_S, KC_D, KC_F, KC_G, KC_BTN2, KC_TRNS, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
KC_RSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_BTN1, KC_BSPC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_MINS,
MT(MOD_LGUI, KC_DEL), MT(MOD_LALT, KC_ENT), KC_TAB, KC_BSPC,
KC_BTN3, KC_PGDN,
LT(SYMB, KC_SPC), LT(NUMB, KC_ESC), LT(SYMB, KC_ENT), LT(NUMB, KC_SPC)),
/* Keymap 1: Symbols layer
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | ! | @ | { | } | | | | | | | | | \ | |
* |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
* | | # | $ | ( | ) | ` | | | | + | - | / | * | % | ' " |
* |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
* | | % | ^ | [ | ] | ~ | | | | & | = | , | . | / ? | - _ |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* .------. .------. .------. .-----.
* | | | | | | | DEL |
* '------' '------' `------. '-----'
* ,-------. ,-------.
* | | | PgUp |
* ,------|-------| |-------|------.
* | | | | | |
* | ; | = | | = | ; |
* | | | | | |
* `--------------' `--------------'
*/
[SYMB] = LAYOUT_GERGO(
KC_TRNS, KC_EXLM, KC_AT, KC_LCBR,KC_RCBR, KC_PIPE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BSLS,
KC_TRNS, KC_HASH, KC_DLR, KC_LPRN,KC_RPRN, KC_GRV, KC_TRNS, KC_TRNS, KC_PLUS, KC_MINS, KC_SLSH, KC_ASTR, KC_PERC, KC_QUOT,
KC_TRNS, KC_PERC, KC_CIRC,KC_LBRC,KC_RBRC, KC_TILD, KC_TRNS, KC_TRNS, KC_AMPR, KC_EQL, KC_COMM, KC_DOT, KC_SLSH, KC_MINS,
KC_TRNS, KC_TRNS, KC_PGUP, KC_DEL,
KC_TRNS, KC_TRNS,
KC_SCLN, KC_EQL, KC_EQL, KC_SCLN),
/* Keymap 2: Pad/Function layer
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | |
* |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
* | F1 | F2 | F3 | F4 | F5 | F6 | BTN1 | | | LEFT | DOWN | UP | RIGHT|VolDn | VolUp |
* |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
* | F7 | F8 | F9 | F10 | F11 | F12 | BTN2 | | | MLFT | MDWN | MUP | MRGHT|Ply/Pa| Skip |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* .------. .------. .------. .-----.
* | | | | | | | |
* '------' '------' `------. '-----'
* ,-------. ,-------.
* | | | PgUp |
* ,------|-------| |-------|------.
* | | | | | |
* | | | | | |
* | | | | | |
* `--------------' `--------------'
*/
[NUMB] = LAYOUT_GERGO(
KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS,
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_VOLD, KC_VOLU,
KC_TRNS, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, KC_MPLY, KC_MNXT,
KC_TRNS, KC_TRNS, KC_PGUP, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
};
/* Keymap template
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | | | | | | | | | | | | |
* |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* .------. .------. .------. .-----.
* | | | | | | | |
* '------' '------' `------. '-----'
* ,-------. ,-------.
* | | | |
* ,------|-------| |-------|------.
* | | | | | |
* | | | | | |
* | | | | | |
* `--------------' `--------------'
[SYMB] = LAYOUT_GERGO(
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,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
*/
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
//uint8_t layer = biton32(layer_state);
biton32(layer_state);
};

View file

@ -0,0 +1,10 @@
# [Gergo! By g Heavy Industries](http://gboards.ca)
![Gergo image](https://4.bp.blogspot.com/-889nMXxgSM0/XCNxwnO5kUI/AAAAAAAA6mI/tZbWgZVCBW0dyZOCGJDkjN06DVax7j8XwCLcBGAs/s1600/48422820_967732713413298_485744639215665152_n.jpg)
This is the default keymap for Gergo, it's based heavily off of the naps62 ErgoDox layout and is aimed at a programmer friendly keymap.
## Settings
To edit various settings, enable the 1u trackball and whatnot please modify /keyboards/gergo/keymaps/default/rules.mk
Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!

View file

@ -0,0 +1,36 @@
#----------------------------------------------------------------------------
# make gergo:germ:dfu
# Make sure you have dfu-programmer installed!
#----------------------------------------------------------------------------
# Firmware options
BALLER = yes # Enable to ball out
BALLSTEP = 20 # Multiple in px to move, multiplied by layer number
SCROLLSTEP = 1 # Lines to scroll with ball
MOUSEKEY_ENABLE = yes # Mouse keys(+4700), needed for baller
#Debug options
VERBOSE = yes
DEBUG_MATRIX_SCAN_RATE = no
DEBUG_BALLER = no
DEBUG_MATRIX = no
# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.
#
# No touchy, capiche?
SRC += matrix.c i2c_master.c
ifneq ($(strip $(BALLSTEP)),)
OPT_DEFS += -DTRKSTEP=$(strip $(BALLSTEP))
endif
ifneq ($(strip $(SCROLLSTEP)),)
OPT_DEFS += -DSCROLLSTEP=$(strip $(SCROLLSTEP))
endif
ifeq ($(strip $(BALLER)), yes)
OPT_DEFS += -DBALLER
endif
ifeq ($(strip $(DEBUG_BALLER)), yes)
OPT_DEFS += -DDEBUG_BALLER
endif
ifeq ($(strip $(DEBUG_MATRIX)), yes)
OPT_DEFS += -DDEBUG_MATRIX
endif