aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wasson <jwasson+github@gmail.com>2017-07-26 14:41:39 -0700
committerJack Humbert <jack.humb@gmail.com>2017-07-27 16:10:36 -0400
commit5987f67989c1b8f5fbd108d4dae21a227bc2f99c (patch)
tree32bee84bf7265d0fce7c924db38021b08ea5cbb2
parentcefc09ae7dd88cd6b92412881888404da1abdfcb (diff)
downloadqmk_firmware-5987f67989c1b8f5fbd108d4dae21a227bc2f99c.tar.gz
qmk_firmware-5987f67989c1b8f5fbd108d4dae21a227bc2f99c.zip
Add TX Bolt protocol support for Stenography
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.
-rw-r--r--common_features.mk6
-rw-r--r--keyboards/planck/keymaps/experimental/Makefile5
-rw-r--r--keyboards/planck/keymaps/experimental/config.h1
-rw-r--r--keyboards/planck/keymaps/experimental/keymap.c26
-rw-r--r--keyboards/planck/keymaps/steno/Makefile7
-rw-r--r--keyboards/planck/keymaps/steno/config.h44
-rw-r--r--keyboards/planck/keymaps/steno/keymap.c253
-rw-r--r--keyboards/planck/keymaps/steno/readme.md4
-rw-r--r--quantum/keymap_extras/keymap_steno.h71
-rw-r--r--quantum/process_keycode/process_steno.c82
-rw-r--r--quantum/process_keycode/process_steno.h12
-rw-r--r--quantum/quantum.c9
-rw-r--r--quantum/quantum.h4
-rw-r--r--quantum/quantum_keycodes.h4
14 files changed, 506 insertions, 22 deletions
diff --git a/common_features.mk b/common_features.mk
index 5eb56ccbf..0adf81afa 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -54,6 +54,12 @@ ifeq ($(strip $(COMBO_ENABLE)), yes)
54 SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c 54 SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
55endif 55endif
56 56
57ifeq ($(strip $(STENO_ENABLE)), yes)
58 OPT_DEFS += -DSTENO_ENABLE
59 VIRTSER_ENABLE := yes
60 SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
61endif
62
57ifeq ($(strip $(VIRTSER_ENABLE)), yes) 63ifeq ($(strip $(VIRTSER_ENABLE)), yes)
58 OPT_DEFS += -DVIRTSER_ENABLE 64 OPT_DEFS += -DVIRTSER_ENABLE
59endif 65endif
diff --git a/keyboards/planck/keymaps/experimental/Makefile b/keyboards/planck/keymaps/experimental/Makefile
index 3a8250a9b..29108e522 100644
--- a/keyboards/planck/keymaps/experimental/Makefile
+++ b/keyboards/planck/keymaps/experimental/Makefile
@@ -1,11 +1,11 @@
1 1
2 2
3# Build Options 3# Build Options
4# change to "no" to disable the options, or define them in the Makefile in 4# change to "no" to disable the options, or define them in the Makefile in
5# the appropriate keymap folder that will get included automatically 5# the appropriate keymap folder that will get included automatically
6# 6#
7BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) 7BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
8MOUSEKEY_ENABLE = yes # Mouse keys(+4700) 8MOUSEKEY_ENABLE = no # Mouse keys(+4700)
9EXTRAKEY_ENABLE = yes # Audio control and System control(+450) 9EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
10CONSOLE_ENABLE = no # Console for debug(+400) 10CONSOLE_ENABLE = no # Console for debug(+400)
11COMMAND_ENABLE = yes # Commands for debug and configuration 11COMMAND_ENABLE = yes # Commands for debug and configuration
@@ -17,6 +17,7 @@ UNICODE_ENABLE = no # Unicode
17BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID 17BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
18RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. 18RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
19ONEHAND_ENABLE = yes # Enable one-hand typing 19ONEHAND_ENABLE = yes # Enable one-hand typing
20STENO_ENABLE = yes # Enable TX Bolt protocol for Stenography, requires VIRTSER and may not work with mouse keys
20 21
21# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE 22# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
22SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend 23SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
diff --git a/keyboards/planck/keymaps/experimental/config.h b/keyboards/planck/keymaps/experimental/config.h
index 492490ca1..0864b5fbc 100644
--- a/keyboards/planck/keymaps/experimental/config.h
+++ b/keyboards/planck/keymaps/experimental/config.h
@@ -5,6 +5,7 @@
5 5
6#define LEADER_TIMEOUT 300 6#define LEADER_TIMEOUT 300
7#define BACKLIGHT_BREATHING 7#define BACKLIGHT_BREATHING
8#define PREVENT_STUCK_MODIFIERS
8 9
9 10
10/* ws2812 RGB LED */ 11/* ws2812 RGB LED */
diff --git a/keyboards/planck/keymaps/experimental/keymap.c b/keyboards/planck/keymaps/experimental/keymap.c
index 17fad784e..2d648b211 100644
--- a/keyboards/planck/keymaps/experimental/keymap.c
+++ b/keyboards/planck/keymaps/experimental/keymap.c
@@ -3,6 +3,7 @@
3 3
4#include "planck.h" 4#include "planck.h"
5#include "action_layer.h" 5#include "action_layer.h"
6#include "keymap_steno.h"
6#ifdef AUDIO_ENABLE 7#ifdef AUDIO_ENABLE
7 #include "audio.h" 8 #include "audio.h"
8#endif 9#endif
@@ -49,7 +50,7 @@ enum planck_keycodes {
49 50
50const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 51const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
51[0] = { 52[0] = {
52 {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}, 53 {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},
53 {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}, 54 {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},
54 {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}, 55 {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},
55 {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} 56 {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] = {
158 */ 159 */
159 160
160[_PLOVER] = { 161[_PLOVER] = {
161 {KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 }, 162 {STN_N1, STN_N2, STN_N3, STN_N4, STN_N5, STN_N6, STN_N7, STN_N8, STN_N9, STN_NA, STN_NB, STN_NC },
162 {XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC}, 163 {STN_FN, STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1, STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR },
163 {XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT}, 164 {XXXXXXX, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2, STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR },
164 {EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX} 165 {EXT_PLV, XXXXXXX, XXXXXXX, STN_A, STN_O, XXXXXXX, XXXXXXX, STN_E, STN_U, STN_PWR, STN_RE1, STN_RE2}
165}, 166},
166 167
167/* Adjust (Lower + Raise) 168/* Adjust (Lower + Raise)
@@ -279,21 +280,12 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
279 break; 280 break;
280 return false; 281 return false;
281 case PLOVER: 282 case PLOVER:
282 if (record->event.pressed) { 283 if (!record->event.pressed) {
283 #ifdef AUDIO_ENABLE 284 #ifdef AUDIO_ENABLE
284 stop_all_notes(); 285 stop_all_notes();
285 PLAY_NOTE_ARRAY(tone_plover, false, 0); 286 PLAY_NOTE_ARRAY(tone_plover, false, 0);
286 #endif 287 #endif
287 layer_off(_RAISE);
288 layer_off(_LOWER);
289 layer_off(_ADJUST);
290 layer_on(_PLOVER); 288 layer_on(_PLOVER);
291 if (!eeconfig_is_enabled()) {
292 eeconfig_init();
293 }
294 keymap_config.raw = eeconfig_read_keymap();
295 keymap_config.nkro = 1;
296 eeconfig_update_keymap(keymap_config.raw);
297 } 289 }
298 break; 290 break;
299 return false; 291 return false;
@@ -397,9 +389,9 @@ void music_scale_user(void)
397LEADER_EXTERNS(); 389LEADER_EXTERNS();
398 390
399void matrix_scan_user(void) { 391void matrix_scan_user(void) {
400 LEADER_DICTIONARY() { 392 LEADER_DICTIONARY() {
401 leading = false; 393 leading = false;
402 leader_end(); 394 leader_end();
403 395
404 SEQ_ONE_KEY (KC_R) { 396 SEQ_ONE_KEY (KC_R) {
405 tap_random_base64(); 397 tap_random_base64();
diff --git a/keyboards/planck/keymaps/steno/Makefile b/keyboards/planck/keymaps/steno/Makefile
new file mode 100644
index 000000000..3ed9d2db4
--- /dev/null
+++ b/keyboards/planck/keymaps/steno/Makefile
@@ -0,0 +1,7 @@
1ifndef QUANTUM_DIR
2 include ../../../../Makefile
3endif
4
5MOUSEKEY_ENABLE = no # Mouse keys(+4700)
6STENO_ENABLE = yes # Enable TX Bolt protocol for Stenography, requires VIRTSER and may not work with mouse keys
7
diff --git a/keyboards/planck/keymaps/steno/config.h b/keyboards/planck/keymaps/steno/config.h
new file mode 100644
index 000000000..1879ab007
--- /dev/null
+++ b/keyboards/planck/keymaps/steno/config.h
@@ -0,0 +1,44 @@
1#ifndef CONFIG_USER_H
2#define CONFIG_USER_H
3
4#include "../../config.h"
5
6#ifdef AUDIO_ENABLE
7 #define STARTUP_SONG SONG(PLANCK_SOUND)
8 // #define STARTUP_SONG SONG(NO_SOUND)
9
10 #define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
11 SONG(COLEMAK_SOUND), \
12 SONG(DVORAK_SOUND) \
13 }
14#endif
15
16#define MUSIC_MASK (keycode != KC_NO)
17
18#define PREVENT_STUCK_MODIFIERS
19
20/*
21 * MIDI options
22 */
23
24/* Prevent use of disabled MIDI features in the keymap */
25//#define MIDI_ENABLE_STRICT 1
26
27/* enable basic MIDI features:
28 - MIDI notes can be sent when in Music mode is on
29*/
30
31#define MIDI_BASIC
32
33/* enable advanced MIDI features:
34 - MIDI notes can be added to the keymap
35 - Octave shift and transpose
36 - Virtual sustain, portamento, and modulation wheel
37 - etc.
38*/
39//#define MIDI_ADVANCED
40
41/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
42//#define MIDI_TONE_KEYCODE_OCTAVES 2
43
44#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
index 000000000..b4e30169f
--- /dev/null
+++ b/keyboards/planck/keymaps/steno/keymap.c
@@ -0,0 +1,253 @@
1/* Copyright 2015-2017 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "planck.h"
18#include "action_layer.h"
19#include "keymap_steno.h"
20
21extern keymap_config_t keymap_config;
22
23enum planck_layers {
24 _QWERTY,
25 _COLEMAK,
26 _DVORAK,
27 _LOWER,
28 _RAISE,
29 _PLOVER,
30 _ADJUST
31};
32
33enum planck_keycodes {
34 QWERTY = SAFE_RANGE,
35 COLEMAK,
36 DVORAK,
37 PLOVER,
38 LOWER,
39 RAISE,
40 BACKLIT,
41 EXT_PLV
42};
43
44const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
45
46/* Qwerty
47 * ,-----------------------------------------------------------------------------------.
48 * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
49 * |------+------+------+------+------+-------------+------+------+------+------+------|
50 * | Esc | A | S | D | F | G | H | J | K | L | ; | " |
51 * |------+------+------+------+------+------|------+------+------+------+------+------|
52 * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
53 * |------+------+------+------+------+------+------+------+------+------+------+------|
54 * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
55 * `-----------------------------------------------------------------------------------'
56 */
57[_QWERTY] = {
58 {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
59 {KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
60 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
61 {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
62},
63
64/* Colemak
65 * ,-----------------------------------------------------------------------------------.
66 * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
67 * |------+------+------+------+------+-------------+------+------+------+------+------|
68 * | Esc | A | R | S | T | D | H | N | E | I | O | " |
69 * |------+------+------+------+------+------|------+------+------+------+------+------|
70 * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
71 * |------+------+------+------+------+------+------+------+------+------+------+------|
72 * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
73 * `-----------------------------------------------------------------------------------'
74 */
75[_COLEMAK] = {
76 {KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
77 {KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
78 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
79 {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
80},
81
82/* Dvorak
83 * ,-----------------------------------------------------------------------------------.
84 * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
85 * |------+------+------+------+------+-------------+------+------+------+------+------|
86 * | Esc | A | O | E | U | I | D | H | T | N | S | / |
87 * |------+------+------+------+------+------|------+------+------+------+------+------|
88 * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
89 * |------+------+------+------+------+------+------+------+------+------+------+------|
90 * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
91 * `-----------------------------------------------------------------------------------'
92 */
93[_DVORAK] = {
94 {KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC},
95 {KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH},
96 {KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT },
97 {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
98},
99
100/* Lower
101 * ,-----------------------------------------------------------------------------------.
102 * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
103 * |------+------+------+------+------+-------------+------+------+------+------+------|
104 * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | |
105 * |------+------+------+------+------+------|------+------+------+------+------+------|
106 * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | Home | End | |
107 * |------+------+------+------+------+------+------+------+------+------+------+------|
108 * | | | | | | | | Next | Vol- | Vol+ | Play |
109 * `-----------------------------------------------------------------------------------'
110 */
111[_LOWER] = {
112 {KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
113 {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
114 {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, S(KC_NUHS), S(KC_NUBS), KC_HOME, KC_END, _______},
115 {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
116},
117
118/* Raise
119 * ,-----------------------------------------------------------------------------------.
120 * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
121 * |------+------+------+------+------+-------------+------+------+------+------+------|
122 * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
123 * |------+------+------+------+------+------|------+------+------+------+------+------|
124 * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / |Pg Up |Pg Dn | |
125 * |------+------+------+------+------+------+------+------+------+------+------+------|
126 * | | | | | | | | Next | Vol- | Vol+ | Play |
127 * `-----------------------------------------------------------------------------------'
128 */
129[_RAISE] = {
130 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
131 {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
132 {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______},
133 {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
134},
135
136/* Plover layer (http://opensteno.org)
137 * ,-----------------------------------------------------------------------------------.
138 * | # | # | # | # | # | # | # | # | # | # | # | # |
139 * |------+------+------+------+------+-------------+------+------+------+------+------|
140 * | FN | S | T | P | H | * | * | F | P | L | T | D |
141 * |------+------+------+------+------+------|------+------+------+------+------+------|
142 * | | S | K | W | R | * | * | R | B | G | S | Z |
143 * |------+------+------+------+------+------+------+------+------+------+------+------|
144 * | Exit | | | A | O | | E | U | PWR | RES1 | RES2 |
145 * `-----------------------------------------------------------------------------------'
146 */
147
148[_PLOVER] = {
149 {STN_N1, STN_N2, STN_N3, STN_N4, STN_N5, STN_N6, STN_N7, STN_N8, STN_N9, STN_NA, STN_NB, STN_NC },
150 {STN_FN, STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1, STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR },
151 {XXXXXXX, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2, STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR },
152 {EXT_PLV, XXXXXXX, XXXXXXX, STN_A, STN_O, XXXXXXX, XXXXXXX, STN_E, STN_U, STN_PWR, STN_RE1, STN_RE2}
153},
154
155/* Adjust (Lower + Raise)
156 * ,-----------------------------------------------------------------------------------.
157 * | | Reset| | | | | | | | | | Del |
158 * |------+------+------+------+------+-------------+------+------+------+------+------|
159 * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| |
160 * |------+------+------+------+------+------|------+------+------+------+------+------|
161 * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | |TXBOLT|GEM RP|
162 * |------+------+------+------+------+------+------+------+------+------+------+------|
163 * | | | | | | | | | | | |
164 * `-----------------------------------------------------------------------------------'
165 */
166[_ADJUST] = {
167 {_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL },
168 {_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______},
169 {_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
170 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
171}
172
173
174};
175
176#ifdef AUDIO_ENABLE
177 float plover_song[][2] = SONG(PLOVER_SOUND);
178 float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND);
179#endif
180
181bool process_record_user(uint16_t keycode, keyrecord_t *record) {
182 switch (keycode) {
183 case QWERTY:
184 if (record->event.pressed) {
185 set_single_persistent_default_layer(_QWERTY);
186 }
187 return false;
188 break;
189 case COLEMAK:
190 if (record->event.pressed) {
191 set_single_persistent_default_layer(_COLEMAK);
192 }
193 return false;
194 break;
195 case DVORAK:
196 if (record->event.pressed) {
197 set_single_persistent_default_layer(_DVORAK);
198 }
199 return false;
200 break;
201 case LOWER:
202 if (record->event.pressed) {
203 layer_on(_LOWER);
204 update_tri_layer(_LOWER, _RAISE, _ADJUST);
205 } else {
206 layer_off(_LOWER);
207 update_tri_layer(_LOWER, _RAISE, _ADJUST);
208 }
209 return false;
210 break;
211 case RAISE:
212 if (record->event.pressed) {
213 layer_on(_RAISE);
214 update_tri_layer(_LOWER, _RAISE, _ADJUST);
215 } else {
216 layer_off(_RAISE);
217 update_tri_layer(_LOWER, _RAISE, _ADJUST);
218 }
219 return false;
220 break;
221 case BACKLIT:
222 if (record->event.pressed) {
223 register_code(KC_RSFT);
224 #ifdef BACKLIGHT_ENABLE
225 backlight_step();
226 #endif
227 } else {
228 unregister_code(KC_RSFT);
229 }
230 return false;
231 break;
232 case PLOVER:
233 if (!record->event.pressed) {
234 #ifdef AUDIO_ENABLE
235 stop_all_notes();
236 PLAY_SONG(plover_song);
237 #endif
238 layer_on(_PLOVER);
239 }
240 return false;
241 break;
242 case EXT_PLV:
243 if (record->event.pressed) {
244 #ifdef AUDIO_ENABLE
245 PLAY_SONG(plover_gb_song);
246 #endif
247 layer_off(_PLOVER);
248 }
249 return false;
250 break;
251 }
252 return true;
253} \ 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
index 000000000..e8ffd9756
--- /dev/null
+++ b/keyboards/planck/keymaps/steno/readme.md
@@ -0,0 +1,4 @@
1# The Default Planck Layout with TX Bolt for the Plover Layer
2
3To use set Plover to TX Bolt and select the COM port that represents your keyboard.
4
diff --git a/quantum/keymap_extras/keymap_steno.h b/quantum/keymap_extras/keymap_steno.h
new file mode 100644
index 000000000..4eb1c7477
--- /dev/null
+++ b/quantum/keymap_extras/keymap_steno.h
@@ -0,0 +1,71 @@
1/* Copyright 2017 Joseph Wasson
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef KEYMAP_STENO_H
17#define KEYMAP_STENO_H
18
19#include "keymap.h"
20
21enum steno_keycodes {
22 STN_FN = QK_STENO,
23 STN_NUM,
24 STN_N1 = STN_NUM,
25 STN_N2,
26 STN_N3,
27 STN_N4,
28 STN_N5,
29 STN_N6,
30 STN_SL,
31 STN_S1 = STN_SL,
32 STN_S2,
33 STN_TL,
34 STN_KL,
35 STN_PL,
36 STN_WL,
37 STN_HL,
38 STN_RL,
39 STN_A,
40 STN_O,
41 STN_STR,
42 STN_ST1 = STN_STR,
43 STN_ST2,
44 STN_RES1,
45 STN_RE1 = STN_RES1,
46 STN_RES2,
47 STN_RE2 = STN_RES2,
48 STN_PWR,
49 STN_ST3,
50 STN_ST4,
51 STN_E,
52 STN_U,
53 STN_FR,
54 STN_RR,
55 STN_PR,
56 STN_BR,
57 STN_LR,
58 STN_GR,
59 STN_TR,
60 STN_SR,
61 STN_DR,
62 STN_N7,
63 STN_N8,
64 STN_N9,
65 STN_NA,
66 STN_NB,
67 STN_NC,
68 STN_ZR
69};
70
71#endif
diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c
new file mode 100644
index 000000000..211f00a5a
--- /dev/null
+++ b/quantum/process_keycode/process_steno.c
@@ -0,0 +1,82 @@
1#include "process_steno.h"
2#include "quantum_keycodes.h"
3#include "keymap_steno.h"
4#include "virtser.h"
5
6uint8_t state[4] = {0};
7uint8_t pressed = 0;
8
9
10// TxBolt Codes
11#define TXB_NUL 0
12#define TXB_S_L 0b00000001
13#define TXB_T_L 0b00000010
14#define TXB_K_L 0b00000100
15#define TXB_P_L 0b00001000
16#define TXB_W_L 0b00010000
17#define TXB_H_L 0b00100000
18#define TXB_R_L 0b01000001
19#define TXB_A_L 0b01000010
20#define TXB_O_L 0b01000100
21#define TXB_STR 0b01001000
22#define TXB_E_R 0b01010000
23#define TXB_U_R 0b01100000
24#define TXB_F_R 0b10000001
25#define TXB_R_R 0b10000010
26#define TXB_P_R 0b10000100
27#define TXB_B_R 0b10001000
28#define TXB_L_R 0b10010000
29#define TXB_G_R 0b10100000
30#define TXB_T_R 0b11000001
31#define TXB_S_R 0b11000010
32#define TXB_D_R 0b11000100
33#define TXB_Z_R 0b11001000
34#define TXB_NUM 0b11010000
35
36#define TXB_GRP0 0b00000000
37#define TXB_GRP1 0b01000000
38#define TXB_GRP2 0b10000000
39#define TXB_GRP3 0b11000000
40#define TXB_GRPMASK 0b11000000
41
42#define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6)
43
44uint8_t boltmap[64] = {
45 TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM,
46 TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L,
47 TXB_R_L, TXB_A_L, TXB_O_L, TXB_STR, TXB_STR, TXB_NUL, TXB_NUL,
48 TXB_NUL, TXB_STR, TXB_STR, TXB_E_R, TXB_U_R, TXB_F_R, TXB_R_R,
49 TXB_P_R, TXB_B_R, TXB_L_R, TXB_G_R, TXB_T_R, TXB_S_R, TXB_D_R,
50 TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_Z_R
51};
52
53#define BOLTMAP_MASK (sizeof(boltmap) - 1)
54
55void send_steno_state(void) {
56 for (uint8_t i = 0; i < 4; ++i) {
57 if (state[i]) {
58 virtser_send(state[i]);
59 state[i] = 0;
60 }
61 }
62 virtser_send(0);
63}
64
65bool process_steno(uint16_t keycode, keyrecord_t *record) {
66 if(keycode >= QK_STENO && keycode <= QK_STENO_MAX) {
67 if(IS_PRESSED(record->event)) {
68 uint8_t boltcode = boltmap[keycode & BOLTMAP_MASK];
69 ++pressed;
70 state[TXB_GET_GROUP(boltcode)] |= boltcode;
71 } else {
72 --pressed;
73 if (pressed <= 0) {
74 pressed = 0; // protect against spurious up keys
75 send_steno_state();
76 }
77 }
78 return false;
79 }
80
81 return true;
82}
diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h
new file mode 100644
index 000000000..fb9b8e8ad
--- /dev/null
+++ b/quantum/process_keycode/process_steno.h
@@ -0,0 +1,12 @@
1#ifndef PROCESS_STENO_H
2#define PROCESS_STENO_H
3
4#include "quantum.h"
5
6#if defined(STENO_ENABLE) && !defined(VIRTSER_ENABLE)
7 #error "must have virtser enabled to use steno"
8#endif
9
10bool process_steno(uint16_t keycode, keyrecord_t *record);
11
12#endif \ No newline at end of file
diff --git a/quantum/quantum.c b/quantum/quantum.c
index b76a11418..1f8ce6c46 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -200,6 +200,9 @@ bool process_record_quantum(keyrecord_t *record) {
200 #ifdef AUDIO_ENABLE 200 #ifdef AUDIO_ENABLE
201 process_audio(keycode, record) && 201 process_audio(keycode, record) &&
202 #endif 202 #endif
203 #ifdef STENO_ENABLE
204 process_steno(keycode, record) &&
205 #endif
203 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) 206 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
204 process_music(keycode, record) && 207 process_music(keycode, record) &&
205 #endif 208 #endif
@@ -722,14 +725,14 @@ void backlight_set(uint8_t level)
722 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); 725 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
723 // #endif 726 // #endif
724 #endif 727 #endif
725 } 728 }
726 #ifndef NO_BACKLIGHT_CLOCK 729 #ifndef NO_BACKLIGHT_CLOCK
727 else if ( level == BACKLIGHT_LEVELS ) { 730 else if ( level == BACKLIGHT_LEVELS ) {
728 // Turn on PWM control of backlight pin 731 // Turn on PWM control of backlight pin
729 TCCR1A |= _BV(COM1x1); 732 TCCR1A |= _BV(COM1x1);
730 // Set the brightness 733 // Set the brightness
731 OCR1x = 0xFFFF; 734 OCR1x = 0xFFFF;
732 } 735 }
733 else { 736 else {
734 // Turn on PWM control of backlight pin 737 // Turn on PWM control of backlight pin
735 TCCR1A |= _BV(COM1x1); 738 TCCR1A |= _BV(COM1x1);
@@ -747,7 +750,7 @@ uint8_t backlight_tick = 0;
747 750
748void backlight_task(void) { 751void backlight_task(void) {
749 #ifdef NO_BACKLIGHT_CLOCK 752 #ifdef NO_BACKLIGHT_CLOCK
750 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) { 753 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
751 #if BACKLIGHT_ON_STATE == 0 754 #if BACKLIGHT_ON_STATE == 0
752 // PORTx &= ~n 755 // PORTx &= ~n
753 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); 756 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 6c0e46573..453cb43f8 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -60,6 +60,10 @@ extern uint32_t default_layer_state;
60 #include "process_audio.h" 60 #include "process_audio.h"
61#endif 61#endif
62 62
63#ifdef STENO_ENABLE
64 #include "process_steno.h"
65#endif
66
63#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) 67#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
64 #include "process_music.h" 68 #include "process_music.h"
65#endif 69#endif
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 06ab6d18d..f0937628e 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -71,6 +71,10 @@ enum quantum_keycodes {
71 QK_TAP_DANCE_MAX = 0x57FF, 71 QK_TAP_DANCE_MAX = 0x57FF,
72 QK_LAYER_TAP_TOGGLE = 0x5800, 72 QK_LAYER_TAP_TOGGLE = 0x5800,
73 QK_LAYER_TAP_TOGGLE_MAX = 0x58FF, 73 QK_LAYER_TAP_TOGGLE_MAX = 0x58FF,
74#ifdef STENO_ENABLE
75 QK_STENO = 0x5900,
76 QK_STENO_MAX = 0x593F,
77#endif
74 QK_MOD_TAP = 0x6000, 78 QK_MOD_TAP = 0x6000,
75 QK_MOD_TAP_MAX = 0x7FFF, 79 QK_MOD_TAP_MAX = 0x7FFF,
76#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE) 80#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE)