aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wasson <jwasson+github@gmail.com>2017-07-26 21:51:41 -0700
committerJack Humbert <jack.humb@gmail.com>2017-07-27 16:10:36 -0400
commitf30f12ec8122b7c025ff83c5e38e171c4107052b (patch)
treeeebbac46d723f8adea852275c4ea37e2dfe06183
parent5987f67989c1b8f5fbd108d4dae21a227bc2f99c (diff)
downloadqmk_firmware-f30f12ec8122b7c025ff83c5e38e171c4107052b.tar.gz
qmk_firmware-f30f12ec8122b7c025ff83c5e38e171c4107052b.zip
Add support for GeminiPR steno protocol.
This protocol breaks out "duplicate" keys into their own entry in the packet so that more complicated logic can be done on the software side, including support for additional languages and alternative theories.
-rw-r--r--keyboards/planck/keymaps/steno/Makefile4
-rw-r--r--keyboards/planck/keymaps/steno/keymap.c5
-rw-r--r--quantum/keymap_extras/keymap_steno.h9
-rw-r--r--quantum/process_keycode/process_steno.c115
-rw-r--r--quantum/process_keycode/process_steno.h4
-rw-r--r--quantum/quantum_keycodes.h2
-rw-r--r--tmk_core/common/eeconfig.c3
-rw-r--r--tmk_core/common/eeconfig.h1
-rw-r--r--tmk_core/common/keyboard.c6
9 files changed, 121 insertions, 28 deletions
diff --git a/keyboards/planck/keymaps/steno/Makefile b/keyboards/planck/keymaps/steno/Makefile
index 3ed9d2db4..874154af6 100644
--- a/keyboards/planck/keymaps/steno/Makefile
+++ b/keyboards/planck/keymaps/steno/Makefile
@@ -3,5 +3,5 @@ ifndef QUANTUM_DIR
3endif 3endif
4 4
5MOUSEKEY_ENABLE = no # Mouse keys(+4700) 5MOUSEKEY_ENABLE = no # Mouse keys(+4700)
6STENO_ENABLE = yes # Enable TX Bolt protocol for Stenography, requires VIRTSER and may not work with mouse keys 6STENO_ENABLE = yes # Additional protocols for Stenography(+1700), requires VIRTSER
7 7AUDIO_ENABLE = no # Audio output on port C6
diff --git a/keyboards/planck/keymaps/steno/keymap.c b/keyboards/planck/keymaps/steno/keymap.c
index b4e30169f..38540a261 100644
--- a/keyboards/planck/keymaps/steno/keymap.c
+++ b/keyboards/planck/keymaps/steno/keymap.c
@@ -41,6 +41,9 @@ enum planck_keycodes {
41 EXT_PLV 41 EXT_PLV
42}; 42};
43 43
44#define ST_BOLT QK_STENO_BOLT
45#define ST_GEM QK_STENO_GEMINI
46
44const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 47const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
45 48
46/* Qwerty 49/* Qwerty
@@ -166,7 +169,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
166[_ADJUST] = { 169[_ADJUST] = {
167 {_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL }, 170 {_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL },
168 {_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______}, 171 {_______, _______, 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, _______, _______, _______, _______, _______}, 172 {_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, ST_BOLT, ST_GEM},
170 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} 173 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
171} 174}
172 175
diff --git a/quantum/keymap_extras/keymap_steno.h b/quantum/keymap_extras/keymap_steno.h
index 4eb1c7477..4ce91cc13 100644
--- a/quantum/keymap_extras/keymap_steno.h
+++ b/quantum/keymap_extras/keymap_steno.h
@@ -18,8 +18,12 @@
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21// List of keycodes for the steno keyboard. To prevent
22// errors, this must be <= 42 total entries in order to
23// support the GeminiPR protocol.
21enum steno_keycodes { 24enum steno_keycodes {
22 STN_FN = QK_STENO, 25 STN__MIN = QK_STENO,
26 STN_FN = STN__MIN,
23 STN_NUM, 27 STN_NUM,
24 STN_N1 = STN_NUM, 28 STN_N1 = STN_NUM,
25 STN_N2, 29 STN_N2,
@@ -65,7 +69,8 @@ enum steno_keycodes {
65 STN_NA, 69 STN_NA,
66 STN_NB, 70 STN_NB,
67 STN_NC, 71 STN_NC,
68 STN_ZR 72 STN_ZR,
73 STN__MAX = STN_ZR, // must be less than QK_STENO_BOLT
69}; 74};
70 75
71#endif 76#endif
diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c
index 211f00a5a..a91268666 100644
--- a/quantum/process_keycode/process_steno.c
+++ b/quantum/process_keycode/process_steno.c
@@ -1,12 +1,8 @@
1#include "process_steno.h" 1 #include "process_steno.h"
2#include "quantum_keycodes.h" 2#include "quantum_keycodes.h"
3#include "keymap_steno.h" 3#include "keymap_steno.h"
4#include "virtser.h" 4#include "virtser.h"
5 5
6uint8_t state[4] = {0};
7uint8_t pressed = 0;
8
9
10// TxBolt Codes 6// TxBolt Codes
11#define TXB_NUL 0 7#define TXB_NUL 0
12#define TXB_S_L 0b00000001 8#define TXB_S_L 0b00000001
@@ -41,6 +37,13 @@ uint8_t pressed = 0;
41 37
42#define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6) 38#define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6)
43 39
40#define BOLT_STATE_SIZE 4
41#define GEMINI_STATE_SIZE 6
42
43uint8_t state[MAX(BOLT_STATE_SIZE, GEMINI_STATE_SIZE)] = {0};
44uint8_t pressed = 0;
45steno_mode_t mode;
46
44uint8_t boltmap[64] = { 47uint8_t boltmap[64] = {
45 TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, 48 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, 49 TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L,
@@ -52,31 +55,97 @@ uint8_t boltmap[64] = {
52 55
53#define BOLTMAP_MASK (sizeof(boltmap) - 1) 56#define BOLTMAP_MASK (sizeof(boltmap) - 1)
54 57
55void send_steno_state(void) { 58
56 for (uint8_t i = 0; i < 4; ++i) { 59void steno_clear_state(void) {
57 if (state[i]) { 60 memset(state, 0, sizeof(state));
61}
62
63void steno_init() {
64 if (!eeconfig_is_enabled()) {
65 eeconfig_init();
66 }
67 mode = eeprom_read_byte(EECONFIG_STENOMODE);
68}
69
70void steno_set_mode(steno_mode_t new_mode) {
71 steno_clear_state();
72 mode = new_mode;
73 eeprom_update_byte(EECONFIG_STENOMODE, mode);
74}
75
76void send_steno_state(uint8_t size, bool send_empty) {
77 for (uint8_t i = 0; i < size; ++i) {
78 if (state[i] || send_empty) {
58 virtser_send(state[i]); 79 virtser_send(state[i]);
59 state[i] = 0;
60 } 80 }
61 } 81 }
62 virtser_send(0); 82 steno_clear_state();
83}
84
85bool update_state_bolt(uint8_t key) {
86 uint8_t boltcode = boltmap[key];
87 state[TXB_GET_GROUP(boltcode)] |= boltcode;
88 return false;
89}
90
91bool send_state_bolt(void) {
92 send_steno_state(BOLT_STATE_SIZE, false);
93 virtser_send(0); // terminating byte
94 return false;
95}
96
97bool update_state_gemini(uint8_t key) {
98 state[key / 7] |= 1 << (6 - (key % 7));
99 return false;
100}
101
102bool send_state_gemini(void) {
103 state[0] |= 0x80; // Indicate start of packet
104 send_steno_state(GEMINI_STATE_SIZE, true);
105 return false;
63} 106}
64 107
65bool process_steno(uint16_t keycode, keyrecord_t *record) { 108bool process_steno(uint16_t keycode, keyrecord_t *record) {
66 if(keycode >= QK_STENO && keycode <= QK_STENO_MAX) { 109 switch (keycode) {
67 if(IS_PRESSED(record->event)) { 110 case QK_STENO_BOLT:
68 uint8_t boltcode = boltmap[keycode & BOLTMAP_MASK]; 111 if (IS_PRESSED(record->event)) {
69 ++pressed; 112 steno_set_mode(STENO_MODE_BOLT);
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 } 113 }
77 } 114 return false;
78 return false; 115
79 } 116 case QK_STENO_GEMINI:
117 if (IS_PRESSED(record->event)) {
118 steno_set_mode(STENO_MODE_GEMINI);
119 }
120 return false;
80 121
122 case STN__MIN...STN__MAX:
123 if (IS_PRESSED(record->event)) {
124 uint8_t key = keycode - QK_STENO;
125 ++pressed;
126 switch(mode) {
127 case STENO_MODE_BOLT:
128 return update_state_bolt(key);
129 case STENO_MODE_GEMINI:
130 return update_state_gemini(key);
131 default:
132 return false;
133 }
134 } else {
135 --pressed;
136 if (pressed <= 0) {
137 pressed = 0;
138 switch(mode) {
139 case STENO_MODE_BOLT:
140 return send_state_bolt();
141 case STENO_MODE_GEMINI:
142 return send_state_gemini();
143 default:
144 return false;
145 }
146 }
147 }
148
149 }
81 return true; 150 return true;
82} 151}
diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h
index fb9b8e8ad..abd1d466c 100644
--- a/quantum/process_keycode/process_steno.h
+++ b/quantum/process_keycode/process_steno.h
@@ -7,6 +7,10 @@
7 #error "must have virtser enabled to use steno" 7 #error "must have virtser enabled to use steno"
8#endif 8#endif
9 9
10typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t;
11
10bool process_steno(uint16_t keycode, keyrecord_t *record); 12bool process_steno(uint16_t keycode, keyrecord_t *record);
13void steno_init(void);
14void steno_set_mode(steno_mode_t mode);
11 15
12#endif \ No newline at end of file 16#endif \ No newline at end of file
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index f0937628e..ee2fac038 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -73,6 +73,8 @@ enum quantum_keycodes {
73 QK_LAYER_TAP_TOGGLE_MAX = 0x58FF, 73 QK_LAYER_TAP_TOGGLE_MAX = 0x58FF,
74#ifdef STENO_ENABLE 74#ifdef STENO_ENABLE
75 QK_STENO = 0x5900, 75 QK_STENO = 0x5900,
76 QK_STENO_BOLT = 0x5930,
77 QK_STENO_GEMINI = 0x5931,
76 QK_STENO_MAX = 0x593F, 78 QK_STENO_MAX = 0x593F,
77#endif 79#endif
78 QK_MOD_TAP = 0x6000, 80 QK_MOD_TAP = 0x6000,
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 140d2b85b..e2eb4a38e 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -19,6 +19,9 @@ void eeconfig_init(void)
19#ifdef RGBLIGHT_ENABLE 19#ifdef RGBLIGHT_ENABLE
20 eeprom_update_dword(EECONFIG_RGBLIGHT, 0); 20 eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
21#endif 21#endif
22#ifdef STENO_ENABLE
23 eeprom_update_byte(EECONFIG_STENOMODE, 0);
24#endif
22} 25}
23 26
24void eeconfig_enable(void) 27void eeconfig_enable(void)
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index 280dc7ab6..ce60ca866 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
34#define EECONFIG_AUDIO (uint8_t *)7 34#define EECONFIG_AUDIO (uint8_t *)7
35#define EECONFIG_RGBLIGHT (uint32_t *)8 35#define EECONFIG_RGBLIGHT (uint32_t *)8
36#define EECONFIG_UNICODEMODE (uint8_t *)12 36#define EECONFIG_UNICODEMODE (uint8_t *)12
37#define EECONFIG_STENOMODE (uint8_t *)13
37 38
38 39
39/* debug bit */ 40/* debug bit */
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 97a8f1cd8..9466e10e2 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -51,6 +51,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
51#ifdef RGBLIGHT_ENABLE 51#ifdef RGBLIGHT_ENABLE
52# include "rgblight.h" 52# include "rgblight.h"
53#endif 53#endif
54#ifdef STENO_ENABLE
55# include "process_steno.h"
56#endif
54#ifdef FAUXCLICKY_ENABLE 57#ifdef FAUXCLICKY_ENABLE
55# include "fauxclicky.h" 58# include "fauxclicky.h"
56#endif 59#endif
@@ -139,6 +142,9 @@ void keyboard_init(void) {
139#ifdef RGBLIGHT_ENABLE 142#ifdef RGBLIGHT_ENABLE
140 rgblight_init(); 143 rgblight_init();
141#endif 144#endif
145#ifdef STENO_ENABLE
146 steno_init();
147#endif
142#ifdef FAUXCLICKY_ENABLE 148#ifdef FAUXCLICKY_ENABLE
143 fauxclicky_init(); 149 fauxclicky_init();
144#endif 150#endif