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) <noreply@anthropic.com>
This commit is contained in:
Me Here 2026-05-31 00:15:15 -05:00
parent bf74c860e5
commit 0dc9daf54f
4 changed files with 364 additions and 0 deletions

71
hardware/BOM_board.csv Normal file
View file

@ -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
1 Qty Refs Value Footprint Manufacturer MPN Populate Notes
2 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
3 12 R7 R9 R13 R23 R27 R28 R29 R35 R37 R44 R48 R49 10k Resistor_SMD:R_0402_1005Metric
4 9 C12 C15 C18 C19 C20 C49 C63 C65 C66 1uF Capacitor_SMD:C_0402_1005Metric
5 7 D3 D4 D5 D6 D7 D8 D11 1N4148WS Diode_SMD:D_SOD-323 onsemi 1N4148WS fast diode (input clamps / MIDI protect)
6 6 R2 R5 R42 R45 R46 R50 100k Resistor_SMD:R_0402_1005Metric
7 5 R10 R38 R39 R40 R41 33 Resistor_SMD:R_0402_1005Metric
8 4 C11 C14 C17 C56 10nF Capacitor_SMD:C_0402_1005Metric
9 4 R17 R19 R20 R43 1Meg Resistor_SMD:R_0402_1005Metric
10 4 R12 R16 R18 R22 1k Resistor_SMD:R_0402_1005Metric
11 4 C13 C16 C47 C48 2.2uF Capacitor_SMD:C_0402_1005Metric
12 4 C2 C3 C21 C22 4.7uF Capacitor_SMD:C_0402_1005Metric
13 4 D9 D10 D12 D13 BAT54 Diode_SMD:D_SOD-323 onsemi BAT54 Schottky (RTC diode-OR / peak-detect)
14 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
15 2 R25 R26 1.5k Resistor_SMD:R_0402_1005Metric
16 2 R3 R32 100 Resistor_SMD:R_0402_1005Metric
17 2 C1 C46 10uF Capacitor_SMD:C_1206_3216Metric
18 2 C32 C33 15pF Capacitor_SMD:C_0402_1005Metric
19 2 C36 C37 2.2uF Capacitor_SMD:C_1206_3216Metric
20 2 C4 C7 22uF Capacitor_SMD:C_1206_3216Metric
21 2 R14 R15 27 Resistor_SMD:R_0402_1005Metric
22 2 R33 R34 4.7k Resistor_SMD:R_0402_1005Metric
23 2 L2 L3 4.7uH Inductor_SMD:L_0806_2016Metric Wurth/EPCOS 7447789004 / B82462-G4472 switcher inductor
24 2 R30 R31 47 Resistor_SMD:R_0402_1005Metric
25 2 R52 R53 5.1k Resistor_SMD:R_0402_1005Metric
26 2 R47 R51 68k Resistor_SMD:R_0402_1005Metric
27 2 D1 D2 MBRM120 Diode_SMD:D_SOD-323 onsemi MBRM120ET3G Schottky rectifier (switcher)
28 2 SW1 SW2 SW_Push Button_Switch_SMD:SW_SPST_SKQG_WithStem
29 1 R11 0 Resistor_SMD:R_0402_1005Metric
30 1 R1 1.4M Resistor_SMD:R_0402_1005Metric
31 1 R4 1.5M Resistor_SMD:R_0402_1005Metric
32 1 C40 100nF Capacitor_SMD:C_1206_3216Metric
33 1 RV1 10k Potentiometer_THT:Potentiometer_Bourns_3296W_Vertical Bourns 3296W-1-103LF output level cal trim (25-turn)
34 1 R6 116k Resistor_SMD:R_0402_1005Metric
35 1 R8 117k Resistor_SMD:R_0402_1005Metric
36 1 Y1 12MHz Crystal:Crystal_SMD_3225-4Pin_3.2x2.5mm Abracon ABM8-272-12.000MHZ-T3 RP2350 crystal; confirm load caps
37 1 C51 1nF Capacitor_SMD:C_0402_1005Metric
38 1 R24 2.2k Resistor_SMD:R_0402_1005Metric
39 1 C50 2.2nF Capacitor_SMD:C_0402_1005Metric
40 1 R36 220 Resistor_SMD:R_0402_1005Metric
41 1 C9 220nF Capacitor_SMD:C_0402_1005Metric
42 1 L4 3.3uH Inductor_SMD:L_0806_2016Metric Abracon AOTA-B201610S3R3-101-T RP2350 core SMPS inductor
43 1 R21 3k Resistor_SMD:R_0402_1005Metric
44 1 C10 4.7nF Capacitor_SMD:C_0402_1005Metric
45 1 C5 6.8pF Capacitor_SMD:C_0402_1005Metric
46 1 L1 600R Inductor_SMD:L_0806_2016Metric Murata BLM18KG.. ferrite bead (USB VBUS input)
47 1 C8 7.5pF Capacitor_SMD:C_0402_1005Metric
48 1 U4 AP2112K-3.3 Package_TO_SOT_SMD:SOT-23-5 Diodes AP2112K-3.3TRG1 3V3 LDO; confirm SOT-23-5 pinout
49 1 BT1 CR2032 Battery:BatteryHolder_Keystone_1066_1x2032 Keystone 1066 coin-cell holder (RTC backup)
50 1 J1 Conn_01x04 Connector_PinHeader_1.27mm:PinHeader_1x04_P1.27mm_Vertical
51 1 J4 Conn_01x08 Connector_PinHeader_2.54mm:PinHeader_1x08_P2.54mm_Vertical
52 1 J3 Conn_02x05_Odd_Even Connector_PinHeader_2.54mm:PinHeader_2x05_P2.54mm_Vertical
53 1 J2 Conn_02x13_Odd_Even Connector_PinHeader_2.54mm:PinHeader_2x13_P2.54mm_Vertical
54 1 U10 OPA1612 Package_SO:SOIC-8_3.9x4.9mm_P1.27mm TI OPA1612AIDR dual: recon filter + summer
55 1 U8 OPA1641 Package_SO:SOIC-8_3.9x4.9mm_P1.27mm TI OPA1641AID JFET Hi-Z DI buffer
56 1 U9 PCM5102A Package_SO:TSSOP-20_4.4x6.5mm_P0.65mm TI PCM5102APWR I2S DAC; SCK->GND (MCLK-less)
57 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
58 1 U13 RV-8803-C7 RTC_MicroCrystal:RV-8803-C7 Micro Crystal RV-8803-C7 I2C RTC; confirm footprint
59 1 U7 THAT1240 Package_SO:SOIC-8_3.9x4.9mm_P1.27mm THAT Corp THAT1240S08-U 0dB balanced line receiver; 2nd-src INA134/SSM2141
60 1 U11 THAT1646 Package_SO:SOIC-8_3.9x4.9mm_P1.27mm THAT Corp THAT1646S08-U balanced line driver, +6dB; 2nd-src DRV134/SSM2142
61 1 U1 TPS65131 Package_DFN_QFN:QFN-24-1EP_4x4mm_P0.5mm TI TPS65131RGER dual boost/inverter -> +/-18V
62 1 U3 TPS7A3001 Package_SO:HVSSOP-8-1EP_3x3mm_P0.65mm TI TPS7A3001DGNR -15V ultra-low-noise LDO; confirm Vfb
63 1 U2 TPS7A4901 Package_SO:HVSSOP-8-1EP_3x3mm_P0.65mm TI TPS7A4901DGNR +15V ultra-low-noise LDO; confirm Vfb
64 1 U12 ULN2003A Package_SO:SOIC-16_3.9x9.9mm_P1.27mm TI ULN2003ADR shared relay driver (3 of 7 ch used)
65 1 U18 USBLC6-2SC6 Package_TO_SOT_SMD:SOT-23-6 STMicro USBLC6-2SC6 USB ESD
66 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
67 1 U6 W25Q128JVS Package_SO:SOIC-8_5.23x5.23mm_P1.27mm Winbond W25Q128JVSIQ 16MB QSPI flash
68 1 U15 74LVC14 Package_SO:TSSOP-14_4.4x5mm_P0.65mm Nexperia 74LVC14APW DNP DNP - MIDI OUT/THRU buffer
69 1 U14 H11L1 Package_DIP:DIP-6_W7.62mm Vishay H11L1M DNP DNP - MIDI opto IN; confirm pinout
70 1 U16 LM393 Package_SO:SOIC-8_3.9x4.9mm_P1.27mm TI LM393DR DNP DNP - SIG/CLIP comparator
71 1 U17 PAM8302A Package_SO:SOIC-8_3.9x4.9mm_P1.27mm Diodes PAM8302AASCR DNP DNP - monitor speaker amp

108
hardware/LAYOUT.md Normal file
View file

@ -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 (VinVout)×I ≈ (1815)×~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.

76
hardware/eda/gen_bom.py Normal file
View file

@ -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))

View file

@ -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 16 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 (~$3001500 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.