diff options
author | Joe Wasson <jwasson+github@gmail.com> | 2017-07-26 21:51:41 -0700 |
---|---|---|
committer | Jack Humbert <jack.humb@gmail.com> | 2017-07-27 16:10:36 -0400 |
commit | f30f12ec8122b7c025ff83c5e38e171c4107052b (patch) | |
tree | eebbac46d723f8adea852275c4ea37e2dfe06183 /quantum | |
parent | 5987f67989c1b8f5fbd108d4dae21a227bc2f99c (diff) |
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.
Diffstat (limited to 'quantum')
-rw-r--r-- | quantum/keymap_extras/keymap_steno.h | 9 | ||||
-rw-r--r-- | quantum/process_keycode/process_steno.c | 115 | ||||
-rw-r--r-- | quantum/process_keycode/process_steno.h | 4 | ||||
-rw-r--r-- | quantum/quantum_keycodes.h | 2 |
4 files changed, 105 insertions, 25 deletions
diff --git a/quantum/keymap_extras/keymap_steno.h b/quantum/keymap_extras/keymap_steno.h index 4eb1c7477a..4ce91cc135 100644 --- a/quantum/keymap_extras/keymap_steno.h +++ b/quantum/keymap_extras/keymap_steno.h @@ -18,8 +18,12 @@ #include "keymap.h" +// List of keycodes for the steno keyboard. To prevent +// errors, this must be <= 42 total entries in order to +// support the GeminiPR protocol. enum steno_keycodes { - STN_FN = QK_STENO, + STN__MIN = QK_STENO, + STN_FN = STN__MIN, STN_NUM, STN_N1 = STN_NUM, STN_N2, @@ -65,7 +69,8 @@ enum steno_keycodes { STN_NA, STN_NB, STN_NC, - STN_ZR + STN_ZR, + STN__MAX = STN_ZR, // must be less than QK_STENO_BOLT }; #endif diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c index 211f00a5a2..a912686660 100644 --- a/quantum/process_keycode/process_steno.c +++ b/quantum/process_keycode/process_steno.c @@ -1,12 +1,8 @@ -#include "process_steno.h" + #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 @@ -41,6 +37,13 @@ uint8_t pressed = 0; #define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6) +#define BOLT_STATE_SIZE 4 +#define GEMINI_STATE_SIZE 6 + +uint8_t state[MAX(BOLT_STATE_SIZE, GEMINI_STATE_SIZE)] = {0}; +uint8_t pressed = 0; +steno_mode_t mode; + 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, @@ -52,31 +55,97 @@ uint8_t boltmap[64] = { #define BOLTMAP_MASK (sizeof(boltmap) - 1) -void send_steno_state(void) { - for (uint8_t i = 0; i < 4; ++i) { - if (state[i]) { + +void steno_clear_state(void) { + memset(state, 0, sizeof(state)); +} + +void steno_init() { + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + mode = eeprom_read_byte(EECONFIG_STENOMODE); +} + +void steno_set_mode(steno_mode_t new_mode) { + steno_clear_state(); + mode = new_mode; + eeprom_update_byte(EECONFIG_STENOMODE, mode); +} + +void send_steno_state(uint8_t size, bool send_empty) { + for (uint8_t i = 0; i < size; ++i) { + if (state[i] || send_empty) { virtser_send(state[i]); - state[i] = 0; } } - virtser_send(0); + steno_clear_state(); +} + +bool update_state_bolt(uint8_t key) { + uint8_t boltcode = boltmap[key]; + state[TXB_GET_GROUP(boltcode)] |= boltcode; + return false; +} + +bool send_state_bolt(void) { + send_steno_state(BOLT_STATE_SIZE, false); + virtser_send(0); // terminating byte + return false; +} + +bool update_state_gemini(uint8_t key) { + state[key / 7] |= 1 << (6 - (key % 7)); + return false; +} + +bool send_state_gemini(void) { + state[0] |= 0x80; // Indicate start of packet + send_steno_state(GEMINI_STATE_SIZE, true); + return false; } 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(); + switch (keycode) { + case QK_STENO_BOLT: + if (IS_PRESSED(record->event)) { + steno_set_mode(STENO_MODE_BOLT); } - } - return false; - } + return false; + + case QK_STENO_GEMINI: + if (IS_PRESSED(record->event)) { + steno_set_mode(STENO_MODE_GEMINI); + } + return false; + case STN__MIN...STN__MAX: + if (IS_PRESSED(record->event)) { + uint8_t key = keycode - QK_STENO; + ++pressed; + switch(mode) { + case STENO_MODE_BOLT: + return update_state_bolt(key); + case STENO_MODE_GEMINI: + return update_state_gemini(key); + default: + return false; + } + } else { + --pressed; + if (pressed <= 0) { + pressed = 0; + switch(mode) { + case STENO_MODE_BOLT: + return send_state_bolt(); + case STENO_MODE_GEMINI: + return send_state_gemini(); + default: + return false; + } + } + } + + } return true; } diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h index fb9b8e8adc..abd1d466cc 100644 --- a/quantum/process_keycode/process_steno.h +++ b/quantum/process_keycode/process_steno.h @@ -7,6 +7,10 @@ #error "must have virtser enabled to use steno" #endif +typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t; + bool process_steno(uint16_t keycode, keyrecord_t *record); +void steno_init(void); +void steno_set_mode(steno_mode_t mode); #endif
\ No newline at end of file diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index f0937628e8..ee2fac0385 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -73,6 +73,8 @@ enum quantum_keycodes { QK_LAYER_TAP_TOGGLE_MAX = 0x58FF, #ifdef STENO_ENABLE QK_STENO = 0x5900, + QK_STENO_BOLT = 0x5930, + QK_STENO_GEMINI = 0x5931, QK_STENO_MAX = 0x593F, #endif QK_MOD_TAP = 0x6000, |