-
Notifications
You must be signed in to change notification settings - Fork 487
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add steno module
- Loading branch information
Showing
3 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Steno | ||
|
||
Communicate with stenography software such as [Plover](https://www.openstenoproject.org/plover/) over the Gemini PR protocol. | ||
|
||
## Setup | ||
|
||
You must include the following in `boot.py` to enable data serial. | ||
|
||
```python | ||
import usb_cdc | ||
usb_cdc.enable(data=True) | ||
``` | ||
|
||
Then, instantiate the module as usual and add steno keys to your keymap. | ||
|
||
```python | ||
from kmk.modules.steno import Steno | ||
keyboard.modules.append(Steno()) | ||
``` | ||
|
||
## Keys | ||
|
||
The following keys are created for use in your keymap: | ||
|
||
| Keycode | Description | | ||
|------------|---------------| | ||
| `KC.STN_LS1` | S1- | | ||
| `KC.STN_LS2` | S2- | | ||
| `KC.STN_LT` | T- | | ||
| `KC.STN_LK` | K- | | ||
| `KC.STN_LP` | P- | | ||
| `KC.STN_LW` | W- | | ||
| `KC.STN_LH` | H- | | ||
| `KC.STN_LR` | R- | | ||
| `KC.STN_A` | A | | ||
| `KC.STN_O` | O | | ||
| `KC.STN_AS1` | * Top-left | | ||
| `KC.STN_AS2` | * Lower-left | | ||
| `KC.STN_AS3` | * Top-right | | ||
| `KC.STN_AS4` | * Lower-right | | ||
| `KC.STN_E` | E | | ||
| `KC.STN_U` | U | | ||
| `KC.STN_RF` | -F | | ||
| `KC.STN_RR` | -R | | ||
| `KC.STN_RP` | -P | | ||
| `KC.STN_RB` | -B | | ||
| `KC.STN_RL` | -L | | ||
| `KC.STN_RT` | -T | | ||
| `KC.STN_RS` | -S | | ||
| `KC.STN_RD` | -D | | ||
| `KC.STN_RZ` | -Z | | ||
| `KC.STN_N1` | Number bar 1 | | ||
| `KC.STN_N2` | Number bar 2 | | ||
| `KC.STN_N3` | Number bar 3 | | ||
| `KC.STN_N4` | Number bar 4 | | ||
| `KC.STN_N5` | Number bar 5 | | ||
| `KC.STN_N6` | Number bar 6 | | ||
| `KC.STN_N7` | Number bar 7 | | ||
| `KC.STN_N8` | Number bar 8 | | ||
| `KC.STN_N9` | Number bar 9 | | ||
| `KC.STN_NA` | Number bar A | | ||
| `KC.STN_NB` | Number bar B | | ||
| `KC.STN_NC` | Number bar C | | ||
| `KC.STN_FN` | Function | | ||
| `KC.STN_RES1` | Reset 2 | | ||
| `KC.STN_RES2` | Reset 1 | | ||
| `KC.STN_PWR` | Power | | ||
|
||
## Connecting Plover | ||
|
||
Open the Plover configuration to the Machine tab. Set Machine to Gemini PR. Then, under Connection set the Port to the keyboard's serial data interface (this may take some trial and error if you are unsure which one to use). All other settings can be left as their defaults. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import usb_cdc | ||
|
||
from kmk.keys import make_key | ||
from kmk.modules import Module | ||
|
||
# key order from https://github.com/openstenoproject/plover/blob/main/plover/machine/geminipr.py | ||
# do not rearrange | ||
STENO_KEYS = ( | ||
'STN_FN', | ||
'STN_N1', | ||
'STN_N2', | ||
'STN_N3', | ||
'STN_N4', | ||
'STN_N5', | ||
'STN_N6', | ||
'STN_LS1', | ||
'STN_LS2', | ||
'STN_LT', | ||
'STN_LK', | ||
'STN_LP', | ||
'STN_LW', | ||
'STN_LH', | ||
'STN_LR', | ||
'STN_A', | ||
'STN_O', | ||
'STN_AS1', | ||
'STN_AS2', | ||
'STN_RES1', | ||
'STN_RES2', | ||
'STN_PWR', | ||
'STN_AS3', | ||
'STN_AS4', | ||
'STN_E', | ||
'STN_U', | ||
'STN_RF', | ||
'STN_RR', | ||
'STN_RP', | ||
'STN_RB', | ||
'STN_RL', | ||
'STN_RG', | ||
'STN_RT', | ||
'STN_RS', | ||
'STN_RD', | ||
'STN_N7', | ||
'STN_N8', | ||
'STN_N9', | ||
'STN_NA', | ||
'STN_NB', | ||
'STN_NC', | ||
'STN_RZ', | ||
) | ||
|
||
|
||
class Steno(Module): | ||
def __init__(self): | ||
self._should_write = False | ||
|
||
self._buffer = bytearray(6) | ||
self._initialize_buffer() | ||
|
||
for idx, key in enumerate(STENO_KEYS): | ||
make_key( | ||
code=((idx // 7) << 8) | (0x40 >> (idx % 7)), | ||
names=(key,), | ||
on_press=self._steno_press, | ||
on_release=self._steno_release, | ||
) | ||
|
||
def _initialize_buffer(self): | ||
self._buffer[:] = b'\x80\x00\x00\x00\x00\x00' | ||
|
||
# flip a key's bit in the buffer | ||
def _steno_press(self, key, *_): | ||
self._should_write = True | ||
self._buffer[key.code >> 8] |= key.code & 0xFF | ||
|
||
# send all keys that were pressed, and reset the buffer | ||
def _steno_release(self, *_): | ||
if self._should_write: | ||
usb_cdc.data.write(self._buffer) | ||
|
||
self._should_write = False | ||
self._initialize_buffer() | ||
|
||
def during_bootup(self, keyboard): | ||
pass | ||
|
||
def before_matrix_scan(self, keyboard): | ||
pass | ||
|
||
def after_matrix_scan(self, keyboard): | ||
pass | ||
|
||
def process_key(self, keyboard, key, is_pressed, int_coord): | ||
return key | ||
|
||
def before_hid_send(self, keyboard): | ||
pass | ||
|
||
def after_hid_send(self, keyboard): | ||
pass | ||
|
||
def on_powersave_enable(self, keyboard): | ||
pass | ||
|
||
def on_powersave_disable(self, keyboard): | ||
pass |