Skip to content

Instantly share code, notes, and snippets.

@crides
Created September 24, 2021 19:01
Show Gist options
  • Save crides/91158027958b9a2f67ee93860adaa9e1 to your computer and use it in GitHub Desktop.
Save crides/91158027958b9a2f67ee93860adaa9e1 to your computer and use it in GitHub Desktop.
Steno keyboard USB protocol (draft)
numbers in `(3)` denote the size in bytes. All numbers are little endian
magic: 0x4e545345 / ESTN
Commands(1):
- 0x00 SETUP()
- 0x01 EN_CAP(cap(1), arg(1))
Enable a capability while passing an argument; the argument may be ignored by the device if the capability doesn't need it
- 0x02 DIS_CAP(cap(1))
- 0x03 GET_NAMES()
Get the names of the individual keys
- 0x04 SET_LED(?)
- 0x05 SHOW_MSG(?)
- 0x06 WRITE_DATA(?)
Capabilities(1):
- 0x00 STROKE
Send full strokes to the host when they are completed
- 0x01 KEY
Send individual key (binary) events to the host
- 0x02 RAW_KEY
Send raw sensor data to the host when polled. Only needed for non-binary sensors
- 0x03 SET_THRES
Threshold for each key can be set. Only needed for non-binary sensors
- 0x04 SHOW_MSG
Can show messages on the keyboard
- 0x05 WRITE_DATA
Can receive raw data, e.g. for dictionary editing?
Host packet:
+------------------------------+
| magic(4) | cmd(1) | arg(0-2) |
+------------------------------+
Device packets:
- setup:
+----------+------------+-------------+------------+---------------------------+
| | | | | +--------+ |
| magic(4) | key_num(1) | key_size(1) | cap_len(1) | caps(cap_len * | cap(1) |)|
| | | | | +--------+ |
+----------+------------+-------------+------------+---------------------------+
- names:
+----------+-----------------------------+
| | +---------+ |
| magic(4) | names(key_num * | name(2) |)|
| | +---------+ |
+----------+-----------------------------+
- stroke
+----------------+-------------------------+
| cap(STROKE(1)) | keys(ceil(key_num / 8)) |
+----------------+-------------------------+
- key
+-------------+--------+
| cap(KEY(1)) | key(1) |
+-------------+--------+
- raw key
+-----------------+--------+
| cap(RAW_KEY(1)) | key(2) |
+-----------------+--------+
TODOs:
[ ] Do we want `GET_NAMES` or enforce some order/pattern on how the keys are reported?
[ ] Setting LEDs / messages
[ ] Dictionary update
[ ] Arbitrary UI stuff??
[ ] Sequencing / CRC?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment