]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Add TX Bolt protocol support for Stenography
authorJoe Wasson <jwasson+github@gmail.com>
Wed, 26 Jul 2017 21:41:39 +0000 (14:41 -0700)
committerJack Humbert <jack.humb@gmail.com>
Thu, 27 Jul 2017 20:10:36 +0000 (16:10 -0400)
Requires virtser; Allows QMK to speak the TX BOlt protocol used by stenography machines and software (such as Plover). The upside is that Plover can be configured to listen only to TX Bolt allow the keyboard to switch layers without need to enable/disable the Plover software, or to have a second non-Steno keyboard work concurrently.

14 files changed:
common_features.mk
keyboards/planck/keymaps/experimental/Makefile
keyboards/planck/keymaps/experimental/config.h
keyboards/planck/keymaps/experimental/keymap.c
keyboards/planck/keymaps/steno/Makefile [new file with mode: 0644]
keyboards/planck/keymaps/steno/config.h [new file with mode: 0644]
keyboards/planck/keymaps/steno/keymap.c [new file with mode: 0644]
keyboards/planck/keymaps/steno/readme.md [new file with mode: 0644]
quantum/keymap_extras/keymap_steno.h [new file with mode: 0644]
quantum/process_keycode/process_steno.c [new file with mode: 0644]
quantum/process_keycode/process_steno.h [new file with mode: 0644]
quantum/quantum.c
quantum/quantum.h
quantum/quantum_keycodes.h

index 5eb56ccbfc23078671f70ea536f326e2f93443e3..0adf81afac4d9dab8056cbd1788e1ab36b258187 100644 (file)
@@ -54,6 +54,12 @@ ifeq ($(strip $(COMBO_ENABLE)), yes)
     SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
 endif
 
+ifeq ($(strip $(STENO_ENABLE)), yes)
+    OPT_DEFS += -DSTENO_ENABLE
+       VIRTSER_ENABLE := yes
+       SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
+endif
+
 ifeq ($(strip $(VIRTSER_ENABLE)), yes)
     OPT_DEFS += -DVIRTSER_ENABLE
 endif
index 3a8250a9b56355f8c6d5a43dba24058c674c5687..29108e522b6b575d15b663ffc42fc237f8f3f9c2 100644 (file)
@@ -1,11 +1,11 @@
 
 
 # Build Options
-#   change to "no" to disable the options, or define them in the Makefile in 
+#   change to "no" to disable the options, or define them in the Makefile in
 #   the appropriate keymap folder that will get included automatically
 #
 BOOTMAGIC_ENABLE = no       # Virtual DIP switch configuration(+1000)
-MOUSEKEY_ENABLE = yes       # Mouse keys(+4700)
+MOUSEKEY_ENABLE = no        # Mouse keys(+4700)
 EXTRAKEY_ENABLE = yes       # Audio control and System control(+450)
 CONSOLE_ENABLE = no         # Console for debug(+400)
 COMMAND_ENABLE = yes        # Commands for debug and configuration
@@ -17,6 +17,7 @@ UNICODE_ENABLE = no         # Unicode
 BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
 RGBLIGHT_ENABLE = yes        # Enable WS2812 RGB underlight.  Do not enable this with audio at the same time.
 ONEHAND_ENABLE = yes        # Enable one-hand typing
+STENO_ENABLE = yes                                     # Enable TX Bolt protocol for Stenography, requires VIRTSER and may not work with mouse keys
 
 # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
 SLEEP_LED_ENABLE = no    # Breathing sleep LED during USB suspend
index 492490ca1c894a02cbb9412de98aee05fc19417f..0864b5fbc92df64ab5292fd7756ce5589a45ea7a 100644 (file)
@@ -5,6 +5,7 @@
 
 #define LEADER_TIMEOUT 300
 #define BACKLIGHT_BREATHING
+#define PREVENT_STUCK_MODIFIERS
 
 
 /* ws2812 RGB LED */
index 17fad784e7c00d2889b9f6d0ae459d5edb5ee422..2d648b211aa119533c01eec6ba4bb7a4b15ef485 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "planck.h"
 #include "action_layer.h"
