Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
4f7fbd2
Phase-1 board: fix the three routing review items
claude Sep 27, 2026
d3b8426
CI: also run on pushes to the development branch
claude Sep 27, 2026
3c53a8f
Merge pull request #6 from udaravima/claude/add-ci-u5o7ik
udaravima Sep 27, 2026
2b43f11
Add build guide, Phase-1 bench test procedure and CAN bench helper; r…
claude Sep 27, 2026
db501c4
Phase-1: JLCPCB pick-and-place (CPL) file
claude Sep 27, 2026
93ae562
Merge pull request #7 from udaravima/claude/build-guide-bench-tests-5…
udaravima Sep 27, 2026
300db85
Phase-1 BOM: Q3/Q4 part, hand-solder notes
claude Sep 27, 2026
46ed89f
Phase-1 BOM: LCSC numbers for every assembled part
claude Sep 27, 2026
c02b058
Merge pull request #5 from udaravima/claude/project-thread-nojoms
udaravima Sep 27, 2026
fdd8de3
Route the phase-3 manager board: 0 unconnected, 0 DRC errors
claude Sep 27, 2026
6793f24
Merge pull request #8 from udaravima/claude/route-manager-shxsg1
udaravima Sep 27, 2026
f40b561
Phase-1 100x80 (WIP): re-place output section around the 17 mm L1 land
claude Sep 27, 2026
8f4fd40
Phase-1 100x80 (WIP): turn U6 so gate/source/BST pins face their parts
claude Sep 27, 2026
87a7b6c
Phase-1 board: 100 x 80 mm, re-routed with the BOM's L1 and U7 lands
claude Sep 27, 2026
de0aeeb
HANDOVER: drop the stale FB-run spacing claim after the re-route
claude Sep 27, 2026
da54069
Phase-1: keep the FB sense run 5.5 mm from SW copper
claude Sep 27, 2026
1c278d9
Merge pull request #9 from udaravima/claude/phase1-100x80
udaravima Sep 27, 2026
da9b40a
Fix manager ENC1, F1 and BZ1 part numbers to fit their existing lands
claude Sep 27, 2026
2a8be29
phase2: rework LM5143 corner and port the phase-1 routing tools
claude Sep 27, 2026
a079113
phase2: hand routes for U3 bottom row, U4 analog ground, output-cap vias
claude Sep 27, 2026
f05d46e
Merge development into claude/project-thread-s19qi4
claude Sep 27, 2026
12f77b6
Merge pull request #10 from udaravima/claude/project-thread-s19qi4
udaravima Sep 27, 2026
159649c
phase2: route VOUT2 and COMP2 inside U3's pad ring, free RT1
claude Sep 27, 2026
8d26af4
phase2 finish_routes: keep routes 0.85 mm off the board edge
claude Sep 27, 2026
685c0e0
phase2: finish routing (0 unconnected, 0 DRC errors) and generate fab…
claude Sep 27, 2026
1b0288c
Merge remote-tracking branch 'origin/development' into claude/route-p…
claude Sep 27, 2026
64eb20b
Manager J3: order the GCT USB4105-GF-A that the board is routed for
claude Sep 28, 2026
ec9d716
BOM: stocked INA228 grade and 10x10 hybrid caps for phase-2
claude Sep 28, 2026
17f670f
HANDOVER: close the phase-2 pre-order review points
claude Sep 28, 2026
7a9bf53
Merge pull request #12 from udaravima/claude/release-prep-x5qsbu
udaravima Sep 28, 2026
30aa97e
Merge pull request #11 from udaravima/claude/route-phase2-6bjwyi
udaravima Sep 28, 2026
ae55484
Module firmware 0.2: OCP backup and OVP latch (protection rows 2 and 4)
claude Sep 28, 2026
a508d01
Phase-1 board: route OVP_TRIP to MCU PB4 so the OVP trip can latch
claude Sep 28, 2026
138ef2f
Docs: protection rows 2 and 4 as implemented in firmware 0.2
claude Sep 28, 2026
df4d6dd
Merge pull request #13 from udaravima/claude/phase1-protections-vzysax
udaravima Sep 28, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: [master]
branches: [master, development]
pull_request:
workflow_dispatch:

Expand Down
77 changes: 45 additions & 32 deletions HANDOVER.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

