diff options
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 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. | ||
| 21 | enum steno_keycodes { | 24 | enum 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 | ||
| 6 | uint8_t state[4] = {0}; | ||
| 7 | uint8_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 | |||
| 43 | uint8_t state[MAX(BOLT_STATE_SIZE, GEMINI_STATE_SIZE)] = {0}; | ||
| 44 | uint8_t pressed = 0; | ||
| 45 | steno_mode_t mode; | ||
| 46 | |||
| 44 | uint8_t boltmap[64] = { | 47 | uint8_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 | ||
| 55 | void send_steno_state(void) { | 58 | |
| 56 | for (uint8_t i = 0; i < 4; ++i) { | 59 | void steno_clear_state(void) { |
| 57 | if (state[i]) { | 60 | memset(state, 0, sizeof(state)); |
| 61 | } | ||
| 62 | |||
| 63 | void steno_init() { | ||
| 64 | if (!eeconfig_is_enabled()) { | ||
| 65 | eeconfig_init(); | ||
| 66 | } | ||
| 67 | mode = eeprom_read_byte(EECONFIG_STENOMODE); | ||
| 68 | } | ||
| 69 | |||
| 70 | void 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 | |||
| 76 | void 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 | |||
| 85 | bool update_state_bolt(uint8_t key) { | ||
| 86 | uint8_t boltcode = boltmap[key]; | ||
| 87 | state[TXB_GET_GROUP(boltcode)] |= boltcode; | ||
| 88 | return false; | ||
| 89 | } | ||
| 90 | |||
| 91 | bool send_state_bolt(void) { | ||
| 92 | send_steno_state(BOLT_STATE_SIZE, false); | ||
| 93 | virtser_send(0); // terminating byte | ||
| 94 | return false; | ||
| 95 | } | ||
| 96 | |||
| 97 | bool update_state_gemini(uint8_t key) { | ||
| 98 | state[key / 7] |= 1 << (6 - (key % 7)); | ||
| 99 | return false; | ||
| 100 | } | ||
| 101 | |||
| 102 | bool 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 | ||
| 65 | bool process_steno(uint16_t keycode, keyrecord_t *record) { | 108 | bool 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 | ||
| 10 | typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t; | ||
| 11 | |||
| 10 | bool process_steno(uint16_t keycode, keyrecord_t *record); | 12 | bool process_steno(uint16_t keycode, keyrecord_t *record); |
| 13 | void steno_init(void); | ||
| 14 | void 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, |
