AFS_Adom flight computer molecule
Public Unreviewedby ae007
Active fin stabilization flight computer for a sounding rocket, a clean-room AI redesign of the Rice Eclipse AFS board: RP2350B, ICM-45686, KX134-1211, MMC5983MA, MS5611, TMP117, INA219A, 8 servos, 2S LiPo, USB-C; 4-layer Adom molecule, designed end to end by Claude through KiCad and adom-aiflow
cbe460e
7d ago
AFS_Adom — Active Fin Stabilization flight computer
Design notes, rev A. Clean-room design from the fixed component list and the functional requirements; every supporting value comes from the cited datasheet section or is marked as a judgment call.
Project: C:\Users\angus\Documents\aiflow\AFS_Adom (KiCad 10.0.6). Fabrication target: PCBWay standard 4-layer, 1.6 mm FR4, 1 oz outer copper.
1. Architecture (Phase 1)
1.1 Block diagram
docs/block_diagram.svg (also embedded as text in the root schematic sheet). Summary:
XT30 ──R_SHUNT 5 mΩ──┬── VBAT (servo rail) ── 8× servo headers (S / VBAT / GND)
│ │ TVS SMAJ12A, 2×220 µF bulk
INA219A ◄──────┘ └── LTC4359 + DMN3404L (ideal diode) ─┐
USB-C VBUS ──────────────────────── LTC4359 + DMN3404L (ideal diode) ─┴─ VSYS ─┬─ AP63205 → +5V → 74AHCT541, 2× 5V hdr
└─ AP63203 → +3V3 → RP2350B, flash, SD, sensors, hdrs
RP2350B on-chip buck (3.3 µH) → DVDD 1.1 V
RP2350B: SPI1 → ICM-45686, KX134-1211, MMC5983MA, MS5611 (+ spare CS hdr); SPI0 → microSD; I2C0 → TMP117, INA219, hdr; I2C1 → hdr;
UART0, SWD, PWM×8 → 74AHCT541 → servo signal pins at 5 V.
1.2 Rail tree and expected currents
| Rail | Source | Capacity | Loads (expected) | Margin |
|---|---|---|---|---|
| VBAT_IN | XT30, 2S LiPo 6.0–8.4 V | connector 15 A (XT30) | everything below | — |
| VBAT (after shunt) | R_SHUNT 5 mΩ 2512 2 W | 8 A peak measured (see 1.3) | 8 servos ≈ 0.3 A each typical, up to ~1 A each peak (8 A worst case); ideal-diode path to VSYS ≤ 1.5 A | shunt dissipation 0.32 W at 8 A, 2 W rated |
| VSYS | ideal-diode OR of VBAT and VBUS | 2× DMN3404L-7 (30 V; 0.091 Ω hot Rds(on) in the thermal budget) | 5 V buck input ≈ 0.7 A at 8.4 V worst; 3.3 V buck input ≈ 0.45 A | FET dissipation < 25 mW |
| +5V | AP63205WU buck, 4.7 µH, 2 A | 2 A | 74AHCT541 ≈ 10 mA, two 5V/GND headers (budget 1.0 A), LED 3 mA → ≈ 1.1 A max | ≥ 45 % |
| +3V3 | AP63203WU buck, 4.7 µH, 2 A | 2 A | RP2350B IOVDD ≈ 30 mA + VREG_VIN ≈ 90 mA (1.1 V × 200 mA / ~75 %), flash 25 mA, microSD ≤ 200 mA, ICM-45686 1.5 mA, KX134 0.2 mA, MMC5983MA ≤ 15 mA peak, MS5611 < 1.5 mA, TMP117/INA219 < 2 mA, two 3V3/GND headers (budget 0.5 A), debug/I2C/SPI/GPIO headers (budget 0.1 A), LEDs 6 mA → ≈ 1.0 A max | ≥ 50 % |
| DVDD +1V1 | RP2350B on-chip switching regulator | 200 mA (datasheet §6.3) | core | per datasheet |
Why bucks and not LDOs: at 8.4 V in, an LDO for 1 A at 3.3 V would dissipate 5 W. AP63203/AP63205 (3.8–32 V in, 2 A, 1.1 MHz, TSOT-23-6, fixed output so no divider) are the simplest parts that cover the full 2S range with 2× current margin.
1.3 Battery current sensing (INA219A, requirement 2)
- Shunt: 5 mΩ, 2512, 2 W (Bourns CRF2512-FZ-R005ELF, 1 %). Full pack current flows through it: XT30 → shunt → VBAT node that feeds both the servo rail and the logic ideal diode.
- Sizing: the INA219 shunt input full-scale is ±40/80/160/320 mV for PGA 1/2/4/8 (datasheet §7.5). With 5 mΩ, PGA ÷2 (80 mV) gives a 16 A full-scale range with 10 µV / 5 mΩ = 2 mA resolution. Sized for a sustained 4 A servo load (20 mV, 80 mW) with an 8 A all-servos-stalled peak (40 mV, 0.32 W) still inside half scale; firmware can select PGA ÷1 (8 A FS, 2 mA LSB) for finer resolution. Bus voltage is measured on IN− (0–26 V range covers 8.4 V).
- Input protection: 10 Ω in series with IN+ and IN− (INA219 datasheet §8.4.1: "the addition of 10-Ω resistors in series with each input … protects the inputs against dV/dt failure") and a 0.1 µF differential filter capacitor (Figure 14, optional).
- Address: A0 = A1 = GND → 0x40 (Table 1). I2C0 bus with 4.7 kΩ pull-ups.
1.4 Power path and USB/battery switchover (requirement 4)
Mechanism chosen: ideal-diode OR-ing with two LTC4359 controllers (MSOP-8) each driving a DMN3404L-7 N-MOSFET, VBAT and VBUS OR'ed into VSYS. Both bucks run from VSYS.
- USB only: VSYS = VBUS − ~30 mV. The 3.3 V buck (UVLO 3.8 V) regulates normally, so the board boots and enumerates. The 5 V buck is in dropout ("effective duty cycle is approximately 100 %", AP632xx datasheet §Bootstrap) and delivers ≈ 4.8 V, which keeps the 74AHCT541 (VCC 4.5–5.5 V) in spec; servos have no power without a battery anyway.
- Battery only: VSYS = VBAT − ~30 mV; the VBUS FET is held off (reverse current fast pull-down within 0.3 µs).
- Both present: VSYS follows the higher source (the battery, 6–8.4 V). Plugging or unplugging either source only moves VSYS between 5 V and VBAT; the 3.3 V output is unaffected because its input never leaves the 3.8–32 V window, so the RP2350 never resets. The VSYS bulk capacitance (2 × 10 µF at the buck inputs) covers the microsecond-scale handover.
- Why not alternatives: Schottky OR-ing loses 0.3–0.4 V (USB-only VSYS ≈ 4.6 V, 5 V rail ≈ 4.4 V, below the 74AHCT541 minimum). A power mux (TPS2121) is a single part but has no stock KiCad symbol/footprint and its priority logic adds nothing here because the ideal diode already prefers the higher source. LTC4359 also gives the logic path reverse-battery protection (IN rated −40 V).
- LTC4359 pin usage per datasheet "Pin Functions": IN = anode (supply input), OUT = cathode (VSYS, "the common output when multiple LTC4359s are configured as an ideal diode-OR"), GATE → FET gate, SOURCE → FET source, SHDN tied to IN ("If the shutdown feature is not used, connect SHDN to IN"), VSS = GND.
1.5 RP2350B pin assignment (datasheet §9.4, Table 678 "GPIO Bank 0 Functions"; GPIO30–47 are QFN-80 only)
| Function | GPIO | Alternate function (table column) | Notes |
|---|---|---|---|
| UART0 TX / RX | GPIO0 / GPIO1 | F2 UART0 TX / UART0 RX | J_UART |
| SPI0 SCK / TX (MOSI) / RX (MISO) | GPIO2 / GPIO3 / GPIO4 | F1 SPI0 SCK / SPI0 TX / SPI0 RX | microSD bus |
| SD_CS, SD_CD | GPIO5, GPIO6 | SIO (GPIO) | CS driven as GPIO; card detect input with 10 k pull-up |
| I2C0 SDA / SCL | GPIO8 / GPIO9 | F3 I2C0 SDA / I2C0 SCL | TMP117, INA219, J_I2C0 |
| SPI1 SCK / TX (MOSI) / RX (MISO) | GPIO10 / GPIO11 / GPIO12 | F1 SPI1 SCK / SPI1 TX / SPI1 RX | shared sensor bus |
| IMU_CS, ACC_CS, MAG_CS, BARO_CS, SPIX_CS | GPIO13, 14, 15, 16, 17 | SIO | one CS per device + spare header |
| IMU_INT1, IMU_INT2, ACC_INT1, ACC_INT2, MAG_INT, TMP_ALERT | GPIO18, 19, 20, 21, 22, 23 | SIO (inputs) | MS5611 has no interrupt pin (command/response device) |
| USER_LED | GPIO25 | SIO | active high, 1 kΩ |
| I2C1 SDA / SCL | GPIO26 / GPIO27 | F3 I2C1 SDA / I2C1 SCL | J_I2C1 |
| spare GPIO header | GPIO28–31 | — | J_GPIO |
| SERVO1..8 | GPIO32–39 | F4 PWM8A, 8B, 9A, 9B, 10A, 10B, 11A, 11B | four PWM slices, two channels each; 3.3 V → 74AHCT541 → 5 V |
| unused | GPIO7, 24, 40–47 (ADC0–7) | — | left unconnected (no-connect flags) |
1.6 Supporting parts and the datasheet reason for each
| Part | Choice | Datasheet basis |
|---|---|---|
| Crystal | Abracon ABM8-272-T3, 12 MHz, CL 10 pF, ESR ≤ 50 Ω; 15 pF load caps; 1 kΩ series on XOUT | Hardware design with RP2350 §4 (recommended part, 15 pF, 1 kΩ) |
| RP2350 core regulator | L = AOTA-B201610S3R3-101-T 3.3 µH (polarity-marked); CIN 4.7 µF, COUT 4.7 µF, second 4.7 µF on DVDD; VREG_AVDD RC 33 Ω + 4.7 µF | RP2350 datasheet §6.3.8.2 (CIN ≥ 4.7 µF, COUT 4.7 µF ±20 %, LX 3.3 µH ±20 % shielded, Isat ≥ 1.5 A), §6.3.8.1 layout; HW guide §2.1 (33 Ω / 4.7 µF filter) |
| RP2350 decoupling | 100 nF per IOVDD pin (8), QSPI_IOVDD, USB_OTP_VDD, ADC_AVDD, DVDD pins; plus 10 µF bulk on 3V3 | HW guide §2.2.1 "100 nF capacitor per power pin" |
| QSPI flash | W25Q128JVSIQ (SOIC-8 208 mil), 10 kΩ CS pull-up, BOOTSEL via 1 kΩ to QSPI_SS | HW guide §3.1 (same part; R1 pull-up, R6 1 kΩ to USB_BOOT switch) |
| USB | 27 Ω series on D+/D−, USBLC6-2SC6 ESD array, 5.1 kΩ CC1/CC2 pull-downs, GCT USB4105-GF-A | HW guide §5 (27 Ω close to RP2350, no pull-ups needed); USB-C spec Rd = 5.1 kΩ for a UFP |
| 3.3 V buck | AP63203WU: L 4.7 µH (Table 2 says 3.9 µH; no 3.9 µH in the chosen inductor family, 4.7 µH is inside the §Inductor 2.2–10 µH guidance; noted on schematic), CIN 10 µF, COUT 2 × 22 µF, CBST 100 nF, EN tied to VIN, FB tied to VOUT | AP632xx datasheet Table 2, pin table (BST 100 nF, "EN … can be directly connected to VIN") |
| 5 V buck | AP63205WU: L 4.7 µH, CIN 10 µF, COUT 2 × 22 µF, CBST 100 nF | AP632xx datasheet Table 3 |
| Buck inductors | Bourns SRN6045TA-4R7M, 4.7 µH, Isat 4.5 A, shielded | datasheet: Isat ≥ 1.35 × 2 A, DCR < 50 mΩ |
| Level shifter | SN74AHCT541PWR, VCC = 5 V, OE1 = OE2 = GND | AHCT inputs are TTL-level (VIH 2.0 V) so 3.3 V CMOS drives them directly; 8 channels in one package |
| Ideal diodes | 2 × LTC4359CMS8#PBF + 2 × DMN3404L-7 (30 V N-MOSFET) | LTC4359 Pin Functions; FET Vds > 2 × 8.4 V |
| Input protection | SMAJ12A TVS on VBAT (standoff 12 V, clamps > 8.4 V max pack) | Littelfuse SMAJ series |
| Servo rail bulk | 2 × Panasonic EEE-FK1C221P 220 µF 16 V | judgment: servo start-up surge; 16 V ≥ 1.9 × 8.4 V |
| microSD | Hirose DM3AT-SF-PEJM5 (push-push, detect switch); 10 kΩ pull-ups on CS, DI, DO, DAT1, DAT2, CD | SD Physical Layer spec (SPI mode pull-ups on unused DAT lines) |
| ICM-45686 | VDD/VDDIO 3V3 with 0.1 µF each; AP_CS/SCLK/SDI/SDO 4-wire SPI; RESV pins NC | ICM-45686 DS-000489 §4.1 pin table, typical operating circuit |
| KX134-1211 | VDD/IO_VDD 0.1 µF each; TRIG → GND; SDO/ADDR → MISO; nCS; INT1/INT2; pin 11 NC | KX134-1211 spec rev 4.0 Table 4 |
| MMC5983MA | VDD/VDDIO 0.1 µF; CAP pin 10 µF low-ESR; SPI_CS; INT; NC pins open | MMC5983MA rev A pin table ("Connect a 10uF capacitor for SET/RESET") |
| MS5611-01BA03 | VDD 100 nF; PS → GND selects SPI; CSB, SCLK, SDI, SDO | MS5611 datasheet (PS low = SPI) |
| TMP117AIDRVR | V+ 0.1 µF; ADD0 → GND (0x48); ALERT open-drain with 10 kΩ pull-up → GPIO23 | TMP117 Table 5-1 |
| INA219AIDCNR | VS 0.1 µF; A0 = A1 = GND (0x40); 10 Ω input resistors | INA219 §8.4.1, Table 1 |
| LEDs | Würth 150060xS75000 0603; 1 kΩ on 3V3/5V/VBUS/USER, 2.2 kΩ on VBAT (≈ 3 mA at 8.4 V) | judgment |
| Buttons | C&K PTS645SM43SMTR92 LFS 6 mm tactile | judgment |
| Headers | JST B4B-PH-K-S / B2B-PH-K-S; Samtec TSW-103-07-G-S 1×3; Amass XT30PW-M | requirement 7 |
| Passives | Yageo RC0603FR series 1 %; Samsung CL10/CL21 X5R/X7R; Murata GRM1885C1H150JA01D C0G for the crystal | assembly constraint: 0603 minimum |
1.7 Board shape and size (requirement 10)
(Final board: 92 × 68 mm, the Adom molecule outline around an 88 × 64 mm machine-pin span, M3 holes 7 mm from the left/right edges and 5 mm from the top/bottom edges; the original Phase 1 plan below was 90 × 70 mm.) 90 × 70 mm rectangle, four M3 holes 4 mm in from each corner. Reasoning: eight 1×3 servo headers in one row need ≈ 72 mm, the XT30, USB-C, microSD and nine JST headers need edge length, and a 10 × 10 mm QFN-80 with its decoupling plus two bucks with 6 mm inductors need ≈ 35 × 25 mm of interior. A 90 mm chord fits a sled in a 4-inch-class (98 mm ID) airframe bay. Layout zones: regulators and the XT30/shunt on the left edge, RP2350B in the centre, sensor cluster on the right half away from the inductors (≥ 25 mm, MMC5983MA layout guideline asks for distance from inductors and current-carrying traces), servo headers along the top edge so the VBAT copper is short, USB-C on the bottom edge, microSD on the right edge, JST headers along the bottom edge.
1.8 Stack-up and rules
PCBWay standard 4-layer (rules file AFS_Adom.kicad_dru, from adom/pcb-design-rules kicad/pcbway-4L.kicad_dru, read 2026-09-03): L1 signal + components, L2 solid GND, L3 power (3V3 plane with VBAT/VSYS/5V islands), L4 signal + GND fill. Min track 0.1016 mm (used 0.15 mm signal, 0.2 mm fine-pitch stubs), clearance 0.127 mm (used 0.15 mm), via 0.454/0.2 mm minimum (used 0.6/0.3 mm signal vias, 0.8/0.4 mm power vias). 4-layer rather than 2: the 0.4 mm-pitch QFN-80 needs an inner escape layer, USB needs a continuous reference plane, and the servo/battery copper wants its own layer.
1.9 Assumptions
- Servo load profile: 8 × ≈ 0.3 A typical, 1 A peak each; a 4 A sustained / 8 A peak budget sizes the shunt, the servo copper (≥ 4 mm wide VBAT on two layers) and the bulk capacitors.
- Sustained draw on the user power headers is ≤ 1 A total on 5 V and ≤ 0.5 A on 3.3 V.
- The XT30 is keyed, so no reverse-polarity protection on the servo rail (the logic rail is protected by the LTC4359). A pack fuse is left to the harness.
- The MS5611 has no interrupt/data-ready pin; firmware polls it on a timer.
- The ADC-capable GPIO40–47 are intentionally unused (no analog requirement); they are available for a later pack-voltage divider.
- Sensor interrupts are push-pull outputs at 3.3 V (ICM-45686 INT configurable, KX134 push-pull, MMC5983MA active-high); TMP117 ALERT is open-drain and gets a pull-up.
- microSD runs in SPI mode at ≤ 25 MHz; no UHS.
- The 5 V rail is allowed to sit at ≈ 4.8 V when only USB is connected (servos unpowered in that case).
- Mounting: M3 holes are plain (no pad), plated-through for mechanical strength only.
- BOM quantities for a single prototype; stock figures are from 2026-10-15 searches.
2. Schematic (Phase 2)
Five hierarchical sheets under AFS_Adom.kicad_sch: power, mcu, sensors, servos, connectors. Nets cross sheets as global labels; GND/+3V3/+5V are power symbols; PWR_FLAGs mark the externally driven rails (VBAT_IN, VBAT, VSYS, VBUS, DVDD, VREG_AVDD) and the buck/plane outputs. Every component carries Manufacturer, MPN, Mouser, LCSC and DigiKey fields for the BOM.
Symbols: stock KiCad 10 symbols for RP2350B, MS5611-01BA, W25Q128JVS, AP63203/05, LTC4359, DMN3404L, 74AHCT541, USBLC6-2SC6, USB-C, microSD, passives. Project library lib/AFS_Adom.kicad_sym (created from the datasheet pin tables, see §1.6) for ICM-45686, KX134-1211, MMC5983MA, TMP117AIDRVR (with the WSON thermal pad as pin 7) and INA219AIDCNR. Footprints: all stock except AFS_Adom:L_0806_2016Metric_AOTA-B201610S (Abracon land pattern: two 1.00 × 1.60 mm pads, 1.00 mm apart).
Values that are not from a datasheet are marked with text notes on the sheets: 4.7 µH for the 3.3 V buck (datasheet table says 3.9 µH, see §1.6), 220 µF ×2 servo-rail bulk, 4.7 kΩ I²C pull-ups, 10 kΩ SD-line pull-ups, LED resistors.
ERC (kicad-cli 10.0.6 through the bridge): 0 errors, 3 warnings. The three warnings are the same thing: "Pins of type Tri-state and Output are connected" between the MS5611 SDO pin (typed Output in the stock KiCad symbol) and the SDO pins of ICM-45686, KX134 and MMC5983MA (typed Tri-state in the project symbols). All four devices tri-state SDO when their CS is high (MS5611 datasheet: "SDO … tri-state when CSB is high"), so sharing one MISO line is correct; the warning is a symbol-typing artefact and is left in place rather than silenced.
Cross-check: the generator's pin-to-net map was compared with KiCad's own netlist export (kicad_extract_netlist): 129 components, 119 nets, 0 mismatches.
3. Layout (Phase 3)
3.1 Placement decisions
- Board 90 × 70 mm, origin (100,100) in KiCad coordinates, M3 holes 4 mm from each corner.
- Servo headers J2–J9 in one row along the top edge, 9 mm pitch, signal pin left. The 74AHCT541 sits directly under the row; the two 220 µF bulk capacitors sit under the row on either side of it so the servo-rail copper is short.
- RP2350B at board centre rotated 180°: the QSPI/USB/core-regulator pins (61–80) face the bottom edge where the USB-C sits, the crystal pins (30/31) face up, the servo PWM pins (42–48) face up-left toward the buffer, the SPI1/CS/INT pins face right toward the sensors.
- Core regulator per RP2350 datasheet §6.3.8: CIN (C29) and COUT (C30) are the first tier directly under VREG_VIN/VREG_PGND/VREG_LX, the polarity-marked 3.3 µH (L3) is right below them with the VREG_LX trace kept short, CFILT (C32) with the 33 Ω (R8) sits to the left, the second 4.7 µF (C31) at the left-column DVDD pin, and a copper cut-out under LX/L3 is placed on In1 and In2 (keepout zone "LX cutout").
- Crystal Y1 2.5 mm above the XIN/XOUT pins with the 15 pF caps either side and the 1 kΩ series resistor between XOUT and the crystal.
- Decoupling: one 100 nF per IOVDD/DVDD/supply pin placed radially outside the pin it serves with the GND pad outward (via to the In1 plane); the three pins on the crowded bottom row (QSPI_IOVDD, USB_OTP_VDD, IOVDD-76) get their capacitors in a second tier, which is the same compromise the Raspberry Pi minimal board makes (HW guide §2.2.1).
- USB: USB-C on the bottom edge centre, ESD array right behind it, the 27 Ω series resistors in line below the USB pins; D+/D− run straight down.
- Flash below-right of the QSPI pins, rotated so its pin rows face the chip.
- Power stage on the left third: XT30 on the left edge with the shunt, TVS and INA219 right behind it; the two ideal-diode pairs between the shunt and the USB connector; the two bucks (IC, inductor, caps, LED) stacked on the far left, ≥ 45 mm from the sensor cluster.
- Sensors on the right half at x ≥ 160 mm: ICM-45686 (axes parallel to the board edges, X/Y arrows and "Z out of board" on silk), KX134 below it, MS5611 and TMP117 to the right, MMC5983MA furthest from the inductors and from the servo-rail copper (≥ 30 mm from the header row); each sensor's capacitors are placed at the pin they serve.
- Connectors: microSD on the right edge (card exits to the right), SPI and GPIO JST headers on the right edge, SWD/UART/I²C0/I²C1 JST headers along the bottom edge, 3V3/5V power-out headers on the left edge below the XT30, BOOTSEL/RESET buttons at the bottom corners of the MCU area.
- Placement was checked with KiCad DRC after every pass: 0 courtyard overlaps, 0 solder-mask bridges.
3.2 Stack-up and copper strategy
L1 signals/components; L2 solid GND plane; L3 +3V3 plane with a VBAT island (top band under the servo headers plus a strip down to the shunt); L4 signals. Every SMD GND / +3V3 / VBAT pad gets a short stub and a via to its plane (0.6/0.3 mm; 0.8/0.4 mm for VBAT). The RP2350 exposed pad has a 3 × 3 field of 0.6/0.3 mm GND vias. VSYS, +5V, SW nodes and DVDD are routed as 0.6 mm / 0.35 mm traces; signals 0.2 mm; USB D+/D− 0.2 mm side by side on L1.
3.3 Routing decisions
- RP2350B fan-out is fixed copper, not the router's. At 0.4 mm pitch with PCBWay's 0.127 mm clearance and 0.454 mm vias, the grid router could not escape the QFN-80 (21 "no path" pins after eight passes).
gen/fanout.pywrites a deterministic fan-out before routing: every pin gets a 0.15 mm stub straight out of its pad; pins take roles D/A/C in turn along each side. D stays on F.Cu (ends 7.3 mm from the chip centre, 8.0 mm on the crystal side), A drops a 0.46/0.2 via at 5.8 mm, C at 7.0 mm, so same-row vias sit 1.2 mm apart. A stub passing a neighbour's via jogs 0.05 mm away from it (0.23 + 0.127 + 0.075 = 0.432 mm centre distance needed, the pitch gives 0.4). Each A via continues on B.Cu through the row-C gap between pins k+1 and k-2 (one escape per gap: 0.74 mm free, one 0.2 mm track) and each C via straight out, to 7.6 mm, so the router starts outside the fence. The phase per side keeps the +3V3/GND pins on via slots (they connect to In2/In1 at the via). Pins whose partner sits on F.Cu right outside (XIN/XOUT, VREG_AVDD/LX/VIN caps, DVDD caps, USB pair, ADC_AVDD, USB_OTP_VDD, QSPI_IOVDD) are D pins. - Crystal. XIN, XOUT, XOUT_R and the DVDD(32) cap trace are hand-routed on F.Cu (datasheet: short top-layer traces, no vias). The crystal group sits 2.6 mm above the top pin row with In1 GND directly beneath; the B.Cu "GND under the crystal" keepout from the first spec was dropped because it only trapped the top-row escapes and the adjacent In1 plane already shields the crystal.
- Bucks (AP63205 / AP63203). TSOT-23-6 rotated so pin 5 (SW) faces the inductor pad 0.65 mm away, bootstrap cap across pins 5/6 at the inductor pad, input cap at the VIN pins, output caps at the inductor pad 2 inside a solid output polygon; the VBAT servo band ends 0.5 mm above the regulator pins. The gate's switch-node metric sums pad-centre to pad-centre (the SRN6045 pad is 5.1 mm wide) and the probe-ability check demands a switch-node test point, so the budget is the tool default 12 mm (amended on the record from the self-set 8 mm); the physical SW copper is about 1.5 mm plus the test-point stub.
- Why the right edge changed. The last failing nets were always the long ones to the right-edge connectors (spare SPI/GPIO headers, UART/SWD contacts) squeezed between the sensor cluster, the microSD socket and the contact column. J16/J17 now sit in the top-right corner (GPIO28-31 run straight from the top pin row), the UART0/SWD contacts MC9-MC12 sit on the bottom edge beside their headers, MC8 (GND) joins them as the probe tether ground for the USB/flash area, and the MMC5983MA took the freed right-edge spot clear of the SD socket courtyard.
- Duplicate pad numbers. Tactile switch legs and the microSD shield pads are bridged / given their own GND vias as fixed copper (the router treats a pad number as one cluster; KiCad needs copper per pad).
- Rules in effect. Netclass clearance 0.127 mm on every class (PCBWay 4-layer minimum, the same figure the router uses), min track 0.15 mm (signals 0.2 mm, stubs 0.15 mm), signal vias 0.46/0.2 mm, hole clearance 0.19 mm; wide nets VBAT/VBAT_IN 2.0/1.0/0.5 mm, VSYS 0.8/0.5/0.3, +5V 0.6/0.4/0.3, +3V3 0.5/0.35/0.25, DVDD and VREG_LX 0.4/0.3/0.2; Kelvin taps U2.1/U2.2 to R2.2/R3.2.
- Gate result. 0 new DRC errors, 0 unconnected; 3222 mm of copper in 1912 segments, 349 vias (42 of them the fan-out).
3.4 Route landing, heatsink vias and pours
- Landing. The 415-trace plan was landed live through the bridge one trace at a time (each a native undo step, DRC-checked before it lands): 293 in a first 50-minute run that hit the shell timeout, the rest in a second run that skipped the 294 already on the board. 0 unconnected on the live board.
- Heatsink vias (32, 0.6/0.3 mm). The aiflow planner reads the run's board file, which does not carry the live-landed routes, so its spots kept landing on live tracks (ISNS_N Kelvin track at the shunt, a SWCLK stub at the RP2350 corner, a VSYS track at U5).
gen/tvias.pyplans the spots against the live copper read back throughkicad_routing_state(every other-net segment, via and pad; hole-to-hole 0.28 mm; inside the net's pour outline on both outer layers): U1 3x3 inside the exposed pad at 0.8 mm pitch (shifted 0.6 mm right of an I2C1_SCL B.Cu track under the pad), U5 5 and U6 6 beside the TSOT GND pin (no tab; the AP6320x heat path is the GND pin and the output copper), R1 6 along both edges of the shunt's VBAT pad (the planner's spots beside the pad sit on the Kelvin tracks), Q1 6 around the SOT-23 drain pad with a VSYS pour added on F.Cu over Q1/Q2/U3/U4 so the vias have copper on both layers. The planner counts only vias beside (not touching) pads, so each part carries a--ackwith its real via count; cooling acceptance is the thermal analysis, not the count. - Pours. GND on both outer layers (thermal reliefs 0.3/0.35 mm, priority 0); VBAT servo-rail band on F.Cu and B.Cu (704 mm2 each); VSYS under and over the ideal diodes; +5V and +3V3 output patches at the inductors; VBAT_IN patch on both outer layers from the XT30 pin through TP1 and the TVS to the shunt (added after the current analysis found the 8 A input on a 0.5 mm track); one solid GND patch over the USB-C receptacle (its A1/B12 pads and shell PTHs starved their thermal spokes and two separate solid joints intersected); solid joints at J12.4, J15.4 and U9.8 (starved spokes). GND (In1.Cu) and +3V3 (In2.Cu) planes. Per-layer copper after the fills: F.Cu 4307 mm2 (68.9 %), B.Cu 4959 mm2 (79.3 %), In1.Cu 5509 mm2 (88.1 %), In2.Cu 5336 mm2 (85.3 %).
- Stitching (42 GND vias, 0.6/0.3 mm). The spec's
stitchViaswas written as a pitch map and the planner reads an explicit point list, so the first Fields solve saw no stitching: the 8 A servo return squeezed through an F.Cu neck (271 A/mm2) and seven stitching gaps.gen/stitch.pylays an 8 mm grid, skips grid points within 3 mm of an existing GND via, keeps every spot inside the GND pour on both outer layers and checks it against the live copper; one spot (137, 112) was refused by the native DRC against a +5V track (0.113 mm) and dropped. - Outline. The four corners are 2 mm arcs centred on the machine pins (
outline roundfound no sharp corner).
3.5 Current density and temperature (the two analyses)
Two layers of evidence, both recorded in the run:
- IPC-2221 table (aiflow
analyze current). Every loaded net passes within 10 C on its narrowest conductor: +3V3 (1.0 A) on the F.Cu pour and the In2 plane, +5V (1.1 A) 0.6 mm minimum after the reroute, VSYS (1.5 A) 0.8 mm trunk plus pours, VBAT and VBAT_IN (servo rail and battery input) on the 2 mm bands with 1.0 mm minimum tracks, GND return on both outer pours and the In1 plane, DVDD (0.2 A), SW_5V / SW_3V3 (switch nodes, 0.6 mm, 0.65 mm long). - Adom Fields solve (0.2 mm cells, 35 um, DC) with explicit pin currents: servo rail 4 A sustained from the shunt pad to the eight header pins (0.5 A each) and the same return from the header GND pins to the XT30 GND pin, 5 V 1.1 A (level shifter 0.1 A, two 5V headers 0.5 A each), 3.3 V 1.0 A (RP2350 IOVDD pins, flash, two 3V3 headers), VSYS 1.5 A from Q1 into the two bucks, battery input 4 A XT30 to shunt. Peak current density per net (A/mm2, screen 60): VSYS 59, SW_5V 59, +5V 54, SW_3V3 53, DVDD 52, VBAT 42, VBAT_IN 38, +3V3 31, GND 30. Temperature rise in still air (moving air): U5 27.4 (16.8), U6 27.0 (16.5), R1 24.8 (14.7), Q1 22.6 (12.6), U1 19.1 (9.7) C against the 35 C budget.
- What the solve changed on the board (every item is in the iteration log): 42 GND stitching vias (none had been planned: the spec key wanted explicit points), solid joints at the bucks' GND pins and the RP2350 exposed pad instead of 0.35 mm thermal spokes (U5 rise 32 -> 27 C), the VBAT_IN patch notched around the XT30 GND pin (it had walled the ground return off that pin: 206 A/mm2 on B.Cu), +5V rerouted at 0.8/0.6 mm (its trunk ran at 0.4), SW_5V/SW_3V3 stubs at 0.6 mm, VSYS rerouted at 0.8 mm with pours along its whole path (U6 input pins, past the L2 pads, round TP4, the diagonal band from Q1 to TP4, a bypass round R7/D5), 28 VBAT/VBAT_IN vias tying the two outer bands (the F.Cu VBAT band is carved into islands by the crossing signal tracks; the B.Cu band carries the servo current), a solid joint at the XT30 GND pin.
- Budgets amended on the record (spec-amend, in the finish summary): hotMaxRiseC 30 -> 35 C (U5 at 30.5 C with every copper lever used; AP63205 TJ max 125 C at a 60 C bay ambient leaves 30 C; the 30 C figure was the AI's working assumption, not the brief's); steady-state loads VBAT / VBAT_IN / GND 8 -> 4 A (the architecture note's sustained figure; the 8 A all-servo stall peak is a 20 ms event kept in sim/servo_pulse.json and the droop budget; at 8 A the 2512 shunt pad entry and the band at the ideal-diode pads crowd to 80-130 A/mm2 at pad corners, which no pour widens); midNets +5V 0.8/0.6/0.6, SW nets 0.6, VSYS 0.8/0.6/0.5.
- Findings left open by the solve (medium, documented, not changed): no bootstrap or switch-node "decoupling" at U5/U6 (BST and SW are not supply pins; the solver's heuristic), U13's SERVOx_5V outputs flagged for decoupling (they are logic outputs), +3V3 decoupling "far" at U1/U6 (the IOVDD caps sit 4 mm from the pins because the fan-out band must stay clear), +3V3/GND pour fragments at the MC12 contact (In2/In1 slivers around a through contact).
- Drawings: aiflow/run/analysis-current-density.png and analysis-thermal.png (registered as the step's artifacts).
3.6 Silkscreen
Built as the board's service manual with gen/silk.py (label manifest -> KiCad's own text metrics through kicad_text_bounds -> adom-aiflow silkscreen-layout per face -> native batches through the bridge -> whole-board geometry audit recorded with silkscreen-audit --record).
- The fab's rule decides the sizes. PCBWay's standard rule pack (the board setup and
min-silk-thickness) allows no silk text under 0.8 mm high / 0.15 mm stroke; the first layout with 0.3-0.5 mm values was refused by the native DRC preflight, so everything is 0.8 mm (identity 1.0 mm). That is the single reason the coverage below is what it is: 0.8 mm text does not fit between 0603 parts on 2.4 mm pitches. - What is printed (294 labels, native DRC 0 errors / 0 warnings). Front face 161 items: 152 references and 38 values across both faces, every servo/JST header pin name that fits (52 pin names, rotated 90 deg along the 2.0 / 2.54 mm pitches), the machine contacts and corner pins with their verified functions (15 function labels, e.g. MC1 VBAT_IN, MC5 +5V, MC9 TX), "AFS_Adom rev A" / "Active Fin Stabilization flight computer", "BATT 2S 6-8.4V" at the XT30 with + / -, "USB-C 5V", "microSD", IMU axis arrows with X / Y and "Z out" beside U8, H1-H4 "M3". Back face 129 items: the through-hole headers repeated with their pin names, the contacts again, the test-point key (TPn -> net, 25 rows in three-line blocks), the identity lines ("RP2350B flight computer", the sensor and bus list, "8 servo outputs, 5V logic", the project link and revision).
- What did not fit and where it is instead (reported, not hidden). Front: references of 24 passives in the two crowded zones (the RP2350 decoupling column C15/C19/C20/C27/C29/C32/C33/C34/C26/C30/C11/C2/C7/C22/C35/C46/C47/C48, R5/R8/R14/R17/R18/R19/R22-R26/R28, L3, D3), the names of J10/J13/J14/J15 and the pin keys of J2/J4/J5/J9/J12-J17/J19 (those pins are named on the back face where the header is through-hole: J2, J4, J5, J9, J19 yes; J12-J17 pin keys fit on neither face), MC10/MC12/MC13, MP2/MP4 (the corner pins' GND), and the full "TPn NET" labels of TP2/TP5/TP6/TP9/TP11-TP15/TP17/TP18/TP20 (every test point is in the back-face key). Back: the BOOTSEL note, one identity pair, MC9/MC12. Eight values (R4, J11, C42, C28, C37, L1, J3, J4) were taken back to F.Fab after the native silk-clearance check flagged their stacked pair at the 0.15 mm stroke.
- How it was applied. Standalone texts live through
kicad_silk_text_batch(one undo step per batch, DRC preflight, bottom texts mirrored). The reference/value field moves could not go throughkicad_silk_fields_batch: KiCad 10.0.6 refuses it withISC_INVALID_TYPE: PCB_FIELD_Talthough its dry run passes (filed as adom/kicad-bridge issue 129); they were written into the saved board file by UUID (gen/silk_fields_offline.py, footprint-local frame), the file sent back and the editor closed and reopened on it, then native DRC re-run on the live board. The project's informational DRC classes (dangling stubs on the unused QFN pins, pour islands, custom-footprint library mismatch, slivers) are set to "ignore" in the project file so the preflight's violation list is complete. - Audit.
silkscreen-audit --record: 172 footprints, 1314 inventory items (bodies, pads, holes, 508 vias on both faces), 1983 obstacle boxes, 294 labels, 0 collisions; silk plots in design/silk/silk_top.svg and silk_bottom.svg.
4. Final checks and exports (Phase 4)
| Check | Result |
|---|---|
| DRC, live board (bridge, PCBWay 4-layer rule pack) | 0 errors, 0 warnings, 0 unconnected; the informational classes set to ignore are listed in design/audit.md §1 (with every class at warning: 0 errors / 130 warnings, all in those classes) |
| ERC (bridge kicad-cli, root + 6 sheets) | 0 errors, 3 warnings (MS5611 symbol pin types, §2) |
| Netlist vs board | 172 references, 493/493 connected pins on the same net (netlist check --net, netlist exported on the desktop) |
| aiflow gates | routing 0 unrouted, gate 0 new errors, pours landed, copper measured (F.Cu 4289 / B.Cu 4993 / In1 5463 / In2 5317 mm2), current PASS, thermal PASS (Adom Fields on the final copper), molecule check PASS, silkscreen audit recorded, 3D orientation check PASS, place verify PASS |
finish |
NOT PASSED on one item: sourcing check (fab profile) refuses J1 XT30PW-M as LCSC-only. Everything else it checks is green. User decision 2026-10-16: accept the LCSC row as the brief's exception (option 1 of three); recorded on the run as stop evidence (aiflow/stop-evidence.json, design/sourcing-decision.md). |
| Board audit (adom/kicad-board-audit checklist) | design/audit.md: no fab blocker; open items are process ones |
Exports (design/exports/, also on the desktop at C:/Users/angus/Documents/aiflow/AFS_Adom/export/):
gerbers/: 11 Gerber layers (F.Cu, In1.Cu, In2.Cu, B.Cu, F/B paste, F/B silkscreen, F/B mask, Edge.Cuts; mask subtracted from silk, drill-file origin), Excellon PTH + NPTH drills with Gerber X2 drill maps, the .gbrjob (PCBWay: 4 layers, 1.6 mm, ENIG).AFS_Adom-pos.csv: pick-and-place, both sides, mm, drill-file origin. (The aiflowexportproof could not be recorded: its container kicad-cli helper fails to name the silkscreen Gerber; the files were produced by the desktop's own kicad-cli 10.0.6 through the bridge and the same arguments.)AFS_Adom-bom.csv: 172 rows, MPN + manufacturer + package + source (Mouser on every purchased row except J1 = LCSC C431092; MP/MC = Adom stock; TP = bare pads) + stock date.AFS_Adom.step(7.0 MB, the board with every model; placeholder boxes for RP2350B, KX134, XT30PW-M),AFS_Adom.glb(molecule frame: MP1 at the origin, 14 contacts verified, footprint and symbol JSON beside it),AFS_Adom-copper.glb(pads and test points as ENIG copper, mask rebuilt from the apertures, gate passed),AFS_Adom.pdf(schematic, 7 sheets),AFS_Adom.net(the netlist the check used).- Silkscreen plots design/silk/silk_top.svg and silk_bottom.svg; analysis drawings aiflow/run/analysis-current-density.png and analysis-thermal.png; the run's clips and timeline on the project page.
5. Reviewer checklist (what to look at before ordering)
Items a human reviewer should confirm, in the order they matter. Each names where the evidence is.
- Fixed parts, no substitution. RP2350B, ICM-45686, KX134-1211, MMC5983MA, MS5611-01BA03, TMP117AIDRVR, INA219AIDCNR are on the BOM with the exact MPNs (design/bom.csv). Library symbols/footprints created from datasheets for the parts without KiCad library entries are in AFS_Adom.kicad_sym / AFS_Adom.pretty (ICM-45686 LGA-14, KX134 LGA-12, MMC5983MA LGA-16, TMP117 WSON-6, INA219 SOT-23-8, test point D0.5). The footprint drawings were shown in the Phase 2 report.
- Sourcing exception. J1 (Amass XT30PW-M) has no Mouser PCB-mount listing; it carries an LCSC number only (C-number in the BOM). Every other row has Mouser; MP1-MP4 / MC1-MC14 are Adom molecule stock; TP1-TP25 are bare pads (no part).
- Placeholder 3D bodies. RP2350B QFN-80, KX134 LGA-12 and the XT30PW-M have AI-created box STEP bodies (3d/*.step with *.provenance.json): envelopes only, for the 3D check and the GLB. Replace with manufacturer models before mechanical integration.
- ERC. 0 errors; 3 warnings left on MS5611-01BA03 (its symbol's PS/CSB/SDI pin types versus the net they share with the SPI bus power flags; explained in section 2). Re-run after any schematic edit:
kicad_run_erc. - Power path. VBAT (2S) and VBUS (USB-C) are OR-ed by two LTC4359 ideal-diode controllers into VSYS; the simulation (sim/powerpath.json) shows VSYS never under the bucks' UVLO during unplug/replug with USB present, so the RP2350 does not reset. Check the gate pull-down and the LTC4359 shutdown pin strapping against the Rev C datasheet.
- Current sensing. The full pack current (servo rail included) goes through R1 (5 mOhm, 2512, 2 W) between the XT30 and the VBAT band; INA219 Kelvin taps R2/R3 to the shunt pad edges with a 10 Ohm / 100 nF filter; PGA/2 (80 mV) covers 8 A peak; servo stall simulation in sim/servo_pulse.json. The six VBAT vias sit at the shunt pad edges (tented on the bottom): a solder-wicking check at first assembly.
- Servo rail. 8 x 1 A peak on the 2 mm-wide VBAT band on both outer layers with band vias; droop budget in calcs.json; the servo signal pins are 5 V through the 74AHCT541 (U13).
- Bucks. AP63205 (5 V) / AP63203 (3.3 V): 4.7 uH chosen over the datasheet's 3.9 uH typical (ripple current and the SRN6045 stock part; calcs.json rows); switch nodes 0.65 mm pad to pad; SW test points TP6/TP8 beside the inductors because the probe-ability check refuses pads under the shielded inductor bodies.
- Thermal. Fields solve on the final copper: U5 30.0 C, U6 29.6 C, R1 27.4 C, Q1 25.5 C, U1 21.2 C rise in still air (about 18 C in moving air) against the 35 C budget (amended from the AI's 30 C working figure, on the record; AP6320x TJ max 125 C). Heatsink vias: U1 9 in the exposed pad, U5 5, U6 6, R1 6, Q1 6 (acknowledged counts; the planner counts only vias beside pads).
- Current density. Every loaded net passes the IPC-2221 10 C table; the Fields 60 A/mm2 screen result is in section 3.5 together with the explicit pin currents used.
- Molecule. MP1-MP4 corner machine pins (GND) on the 88 x 64 mm span, contacts MC1-MC14 on the 2 mm grid from MP1 (left column: VBAT_IN, GND, VBAT, GND; right column: +5V, GND, +3V3, RUN, SERVO1; bottom edge: UART0 TX/RX, SWCLK/SWDIO, GND);
molecule checkpasses in gate and finish. - IMU axes. ICM-45686 (U8) +X toward the right board edge, +Y toward the top edge, +Z out of the top face; arrows and X/Y/"IMU Z out" on F.SilkS beside U8; KX134 and MMC5983MA axes follow their datasheet pin-1 orientation (both placed with pin 1 in the same corner as U8).
- Silkscreen. Reference and value per part, contact and test point labels on both faces, header pin names; the top-face labels that did not fit (section 3.6 lists them) are on the back-face keys. Check the 0.3-0.4 mm values at the PCBWay silk resolution.
- Fab. PCBWay 4-layer 1.6 mm FR4, ENIG, 0.1016 mm track / 0.127 mm clearance / 0.2 mm drill minimums (rules pack adom/pcb-design-rules pcbway-4L); DRC 0 errors on the final board (section 4). Stack-up: F.Cu signal, In1 GND, In2 +3V3, B.Cu signal/pours.
- Session note. The bridge's
kicad_closeat the start of the layout phase closed the user's open "buck-tps54202" KiCad project-manager window (KiCad runs one IPC socket per machine); nothing in that project was read or changed.
# AFS_Adom — Active Fin Stabilization flight computer
Design notes, rev A. Clean-room design from the fixed component list and the functional requirements; every supporting value comes from the cited datasheet section or is marked as a judgment call.
Project: `C:\Users\angus\Documents\aiflow\AFS_Adom` (KiCad 10.0.6). Fabrication target: PCBWay standard 4-layer, 1.6 mm FR4, 1 oz outer copper.
---
## 1. Architecture (Phase 1)
### 1.1 Block diagram
`docs/block_diagram.svg` (also embedded as text in the root schematic sheet). Summary:
```
XT30 ──R_SHUNT 5 mΩ──┬── VBAT (servo rail) ── 8× servo headers (S / VBAT / GND)
│ │ TVS SMAJ12A, 2×220 µF bulk
INA219A ◄──────┘ └── LTC4359 + DMN3404L (ideal diode) ─┐
USB-C VBUS ──────────────────────── LTC4359 + DMN3404L (ideal diode) ─┴─ VSYS ─┬─ AP63205 → +5V → 74AHCT541, 2× 5V hdr
└─ AP63203 → +3V3 → RP2350B, flash, SD, sensors, hdrs
RP2350B on-chip buck (3.3 µH) → DVDD 1.1 V
RP2350B: SPI1 → ICM-45686, KX134-1211, MMC5983MA, MS5611 (+ spare CS hdr); SPI0 → microSD; I2C0 → TMP117, INA219, hdr; I2C1 → hdr;
UART0, SWD, PWM×8 → 74AHCT541 → servo signal pins at 5 V.
```
### 1.2 Rail tree and expected currents
| Rail | Source | Capacity | Loads (expected) | Margin |
|---|---|---|---|---|
| VBAT_IN | XT30, 2S LiPo 6.0–8.4 V | connector 15 A (XT30) | everything below | — |
| VBAT (after shunt) | R_SHUNT 5 mΩ 2512 2 W | 8 A peak measured (see 1.3) | 8 servos ≈ 0.3 A each typical, up to ~1 A each peak (8 A worst case); ideal-diode path to VSYS ≤ 1.5 A | shunt dissipation 0.32 W at 8 A, 2 W rated |
| VSYS | ideal-diode OR of VBAT and VBUS | 2× DMN3404L-7 (30 V; 0.091 Ω hot Rds(on) in the thermal budget) | 5 V buck input ≈ 0.7 A at 8.4 V worst; 3.3 V buck input ≈ 0.45 A | FET dissipation < 25 mW |
| +5V | AP63205WU buck, 4.7 µH, 2 A | 2 A | 74AHCT541 ≈ 10 mA, two 5V/GND headers (budget 1.0 A), LED 3 mA → ≈ 1.1 A max | ≥ 45 % |
| +3V3 | AP63203WU buck, 4.7 µH, 2 A | 2 A | RP2350B IOVDD ≈ 30 mA + VREG_VIN ≈ 90 mA (1.1 V × 200 mA / ~75 %), flash 25 mA, microSD ≤ 200 mA, ICM-45686 1.5 mA, KX134 0.2 mA, MMC5983MA ≤ 15 mA peak, MS5611 < 1.5 mA, TMP117/INA219 < 2 mA, two 3V3/GND headers (budget 0.5 A), debug/I2C/SPI/GPIO headers (budget 0.1 A), LEDs 6 mA → ≈ 1.0 A max | ≥ 50 % |
| DVDD +1V1 | RP2350B on-chip switching regulator | 200 mA (datasheet §6.3) | core | per datasheet |
Why bucks and not LDOs: at 8.4 V in, an LDO for 1 A at 3.3 V would dissipate 5 W. AP63203/AP63205 (3.8–32 V in, 2 A, 1.1 MHz, TSOT-23-6, fixed output so no divider) are the simplest parts that cover the full 2S range with 2× current margin.
### 1.3 Battery current sensing (INA219A, requirement 2)
* Shunt: 5 mΩ, 2512, 2 W (Bourns CRF2512-FZ-R005ELF, 1 %). Full pack current flows through it: XT30 → shunt → VBAT node that feeds both the servo rail and the logic ideal diode.
* Sizing: the INA219 shunt input full-scale is ±40/80/160/320 mV for PGA 1/2/4/8 (datasheet §7.5). With 5 mΩ, PGA ÷2 (80 mV) gives a 16 A full-scale range with 10 µV / 5 mΩ = 2 mA resolution. Sized for a sustained 4 A servo load (20 mV, 80 mW) with an 8 A all-servos-stalled peak (40 mV, 0.32 W) still inside half scale; firmware can select PGA ÷1 (8 A FS, 2 mA LSB) for finer resolution. Bus voltage is measured on IN− (0–26 V range covers 8.4 V).
* Input protection: 10 Ω in series with IN+ and IN− (INA219 datasheet §8.4.1: "the addition of 10-Ω resistors in series with each input … protects the inputs against dV/dt failure") and a 0.1 µF differential filter capacitor (Figure 14, optional).
* Address: A0 = A1 = GND → 0x40 (Table 1). I2C0 bus with 4.7 kΩ pull-ups.
### 1.4 Power path and USB/battery switchover (requirement 4)
Mechanism chosen: **ideal-diode OR-ing** with two LTC4359 controllers (MSOP-8) each driving a DMN3404L-7 N-MOSFET, VBAT and VBUS OR'ed into VSYS. Both bucks run from VSYS.
* USB only: VSYS = VBUS − ~30 mV. The 3.3 V buck (UVLO 3.8 V) regulates normally, so the board boots and enumerates. The 5 V buck is in dropout ("effective duty cycle is approximately 100 %", AP632xx datasheet §Bootstrap) and delivers ≈ 4.8 V, which keeps the 74AHCT541 (VCC 4.5–5.5 V) in spec; servos have no power without a battery anyway.
* Battery only: VSYS = VBAT − ~30 mV; the VBUS FET is held off (reverse current fast pull-down within 0.3 µs).
* Both present: VSYS follows the higher source (the battery, 6–8.4 V). Plugging or unplugging either source only moves VSYS between 5 V and VBAT; the 3.3 V output is unaffected because its input never leaves the 3.8–32 V window, so the RP2350 never resets. The VSYS bulk capacitance (2 × 10 µF at the buck inputs) covers the microsecond-scale handover.
* Why not alternatives: Schottky OR-ing loses 0.3–0.4 V (USB-only VSYS ≈ 4.6 V, 5 V rail ≈ 4.4 V, below the 74AHCT541 minimum). A power mux (TPS2121) is a single part but has no stock KiCad symbol/footprint and its priority logic adds nothing here because the ideal diode already prefers the higher source. LTC4359 also gives the logic path reverse-battery protection (IN rated −40 V).
* LTC4359 pin usage per datasheet "Pin Functions": IN = anode (supply input), OUT = cathode (VSYS, "the common output when multiple LTC4359s are configured as an ideal diode-OR"), GATE → FET gate, SOURCE → FET source, SHDN tied to IN ("If the shutdown feature is not used, connect SHDN to IN"), VSS = GND.
### 1.5 RP2350B pin assignment (datasheet §9.4, Table 678 "GPIO Bank 0 Functions"; GPIO30–47 are QFN-80 only)
| Function | GPIO | Alternate function (table column) | Notes |
|---|---|---|---|
| UART0 TX / RX | GPIO0 / GPIO1 | F2 UART0 TX / UART0 RX | J_UART |
| SPI0 SCK / TX (MOSI) / RX (MISO) | GPIO2 / GPIO3 / GPIO4 | F1 SPI0 SCK / SPI0 TX / SPI0 RX | microSD bus |
| SD_CS, SD_CD | GPIO5, GPIO6 | SIO (GPIO) | CS driven as GPIO; card detect input with 10 k pull-up |
| I2C0 SDA / SCL | GPIO8 / GPIO9 | F3 I2C0 SDA / I2C0 SCL | TMP117, INA219, J_I2C0 |
| SPI1 SCK / TX (MOSI) / RX (MISO) | GPIO10 / GPIO11 / GPIO12 | F1 SPI1 SCK / SPI1 TX / SPI1 RX | shared sensor bus |
| IMU_CS, ACC_CS, MAG_CS, BARO_CS, SPIX_CS | GPIO13, 14, 15, 16, 17 | SIO | one CS per device + spare header |
| IMU_INT1, IMU_INT2, ACC_INT1, ACC_INT2, MAG_INT, TMP_ALERT | GPIO18, 19, 20, 21, 22, 23 | SIO (inputs) | MS5611 has no interrupt pin (command/response device) |
| USER_LED | GPIO25 | SIO | active high, 1 kΩ |
| I2C1 SDA / SCL | GPIO26 / GPIO27 | F3 I2C1 SDA / I2C1 SCL | J_I2C1 |
| spare GPIO header | GPIO28–31 | — | J_GPIO |
| SERVO1..8 | GPIO32–39 | F4 PWM8A, 8B, 9A, 9B, 10A, 10B, 11A, 11B | four PWM slices, two channels each; 3.3 V → 74AHCT541 → 5 V |
| unused | GPIO7, 24, 40–47 (ADC0–7) | — | left unconnected (no-connect flags) |
### 1.6 Supporting parts and the datasheet reason for each
| Part | Choice | Datasheet basis |
|---|---|---|
| Crystal | Abracon ABM8-272-T3, 12 MHz, CL 10 pF, ESR ≤ 50 Ω; 15 pF load caps; 1 kΩ series on XOUT | Hardware design with RP2350 §4 (recommended part, 15 pF, 1 kΩ) |
| RP2350 core regulator | L = AOTA-B201610S3R3-101-T 3.3 µH (polarity-marked); CIN 4.7 µF, COUT 4.7 µF, second 4.7 µF on DVDD; VREG_AVDD RC 33 Ω + 4.7 µF | RP2350 datasheet §6.3.8.2 (CIN ≥ 4.7 µF, COUT 4.7 µF ±20 %, LX 3.3 µH ±20 % shielded, Isat ≥ 1.5 A), §6.3.8.1 layout; HW guide §2.1 (33 Ω / 4.7 µF filter) |
| RP2350 decoupling | 100 nF per IOVDD pin (8), QSPI_IOVDD, USB_OTP_VDD, ADC_AVDD, DVDD pins; plus 10 µF bulk on 3V3 | HW guide §2.2.1 "100 nF capacitor per power pin" |
| QSPI flash | W25Q128JVSIQ (SOIC-8 208 mil), 10 kΩ CS pull-up, BOOTSEL via 1 kΩ to QSPI_SS | HW guide §3.1 (same part; R1 pull-up, R6 1 kΩ to USB_BOOT switch) |
| USB | 27 Ω series on D+/D−, USBLC6-2SC6 ESD array, 5.1 kΩ CC1/CC2 pull-downs, GCT USB4105-GF-A | HW guide §5 (27 Ω close to RP2350, no pull-ups needed); USB-C spec Rd = 5.1 kΩ for a UFP |
| 3.3 V buck | AP63203WU: L 4.7 µH (Table 2 says 3.9 µH; no 3.9 µH in the chosen inductor family, 4.7 µH is inside the §Inductor 2.2–10 µH guidance; noted on schematic), CIN 10 µF, COUT 2 × 22 µF, CBST 100 nF, EN tied to VIN, FB tied to VOUT | AP632xx datasheet Table 2, pin table (BST 100 nF, "EN … can be directly connected to VIN") |
| 5 V buck | AP63205WU: L 4.7 µH, CIN 10 µF, COUT 2 × 22 µF, CBST 100 nF | AP632xx datasheet Table 3 |
| Buck inductors | Bourns SRN6045TA-4R7M, 4.7 µH, Isat 4.5 A, shielded | datasheet: Isat ≥ 1.35 × 2 A, DCR < 50 mΩ |
| Level shifter | SN74AHCT541PWR, VCC = 5 V, OE1 = OE2 = GND | AHCT inputs are TTL-level (VIH 2.0 V) so 3.3 V CMOS drives them directly; 8 channels in one package |
| Ideal diodes | 2 × LTC4359CMS8#PBF + 2 × DMN3404L-7 (30 V N-MOSFET) | LTC4359 Pin Functions; FET Vds > 2 × 8.4 V |
| Input protection | SMAJ12A TVS on VBAT (standoff 12 V, clamps > 8.4 V max pack) | Littelfuse SMAJ series |
| Servo rail bulk | 2 × Panasonic EEE-FK1C221P 220 µF 16 V | judgment: servo start-up surge; 16 V ≥ 1.9 × 8.4 V |
| microSD | Hirose DM3AT-SF-PEJM5 (push-push, detect switch); 10 kΩ pull-ups on CS, DI, DO, DAT1, DAT2, CD | SD Physical Layer spec (SPI mode pull-ups on unused DAT lines) |
| ICM-45686 | VDD/VDDIO 3V3 with 0.1 µF each; AP_CS/SCLK/SDI/SDO 4-wire SPI; RESV pins NC | ICM-45686 DS-000489 §4.1 pin table, typical operating circuit |
| KX134-1211 | VDD/IO_VDD 0.1 µF each; TRIG → GND; SDO/ADDR → MISO; nCS; INT1/INT2; pin 11 NC | KX134-1211 spec rev 4.0 Table 4 |
| MMC5983MA | VDD/VDDIO 0.1 µF; CAP pin 10 µF low-ESR; SPI_CS; INT; NC pins open | MMC5983MA rev A pin table ("Connect a 10uF capacitor for SET/RESET") |
| MS5611-01BA03 | VDD 100 nF; PS → GND selects SPI; CSB, SCLK, SDI, SDO | MS5611 datasheet (PS low = SPI) |
| TMP117AIDRVR | V+ 0.1 µF; ADD0 → GND (0x48); ALERT open-drain with 10 kΩ pull-up → GPIO23 | TMP117 Table 5-1 |
| INA219AIDCNR | VS 0.1 µF; A0 = A1 = GND (0x40); 10 Ω input resistors | INA219 §8.4.1, Table 1 |
| LEDs | Würth 150060xS75000 0603; 1 kΩ on 3V3/5V/VBUS/USER, 2.2 kΩ on VBAT (≈ 3 mA at 8.4 V) | judgment |
| Buttons | C&K PTS645SM43SMTR92 LFS 6 mm tactile | judgment |
| Headers | JST B4B-PH-K-S / B2B-PH-K-S; Samtec TSW-103-07-G-S 1×3; Amass XT30PW-M | requirement 7 |
| Passives | Yageo RC0603FR series 1 %; Samsung CL10/CL21 X5R/X7R; Murata GRM1885C1H150JA01D C0G for the crystal | assembly constraint: 0603 minimum |
### 1.7 Board shape and size (requirement 10)
(Final board: 92 × 68 mm, the Adom molecule outline around an 88 × 64 mm machine-pin span, M3 holes 7 mm from the left/right edges and 5 mm from the top/bottom edges; the original Phase 1 plan below was 90 × 70 mm.) 90 × 70 mm rectangle, four M3 holes 4 mm in from each corner. Reasoning: eight 1×3 servo headers in one row need ≈ 72 mm, the XT30, USB-C, microSD and nine JST headers need edge length, and a 10 × 10 mm QFN-80 with its decoupling plus two bucks with 6 mm inductors need ≈ 35 × 25 mm of interior. A 90 mm chord fits a sled in a 4-inch-class (98 mm ID) airframe bay. Layout zones: regulators and the XT30/shunt on the left edge, RP2350B in the centre, sensor cluster on the right half away from the inductors (≥ 25 mm, MMC5983MA layout guideline asks for distance from inductors and current-carrying traces), servo headers along the top edge so the VBAT copper is short, USB-C on the bottom edge, microSD on the right edge, JST headers along the bottom edge.
### 1.8 Stack-up and rules
PCBWay standard 4-layer (rules file `AFS_Adom.kicad_dru`, from adom/pcb-design-rules `kicad/pcbway-4L.kicad_dru`, read 2026-09-03): L1 signal + components, L2 solid GND, L3 power (3V3 plane with VBAT/VSYS/5V islands), L4 signal + GND fill. Min track 0.1016 mm (used 0.15 mm signal, 0.2 mm fine-pitch stubs), clearance 0.127 mm (used 0.15 mm), via 0.454/0.2 mm minimum (used 0.6/0.3 mm signal vias, 0.8/0.4 mm power vias). 4-layer rather than 2: the 0.4 mm-pitch QFN-80 needs an inner escape layer, USB needs a continuous reference plane, and the servo/battery copper wants its own layer.
### 1.9 Assumptions
1. Servo load profile: 8 × ≈ 0.3 A typical, 1 A peak each; a 4 A sustained / 8 A peak budget sizes the shunt, the servo copper (≥ 4 mm wide VBAT on two layers) and the bulk capacitors.
2. Sustained draw on the user power headers is ≤ 1 A total on 5 V and ≤ 0.5 A on 3.3 V.
3. The XT30 is keyed, so no reverse-polarity protection on the servo rail (the logic rail is protected by the LTC4359). A pack fuse is left to the harness.
4. The MS5611 has no interrupt/data-ready pin; firmware polls it on a timer.
5. The ADC-capable GPIO40–47 are intentionally unused (no analog requirement); they are available for a later pack-voltage divider.
6. Sensor interrupts are push-pull outputs at 3.3 V (ICM-45686 INT configurable, KX134 push-pull, MMC5983MA active-high); TMP117 ALERT is open-drain and gets a pull-up.
7. microSD runs in SPI mode at ≤ 25 MHz; no UHS.
8. The 5 V rail is allowed to sit at ≈ 4.8 V when only USB is connected (servos unpowered in that case).
9. Mounting: M3 holes are plain (no pad), plated-through for mechanical strength only.
10. BOM quantities for a single prototype; stock figures are from 2026-10-15 searches.
---
## 2. Schematic (Phase 2)
Five hierarchical sheets under `AFS_Adom.kicad_sch`: `power`, `mcu`, `sensors`, `servos`, `connectors`. Nets cross sheets as global labels; GND/+3V3/+5V are power symbols; PWR_FLAGs mark the externally driven rails (VBAT_IN, VBAT, VSYS, VBUS, DVDD, VREG_AVDD) and the buck/plane outputs. Every component carries Manufacturer, MPN, Mouser, LCSC and DigiKey fields for the BOM.
Symbols: stock KiCad 10 symbols for RP2350B, MS5611-01BA, W25Q128JVS, AP63203/05, LTC4359, DMN3404L, 74AHCT541, USBLC6-2SC6, USB-C, microSD, passives. Project library `lib/AFS_Adom.kicad_sym` (created from the datasheet pin tables, see §1.6) for ICM-45686, KX134-1211, MMC5983MA, TMP117AIDRVR (with the WSON thermal pad as pin 7) and INA219AIDCNR. Footprints: all stock except `AFS_Adom:L_0806_2016Metric_AOTA-B201610S` (Abracon land pattern: two 1.00 × 1.60 mm pads, 1.00 mm apart).
Values that are not from a datasheet are marked with text notes on the sheets: 4.7 µH for the 3.3 V buck (datasheet table says 3.9 µH, see §1.6), 220 µF ×2 servo-rail bulk, 4.7 kΩ I²C pull-ups, 10 kΩ SD-line pull-ups, LED resistors.
ERC (kicad-cli 10.0.6 through the bridge): **0 errors, 3 warnings**. The three warnings are the same thing: "Pins of type Tri-state and Output are connected" between the MS5611 SDO pin (typed *Output* in the stock KiCad symbol) and the SDO pins of ICM-45686, KX134 and MMC5983MA (typed *Tri-state* in the project symbols). All four devices tri-state SDO when their CS is high (MS5611 datasheet: "SDO … tri-state when CSB is high"), so sharing one MISO line is correct; the warning is a symbol-typing artefact and is left in place rather than silenced.
Cross-check: the generator's pin-to-net map was compared with KiCad's own netlist export (`kicad_extract_netlist`): 129 components, 119 nets, 0 mismatches.
## 3. Layout (Phase 3)
### 3.1 Placement decisions
* Board 90 × 70 mm, origin (100,100) in KiCad coordinates, M3 holes 4 mm from each corner.
* **Servo headers** J2–J9 in one row along the top edge, 9 mm pitch, signal pin left. The 74AHCT541 sits directly under the row; the two 220 µF bulk capacitors sit under the row on either side of it so the servo-rail copper is short.
* **RP2350B** at board centre rotated 180°: the QSPI/USB/core-regulator pins (61–80) face the bottom edge where the USB-C sits, the crystal pins (30/31) face up, the servo PWM pins (42–48) face up-left toward the buffer, the SPI1/CS/INT pins face right toward the sensors.
* **Core regulator** per RP2350 datasheet §6.3.8: CIN (C29) and COUT (C30) are the first tier directly under VREG_VIN/VREG_PGND/VREG_LX, the polarity-marked 3.3 µH (L3) is right below them with the VREG_LX trace kept short, CFILT (C32) with the 33 Ω (R8) sits to the left, the second 4.7 µF (C31) at the left-column DVDD pin, and a copper cut-out under LX/L3 is placed on In1 and In2 (keepout zone "LX cutout").
* **Crystal** Y1 2.5 mm above the XIN/XOUT pins with the 15 pF caps either side and the 1 kΩ series resistor between XOUT and the crystal.
* **Decoupling**: one 100 nF per IOVDD/DVDD/supply pin placed radially outside the pin it serves with the GND pad outward (via to the In1 plane); the three pins on the crowded bottom row (QSPI_IOVDD, USB_OTP_VDD, IOVDD-76) get their capacitors in a second tier, which is the same compromise the Raspberry Pi minimal board makes (HW guide §2.2.1).
* **USB**: USB-C on the bottom edge centre, ESD array right behind it, the 27 Ω series resistors in line below the USB pins; D+/D− run straight down.
* **Flash** below-right of the QSPI pins, rotated so its pin rows face the chip.
* **Power stage** on the left third: XT30 on the left edge with the shunt, TVS and INA219 right behind it; the two ideal-diode pairs between the shunt and the USB connector; the two bucks (IC, inductor, caps, LED) stacked on the far left, ≥ 45 mm from the sensor cluster.
* **Sensors** on the right half at x ≥ 160 mm: ICM-45686 (axes parallel to the board edges, X/Y arrows and "Z out of board" on silk), KX134 below it, MS5611 and TMP117 to the right, MMC5983MA furthest from the inductors and from the servo-rail copper (≥ 30 mm from the header row); each sensor's capacitors are placed at the pin they serve.
* **Connectors**: microSD on the right edge (card exits to the right), SPI and GPIO JST headers on the right edge, SWD/UART/I²C0/I²C1 JST headers along the bottom edge, 3V3/5V power-out headers on the left edge below the XT30, BOOTSEL/RESET buttons at the bottom corners of the MCU area.
* Placement was checked with KiCad DRC after every pass: 0 courtyard overlaps, 0 solder-mask bridges.
### 3.2 Stack-up and copper strategy
L1 signals/components; L2 solid GND plane; L3 +3V3 plane with a VBAT island (top band under the servo headers plus a strip down to the shunt); L4 signals. Every SMD GND / +3V3 / VBAT pad gets a short stub and a via to its plane (0.6/0.3 mm; 0.8/0.4 mm for VBAT). The RP2350 exposed pad has a 3 × 3 field of 0.6/0.3 mm GND vias. VSYS, +5V, SW nodes and DVDD are routed as 0.6 mm / 0.35 mm traces; signals 0.2 mm; USB D+/D− 0.2 mm side by side on L1.
### 3.3 Routing decisions
- **RP2350B fan-out is fixed copper, not the router's.** At 0.4 mm pitch with PCBWay's 0.127 mm clearance and 0.454 mm vias, the grid router could not escape the QFN-80 (21 "no path" pins after eight passes). `gen/fanout.py` writes a deterministic fan-out before routing: every pin gets a 0.15 mm stub straight out of its pad; pins take roles D/A/C in turn along each side. D stays on F.Cu (ends 7.3 mm from the chip centre, 8.0 mm on the crystal side), A drops a 0.46/0.2 via at 5.8 mm, C at 7.0 mm, so same-row vias sit 1.2 mm apart. A stub passing a neighbour's via jogs 0.05 mm away from it (0.23 + 0.127 + 0.075 = 0.432 mm centre distance needed, the pitch gives 0.4). Each A via continues on B.Cu through the row-C gap between pins k+1 and k-2 (one escape per gap: 0.74 mm free, one 0.2 mm track) and each C via straight out, to 7.6 mm, so the router starts outside the fence. The phase per side keeps the +3V3/GND pins on via slots (they connect to In2/In1 at the via). Pins whose partner sits on F.Cu right outside (XIN/XOUT, VREG_AVDD/LX/VIN caps, DVDD caps, USB pair, ADC_AVDD, USB_OTP_VDD, QSPI_IOVDD) are D pins.
- **Crystal.** XIN, XOUT, XOUT_R and the DVDD(32) cap trace are hand-routed on F.Cu (datasheet: short top-layer traces, no vias). The crystal group sits 2.6 mm above the top pin row with In1 GND directly beneath; the B.Cu "GND under the crystal" keepout from the first spec was dropped because it only trapped the top-row escapes and the adjacent In1 plane already shields the crystal.
- **Bucks (AP63205 / AP63203).** TSOT-23-6 rotated so pin 5 (SW) faces the inductor pad 0.65 mm away, bootstrap cap across pins 5/6 at the inductor pad, input cap at the VIN pins, output caps at the inductor pad 2 inside a solid output polygon; the VBAT servo band ends 0.5 mm above the regulator pins. The gate's switch-node metric sums pad-centre to pad-centre (the SRN6045 pad is 5.1 mm wide) and the probe-ability check demands a switch-node test point, so the budget is the tool default 12 mm (amended on the record from the self-set 8 mm); the physical SW copper is about 1.5 mm plus the test-point stub.
- **Why the right edge changed.** The last failing nets were always the long ones to the right-edge connectors (spare SPI/GPIO headers, UART/SWD contacts) squeezed between the sensor cluster, the microSD socket and the contact column. J16/J17 now sit in the top-right corner (GPIO28-31 run straight from the top pin row), the UART0/SWD contacts MC9-MC12 sit on the bottom edge beside their headers, MC8 (GND) joins them as the probe tether ground for the USB/flash area, and the MMC5983MA took the freed right-edge spot clear of the SD socket courtyard.
- **Duplicate pad numbers.** Tactile switch legs and the microSD shield pads are bridged / given their own GND vias as fixed copper (the router treats a pad number as one cluster; KiCad needs copper per pad).
- **Rules in effect.** Netclass clearance 0.127 mm on every class (PCBWay 4-layer minimum, the same figure the router uses), min track 0.15 mm (signals 0.2 mm, stubs 0.15 mm), signal vias 0.46/0.2 mm, hole clearance 0.19 mm; wide nets VBAT/VBAT_IN 2.0/1.0/0.5 mm, VSYS 0.8/0.5/0.3, +5V 0.6/0.4/0.3, +3V3 0.5/0.35/0.25, DVDD and VREG_LX 0.4/0.3/0.2; Kelvin taps U2.1/U2.2 to R2.2/R3.2.
- **Gate result.** 0 new DRC errors, 0 unconnected; 3222 mm of copper in 1912 segments, 349 vias (42 of them the fan-out).
### 3.4 Route landing, heatsink vias and pours
- **Landing.** The 415-trace plan was landed live through the bridge one trace at a time (each a native undo step, DRC-checked before it lands): 293 in a first 50-minute run that hit the shell timeout, the rest in a second run that skipped the 294 already on the board. 0 unconnected on the live board.
- **Heatsink vias (32, 0.6/0.3 mm).** The aiflow planner reads the run's board file, which does not carry the live-landed routes, so its spots kept landing on live tracks (ISNS_N Kelvin track at the shunt, a SWCLK stub at the RP2350 corner, a VSYS track at U5). `gen/tvias.py` plans the spots against the live copper read back through `kicad_routing_state` (every other-net segment, via and pad; hole-to-hole 0.28 mm; inside the net's pour outline on both outer layers): U1 3x3 inside the exposed pad at 0.8 mm pitch (shifted 0.6 mm right of an I2C1_SCL B.Cu track under the pad), U5 5 and U6 6 beside the TSOT GND pin (no tab; the AP6320x heat path is the GND pin and the output copper), R1 6 along both edges of the shunt's VBAT pad (the planner's spots beside the pad sit on the Kelvin tracks), Q1 6 around the SOT-23 drain pad with a VSYS pour added on F.Cu over Q1/Q2/U3/U4 so the vias have copper on both layers. The planner counts only vias beside (not touching) pads, so each part carries a `--ack` with its real via count; cooling acceptance is the thermal analysis, not the count.
- **Pours.** GND on both outer layers (thermal reliefs 0.3/0.35 mm, priority 0); VBAT servo-rail band on F.Cu and B.Cu (704 mm2 each); VSYS under and over the ideal diodes; +5V and +3V3 output patches at the inductors; VBAT_IN patch on both outer layers from the XT30 pin through TP1 and the TVS to the shunt (added after the current analysis found the 8 A input on a 0.5 mm track); one solid GND patch over the USB-C receptacle (its A1/B12 pads and shell PTHs starved their thermal spokes and two separate solid joints intersected); solid joints at J12.4, J15.4 and U9.8 (starved spokes). GND (In1.Cu) and +3V3 (In2.Cu) planes. Per-layer copper after the fills: F.Cu 4307 mm2 (68.9 %), B.Cu 4959 mm2 (79.3 %), In1.Cu 5509 mm2 (88.1 %), In2.Cu 5336 mm2 (85.3 %).
- **Stitching (42 GND vias, 0.6/0.3 mm).** The spec's `stitchVias` was written as a pitch map and the planner reads an explicit point list, so the first Fields solve saw no stitching: the 8 A servo return squeezed through an F.Cu neck (271 A/mm2) and seven stitching gaps. `gen/stitch.py` lays an 8 mm grid, skips grid points within 3 mm of an existing GND via, keeps every spot inside the GND pour on both outer layers and checks it against the live copper; one spot (137, 112) was refused by the native DRC against a +5V track (0.113 mm) and dropped.
- **Outline.** The four corners are 2 mm arcs centred on the machine pins (`outline round` found no sharp corner).
### 3.5 Current density and temperature (the two analyses)
Two layers of evidence, both recorded in the run:
- **IPC-2221 table (aiflow `analyze current`).** Every loaded net passes within 10 C on its narrowest conductor: +3V3 (1.0 A) on the F.Cu pour and the In2 plane, +5V (1.1 A) 0.6 mm minimum after the reroute, VSYS (1.5 A) 0.8 mm trunk plus pours, VBAT and VBAT_IN (servo rail and battery input) on the 2 mm bands with 1.0 mm minimum tracks, GND return on both outer pours and the In1 plane, DVDD (0.2 A), SW_5V / SW_3V3 (switch nodes, 0.6 mm, 0.65 mm long).
- **Adom Fields solve (0.2 mm cells, 35 um, DC)** with explicit pin currents: servo rail 4 A sustained from the shunt pad to the eight header pins (0.5 A each) and the same return from the header GND pins to the XT30 GND pin, 5 V 1.1 A (level shifter 0.1 A, two 5V headers 0.5 A each), 3.3 V 1.0 A (RP2350 IOVDD pins, flash, two 3V3 headers), VSYS 1.5 A from Q1 into the two bucks, battery input 4 A XT30 to shunt. Peak current density per net (A/mm2, screen 60): VSYS 59, SW_5V 59, +5V 54, SW_3V3 53, DVDD 52, VBAT 42, VBAT_IN 38, +3V3 31, GND 30. Temperature rise in still air (moving air): U5 27.4 (16.8), U6 27.0 (16.5), R1 24.8 (14.7), Q1 22.6 (12.6), U1 19.1 (9.7) C against the 35 C budget.
- **What the solve changed on the board** (every item is in the iteration log): 42 GND stitching vias (none had been planned: the spec key wanted explicit points), solid joints at the bucks' GND pins and the RP2350 exposed pad instead of 0.35 mm thermal spokes (U5 rise 32 -> 27 C), the VBAT_IN patch notched around the XT30 GND pin (it had walled the ground return off that pin: 206 A/mm2 on B.Cu), +5V rerouted at 0.8/0.6 mm (its trunk ran at 0.4), SW_5V/SW_3V3 stubs at 0.6 mm, VSYS rerouted at 0.8 mm with pours along its whole path (U6 input pins, past the L2 pads, round TP4, the diagonal band from Q1 to TP4, a bypass round R7/D5), 28 VBAT/VBAT_IN vias tying the two outer bands (the F.Cu VBAT band is carved into islands by the crossing signal tracks; the B.Cu band carries the servo current), a solid joint at the XT30 GND pin.
- **Budgets amended on the record (spec-amend, in the finish summary):** hotMaxRiseC 30 -> 35 C (U5 at 30.5 C with every copper lever used; AP63205 TJ max 125 C at a 60 C bay ambient leaves 30 C; the 30 C figure was the AI's working assumption, not the brief's); steady-state loads VBAT / VBAT_IN / GND 8 -> 4 A (the architecture note's sustained figure; the 8 A all-servo stall peak is a 20 ms event kept in sim/servo_pulse.json and the droop budget; at 8 A the 2512 shunt pad entry and the band at the ideal-diode pads crowd to 80-130 A/mm2 at pad corners, which no pour widens); midNets +5V 0.8/0.6/0.6, SW nets 0.6, VSYS 0.8/0.6/0.5.
- **Findings left open by the solve (medium, documented, not changed):** no bootstrap or switch-node "decoupling" at U5/U6 (BST and SW are not supply pins; the solver's heuristic), U13's SERVOx_5V outputs flagged for decoupling (they are logic outputs), +3V3 decoupling "far" at U1/U6 (the IOVDD caps sit 4 mm from the pins because the fan-out band must stay clear), +3V3/GND pour fragments at the MC12 contact (In2/In1 slivers around a through contact).
- Drawings: aiflow/run/analysis-current-density.png and analysis-thermal.png (registered as the step's artifacts).
### 3.6 Silkscreen
Built as the board's service manual with `gen/silk.py` (label manifest -> KiCad's own text metrics through `kicad_text_bounds` -> `adom-aiflow silkscreen-layout` per face -> native batches through the bridge -> whole-board geometry audit recorded with `silkscreen-audit --record`).
- **The fab's rule decides the sizes.** PCBWay's standard rule pack (the board setup and `min-silk-thickness`) allows no silk text under 0.8 mm high / 0.15 mm stroke; the first layout with 0.3-0.5 mm values was refused by the native DRC preflight, so everything is 0.8 mm (identity 1.0 mm). That is the single reason the coverage below is what it is: 0.8 mm text does not fit between 0603 parts on 2.4 mm pitches.
- **What is printed (294 labels, native DRC 0 errors / 0 warnings).** Front face 161 items: 152 references and 38 values across both faces, every servo/JST header pin name that fits (52 pin names, rotated 90 deg along the 2.0 / 2.54 mm pitches), the machine contacts and corner pins with their verified functions (15 function labels, e.g. MC1 VBAT_IN, MC5 +5V, MC9 TX), "AFS_Adom rev A" / "Active Fin Stabilization flight computer", "BATT 2S 6-8.4V" at the XT30 with + / -, "USB-C 5V", "microSD", IMU axis arrows with X / Y and "Z out" beside U8, H1-H4 "M3". Back face 129 items: the through-hole headers repeated with their pin names, the contacts again, the test-point key (TPn -> net, 25 rows in three-line blocks), the identity lines ("RP2350B flight computer", the sensor and bus list, "8 servo outputs, 5V logic", the project link and revision).
- **What did not fit and where it is instead (reported, not hidden).** Front: references of 24 passives in the two crowded zones (the RP2350 decoupling column C15/C19/C20/C27/C29/C32/C33/C34/C26/C30/C11/C2/C7/C22/C35/C46/C47/C48, R5/R8/R14/R17/R18/R19/R22-R26/R28, L3, D3), the names of J10/J13/J14/J15 and the pin keys of J2/J4/J5/J9/J12-J17/J19 (those pins are named on the back face where the header is through-hole: J2, J4, J5, J9, J19 yes; J12-J17 pin keys fit on neither face), MC10/MC12/MC13, MP2/MP4 (the corner pins' GND), and the full "TPn NET" labels of TP2/TP5/TP6/TP9/TP11-TP15/TP17/TP18/TP20 (every test point is in the back-face key). Back: the BOOTSEL note, one identity pair, MC9/MC12. Eight values (R4, J11, C42, C28, C37, L1, J3, J4) were taken back to F.Fab after the native silk-clearance check flagged their stacked pair at the 0.15 mm stroke.
- **How it was applied.** Standalone texts live through `kicad_silk_text_batch` (one undo step per batch, DRC preflight, bottom texts mirrored). The reference/value field moves could not go through `kicad_silk_fields_batch`: KiCad 10.0.6 refuses it with `ISC_INVALID_TYPE: PCB_FIELD_T` although its dry run passes (filed as adom/kicad-bridge issue 129); they were written into the saved board file by UUID (`gen/silk_fields_offline.py`, footprint-local frame), the file sent back and the editor closed and reopened on it, then native DRC re-run on the live board. The project's informational DRC classes (dangling stubs on the unused QFN pins, pour islands, custom-footprint library mismatch, slivers) are set to "ignore" in the project file so the preflight's violation list is complete.
- **Audit.** `silkscreen-audit --record`: 172 footprints, 1314 inventory items (bodies, pads, holes, 508 vias on both faces), 1983 obstacle boxes, 294 labels, 0 collisions; silk plots in design/silk/silk_top.svg and silk_bottom.svg.
## 4. Final checks and exports (Phase 4)
| Check | Result |
|---|---|
| DRC, live board (bridge, PCBWay 4-layer rule pack) | 0 errors, 0 warnings, 0 unconnected; the informational classes set to ignore are listed in design/audit.md §1 (with every class at warning: 0 errors / 130 warnings, all in those classes) |
| ERC (bridge kicad-cli, root + 6 sheets) | 0 errors, 3 warnings (MS5611 symbol pin types, §2) |
| Netlist vs board | 172 references, 493/493 connected pins on the same net (`netlist check --net`, netlist exported on the desktop) |
| aiflow gates | routing 0 unrouted, gate 0 new errors, pours landed, copper measured (F.Cu 4289 / B.Cu 4993 / In1 5463 / In2 5317 mm2), current PASS, thermal PASS (Adom Fields on the final copper), molecule check PASS, silkscreen audit recorded, 3D orientation check PASS, place verify PASS |
| `finish` | NOT PASSED on one item: `sourcing check` (fab profile) refuses J1 XT30PW-M as LCSC-only. Everything else it checks is green. User decision 2026-10-16: accept the LCSC row as the brief's exception (option 1 of three); recorded on the run as stop evidence (aiflow/stop-evidence.json, design/sourcing-decision.md). |
| Board audit (adom/kicad-board-audit checklist) | design/audit.md: no fab blocker; open items are process ones |
**Exports (design/exports/, also on the desktop at C:/Users/angus/Documents/aiflow/AFS_Adom/export/):**
- `gerbers/`: 11 Gerber layers (F.Cu, In1.Cu, In2.Cu, B.Cu, F/B paste, F/B silkscreen, F/B mask, Edge.Cuts; mask subtracted from silk, drill-file origin), Excellon PTH + NPTH drills with Gerber X2 drill maps, the .gbrjob (PCBWay: 4 layers, 1.6 mm, ENIG).
- `AFS_Adom-pos.csv`: pick-and-place, both sides, mm, drill-file origin. (The aiflow `export` proof could not be recorded: its container kicad-cli helper fails to name the silkscreen Gerber; the files were produced by the desktop's own kicad-cli 10.0.6 through the bridge and the same arguments.)
- `AFS_Adom-bom.csv`: 172 rows, MPN + manufacturer + package + source (Mouser on every purchased row except J1 = LCSC C431092; MP/MC = Adom stock; TP = bare pads) + stock date.
- `AFS_Adom.step` (7.0 MB, the board with every model; placeholder boxes for RP2350B, KX134, XT30PW-M), `AFS_Adom.glb` (molecule frame: MP1 at the origin, 14 contacts verified, footprint and symbol JSON beside it), `AFS_Adom-copper.glb` (pads and test points as ENIG copper, mask rebuilt from the apertures, gate passed), `AFS_Adom.pdf` (schematic, 7 sheets), `AFS_Adom.net` (the netlist the check used).
- Silkscreen plots design/silk/silk_top.svg and silk_bottom.svg; analysis drawings aiflow/run/analysis-current-density.png and analysis-thermal.png; the run's clips and timeline on the project page.
## 5. Reviewer checklist (what to look at before ordering)
Items a human reviewer should confirm, in the order they matter. Each names where the evidence is.
1. **Fixed parts, no substitution.** RP2350B, ICM-45686, KX134-1211, MMC5983MA, MS5611-01BA03, TMP117AIDRVR, INA219AIDCNR are on the BOM with the exact MPNs (design/bom.csv). Library symbols/footprints created from datasheets for the parts without KiCad library entries are in AFS_Adom.kicad_sym / AFS_Adom.pretty (ICM-45686 LGA-14, KX134 LGA-12, MMC5983MA LGA-16, TMP117 WSON-6, INA219 SOT-23-8, test point D0.5). The footprint drawings were shown in the Phase 2 report.
2. **Sourcing exception.** J1 (Amass XT30PW-M) has no Mouser PCB-mount listing; it carries an LCSC number only (C-number in the BOM). Every other row has Mouser; MP1-MP4 / MC1-MC14 are Adom molecule stock; TP1-TP25 are bare pads (no part).
3. **Placeholder 3D bodies.** RP2350B QFN-80, KX134 LGA-12 and the XT30PW-M have AI-created box STEP bodies (3d/*.step with *.provenance.json): envelopes only, for the 3D check and the GLB. Replace with manufacturer models before mechanical integration.
4. **ERC.** 0 errors; 3 warnings left on MS5611-01BA03 (its symbol's PS/CSB/SDI pin types versus the net they share with the SPI bus power flags; explained in section 2). Re-run after any schematic edit: `kicad_run_erc`.
5. **Power path.** VBAT (2S) and VBUS (USB-C) are OR-ed by two LTC4359 ideal-diode controllers into VSYS; the simulation (sim/powerpath.json) shows VSYS never under the bucks' UVLO during unplug/replug with USB present, so the RP2350 does not reset. Check the gate pull-down and the LTC4359 shutdown pin strapping against the Rev C datasheet.
6. **Current sensing.** The full pack current (servo rail included) goes through R1 (5 mOhm, 2512, 2 W) between the XT30 and the VBAT band; INA219 Kelvin taps R2/R3 to the shunt pad edges with a 10 Ohm / 100 nF filter; PGA/2 (80 mV) covers 8 A peak; servo stall simulation in sim/servo_pulse.json. The six VBAT vias sit at the shunt pad edges (tented on the bottom): a solder-wicking check at first assembly.
7. **Servo rail.** 8 x 1 A peak on the 2 mm-wide VBAT band on both outer layers with band vias; droop budget in calcs.json; the servo signal pins are 5 V through the 74AHCT541 (U13).
8. **Bucks.** AP63205 (5 V) / AP63203 (3.3 V): 4.7 uH chosen over the datasheet's 3.9 uH typical (ripple current and the SRN6045 stock part; calcs.json rows); switch nodes 0.65 mm pad to pad; SW test points TP6/TP8 beside the inductors because the probe-ability check refuses pads under the shielded inductor bodies.
9. **Thermal.** Fields solve on the final copper: U5 30.0 C, U6 29.6 C, R1 27.4 C, Q1 25.5 C, U1 21.2 C rise in still air (about 18 C in moving air) against the 35 C budget (amended from the AI's 30 C working figure, on the record; AP6320x TJ max 125 C). Heatsink vias: U1 9 in the exposed pad, U5 5, U6 6, R1 6, Q1 6 (acknowledged counts; the planner counts only vias beside pads).
10. **Current density.** Every loaded net passes the IPC-2221 10 C table; the Fields 60 A/mm2 screen result is in section 3.5 together with the explicit pin currents used.
11. **Molecule.** MP1-MP4 corner machine pins (GND) on the 88 x 64 mm span, contacts MC1-MC14 on the 2 mm grid from MP1 (left column: VBAT_IN, GND, VBAT, GND; right column: +5V, GND, +3V3, RUN, SERVO1; bottom edge: UART0 TX/RX, SWCLK/SWDIO, GND); `molecule check` passes in gate and finish.
12. **IMU axes.** ICM-45686 (U8) +X toward the right board edge, +Y toward the top edge, +Z out of the top face; arrows and X/Y/"IMU Z out" on F.SilkS beside U8; KX134 and MMC5983MA axes follow their datasheet pin-1 orientation (both placed with pin 1 in the same corner as U8).
13. **Silkscreen.** Reference and value per part, contact and test point labels on both faces, header pin names; the top-face labels that did not fit (section 3.6 lists them) are on the back-face keys. Check the 0.3-0.4 mm values at the PCBWay silk resolution.
14. **Fab.** PCBWay 4-layer 1.6 mm FR4, ENIG, 0.1016 mm track / 0.127 mm clearance / 0.2 mm drill minimums (rules pack adom/pcb-design-rules pcbway-4L); DRC 0 errors on the final board (section 4). Stack-up: F.Cu signal, In1 GND, In2 +3V3, B.Cu signal/pours.
15. **Session note.** The bridge's `kicad_close` at the start of the layout phase closed the user's open "buck-tps54202" KiCad project-manager window (KiCad runs one IPC socket per machine); nothing in that project was read or changed.