Written 2026-07-16, updated 2026-07-26 for the next agent (or future session)
continuing this project. Read this + README.md before touching anything.
**Start with "Phase-2 PCB — resume point" below** — that is the live work
front: 83 connections to finish by hand in KiCad. Manager firmware is done.
**Phase-2 PCB is routed (2026-09-27): 0 unconnected, 0 DRC errors, fab
outputs generated** — see "Phase-2 PCB — resume point" below and
`hardware/phase2-module/tools/README.md`. Manager firmware is done.

## The user & working agreement

Expand Down Expand Up @@ -42,13 +43,13 @@ 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 | **Routed, 0 unconnected, 0 DRC errors** (2026-09-27, draft PR from `claude/project-thread-nojoms`): pass-1 + `fanout.py` + Freerouting 1.9 + `finish_routes.py`; 1173 tracks / 358 vias. DRC = 9 silk *warnings* (6 are J1/J4 terminal-block silk over the edge, by design). Fab zip generated. Placement nudges (C25, C26, R3, R6) live in `fanout.py`, so `gen_board.py` no longer reproduces the board — see tools/README |
| PCB — Phase 1 | **100 × 80 mm, routed, 0 unconnected, 0 DRC errors** (2026-09-27, draft PR from `claude/phase1-100x80`; 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 |
| 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 | **83 unconnected, 0 copper DRC, silk clean (2026-07-26, c1a86eb)** — see the resume section; finish by hand in KiCad. Older detail below: |
| PCB — Phase 2 (history) | **(2026-07-25, 27fb2d1).** `gen_board.py` placement green (173 comps, all pour/courtyard/edge assertions pass, 130×90 4-layer); `route_board.py` pass-1 done (power pours, In2 heat patches, both phases' gate fan-outs, Kelvin pairs, disconnect trunk). DRC: **copper down to ~19 clearance + ~11 dangling/mask/hole in 3 known clusters** (see resume section); 243 unconnected = signal nets, autoroute not yet run. Found & fixed a real LM5143 land-pattern bug in the process (see load-bearing decisions) |
| PCB — Phase 3 backplane | **COMPLETE pass-1 (2026-07-25)**: `phase3-backplane/tools/gen_board.py` (single-script: placement + 2oz bus pours + stitching + ALL signal routing) — **0 copper DRC, 0 unconnected**; only lib-bookkeeping (39) + 1 silk nick remain. 8 slots @30mm (XT60PW-F rot-90 mates the module pad-for-pad, socket y60..77.8 = module J5 1:1), M6 lugs -> RS1‖RS2 0.5mΩ Kelvin-sensed by INA228, nested PRESENT L-bus, CAN terminated past both end slots, E-stop chain threaded per docs. Netlist from `tools/wip/bp.net` (regenerate via kicad-cli) |
| PCB — Phase 3 manager | **placement pass complete, 0 DRC (2026-07-26)**: 100×80 2L, 87 footprints (80 comps + 4 M3 + 3 fiducials), 86 nets, F.Cu 3V3 / B.Cu PGND planes, antenna keep-out verified copper-free. **173 unconnected = the signal nets; routing is the next pass.** Reproduce: `cd tools && python3 gen_board.py wip/mgr.net` → `python3 ../../common/fix_fpids.py ../phase3-manager.kicad_pcb` → `python3 ../../common/finish_board.py ../phase3-manager.kicad_pcb --silk --planes` → `python3 run_drc.py` |
| Module firmware | v0.1 builds clean (6.3 KB): full peripheral binding + CAN dispatch around the host-tested `module_core`. Untested on silicon (no board yet) |
| PCB — Phase 3 manager | **Routed, 0 unconnected, 0 DRC errors (2026-09-27, draft PR into `development` from `claude/route-manager-shxsg1`)**: 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` |
| 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 |
| Manager firmware | **v0.2 COMPLETE (2026-07-25, commit 174595e)**: `scpi_core` + `ui_core` join `manager_core` as host-tested cores; ESP-IDF shell fully written (display/encoder/USB-SCPI/app_main). **First compile 2026-09-27: builds clean on IDF v5.3.2** (355 KB image, two build fixes). Untested on silicon. See docs/10 |
| Phase-2 circuit design | **complete (docs/08, 2026-07-16)**: all values worked + datasheet-verified; LM5143/LM5069/CSD18540Q5B/CSD19536KTT/XAL1510/TMUX1101/TL431 PDFs now in docs/datasheets/ |
Expand All @@ -57,9 +58,24 @@ manager, CAN 2.0B @500k. Docs 01–07 are the spec; read 05 (build plan) first
| Manager firmware — detail | manager_core v0.1 (2026-07-18) + **scpi_core & ui_core v0.2 (2026-07-25)**, all host-tested. Shell modules: `display.c` (esp_lcd ILI9341, 8×16 VGA font generated by `idf/tools/gen_font.py` from the system PSF — never hand-typed), `encoder.c` (PCNT ×4 quadrature, push/hold), `scpi_usb.c` (TinyUSB CDC), `app_main.c` (one mutex over the three cores; TCA9535 keys; backplane INA228 meter). Managed components in `main/idf_component.yml`. **Bring-up knobs (expect wrong on first light-up): display rotation + RGB565 byte order, then encoder direction** — docs/10 §Bring-up 6–7 |
| Ordering/BOM | **China-first sourcing pass done (hardware/SOURCING.md, 2026-07-18)**: LCSC prices/stock verified for all phases (~$135 parts for the Phase-3 build, ~$300–380 all-in); inductor + slot-connector decisions taken (Sunlord + 3.75 mΩ shunts APPLIED to gen_phase2; XT60PW slots queued); order-early list: LTC7004 (5 pcs), CSD19536KTT (12 pcs). MPN-properties pass into symbols still pending |

## Phase-2 PCB — resume point (LIVE, 2026-07-26)

**State: 83 unconnected, 0 copper DRC, silk clean.** Reproduce end to end:
## Phase-2 PCB — resume point (routed, 2026-09-27)

**State: routed. 0 unconnected, 0 DRC errors, 19 warnings (silk and
four one-layer vias), PS-002 clear, fab zip + CPL generated.** The routing
recipe is in `tools/README.md`. The pre-order review (2026-09-28) closed
every point: FB2 -> AGND is what LM5143 §8.3.17.2 asks for in interleaved
mode; C15/16/36/37 are now EEHZA1V221P (fits the 10x10.5 land); U5 is the
stocked INA228AQDGSRQ1 (same pinout and registers). Layout points kept on
purpose: G_LS_A's B.Cu detour is 26 mm vs G_LS_B's 20 mm (a few nH);
VOUT2/COMP2 under U3 are mask-covered, DC-quiet tie nets; B.Cu signal
crossings leave the In1 AGND pocket (the reference plane) unbroken.
**Bring-up item:** RT1 sits between the phases as docs/08 intends, but on
the AGND pocket, which is thermally isolated from the PGND copper the FETs
heat. Expect NTC_FET to lag and read low: log it against a thermocouple
on Q2 at full load and set the derate/OTP thresholds from that offset.

Everything below in this section is the 2026-07-26 history (83 open
connections), kept for its Freerouting and PS-002 notes. The old recipe:

```bash
cd hardware/phase2-module/tools
Expand Down Expand Up @@ -195,31 +211,28 @@ Notable route_board facts a future session needs:

## Immediate next steps (agreed order)

1. **Finish Phase-2 board** — hand-route the remaining 83 connections in
KiCad (table + per-item coords in the resume section), then
`../common/finish_board.py` (silk + planes + fab) and `run_drc.py`.
2. **Phase-3 manager board — ROUTE it.** Placement is done and DRC-clean
(see the table); what is left is 173 unconnected signal nets on a 2-layer
board. Mostly 3-node digital nets, so hand-routing in KiCad is realistic;
there is no `route_board.py` for this phase yet.
1. **Phase-2 board — routed (2026-09-27).** Review the items listed in the
resume section before ordering.
2. **Phase-3 manager board — routed (2026-09-27).** Review before ordering:
J3 is the GCT USB4105-GF-A (C3020560, picked 2026-09-28 to match the
routed land; JLCPCB assembly stock, backup -120 C5184243); 13 nets cross under the USB pair on B.Cu (fine at
full speed); the 0.2 mm drilling gate below still applies.
3. **Order files** — the MPN/LCSC pass is done for every part SOURCING.md
verified: `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`. The part table
is `common/lcsc_parts.py`; `--check` fails if anything is stale. Still
open: generic R/C/jellybean/header numbers, and the `CHECK:` rows in the
BOMs (footprint/variant mismatches vs SOURCING.md).
4. **Phase-1 board** — 187 unconnected; port the phase-2 autoroute fixes
(connectivity seeding, entry-stub snap, pocket costs, net ordering)
before hand-finishing.
3. **MPN-properties pass → BOM CSVs → order files** — LCSC part numbers
and prices are already verified in `hardware/SOURCING.md`; what is
missing is the properties in the symbols and the generated CSVs.
4. **Phase-1 board** — routed (0 unconnected, 0 DRC errors). Review before
ordering: the long thin sense runs (VBUS_F to R60.1 is 79 mm with 4 vias,
VOUT_INT to L1.2 39.5 mm), C28's PS_VIN decoupling (7.1 mm, 1 via) and
the placement nudges. Then fold the nudges back into `gen_board.py`
PLACEMENT.
4. **Phase-1 board** — shrunk to 100 × 80 mm and re-routed (0
unconnected, 0 DRC errors, 2026-09-27) with the BOM's L1 and U7 lands;
the 120 × 80 version (wrong L1/U7 lands) is on branch `phase1-120x80`.
Earlier review items still hold: C28 sits on U3.20, the VBUS divider
(R60/R61/C62) sits by U10.14, and every part offset is in `gen_board.py`
PLACEMENT. The VOUT_INT FB sense run (52 mm, tapped at L1.2) keeps
5.5 mm or more from SW copper on every layer, enforced by
`tools/fb_reroute.py` after routing. Next: owner picks the BOM `CHECK:` parts,
then order.

**Gates before ordering ANY board — including the fab-ready backplane:**

Expand Down Expand Up @@ -320,9 +333,9 @@ by hand. If a DRC report ever shows this class again, suspect the env.
- **INA228 ALERT has no external pull-up** in schematic v1 — firmware enables
PB7's internal one; add a discrete pull-up in the next schematic rev.
- **Grounding**: PGND/AGND split planes joined ONLY at NT1 (net-tie beside the
sense amps); In1 has an AGND pocket under the LTC7004 cluster. Never add a
via that shorts the domains — the seam geometry lives in gen_board.py
(`SEAM`, `AUXW`, `POCKET`).
sense amps). Phase-1 (100 × 80) has no AGND pocket: the LTC7004 cluster
sits below the seam. Never add a via that shorts the domains — the seam
geometry lives in gen_board.py (`SEAM`, `AUXW`).
- **Kelvin shunt**: pours grab only the outer halves of R30's pads; sense
traces leave the inner edges. Preserve this in any re-layout.
- Package truths (all datasheet-verified): LM5145 pin 15 = isolated "EP"
Expand Down Expand Up @@ -376,11 +389,11 @@ that the average is servo'd but ripple is skip-mode coarse.

## Open items / known warts

- **Phase-2: 83 connections to finish by hand** — see the resume section.
- **`route_board.py` is not deterministic** (67/68/66 pad-vias on identical
input). Harmless today, but it breaks the reproducibility contract.
- **Freerouting does not work on the phase-2 board** — evidence in the resume
section; the KiCad plugin hits the same StackOverflowError. On phase-1 it
- **Freerouting on the phase-2 board works since 2026-09-27** (1.9.0,
zone-free DSN, `-oit` bounds the optimizer; see tools/README.md). The
older failure notes: the KiCad plugin hits the same StackOverflowError. On phase-1 it
works headless as **1.9.0** under `xvfb-run` with `-Xss64m` (2.x's CLI
never finished); see phase1-module/tools/README.md. phase-2's
`import_ses.py` is broken (KiCad 7 `ImportSpecctraSES` takes no board);
Expand Down
58 changes: 26 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,20 @@ precision, usable for lab work, bulk DC power, and battery charging.
| [docs/08-phase2-circuit-design.md](docs/08-phase2-circuit-design.md) | Worked component values for the 600 W module (LM5143 + LM5069) |
| [docs/09-phase3-circuit-design.md](docs/09-phase3-circuit-design.md) | Backplane + ESP32-S3 manager design (slots, E-stop chain, bus metering, UI) |
| [docs/10-manager-firmware.md](docs/10-manager-firmware.md) | Manager firmware architecture (host-tested core + ESP-IDF shell) |
| [docs/11-build-guide.md](docs/11-build-guide.md) | How to build one: ordering, assembly, firmware, first power-up |
| [docs/12-phase1-bench-tests.md](docs/12-phase1-bench-tests.md) | Phase-1 bench test procedure against the exit criteria (+ results template) |
| [hardware/SOURCING.md](hardware/SOURCING.md) | LCSC-first part sourcing, prices, order-early list |
| [HANDOVER.md](HANDOVER.md) | Session handover: state, decisions, gotchas, next steps |
| [hardware/phase1-module/tools/README.md](hardware/phase1-module/tools/README.md) | Schematic/PCB generation + verification pipeline |
| [hardware/phase1-module/lib/PARTS-TO-DOWNLOAD.md](hardware/phase1-module/lib/PARTS-TO-DOWNLOAD.md) | Exact orderables, package corrections, verified pricing |

## Repository layout

```
docs/ Design docs 01..08 (+ datasheets/, gitignored)
hardware/common/ Shared schematic generator + sheet builders + checkers
hardware/phase1-module/ KiCad 7 project — GENERATED, do not hand-edit
docs/ Design docs 01..10, build guide 11, bench tests 12
test-results/ Bench results (template + one file per board run)
hardware/common/ Shared generators, checkers, bom.py + lcsc_parts.py
hardware/phase1-module/ KiCad 7 project (schematics hand-owned; board generated + routed)
tools/ Generators + mechanical checkers (see README)
lib/ Vetted symbol + footprint libraries (shared by phase 2)
hardware/phase2-module/ KiCad 7 project — GENERATED (600 W module, docs/08)
Expand All @@ -58,38 +62,28 @@ firmware/
manager/core/ Portable manager core (host-tested)
manager/idf/ ESP-IDF shell (needs IDF >= 5.1; unproven on silicon)
tests/ Host unit tests — `cd firmware/tests && make test`
tools/lbcan.py Bench helper: build cansend frames, decode candump
```

## Status (2026-07-16)
## Status (2026-09-27)

- **Phase 0 — design docs: complete** (01–07).
- **Phase-1 schematic: complete (v1) and machine-verified** — 7 generated
sheets, 137 components; every net asserted against the intended net table,
every footprint pad-checked; vendor symbols/footprints datasheet-vetted.
Audited with the kicad-happy analyzers + ngspice (38/40 subcircuits pass);
the audit's one real electrical find (ADC injection current on PA1) is fixed.
- **Module firmware v0.1: builds** — bare-metal STM32G431, 6.3 KB, binds the
host-tested control core to SPI DAC, I²C INA228, FDCAN @500k, ADC, fan PWM,
IWDG, flash calibration. Untested on silicon (no board yet).
- **PCB layout: deferred by design** — all phases' boards get laid out
together at the end. The committed board file is a clean intermediate
(full placement, split ground planes, power pours, thermal vias, critical
routes — zero copper DRC errors); the signal autorouter is committed as WIP.
- **Pricing verified** — complete Phase-1 build ≈ **US$100–125** including
five 4-layer PCBs (details in PARTS-TO-DOWNLOAD.md §E).
- **Phase-2 circuit design: complete (docs/08)** — all component values
worked and datasheet-verified (LM5143 interleaved config, LM5069 hot-swap
with SOA check, 6.8 µH subharmonic-stability fix, INA240A3 scaling fix).
- **Phase-2 schematic: complete (v1) and machine-verified** — 8 generated
sheets, 171 components, 116 nets asserted against the intended net table,
every footprint pad-checked. The control core / sensing / disconnect /
aux / MCU sheets are the verified Phase-1 blocks, factored into
`hardware/common/sheets_common.py` (extraction proven netlist-identical
for Phase 1) and re-parameterized per docs/08.
- **Next:** Phase-3 backplane + ESP32-S3 manager schematics, manager
firmware, kicad-happy/SPICE audit of the Phase-2 schematic — then the
batch PCB pass, ordering, and the Phase-1 test campaign per
[docs/05-build-plan.md](docs/05-build-plan.md).
Nothing has run on silicon yet; the first board to be built is the Phase-1 module.

| Area | State |
|---|---|
| Design docs | Complete: 01–10, plus the build guide (11) and Phase-1 bench test procedure (12) |
| Phase-1 module (150 W) | Schematic verified and audited; **board routed, 0 unconnected, 0 DRC errors**, fab zip committed. Layout review fixes in PR #5. Next: settle the open BOM items (Q3/Q4 part, R30 shunt, the BOM `CHECK:` rows), then order and run [docs/12](docs/12-phase1-bench-tests.md) |
| Phase-2 module (600 W) | Schematic verified and audited; board placed and pass-1 routed, **83 connections left** to finish by hand in KiCad |
| Phase-3 backplane | Board fab-ready; gated on the XT60 polarity buzz-out ([MECHANICAL.md](hardware/MECHANICAL.md)) |
| Phase-3 manager | Schematic verified; board placed, signal routing not started |
| Module firmware | v0.1 builds (~6 KB, bare-metal STM32G431); 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 CSVs (`hardware/common/bom.py`); five `CHECK:` part mismatches await a pick; 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.
[HANDOVER.md](HANDOVER.md) has the detailed resume points. Work lands on the
`development` branch through pull requests; `master` receives batched merges.

## License

Expand Down
Loading
Loading