From 0dc9daf54f9b0cf9174fd987c76fb5cd3c669c10 Mon Sep 17 00:00:00 2001 From: Me Here Date: Sun, 31 May 2026 00:15:15 -0500 Subject: [PATCH] PM_K-1 hardware: consolidated BOM + LAYOUT.md + PCB-layout tutorial - gen_bom.py + BOM_board.csv: authoritative BOM generated from board.net (70 line items, 167 placements), grouped with MPNs; refs match the integrated netlist; DNP ICs flagged. (Supersedes the early hand-written BOM.csv, which used per-block refs.) - LAYOUT.md: routing rulebook for board.net -- 4-layer stackup, the grounding/star-point strategy, switcher loop isolation, analog separation, USB diff pair, RP2350/crystal/flash, thermal, DNP blocks, pre-fab confirm list, DRC checklist. - pcb_layout_tutorial.md: beginner orientation -- use KiCad; the schematic/netlist=contract vs layout=physical-realization paradigm; the import->place->route->pour->DRC->Gerber workflow; vocabulary; how our files fit; learning resources; honest expectations. Co-Authored-By: Claude Opus 4.8 (1M context) --- hardware/BOM_board.csv | 71 +++++++++++++++++++++ hardware/LAYOUT.md | 108 +++++++++++++++++++++++++++++++ hardware/eda/gen_bom.py | 76 ++++++++++++++++++++++ hardware/pcb_layout_tutorial.md | 109 ++++++++++++++++++++++++++++++++ 4 files changed, 364 insertions(+) create mode 100644 hardware/BOM_board.csv create mode 100644 hardware/LAYOUT.md create mode 100644 hardware/eda/gen_bom.py create mode 100644 hardware/pcb_layout_tutorial.md diff --git a/hardware/BOM_board.csv b/hardware/BOM_board.csv new file mode 100644 index 0000000..1bdad7b --- /dev/null +++ b/hardware/BOM_board.csv @@ -0,0 +1,71 @@ +Qty,Refs,Value,Footprint,Manufacturer,MPN,Populate,Notes +30,C6 C23 C24 C25 C26 C27 C28 C29 C30 C31 C34 C35 C38 C39 C41 C42 C43 C44 C45 C52 C53 C54 C55 C57 C58 C59 C60 C61 C62 C64,100nF,Capacitor_SMD:C_0402_1005Metric,,,, +12,R7 R9 R13 R23 R27 R28 R29 R35 R37 R44 R48 R49,10k,Resistor_SMD:R_0402_1005Metric,,,, +9,C12 C15 C18 C19 C20 C49 C63 C65 C66,1uF,Capacitor_SMD:C_0402_1005Metric,,,, +7,D3 D4 D5 D6 D7 D8 D11,1N4148WS,Diode_SMD:D_SOD-323,onsemi,1N4148WS,,fast diode (input clamps / MIDI protect) +6,R2 R5 R42 R45 R46 R50,100k,Resistor_SMD:R_0402_1005Metric,,,, +5,R10 R38 R39 R40 R41,33,Resistor_SMD:R_0402_1005Metric,,,, +4,C11 C14 C17 C56,10nF,Capacitor_SMD:C_0402_1005Metric,,,, +4,R17 R19 R20 R43,1Meg,Resistor_SMD:R_0402_1005Metric,,,, +4,R12 R16 R18 R22,1k,Resistor_SMD:R_0402_1005Metric,,,, +4,C13 C16 C47 C48,2.2uF,Capacitor_SMD:C_0402_1005Metric,,,, +4,C2 C3 C21 C22,4.7uF,Capacitor_SMD:C_0402_1005Metric,,,, +4,D9 D10 D12 D13,BAT54,Diode_SMD:D_SOD-323,onsemi,BAT54,,Schottky (RTC diode-OR / peak-detect) +3,K1 K2 K3,TQ2SA-5V,Relay_SMD:Relay_DPDT_Panasonic_TQ2-SA,Panasonic,TQ2SA-5V,,"DPDT signal relay, gold; K1 select/K2 mute/K3 gnd-lift" +2,R25 R26,1.5k,Resistor_SMD:R_0402_1005Metric,,,, +2,R3 R32,100,Resistor_SMD:R_0402_1005Metric,,,, +2,C1 C46,10uF,Capacitor_SMD:C_1206_3216Metric,,,, +2,C32 C33,15pF,Capacitor_SMD:C_0402_1005Metric,,,, +2,C36 C37,2.2uF,Capacitor_SMD:C_1206_3216Metric,,,, +2,C4 C7,22uF,Capacitor_SMD:C_1206_3216Metric,,,, +2,R14 R15,27,Resistor_SMD:R_0402_1005Metric,,,, +2,R33 R34,4.7k,Resistor_SMD:R_0402_1005Metric,,,, +2,L2 L3,4.7uH,Inductor_SMD:L_0806_2016Metric,Wurth/EPCOS,7447789004 / B82462-G4472,,switcher inductor +2,R30 R31,47,Resistor_SMD:R_0402_1005Metric,,,, +2,R52 R53,5.1k,Resistor_SMD:R_0402_1005Metric,,,, +2,R47 R51,68k,Resistor_SMD:R_0402_1005Metric,,,, +2,D1 D2,MBRM120,Diode_SMD:D_SOD-323,onsemi,MBRM120ET3G,,Schottky rectifier (switcher) +2,SW1 SW2,SW_Push,Button_Switch_SMD:SW_SPST_SKQG_WithStem,,,, +1,R11,0,Resistor_SMD:R_0402_1005Metric,,,, +1,R1,1.4M,Resistor_SMD:R_0402_1005Metric,,,, +1,R4,1.5M,Resistor_SMD:R_0402_1005Metric,,,, +1,C40,100nF,Capacitor_SMD:C_1206_3216Metric,,,, +1,RV1,10k,Potentiometer_THT:Potentiometer_Bourns_3296W_Vertical,Bourns,3296W-1-103LF,,output level cal trim (25-turn) +1,R6,116k,Resistor_SMD:R_0402_1005Metric,,,, +1,R8,117k,Resistor_SMD:R_0402_1005Metric,,,, +1,Y1,12MHz,Crystal:Crystal_SMD_3225-4Pin_3.2x2.5mm,Abracon,ABM8-272-12.000MHZ-T3,,RP2350 crystal; confirm load caps +1,C51,1nF,Capacitor_SMD:C_0402_1005Metric,,,, +1,R24,2.2k,Resistor_SMD:R_0402_1005Metric,,,, +1,C50,2.2nF,Capacitor_SMD:C_0402_1005Metric,,,, +1,R36,220,Resistor_SMD:R_0402_1005Metric,,,, +1,C9,220nF,Capacitor_SMD:C_0402_1005Metric,,,, +1,L4,3.3uH,Inductor_SMD:L_0806_2016Metric,Abracon,AOTA-B201610S3R3-101-T,,RP2350 core SMPS inductor +1,R21,3k,Resistor_SMD:R_0402_1005Metric,,,, +1,C10,4.7nF,Capacitor_SMD:C_0402_1005Metric,,,, +1,C5,6.8pF,Capacitor_SMD:C_0402_1005Metric,,,, +1,L1,600R,Inductor_SMD:L_0806_2016Metric,Murata,BLM18KG..,,ferrite bead (USB VBUS input) +1,C8,7.5pF,Capacitor_SMD:C_0402_1005Metric,,,, +1,U4,AP2112K-3.3,Package_TO_SOT_SMD:SOT-23-5,Diodes,AP2112K-3.3TRG1,,3V3 LDO; confirm SOT-23-5 pinout +1,BT1,CR2032,Battery:BatteryHolder_Keystone_1066_1x2032,Keystone,1066,,coin-cell holder (RTC backup) +1,J1,Conn_01x04,Connector_PinHeader_1.27mm:PinHeader_1x04_P1.27mm_Vertical,,,, +1,J4,Conn_01x08,Connector_PinHeader_2.54mm:PinHeader_1x08_P2.54mm_Vertical,,,, +1,J3,Conn_02x05_Odd_Even,Connector_PinHeader_2.54mm:PinHeader_2x05_P2.54mm_Vertical,,,, +1,J2,Conn_02x13_Odd_Even,Connector_PinHeader_2.54mm:PinHeader_2x13_P2.54mm_Vertical,,,, +1,U10,OPA1612,Package_SO:SOIC-8_3.9x4.9mm_P1.27mm,TI,OPA1612AIDR,,dual: recon filter + summer +1,U8,OPA1641,Package_SO:SOIC-8_3.9x4.9mm_P1.27mm,TI,OPA1641AID,,JFET Hi-Z DI buffer +1,U9,PCM5102A,Package_SO:TSSOP-20_4.4x6.5mm_P0.65mm,TI,PCM5102APWR,,I2S DAC; SCK->GND (MCLK-less) +1,U5,RP2350A,Package_DFN_QFN:QFN-60-1EP_7x7mm_P0.4mm_EP3.6x3.6mm,Raspberry Pi,RP2350A,,MCU (QFN-60); via KiCad lib symbol +1,U13,RV-8803-C7,RTC_MicroCrystal:RV-8803-C7,Micro Crystal,RV-8803-C7,,I2C RTC; confirm footprint +1,U7,THAT1240,Package_SO:SOIC-8_3.9x4.9mm_P1.27mm,THAT Corp,THAT1240S08-U,,0dB balanced line receiver; 2nd-src INA134/SSM2141 +1,U11,THAT1646,Package_SO:SOIC-8_3.9x4.9mm_P1.27mm,THAT Corp,THAT1646S08-U,,"balanced line driver, +6dB; 2nd-src DRV134/SSM2142" +1,U1,TPS65131,Package_DFN_QFN:QFN-24-1EP_4x4mm_P0.5mm,TI,TPS65131RGER,,dual boost/inverter -> +/-18V +1,U3,TPS7A3001,Package_SO:HVSSOP-8-1EP_3x3mm_P0.65mm,TI,TPS7A3001DGNR,,-15V ultra-low-noise LDO; confirm Vfb +1,U2,TPS7A4901,Package_SO:HVSSOP-8-1EP_3x3mm_P0.65mm,TI,TPS7A4901DGNR,,+15V ultra-low-noise LDO; confirm Vfb +1,U12,ULN2003A,Package_SO:SOIC-16_3.9x9.9mm_P1.27mm,TI,ULN2003ADR,,shared relay driver (3 of 7 ch used) +1,U18,USBLC6-2SC6,Package_TO_SOT_SMD:SOT-23-6,STMicro,USBLC6-2SC6,,USB ESD +1,J5,USB_C_Receptacle,Connector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12,GCT,USB4085-GF-A,,USB-C; 24-pin sym vs 16-pin part - resolve at layout +1,U6,W25Q128JVS,Package_SO:SOIC-8_5.23x5.23mm_P1.27mm,Winbond,W25Q128JVSIQ,,16MB QSPI flash +1,U15,74LVC14,Package_SO:TSSOP-14_4.4x5mm_P0.65mm,Nexperia,74LVC14APW,DNP,DNP - MIDI OUT/THRU buffer +1,U14,H11L1,Package_DIP:DIP-6_W7.62mm,Vishay,H11L1M,DNP,DNP - MIDI opto IN; confirm pinout +1,U16,LM393,Package_SO:SOIC-8_3.9x4.9mm_P1.27mm,TI,LM393DR,DNP,DNP - SIG/CLIP comparator +1,U17,PAM8302A,Package_SO:SOIC-8_3.9x4.9mm_P1.27mm,Diodes,PAM8302AASCR,DNP,DNP - monitor speaker amp diff --git a/hardware/LAYOUT.md b/hardware/LAYOUT.md new file mode 100644 index 0000000..21c94bb --- /dev/null +++ b/hardware/LAYOUT.md @@ -0,0 +1,108 @@ +# PM_K-1 Core Board — PCB Layout Guide + +The rulebook for turning `hardware/kicad/board.net` (167 components) into a routed board. +Read alongside `pcb_layout_tutorial.md` (how the tool works) and `DESIGN.md` (why the +circuit is shaped this way). This is a mixed-signal board — a switching supply, sensitive +±15 V analog, a fast MCU, and USB all on one PCB — so **layout discipline matters more than +on a simple digital board.** The schematic is done and verified; good layout is now what +makes it actually perform. + +## 1. Stackup — use 4 layers +A 2-layer board will work electrically but will be noisy. Use **4 layers**: +``` +L1 signal + components (top) +L2 GROUND plane (solid) <- the single most important thing for noise +L3 power (3V3 / +5 / ±15 split zones) +L4 signal + components (bottom) +``` +A solid ground plane directly under the signal layer gives every fast/analog trace a clean +return path. **Do not cut the L2 ground plane up** (one exception: the star-point, below). +Finish: **ENIG (gold)** — heirloom requirement. + +## 2. Grounding — the heart of a mixed-signal board +There are three "kinds" of ground current that must not share copper: +- **Switcher ground** — the TPS65131 boost/inverter pumps current in sharp pulses. Dirty. +- **Digital ground** — RP2350, flash, USB. Medium. +- **Analog ground** — the ±15 V audio section (THAT/OPA, DAC). Must stay quiet. + +**Strategy:** one solid ground plane (L2), but *partition by placement* — put the switcher +in one corner, digital in another, analog in a third, so each section's return currents stay +local and don't flow under another section. Join them at a **single star point** near the +main ground entry. Keep the switcher's high-current loop entirely in its corner. +- `AGND` (analog signal ground) and `CHASSIS` (shield) meet **only** through the ground-lift + relay K3 + its 100 Ω∥10 nF soft-lift — keep those two nodes otherwise separate. +- The DAC datasheet rule: AGND/DGND/CPGND within 0.2 V of each other — tie them at the star. + +## 3. Switching supply (TPS65131) — most layout-critical block +Switchers fail in *layout*, not schematic. Keep these loops physically tiny: +- **Input caps** (C1/C2, 4.7 µF) right at the INP/INN pins. +- **Inductors L1/L2 (4.7 µH)** and **Schottkys D1/D2 (MBRM120)** close to the switch nodes + (`SW_BOOST`, `SW_INV`) — these nodes are the noisiest copper on the board; keep them **small + and away from everything analog**. Don't run any audio or USB trace near them. +- **Output caps** (C4/C5, 22 µF) close to VPOS/VNEG. +- **Feedback dividers** (R1/R2, R3/R4) and `VREF` (C8) routed quietly, away from the switch nodes. +- Then the **±15 V LDOs** (TPS7A49/30) take the raw ±18 V to clean rails — place them between + the switcher and the analog section so the clean rails enter analog, not the raw ones. + +## 4. Analog audio section — keep it quiet and far +- Place the whole audio chain (THAT1240/1646, OPA1641/1612, DAC, relays) **as a group**, far + from the switcher and the digital ribbon. +- **No analog audio trace runs parallel to the fast SPI or the switch nodes** (this is why + the analog interconnect J3 is physically separate from the digital ribbon J2). +- Film coupling caps and 0.1 % resistors in the signal path; keep signal traces short. +- The balanced in/out: route HOT/COLD as a **tight pair** so noise hits both equally (that's + what the receiver's CMRR rejects). The `MUTE` (K2) and `GND-LIFT` (K3) relays near the output. +- The level-cal trimmer **RV1** must be reachable with a screwdriver after assembly. + +## 5. RP2350 core (per RP "Hardware design with RP2350") +- **QSPI flash** (U?) traces to the RP2350 **short and direct** — high-frequency bus. +- **12 MHz crystal** tight to XIN/XOUT, with its own local ground; a guard ring helps; keep + fast signals away from underneath it. +- **Core SMPS**: the 3.3 µH inductor loop (VREG_LX → DVDD) small; 100 nF per power pin, placed + right at each pin. +- **BOOTSEL** (R6 1 k + button) and the flash-CS resistors close to the flash. + +## 6. USB +- `D+`/`D-` (`USB_DP_CONN`/`USB_DM_CONN`) routed as a **90 Ω differential pair**: short, + length-matched, same layer, reference the ground plane, no stubs. +- The **USBLC6-2 ESD** and the **27 Ω series resistors** right at the connector, before the pair. +- CC 5.1 k pulldowns near the connector. USB-C shell to chassis. + +## 7. The two interconnects (the modular split) +- **J2 digital ribbon** (Pico-pinout) and **J3 analog** (balanced audio + speaker) are on + separate connectors *on purpose* — keep them physically apart on the board and in the + cabling. Interleave grounds on the digital ribbon for the SPI return. +- **J4 MIDI** only matters if the DNP MIDI block is fitted. + +## 8. Mechanical & fab +- 4× M3 mounting holes with keep-outs; a chassis-ground pad. +- **USB-C connector with through-hole anchor tabs** (SMD-only tabs shear off — unacceptable + for a 50-year device). Connector strain relief lives on the face/enclosure. +- Shrouded/keyed/latching interconnect headers. +- **4-layer, ENIG**, controlled impedance on the USB pair. Optional conformal coat for humidity. + +## 9. Thermal +- The ±15 V LDOs dissipate (Vin−Vout)×I ≈ (18−15)×~30 mA ≈ 90 mW each — small, but give them + copper pour / the PowerPAD to the plane. +- The TPS65131 thermal pad to the ground plane with vias. + +## 10. Do-not-populate (DNP) blocks +Per form factor, these are optional — leave the footprints, populate per build: +- **MIDI** (U?/H11L1 opto + 74LVC14 buffer + its resistors) +- **SIG/CLIP indicator** (LM393 + peak-detect parts) +- **monitor speaker amp** (PAM8302A + its caps/resistors) +The BOM flags the DNP *ICs*; their surrounding passives are DNP too when the block is unfitted. + +## 11. Pre-fab confirm list (flagged during capture) +- Footprints: RV-8803-C7, the QFN variants (RP2350A/TPS65131), USB-C (24-pin symbol vs the + 16-pin GCT USB4085 part — pick one), the relay TQ2-SA. +- Values: LDO V_FB exact (used 1.194 V / −1.18 V for the dividers); crystal load caps (~15 pF + per the chosen crystal); 3.3 V-MIDI series-R values. +- Confirm: H11L1 pinout (standard; datasheet fetch had timed out); PCM5102A MCLK-less = SCK→GND. + +## 12. Final checks before Gerbers +1. **DRC clean** (clearances, track widths, the diff-pair rules). +2. Re-import the netlist and confirm no unrouted nets (ratsnest empty). +3. Verify the switcher loops are tight and isolated; analog has no switch-node neighbors. +4. Confirm the ground star point and the analog/digital partition. +5. Generate Gerbers + drill + pick-and-place + the BOM (`BOM_board.csv`) for the fab. diff --git a/hardware/eda/gen_bom.py b/hardware/eda/gen_bom.py new file mode 100644 index 0000000..9ec27c5 --- /dev/null +++ b/hardware/eda/gen_bom.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +"""Generate a consolidated BOM from the integrated board.net. + +Run INSIDE the EDA container: + cd hardware/eda && ./run.sh python3 ../eda/gen_bom.py +Reads hardware/kicad/board.net, groups like parts, attaches MPNs, writes +hardware/BOM_board.csv (authoritative part list keyed to the board.net references). +""" +import re, csv, os, collections + +ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) +NET = os.path.join(ROOT, "hardware/kicad/board.net") +OUT = os.path.join(ROOT, "hardware/BOM_board.csv") + +# value -> (manufacturer, MPN, note) +MPN = { + "RP2350A": ("Raspberry Pi", "RP2350A", "MCU (QFN-60); via KiCad lib symbol"), + "W25Q128JVS": ("Winbond", "W25Q128JVSIQ", "16MB QSPI flash"), + "PCM5102A": ("TI", "PCM5102APWR", "I2S DAC; SCK->GND (MCLK-less)"), + "THAT1240": ("THAT Corp", "THAT1240S08-U", "0dB balanced line receiver; 2nd-src INA134/SSM2141"), + "THAT1646": ("THAT Corp", "THAT1646S08-U", "balanced line driver, +6dB; 2nd-src DRV134/SSM2142"), + "OPA1641": ("TI", "OPA1641AID", "JFET Hi-Z DI buffer"), + "OPA1612": ("TI", "OPA1612AIDR", "dual: recon filter + summer"), + "TPS65131": ("TI", "TPS65131RGER", "dual boost/inverter -> +/-18V"), + "TPS7A4901": ("TI", "TPS7A4901DGNR", "+15V ultra-low-noise LDO; confirm Vfb"), + "TPS7A3001": ("TI", "TPS7A3001DGNR", "-15V ultra-low-noise LDO; confirm Vfb"), + "AP2112K-3.3": ("Diodes", "AP2112K-3.3TRG1", "3V3 LDO; confirm SOT-23-5 pinout"), + "ULN2003A": ("TI", "ULN2003ADR", "shared relay driver (3 of 7 ch used)"), + "RV-8803-C7": ("Micro Crystal", "RV-8803-C7", "I2C RTC; confirm footprint"), + "LM393": ("TI", "LM393DR", "DNP - SIG/CLIP comparator"), + "H11L1": ("Vishay", "H11L1M", "DNP - MIDI opto IN; confirm pinout"), + "74LVC14": ("Nexperia", "74LVC14APW", "DNP - MIDI OUT/THRU buffer"), + "PAM8302A": ("Diodes", "PAM8302AASCR", "DNP - monitor speaker amp"), + "USBLC6-2SC6": ("STMicro", "USBLC6-2SC6", "USB ESD"), + "TQ2SA-5V": ("Panasonic", "TQ2SA-5V", "DPDT signal relay, gold; K1 select/K2 mute/K3 gnd-lift"), + "12MHz": ("Abracon", "ABM8-272-12.000MHZ-T3", "RP2350 crystal; confirm load caps"), + "USB_C_Receptacle": ("GCT", "USB4085-GF-A", "USB-C; 24-pin sym vs 16-pin part - resolve at layout"), + "CR2032": ("Keystone", "1066", "coin-cell holder (RTC backup)"), + "MBRM120": ("onsemi", "MBRM120ET3G", "Schottky rectifier (switcher)"), + "BAT54": ("onsemi", "BAT54", "Schottky (RTC diode-OR / peak-detect)"), + "1N4148WS": ("onsemi", "1N4148WS", "fast diode (input clamps / MIDI protect)"), + "4.7uH": ("Wurth/EPCOS", "7447789004 / B82462-G4472", "switcher inductor"), + "3.3uH": ("Abracon", "AOTA-B201610S3R3-101-T", "RP2350 core SMPS inductor"), + "600R": ("Murata", "BLM18KG..", "ferrite bead (USB VBUS input)"), +} + +comps = re.findall(r'\(comp\s*\(ref "([^"]+)"\)\s*\(value "([^"]+)"\)(.*?)\(libsource', open(NET).read(), re.S) +def fp(blk): + m = re.search(r'\(footprint "([^"]+)"', blk); return m.group(1) if m else "" + +groups = collections.OrderedDict() +for ref, val, blk in comps: + key = (val, fp(blk)) + groups.setdefault(key, []).append(ref) + +def sortkey(r): + m = re.match(r'([A-Za-z]+)(\d+)', r); return (m.group(1), int(m.group(2))) if m else (r, 0) + +rows = [] +for (val, foot), refs in groups.items(): + refs = sorted(refs, key=sortkey) + man, mpn, note = MPN.get(val, ("", "", "")) + if "Potentiometer" in foot: # the level-cal trimmer (value "10k" but a pot) + man, mpn, note = ("Bourns", "3296W-1-103LF", "output level cal trim (25-turn)") + # heuristic DNP flag + dnp = any(s in note for s in ("DNP",)) + rows.append([len(refs), " ".join(refs), val, foot, man, mpn, ("DNP" if dnp else ""), note]) + +rows.sort(key=lambda r: (r[6] == "DNP", -r[0], r[2])) # populated first, then by qty +with open(OUT, "w", newline="") as f: + w = csv.writer(f) + w.writerow(["Qty", "Refs", "Value", "Footprint", "Manufacturer", "MPN", "Populate", "Notes"]) + w.writerows(rows) + +print("wrote", OUT) +print("line items:", len(rows), " total placements:", sum(r[0] for r in rows)) diff --git a/hardware/pcb_layout_tutorial.md b/hardware/pcb_layout_tutorial.md new file mode 100644 index 0000000..ee9a7df --- /dev/null +++ b/hardware/pcb_layout_tutorial.md @@ -0,0 +1,109 @@ +# PCB Layout — what software, and how it actually works + +A plain-English orientation for turning our finished schematic into a manufacturable board. +You don't need prior PCB experience to follow this. (Reminder: this is **board design** — +arranging finished chips and copper wires — *not* "chip design," which is the silicon inside +the chips. Totally different, far more approachable.) + +## The software: KiCad + +**Use KiCad** (free, open-source, professional-grade). It's what we've been using to verify +the design, and it's already installed in the project container (`hardware/eda/run.sh`). +There are paid alternatives (Altium ~$$$, Autodesk Fusion/EAGLE), but KiCad is free, capable, +and has the best free learning material — no reason to use anything else here. + +KiCad is actually several tools in one: +- **Eeschema** — draws the *schematic* (what connects to what). *We did this in code (SKiDL), + which generated the same thing.* +- **Pcbnew** — the *PCB layout* editor. **This is the part you'll learn next.** +- helpers for 3D view, Gerber export, etc. + +## The core paradigm (read this part twice) + +A circuit board is described at **two levels**, and keeping them separate is the whole idea: + +1. **The schematic / netlist = the *contract*.** It says *what must be electrically + connected* — "pin 6 of the DAC connects to the resistor R12, which connects to the op-amp." + It says nothing about physical position. **Ours is done:** `hardware/kicad/board.net`. + +2. **The PCB layout = the *physical realization*.** You decide *where* each component sits and + *how* the copper wires (called **traces**) run to satisfy every connection the netlist + demands — while obeying physical rules (wires can't be too thin, too close, etc.). + +So the mental model is: **constraint-satisfying connect-the-dots.** The netlist hands you a +list of dots that *must* be joined; you place the parts on a rectangle and draw copper to join +exactly those dots, in the cleanest way, without breaking the rules. Nothing more, nothing less. + +Why two levels? Because *what* connects (the design) and *where things go* (the craft) are +genuinely different problems. We nailed the first — rigorously, with simulations. The second +is a spatial puzzle. + +## The workflow, step by step + +1. **Import the netlist.** Open Pcbnew, import `board.net`. All 167 components appear as + **footprints** (the real-world copper pads + outline for each part), piled up, joined by a + tangle of thin lines called the **ratsnest** — each line is one connection the netlist + requires but that isn't routed yet. + +2. **Place the footprints.** Drag parts into a sensible arrangement. *This is where our + `LAYOUT.md` rules apply* — switcher in one corner, quiet analog in another, USB by its + connector, etc. Good placement makes routing easy; bad placement makes it impossible. + +3. **Route the traces.** Draw copper to replace each ratsnest line. You work on **layers** + (top copper, bottom copper, and inner layers on a 4-layer board); you hop between layers + through plated holes called **vias**. As you connect dots, the ratsnest lines disappear. + +4. **Pour the planes.** Fill empty areas with copper connected to **GND** (and power) — the + "ground plane" that keeps everything quiet. (Big topic in `LAYOUT.md`.) + +5. **Run DRC** (**Design Rule Check**) — the layout equivalent of the ERC we ran on the + schematic. It flags traces too close together, too thin, unrouted connections, etc. Fix + until clean. + +6. **Export and order.** Generate **Gerber** files (the standard format every fab understands — + one file per layer), plus a drill file, a pick-and-place file, and the BOM + (`BOM_board.csv`). Upload to a fab like **JLCPCB** or **PCBWay**; they make and (optionally) + assemble it. + +## The vocabulary you'll meet + +| Term | Plain meaning | +|---|---| +| **Footprint** | the copper pads + outline a real part solders onto | +| **Net** | one electrical connection (a wire), e.g. `+3V3`, `MIX_OUT` | +| **Ratsnest** | the thin "still-to-route" lines showing required connections | +| **Trace** | a copper wire you draw | +| **Via** | a plated hole that carries a trace between layers | +| **Plane / pour** | a large copper fill, usually ground or power | +| **Layer** | one copper sheet; our board uses 4, stacked | +| **Clearance** | the minimum gap rules between copper | +| **DRC** | Design Rule Check — automated "is this manufacturable?" | +| **Gerber** | the file format you send to the factory | + +## How our files fit together +- **`board.net`** → the contract you import into Pcbnew (the dots to connect). +- **`LAYOUT.md`** → the rulebook for *how* to place and route this specific board (grounding, + the switcher, USB pair, analog isolation). +- **`BOM_board.csv`** → the parts list for ordering/assembly. +- **`DESIGN.md`** → why the circuit is the way it is, if you want the background. + +## Learning resources (do these in order) +1. **Digi-Key "Intro to KiCad" by Shawn Hymel** (YouTube) — start-to-finish, free; the layout + parts are exactly steps 1–6 above. +2. **Phil's Lab** (YouTube) — especially relevant: he does **audio and mixed-signal** PCBs, + grounding, and USB — our exact problem domain. +3. KiCad's official "Getting Started" docs. + +## Honest expectations +The *digital* parts of this board (RP2350, flash, the ribbons) are beginner-friendly to route. +The **switching supply, the ±15 V analog section, and the USB pair are not** — they reward +experience, and mistakes there show up as noise or instability. Three realistic paths: +- **Learn on it:** route the easy parts yourself, and follow `LAYOUT.md` carefully (with me) for + the tricky three. Best for understanding your own device. +- **Hybrid:** you place + route the digital/connectors; hand the switcher/analog/USB to a + freelance layout person (or me, iterating). +- **Hire the layout:** `board.net` + `BOM_board.csv` + `LAYOUT.md` is a complete brief a + contract PCB designer can execute (~$300–1500 for a board this size). + +The hard intellectual work — the design — is already done and verified. Layout is craft and +care, and it's learnable.