Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 26 additions & 24 deletions HANDOVER.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ Written 2026-07-16, last refreshed 2026-10-06 for the next agent (or future
session) continuing this project. Read this + README.md before touching anything.
**All four boards are routed with 0 unconnected and 0 DRC errors**, v0.1.0
was released from `master` on 2026-09-29, and the manager L2 / backplane C2
part change (PR #16) landed on `development` on 2026-10-06. What stands
between the project and the first order is the owner's pick on the BOM
`CHECK:` rows and the gates under "Immediate next steps".
part change (PR #16) landed on `development` on 2026-10-06. On 2026-10-06
the phase-1/phase-2 L2 moved to the manager's 5 × 5 mm land and the last
BOM `CHECK:` rows were closed, so no `CHECK:` row is left in any BOM. What
stands between the project and the first order is the gates under
"Immediate next steps".

## The user & working agreement

Expand Down Expand Up @@ -48,9 +50,9 @@ manager, CAN 2.0B @500k. Docs 01–07 are the spec; read 05 (build plan) first
| Design docs 01–07 | complete (07 = module firmware, new) |
| Phase-1 schematic | **complete, v1**: 7 generated sheets, 137 components, ~90 nets machine-verified; audited (kicad-happy + ngspice 38/40 pass) |
| Footprints | all vetted; custom lib `labbench.pretty` (LM5145 RGY, LMR36015 RNX, DAC80502 no-EP WSON, PowerFET_SON5x6_GDS) |
| PCB — Phase 1 | **100 × 80 mm, routed, 0 unconnected, 0 DRC errors** (2026-09-27, PR #9, merged; the 120 × 80 layout it replaces is kept on branch `phase1-120x80`). Re-placed from the netlist, so L1 now has the 17 mm MWSA1707S/XAL1510 superset land and U7 the SC-70-5 land the BOM orders (the 120 × 80 board still carried XAL1350 and SOT-23-5 lands: do not order it). Output bank tightened round the bigger L1; R30 Kelvin shunt, U4/U5 and their sense traces moved as one block with the same geometry; Q3/Q4, J4 and the LTC7004 stack down the right edge. Pipeline: pass-1 + `fanout.py` + Freerouting 1.9 + `finish_routes.py`; 1303 tracks / 353 vias. DRC = 11 silk *warnings*. Fab zip + CPL regenerated. 2026-09-28 (PR #13): OVP_TRIP routed to U10 PB4 for the firmware 0.2 OVP latch |
| PCB — Phase 1 | **100 × 80 mm, routed, 0 unconnected, 0 DRC errors** (2026-09-27, PR #9, merged; the 120 × 80 layout it replaces is kept on branch `phase1-120x80`). Re-placed from the netlist, so L1 now has the 17 mm MWSA1707S/XAL1510 superset land and U7 the SC-70-5 land the BOM orders (the 120 × 80 board still carried XAL1350 and SOT-23-5 lands: do not order it). Output bank tightened round the bigger L1; R30 Kelvin shunt, U4/U5 and their sense traces moved as one block with the same geometry; Q3/Q4, J4 and the LTC7004 stack down the right edge. Pipeline: pass-1 + `fanout.py` + Freerouting 1.9 + `finish_routes.py`; 1303 tracks / 353 vias. DRC = 11 silk *warnings*. Fab zip + CPL regenerated. 2026-09-28 (PR #13): OVP_TRIP routed to U10 PB4 for the firmware 0.2 OVP latch. **ECO 2026-10-06:** L2 1210 → 5×5 mm FNR5040S at (32.6, 61.25), SW_AUX stub re-ended on the new pad, a 0.4 mm F.Cu 5V0 link added from L2's via to C54's; C20/C75–C77 value now 10u/50V. DRC unchanged (10 silk warnings) |
| PCB — Phase 3 backplane | **FAB-READY (2026-07-26, d9e1a7b)**: 0 DRC, 0 unconnected, silk 39/39 clean, no plane islands. Gerbers+drills in `fab/` (gitignored) via `python3 ../common/finish_board.py phase3-backplane.kicad_pcb`. Cross-checked: Edge_Cuts exactly 330.00×100.00 mm; drills 2×6.4 (M6 lugs), 16×2.8 (8 slots × 2 XT60 pins), 6×3.2 (M3), 86×1.0, 61×0.4. **Still gated on the XT60 polarity buzz-out before ordering** |
| PCB — Phase 2 | **130 × 90 mm, routed, 0 unconnected, 0 DRC errors (2026-09-27, PR #11, merged 2026-09-28)**; fab zip + CPL committed; pre-order review closed (see the resume section). The 83-unconnected history is kept below for its tooling notes |
| PCB — Phase 2 | **130 × 90 mm, routed, 0 unconnected, 0 DRC errors (2026-09-27, PR #11, merged 2026-09-28)**; fab zip + CPL committed; pre-order review closed (see the resume section). **ECO 2026-10-06:** L2 1210 → 5×5 mm FNR5040S at (68.4, 57.45) r270; its SW_AUX and 5V0 vias now sit in its pads, a 5V0 stub ties C55's via to L2. DRC unchanged (19 warnings, 0 errors). The 83-unconnected history is kept below for its tooling notes |
| PCB — Phase 3 manager | **Routed, 0 unconnected, 0 DRC errors (2026-09-27, merged into `development`)**: placement reworked (15+ passives had been placed by stale refdes, far from their pins; U8 buck re-laid tight round its pinout; U11 turned so CAN faces J1; U12 in the USB path), PGND now poured on both layers (was F.Cu 3V3 / B.Cu PGND), USB + CAN pairs and buck power copper hand-drawn and locked (`route_critical.py`), rest Freerouting 1.9 + `finish_routes.py`, 283 PGND stitch vias. DRC = 5 warnings (4 silk, 1 U8 courtyard-override lib mismatch). Antenna keep-out copper-free. Pipeline: `phase3-manager/tools/README.md`. **ECO 2026-10-05:** L2 moved from the 1210 land (no stocked 33 µH above 0.5 A) to a 5×5 mm FNR5040S (FNR5040S330MT, Isat 1.3 A); C54/C55 turned 180° so 5V0 runs straight from L2; PRESENT1/4–7 re-routed round the bigger part with `finish_routes.py`. Still 0 unconnected, 0 DRC errors, 4 warnings (PR #16, merged 2026-10-06; fab zip, BOM and CPL regenerated) |
| Module firmware | v0.2 builds clean (7.1 KB): full peripheral binding + CAN dispatch around the host-tested `module_core`. 0.2 (2026-09-28) closes the two protection gaps from the bench-test review: OCP backup #2 (`lb_core_ocp_sample`: INA240 ADC or INA228 SOVL alert >110 % i_max for >5 ms) and OVP latch #4 (OVP_TRIP routed to PB4 on the 100 × 80 board; EXTI4 kills EN, tick latches). Untested on silicon (no board yet) |
| Host tests | `cd firmware/tests && make test` — must stay green. **5 suites now**: can, core, manager, scpi, ui |
Expand Down Expand Up @@ -217,29 +219,28 @@ Notable route_board facts a future session needs:

## Immediate next steps (agreed order)

1. **Owner picks the five BOM `CHECK:` rows** (state 2026-10-06; the
notes in the BOM CSVs say what each one needs):
- Phase-1 C20/C75–C77: no 22 µF 50 V 1210 stocked, 10 µF 50 V fitted
(input ceramic drops from 88 to 40 µF; C21 is the bulk).
- Phase-1 L2: 33 µH on a 1210 land, the strongest stocked part is 0.5 A
against a 1.2 A value. Fine only if 5V0 stays well under ~0.4 A.
- Phase-1 Q1/Q2 and Q3/Q4: NTMFS5C670NLT1G stands in for the
out-of-stock CSD18563Q5A (same S-S-S-G / tab pinout); confirm the pad
overlay in the JLCPCB preview.
- Phase-2 U3: symbol says LM5143RHAR, the BOM orders the cheaper
LM5143QRHARQ1; confirm the RHA0040P land against the Q1 addendum.
2. **Open: Phase-1 and Phase-2 L2 still sit on 1210 lands** (phase-2 L2
has no LCSC number yet). The manager had the same problem and was fixed
by moving to the 5 × 5 mm FNR5040S land as an ECO (PR #16); the same
change was offered for phase-1/2 and waits on the owner's call.
1. **BOM `CHECK:` rows: all closed 2026-10-06** (stock checked that day):
- Phase-1 C20/C75–C77: no 22 µF 50 V 1210 is stocked anywhere, so the
design value is now 10 µF 50 V X7R (GRM32ER71H106KA12L). About 0.3 Vpp
input ripple at 8 A, D = 0.5, 350 kHz; ~1 A RMS per cap; C21 is the bulk.
- Phase-1 and phase-2 L2: moved to the manager's 5 × 5 mm FNR5040S land
(FNR5040S330MT, C167973, Isat 1.3 A) as an ECO on both routed boards.
- Phase-1 Q1–Q4: CSD18563Q5A is still out of stock; NTMFS5C670NLT1G
stays. Its case 488AA terminals sit within 0.14 mm of the TI part's on
the TI Q5A land, with more clearance to the drain land (0.35 vs 0.24 mm).
- Phase-2 U3: LM5143QRHARQ1 is the LM5143A-Q1. Same pin map, and its
RHA0040N land equals RHA0040P (EP 3.3, 0.5 pitch, 5.8 span); only
wettable flanks differ. It now costs $6.29 (243 at LCSC).
2. **Thin stock (2026-10-06):** INA228AQDGSRQ1 has **5** at LCSC/JLCPCB
(the AIDGSR has 0): one per module plus the backplane, so buy them
first or from Mouser/DigiKey. LTC7004EMSE has 25 (now $11.62).
3. **Order files**: `python3 common/bom.py` (from `hardware/`) writes hidden
LCSC/MPN/Manufacturer properties into the schematics (surgical, additive
only) and emits `<board>/bom/*-bom.csv` + `*-jlcpcb.csv`;
`common/cpl.py` writes the placement files. The part table is
`common/lcsc_parts.py`; `--check` fails if anything is stale. Still
open: generic R/C/jellybean/header numbers. The manager and backplane
order files bundled with the v0.1.0 release predate PR #16: regenerate
them from `development` before ordering those two boards.
open: generic R/C/jellybean/header numbers. The v0.1.0 release order
files are superseded; use the v0.2.0 set.
4. Review notes that still hold at order time: manager J3 is the GCT
USB4105-GF-A (C3020560; JLCPCB assembly stock, backup -120 C5184243);
13 manager nets cross under the USB pair on B.Cu (fine at full speed).
Expand All @@ -254,7 +255,8 @@ Notable route_board facts a future session needs:
- **XT60 polarity continuity check** (MECHANICAL.md — verify J1 male vs
backplane J-female in the *mated* orientation; the footprint descr still
says pads 1/2 are ASSUMED +/−).
- **Re-verify LCSC stock** of the order-early parts (LTC7004, CSD19536KTT).
- **Re-verify LCSC stock** of the order-early parts (INA228AQDGSRQ1,
LTC7004, CSD19536KTT).
- **Manager board only: confirm the fab quotes 0.2 mm drilling** on a 2-layer
stackup — the board rule was relaxed from 0.3 to 0.2 for the stock ESP32
footprint's thermal-pad stitching, and that is above some cheapest-process
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ module. v0.1.0 was released from `master` on 2026-09-29.
| Area | State |
|---|---|
| Design docs | Complete: 01–10, plus the build guide (11) and Phase-1 bench test procedure (12) |
| Phase-1 module (150 W) | 100 × 80 mm, **routed, 0 unconnected, 0 DRC errors**, fab zip and CPL committed. OVP_TRIP routed to the MCU (PB4) for the firmware 0.2 OVP latch. Next: the owner picks the four Phase-1 BOM `CHECK:` rows, then order and run [docs/12](docs/12-phase1-bench-tests.md). The older 120 × 80 layout on branch `phase1-120x80` has wrong L1/U7 lands: do not order it |
| Phase-2 module (600 W) | 130 × 90 mm, **routed, 0 unconnected, 0 DRC errors**, fab zip and CPL committed; pre-order review closed (HANDOVER) |
| Phase-1 module (150 W) | 100 × 80 mm, **routed, 0 unconnected, 0 DRC errors**, fab zip and CPL committed. OVP_TRIP routed to the MCU (PB4) for the firmware 0.2 OVP latch. L2 moved to a 5 × 5 mm land (2026-10-06). Next: order and run [docs/12](docs/12-phase1-bench-tests.md). The older 120 × 80 layout on branch `phase1-120x80` has wrong L1/U7 lands: do not order it |
| Phase-2 module (600 W) | 130 × 90 mm, **routed, 0 unconnected, 0 DRC errors**, fab zip and CPL committed; pre-order review closed (HANDOVER); L2 moved to a 5 × 5 mm land (2026-10-06) |
| Phase-3 backplane | 330 × 100 mm, fab-ready; gated on the XT60 polarity buzz-out ([MECHANICAL.md](hardware/MECHANICAL.md)) |
| Phase-3 manager | 100 × 80 mm, **routed, 0 unconnected, 0 DRC errors**; L2 moved to a 5 × 5 mm land (2026-10-05) |
| Module firmware | v0.2 builds (~7 KB, bare-metal STM32G431) with the OCP backup and OVP latch; control core host-tested |
| Manager firmware | v0.2 builds on ESP-IDF 5.3.2; manager, SCPI and UI cores host-tested |
| BOM / sourcing | LCSC numbers in the schematics and per-board BOM and CPL files (`hardware/common/bom.py`); five `CHECK:` rows await the owner's pick (four Phase-1, one Phase-2); generic R/C parts not yet numbered |
| BOM / sourcing | LCSC numbers in the schematics and per-board BOM and CPL files (`hardware/common/bom.py`); no `CHECK:` rows left (closed 2026-10-06); INA228 stock is thin (5 at LCSC); generic R/C parts not yet numbered |
| CI | GitHub Actions: host tests, module and manager firmware builds on every PR |

Complete Phase-1 build (parts, five PCBs, stencil, shipping) ≈ US$100–125.
Expand Down
6 changes: 4 additions & 2 deletions docs/06-phase1-circuit-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ e.g. Würth 744325550 class.
Ripple ≈ ESR·ΔI ≈ 7.5 mΩ · 1.7 A ≈ 13 mVpp ✓.
LC corner: f_LC = 1/(2π√(10 µH · ~480 µF)) ≈ **2.3 kHz**;
ESR zero ≈ 1/(2π·7.5 mΩ·440 µF) ≈ **48 kHz** — both needed for compensation (§6).
- **Input:** 4 × 22 µF 50 V X7R close to the FETs (input RMS ripple ≈ I_out/2 = 4 A
at D = 0.5) + 220 µF 50 V electrolytic bulk.
- **Input:** 4 × 10 µF 50 V X7R close to the FETs (input RMS ripple ≈ I_out/2 = 4 A
at D = 0.5, ~1 A per cap) + 220 µF 50 V electrolytic bulk. 22 µF 50 V 1210 is
not stocked; at 30 V bias each 10 µF keeps ~4.5 µF, so ΔV ≈ 8 A · 0.25 /
(350 kHz · 18 µF) ≈ 0.3 Vpp at the worst duty cycle.
- **Preload:** 2.2 kΩ across the output — gives DEM mode a minimum load so the
output doesn't drift up at zero load, and discharges the caps when disabled.

Expand Down
22 changes: 10 additions & 12 deletions docs/11-build-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ takes over and checks that it actually meets the spec.

| Board | What it is | Can you order it? |
|---|---|---|
| **Phase-1 module** (`hardware/phase1-module/`) | Single 150 W channel: 24 V in, 0–20 V / 0–8 A out, CAN controlled | **Yes, once the parts in §3.3 are settled.** Order the 100 × 80 board on `development`/`master`; the 120 × 80 layout on branch `phase1-120x80` has wrong L1/U7 lands |
| Phase-2 module (`hardware/phase2-module/`) | 600 W channel, 0–28 V / 0–30 A, hot-swap input | Routed and fab-ready (2026-09-27). Wait for Phase-1 to pass its bench tests (docs/05 exit criteria) and settle the U3 `CHECK:` row |
| **Phase-1 module** (`hardware/phase1-module/`) | Single 150 W channel: 24 V in, 0–20 V / 0–8 A out, CAN controlled | **Yes.** Check the parts in §3.3, then order the 100 × 80 board on `development`/`master`; the 120 × 80 layout on branch `phase1-120x80` has wrong L1/U7 lands |
| Phase-2 module (`hardware/phase2-module/`) | 600 W channel, 0–28 V / 0–30 A, hot-swap input | Routed and fab-ready (2026-09-27). Wait for Phase-1 to pass its bench tests (docs/05 exit criteria) |
| Phase-3 backplane (`hardware/phase3-backplane/`) | 8-slot bus with CAN, E-stop and bus metering | Fab-ready, but gated on the XT60 polarity check and only useful with Phase-2 modules and a manager |
| Phase-3 manager (`hardware/phase3-manager/`) | ESP32-S3 with display, encoder, USB SCPI | Routed and fab-ready. Confirm the fab quotes 0.2 mm drilling on 2 layers; regenerate the order files if yours predate 2026-10-06 (L2 changed) |
| Phase-3 manager (`hardware/phase3-manager/`) | ESP32-S3 with display, encoder, USB SCPI | Routed and fab-ready. Confirm the fab quotes 0.2 mm drilling on 2 layers; use the v0.2.0 order files or newer (L2 changed 2026-10-05) |

So today this guide is about the **Phase-1 module**. It is the "learning
board": every risky part of the design (analog CV/CC loops, sensing,
Expand Down Expand Up @@ -126,13 +126,11 @@ tolerance matters in a few places:

| Item | What to decide |
|---|---|
| **Q1–Q4 (power and disconnect FETs)** | The CSD18563Q5A was out of stock on 2026-09-27; the BOM orders onsemi NTMFS5C670NLT1G (60 V, 6.1 mΩ, Qg 20 nC) with the same S-S-S-G / tab pinout. Confirm the pad overlay in the JLCPCB preview, or buy CSD18563Q5A if it is back |
| **C20, C75–C77 (input ceramics)** | No 22 µF 50 V 1210 is stocked; the BOM orders 10 µF 50 V, which drops the input ceramic from 88 to 40 µF (C21 is the bulk). Accept it or source 22 µF elsewhere |
| **L2 (5V0 aux buck inductor)** | The 1210 land only takes 33 µH parts rated about 0.5 A; the value asks for 1.2 A. Fine if the 5V0 load (fan included) stays well under ~0.4 A. A bigger 5 × 5 mm land, as on the manager, is an open option |
| **Q1–Q4 (power and disconnect FETs)** | The CSD18563Q5A is out of stock (2026-10-06); the BOM orders onsemi NTMFS5C670NLT1G (60 V, 6.1 mΩ, Qg 20 nC), same S-S-S-G / tab pinout, overlay on the land checked. If the CSD18563Q5A is back, either part fits |
| **R30 (2 mΩ shunt)** | The LCSC part (C2994640) is cheap but its TCR is unverified. The CC accuracy depends on it. A Vishay WSLP-class part (~US$1.50) is the safe choice |
| **U8, U11 variants** | The LCSC variants (LMR36015ARNXR, TCAN1042VDRQ1) differ from the symbol values. Both are the right function (adjustable buck, VIO-capable CAN transceiver) in the same package |
| **J1, J4 terminal blocks** | The footprint is a 5.0 mm Phoenix PT; SOURCING.md lists 5.08 mm 2EDG plugs. Buy a header that matches the 5.0 mm footprint |
| **Order-early parts** | LTC7004EMSE had only 5 in stock at LCSC. Put it in the cart first |
| **Order-early parts** | INA228AQDGSRQ1 had 5 and LTC7004EMSE 25 in stock at LCSC (2026-10-06). Put them in the cart first |

## 4. Assemble

Expand Down Expand Up @@ -179,7 +177,7 @@ is cheap; a short at 24 V is not.
| J2 SWD | 1 = 3V3, 2 = SWDIO, 3 = SWCLK, 4 = NRST, 5 = GND | See the note on pin 1 below |
| J3 UART | 1 = GND, 2 = TX (from MCU), 3 = RX (to MCU) | 115200 8N1, 3.3 V |
| J5 BACKPLANE | 1 = CAN_H, 2 = CAN_L, 3 = HW_EN, 4–6 = SLOT_ID0–2, 7–8 = PGND | The bench harness plugs in here |
| J6 FAN | 1 = +5 V, 2 = fan return (switched low side) | Small 5 V fan; keep it under ~200 mA. The 5 V rail is sized for 0.5 A total, and the 1210 L2 the BOM fits is rated about 0.5 A, so keep the whole 5V0 load under ~0.4 A (§3.3) |
| J6 FAN | 1 = +5 V, 2 = fan return (switched low side) | Small 5 V fan; keep it under ~200 mA. The 5 V rail is sized for 0.5 A total; L2 (FNR5040S330MT) is rated 1.2 A, so the converter, not the inductor, sets that limit |

**J2 pin 1:** a genuine ST-Link only senses target voltage on this pin. Many
clone ST-Link V2 dongles *drive* 3.3 V onto it, which then fights the board's
Expand Down Expand Up @@ -270,14 +268,14 @@ ADC sampling on the high-impedance V_MEAS divider, then the DAC80502 gain.
aux and MCU blocks, with a 2-phase LM5143 power stage and LM5069 hot-swap
input. Its assembly is the same as above plus heavier soldering on the power
stage. The board is routed and the 220 µF caps are settled (EEHZA1V221P);
the one open BOM item is the LM5143 Q1-variant land check (U3), plus the
1210 L2 question that Phase-1 has too.
the LM5143 Q1 variant (U3) was checked against its land on 2026-10-06, and
L2 moved to a 5 × 5 mm land like Phase-1's.
- **Phase-3 backplane and manager** turn modules into a rack. Before ordering
the backplane, mate one XT60PW-M/F pair and buzz out which pad connects to
which, and which cavity is marked "+" ([hardware/MECHANICAL.md](../hardware/MECHANICAL.md)).
Pads 1 = + on both sides is still an assumption. The manager board is
routed; its order files changed on 2026-10-06 (L2 on a 5 × 5 mm land), so
use ones generated from `development` or later. The manager firmware builds
routed; its order files changed on 2026-10-05 (L2 on a 5 × 5 mm land), so
use the v0.2.0 set or newer. The manager firmware builds
in CI (`firmware/manager/idf`, ESP-IDF 5.3.2); its bring-up knobs are in
[docs/10](10-manager-firmware.md).

Expand Down
Loading
Loading