Skip to the content.

Layout status

Status: v0.3, 2026-10-24. Schematic complete, PCB placed (50×70 mm, two-sided). v1.0 board: hardware/rp569-routed.kicad_pcb — KRT autoroute finished by hand, 0 unconnected, 0 DRC errors (D-021: some tracks on In1). Production files in hardware/jlcpcb/ (D-022). Still to do before ordering: USB pairs as coupled pairs, silkscreen; see .claude/todo.md.

Top Bottom
top bottom

(v1.0, kicad-cli pcb render of hardware/rp569-routed.kicad_pcb)

How the KiCad files are produced

Everything under hardware/ is generated from hardware/gen/board.py (parts, footprints, pin→net map):

Script Output
gen/mk_lib.py lib/rp569.kicad_sym: CH569W symbol from phantomdrive (MIT), pin types corrected; TPS2121
gen/mk_fp.py lib/rp569.pretty: GSB343K33HR and TI RUX0012A footprints from the datasheets
gen/gen_sch.py rp569.kicad_sch: one sheet, symbols grouped by block, a net label on every pin
gen/gen_pcb.py rp569.kicad_pcb: 4-layer 50×70 mm with 3 mm rounded corners, footprints + nets, fixed connectors/chips/buttons/LEDs, two-sided automatic placement, GND plane on In1
gen/gen_pro.py net classes in rp569.kicad_pro (USB3_90R, USB2_90R, HSPI, Power, Rail)
gen/route_krt.sh KiCadRoutingTools chain on a copy of the board (Routing options B)
gen/gen_fab.py DRC gate, then gerbers + drill (jlcpcb/rp569-gerbers.zip), BOM and CPL from rp569-routed.kicad_pcb
gen/gen_bom.py JLCPCB BOM and CPL in hardware/jlcpcb/
gen/build.sh runs all of the above, then ERC and DRC with schematic parity → hardware/reports/

Once hand-routing starts, stop running gen_pcb.py: it rebuilds the board from scratch and would wipe the routing. From then on, change board.py → gen_sch.py → in pcbnew Tools → Update PCB from Schematic. Footprints are already linked to their symbols, and schematic parity is 0 issues.

Check results (v0.3)

Placement summary (D-011, D-017, D-018)

Board 50×70 mm, portrait, 3 mm-radius rounded corners (D-023; 45° chamfers until then), M3 holes 4 mm from each corner.

Rules (D-016, D-017)

JLCPCB JLC04161H-7628 4-layer stack. F.Cu / In2.Cu / B.Cu are routing layers, In1.Cu is the solid GND plane (reference for the 90 Ω USB pairs on F.Cu). Net classes: Default 0.15/0.1 mm, Rail 0.2/0.1 mm (+3V3, 3V3_CH, 1V2_CH, 1V1, GND), Power 0.3/0.1 mm (VBUS, 5 V, switch nodes), USB 0.24 mm / 0.13 mm gap and clearance, HSPI 0.15/0.1 mm. Vias 0.5/0.3 mm, hole-to-copper 0.2 mm. HSPI and Power clearance 0.1 mm since D-019 (USB keeps 0.13 mm).

Routing options

Option A — Freerouting (documented, on hold since 2026-10-24)

/usr/bin/python3 hardware/gen/route.py [passes] [board.kicad_pcb] [--keep]

Option B — KiCadRoutingTools (under trial, D-019)

hardware/gen/route_krt.sh <workdir>     # works on a copy; result <workdir>/k5.kicad_pcb + DRC summary

https://github.com/drandyhaas/KiCadRoutingTools, cloned in ~/tools/KiCadRoutingTools (venv .venv, prebuilt Rust router from its release). Rust A* router with rip-up and reroute, coupled differential pairs, power-net neck-down at fine-pitch pads, QFN fanout, plane pours and KiCad-DRC-driven reconnect. The script’s header lists the flags this board needs (no silent fab-rule relaxation, keep net-class clearances, keep In1 solid).

Trials on v0.3/D-018 (unconnected by KiCad DRC against the project rules):

Chain Unconnected Clearance violations
planes → diff pairs → route (In1 kept free) 26 0
+ QFN fanout of U7/U9, class clearances lowered to 0.1 mm by a step 13 172
+ QFN fanout, 0.15/0.13 mm classes kept 32 1
route_krt.sh after D-019 (HSPI/Power 0.1 mm, USB 0.13 mm) 27 0
+ a second route.py pass on that result 21 0
D-020 placement (TPS2121 at the USB-C, sense dividers at their rail, pull-ups at their chip), 2 passes 16 0

Each chain runs in ~10–15 min. The result, finished by hand, is hardware/rp569-routed.kicad_pcb (its project file rp569-routed.kicad_pro is a copy of hardware/rp569.kicad_pro); at the time of the last autoroute: 16 links left, 0 electrical DRC violations, 6 dangling tracks and 2 dangling vias to delete, 3 of 6 USB pairs coupled. It is a starting point for hand finishing. hardware/rp569.kicad_pcb stays the generated, unrouted source of truth; after a board.py change, regenerate and re-run the chain rather than editing the autorouted copy.

Production files (v1.0, D-022)

python3 hardware/gen/gen_fab.py      # DRC gate -> hardware/jlcpcb/
File Content
hardware/jlcpcb/rp569-gerbers.zip 11 gerber layers (4 copper, paste, silkscreen, mask, Edge.Cuts) + PTH/NPTH Excellon + drill maps
hardware/jlcpcb/rp569-bom.csv JLCPCB BOM, 43 lines with LCSC numbers (2 consigned)
hardware/jlcpcb/rp569-cpl.csv Placement, 141 parts, from the routed board
hardware/jlcpcb/gerbers/ Same files unzipped, for review in KiCad’s Gerber viewer
hardware/reports/drc-routed.json DRC of the routed board at export (v1.0: 0 unconnected, 0 errors)

JLCPCB order: 4 layers, 1.6 mm, JLC04161H-7628 stackup, PCBA on both sides. Check every part’s rotation in the placement preview.

Before ordering

  1. Impedance: confirm the 90 Ω width/gap with JLCPCB’s calculator for JLC04161H-7628.
  2. Review the placement by hand: RP2350 VREG loop (VREG_VIN cap, inductor, DVDD cap), TLV62569 loops (CIN, SW node, inductor), SuperSpeed AC caps and ESD close to the USB3 connector, crystals next to their chips.
  3. Silkscreen cleanup and new renders.

Routing order (suggested)

  1. USB3 SuperSpeed pairs (SSTX via AC caps, SSRX) and USB2 pairs: coupled pairs on F.Cu over the In1 GND plane, length-matched within each pair, no vias if possible.
  2. Power: VBUS → TPS2121 → bucks; RP2350 VREG; CH569 1V2/3V3.
  3. HSPI bus (16 direct lines): matched lengths ±1 mm relative to HSPI_RCLK.
  4. Everything else.