]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Add support for GeminiPR steno protocol.
authorJoe Wasson <jwasson+github@gmail.com>
Thu, 27 Jul 2017 04:51:41 +0000 (21:51 -0700)
committerJack Humbert <jack.humb@gmail.com>
Thu, 27 Jul 2017 20:10:36 +0000 (16:10 -0400)
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.

keyboards/planck/keymaps/steno/Makefile
keyboards/planck/keymaps/steno/keymap.c
quantum/keymap_extras/keymap_steno.h
quantum/process_keycode/process_steno.c
quantum/process_keycode/process_steno.h
quantum/quantum_keycodes.h
tmk_core/common/eeconfig.c
tmk_core/common/eeconfig.h
tmk_core/common/keyboard.c

index 3ed9d2db45fbbec97642b04fb8365c81b9dc4c3e..874154af630123c775baf317c9272819e15a4fbd 100644 (file)
@@ -3,5 +3,5 @@ ifndef QUANTUM_DIR
 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
-
+STENO_ENABLE = yes          # Additional protocols for Stenography(+1700), requires VIRTSER
+AUDIO_ENABLE = no           # Audio output on port C6
index b4e30169fb37de82c18df7adb1f0f64f555b9f44..38540a2613790303091755de0193f86eb3008e38 100644 (file)
@@ -41,6 +41,9 @@ enum planck_keycodes {
   EXT_PLV
 };
 
+#define ST_BOLT QK_STENO_BOLT
+#define ST_GEM  QK_STENO_GEMINI
+
 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 
 /* Qwerty
@@ -166,7 +169,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 [_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,  _______, _______, _______, _______, _______},
+  {_______, MUV_DE,  MUV_IN,  MU_ON,   MU_OFF,  MI_ON,   MI_OFF,  _______, _______, _______, ST_BOLT, ST_GEM},
   {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
 }
 
index 4eb1c7477adccf2750ec6b15d9311947089c3fab..4ce91cc1352012a22fb9452815beb0a1fd6599f3 100644 (file)
 
 #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
index 211f00a5a2b5fc620ae7c05ffe6ef8c2febe49c1..a9126866603015ed3dafeb89a4e6db9af6df792a 100644 (file)
@@ -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;
 }
index fb9b8e8adce9bb40afdecbdceeb1a87cd1bcb209..abd1d466cc4d59990216d10e451d162f21e69eb5 100644 (file)
@@ -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
index f0937628e876ad8bd7af2398837e672c797f90f6..ee2fac038500669696e99ab6695a43df764e0d1e 100644 (file)
@@ -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,
index 140d2b85bb9f2857af85bd57731459506e8dc0c6..e2eb4a38e3d21e6629f0dd71204b3737587df9a0 100644 (file)
@@ -19,6 +19,9 @@ void eeconfig_init(void)
 #ifdef RGBLIGHT_ENABLE
     eeprom_update_dword(EECONFIG_RGBLIGHT,      0);
 #endif
+#ifdef STENO_ENABLE
+    eeprom_update_byte(EECONFIG_STENOMODE,      0);
+#endif
 }
 
 void eeconfig_enable(void)
index 280dc7ab67e7bf8fe2e94f1affd8d67d79931a5b..ce60ca86615cd1df35eee18d4897734f7c219b0d 100644 (file)
@@ -34,6 +34,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define EECONFIG_AUDIO                              (uint8_t *)7
 #define EECONFIG_RGBLIGHT                           (uint32_t *)8
 #define EECONFIG_UNICODEMODE                        (uint8_t *)12
+#define EECONFIG_STENOMODE                          (uint8_t *)13
 
 
 /* debug bit */
index 97a8f1cd8c4e2f88086cbaab490a51b58ecd5cc9..9466e10e2d412d1b4f50aa966a33093a3dc10f2c 100644 (file)
@@ -51,6 +51,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifdef RGBLIGHT_ENABLE
 #   include "rgblight.h"
 #endif
+#ifdef STENO_ENABLE
+#   include "process_steno.h"
+#endif
 #ifdef FAUXCLICKY_ENABLE
 #   include "fauxclicky.h"
 #endif
@@ -139,6 +142,9 @@ void keyboard_init(void) {
 #ifdef RGBLIGHT_ENABLE
     rgblight_init();
 #endif
+#ifdef STENO_ENABLE
+    steno_init();
+#endif
 #ifdef FAUXCLICKY_ENABLE
     fauxclicky_init();
 #endif