+#include "keymap_steno.h"
 #ifdef AUDIO_ENABLE
   #include "audio.h"
 #endif
@@ -49,7 +50,7 @@ enum planck_keycodes {
 
 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 [0] = {
-  {KC_NO, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL},
+  {QWERTY, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL},
   {KC_NO, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL},
   {KC_NO, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL},
   {KC_NO, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL}
@@ -158,10 +159,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  */
 
 [_PLOVER] = {
-  {KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1   },
-  {XXXXXXX, KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC},
-  {XXXXXXX, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT},
-  {EXT_PLV, XXXXXXX, XXXXXXX, KC_C,    KC_V,    XXXXXXX, XXXXXXX, KC_N,    KC_M,    XXXXXXX, XXXXXXX, XXXXXXX}
+  {STN_N1,  STN_N2,  STN_N3,  STN_N4,  STN_N5,  STN_N6,  STN_N7,  STN_N8,  STN_N9,  STN_NA,  STN_NB,  STN_NC },
+  {STN_FN,  STN_S1,  STN_TL,  STN_PL,  STN_HL,  STN_ST1, STN_ST3, STN_FR,  STN_PR,  STN_LR,  STN_TR,  STN_DR },
+  {XXXXXXX, STN_S2,  STN_KL,  STN_WL,  STN_RL,  STN_ST2, STN_ST4, STN_RR,  STN_BR,  STN_GR,  STN_SR,  STN_ZR },
+  {EXT_PLV, XXXXXXX, XXXXXXX, STN_A,   STN_O,   XXXXXXX, XXXXXXX, STN_E,   STN_U,   STN_PWR, STN_RE1, STN_RE2}
 },
 
 /* Adjust (Lower + Raise)
@@ -279,21 +280,12 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
         break;
       return false;
         case PLOVER:
-          if (record->event.pressed) {
+          if (!record->event.pressed) {
             #ifdef AUDIO_ENABLE
               stop_all_notes();
               PLAY_NOTE_ARRAY(tone_plover, false, 0);
             #endif
-            layer_off(_RAISE);
-            layer_off(_LOWER);
-            layer_off(_ADJUST);
             layer_on(_PLOVER);
-            if (!eeconfig_is_enabled()) {
-                eeconfig_init();
-            }
-            keymap_config.raw = eeconfig_read_keymap();
-            keymap_config.nkro = 1;
-            eeconfig_update_keymap(keymap_config.raw);
           }
         break;
       return false;
@@ -397,9 +389,9 @@ void music_scale_user(void)
 LEADER_EXTERNS();
 
 void matrix_scan_user(void) {
-  LEADER_DICTIONARY() { 
+  LEADER_DICTIONARY() {
     leading = false;
-    leader_end(); 
+    leader_end();
 
     SEQ_ONE_KEY (KC_R) {
       tap_random_base64();
diff --git a/keyboards/planck/keymaps/steno/Makefile b/keyboards/planck/keymaps/steno/Makefile
new file mode 100644 (file)
index 0000000..3ed9d2d
--- /dev/null
@@ -0,0 +1,7 @@
+ifndef QUANTUM_DIR
+       include ../../../../Makefile
+endif
+
+MOUSEKEY_ENABLE = no        # Mouse keys(+4700)
+STENO_ENABLE = yes                                     # Enable TX Bolt protocol for Stenography, requires VIRTSER and may not work with mouse keys
+
diff --git a/keyboards/planck/keymaps/steno/config.h b/keyboards/planck/keymaps/steno/config.h
new file mode 100644 (file)
index 0000000..1879ab0
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+#ifdef AUDIO_ENABLE
+    #define STARTUP_SONG SONG(PLANCK_SOUND)
+    // #define STARTUP_SONG SONG(NO_SOUND)
+
+    #define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
+                                  SONG(COLEMAK_SOUND), \
+                                  SONG(DVORAK_SOUND) \
+                                }
+#endif
+
+#define MUSIC_MASK (keycode != KC_NO)
+
+#define PREVENT_STUCK_MODIFIERS
+
+/*
+ * MIDI options
+ */
+
+/* Prevent use of disabled MIDI features in the keymap */
+//#define MIDI_ENABLE_STRICT 1
+
+/* enable basic MIDI features:
+   - MIDI notes can be sent when in Music mode is on
+*/
+
+#define MIDI_BASIC
+
+/* enable advanced MIDI features:
+   - MIDI notes can be added to the keymap
+   - Octave shift and transpose
+   - Virtual sustain, portamento, and modulation wheel
+   - etc.
+*/
+//#define MIDI_ADVANCED
+
+/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
+//#define MIDI_TONE_KEYCODE_OCTAVES 2
+
+#endif
\ No newline at end of file
diff --git a/keyboards/planck/keymaps/steno/keymap.c b/keyboards/planck/keymaps/steno/keymap.c
new file mode 100644 (file)
index 0000000..b4e3016
--- /dev/null
@@ -0,0 +1,253 @@
+/* Copyright 2015-2017 Jack Humbert
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "planck.h"
+#include "action_layer.h"
+#include "keymap_steno.h"
+
+extern keymap_config_t keymap_config;
+
+enum planck_layers {
+  _QWERTY,
+  _COLEMAK,
+  _DVORAK,
+  _LOWER,
+  _RAISE,
+  _PLOVER,
+  _ADJUST
+};
+
+enum planck_keycodes {
+  QWERTY = SAFE_RANGE,
+  COLEMAK,
+  DVORAK,
+  PLOVER,
+  LOWER,
+  RAISE,
+  BACKLIT,
+  EXT_PLV
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |  "   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_QWERTY] = {
+  {KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC},
+  {KC_ESC,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT},
+  {KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT },
+  {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT}
+},
+
+/* Colemak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   Q  |   W  |   F  |   P  |   G  |   J  |   L  |   U  |   Y  |   ;  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   R  |   S  |   T  |   D  |   H  |   N  |   E  |   I  |   O  |  "   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   Z  |   X  |   C  |   V  |   B  |   K  |   M  |   ,  |   .  |   /  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_COLEMAK] = {
+  {KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,    KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN, KC_BSPC},
+  {KC_ESC,  KC_A,    KC_R,    KC_S,    KC_T,    KC_D,    KC_H,    KC_N,    KC_E,    KC_I,    KC_O,    KC_QUOT},
+  {KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_K,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT },
+  {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT}
+},
+
+/* Dvorak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   "  |   ,  |   .  |   P  |   Y  |   F  |   G  |   C  |   R  |   L  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   O  |   E  |   U  |   I  |   D  |   H  |   T  |   N  |   S  |  /   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   ;  |   Q  |   J  |   K  |   X  |   B  |   M  |   W  |   V  |   Z  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_DVORAK] = {
+  {KC_TAB,  KC_QUOT, KC_COMM, KC_DOT,  KC_P,    KC_Y,    KC_F,    KC_G,    KC_C,    KC_R,    KC_L,    KC_BSPC},
+  {KC_ESC,  KC_A,    KC_O,    KC_E,    KC_U,    KC_I,    KC_D,    KC_H,    KC_T,    KC_N,    KC_S,    KC_SLSH},
+  {KC_LSFT, KC_SCLN, KC_Q,    KC_J,    KC_K,    KC_X,    KC_B,    KC_M,    KC_W,    KC_V,    KC_Z,    KC_ENT },
+  {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT}
+},
+
+/* Lower
+ * ,-----------------------------------------------------------------------------------.
+ * |   ~  |   !  |   @  |   #  |   $  |   %  |   ^  |   &  |   *  |   (  |   )  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   _  |   +  |   {  |   }  |  |   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO ~ |ISO | | Home | End  |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_LOWER] = {
+  {KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_CIRC, KC_AMPR,    KC_ASTR,    KC_LPRN, KC_RPRN, KC_BSPC},
+  {KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_UNDS,    KC_PLUS,    KC_LCBR, KC_RCBR, KC_PIPE},
+  {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  S(KC_NUHS), S(KC_NUBS), KC_HOME, KC_END,  _______},
+  {_______, _______, _______, _______, _______, _______, _______, _______,    KC_MNXT,    KC_VOLD, KC_VOLU, KC_MPLY}
+},
+
+/* Raise
+ * ,-----------------------------------------------------------------------------------.
+ * |   `  |   1  |   2  |   3  |   4  |   5  |   6  |   7  |   8  |   9  |   0  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   -  |   =  |   [  |   ]  |  \   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO # |ISO / |Pg Up |Pg Dn |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_RAISE] = {
+  {KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC},
+  {KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS},
+  {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______},
+  {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
+},
+
+/* Plover layer (http://opensteno.org)
+ * ,-----------------------------------------------------------------------------------.
+ * |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * |  FN  |   S  |   T  |   P  |   H  |   *  |   *  |   F  |   P  |   L  |   T  |   D  |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |   S  |   K  |   W  |   R  |   *  |   *  |   R  |   B  |   G  |   S  |   Z  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Exit |      |      |   A  |   O  |             |   E  |   U  |  PWR | RES1 | RES2 |
+ * `-----------------------------------------------------------------------------------'
+ */
+
+[_PLOVER] = {
+  {STN_N1,  STN_N2,  STN_N3,  STN_N4,  STN_N5,  STN_N6,  STN_N7,  STN_N8,  STN_N9,  STN_NA,  STN_NB,  STN_NC },
+  {STN_FN,  STN_S1,  STN_TL,  STN_PL,  STN_HL,  STN_ST1, STN_ST3, STN_FR,  STN_PR,  STN_LR,  STN_TR,  STN_DR },
+  {XXXXXXX, STN_S2,  STN_KL,  STN_WL,  STN_RL,  STN_ST2, STN_ST4, STN_RR,  STN_BR,  STN_GR,  STN_SR,  STN_ZR },
+  {EXT_PLV, XXXXXXX, XXXXXXX, STN_A,   STN_O,   XXXXXXX, XXXXXXX, STN_E,   STN_U,   STN_PWR, STN_RE1, STN_RE2}
+},
+
+/* Adjust (Lower + Raise)
+ * ,-----------------------------------------------------------------------------------.
+ * |      | Reset|      |      |      |      |      |      |      |      |      |  Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * |      |      |      |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover|      |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof|      |      |      |TXBOLT|GEM RP|
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_ADJUST] = {
+  {_______, RESET,   _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL },
+  {_______, _______, MU_MOD,  AU_ON,   AU_OFF,  AG_NORM, AG_SWAP, QWERTY,  COLEMAK, DVORAK,  PLOVER,  _______},
+  {_______, MUV_DE,  MUV_IN,  MU_ON,   MU_OFF,  MI_ON,   MI_OFF,  _______, _______, _______, _______, _______},
+  {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
+}
+
+
+};
+
+#ifdef AUDIO_ENABLE
+  float plover_song[][2]     = SONG(PLOVER_SOUND);
+  float plover_gb_song[][2]  = SONG(PLOVER_GOODBYE_SOUND);
+#endif
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+    case QWERTY:
+      if (record->event.pressed) {
+        set_single_persistent_default_layer(_QWERTY);
+      }
+      return false;
+      break;
+    case COLEMAK:
+      if (record->event.pressed) {
+        set_single_persistent_default_layer(_COLEMAK);
+      }
+      return false;
+      break;
+    case DVORAK:
+      if (record->event.pressed) {
+        set_single_persistent_default_layer(_DVORAK);
+      }
+      return false;
+      break;
+    case LOWER:
+      if (record->event.pressed) {
+        layer_on(_LOWER);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      } else {
+        layer_off(_LOWER);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      }
+      return false;
+      break;
+    case RAISE:
+      if (record->event.pressed) {
+        layer_on(_RAISE);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      } else {
+        layer_off(_RAISE);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      }
+      return false;
+      break;
+    case BACKLIT:
+      if (record->event.pressed) {
+        register_code(KC_RSFT);
+        #ifdef BACKLIGHT_ENABLE
+          backlight_step();
+        #endif
+      } else {
+        unregister_code(KC_RSFT);
+      }
+      return false;
+      break;
+    case PLOVER:
+      if (!record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          stop_all_notes();
+          PLAY_SONG(plover_song);
+        #endif
+        layer_on(_PLOVER);
+      }
+      return false;
+      break;
+    case EXT_PLV:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_SONG(plover_gb_song);
+        #endif
+        layer_off(_PLOVER);
+      }
+      return false;
+      break;
+  }
+  return true;
+}
\ No newline at end of file
diff --git a/keyboards/planck/keymaps/steno/readme.md b/keyboards/planck/keymaps/steno/readme.md
new file mode 100644 (file)
index 0000000..e8ffd97
--- /dev/null
@@ -0,0 +1,4 @@
+# The Default Planck Layout with TX Bolt for the Plover Layer
+
+To use set Plover to TX Bolt and select the COM port that represents your keyboard.
+
diff --git a/quantum/keymap_extras/keymap_steno.h b/quantum/keymap_extras/keymap_steno.h
new file mode 100644 (file)
index 0000000..4eb1c74
--- /dev/null
@@ -0,0 +1,71 @@
+/* Copyright 2017 Joseph Wasson
+ *
+ * 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/>.
+ */
+#ifndef KEYMAP_STENO_H
+#define KEYMAP_STENO_H
+
+#include "keymap.h"
+
+enum steno_keycodes {
+  STN_FN  = QK_STENO,
+  STN_NUM,
+  STN_N1 = STN_NUM,
+  STN_N2,
+  STN_N3,
+  STN_N4,
+  STN_N5,
+  STN_N6,
+  STN_SL,
+  STN_S1 = STN_SL,
+  STN_S2,
+  STN_TL,
+  STN_KL,
+  STN_PL,
+  STN_WL,
+  STN_HL,
+  STN_RL,
+  STN_A,
+  STN_O,
+  STN_STR,
+  STN_ST1 = STN_STR,
+  STN_ST2,
+  STN_RES1,
+  STN_RE1 = STN_RES1,
+  STN_RES2,
+  STN_RE2 = STN_RES2,
+  STN_PWR,
+  STN_ST3,
+  STN_ST4,
+  STN_E,
+  STN_U,
+  STN_FR,
+  STN_RR,
+  STN_PR,
+  STN_BR,
+  STN_LR,
+  STN_GR,
+  STN_TR,
+  STN_SR,
+  STN_DR,
+  STN_N7,
+  STN_N8,
+  STN_N9,
+  STN_NA,
+  STN_NB,
+  STN_NC,
+  STN_ZR
+};
+
+#endif
diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c
new file mode 100644 (file)
index 0000000..211f00a
--- /dev/null
@@ -0,0 +1,82 @@
+#include "process_steno.h"
+#include "quantum_keycodes.h"
+#include "keymap_steno.h"
+#include "virtser.h"
+
+uint8_t state[4] = {0};
+uint8_t pressed = 0;
+
+
+// TxBolt Codes
+#define TXB_NUL 0
+#define TXB_S_L 0b00000001
+#define TXB_T_L 0b00000010
+#define TXB_K_L 0b00000100
+#define TXB_P_L 0b00001000
+#define TXB_W_L 0b00010000
+#define TXB_H_L 0b00100000
+#define TXB_R_L 0b01000001
+#define TXB_A_L 0b01000010
+#define TXB_O_L 0b01000100
+#define TXB_STR 0b01001000
+#define TXB_E_R 0b01010000
+#define TXB_U_R 0b01100000
+#define TXB_F_R 0b10000001
+#define TXB_R_R 0b10000010
+#define TXB_P_R 0b10000100
+#define TXB_B_R 0b10001000
+#define TXB_L_R 0b10010000
+#define TXB_G_R 0b10100000
+#define TXB_T_R 0b11000001
+#define TXB_S_R 0b11000010
+#define TXB_D_R 0b11000100
+#define TXB_Z_R 0b11001000
+#define TXB_NUM 0b11010000
+
+#define TXB_GRP0 0b00000000
+#define TXB_GRP1 0b01000000
+#define TXB_GRP2 0b10000000
+#define TXB_GRP3 0b11000000
+#define TXB_GRPMASK 0b11000000
+
+#define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6)
+
+uint8_t boltmap[64] = {
+  TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM,
+  TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L,
+  TXB_R_L, TXB_A_L, TXB_O_L, TXB_STR, TXB_STR, TXB_NUL, TXB_NUL,
+  TXB_NUL, TXB_STR, TXB_STR, TXB_E_R, TXB_U_R, TXB_F_R, TXB_R_R,
+  TXB_P_R, TXB_B_R, TXB_L_R, TXB_G_R, TXB_T_R, TXB_S_R, TXB_D_R,
+  TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_Z_R
+};
+
+#define BOLTMAP_MASK (sizeof(boltmap) - 1)
+
+void send_steno_state(void) {
+  for (uint8_t i = 0; i < 4; ++i) {
+    if (state[i]) {
+      virtser_send(state[i]);
+      state[i] = 0;
+    }
+  }
+  virtser_send(0);
+}
+
+bool process_steno(uint16_t keycode, keyrecord_t *record) {
+  if(keycode >= QK_STENO && keycode <= QK_STENO_MAX) {
+    if(IS_PRESSED(record->event)) {
+      uint8_t boltcode = boltmap[keycode & BOLTMAP_MASK];
+      ++pressed;
+      state[TXB_GET_GROUP(boltcode)] |= boltcode;
+    } else {
+      --pressed;
+      if (pressed <= 0) {
+        pressed = 0; // protect against spurious up keys
+        send_steno_state();
+      }
+    }
+    return false;
+  }
+
+  return true;
+}
diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h
new file mode 100644 (file)
index 0000000..fb9b8e8
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef PROCESS_STENO_H
+#define PROCESS_STENO_H
+
+#include "quantum.h"
+
+#if defined(STENO_ENABLE) && !defined(VIRTSER_ENABLE)
+  #error "must have virtser enabled to use steno"
+#endif
+
+bool process_steno(uint16_t keycode, keyrecord_t *record);
+
+#endif
\ No newline at end of file
index b76a1141868b2ee41aa9a56c2a3daa672c2f2624..1f8ce6c46f52464817f37f5777256c8d27a75428 100644 (file)
@@ -200,6 +200,9 @@ bool process_record_quantum(keyrecord_t *record) {
   #ifdef AUDIO_ENABLE
     process_audio(keycode, record) &&
   #endif
+  #ifdef STENO_ENABLE
+    process_steno(keycode, record) &&
+  #endif
   #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
     process_music(keycode, record) &&
   #endif
@@ -722,14 +725,14 @@ void backlight_set(uint8_t level)
       //   _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
       // #endif
     #endif
-  } 
+  }
   #ifndef NO_BACKLIGHT_CLOCK
     else if ( level == BACKLIGHT_LEVELS ) {
       // Turn on PWM control of backlight pin
       TCCR1A |= _BV(COM1x1);
       // Set the brightness
       OCR1x = 0xFFFF;
-    } 
+    }
     else {
       // Turn on PWM control of backlight pin
       TCCR1A |= _BV(COM1x1);
@@ -747,7 +750,7 @@ uint8_t backlight_tick = 0;
 
 void backlight_task(void) {
   #ifdef NO_BACKLIGHT_CLOCK
-  if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) { 
+  if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
     #if BACKLIGHT_ON_STATE == 0
       // PORTx &= ~n
       _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
index 6c0e465732ea313e5b6383c4f002496aa40b8389..453cb43f88af863e02c12ca87072b2cbee586f8b 100644 (file)
@@ -60,6 +60,10 @@ extern uint32_t default_layer_state;
        #include "process_audio.h"
 #endif
 
+#ifdef STENO_ENABLE
+       #include "process_steno.h"
+#endif
+
 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
        #include "process_music.h"
 #endif
index 06ab6d18db655c562807ab49f0e7c831f50080b9..f0937628e876ad8bd7af2398837e672c797f90f6 100644 (file)
@@ -71,6 +71,10 @@ enum quantum_keycodes {
     QK_TAP_DANCE_MAX      = 0x57FF,
     QK_LAYER_TAP_TOGGLE   = 0x5800,
     QK_LAYER_TAP_TOGGLE_MAX = 0x58FF,
+#ifdef STENO_ENABLE
+    QK_STENO              = 0x5900,
+    QK_STENO_MAX          = 0x593F,
+#endif
     QK_MOD_TAP            = 0x6000,
     QK_MOD_TAP_MAX        = 0x7FFF,
 #if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE)