From 2c6e7e8762b330363e0d76b23579b3a95719cbb5 Mon Sep 17 00:00:00 2001 From: blue Date: Thu, 11 Jun 2026 15:10:15 -0400 Subject: [PATCH] hardware: KiCad bootstrap for the Resound carrier PCB (Small Build) Netlist-first KiCad-import package for the single carrier PCB (ESP32-WROOM-32E, SINK/BROADCASTER assembly variants): - hardware/carrier/resound-carrier.net : KiCad s-expr netlist, 44 components / 40 nets, real library footprints (RF_Module:ESP32-WROOM-32, 2x13 stacking header, 0402 passives, SOT-23 auto-reset, JST-SH HUD conn). Parens balanced. - hardware/carrier/BOM.csv : 44 parts (ref/value/footprint/MPN/DNP/notes). - hardware/carrier/LAYOUT.md : 45x45 4-layer stackup, 15mm antenna keep-out, placement, JLCPCB DRC, SINK-vs-BROADCASTER variant + address-strap table. - hardware/carrier/README.md : KiCad import steps + caveats. Agent decisions flagged for EE: LED moved off the GPIO13 strap to LED_DAT=GPIO21 / LED_CLK=GPIO4; verify WROOM footprint pad numbering; UART2 is connector-only this rev. Deliverable is import-ready netlist+BOM+spec, not a finished .kicad_pcb. Co-Authored-By: Claude Opus 4.8 (1M context) --- hardware/carrier/BOM.csv | 45 ++++ hardware/carrier/LAYOUT.md | 129 +++++++++ hardware/carrier/README.md | 84 ++++++ hardware/carrier/resound-carrier.net | 387 +++++++++++++++++++++++++++ 4 files changed, 645 insertions(+) create mode 100644 hardware/carrier/BOM.csv create mode 100644 hardware/carrier/LAYOUT.md create mode 100644 hardware/carrier/README.md create mode 100644 hardware/carrier/resound-carrier.net diff --git a/hardware/carrier/BOM.csv b/hardware/carrier/BOM.csv new file mode 100644 index 0000000..da334d4 --- /dev/null +++ b/hardware/carrier/BOM.csv @@ -0,0 +1,45 @@ +Ref,Qty,Value,Footprint,MPN/JLCPCB part,DNP(y/n),Notes +U1,1,ESP32-WROOM-32E,RF_Module:ESP32-WROOM-32,ESP32-WROOM-32E / JLCPCB C701343,n,SMD castellated 38-pad module; antenna overhangs board edge (see keep-out) +J1,1,Stack_2x13,Connector_PinHeader_2.54mm:PinHeader_2x13_P2.54mm_Vertical,Generic 2x13 2.54mm,n,Stacking pass-through bus; mirror header on bottom shares same nets +J2,1,PROG_1x6,Connector_PinHeader_2.54mm:PinHeader_1x06_P2.54mm_Vertical,Generic 1x6 2.54mm,n,Programming/serial: GND +5V RX(IO3) TX(IO1) DTR RTS +J3,1,HUD_SH1.0_1x6,Connector_JST:JST_SH_BM06B-SRSS-TB_1x06-1MP_P1.00mm_Vertical,JST BM06B-SRSS-TB,n,TOP board only: 1=+5V 2=GND 3=SDA 4=SCL 5=SPARE 6=NC. Verify pin order vs HUD cable +Q1,1,MMBT3904,Package_TO_SOT_SMD:SOT-23,MMBT3904 / JLCPCB C20526,n,Auto-reset (DTR->EN) +Q2,1,MMBT3904,Package_TO_SOT_SMD:SOT-23,MMBT3904 / JLCPCB C20526,n,Auto-boot (RTS->IO0) +SW1,1,EN/RESET,Button_Switch_SMD:SW_SPST_PTS645,PTS645 series,n,Tactile EN->GND +SW2,1,BOOT/IO0,Button_Switch_SMD:SW_SPST_PTS645,PTS645 series,n,Tactile IO0->GND +JP1,1,0R,Resistor_SMD:R_0603_1608Metric,0R 0603,n,I2S_BCK=GPIO5 (SINK column) +JP2,1,0R,Resistor_SMD:R_0603_1608Metric,0R 0603,n,I2S_WS=GPIO25 (SINK column) +JP3,1,0R,Resistor_SMD:R_0603_1608Metric,0R 0603,n,I2S_DATA=GPIO23 (SINK column) +JP4,1,0R,Resistor_SMD:R_0603_1608Metric,0R 0603,n,I2S_BCK=GPIO19 (BROADCASTER column) +JP5,1,0R,Resistor_SMD:R_0603_1608Metric,0R 0603,n,I2S_WS=GPIO18 (BROADCASTER column) +JP6,1,0R,Resistor_SMD:R_0603_1608Metric,0R 0603,n,I2S_DATA=GPIO22 (BROADCASTER column) +R1,1,33R,Resistor_SMD:R_0402_1005Metric,33R 0402,y,I2S_BCK series term (optional; DNP default) +R2,1,33R,Resistor_SMD:R_0402_1005Metric,33R 0402,y,I2S_WS series term (optional; DNP default) +R3,1,33R,Resistor_SMD:R_0402_1005Metric,33R 0402,y,I2S_DATA series term (optional; DNP default = 0R jumper if not fitted) +R4,1,4.7k,Resistor_SMD:R_0402_1005Metric,4.7k 0402,y,SDA pull-up to 3V3. Populate on SINK only (single pull-up on bus) +R5,1,4.7k,Resistor_SMD:R_0402_1005Metric,4.7k 0402,y,SCL pull-up to 3V3. Populate on SINK only (single pull-up on bus) +R6,1,10k,Resistor_SMD:R_0402_1005Metric,10k 0402,n,EN pull-up to 3V3 +R7,1,10k,Resistor_SMD:R_0402_1005Metric,10k 0402,n,IO0 pull-up to 3V3 +R8,1,10k,Resistor_SMD:R_0402_1005Metric,10k 0402,n,Q1 base resistor (auto-reset) +R9,1,10k,Resistor_SMD:R_0402_1005Metric,10k 0402,n,Q2 base resistor (auto-boot) +R10,1,10k,Resistor_SMD:R_0402_1005Metric,10k 0402,n,ADDR0/GPIO13 strap to 3V3 (populate this OR R11) +R11,1,0R,Resistor_SMD:R_0402_1005Metric,0R 0402,y,ADDR0/GPIO13 strap to GND (populate this OR R10) +R12,1,10k,Resistor_SMD:R_0402_1005Metric,10k 0402,n,ADDR1/GPIO14 strap to 3V3 (populate this OR R13) +R13,1,0R,Resistor_SMD:R_0402_1005Metric,0R 0402,y,ADDR1/GPIO14 strap to GND (populate this OR R12) +R14,1,10k,Resistor_SMD:R_0402_1005Metric,10k 0402,n,ADDR2/GPIO27 strap to 3V3 (populate this OR R15) +R15,1,0R,Resistor_SMD:R_0402_1005Metric,0R 0402,y,ADDR2/GPIO27 strap to GND (populate this OR R14) +R16,1,10k,Resistor_SMD:R_0402_1005Metric,10k 0402,n,ADDR3/GPIO26 strap to 3V3 (populate this OR R17) +R17,1,0R,Resistor_SMD:R_0402_1005Metric,0R 0402,y,ADDR3/GPIO26 strap to GND (populate this OR R16) +C1,1,1uF,Capacitor_SMD:C_0603_1608Metric,1uF 0603,n,EN to GND (reset delay) +C2,1,100nF,Capacitor_SMD:C_0402_1005Metric,100nF 0402,n,IO0 to GND (boot debounce) +C3,1,100nF,Capacitor_SMD:C_0402_1005Metric,100nF 0402,n,DTR coupling cap to Q1 +C4,1,100nF,Capacitor_SMD:C_0402_1005Metric,100nF 0402,n,RTS coupling cap to Q2 +C5,1,10uF,Capacitor_SMD:C_0805_2012Metric,10uF 0805,n,3V3 bulk at WROOM 3V3 pad +C6,1,100nF,Capacitor_SMD:C_0402_1005Metric,100nF 0402,n,3V3 decap at WROOM 3V3 pad +C7,1,100nF,Capacitor_SMD:C_0402_1005Metric,100nF 0402,n,3V3 decap at WROOM 3V3 pad +C8,1,10uF,Capacitor_SMD:C_0805_2012Metric,10uF 0805,n,+5V bulk at stacking connector +C9,1,22uF,Capacitor_SMD:C_0805_2012Metric,22uF 0805,n,3V3 bulk rail +H1,1,MountingHole_M3,MountingHole:MountingHole_3.2mm_M3,-,n,Corner mount, 38x38mm pattern, GND-tied +H2,1,MountingHole_M3,MountingHole:MountingHole_3.2mm_M3,-,n,Corner mount, GND-tied +H3,1,MountingHole_M3,MountingHole:MountingHole_3.2mm_M3,-,n,Corner mount, GND-tied +H4,1,MountingHole_M3,MountingHole:MountingHole_3.2mm_M3,-,n,Corner mount, GND-tied diff --git a/hardware/carrier/LAYOUT.md b/hardware/carrier/LAYOUT.md new file mode 100644 index 0000000..195be14 --- /dev/null +++ b/hardware/carrier/LAYOUT.md @@ -0,0 +1,129 @@ +# Resound Small Build — Carrier PCB Layout & Fab Spec + +This document is the layout intent that pairs with `resound-carrier.net`. The netlist +defines connectivity; this defines board outline, stackup, placement, and design rules. +An engineer imports the netlist into KiCad, then lays out per the constraints here. + +## 1. Board outline +- **Size:** 45.0 mm x 45.0 mm. +- **Corners:** rounded, R = 3.0 mm (4x). +- **Edge.Cuts** layer defines outline. Keep all copper >= 0.3 mm inside the edge except + the deliberate antenna keep-out region (see section 4). + +## 2. Stackup (4-layer) +| Layer | Name | Use | +|-------|-------------|--------------------------------------------------| +| L1 | Sig (top) | Components, signal routing, WROOM, connectors | +| L2 | GND | Solid ground plane (reference for all signals) | +| L3 | PWR | +3V3 / +5V power pours | +| L4 | Sig (bottom)| Signal routing, bottom stacking header, fanout | + +- Standard JLCPCB 4-layer: 1.6 mm finished, 0.5 oz inner / 1 oz outer, FR-4 TG155 OK. +- Stitch GND plane to top/bottom ground pours with vias around board perimeter and under + the WROOM ground pad array. Place a dense via field under U1's exposed/edge GND pads. + +## 3. Power distribution +- +5V enters on stacking connector J1 pins 1,2. C8 (10uF) bulk at connector. +- +3V3 rail on J1 pins 5,6 (module/regulator assumed upstream on the +3V3 supplying board). + C9 (22uF) bulk on 3V3. C5 (10uF) + C6/C7 (100nF) directly at the WROOM 3V3 pad (pad 2), + shortest possible loop to nearest GND via. +- Power pour widths: 5V and 3V3 main feeds >= 0.6 mm or plane on L3. + +## 4. Antenna keep-out (CRITICAL) +- U1 (ESP32-WROOM-32E) placed at one board edge with the **PCB antenna overhanging the + board edge** — the antenna end of the module must sit flush with / past the edge cut. +- **15 mm copper keep-out, ALL LAYERS**, around the antenna: no copper (no traces, no + pours, no plane fill, no ground) within 15 mm of the antenna trace footprint, including + L2 GND and L3 PWR planes. Add a keep-out zone on every layer. +- No mounting hardware, no metal, no components in the antenna keep-out. +- This is why U1 lives at the edge and the antenna overhangs: maximize RF clearance. + +## 5. Placement plan +``` + +-----------------------------------------------+ + | (H1) (H2) | + | [ U1 ESP32-WROOM-32E ] <- antenna overhang| <- this edge: antenna keep-out 15mm + | 3V3 decap C5/C6/C7 hugging pad 2 | + | | + | [ J1 2x13 stacking connector ] | <- centered, vertical, top+bottom + | I2S jumper field JP1..JP6 near J1 | + | | + | [J2 prog 1x6] Q1 Q2 C3 C4 [SW1] [SW2] | <- opposite edge: prog + buttons + | (H3) [J3 HUD SH1.0 - TOP only] (H4) | + +-----------------------------------------------+ +``` +- **U1:** top edge, antenna overhanging, keep-out enforced. +- **J1 stacking connector:** centered on the board so the stack aligns mechanically. + Top header + mirrored bottom header on the SAME footprint position share nets + (pass-through). Verify pin 1 indexing matches between top and bottom of the stack. +- **I2S role jumpers JP1..JP6:** group as two visible columns (SINK | BROADCASTER) next + to J1, silkscreen-label each column and net. +- **Address straps R10..R17:** group as a labelled field; silkscreen "3V3 / GND" per strap. +- **Prog header J2, transistors Q1/Q2, caps C3/C4, buttons SW1/SW2:** opposite edge from + the antenna, accessible. +- **J3 HUD SH1.0:** near a board edge, TOP board assembly only. +- **Mounting holes H1..H4:** 38 x 38 mm square pattern (centered on 45x45 board => holes + at +/-19 mm from center X and Y), M3 (3.2 mm), keep clear of antenna keep-out (move the + two antenna-edge holes inward if they fall inside the 15 mm keep-out). + +## 6. Design rules (JLCPCB 4-layer, standard) +- Min trace width: 0.127 mm (5 mil); use 0.2 mm default signal, 0.15 mm only in fanout. +- Min spacing: 0.127 mm (5 mil); 0.2 mm default. +- Min via: 0.3 mm drill / 0.6 mm pad; 0.2/0.4 only where needed. +- Min annular ring: 0.13 mm. +- Edge clearance: copper >= 0.3 mm from Edge.Cuts (except antenna keep-out which is larger). +- **I2S series termination:** R1/R2/R3 (33R) footprints sit inline on I2S_BCK/WS/DATA + between the jumper field and J1. Default DNP — if I2S edges ring on the scope across the + stack, populate 33R and remove the equivalent direct short. Keep I2S traces short, equal + length within the pair set, referenced to L2 GND, away from the antenna. +- **Single pull-up rule:** I2C SDA/SCL pull-ups (R4/R5) have footprints on EVERY board but + are DNP except on the SINK board, so the bus has exactly ONE pull-up pair across the stack. +- Decoupling caps: place on the same layer as U1, vias to L2/L3 directly under the cap pad. + +## 7. Assembly variants (ONE board, two BOMs) + +| Item / Net | SINK board | BROADCASTER board | +|-----------------------|----------------------------|----------------------------| +| I2S BCK jumper | JP1 (GPIO5) populated | JP4 (GPIO19) populated | +| I2S WS jumper | JP2 (GPIO25) populated | JP5 (GPIO18) populated | +| I2S DATA jumper | JP3 (GPIO23) populated | JP6 (GPIO22) populated | +| Opposite I2S column | JP4/JP5/JP6 DNP | JP1/JP2/JP3 DNP | +| I2C pull-up R4 (SDA) | **populate 4.7k** | DNP | +| I2C pull-up R5 (SCL) | **populate 4.7k** | DNP | +| I2S series term R1-R3 | DNP (unless ringing) | DNP (unless ringing) | +| HUD connector J3 | per mechanical (TOP only) | per mechanical (TOP only) | +| Address straps | per node address (see below)| per node address | +| Reset/boot/prog (R6-9, C1-4, Q1-2, SW1-2, J2) | populate | populate | +| Decoupling C5-C9 | populate | populate | + +**Address straps (R10..R17):** for each of ADDR0..ADDR3, populate EXACTLY ONE of the pair: +- "1" / high => populate the 10k-to-3V3 resistor (R10/R12/R14/R16), leave the 0R-to-GND DNP. +- "0" / low => populate the 0R-to-GND resistor (R11/R13/R15/R17), leave the 10k DNP. + +This is independent of SINK/BROADCASTER — it sets each board's bus address in the stack. + +## 8. Connector pinouts (reference) + +### J1 — 26-pin (2x13) stacking, 2.54 mm, pass-through (top + mirrored bottom) +| Pin | Net | Pin | Net | +|-----|------------|-----|------------| +| 1 | +5V | 2 | +5V | +| 3 | GND | 4 | GND | +| 5 | +3V3 | 6 | +3V3 | +| 7 | GND | 8 | I2S_BCK | +| 9 | GND | 10 | I2S_WS | +| 11 | GND | 12 | I2S_DATA | +| 13 | GND | 14 | GND | +| 15 | I2C_SDA | 16 | I2C_SCL | +| 17 | UART_TX | 18 | UART_RX | +| 19 | UART2_TX | 20 | UART2_RX | +| 21 | LED_DAT | 22 | LED_CLK | +| 23 | ADDR_CHAIN_IN | 24 | ADDR_CHAIN_OUT | +| 25 | SPARE | 26 | GND | + +### J2 — programming 1x6, 2.54 mm +1=GND, 2=+5V, 3=RX (IO3 / GPIO3), 4=TX (IO1 / GPIO1), 5=DTR, 6=RTS + +### J3 — HUD SH1.0 1x6 (TOP board only) +1=+5V (VSYS), 2=GND, 3=I2C_SDA, 4=I2C_SCL, 5=SPARE, 6=NC +(Verify physical pin order against the HUD cable before fab — see README caveat.) diff --git a/hardware/carrier/README.md b/hardware/carrier/README.md new file mode 100644 index 0000000..900276e --- /dev/null +++ b/hardware/carrier/README.md @@ -0,0 +1,84 @@ +# Resound Small Build — Carrier PCB (KiCad bootstrap) + +A netlist-first hardware bootstrap for the **Resound** carrier PCB: one 45 x 45 mm +4-layer board built around an **ESP32-WROOM-32E**, with a 26-pin stacking bus, that +ships in two assembly variants — **SINK** and **BROADCASTER** — from the same layout. + +## What's here +| File | Purpose | +|------|---------| +| `resound-carrier.net` | KiCad S-expression netlist: every component (ref/value/**real KiCad footprint**) and every net with pin connections. The importable artifact. | +| `BOM.csv` | Bill of materials: Ref, Qty, Value, Footprint, MPN/JLCPCB, DNP, Notes. | +| `LAYOUT.md` | Board outline, 4-layer stackup, antenna keep-out, placement plan, mounting holes, JLCPCB design rules, and the SINK vs BROADCASTER variant table. | +| `README.md` | This file. | + +## Honest scope +A text agent cannot emit a guaranteed-openable `.kicad_pcb` with real geometry. So the +deliverable is a **complete, accurate, importable netlist + BOM + layout spec**. The +schematic is **not yet drawn** — this is a netlist-first workflow. An engineer imports +the netlist, lays out the board per `LAYOUT.md`, and (optionally) back-annotates a +schematic afterwards. + +## How to import into KiCad (8.x) + +### Option A — straight into the PCB editor (fastest, matches netlist-first) +1. New KiCad project. Open the **PCB Editor** (Pcbnew). +2. **File -> Import -> Netlist...** Select `resound-carrier.net`. +3. KiCad places all footprints (it resolves the library footprint names like + `RF_Module:ESP32-WROOM-32`, `Connector_PinHeader_2.54mm:PinHeader_2x13_P2.54mm_Vertical`, + `Resistor_SMD:R_0402_1005Metric`, `Package_TO_SOT_SMD:SOT-23`, etc. from the standard + KiCad footprint libraries — make sure those libs are installed/enabled). +4. Build the board outline on **Edge.Cuts** (45x45, rounded corners) and lay out per + `LAYOUT.md`. Add the antenna keep-out zones, GND/PWR plane pours, and mounting holes. +5. Run **DRC** with JLCPCB rules from `LAYOUT.md` section 6. + +### Option B — schematic-first (if you prefer drawing the schematic) +1. Use the netlist as the connectivity spec and draw the schematic in Eeschema, matching + refs/nets exactly, then **Update PCB from Schematic** (F8). The provided `.net` is the + single source of truth for which pin connects to which net. + +> Note: the `.net` uses KiCad's S-expression `(export ...)` netlist format with +> `(comp ...)` + `(net ...)` sections and per-component `(footprint ...)`. This is what +> "Import Netlist" consumes. The `(libparts)`/`(libraries)` blocks are intentionally empty +> (footprints are assigned directly on each component, which is sufficient for PCB import). + +## ESP32-WROOM-32E pad mapping used +The netlist references U1 by the standard KiCad `RF_Module:ESP32-WROOM-32` footprint pad +numbers 1..38 (+ EP on pad 38). Key assignments: +- GND = pads 1, 15, 38(EP) | 3V3 = pad 2 | EN = pad 3 +- I2C: SDA=GPIO32 (pad 8), SCL=GPIO33 (pad 9) +- I2S SINK: BCK=GPIO5 (pad 29), WS=GPIO25 (pad 10), DATA=GPIO23 (pad 37) +- I2S BCAST: BCK=GPIO19 (pad 31), WS=GPIO18 (pad 30), DATA=GPIO22 (pad 36) +- ADDR: GPIO13 (pad 16), GPIO14 (pad 13), GPIO27 (pad 12), GPIO26 (pad 11) +- UART bus: TX=GPIO17 (pad 28), RX=GPIO16 (pad 27) +- LED: DAT=GPIO21 (pad 33), CLK=GPIO4 (pad 26) *(reassigned — see caveats)* +- Prog UART0: RX/IO3=GPIO3 (pad 34), TX/IO1=GPIO1 (pad 35), IO0=pad 25 +**Verify this pad mapping against the exact footprint variant you load** before committing +copper, since some WROOM footprint variants renumber pads. + +## Known caveats / open items for the EE +1. **LED pin reuse (RESOLVE THIS).** The original spec note put the APA102 LED DATA on + GPIO13, but GPIO13 is already an **address strap** (ADDR0). To avoid the conflict the + netlist reassigns LED to spare pins: **LED_DAT = GPIO21, LED_CLK = GPIO4**. Confirm + these spares are truly free for your firmware and that GPIO4/GPIO21 have no strapping or + boot side-effects in your build. Adjust if needed — flagged intentionally. +2. **Antenna coupling across the stack.** Boards stack vertically; the WROOM antenna of a + lower board sits near the copper/components of the board above. Enforce the 15 mm + all-layer keep-out (LAYOUT.md §4) and consider stack spacing / antenna orientation so + the antenna of any board does not sit under metal of the neighbor. +3. **Verify HUD SH1.0 pin order.** J3 is keyed/genderable; confirm pin 1 of the chosen + SH1.0 connector and the HUD cable match the `1=+5V 2=GND 3=SDA 4=SCL 5=SPARE 6=NC` + order before fab. Easy to mirror. +4. **UART2 bus pins (J1 19/20)** are connector pass-through only on this rev — no MCU tap + is routed (the ESP32 second hardware UART pins are not broken out here). If a board + needs to drive UART2, the EE must route MCU spares to those connector pins. +5. **Auto-reset cross-bias.** The DTR/RTS auto-reset/boot circuit follows the NodeMCU + 2-transistor pattern; the base-resistor cross-bias nets (R8_BIAS->RTS, R9_BIAS->DTR) + prevent EN+IO0 asserting simultaneously. Sanity-check against your USB-serial adapter's + DTR/RTS polarity. +6. **I2S series terminators R1/R2/R3** are DNP by default (direct connection). Populate + 33R only if I2S signals ring across the stack. + +## Variants in one line +SINK = I2S jumpers JP1/JP2/JP3 + I2C pull-ups R4/R5 populated. BROADCASTER = I2S jumpers +JP4/JP5/JP6, pull-ups DNP. Address straps set per board. Full table in `LAYOUT.md` §7. diff --git a/hardware/carrier/resound-carrier.net b/hardware/carrier/resound-carrier.net new file mode 100644 index 0000000..67b7e2d --- /dev/null +++ b/hardware/carrier/resound-carrier.net @@ -0,0 +1,387 @@ +(export (version "E") + (design + (source "resound-carrier") + (date "2026-06-11") + (tool "blue-agent netlist-first bootstrap") + (sheet (number "1") (name "/") (tstamps "/") + (title_block + (title "Resound Small Build Carrier PCB") + (company "Resound") + (rev "A") + (date "2026-06-11") + (comment (number "1") (value "ONE board, two assembly variants: SINK / BROADCASTER")) + (comment (number "2") (value "ESP32-WROOM-32E carrier with 26-pin stacking bus")) + (comment (number "3") (value "Netlist-first: schematic still to be drawn. See README.md")) + (comment (number "4") (value "CAVEAT: LED_DAT/LED_CLK pin assignment to be confirmed by EE"))))) + + (components + ;; ---- MCU ---- + (comp (ref "U1") + (value "ESP32-WROOM-32E") + (footprint "RF_Module:ESP32-WROOM-32") + (datasheet "https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32e_esp32-wroom-32ue_datasheet_en.pdf") + (fields + (field (name "MPN") "ESP32-WROOM-32E") + (field (name "JLCPCB") "C701343")) + (tstamps "00000001")) + + ;; ---- Stacking connector (2x13 pass-through, top + bottom mirrored = same net per position) ---- + (comp (ref "J1") + (value "Stack_2x13") + (footprint "Connector_PinHeader_2.54mm:PinHeader_2x13_P2.54mm_Vertical") + (fields (field (name "Notes") "2.54mm 2x13 pass-through; mirror header on bottom shares nets")) + (tstamps "00000002")) + + ;; ---- Programming header 1x6 ---- + (comp (ref "J2") + (value "PROG_1x6") + (footprint "Connector_PinHeader_2.54mm:PinHeader_1x06_P2.54mm_Vertical") + (fields (field (name "Pinout") "1=GND 2=+5V 3=RX/IO3 4=TX/IO1 5=DTR 6=RTS")) + (tstamps "00000003")) + + ;; ---- HUD connector SH1.0 1x6 (TOP board only) ---- + (comp (ref "J3") + (value "HUD_SH1.0_1x6") + (footprint "Connector_JST:JST_SH_BM06B-SRSS-TB_1x06-1MP_P1.00mm_Vertical") + (fields + (field (name "Pinout") "1=+5V 2=GND 3=SDA 4=SCL 5=SPARE 6=NC") + (field (name "MPN") "BM06B-SRSS-TB") + (field (name "Notes") "Populate on TOP board only")) + (tstamps "00000004")) + + ;; ---- Auto reset/boot transistors ---- + (comp (ref "Q1") (value "MMBT3904") (footprint "Package_TO_SOT_SMD:SOT-23") + (fields (field (name "Func") "DTR->EN reset") (field (name "JLCPCB") "C20526")) (tstamps "00000005")) + (comp (ref "Q2") (value "MMBT3904") (footprint "Package_TO_SOT_SMD:SOT-23") + (fields (field (name "Func") "RTS->IO0 boot") (field (name "JLCPCB") "C20526")) (tstamps "00000006")) + + ;; ---- Tactile buttons ---- + (comp (ref "SW1") (value "EN/RESET") (footprint "Button_Switch_SMD:SW_SPST_PTS645") + (fields (field (name "Notes") "EN to GND")) (tstamps "00000007")) + (comp (ref "SW2") (value "BOOT/IO0") (footprint "Button_Switch_SMD:SW_SPST_PTS645") + (fields (field (name "Notes") "IO0 to GND")) (tstamps "00000008")) + + ;; ---- I2S role jumpers (0R, two columns) ---- + ;; SINK column + (comp (ref "JP1") (value "0R") (footprint "Resistor_SMD:R_0603_1608Metric") + (fields (field (name "Func") "I2S_BCK = GPIO5 (SINK)")) (tstamps "00000010")) + (comp (ref "JP2") (value "0R") (footprint "Resistor_SMD:R_0603_1608Metric") + (fields (field (name "Func") "I2S_WS = GPIO25 (SINK)")) (tstamps "00000011")) + (comp (ref "JP3") (value "0R") (footprint "Resistor_SMD:R_0603_1608Metric") + (fields (field (name "Func") "I2S_DATA = GPIO23 (SINK)")) (tstamps "00000012")) + ;; BROADCASTER column + (comp (ref "JP4") (value "0R") (footprint "Resistor_SMD:R_0603_1608Metric") + (fields (field (name "Func") "I2S_BCK = GPIO19 (BROADCASTER)")) (tstamps "00000013")) + (comp (ref "JP5") (value "0R") (footprint "Resistor_SMD:R_0603_1608Metric") + (fields (field (name "Func") "I2S_WS = GPIO18 (BROADCASTER)")) (tstamps "00000014")) + (comp (ref "JP6") (value "0R") (footprint "Resistor_SMD:R_0603_1608Metric") + (fields (field (name "Func") "I2S_DATA = GPIO22 (BROADCASTER)")) (tstamps "00000015")) + + ;; ---- I2S series termination (option) ---- + (comp (ref "R1") (value "33R") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "I2S_BCK series term") (field (name "DNP") "y")) (tstamps "00000020")) + (comp (ref "R2") (value "33R") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "I2S_WS series term") (field (name "DNP") "y")) (tstamps "00000021")) + (comp (ref "R3") (value "33R") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "I2S_DATA series term") (field (name "DNP") "y")) (tstamps "00000022")) + + ;; ---- I2C pull-ups (on every board, DNP except SINK) ---- + (comp (ref "R4") (value "4.7k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "SDA pull-up") (field (name "DNP") "y (populate on SINK only)")) (tstamps "00000023")) + (comp (ref "R5") (value "4.7k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "SCL pull-up") (field (name "DNP") "y (populate on SINK only)")) (tstamps "00000024")) + + ;; ---- Reset / boot RC + pull-ups ---- + (comp (ref "R6") (value "10k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "EN pull-up to 3V3")) (tstamps "00000025")) + (comp (ref "C1") (value "1uF") (footprint "Capacitor_SMD:C_0603_1608Metric") + (fields (field (name "Func") "EN to GND")) (tstamps "00000026")) + (comp (ref "R7") (value "10k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "IO0 pull-up to 3V3")) (tstamps "00000027")) + (comp (ref "C2") (value "100nF") (footprint "Capacitor_SMD:C_0402_1005Metric") + (fields (field (name "Func") "IO0 to GND")) (tstamps "00000028")) + + ;; ---- Auto reset/boot coupling caps + base resistors ---- + (comp (ref "C3") (value "100nF") (footprint "Capacitor_SMD:C_0402_1005Metric") + (fields (field (name "Func") "DTR coupling to Q1")) (tstamps "00000029")) + (comp (ref "C4") (value "100nF") (footprint "Capacitor_SMD:C_0402_1005Metric") + (fields (field (name "Func") "RTS coupling to Q2")) (tstamps "0000002A")) + (comp (ref "R8") (value "10k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "Q1 base series")) (tstamps "0000002B")) + (comp (ref "R9") (value "10k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "Q2 base series")) (tstamps "0000002C")) + + ;; ---- Address straps (GPIO13/14/27/26): 10k to 3V3 OR 0R to GND ---- + (comp (ref "R10") (value "10k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "ADDR0/GPIO13 -> 3V3 strap")) (tstamps "00000030")) + (comp (ref "R11") (value "0R") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "ADDR0/GPIO13 -> GND strap") (field (name "DNP") "y (pick one)")) (tstamps "00000031")) + (comp (ref "R12") (value "10k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "ADDR1/GPIO14 -> 3V3 strap")) (tstamps "00000032")) + (comp (ref "R13") (value "0R") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "ADDR1/GPIO14 -> GND strap") (field (name "DNP") "y (pick one)")) (tstamps "00000033")) + (comp (ref "R14") (value "10k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "ADDR2/GPIO27 -> 3V3 strap")) (tstamps "00000034")) + (comp (ref "R15") (value "0R") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "ADDR2/GPIO27 -> GND strap") (field (name "DNP") "y (pick one)")) (tstamps "00000035")) + (comp (ref "R16") (value "10k") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "ADDR3/GPIO26 -> 3V3 strap")) (tstamps "00000036")) + (comp (ref "R17") (value "0R") (footprint "Resistor_SMD:R_0402_1005Metric") + (fields (field (name "Func") "ADDR3/GPIO26 -> GND strap") (field (name "DNP") "y (pick one)")) (tstamps "00000037")) + + ;; ---- Decoupling ---- + (comp (ref "C5") (value "10uF") (footprint "Capacitor_SMD:C_0805_2012Metric") + (fields (field (name "Func") "3V3 bulk at WROOM pad")) (tstamps "00000040")) + (comp (ref "C6") (value "100nF") (footprint "Capacitor_SMD:C_0402_1005Metric") + (fields (field (name "Func") "3V3 decap at WROOM pad")) (tstamps "00000041")) + (comp (ref "C7") (value "100nF") (footprint "Capacitor_SMD:C_0402_1005Metric") + (fields (field (name "Func") "3V3 decap at WROOM pad")) (tstamps "00000042")) + (comp (ref "C8") (value "10uF") (footprint "Capacitor_SMD:C_0805_2012Metric") + (fields (field (name "Func") "+5V bulk at connector")) (tstamps "00000043")) + (comp (ref "C9") (value "22uF") (footprint "Capacitor_SMD:C_0805_2012Metric") + (fields (field (name "Func") "3V3 bulk rail")) (tstamps "00000044")) + + ;; ---- Mounting holes (M3) ---- + (comp (ref "H1") (value "MountingHole_M3") (footprint "MountingHole:MountingHole_3.2mm_M3") (tstamps "00000050")) + (comp (ref "H2") (value "MountingHole_M3") (footprint "MountingHole:MountingHole_3.2mm_M3") (tstamps "00000051")) + (comp (ref "H3") (value "MountingHole_M3") (footprint "MountingHole:MountingHole_3.2mm_M3") (tstamps "00000052")) + (comp (ref "H4") (value "MountingHole_M3") (footprint "MountingHole:MountingHole_3.2mm_M3") (tstamps "00000053"))) + + (libparts) + + (libraries) + + (nets + ;; ================= POWER ================= + (net (code "1") (name "+5V") + (node (ref "J1") (pin "1")) + (node (ref "J1") (pin "2")) + (node (ref "J2") (pin "2")) + (node (ref "J3") (pin "1")) + (node (ref "C8") (pin "1"))) + + (net (code "2") (name "+3V3") + (node (ref "U1") (pin "2")) + (node (ref "J1") (pin "5")) + (node (ref "J1") (pin "6")) + (node (ref "R4") (pin "1")) + (node (ref "R5") (pin "1")) + (node (ref "R6") (pin "1")) + (node (ref "R7") (pin "1")) + (node (ref "R10") (pin "1")) + (node (ref "R12") (pin "1")) + (node (ref "R14") (pin "1")) + (node (ref "R16") (pin "1")) + (node (ref "C5") (pin "1")) + (node (ref "C6") (pin "1")) + (node (ref "C7") (pin "1")) + (node (ref "C9") (pin "1"))) + + (net (code "3") (name "GND") + (node (ref "U1") (pin "1")) + (node (ref "U1") (pin "15")) + (node (ref "U1") (pin "38")) + (node (ref "J1") (pin "3")) + (node (ref "J1") (pin "4")) + (node (ref "J1") (pin "7")) + (node (ref "J1") (pin "9")) + (node (ref "J1") (pin "11")) + (node (ref "J1") (pin "13")) + (node (ref "J1") (pin "14")) + (node (ref "J1") (pin "26")) + (node (ref "J2") (pin "1")) + (node (ref "J3") (pin "2")) + (node (ref "C1") (pin "2")) + (node (ref "C2") (pin "2")) + (node (ref "C5") (pin "2")) + (node (ref "C6") (pin "2")) + (node (ref "C7") (pin "2")) + (node (ref "C8") (pin "2")) + (node (ref "C9") (pin "2")) + (node (ref "R11") (pin "2")) + (node (ref "R13") (pin "2")) + (node (ref "R15") (pin "2")) + (node (ref "R17") (pin "2")) + (node (ref "Q1") (pin "2")) + (node (ref "Q2") (pin "2")) + (node (ref "SW1") (pin "2")) + (node (ref "SW2") (pin "2")) + (node (ref "H1") (pin "1")) + (node (ref "H2") (pin "1")) + (node (ref "H3") (pin "1")) + (node (ref "H4") (pin "1"))) + + ;; ================= RESET / BOOT ================= + ;; EN: WROOM pin3, pull-up R6, cap C1, button SW1, reset transistor Q1 collector + (net (code "4") (name "EN") + (node (ref "U1") (pin "3")) + (node (ref "R6") (pin "2")) + (node (ref "C1") (pin "1")) + (node (ref "SW1") (pin "1")) + (node (ref "Q1") (pin "3"))) + + ;; IO0: WROOM pin25 (GPIO0), pull-up R7, cap C2, button SW2, boot transistor Q2 collector + (net (code "5") (name "IO0") + (node (ref "U1") (pin "25")) + (node (ref "R7") (pin "2")) + (node (ref "C2") (pin "1")) + (node (ref "SW2") (pin "1")) + (node (ref "Q2") (pin "3"))) + + ;; ================= PROGRAMMING UART0 + AUTO RESET/BOOT ================= + ;; UART0 RX into ESP = GPIO3 (pad34); prog header pin3 labelled RX (host TX -> ESP RX/IO3) + (net (code "6") (name "IO3_RXD0") + (node (ref "U1") (pin "34")) + (node (ref "J2") (pin "3"))) + ;; UART0 TX out of ESP = GPIO1 (pad35); prog header pin4 labelled TX (ESP TX/IO1 -> host RX) + (net (code "7") (name "IO1_TXD0") + (node (ref "U1") (pin "35")) + (node (ref "J2") (pin "4"))) + + ;; DTR -> C3 -> Q1 base via R8 (reset) + (net (code "8") (name "DTR") + (node (ref "J2") (pin "5")) + (node (ref "C3") (pin "1"))) + (net (code "9") (name "Q1_BASE") + (node (ref "C3") (pin "2")) + (node (ref "R8") (pin "1")) + (node (ref "Q1") (pin "1"))) + ;; RTS -> C4 -> Q2 base via R9 (boot) + (net (code "10") (name "RTS") + (node (ref "J2") (pin "6")) + (node (ref "C4") (pin "1"))) + (net (code "11") (name "Q2_BASE") + (node (ref "C4") (pin "2")) + (node (ref "R9") (pin "1")) + (node (ref "Q2") (pin "1"))) + ;; Base resistors pull the bases; classic NodeMCU auto-reset cross-couples R8 to RTS-side and + ;; R9 to DTR-side so simultaneous DTR+RTS does not assert. Implemented as cross bias below. + (net (code "12") (name "R8_BIAS") + (node (ref "R8") (pin "2")) + (node (ref "J2") (pin "6"))) + (net (code "13") (name "R9_BIAS") + (node (ref "R9") (pin "2")) + (node (ref "J2") (pin "5"))) + + ;; ================= I2S ROLE JUMPER FIELD ================= + ;; ESP source pins feed jumper input side; jumper output side ties to the I2S bus net. + ;; SINK col: GPIO5=BCK(pad29), GPIO25=WS(pad10), GPIO23=DATA(pad37) + ;; BCAST col: GPIO19=BCK(pad31), GPIO18=WS(pad30), GPIO22=DATA(pad36) + (net (code "20") (name "GPIO5") + (node (ref "U1") (pin "29")) + (node (ref "JP1") (pin "1"))) + (net (code "21") (name "GPIO25") + (node (ref "U1") (pin "10")) + (node (ref "JP2") (pin "1"))) + (net (code "22") (name "GPIO23") + (node (ref "U1") (pin "37")) + (node (ref "JP3") (pin "1"))) + (net (code "23") (name "GPIO19") + (node (ref "U1") (pin "31")) + (node (ref "JP4") (pin "1"))) + (net (code "24") (name "GPIO18") + (node (ref "U1") (pin "30")) + (node (ref "JP5") (pin "1"))) + (net (code "25") (name "GPIO22") + (node (ref "U1") (pin "36")) + (node (ref "JP6") (pin "1"))) + + ;; I2S bus nets: jumper outputs from BOTH columns land on the same bus node, + ;; then through optional series term R1/R2/R3 to the stacking connector. + (net (code "26") (name "I2S_BCK_PRE") + (node (ref "JP1") (pin "2")) + (node (ref "JP4") (pin "2")) + (node (ref "R1") (pin "1"))) + (net (code "27") (name "I2S_BCK") + (node (ref "R1") (pin "2")) + (node (ref "J1") (pin "8"))) + (net (code "28") (name "I2S_WS_PRE") + (node (ref "JP2") (pin "2")) + (node (ref "JP5") (pin "2")) + (node (ref "R2") (pin "1"))) + (net (code "29") (name "I2S_WS") + (node (ref "R2") (pin "2")) + (node (ref "J1") (pin "10"))) + (net (code "30") (name "I2S_DATA_PRE") + (node (ref "JP3") (pin "2")) + (node (ref "JP6") (pin "2")) + (node (ref "R3") (pin "1"))) + (net (code "31") (name "I2S_DATA") + (node (ref "R3") (pin "2")) + (node (ref "J1") (pin "12"))) + + ;; ================= I2C ================= + ;; GPIO32=SDA(pad8), GPIO33=SCL(pad9) + (net (code "40") (name "I2C_SDA") + (node (ref "U1") (pin "8")) + (node (ref "R4") (pin "2")) + (node (ref "J1") (pin "15")) + (node (ref "J3") (pin "3"))) + (net (code "41") (name "I2C_SCL") + (node (ref "U1") (pin "9")) + (node (ref "R5") (pin "2")) + (node (ref "J1") (pin "16")) + (node (ref "J3") (pin "4"))) + + ;; ================= UART (bus, GPIO17=TX pad28 / GPIO16=RX pad27) ================= + (net (code "50") (name "UART_TX") + (node (ref "U1") (pin "28")) + (node (ref "J1") (pin "17"))) + (net (code "51") (name "UART_RX") + (node (ref "U1") (pin "27")) + (node (ref "J1") (pin "18"))) + + ;; ================= UART2 second bus pair (19,20 on connector) ================= + ;; No dedicated second hardware UART pins routed from MCU on this rev; bus pass-through + ;; for daisy-chained boards. Left as connector-only nets (flag for EE if MCU tap needed). + (net (code "52") (name "UART2_TX") + (node (ref "J1") (pin "19"))) + (net (code "53") (name "UART2_RX") + (node (ref "J1") (pin "20"))) + + ;; ================= LED (APA102) ================= + ;; CAVEAT: original note said GPIO13 but GPIO13 is an ADDR strap. Reassigned to spare GPIOs: + ;; LED_DAT = GPIO21 (pad33), LED_CLK = GPIO4 (pad26). EE to confirm. + (net (code "60") (name "LED_DAT") + (node (ref "U1") (pin "33")) + (node (ref "J1") (pin "21"))) + (net (code "61") (name "LED_CLK") + (node (ref "U1") (pin "26")) + (node (ref "J1") (pin "22"))) + + ;; ================= ADDRESS STRAPS ================= + ;; Each GPIO -> two strap pads: R(10k) to 3V3 OR R(0R) to GND. Populate exactly one. + ;; ADDR0 GPIO13 = pad16 + (net (code "70") (name "ADDR0_GPIO13") + (node (ref "U1") (pin "16")) + (node (ref "R10") (pin "2")) + (node (ref "R11") (pin "1"))) + ;; ADDR1 GPIO14 = pad13 + (net (code "71") (name "ADDR1_GPIO14") + (node (ref "U1") (pin "13")) + (node (ref "R12") (pin "2")) + (node (ref "R13") (pin "1"))) + ;; ADDR2 GPIO27 = pad12 + (net (code "72") (name "ADDR2_GPIO27") + (node (ref "U1") (pin "12")) + (node (ref "R14") (pin "2")) + (node (ref "R15") (pin "1"))) + ;; ADDR3 GPIO26 = pad11 + (net (code "73") (name "ADDR3_GPIO26") + (node (ref "U1") (pin "11")) + (node (ref "R16") (pin "2")) + (node (ref "R17") (pin "1"))) + + ;; ================= ADDR CHAIN (connector pass-through 23/24) ================= + (net (code "74") (name "ADDR_CHAIN_IN") + (node (ref "J1") (pin "23"))) + (net (code "75") (name "ADDR_CHAIN_OUT") + (node (ref "J1") (pin "24"))) + + ;; ================= SPARE ================= + (net (code "80") (name "SPARE_CONN25") + (node (ref "J1") (pin "25")) + (node (ref "J3") (pin "5"))) + ;; J3 pin6 = NC (HUD), intentionally unconnected + ) +)