summaryrefslogtreecommitdiffstats
path: root/keyboards
diff options
context:
space:
mode:
authorJeremy Bernhardt <jeremythegeek@gmail.com>2019-03-14 14:59:34 -0600
committerDrashna Jaelre <drashna@live.com>2019-03-14 13:59:34 -0700
commit980a41e9049aad53c49b667066a3c5e5cabda113 (patch)
tree68edfd6f3948e13852ae0c1b91f6d1119e4d96ac /keyboards
parent2558372b3f5b383582ee35f318d75a2dc7a28c6e (diff)
[Keyboard] Georgi Support (#5384)
* 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
Diffstat (limited to 'keyboards')
-rw-r--r--keyboards/georgi/config.h74
-rw-r--r--keyboards/georgi/georgi.c68
-rw-r--r--keyboards/georgi/georgi.h82
-rw-r--r--keyboards/georgi/info.json133
-rw-r--r--keyboards/georgi/keymaps/default/keymap.c229
-rw-r--r--keyboards/georgi/keymaps/default/readme.md11
-rw-r--r--keyboards/georgi/keymaps/default/rules.mk27
-rw-r--r--keyboards/georgi/keymaps/template/keymap.c216
-rw-r--r--keyboards/georgi/keymaps/template/readme.md6
-rw-r--r--keyboards/georgi/keymaps/template/rules.mk27
-rw-r--r--keyboards/georgi/matrix.c402
-rw-r--r--keyboards/georgi/readme.md29
-rw-r--r--keyboards/georgi/rules.mk22
-rw-r--r--keyboards/georgi/sten.c2
-rw-r--r--keyboards/georgi/sten.h290
15 files changed, 1618 insertions, 0 deletions
diff --git a/keyboards/georgi/config.h b/keyboards/georgi/config.h
new file mode 100644
index 0000000000..041567719b
--- /dev/null
+++ b/keyboards/georgi/config.h
@@ -0,0 +1,74 @@
+/*
+Copyright 2012 Jun Wako <wakojun@gmail.com>
+Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// Copy and worked on with love from the EZ team
+
+#pragma once
+#include "config_common.h"
+
+/* Defaults */
+
+#define VERSION "Alpha 01: Ted "
+#define VERBOSE
+
+#define FORCE_NKRO
+#define NO_ACTION_MACRO
+#define NO_ACTION_FUNCTION
+#define NO_DEBUG
+#define NO_ACTION_ONESHOT
+#define NO_ACTION_FUNCTION
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x1337
+#define DEVICE_VER 0x0001
+#define MANUFACTURER g Heavy Industries
+#define PRODUCT Georgi
+#define DESCRIPTION QMK keyboard firmware for Georgi
+
+/* key matrix size */
+#define MATRIX_ROWS 14
+#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2)
+#define MATRIX_COLS 4
+
+#define MOUSEKEY_INTERVAL 20
+#define MOUSEKEY_DELAY 0
+#define MOUSEKEY_TIME_TO_MAX 60
+#define MOUSEKEY_MAX_SPEED 7
+#define MOUSEKEY_WHEEL_DELAY 0
+#define TAPPING_TOGGLE 2
+
+/* define if matrix has ghost */
+//#define MATRIX_HAS_GHOST
+
+#define TAPPING_TERM 200
+#define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.)
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)) || \
+ keyboard_report->mods == (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) \
+)
+
+#define DEBOUNCE 5
+#define USB_MAX_POWER_CONSUMPTION 500
diff --git a/keyboards/georgi/georgi.c b/keyboards/georgi/georgi.c
new file mode 100644
index 0000000000..8866886ce7
--- /dev/null
+++ b/keyboards/georgi/georgi.c
@@ -0,0 +1,68 @@
+#include QMK_KEYBOARD_H
+
+bool i2c_initialized = 0;
+i2c_status_t mcp23018_status = 0x20;
+
+void matrix_init_kb(void) {
+ steno_set_mode(STENO_MODE_GEMINI); // or STENO_MODE_BOLT
+
+ // (tied to Vcc for hardware convenience)
+ //DDRB &= ~(1<<4); // set B(4) as input
+ //PORTB &= ~(1<<4); // set B(4) internal pull-up disabled
+
+ // unused pins - C7, D4, D5, D7, E6
+ // set as input with internal pull-up enabled
+ DDRC &= ~(1<<7);
+ DDRD &= ~(1<<5 | 1<<4 | 1<<6 | 1<<7);
+ DDRE &= ~(1<<6);
+ PORTC |= (1<<7);
+ PORTD |= (1<<5 | 1<<4 | 1<<6 | 1<<7);
+ PORTE |= (1<<6);
+
+ matrix_init_user();
+}
+
+
+uint8_t init_mcp23018(void) {
+ print("starting init");
+ mcp23018_status = 0x20;
+
+ // I2C subsystem
+
+ // uint8_t sreg_prev;
+ // sreg_prev=SREG;
+ // cli();
+
+ if (i2c_initialized == 0) {
+ i2c_init(); // on pins D(1,0)
+ i2c_initialized = true;
+ _delay_ms(1000);
+ }
+ // i2c_init(); // on pins D(1,0)
+ // _delay_ms(1000);
+
+ // set pin direction
+ // - unused : input : 1
+ // - input : input : 1
+ // - driving : output : 0
+ mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b10000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
+ i2c_stop();
+
+ // set pull-up
+ // - unused : on : 1
+ // - input : on : 1
+ // - driving : off : 0
+ mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(GPPUA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b10000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
+ mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
+
+out:
+ i2c_stop();
+ // SREG=sreg_prev;
+ //uprintf("Init %x\n", mcp23018_status);
+ return mcp23018_status;
+}
diff --git a/keyboards/georgi/georgi.h b/keyboards/georgi/georgi.h
new file mode 100644
index 0000000000..df6bb6ea9a
--- /dev/null
+++ b/keyboards/georgi/georgi.h
@@ -0,0 +1,82 @@
+#pragma once
+#include <util/delay.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "quantum.h"
+#include "i2c_master.h"
+#include "matrix.h"
+
+
+extern i2c_status_t mcp23018_status;
+#define ERGODOX_EZ_I2C_TIMEOUT 1000
+#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
+#define CPU_16MHz 0x00
+
+// I2C aliases and register addresses (see "mcp23018.md")
+//#define I2C_ADDR 0b0100000
+#define I2C_ADDR 0x20
+#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE )
+#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ )
+#define IODIRA 0x00 // i/o direction register
+#define IODIRB 0x01
+#define GPPUA 0x0C // GPIO pull-up resistor register
+#define GPPUB 0x0D
+#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
+#define GPIOB 0x13
+#define OLATA 0x14 // output latch register
+#define OLATB 0x15
+
+void init_ergodox(void);
+uint8_t init_mcp23018(void);
+
+/* ---------- LEFT HAND ----------- ---------- RIGHT HAND ---------- */
+#define LAYOUT_georgi( \
+ L00,L01,L02,L03,L04,L05, R00,R01,R02,R03,R04,R05, \
+ L10,L11,L12,L13,L14,L15, R10,R11,R12,R13,R14,R15, \
+ L20,L21,L22, R20,R21,R22) \
+ \
+ { \
+ { KC_NO, R00, R10, R21}, \
+ { KC_NO, R01, R11, R20}, \
+ { KC_NO, R02, R12, R22}, \
+ { KC_NO, R03, R13, KC_NO}, \
+ { KC_NO, R04, R14, KC_NO}, \
+ { KC_NO, R05, R15, KC_NO}, \
+ { KC_NO, KC_NO, KC_NO, KC_NO}, \
+ \
+ { KC_NO, L05, L15, L22}, \
+ { KC_NO, L04, L14, L21}, \
+ { KC_NO, L03, L13, L20}, \
+ { KC_NO, L02, L12, KC_NO}, \
+ { KC_NO, L01, L11, KC_NO}, \
+ { KC_NO, L00, L10, KC_NO}, \
+ { KC_NO, KC_NO, KC_NO, KC_NO}, \
+ \
+}
+
+/* ---------- LEFT HAND ----------- ---------- RIGHT HAND ----------
+#define LAYOUT_GERGO( \
+ L00,L01,L02,L03,L04,L05, R00,R01,R02,R03,R04,R05, \
+ L10,L11,L12,L13,L14,L15,L16, R10,R11,R12,R13,R14,R15,R16, \
+ L20,L21,L22,L23,L24,L25,L26, R20,R21,R22,R23,R24,R25,R26, \
+ L31,L32, R33,R34, \
+ L30, R30, \
+ L33,L34, R31,R32) \
+ \
+ { \
+ { KC_NO, L16, L26, L30}, \
+ { L05, L15, L25, L34}, \
+ { L04, L14, L24, L33}, \
+ { L03, L13, L23, L32}, \
+ { L02, L12, L22, L31}, \
+ { L01, L11, L21, KC_NO}, \
+ { L00, L10, L20, KC_NO}, \
+ \
+ { KC_NO, R10, R20, R30}, \
+ { R00, R11, R21, R31}, \
+ { R01, R12, R22, R32}, \
+ { R02, R13, R23, R33}, \
+ { R03, R14, R24, R34}, \
+ { R04, R15, R25, KC_NO}, \
+ { R05, R16, R26, KC_NO}, \
+} */
diff --git a/keyboards/georgi/info.json b/keyboards/georgi/info.json
new file mode 100644
index 0000000000..d0752e2cd3
--- /dev/null
+++ b/keyboards/georgi/info.json
@@ -0,0 +1,133 @@
+{
+ "keyboard_name": "Georgi",
+ "url": "http://gboards.ca",
+ "maintainer": "germ",
+ "width": 13.2,
+ "height": 3.68,
+ "layouts": {
+ "LAYOUT_georgi": {
+ "layout": [
+ {
+ "x": 0.05,
+ "y": 0.54
+ },
+ {
+ "x": 1.06,
+ "y": 0.55
+ },
+ {
+ "x": 2.06,
+ "y": 0.29
+ },
+ {
+ "x": 3.05,
+ "y": 0.16
+ },
+ {
+ "x": 4.06,
+ "y": 0.41
+ },
+ {
+ "x": 5.06,
+ "y": 0.54
+ },
+ {
+ "x": 7.1899999999999995,
+ "y": 0.41
+ },
+ {
+ "x": 8.2,
+ "y": 0.3
+ },
+ {
+ "x": 9.2,
+ "y": 0.05
+ },
+ {
+ "x": 10.2,
+ "y": 0.29
+ },
+ {
+ "x": 11.2,
+ "y": 0.43
+ },
+ {
+ "x": 12.2,
+ "y": 0.42
+ },
+ {
+ "x": 0.05,
+ "y": 1.54
+ },
+ {
+ "x": 1.06,
+ "y": 1.54
+ },
+ {
+ "x": 2.06,
+ "y": 1.28
+ },
+ {
+ "x": 3.05,
+ "y": 1.16
+ },
+ {
+ "x": 4.06,
+ "y": 1.4
+ },
+ {
+ "x": 5.06,
+ "y": 1.54
+ },
+ {
+ "x": 7.1899999999999995,
+ "y": 1.4
+ },
+ {
+ "x": 8.2,
+ "y": 1.28
+ },
+ {
+ "x": 9.2,
+ "y": 1.04
+ },
+ {
+ "x": 10.2,
+ "y": 1.28
+ },
+ {
+ "x": 11.2,
+ "y": 1.42
+ },
+ {
+ "x": 12.2,
+ "y": 1.42
+ },
+ {
+ "x": 3.05,
+ "y": 2.67
+ },
+ {
+ "x": 4.06,
+ "y": 2.68
+ },
+ {
+ "x": 5.06,
+ "y": 2.68
+ },
+ {
+ "x": 7.19,
+ "y": 2.67
+ },
+ {
+ "x": 8.2,
+ "y": 2.67
+ },
+ {
+ "x": 9.2,
+ "y": 2.66
+ }
+ ]
+ }
+ }
+}
diff --git a/keyboards/georgi/keymaps/default/keymap.c b/keyboards/georgi/keymaps/default/keymap.c
new file mode 100644
index 0000000000..c3d69eb8aa
--- /dev/null
+++ b/keyboards/georgi/keymaps/default/keymap.c
@@ -0,0 +1,229 @@
+/*
+ * 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
+#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
+
+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)),
+
+[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]);
+}
diff --git a/keyboards/georgi/keymaps/default/readme.md b/keyboards/georgi/keymaps/default/readme.md
new file mode 100644
index 0000000000..f9da34b024
--- /dev/null
+++ b/keyboards/georgi/keymaps/default/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/default/rules.mk b/keyboards/georgi/keymaps/default/rules.mk
new file mode 100644
index 0000000000..2973c45918
--- /dev/null
+++ b/keyboards/georgi/keymaps/default/rules.mk
@@ -0,0 +1,27 @@
+#----------------------------------------------------------------------------
+# make georgi:extrakey:dfu
+# Make sure you have dfu-programmer installed!
+#----------------------------------------------------------------------------
+
+#Debug options
+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
+
+
+# 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 $(SINGLE_LAYER)), yes)
+ OPT_DEFS += -DSINGLE_LAYER
+endif
diff --git a/keyboards/georgi/keymaps/template/keymap.c b/keyboards/georgi/keymaps/template/keymap.c
new file mode 100644
index 0000000000..b17d7ed9f7
--- /dev/null
+++ b/keyboards/georgi/keymaps/template/keymap.c
@@ -0,0 +1,216 @@
+/*
+ * 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
new file mode 100644
index 0000000000..7c6fc35123
--- /dev/null
+++ b/keyboards/georgi/keymaps/template/readme.md
@@ -0,0 +1,6 @@
+# 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/keymaps/template/rules.mk b/keyboards/georgi/keymaps/template/rules.mk
new file mode 100644
index 0000000000..1178fd80db
--- /dev/null
+++ b/keyboards/georgi/keymaps/template/rules.mk
@@ -0,0 +1,27 @@
+#----