forked from mirrors/qmk_userspace
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.
This commit is contained in:
parent
cefc09ae7d
commit
5987f67989
14 changed files with 506 additions and 22 deletions
71
quantum/keymap_extras/keymap_steno.h
Normal file
71
quantum/keymap_extras/keymap_steno.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* Copyright 2017 Joseph Wasson
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef KEYMAP_STENO_H
|
||||
#define KEYMAP_STENO_H
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
enum steno_keycodes {
|
||||
STN_FN = QK_STENO,
|
||||
STN_NUM,
|
||||
STN_N1 = STN_NUM,
|
||||
STN_N2,
|
||||
STN_N3,
|
||||
STN_N4,
|
||||
STN_N5,
|
||||
STN_N6,
|
||||
STN_SL,
|
||||
STN_S1 = STN_SL,
|
||||
STN_S2,
|
||||
STN_TL,
|
||||
STN_KL,
|
||||
STN_PL,
|
||||
STN_WL,
|
||||
STN_HL,
|
||||
STN_RL,
|
||||
STN_A,
|
||||
STN_O,
|
||||
STN_STR,
|
||||
STN_ST1 = STN_STR,
|
||||
STN_ST2,
|
||||
STN_RES1,
|
||||
STN_RE1 = STN_RES1,
|
||||
STN_RES2,
|
||||
STN_RE2 = STN_RES2,
|
||||
STN_PWR,
|
||||
STN_ST3,
|
||||
STN_ST4,
|
||||
STN_E,
|
||||
STN_U,
|
||||
STN_FR,
|
||||
STN_RR,
|
||||
STN_PR,
|
||||
STN_BR,
|
||||
STN_LR,
|
||||
STN_GR,
|
||||
STN_TR,
|
||||
STN_SR,
|
||||
STN_DR,
|
||||
STN_N7,
|
||||
STN_N8,
|
||||
STN_N9,
|
||||
STN_NA,
|
||||
STN_NB,
|
||||
STN_NC,
|
||||
STN_ZR
|
||||
};
|
||||
|
||||
#endif
|
82
quantum/process_keycode/process_steno.c
Normal file
82
quantum/process_keycode/process_steno.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
#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
|
||||
#define TXB_T_L 0b00000010
|
||||
#define TXB_K_L 0b00000100
|
||||
#define TXB_P_L 0b00001000
|
||||
#define TXB_W_L 0b00010000
|
||||
#define TXB_H_L 0b00100000
|
||||
#define TXB_R_L 0b01000001
|
||||
#define TXB_A_L 0b01000010
|
||||
#define TXB_O_L 0b01000100
|
||||
#define TXB_STR 0b01001000
|
||||
#define TXB_E_R 0b01010000
|
||||
#define TXB_U_R 0b01100000
|
||||
#define TXB_F_R 0b10000001
|
||||
#define TXB_R_R 0b10000010
|
||||
#define TXB_P_R 0b10000100
|
||||
#define TXB_B_R 0b10001000
|
||||
#define TXB_L_R 0b10010000
|
||||
#define TXB_G_R 0b10100000
|
||||
#define TXB_T_R 0b11000001
|
||||
#define TXB_S_R 0b11000010
|
||||
#define TXB_D_R 0b11000100
|
||||
#define TXB_Z_R 0b11001000
|
||||
#define TXB_NUM 0b11010000
|
||||
|
||||
#define TXB_GRP0 0b00000000
|
||||
#define TXB_GRP1 0b01000000
|
||||
#define TXB_GRP2 0b10000000
|
||||
#define TXB_GRP3 0b11000000
|
||||
#define TXB_GRPMASK 0b11000000
|
||||
|
||||
#define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6)
|
||||
|
||||
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,
|
||||
TXB_R_L, TXB_A_L, TXB_O_L, TXB_STR, TXB_STR, TXB_NUL, TXB_NUL,
|
||||
TXB_NUL, TXB_STR, TXB_STR, TXB_E_R, TXB_U_R, TXB_F_R, TXB_R_R,
|
||||
TXB_P_R, TXB_B_R, TXB_L_R, TXB_G_R, TXB_T_R, TXB_S_R, TXB_D_R,
|
||||
TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_Z_R
|
||||
};
|
||||
|
||||
#define BOLTMAP_MASK (sizeof(boltmap) - 1)
|
||||
|
||||
void send_steno_state(void) {
|
||||
for (uint8_t i = 0; i < 4; ++i) {
|
||||
if (state[i]) {
|
||||
virtser_send(state[i]);
|
||||
state[i] = 0;
|
||||
}
|
||||
}
|
||||
virtser_send(0);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
12
quantum/process_keycode/process_steno.h
Normal file
12
quantum/process_keycode/process_steno.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef PROCESS_STENO_H
|
||||
#define PROCESS_STENO_H
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#if defined(STENO_ENABLE) && !defined(VIRTSER_ENABLE)
|
||||
#error "must have virtser enabled to use steno"
|
||||
#endif
|
||||
|
||||
bool process_steno(uint16_t keycode, keyrecord_t *record);
|
||||
|
||||
#endif
|
|
@ -200,6 +200,9 @@ bool process_record_quantum(keyrecord_t *record) {
|
|||
#ifdef AUDIO_ENABLE
|
||||
process_audio(keycode, record) &&
|
||||
#endif
|
||||
#ifdef STENO_ENABLE
|
||||
process_steno(keycode, record) &&
|
||||
#endif
|
||||
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
|
||||
process_music(keycode, record) &&
|
||||
#endif
|
||||
|
@ -722,14 +725,14 @@ void backlight_set(uint8_t level)
|
|||
// _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
|
||||
// #endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifndef NO_BACKLIGHT_CLOCK
|
||||
else if ( level == BACKLIGHT_LEVELS ) {
|
||||
// Turn on PWM control of backlight pin
|
||||
TCCR1A |= _BV(COM1x1);
|
||||
// Set the brightness
|
||||
OCR1x = 0xFFFF;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Turn on PWM control of backlight pin
|
||||
TCCR1A |= _BV(COM1x1);
|
||||
|
@ -747,7 +750,7 @@ uint8_t backlight_tick = 0;
|
|||
|
||||
void backlight_task(void) {
|
||||
#ifdef NO_BACKLIGHT_CLOCK
|
||||
if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
|
||||
if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
|
||||
#if BACKLIGHT_ON_STATE == 0
|
||||
// PORTx &= ~n
|
||||
_SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
|
||||
|
|
|
@ -60,6 +60,10 @@ extern uint32_t default_layer_state;
|
|||
#include "process_audio.h"
|
||||
#endif
|
||||
|
||||
#ifdef STENO_ENABLE
|
||||
#include "process_steno.h"
|
||||
#endif
|
||||
|
||||
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
|
||||
#include "process_music.h"
|
||||
#endif
|
||||
|
|
|
@ -71,6 +71,10 @@ enum quantum_keycodes {
|
|||
QK_TAP_DANCE_MAX = 0x57FF,
|
||||
QK_LAYER_TAP_TOGGLE = 0x5800,
|
||||
QK_LAYER_TAP_TOGGLE_MAX = 0x58FF,
|
||||
#ifdef STENO_ENABLE
|
||||
QK_STENO = 0x5900,
|
||||
QK_STENO_MAX = 0x593F,
|
||||
#endif
|
||||
QK_MOD_TAP = 0x6000,
|
||||
QK_MOD_TAP_MAX = 0x7FFF,
|
||||
#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue