Initial design record for the three-piece keyboard

Two mirrored halves plus a numpad that carries the USB hub. Captures the
architecture decisions and the reasoning behind them: CH32L103 with an
STM32F103 pin-compatible escape hatch, split protocol tunnelled over USB-C
SBU through the numpad, hotswap sockets bottom-side, and why crystal-less
USB was ruled out across the whole WCH catalogue.

No boards ordered, no firmware written. Layout still undesigned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
William Rickert
2026-08-27 14:07:50 -05:00
co-authored by Claude Opus 5
commit 4467aa9433
4 changed files with 404 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
# agent config — can contain live API tokens
.claude/
.codex/
# KiCad
*-backups/
*.kicad_prl
*.kicad_pcb-bak
*.kicad_sch-bak
*.net
fp-info-cache
\#auto_saved_files#
*.bak
*~
# fab output
gerbers/
*.zip
# firmware build
build/
.build/
+221
View File
@@ -0,0 +1,221 @@
# tertiary
A three-piece keyboard: two mirrored halves plus a numpad/nav/media board that
also carries the USB hub. One cable reaches the computer.
Status: **design**. No boards ordered, no firmware written.
---
## The three boards
| Board | Qty | Keys | Carries |
|---|---|---|---|
| `hardware/half` | 2 (mirrored) | TBD — layout not designed | MCU, matrix, USB-C, SBU split link |
| `hardware/numpad` | 1 | 26 (17 numpad + 9 nav) | MCU, matrix, 2 encoders, **CH334R hub**, 3 downstream ports |
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, 6264 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 36 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.
> ⚠️ **Unverified assumption the whole board rests on:** pin *names and functions*
> were confirmed identical from both datasheets, but the pin *numbering* was not —
> the PDFs interleave four packages and extract badly. **Overlay the two pinout
> drawings before routing.**
**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.
### Mirrored board files, not a reversible PCB
The socket footprint isn't mirror-symmetric, so a reversible board needs two
socket footprints per key with one populated. Two mirrored layouts sharing one
schematic and one BOM is simpler and keeps everything that mattered.
### 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.75.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 (19, 0, `.`). `KP_SLASH`/`ASTERISK`/`MINUS`/`PLUS`/
`ENTER` mean the same thing either way.
**Encoders:** volume wants a **detented** EC11; scroll wants a **detentless** one,
because hi-res scrolling (`POINTING_DEVICE_HIRES_SCROLL_ENABLE`, resolution
multiplier, 1/120 tick) fights physical detents. Confirm the detentless SKU from
the datasheet — vendor descriptions are unreliable.
---
## 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
keyboards. The hardware supports both — see `docs/104-key-split.svg` for how a
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.
- [ ] Decide on a licence before publishing hardware files (CERN-OHL-S or
TAPR OHL for hardware; GPL2 for anything derived from QMK).
+119
View File
@@ -0,0 +1,119 @@
<svg width="100%" viewBox="0 0 680 330" role="img" xmlns="http://www.w3.org/2000/svg">
<title>Full 104-key keyboard split across three pieces</title>
<desc>An ANSI 104-key layout colour-coded by which of three boards each key lands on: left half 36 keys, right half 39 keys, numpad piece 26 keys, and four keys not on any piece.</desc>
<text class="th" x="18" y="24">A 104-key layout, divided across the three boards</text>
<g class="c-teal"><rect x="18.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="29.5" y="55.5" text-anchor="middle">Esc</text></g>
<g class="c-teal"><rect x="70.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="81.5" y="55.5" text-anchor="middle">F1</text></g>
<g class="c-teal"><rect x="96.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="107.5" y="55.5" text-anchor="middle">F2</text></g>
<g class="c-teal"><rect x="122.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="133.5" y="55.5" text-anchor="middle">F3</text></g>
<g class="c-teal"><rect x="148.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="159.5" y="55.5" text-anchor="middle">F4</text></g>
<g class="c-teal"><rect x="187.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="198.5" y="55.5" text-anchor="middle">F5</text></g>
<g class="c-teal"><rect x="213.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="224.5" y="55.5" text-anchor="middle">F6</text></g>
<g class="c-purple"><rect x="255.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="266.5" y="55.5" text-anchor="middle">F7</text></g>
<g class="c-purple"><rect x="281.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="292.5" y="55.5" text-anchor="middle">F8</text></g>
<g class="c-purple"><rect x="320.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="331.5" y="55.5" text-anchor="middle">F9</text></g>
<g class="c-purple"><rect x="346.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="357.5" y="55.5" text-anchor="middle">F10</text></g>
<g class="c-purple"><rect x="372.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="383.5" y="55.5" text-anchor="middle">F11</text></g>
<g class="c-purple"><rect x="398.0" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="409.5" y="55.5" text-anchor="middle">F12</text></g>
<g class="c-gray"><rect x="446.5" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="458.0" y="55.5" text-anchor="middle">PrS</text></g>
<g class="c-gray"><rect x="472.5" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="484.0" y="55.5" text-anchor="middle">ScL</text></g>
<g class="c-gray"><rect x="498.5" y="40.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="510.0" y="55.5" text-anchor="middle">Pau</text></g>
<g class="c-teal"><rect x="18.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="29.5" y="94.5" text-anchor="middle">`</text></g>
<g class="c-teal"><rect x="44.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="55.5" y="94.5" text-anchor="middle">1</text></g>
<g class="c-teal"><rect x="70.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="81.5" y="94.5" text-anchor="middle">2</text></g>
<g class="c-teal"><rect x="96.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="107.5" y="94.5" text-anchor="middle">3</text></g>
<g class="c-teal"><rect x="122.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="133.5" y="94.5" text-anchor="middle">4</text></g>
<g class="c-teal"><rect x="148.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="159.5" y="94.5" text-anchor="middle">5</text></g>
<g class="c-teal"><rect x="174.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="185.5" y="94.5" text-anchor="middle">6</text></g>
<g class="c-purple"><rect x="216.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="227.5" y="94.5" text-anchor="middle">7</text></g>
<g class="c-purple"><rect x="242.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="253.5" y="94.5" text-anchor="middle">8</text></g>
<g class="c-purple"><rect x="268.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="279.5" y="94.5" text-anchor="middle">9</text></g>
<g class="c-purple"><rect x="294.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="305.5" y="94.5" text-anchor="middle">0</text></g>
<g class="c-purple"><rect x="320.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="331.5" y="94.5" text-anchor="middle">-</text></g>
<g class="c-purple"><rect x="346.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="357.5" y="94.5" text-anchor="middle">=</text></g>
<g class="c-purple"><rect x="372.0" y="79.0" width="49.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="396.5" y="94.5" text-anchor="middle">Bksp</text></g>
<g class="c-gray"><rect x="446.5" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="458.0" y="94.5" text-anchor="middle">Ins</text></g>
<g class="c-coral"><rect x="472.5" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="484.0" y="94.5" text-anchor="middle">Hom</text></g>
<g class="c-coral"><rect x="498.5" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="510.0" y="94.5" text-anchor="middle">PgU</text></g>
<g class="c-coral"><rect x="531.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="542.5" y="94.5" text-anchor="middle">Num</text></g>
<g class="c-coral"><rect x="557.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="568.5" y="94.5" text-anchor="middle">/</text></g>
<g class="c-coral"><rect x="583.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="594.5" y="94.5" text-anchor="middle">*</text></g>
<g class="c-coral"><rect x="609.0" y="79.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="620.5" y="94.5" text-anchor="middle">-</text></g>
<g class="c-teal"><rect x="18.0" y="105.0" width="36.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="36.0" y="120.5" text-anchor="middle">Tab</text></g>
<g class="c-teal"><rect x="57.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="68.5" y="120.5" text-anchor="middle">Q</text></g>
<g class="c-teal"><rect x="83.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="94.5" y="120.5" text-anchor="middle">W</text></g>
<g class="c-teal"><rect x="109.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="120.5" y="120.5" text-anchor="middle">E</text></g>
<g class="c-teal"><rect x="135.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="146.5" y="120.5" text-anchor="middle">R</text></g>
<g class="c-teal"><rect x="161.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="172.5" y="120.5" text-anchor="middle">T</text></g>
<g class="c-purple"><rect x="203.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="214.5" y="120.5" text-anchor="middle">Y</text></g>
<g class="c-purple"><rect x="229.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="240.5" y="120.5" text-anchor="middle">U</text></g>
<g class="c-purple"><rect x="255.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="266.5" y="120.5" text-anchor="middle">I</text></g>
<g class="c-purple"><rect x="281.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="292.5" y="120.5" text-anchor="middle">O</text></g>
<g class="c-purple"><rect x="307.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="318.5" y="120.5" text-anchor="middle">P</text></g>
<g class="c-purple"><rect x="333.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="344.5" y="120.5" text-anchor="middle">[</text></g>
<g class="c-purple"><rect x="359.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="370.5" y="120.5" text-anchor="middle">]</text></g>
<g class="c-purple"><rect x="385.0" y="105.0" width="36.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="403.0" y="120.5" text-anchor="middle">\</text></g>
<g class="c-coral"><rect x="446.5" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="458.0" y="120.5" text-anchor="middle">Del</text></g>
<g class="c-coral"><rect x="472.5" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="484.0" y="120.5" text-anchor="middle">End</text></g>
<g class="c-coral"><rect x="498.5" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="510.0" y="120.5" text-anchor="middle">PgD</text></g>
<g class="c-coral"><rect x="531.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="542.5" y="120.5" text-anchor="middle">7</text></g>
<g class="c-coral"><rect x="557.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="568.5" y="120.5" text-anchor="middle">8</text></g>
<g class="c-coral"><rect x="583.0" y="105.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="594.5" y="120.5" text-anchor="middle">9</text></g>
<g class="c-coral"><rect x="609.0" y="105.0" width="23.0" height="49.0" rx="4" stroke-width="0.5"/><text class="ts" x="620.5" y="133.5" text-anchor="middle">+</text></g>
<g class="c-teal"><rect x="18.0" y="131.0" width="42.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="39.2" y="146.5" text-anchor="middle">Caps</text></g>
<g class="c-teal"><rect x="63.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="75.0" y="146.5" text-anchor="middle">A</text></g>
<g class="c-teal"><rect x="89.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="101.0" y="146.5" text-anchor="middle">S</text></g>
<g class="c-teal"><rect x="115.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="127.0" y="146.5" text-anchor="middle">D</text></g>
<g class="c-teal"><rect x="141.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="153.0" y="146.5" text-anchor="middle">F</text></g>
<g class="c-teal"><rect x="167.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="179.0" y="146.5" text-anchor="middle">G</text></g>
<g class="c-purple"><rect x="209.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="221.0" y="146.5" text-anchor="middle">H</text></g>
<g class="c-purple"><rect x="235.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="247.0" y="146.5" text-anchor="middle">J</text></g>
<g class="c-purple"><rect x="261.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="273.0" y="146.5" text-anchor="middle">K</text></g>
<g class="c-purple"><rect x="287.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="299.0" y="146.5" text-anchor="middle">L</text></g>
<g class="c-purple"><rect x="313.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="325.0" y="146.5" text-anchor="middle">;</text></g>
<g class="c-purple"><rect x="339.5" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="351.0" y="146.5" text-anchor="middle">'</text></g>
<g class="c-purple"><rect x="365.5" y="131.0" width="55.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="393.2" y="146.5" text-anchor="middle">Enter</text></g>
<g class="c-coral"><rect x="531.0" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="542.5" y="146.5" text-anchor="middle">4</text></g>
<g class="c-coral"><rect x="557.0" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="568.5" y="146.5" text-anchor="middle">5</text></g>
<g class="c-coral"><rect x="583.0" y="131.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="594.5" y="146.5" text-anchor="middle">6</text></g>
<g class="c-teal"><rect x="18.0" y="157.0" width="55.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="45.8" y="172.5" text-anchor="middle">Shift</text></g>
<g class="c-teal"><rect x="76.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="88.0" y="172.5" text-anchor="middle">Z</text></g>
<g class="c-teal"><rect x="102.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="114.0" y="172.5" text-anchor="middle">X</text></g>
<g class="c-teal"><rect x="128.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="140.0" y="172.5" text-anchor="middle">C</text></g>
<g class="c-teal"><rect x="154.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="166.0" y="172.5" text-anchor="middle">V</text></g>
<g class="c-teal"><rect x="180.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="192.0" y="172.5" text-anchor="middle">B</text></g>
<g class="c-purple"><rect x="222.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="234.0" y="172.5" text-anchor="middle">N</text></g>
<g class="c-purple"><rect x="248.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="260.0" y="172.5" text-anchor="middle">M</text></g>
<g class="c-purple"><rect x="274.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="286.0" y="172.5" text-anchor="middle">,</text></g>
<g class="c-purple"><rect x="300.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="312.0" y="172.5" text-anchor="middle">.</text></g>
<g class="c-purple"><rect x="326.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="338.0" y="172.5" text-anchor="middle">/</text></g>
<g class="c-purple"><rect x="352.5" y="157.0" width="68.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="386.8" y="172.5" text-anchor="middle">Shift</text></g>
<g class="c-coral"><rect x="472.5" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="484.0" y="172.5" text-anchor="middle"></text></g>
<g class="c-coral"><rect x="531.0" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="542.5" y="172.5" text-anchor="middle">1</text></g>
<g class="c-coral"><rect x="557.0" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="568.5" y="172.5" text-anchor="middle">2</text></g>
<g class="c-coral"><rect x="583.0" y="157.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="594.5" y="172.5" text-anchor="middle">3</text></g>
<g class="c-coral"><rect x="609.0" y="157.0" width="23.0" height="49.0" rx="4" stroke-width="0.5"/><text class="ts" x="620.5" y="185.5" text-anchor="middle">Ent</text></g>
<g class="c-teal"><rect x="18.0" y="183.0" width="29.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="32.8" y="198.5" text-anchor="middle">Ctrl</text></g>
<g class="c-teal"><rect x="50.5" y="183.0" width="29.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="65.2" y="198.5" text-anchor="middle">Win</text></g>
<g class="c-teal"><rect x="83.0" y="183.0" width="29.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="97.8" y="198.5" text-anchor="middle">Alt</text></g>
<g class="c-teal"><rect x="115.5" y="183.0" width="62.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="146.5" y="198.5" text-anchor="middle">Spc</text></g>
<g class="c-purple"><rect x="196.5" y="183.0" width="94.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="243.8" y="198.5" text-anchor="middle">Spc</text></g>
<g class="c-purple"><rect x="294.0" y="183.0" width="29.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="308.8" y="198.5" text-anchor="middle">Alt</text></g>
<g class="c-purple"><rect x="326.5" y="183.0" width="29.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="341.2" y="198.5" text-anchor="middle">Win</text></g>
<g class="c-purple"><rect x="359.0" y="183.0" width="29.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="373.8" y="198.5" text-anchor="middle">Mnu</text></g>
<g class="c-purple"><rect x="391.5" y="183.0" width="29.5" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="406.2" y="198.5" text-anchor="middle">Ctrl</text></g>
<g class="c-coral"><rect x="446.5" y="183.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="458.0" y="198.5" text-anchor="middle"></text></g>
<g class="c-coral"><rect x="472.5" y="183.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="484.0" y="198.5" text-anchor="middle"></text></g>
<g class="c-coral"><rect x="498.5" y="183.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="510.0" y="198.5" text-anchor="middle"></text></g>
<g class="c-coral"><rect x="531.0" y="183.0" width="49.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="555.5" y="198.5" text-anchor="middle">0</text></g>
<g class="c-coral"><rect x="583.0" y="183.0" width="23.0" height="23.0" rx="4" stroke-width="0.5"/><text class="ts" x="594.5" y="198.5" text-anchor="middle">.</text></g>
<g class="c-teal"><rect x="18" y="254" width="13" height="13" rx="3" stroke-width="0.5"/></g>
<text class="ts" x="37" y="264">Left half &#183; 36 keys</text>
<g class="c-purple"><rect x="170" y="254" width="13" height="13" rx="3" stroke-width="0.5"/></g>
<text class="ts" x="189" y="264">Right half &#183; 39 keys</text>
<g class="c-coral"><rect x="322" y="254" width="13" height="13" rx="3" stroke-width="0.5"/></g>
<text class="ts" x="341" y="264">Numpad piece &#183; 26 keys</text>
<g class="c-gray"><rect x="474" y="254" width="13" height="13" rx="3" stroke-width="0.5"/></g>
<text class="ts" x="493" y="264">No board &#183; layer only</text>
<text class="ts" x="18" y="290">A straight chop gives 36 vs 39 keys &#8212; but mirrored boards need matching counts.<tspan x="18" dy="1.35em">A real split trims to a symmetric core and reaches the rest by layer.</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

