diff --git a/keyboards/georgi/config.h b/keyboards/georgi/config.h
index b35762fbc..30f07667e 100644
--- a/keyboards/georgi/config.h
+++ b/keyboards/georgi/config.h
@@ -23,15 +23,13 @@ along with this program. If not, see .
/* 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
diff --git a/keyboards/georgi/keymaps/default/keymap.c b/keyboards/georgi/keymaps/default/keymap.c
index c3d69eb8a..3a0edb892 100644
--- a/keyboards/georgi/keymaps/default/keymap.c
+++ b/keyboards/georgi/keymaps/default/keymap.c
@@ -1,4 +1,4 @@
-/*
+/*
* 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
*
@@ -15,215 +15,224 @@
#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));
- // 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));
+ // Mouse Keys
+ P( LO | LSD | LK, CLICK_MOUSE(KC_MS_BTN2));
+ P( LO | LR | LW, CLICK_MOUSE(KC_MS_BTN1));
- // 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));
+ // 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));
- // 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));
+ // 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));
- // 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));
+ // 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));
- // 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));
+ // 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));
- // 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));
+ // 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));
- // 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));
+ // 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));
- // If we make here, send as a steno chord
- // If plover is running we can hook that host side
- return false;
+ // 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;
}
-#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)
-,
-// 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)),
+ // 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_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)
+ )
+};
-int getKeymapCount(void) {
- return sizeof(keymaps)/sizeof(keymaps[0]);
-}
+// Don't fuck with this, thanks.
+size_t keymapsCount = sizeof(keymaps)/sizeof(keymaps[0]);
diff --git a/keyboards/georgi/keymaps/default/rules.mk b/keyboards/georgi/keymaps/default/rules.mk
index 2973c4591..90d8057c3 100644
--- a/keyboards/georgi/keymaps/default/rules.mk
+++ b/keyboards/georgi/keymaps/default/rules.mk
@@ -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
diff --git a/keyboards/georgi/keymaps/minimal/keymap.c b/keyboards/georgi/keymaps/minimal/keymap.c
new file mode 100644
index 000000000..1d9b57e9a
--- /dev/null
+++ b/keyboards/georgi/keymaps/minimal/keymap.c
@@ -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]);
diff --git a/keyboards/georgi/keymaps/minimal/readme.md b/keyboards/georgi/keymaps/minimal/readme.md
new file mode 100644
index 000000000..f9da34b02
--- /dev/null
+++ b/keyboards/georgi/keymaps/minimal/readme.md
@@ -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!
diff --git a/keyboards/georgi/keymaps/minimal/rules.mk b/keyboards/georgi/keymaps/minimal/rules.mk
new file mode 100644
index 000000000..cdbbbc280
--- /dev/null
+++ b/keyboards/georgi/keymaps/minimal/rules.mk
@@ -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
diff --git a/keyboards/georgi/keymaps/norman/keymap.c b/keyboards/georgi/keymaps/norman/keymap.c
new file mode 100644
index 000000000..58c42c852
--- /dev/null
+++ b/keyboards/georgi/keymaps/norman/keymap.c
@@ -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]);
diff --git a/keyboards/georgi/keymaps/norman/readme.md b/keyboards/georgi/keymaps/norman/readme.md
new file mode 100644
index 000000000..f9da34b02
--- /dev/null
+++ b/keyboards/georgi/keymaps/norman/readme.md
@@ -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!
diff --git a/keyboards/georgi/keymaps/template/rules.mk b/keyboards/georgi/keymaps/norman/rules.mk
similarity index 61%
rename from keyboards/georgi/keymaps/template/rules.mk
rename to keyboards/georgi/keymaps/norman/rules.mk
index 1178fd80d..bb97bef28 100644
--- a/keyboards/georgi/keymaps/template/rules.mk
+++ b/keyboards/georgi/keymaps/norman/rules.mk
@@ -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
diff --git a/keyboards/georgi/keymaps/template/keymap.c b/keyboards/georgi/keymaps/template/keymap.c
deleted file mode 100644
index b17d7ed9f..000000000
--- a/keyboards/georgi/keymaps/template/keymap.c
+++ /dev/null
@@ -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]);
-}
diff --git a/keyboards/georgi/keymaps/template/readme.md b/keyboards/georgi/keymaps/template/readme.md
deleted file mode 100644
index 7c6fc3512..000000000
--- a/keyboards/georgi/keymaps/template/readme.md
+++ /dev/null
@@ -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!
diff --git a/keyboards/georgi/readme.md b/keyboards/georgi/readme.md
index 03e2e3d83..d86994883 100644
--- a/keyboards/georgi/readme.md
+++ b/keyboards/georgi/readme.md
@@ -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).
diff --git a/keyboards/georgi/rules.mk b/keyboards/georgi/rules.mk
index 0f730f3b7..a87b448e3 100644
--- a/keyboards/georgi/rules.mk
+++ b/keyboards/georgi/rules.mk
@@ -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
diff --git a/keyboards/georgi/sten.c b/keyboards/georgi/sten.c
index 3b33b11d6..1a84c7893 100644
--- a/keyboards/georgi/sten.c
+++ b/keyboards/georgi/sten.c
@@ -1,2 +1,406 @@
-#include "sten.h"
+#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
+}
diff --git a/keyboards/georgi/sten.h b/keyboards/georgi/sten.h
index fee05deca..5a9771d9a 100644
--- a/keyboards/georgi/sten.h
+++ b/keyboards/georgi/sten.h
@@ -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
+// i.e) S(teno)R(ight)F
#define STN(n) (1L< 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;
-}
diff --git a/keyboards/gergo/keymaps/default/rules.mk b/keyboards/gergo/keymaps/default/rules.mk
index 2f825a766..507cc97b7 100644
--- a/keyboards/gergo/keymaps/default/rules.mk
+++ b/keyboards/gergo/keymaps/default/rules.mk
@@ -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.
diff --git a/keyboards/gergo/keymaps/germ/keymap.c b/keyboards/gergo/keymaps/germ/keymap.c
new file mode 100644
index 000000000..fabd945fe
--- /dev/null
+++ b/keyboards/gergo/keymaps/germ/keymap.c
@@ -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);
+};
+
+
diff --git a/keyboards/gergo/keymaps/germ/readme.md b/keyboards/gergo/keymaps/germ/readme.md
new file mode 100644
index 000000000..471a20fbd
--- /dev/null
+++ b/keyboards/gergo/keymaps/germ/readme.md
@@ -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!
diff --git a/keyboards/gergo/keymaps/germ/rules.mk b/keyboards/gergo/keymaps/germ/rules.mk
new file mode 100644
index 000000000..2f825a766
--- /dev/null
+++ b/keyboards/gergo/keymaps/germ/rules.mk
@@ -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