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) <noreply@anthropic.com>
This commit is contained in:
blue — ESP32/PlatformIO firmware 2026-06-11 15:10:15 -04:00
parent b5d1169392
commit 2c6e7e8762
4 changed files with 645 additions and 0 deletions

45
hardware/carrier/BOM.csv Normal file
View File

@ -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
Can't render this file because it has a wrong number of fields in line 42.

129
hardware/carrier/LAYOUT.md Normal file
View File

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

View File

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

View File

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