2026-08-27 14:07:50 -05:00
|
|
|
|
# tertiary
|
|
|
|
|
|
|
2026-08-27 15:12:17 -05:00
|
|
|
|
A three-piece keyboard: two column-staggered halves plus a numpad/nav/media
|
|
|
|
|
|
board that also carries the USB hub. One cable reaches the computer.
|
2026-08-27 14:07:50 -05:00
|
|
|
|
|
|
|
|
|
|
Status: **design**. No boards ordered, no firmware written.
|
|
|
|
|
|
|
2026-08-28 08:26:38 -05:00
|
|
|
|

|
2026-08-27 15:12:17 -05:00
|
|
|
|
|
|
|
|
|
|
<table>
|
|
|
|
|
|
<tr>
|
2026-08-28 08:26:38 -05:00
|
|
|
|
<td><img src="Documents/half-left-staggered.svg" alt="Left half, 34 keys"></td>
|
|
|
|
|
|
<td><img src="Documents/half-right-staggered.svg" alt="Right half, 41 keys"></td>
|
2026-08-27 15:12:17 -05:00
|
|
|
|
</tr>
|
|
|
|
|
|
</table>
|
|
|
|
|
|
|
2026-08-28 08:26:38 -05:00
|
|
|
|

|
2026-08-27 15:12:17 -05:00
|
|
|
|
|
|
|
|
|
|
Derived from a full 104 rather than a compact ergo core — see
|
2026-08-28 08:26:38 -05:00
|
|
|
|
[`Documents/104-key-split.svg`](Documents/104-key-split.svg) for how the original layout
|
2026-08-27 15:12:17 -05:00
|
|
|
|
maps across the three boards.
|
|
|
|
|
|
|
|
|
|
|
|
## Licence
|
|
|
|
|
|
|
2026-08-27 15:15:19 -05:00
|
|
|
|
**Hardware and documentation: [CC BY-NC-SA 4.0](LICENSES/CC-BY-NC-SA-4.0.txt).**
|
|
|
|
|
|
Build one, modify it, share your modifications under the same terms — but no
|
|
|
|
|
|
commercial products.
|
2026-08-27 15:12:17 -05:00
|
|
|
|
|
2026-08-27 15:15:19 -05:00
|
|
|
|
**Firmware: [GPL-2.0-or-later](LICENSES/GPL-2.0.txt)**, forced by QMK, which
|
|
|
|
|
|
permits commercial use. See [`LICENSE.md`](LICENSE.md) for why the two can't be
|
|
|
|
|
|
the same, and for the caveats on what "NonCommercial" actually means.
|
|
|
|
|
|
|
2026-08-28 08:26:38 -05:00
|
|
|
|
The vendor PDFs inside `Documents/` (WCH, ST) are third-party and aren't covered by
|
2026-08-27 15:15:19 -05:00
|
|
|
|
either.
|
2026-08-27 15:12:17 -05:00
|
|
|
|
|
2026-08-27 14:07:50 -05:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## The three boards
|
|
|
|
|
|
|
|
|
|
|
|
| Board | Qty | Keys | Carries |
|
|
|
|
|
|
|---|---|---|---|
|
2026-08-28 08:26:38 -05:00
|
|
|
|
| `Schematics/Left` | 1 | **34** | MCU, matrix, USB-C, SBU split link |
|
|
|
|
|
|
| `Schematics/Right` | 1 | **41** | MCU, matrix, USB-C, SBU split link |
|
2026-09-01 10:35:24 -05:00
|
|
|
|
| `Schematics/Numpad` | 1 | **26** (14 numpad + 10 nav + 2 thumb) | MCU, matrix, **CH334R hub**, 3 downstream ports |
|
2026-08-27 14:43:40 -05:00
|
|
|
|
|
2026-08-28 08:26:38 -05:00
|
|
|
|
**Numpad layout is settled** — see `Documents/numpad-layout.svg`, and
|
2026-09-01 08:59:04 -05:00
|
|
|
|
`Documents/three-board-overview.svg` for all three at the same scale. Six
|
2026-09-01 10:35:24 -05:00
|
|
|
|
columns by five rows, ~114 × 105 mm, **26 keys and no encoder**.
|
2026-09-01 08:59:04 -05:00
|
|
|
|
|
2026-09-01 10:35:24 -05:00
|
|
|
|
- **Nav block across the top**: a solid 3×2 — Home/End/PgUp over Del/PrtSc/PgDn
|
|
|
|
|
|
— with the arrows in a standard **inverted-T** isolated below by a symmetric
|
|
|
|
|
|
pair of empty cells, the same breathing room a 104 gives them. Del sits two
|
|
|
|
|
|
rows above `←` with a gap between, so the destructive key is never adjacent to
|
|
|
|
|
|
the one you hit blind.
|
|
|
|
|
|
- **PrtSc has a real key.** It's the screenshot key on every Linux desktop, so
|
|
|
|
|
|
it earns one. Insert, ScrLk and Pause do not, and stay on a layer.
|
2026-09-01 08:59:04 -05:00
|
|
|
|
- **Numpad on the right**: digits in a 3×3 with `0` as a 2u, and `/ * −` in a
|
|
|
|
|
|
right-hand column beside 9/6/3, where a full-size numpad puts its operators.
|
|
|
|
|
|
- **`Enter` (2u) and `+` on a stepped thumb cluster**, spanning exactly the
|
|
|
|
|
|
three nav columns. That's what lets the digits drop from four columns to
|
|
|
|
|
|
three and keeps the board at six wide.
|
|
|
|
|
|
- **No Num key** — the firmware resolves keypad vs number-row at press time, so
|
|
|
|
|
|
the pad never needed one.
|
|
|
|
|
|
- **No encoder.** Dropped along with the scroll wheel; volume lives on a layer
|
|
|
|
|
|
or on the halves' function row. This makes the numpad a completely plain QMK
|
|
|
|
|
|
keyboard — no encoder, no pointing device, just a matrix. It is the simplest
|
2026-09-01 10:35:24 -05:00
|
|
|
|
of the three boards by a distance, and ~$4.16 in parts.
|
2026-08-27 14:07:50 -05:00
|
|
|
|
|
|
|
|
|
|
Cabling:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
PC ──USB-C── numpad ──USB-C── left half
|
|
|
|
|
|
└─USB-C── right half
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Both halves plug into the numpad. The numpad's hub gives each half a USB port,
|
|
|
|
|
|
and a **passive trace across the numpad shorts SBU between the two half ports**,
|
|
|
|
|
|
which is how QMK's split protocol gets from one half to the other. See below.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Decisions, and why
|
|
|
|
|
|
|
|
|
|
|
|
### MCU: CH32L103C8T6, with an STM32F103C8T6 escape hatch
|
|
|
|
|
|
|
|
|
|
|
|
`C22398291`, LQFP-48, 62–64 K flash / 20 K SRAM, QingKe RISC-V4C.
|
|
|
|
|
|
|
|
|
|
|
|
**QMK does not support CH32.** Verified: zero issues or PRs mentioning CH32 in
|
|
|
|
|
|
`qmk/qmk_firmware` ever, and no `os/hal/ports/CH32` in ChibiOS-Contrib. Adding it
|
|
|
|
|
|
means a ChibiOS HAL port — PAL, ST, and critically a `usb_lld` for WCH's own USBFS
|
|
|
|
|
|
peripheral. Estimated 3–6 weeks of evenings; the USB driver is ~75% of it.
|
|
|
|
|
|
|
|
|
|
|
|
So the board is laid out to the **STM32F103C8T6 (`C8734`) footprint**, which the
|
|
|
|
|
|
L103 is pin-compatible with (same LQFP-48, `PC13`/`PC14`/`PC15`, `PD0`/`PD1` as
|
|
|
|
|
|
`OSC_IN`/`OSC_OUT`, `PA11`/`PA12` as USB DM/DP, `PA13`/`PA14` as SWDIO/SWCLK).
|
|
|
|
|
|
Populate the F103 and it works with stock QMK today; populate the L103 when the
|
|
|
|
|
|
port lands. Same board either way.
|
|
|
|
|
|
|
2026-09-01 10:42:07 -05:00
|
|
|
|
> ✅ **Verified 2026-09-01: all 48 pins identical, zero mismatches.** Both
|
|
|
|
|
|
> datasheets' pin-definition tables were parsed and diffed pin by pin — including
|
|
|
|
|
|
> `OSC_IN`/`OSC_OUT`, `NRST`, `PA11`/`PA12` (USB), `PA13`/`PA14` (SWD) and
|
|
|
|
|
|
> `BOOT0`. Power pins differ only in naming (`VSS` vs `VSS_1..3`). Full table:
|
|
|
|
|
|
> [`Documents/pinout-L103-vs-F103.md`](Documents/pinout-L103-vs-F103.md).
|
|
|
|
|
|
> This was the one assumption the whole project rested on. It holds.
|
2026-08-27 14:07:50 -05:00
|
|
|
|
|
|
|
|
|
|
**Only one component differs between the two MCUs:** `R5`, a 1.5 kΩ pull-up on
|
|
|
|
|
|
D+. The F103 has no internal one. The L103 does (~1.5 kΩ, enabled via
|
|
|
|
|
|
`RB_UC_DEV_PU_EN` in `R8_USB_CTRL`) — so populate `R5` for F103, DNF for L103.
|
|
|
|
|
|
|
|
|
|
|
|
Buy three loose F103s and keep them in a drawer. When the first board doesn't
|
|
|
|
|
|
enumerate, hot-air one over and flash stock QMK: that tells you instantly whether
|
|
|
|
|
|
the fault is the PCB or your USB driver. Debugging both at once is where this
|
|
|
|
|
|
project would die.
|
|
|
|
|
|
|
|
|
|
|
|
### Why not RP2040
|
|
|
|
|
|
|
|
|
|
|
|
No internal flash, so it needs an external QSPI chip, a crystal, and fussy
|
|
|
|
|
|
decoupling — ~24 line items versus ~16. Modules (RP2040-Zero, $3.99) were the
|
|
|
|
|
|
first plan and are still viable, but bare silicon gives USB-C placement freedom
|
|
|
|
|
|
and no single-supplier risk.
|
|
|
|
|
|
|
|
|
|
|
|
### Why not crystal-less
|
|
|
|
|
|
|
|
|
|
|
|
Nothing in WCH's catalogue does spec-compliant crystal-less USB. Checked V203,
|
|
|
|
|
|
X035 and L103: all use factory-calibrated RC with manual `HSITRIM` and **no
|
|
|
|
|
|
SOF-based clock recovery anywhere in the family**. Accuracies run −1.0/+1.6 %
|
|
|
|
|
|
(V203), −1.7/+1.6 % (X035), ±1.6 % rising to ±2.2 % over full range (L103).
|
|
|
|
|
|
USB full-speed wants ±0.25 %.
|
|
|
|
|
|
|
|
|
|
|
|
WCH's own datasheet admits it: crystal-free "may deviate from the USB
|
|
|
|
|
|
specification, and are only applicable to non-precision occasions", and it's a
|
|
|
|
|
|
factory ordering option not enabled by default on stock parts.
|
|
|
|
|
|
|
|
|
|
|
|
The only genuinely crystal-less option found was **STM32F0x2** (HSI48 + CRS,
|
|
|
|
|
|
actively trimmed against host SOF packets) — rejected on stock: 773 units.
|
|
|
|
|
|
|
|
|
|
|
|
An 8 MHz crystal plus two caps is $0.12 and satisfies both MCUs' USB PLL.
|
|
|
|
|
|
|
|
|
|
|
|
### Hub in the numpad, not the right half
|
|
|
|
|
|
|
|
|
|
|
|
Keeps both halves the same design. The numpad is a one-off anyway and it's the
|
|
|
|
|
|
roomiest board. Cost: the numpad must be plugged in for the halves to reach the
|
|
|
|
|
|
computer — but each half has a complete USB stack, so any half can be plugged
|
|
|
|
|
|
directly into a machine when travelling.
|
|
|
|
|
|
|
|
|
|
|
|
**CH334R** (`C4154405`, QSOP-16, $0.50), 4 ports mapping exactly:
|
|
|
|
|
|
|
|
|
|
|
|
| Port | Destination |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| Upstream | PC |
|
|
|
|
|
|
| 1 | numpad's own MCU — internal trace, no connector |
|
|
|
|
|
|
| 2 | left half |
|
|
|
|
|
|
| 3 | right half |
|
|
|
|
|
|
| 4 | spare external |
|
|
|
|
|
|
|
|
|
|
|
|
CH334R has no port power switching (dropped in the 16-pin package), so each
|
|
|
|
|
|
downstream port gets a **CH213K** ideal diode for overcurrent — WCH's own
|
|
|
|
|
|
recommendation in the CH334 reference design.
|
|
|
|
|
|
|
|
|
|
|
|
Downstream ports are host-side: **56 kΩ Rp pull-*ups* on CC, not 5.1 kΩ Rd
|
|
|
|
|
|
pull-downs.** Getting this backwards means nothing enumerates.
|
|
|
|
|
|
|
|
|
|
|
|
### Split link over USB-C SBU
|
|
|
|
|
|
|
|
|
|
|
|
The 16-pin USB-C connector breaks out **SBU1 (A8) and SBU2 (B8)** and nothing
|
|
|
|
|
|
uses them. Each half ties SBU1+SBU2 together — **SBU is crossed inside the
|
|
|
|
|
|
cable**, so tying them makes the link orientation-proof and doubles the
|
|
|
|
|
|
conductor — and runs it through 100 Ω + ESD to a USART pin. The numpad shorts
|
|
|
|
|
|
the two half-ports' SBU nets with a passive trace.
|
|
|
|
|
|
|
|
|
|
|
|
Result: QMK `split_common` runs between the halves with no extra cable and no
|
|
|
|
|
|
TRRS.
|
|
|
|
|
|
|
|
|
|
|
|
> ⚠️ **Requires a full-featured USB-C cable.** Cheap USB 2.0 charge cables omit
|
|
|
|
|
|
> SBU entirely. Failure mode is nasty: power and USB work, only the split dies.
|
|
|
|
|
|
> **Put "USE A FULL-FEATURED CABLE" on the silkscreen.**
|
|
|
|
|
|
|
|
|
|
|
|
A 3-pin JST footprint is carried on both halves as **DNF insurance** if SBU
|
|
|
|
|
|
proves unreliable.
|
|
|
|
|
|
|
|
|
|
|
|
### Hotswap sockets, everything bottom-side
|
|
|
|
|
|
|
|
|
|
|
|
Kailh MX `CPG151101S11` (`C41430893`, $0.037, 93 k in stock — they *are* in JLC's
|
|
|
|
|
|
library). Sockets mount on the back, so put **all** SMD on the bottom: MCU,
|
|
|
|
|
|
passives, diodes, sockets. Single-sided assembly, one JLC setup instead of two.
|
|
|
|
|
|
|
|
|
|
|
|
**A plate is mandatory.** Without one, switch insertion flexes the PCB and tears
|
|
|
|
|
|
socket pads off. FR4 plate is just another JLC board.
|
|
|
|
|
|
|
|
|
|
|
|
Use [perigoso/keyswitch-kicad-library](https://github.com/perigoso/keyswitch-kicad-library)
|
|
|
|
|
|
for footprints — don't draw them.
|
|
|
|
|
|
|
2026-08-27 14:52:06 -05:00
|
|
|
|
### The halves are two different boards
|
2026-08-27 14:07:50 -05:00
|
|
|
|
|
2026-08-27 15:09:21 -05:00
|
|
|
|
Splitting a full 104 gives **34 keys left, 41 right** (after moving `6`/`F6` right) —
|
2026-08-27 14:52:06 -05:00
|
|
|
|
the right side inherits Backspace, Enter, both brackets, the backslash and an
|
|
|
|
|
|
extra bottom-row key. They are therefore *not* mirrors, and the earlier plan of
|
|
|
|
|
|
one layout flipped for both halves does not survive.
|
|
|
|
|
|
|
|
|
|
|
|
Two separate designs: two schematics, two layouts, two fab setups, different
|
|
|
|
|
|
diode and socket counts. A reversible PCB was never on the table anyway — the
|
|
|
|
|
|
hotswap socket footprint isn't mirror-symmetric, so it would have needed two
|
|
|
|
|
|
socket footprints per key with one populated.
|
|
|
|
|
|
|
2026-08-28 08:26:38 -05:00
|
|
|
|
See `Documents/half-left.svg` and `Documents/half-right.svg`.
|
2026-08-27 14:07:50 -05:00
|
|
|
|
|
2026-08-27 14:58:05 -05:00
|
|
|
|
### Column stagger, not row stagger
|
|
|
|
|
|
|
|
|
|
|
|
A 104's row offsets are a typewriter artifact — mechanical linkages needed the
|
|
|
|
|
|
room, hands didn't. Since these are new PCBs, the columns get offset vertically
|
|
|
|
|
|
to match finger length instead: middle column highest, pinky and inner-reach
|
|
|
|
|
|
columns down ~0.4u.
|
|
|
|
|
|
|
2026-08-28 08:26:38 -05:00
|
|
|
|
`Documents/half-left-staggered.svg` is the left half rebuilt this way. **Same 36
|
2026-08-27 14:58:05 -05:00
|
|
|
|
keys**, and it resolves into a clean 7-column grid:
|
|
|
|
|
|
|
|
|
|
|
|
| Column | Holds |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 0 (outer) | Esc, `, Tab, Caps, Shift |
|
|
|
|
|
|
| 1–5 | the finger columns, 5 keys each |
|
|
|
|
|
|
| 6 (inner reach) | F6, 6 — only two keys |
|
|
|
|
|
|
|
|
|
|
|
|
That last column is honest rather than a defect: on a 104, `6` and `F6` really
|
|
|
|
|
|
are an index-finger stretch, and the stagger makes it visible.
|
|
|
|
|
|
|
|
|
|
|
|
Side effect worth having: it comes out **~7u wide instead of 8.5u** (~134 mm vs
|
|
|
|
|
|
~162 mm), because the function row no longer carries the 104's arbitrary gaps.
|
|
|
|
|
|
Narrower *and* better.
|
|
|
|
|
|
|
|
|
|
|
|
### Thumb clusters
|
|
|
|
|
|
|
|
|
|
|
|
Both spacebars break into stepped thumb keys. On the left that's Ctrl / Win /
|
|
|
|
|
|
Alt / Space stepping down and inward. This is where the pinky relief actually
|
|
|
|
|
|
comes from — a stock 104 puts Tab, Caps, Shift *and* Ctrl on the weakest finger.
|
|
|
|
|
|
|
|
|
|
|
|
⚠️ Only about **two or three** of the four are genuinely comfortable; the
|
|
|
|
|
|
outermost is at the edge of thumb travel. Consider dropping Ctrl to a home-row
|
|
|
|
|
|
mod and reclaiming that slot for a layer key.
|
|
|
|
|
|
|
2026-08-27 15:02:32 -05:00
|
|
|
|
The right is worse: **five** thumb keys (Space / Alt / Win / Menu / Ctrl). One
|
|
|
|
|
|
thumb will not cover five. Menu is the obvious deletion — nothing else on the
|
|
|
|
|
|
board is used less.
|
|
|
|
|
|
|
2026-08-28 08:26:38 -05:00
|
|
|
|
`Documents/half-right-staggered.svg`.
|
2026-08-27 15:02:32 -05:00
|
|
|
|
|
2026-08-27 15:09:21 -05:00
|
|
|
|
### The outer edge — resolved
|
2026-08-27 15:02:32 -05:00
|
|
|
|
|
2026-08-27 15:09:21 -05:00
|
|
|
|
Splitting a row-staggered 104 leaves keys with no column to belong to: the
|
|
|
|
|
|
number row and the alpha rows are cut half a unit apart, so `6` sits between `T`
|
|
|
|
|
|
and `Y` with no alpha beneath it.
|
2026-08-27 15:02:32 -05:00
|
|
|
|
|
2026-08-27 15:09:21 -05:00
|
|
|
|
**Resolved by shifting the right half's top two rows over one column**, so `6`
|
|
|
|
|
|
leads the number row and `F6` leads the function row, both sitting above `Y`.
|
2026-08-27 15:02:32 -05:00
|
|
|
|
|
2026-08-27 15:09:21 -05:00
|
|
|
|
- **Left: 34 keys, six columns, every one five deep.** No orphans at all.
|
|
|
|
|
|
- **Right: 41 keys.** Six full columns, then `F12`/`=`/`]`/`Enter`, then `Bksp`
|
|
|
|
|
|
and `\` sharing the outer pinky column.
|
2026-08-27 15:02:32 -05:00
|
|
|
|
|
2026-08-27 15:09:21 -05:00
|
|
|
|
`\` no longer sits alone two columns out — it pairs with Backspace, and both
|
2026-08-28 08:26:38 -05:00
|
|
|
|
are genuine outer-pinky reaches. `Documents/half-left-staggered.svg`,
|
|
|
|
|
|
`Documents/half-right-staggered.svg`.
|
2026-08-27 15:02:32 -05:00
|
|
|
|
|
2026-08-27 15:09:21 -05:00
|
|
|
|
Still open: the right thumb is carrying **five** keys (Space / Alt / Win / Menu
|
|
|
|
|
|
/ Ctrl) and one thumb will not cover five. Menu is the obvious deletion.
|
2026-08-27 15:02:32 -05:00
|
|
|
|
|
2026-08-27 14:58:05 -05:00
|
|
|
|
### Tenting
|
|
|
|
|
|
|
|
|
|
|
|
Tenting hardware is a CAD/case job and comes after the PCB — but the **mounting
|
|
|
|
|
|
holes are PCB**, and where they go depends on the case scheme. Decide sandwich
|
|
|
|
|
|
vs tray *before routing*, or you'll find the case wants a standoff exactly where
|
|
|
|
|
|
a switch or a matrix trace already is. Holes can't be added later without a
|
|
|
|
|
|
respin.
|
|
|
|
|
|
|
2026-08-27 14:07:50 -05:00
|
|
|
|
### RGB: numpad underglow only
|
|
|
|
|
|
|
|
|
|
|
|
Per-key RGB is arithmetically impossible on a bus-powered hub. Each half sits on
|
|
|
|
|
|
a downstream port capped at 100 mA; 42 SK6812MINI-E at full white is 1.5 A, and
|
|
|
|
|
|
even 10 % brightness overruns the port. Real per-key RGB needs a self-powered hub
|
|
|
|
|
|
with an external supply — and probably a bigger CH334 variant, since the small
|
|
|
|
|
|
packages don't expose `PSELF`.
|
|
|
|
|
|
|
|
|
|
|
|
Numpad has ~355 mA to itself: about 9 LEDs at full white or ~30 at 30 %.
|
|
|
|
|
|
|
|
|
|
|
|
If any SK6812 is fitted: **3.3 V data into a 5 V part is out of spec** (Vih ≈
|
|
|
|
|
|
3.5 V). SK6812MINI-E is rated 3.7–5.5 V, so run the LED rail at ~4.3 V through a
|
|
|
|
|
|
series diode — Vih drops to ~3.0 V and you stay in spec.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Firmware notes
|
|
|
|
|
|
|
|
|
|
|
|
Nothing written yet. Things already known:
|
|
|
|
|
|
|
|
|
|
|
|
**Do not use `SPLIT_USB_DETECT`.** Both halves are plugged into the hub, so both
|
|
|
|
|
|
would see VBUS and both would decide they're master. Set `MASTER_LEFT` (or
|
|
|
|
|
|
`MASTER_RIGHT`) at compile time. The peripheral still enumerates as an idle HID
|
|
|
|
|
|
device — expected, not a fault.
|
|
|
|
|
|
|
|
|
|
|
|
**Split pin:** `PA9` (USART1_TX) exists on both MCUs. QMK's half-duplex
|
|
|
|
|
|
`serial_usart` uses TX only, open-drain with pull-up.
|
|
|
|
|
|
|
|
|
|
|
|
**Numpad Num Lock handling.** Num Lock is global host state on Windows and Linux;
|
|
|
|
|
|
with it off, `KP_7` sends Home and the pad silently becomes a duplicate of the
|
|
|
|
|
|
nav cluster three inches away. macOS has no functional Num Lock (Apple keyboards
|
|
|
|
|
|
use Clear) and the pad always types digits there.
|
|
|
|
|
|
|
|
|
|
|
|
Plan is belt-and-braces:
|
|
|
|
|
|
|
|
|
|
|
|
1. One attempt per power-up to turn Num Lock on, fired from
|
|
|
|
|
|
`housekeeping_task_user` (**never** from inside `led_update_user` — an
|
|
|
|
|
|
unbounded loop there has been reported to brick a Moonlander), after a 500 ms
|
|
|
|
|
|
settle so a transient enumeration report doesn't trigger a false correction.
|
|
|
|
|
|
2. Regardless of whether that took, resolve each keypad key at press time against
|
|
|
|
|
|
`host_keyboard_led_state().num_lock` and emit the number-row keycode when Num
|
|
|
|
|
|
Lock is off. Latch what was registered so the release matches if state flips
|
|
|
|
|
|
mid-hold.
|
|
|
|
|
|
|
|
|
|
|
|
Only eleven keys need this (1–9, 0, `.`). `KP_SLASH`/`ASTERISK`/`MINUS`/`PLUS`/
|
|
|
|
|
|
`ENTER` mean the same thing either way.
|
|
|
|
|
|
|
2026-09-01 08:59:04 -05:00
|
|
|
|
**No encoder anywhere.** The scroll wheel went first, then the volume knob. That
|
|
|
|
|
|
strips a surprising amount out of the numpad's firmware:
|
2026-08-27 14:43:40 -05:00
|
|
|
|
|
2026-09-01 08:59:04 -05:00
|
|
|
|
- No `ENCODER_ENABLE`, no `POINTING_DEVICE_ENABLE`, no `MOUSEKEY_ENABLE`, no
|
|
|
|
|
|
hi-res scroll multiplier.
|
|
|
|
|
|
- The numpad **enumerates as a plain keyboard and nothing else** — no mouse
|
|
|
|
|
|
interface, no consumer-control interface unless media keys go on a layer.
|
2026-08-27 14:43:40 -05:00
|
|
|
|
- One fewer USB endpoint, which matters because the L103's USBFS has eight and
|
2026-09-01 08:59:04 -05:00
|
|
|
|
QMK's composite device was tight against that.
|
|
|
|
|
|
- The detentless-EC11 sourcing risk is gone, because there is no EC11.
|
2026-08-27 14:43:40 -05:00
|
|
|
|
|
2026-09-01 08:59:04 -05:00
|
|
|
|
Volume has to live on a layer, or on the halves' function row. Decide that
|
|
|
|
|
|
rather than discover it.
|
2026-08-27 14:07:50 -05:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Open questions
|
|
|
|
|
|
|
|
|
|
|
|
- **The layout.** Undesigned, and it's the only input the PCB can't defer. If a
|
|
|
|
|
|
thumb layer on one half reaches keys on the other, the halves must be a QMK
|
|
|
|
|
|
split. If each half is self-sufficient, they can be three independent
|
2026-08-28 08:26:38 -05:00
|
|
|
|
keyboards. The hardware supports both — see `Documents/104-key-split.svg` for how a
|
2026-08-27 14:07:50 -05:00
|
|
|
|
104-key layout maps onto three boards, and note a straight chop gives 36 vs 39
|
|
|
|
|
|
keys, so a symmetric core plus layers is needed for mirrored boards.
|
|
|
|
|
|
- Pin-number overlay of L103 vs F103 (above).
|
|
|
|
|
|
- CH334 internal crystal load-cap value vs the 20 pF-CL crystal — fit DNF cap pads.
|
|
|
|
|
|
- Whether AT32F415 is a better fallback than F103 (128 K/32 K vs 64 K/20 K, same price).
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## TODO before this repo is made public
|
|
|
|
|
|
|
|
|
|
|
|
Per house convention. This one is unusually clean:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] Nothing here touches LAN topology, credentials, or personal data — no
|
|
|
|
|
|
scrubbing needed, unlike most repos here.
|
|
|
|
|
|
- [ ] Confirm no JLC/LCSC account identifiers end up in fab exports.
|
2026-08-27 15:12:17 -05:00
|
|
|
|
- [x] Scanned: no LAN topology, credentials or personal data in files or history.
|
2026-08-27 15:15:19 -05:00
|
|
|
|
- [x] Licence chosen: CC BY-NC-SA 4.0 (hardware) + GPL-2.0 (firmware).
|
2026-08-27 15:12:17 -05:00
|
|
|
|
- [ ] Vendor datasheets in `Documents/` are redistributed third-party PDFs.
|
|
|
|
|
|
Consider linking instead of vendoring if that matters to you.
|