+42
View File
@@ -0,0 +1,42 @@
Board,Section,Ref,Qty,Value,MPN,LCSC,Package,JLC,Unit USD,Notes
ALL,MCU,U1,1,CH32L103C8T6,CH32L103C8T6,C22398291,LQFP-48(7x7),Extended,0.80,"MCU. Swap-compatible: STM32F103C8T6 = C8734 / Preferred / $1.44"
ALL,MCU,U2,1,3.3V LDO 500mA,RT9013-33GB-MS,C7434207,SOT-23-5,Extended,0.06,"Alt basic: XC6206P332MR-G C5446 but only 200mA"
ALL,MCU,U3,1,USB ESD,USBLC6-2SC6,C2687116,SOT-23-6,Extended,0.048,"on this board's own USB-C"
ALL,MCU,J1,1,USB-C 16P,TYPE-C16PIN,C393939,SMD,Extended,0.069,"upstream / device port"
ALL,MCU,J2,1,SWD header,-,-,1.27mm 4-pin,Consigned,0.00,"SWDIO=PA13 SWCLK=PA14 GND 3V3"
ALL,MCU,Y1,1,8MHz crystal,TAXM8M4RDBCCT2T,C400090,SMD3225-4P,Extended,0.146,"10pF load 250R ESR +/-10ppm. Satisfies both MCUs' USB PLL"
ALL,MCU,SW1,1,Tactile RESET,TS2306A 200gf,C5363482,SMD 3x2mm,Extended,0.062,"to NRST"
ALL,MCU,SW2,1,Tactile BOOT,TS2306A 200gf,C5363482,SMD 3x2mm,Extended,0.062,"BOOT0 to 3V3. Works for both boot paths"
ALL,MCU,C1-C5,5,100nF 0402 X7R 16V,CL05B104KO5NNNC,C1525,0402,Basic,0.006,"VDD_1 VDD_2 VDD_3 VDDA NRST"
ALL,MCU,C6,1,4.7uF 0603 X5R,CL10A475KO8NNNC,C19666,0603,Basic,0.024,"bulk at MCU"
ALL,MCU,C7,1,1uF 0402 X5R 25V,CL05A105KA5NQNC,C52923,0402,Basic,0.014,"VDDA"
ALL,MCU,C8-C9,2,10uF 0805 X5R,CL21A106KAYNNNE,C15850,0805,Basic,0.077,"LDO input and output"
ALL,MCU,C10-C11,2,12pF 0402 C0G,JLC basic library,-,0402,Basic,0.005,"MCU crystal load. 12pF assumes 10pF CL + ~4pF stray - verify vs stackup"
ALL,MCU,R1-R2,2,22R 0402,FRC0402F22R0TS,C2929994,0402,Extended,0.0007,"USB D+/D- series. 0R (C17168 Basic) also acceptable"
ALL,MCU,R3-R4,2,5.1k 0402,JLC basic library,-,0402,Basic,0.002,"USB-C CC1/CC2 pull-DOWN (Rd - device side)"
ALL,MCU,R5,1,1.5k 0402,JLC basic library,-,0402,Basic,0.002,"*** SWAP-DEPENDENT *** D+ pull-up. POPULATE for STM32F103. DNF for CH32L103 (internal 1.5k via RB_UC_DEV_PU_EN)"
ALL,MCU,R6-R7,2,10k 0402,FRC0402F1002TS,C25744,0402,Basic,0.003,"BOOT0 pulldown, BOOT1/PB2 pulldown"
HALF,Matrix,D1-Dn,1,1N4148W,1N4148W,C81598,SOD-123,Basic,0.011,"One per key. Qty per your layout"
HALF,Split,R14,1,100R 0402,JLC basic library,-,0402,Basic,0.002,"Series on the SBU net between connector and MCU USART pin"
HALF,Split,D-ESD,1,ESD 5V bidirectional,PESD5V0S1BA,C2827694,SOD-323,Extended,0.036,"On the SBU net - user-exposed signal going to a GPIO"
HALF,Split,J3,1,3-pin header DNF,JST SH,-,-,Consigned,0.02,"*** DNF INSURANCE *** VCC/GND/DATA fallback if SBU proves flaky (bad cables). 3 pads cost nothing"
HALF,Split,-,-,SBU1+SBU2 TIE,-,-,-,-,0.00,"Tie A8 and B8 together on the board. SBU is CROSSED in the cable, so this makes it orientation-proof and doubles the conductor"
NUMPAD,DNF,J1/U3/R3/R4/R5,0,DO NOT POPULATE,-,-,-,-,0.00,"*** From the ALL block: numpad MCU has NO connector of its own. Its D+/D- route internally to hub downstream port 1. No connector = no ESD part and no CC resistors needed. Saves ~$0.19"
NUMPAD,Matrix,D1-D26,26,1N4148W,1N4148W,C81598,SOD-123,Basic,0.011,"26 keys: 17 numpad + 9 nav"
NUMPAD,Encoder,ENC1,1,EC11 detented,EC11L1525G01,C2991196,THT,Extended,1.27,"VOLUME - wants detents. THT: hand-solder or JLC THT surcharge"
NUMPAD,Encoder,ENC2,1,EC11 detentless,verify variant,-,THT,Extended,1.27,"SCROLL - wants NO detents for hi-res scroll. Confirm detentless SKU"
NUMPAD,Hub,U4,1,USB2.0 4-port hub,CH334R,C4154405,QSOP-16-150mil,Extended,0.50,"Ports: 1=own MCU (internal FS) 2=left half 3=right half 4=spare"
NUMPAD,Hub,Y2,1,12MHz crystal,X322512MSB4SI,C9002,SMD3225-4P,Basic,0.101,"CH334 has built-in load caps - verify internal value vs this 20pF CL crystal; fit DNF cap pads"
NUMPAD,Hub,C12-C14,3,100nF 0402,CL05B104KO5NNNC,C1525,0402,Basic,0.006,"hub decoupling"
NUMPAD,Hub,C15,1,10uF 0805,CL21A106KAYNNNE,C15850,0805,Basic,0.077,"hub bulk"
NUMPAD,Hub,J4,1,USB-C upstream,TYPE-C16PIN,C393939,SMD,Extended,0.069,"to PC. This replaces J1 as the board's real upstream"
NUMPAD,Hub,J5-J7,3,USB-C downstream,TYPE-C16PIN,C393939,SMD,Extended,0.069,"left half / right half / spare"
NUMPAD,Hub,U5-U7,3,USB ESD,USBLC6-2SC6,C2687116,SOT-23-6,Extended,0.048,"one per downstream port"
NUMPAD,Hub,U8-U10,3,Ideal diode / OCP,CH213K,C5456874,SOT-23-3,Extended,0.073,"VBUS protection per downstream port. CH334R has no port power switching"
NUMPAD,Hub,R8-R13,6,56k 0402,FRC0402F5602TS,C2906875,0402,Extended,0.0018,"Rp pull-UPS on CC1/CC2 of each downstream port - host side. NOT 5.1k"
NUMPAD,SBU,-,-,SBU PASS-THROUGH,-,-,-,-,0.00,"*** Passive trace *** Tie SBU1+SBU2 on J5 (left half) and on J6 (right half), then connect the two nets together. Carries QMK split_common UART between the halves. Numpad MCU does NOT touch this net"
NUMPAD,SBU,D-ESD2,2,ESD 5V bidirectional,PESD5V0S1BA,C2827694,SOD-323,Extended,0.036,"One per half-port SBU net"
HALF,Switches,SW-,1,MX hotswap socket,CPG151101S11,C41430893,SMD 14.5x5.9mm,Extended,0.037,"One per key. BOTTOM SIDE. Alt: C49352235 (CPG151101S11-2)"
NUMPAD,Switches,SW-,26,MX hotswap socket,CPG151101S11,C41430893,SMD 14.5x5.9mm,Extended,0.037,"One per key. BOTTOM SIDE"
NOTE,Assembly,-,-,SINGLE-SIDED,-,-,-,-,-,"Put ALL SMD on the BOTTOM: sockets, MCU, passives, diodes, and any reverse-mount SK6812MINI-E. Top face bare except switch holes. Keeps JLC to one assembly pass"
NOTE,Mechanical,-,-,PLATE REQUIRED,-,-,-,-,-,"Hotswap needs a switch plate or socket pads tear off during switch insertion. FR4 plate = just another JLC board"
1 Board Section Ref Qty Value MPN LCSC Package JLC Unit USD Notes
2 ALL MCU U1 1 CH32L103C8T6 CH32L103C8T6 C22398291 LQFP-48(7x7) Extended 0.80 MCU. Swap-compatible: STM32F103C8T6 = C8734 / Preferred / $1.44
3 ALL MCU U2 1 3.3V LDO 500mA RT9013-33GB-MS C7434207 SOT-23-5 Extended 0.06 Alt basic: XC6206P332MR-G C5446 but only 200mA
4 ALL MCU U3 1 USB ESD USBLC6-2SC6 C2687116 SOT-23-6 Extended 0.048 on this board's own USB-C
5 ALL MCU J1 1 USB-C 16P TYPE-C16PIN C393939 SMD Extended 0.069 upstream / device port
6 ALL MCU J2 1 SWD header - - 1.27mm 4-pin Consigned 0.00 SWDIO=PA13 SWCLK=PA14 GND 3V3
7 ALL MCU Y1 1 8MHz crystal TAXM8M4RDBCCT2T C400090 SMD3225-4P Extended 0.146 10pF load 250R ESR +/-10ppm. Satisfies both MCUs' USB PLL
8 ALL MCU SW1 1 Tactile RESET TS2306A 200gf C5363482 SMD 3x2mm Extended 0.062 to NRST
9 ALL MCU SW2 1 Tactile BOOT TS2306A 200gf C5363482 SMD 3x2mm Extended 0.062 BOOT0 to 3V3. Works for both boot paths
10 ALL MCU C1-C5 5 100nF 0402 X7R 16V CL05B104KO5NNNC C1525 0402 Basic 0.006 VDD_1 VDD_2 VDD_3 VDDA NRST
11 ALL MCU C6 1 4.7uF 0603 X5R CL10A475KO8NNNC C19666 0603 Basic 0.024 bulk at MCU
12 ALL MCU C7 1 1uF 0402 X5R 25V CL05A105KA5NQNC C52923 0402 Basic 0.014 VDDA
13 ALL MCU C8-C9 2 10uF 0805 X5R CL21A106KAYNNNE C15850 0805 Basic 0.077 LDO input and output
14 ALL MCU C10-C11 2 12pF 0402 C0G JLC basic library - 0402 Basic 0.005 MCU crystal load. 12pF assumes 10pF CL + ~4pF stray - verify vs stackup
15 ALL MCU R1-R2 2 22R 0402 FRC0402F22R0TS C2929994 0402 Extended 0.0007 USB D+/D- series. 0R (C17168 Basic) also acceptable
16 ALL MCU R3-R4 2 5.1k 0402 JLC basic library - 0402 Basic 0.002 USB-C CC1/CC2 pull-DOWN (Rd - device side)
17 ALL MCU R5 1 1.5k 0402 JLC basic library - 0402 Basic 0.002 *** SWAP-DEPENDENT *** D+ pull-up. POPULATE for STM32F103. DNF for CH32L103 (internal 1.5k via RB_UC_DEV_PU_EN)
18 ALL MCU R6-R7 2 10k 0402 FRC0402F1002TS C25744 0402 Basic 0.003 BOOT0 pulldown, BOOT1/PB2 pulldown
19 HALF Matrix D1-Dn 1 1N4148W 1N4148W C81598 SOD-123 Basic 0.011 One per key. Qty per your layout
20 HALF Split R14 1 100R 0402 JLC basic library - 0402 Basic 0.002 Series on the SBU net between connector and MCU USART pin
21 HALF Split D-ESD 1 ESD 5V bidirectional PESD5V0S1BA C2827694 SOD-323 Extended 0.036 On the SBU net - user-exposed signal going to a GPIO
22 HALF Split J3 1 3-pin header DNF JST SH - - Consigned 0.02 *** DNF INSURANCE *** VCC/GND/DATA fallback if SBU proves flaky (bad cables). 3 pads cost nothing
23 HALF Split - - SBU1+SBU2 TIE - - - - 0.00 Tie A8 and B8 together on the board. SBU is CROSSED in the cable, so this makes it orientation-proof and doubles the conductor
24 NUMPAD DNF J1/U3/R3/R4/R5 0 DO NOT POPULATE - - - - 0.00 *** From the ALL block: numpad MCU has NO connector of its own. Its D+/D- route internally to hub downstream port 1. No connector = no ESD part and no CC resistors needed. Saves ~$0.19
25 NUMPAD Matrix D1-D26 26 1N4148W 1N4148W C81598 SOD-123 Basic 0.011 26 keys: 17 numpad + 9 nav
26 NUMPAD Encoder ENC1 1 EC11 detented EC11L1525G01 C2991196 THT Extended 1.27 VOLUME - wants detents. THT: hand-solder or JLC THT surcharge
27 NUMPAD Encoder ENC2 1 EC11 detentless verify variant - THT Extended 1.27 SCROLL - wants NO detents for hi-res scroll. Confirm detentless SKU
28 NUMPAD Hub U4 1 USB2.0 4-port hub CH334R C4154405 QSOP-16-150mil Extended 0.50 Ports: 1=own MCU (internal FS) 2=left half 3=right half 4=spare
29 NUMPAD Hub Y2 1 12MHz crystal X322512MSB4SI C9002 SMD3225-4P Basic 0.101 CH334 has built-in load caps - verify internal value vs this 20pF CL crystal; fit DNF cap pads
30 NUMPAD Hub C12-C14 3 100nF 0402 CL05B104KO5NNNC C1525 0402 Basic 0.006 hub decoupling
31 NUMPAD Hub C15 1 10uF 0805 CL21A106KAYNNNE C15850 0805 Basic 0.077 hub bulk
32 NUMPAD Hub J4 1 USB-C upstream TYPE-C16PIN C393939 SMD Extended 0.069 to PC. This replaces J1 as the board's real upstream
33 NUMPAD Hub J5-J7 3 USB-C downstream TYPE-C16PIN C393939 SMD Extended 0.069 left half / right half / spare
34 NUMPAD Hub U5-U7 3 USB ESD USBLC6-2SC6 C2687116 SOT-23-6 Extended 0.048 one per downstream port
35 NUMPAD Hub U8-U10 3 Ideal diode / OCP CH213K C5456874 SOT-23-3 Extended 0.073 VBUS protection per downstream port. CH334R has no port power switching
36 NUMPAD Hub R8-R13 6 56k 0402 FRC0402F5602TS C2906875 0402 Extended 0.0018 Rp pull-UPS on CC1/CC2 of each downstream port - host side. NOT 5.1k
37 NUMPAD SBU - - SBU PASS-THROUGH - - - - 0.00 *** Passive trace *** Tie SBU1+SBU2 on J5 (left half) and on J6 (right half), then connect the two nets together. Carries QMK split_common UART between the halves. Numpad MCU does NOT touch this net
38 NUMPAD SBU D-ESD2 2 ESD 5V bidirectional PESD5V0S1BA C2827694 SOD-323 Extended 0.036 One per half-port SBU net
39 HALF Switches SW- 1 MX hotswap socket CPG151101S11 C41430893 SMD 14.5x5.9mm Extended 0.037 One per key. BOTTOM SIDE. Alt: C49352235 (CPG151101S11-2)
40 NUMPAD Switches SW- 26 MX hotswap socket CPG151101S11 C41430893 SMD 14.5x5.9mm Extended 0.037 One per key. BOTTOM SIDE
41 NOTE Assembly - - SINGLE-SIDED - - - - - Put ALL SMD on the BOTTOM: sockets, MCU, passives, diodes, and any reverse-mount SK6812MINI-E. Top face bare except switch holes. Keeps JLC to one assembly pass
42 NOTE Mechanical - - PLATE REQUIRED - - - - - Hotswap needs a switch plate or socket pads tear off during switch insertion. FR4 plate = just another JLC board