Update README with features, flash space, and simulator fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,90 @@
|
||||
# ku1255cfw
|
||||
Custom open firmware for the Lenovo KU-1255 compact USB keyboard
|
||||
|
||||
## Overview
|
||||
|
||||
The Lenovo ThinkPad Compact USB Keyboard with TrackPoint (KU-1255) uses a
|
||||
Sonix SN8F2288FG 8-bit MCU with 12K words (24KB) flash and 512 bytes RAM.
|
||||
The TrackPoint is connected via bit-banged I2C (P2.4 SCL, P2.5 SDA, address
|
||||
0x2A, Synaptics proprietary protocol).
|
||||
|
||||
This firmware is a from-scratch rewrite based on the original by
|
||||
[ranma](https://github.com/ranma/ku1255cfw), adding standalone middle-button
|
||||
scroll and other missing features so the keyboard works fully without an
|
||||
external converter.
|
||||
|
||||
## Features added over base firmware
|
||||
|
||||
### Middle-button scroll
|
||||
3-state state machine (IDLE / UNDECIDED / SCROLLING) with 150ms timeout:
|
||||
- **Short press** (<150ms): sends a normal middle click (deferred on release)
|
||||
- **Hold + TrackPoint movement**: converts XY deltas to scroll wheel events
|
||||
- **FN + middle button**: passes middle button through directly (no scroll logic)
|
||||
|
||||
### CapsLock LED feedback
|
||||
Host LED output reports (SET_REPORT) are parsed and CapsLock state (bit 1) drives
|
||||
the power LED on P5.3/PWM0 (active-low). The flasher magic byte sequence detection
|
||||
is preserved.
|
||||
|
||||
### FN+F7 through FN+F12
|
||||
| Key | Normal | With FN held |
|
||||
|-----|--------|-------------|
|
||||
| F7 | F7 | LGUI+P (display settings) |
|
||||
| F8 | F8 | F8 (passthrough) |
|
||||
| F9 | F9 | LGUI+I (settings) |
|
||||
| F10 | F10 | LGUI (search) |
|
||||
| F11 | F11 | LCTRL+LALT+TAB (task switch) |
|
||||
| F12 | F12 | F12 (passthrough) |
|
||||
|
||||
### USB compliance fixes
|
||||
- **HID GET_REPORT**: returns proper per-interface empty reports (8B keyboard / 5B mouse)
|
||||
instead of stale buffer contents. Some OSes query this on resume from suspend.
|
||||
- **SET/CLEAR FEATURE**: tracks DEVICE_REMOTE_WAKEUP state instead of just ACKing.
|
||||
|
||||
## Flash space
|
||||
|
||||
| Firmware | Words used | Free | Utilization |
|
||||
|----------|-----------|------|-------------|
|
||||
| OEM | 10,226 / 10,239 | 13 | 99.9% |
|
||||
| This | 10,238 / 10,239 | 1 | 100.0% |
|
||||
|
||||
Key debouncing is not implemented (and not needed) — the 8ms scan cycle naturally
|
||||
debounces scissor switches (<1ms bounce time). The OEM firmware also does not debounce.
|
||||
|
||||
## Flashing
|
||||
|
||||
Requires [vpelletier/dissn8](https://github.com/vpelletier/dissn8) tools.
|
||||
|
||||
1. Build: `asn8 main.s -o ku1255cfw.bin`
|
||||
2. Enter bootloader: hold **Return** while plugging in the keyboard
|
||||
3. Flash: `flashsn8 ku1255cfw.bin`
|
||||
|
||||
## Simulator testing
|
||||
|
||||
`test_scroll.py` runs 23 automated tests against the
|
||||
[dissn8 simulator](https://github.com/vpelletier/dissn8) via the `ku1255_sim.py`
|
||||
harness. Tests cover all scroll state transitions, deferred click timing, FN modifier
|
||||
interaction, and edge cases (rapid clicks, timeout behavior).
|
||||
|
||||
**Note:** The simulator requires a fix for PnUR register read handlers (see below).
|
||||
|
||||
## Simulator fixes (for vpelletier/dissn8)
|
||||
|
||||
Running this firmware in the dissn8 simulator exposed three bugs:
|
||||
|
||||
1. **PnUR read handlers crash** — `_volatile_dict` maps P0UR-P5UR read handlers to
|
||||
`None`. B0BSET/B0BCLR (read-modify-write) on these registers causes
|
||||
`TypeError: 'NoneType' object is not callable`. Fixed by adding `readPullUp()`
|
||||
returning the latch value. Branch: `pnur_readpullup` (PR pending upstream).
|
||||
|
||||
2. **Hardcoded HID descriptor sizes** — `ku1255_sim.py` assumed 0x51/0xD3 byte
|
||||
HID report descriptors (OEM sizes). This firmware uses 91/61 bytes. Fixed by
|
||||
parsing sizes dynamically from the config descriptor.
|
||||
|
||||
3. **Wrong HID descriptor recipient** — HID report descriptor requests must use
|
||||
interface recipient (0x81), not device (0x80), per USB spec. The OEM firmware
|
||||
happened to accept both.
|
||||
|
||||
## Dev setup
|
||||
- [OpenViszla](https://github.com/openvizsla/ov_ftdi) USB protocol analyzer
|
||||
- 5V-tolerant PL2303 UART interface (e.g. https://www.adafruit.com/product/954)
|
||||
|
||||
Reference in New Issue
Block a user