
Monolith
MidwestMotorBoy/Battery-Bank
Monolith: an ultralight IP67 power bank for backpacking. 4S BAK 65E 21700 (91 Wh, under the 100 Wh airline limit), two bidirectional 100 W USB-C PD ports, Bluetooth LE (TI CC2340) with an iPhone app.

Monolith: an ultralight IP67 power bank for backpacking. 4S BAK 65E 21700 (91 Wh, under the 100 Wh airline limit), two bidirectional 100 W USB-C PD ports, Bluetooth LE (TI CC2340) with an iPhone app. KiCad electronics, MJF nylon enclosure.
MonolithDev is an open-source printed circuit board by MidwestMotorBoy, from the MidwestMotorBoy/Battery-Bank repository on GitHub. It is a 6-layer board of 196 × 115 mm with 430 parts on 255 nets, routed with 2,656 tracks and 974 vias.
It is built around the BQ25756RRVR, M24512-DFMC6TG and CL05B104KB54PNC, with the CL31A226KAHNNNE, BAT54WS and GMK325BJ226MM-P among its other parts. Its parts include 141 resistors, 116 capacitors, 20 transistors, 13 diodes and 4 ICs. It belongs with the power boards of this library.
Dev board for the Monolith battery bank, described in ../../docs/devboard/circuit-description.md. The schematic was first drawn on 2026-10-11 with the KiCad MCP.
This board was never ordered or built. On 2026-10-18 the dev board was skipped and production P0 was built directly. The live design is P0 in
../Production/on theProductionbranch; the current spec isdocs/spec.md. This folder is kept as the reviewed reference (rev A8) that P0 was derived from, and as history: everything below describes the dev board as it stood on 2026-10-17, not the current product. The cell assumed here (EVE INR21700-58E, used for the cell 3D model on the holder footprint) is superseded too: the pack uses the BAK N21700CX-65E (4S1P, 14.0 V nominal, 91 Wh); seedocs/spec.md.Still in use by P0, so don't delete or rename:
hardware/Production/tools/make_production.pyandmake_board.pycopy the schematic sheets,MonolithDev.kicad_sym,MonolithDev.pretty/,fp-lib-table,sym-lib-table,MonolithDev.kicad_pro,MonolithDev.kicad_druand readMonolithDev.kicad_pcbfrom here;make_3d_models.pycopies three STEP files from3dmodels/;layout_production.pyrunstools/move_region.py,tools/place_fields.pyandtools/check_overlaps.py(which importtools/sch_geom.py);pack_bus_sims.py(and through itlow_profile_sims.py) loadstools/cap_sims.py.
Status (rev A8, 2026-10-14; routed 2026-10-17):
../../docs/devboard/schematic-review-*.md), cost-down applied, review 4 fully applied (rev A8, items 41–42).tools/place_blocks.py), updated for rev A8; routed and DRC-clean on 2026-10-17 (item 49), fab outputs in fab/ (item 50). Not ordered, not built.See Status for the checks and the costed BOM.
| File | Contents |
|---|---|
MonolithDev.kicad_sch | Root: sheet blocks, PD controller address straps (R1–R4) |
gauge.kicad_sch | 4 × 21700 holders, pack connector, fuse, BQ40Z50-R2, 1 mΩ shunt, CHG/DSG FETs, second-level protection (BQ294700 + chemical fuse F102), EV2400 header (1xx) |
power.kicad_sch | 10 Ω R_MEAS, INA190 ×2 with test-loop outputs, HT7550-1 5 V LDO, TPS62177 3.3 V rail (2xx) |
mcu.kicad_sch | CC2340R5MODA (rev A7), SWD / UART / spare headers, status LED (3xx). The TMP1075 sensors were removed in rev A8 (item 48) |
usb_port.kicad_sch | One USB-C port: IP68 connector, VBUS TVS, TPD4S201 CC/SBU protector, liquid detection, TPS25751D, EEPROM, BQ25756 with four discrete FETs, TPS62933 5 V buck. Placed twice: port 1 = 4xx, port 2 = 5xx |
MonolithDev.pretty, fp-lib-table | Project footprints for parts KiCad doesn't ship (see Footprints below). Generated by tools/make_footprints.py |
MonolithDev.kicad_sym | Project symbols for parts KiCad doesn't ship. Generated by tools/make_symbols.py; pin numbers checked against ../../datasheets/ |
../../docs/hardware/monolithdev-schematic.pdf | PDF export of every sheet |
bom_cost.csv | Costed BOM at JLC buy quantities, with a production column. Generated by tools/bom_cost.py [boards] |
fab/ | The prepared (never placed) JLC order, 2026-10-17: MonolithDev-gerbers.zip, -bom.csv, -cpl.csv, -hand-fit.csv from tools/export_fab.py (item 50); -lcsc-order.csv, -lcsc-quick-order.txt, -lcsc-optional-dnp.csv, -lcsc-not-ordered.txt (hand-fit parts to buy from LCSC) from tools/lcsc_order.py |
MonolithDev_placement.png | Placement plot of the board (parts by block, before routing) |
Drawing conventions (cleanup pass, 2026-10-11): signal and power flow left to right, supplies up and ground down; each sheet is split into headed functional blocks with a NOTES block; rails use power symbols (PACK_P, 3V3, GND, and a separate ground-reference symbol for CELL_N, the gauge's VSS); short local connections are real wires, long runs use net labels; unused IC pins are tied with short bars to one symbol; MPNs live in properties, not the value text; every sheet has a filled title block. Readability pass (rev A2, following MacroFab's schematic guide): no text overlaps anywhere, values are the value or part number only (explanations live in each part's hidden Notes property and the sheet NOTES), direct same-page connections are wires rather than duplicate labels, sheet-pin names sit inside the sheet boxes, cap banks are at 10.16 mm pitch so every value reads horizontally, and the top sheet carries a revision log.
Wiring pass (rev A3): wires instead of labels wherever parts sit on the same block. Passives are placed on the row of the pin they serve (datasheet style): the BQ40Z50 cell-tap filters are an R/C ladder fanning into the VC pins; BAT/VCC/PBI/PACK/SMBus, the BQ25756 VAC divider, pull-down comb, bootstrap caps, FB divider and DRV_SUP, the TPS25751 I2Cc pull-ups (off a short LDO_3V3 rail), the STM32 BOOT0/NRST/SWD header and the TPS62177 PG pull-up are all drawn with wires. Labels remain for genuinely long runs and cross-sheet nets (I2C buses, gate drive to the FETs, cell taps from the holders, NTC dividers, test points). Local labels went from 275 to 198 and wires from 272 to 350. Nets that are fully wired lost their old names and now carry KiCad's automatic names (for example Net-(U101-VC1)).
Tools (most of tools/ is one-shot history: the finish_*, review4_*, mcu_cc2340.py, remove_tmp1075.py, downsize_passives.py, bom_fee_cut.py, gate_diodes.py / add_gate_diodes_board.py scripts each applied one numbered change below to the sheets or board of their day and won't re-run on the current files; the *.uuids files are the routers' re-run sidecars):
tools/place_blocks.py places every footprint in its sheet's zone (current placement, rev A7). It changes footprint positions only; no copper or silkscreen.tools/reset_board.py net.sexp [REF,...] then reset_board.py x --load strips copper, silk text and zones, deletes footprints the schematic no longer has, and reloads footprints whose library footprint changed (or the listed refs) at their old positions.tools/bom_cost.py [boards] exports the netlist and prices it from JLC into bom_cost.csv.tools/make_footprints.py, tools/make_symbols.py, tools/make_3d_*.py generate the project footprints, symbols and 3D models.tools/place_parts.py, route_power.py, route_signals.py, fanout_gnd.py, autoroute.py: the rev A5 placement and routing scripts, written for the old parts. Kept for their silkscreen pass and routing methods; they need updating before they run on the current board.tools/setup_board.py writes the board outline, stack-up, mounting holes (only while the board is empty), JLC design rules, net classes and MonolithDev.kicad_dru.tools/netlist_to_board.py net.xml [REF,...] pushes a kicad-cli sch export netlist --format kicadxml netlist into the board: pad nets, symbol links, values and fields, and swaps footprints whose schematic footprint changed (listed refs are refreshed from the library). Use it instead of the KiCad MCP's sync_schematic_to_board, which mishandles the reused USB port sheet (it left port 1 unconnected and merged the two ports' nets). It doesn't add new footprints; use KiCad's Update PCB from Schematic (F8) for that, then check parity.tools/junctions.py sheet [--drop-labels A,B] adds missing junction dots (KiCad only joins a wire end to the middle of another wire if a junction is there, and some MCP move/rotate operations delete junctions) and optionally deletes labels by name. Run it on every sheet after any edit, then diff the netlist.tools/remove_items.py sheet spec.txt deletes specific wires/labels by coordinates.tools/route_labels.py auto-wires short label-only nets (A* on the 1.27 mm grid, never touching other nets). Its output was only kept where it read cleanly; the main wiring was laid out by hand.tools/check_overlaps.py [-v] reports every place where text, labels, symbol bodies, pin numbers or wires collide (text widths calibrated against KiCad's renderer). It should print TOTAL 0.tools/place_fields.py re-places Reference/Value text on all sheets into free space next to each part and re-orients labels about their anchors. Run it after moving parts, then run the checker.tools/tidy_fields.py wrote the title blocks (the older field placement in it is superseded by place_fields.py).Cross-sheet signal nets use global labels (PACK_P, GND, 3V3, SDA, SCL, IRQ_N, EN_5V1/2, 3V3_SLEEP). Both ports share one sheet file, so any change to it applies to both ports.
| Layer | Copper | Dielectric below | Use |
|---|---|---|---|
| F.Cu | 70 µm | prepreg 0.2 | parts, power pours |
| In1.Cu | 17.5 µm | core 0.3 | solid GND |
| In2.Cu | 17.5 µm | prepreg 0.37 | signals + 3V3 |
| In3.Cu | 17.5 µm | core 0.3 | signals + 5 V |
| In4.Cu | 17.5 µm | prepreg 0.2 | solid GND |
| B.Cu | 70 µm | power pours |
MonolithDev.kicad_dru.kicad-cli pcb drc --schematic-parity reports 0 parity issues.tools/reset_board.py). The board now holds only the outline (Edge.Cuts), the mounting holes and the parts.
ANT_KEEPOUT rule area), board silkscreen text and group.netlist_to_board.py then set nets and fields. kicad-cli pcb drc --schematic-parity reports 0 parity issues; the remaining DRC items are the unrouted nets and overlaps from the old placement.TI_YFF0009_DSBGA-9_P0.4mm is a plated 0.15 mm drill in a 0.25 mm pad (JLC's minimum via; 5:1 aspect ratio on the 0.8 mm board), down to the In1 GND plane, 0.16 mm from its neighbours. Top mask and paste are the same as the other balls.place_parts.py, route_power.py, route_signals.py and fanout_gnd.py were written for the old placement and still need the new parts. Their .uuids sidecars point at deleted copper. The notes below describe that earlier placement.tools/place_blocks.py). Every part is on the board, one zone per schematic sheet: gauge column (x 104–134), MCU band along the top edge, one 36 mm port band per USB-C connector (port 2 is port 1 moved 36 mm down), sleep-current block along the bottom. No courtyard overlaps; DRC parity 0. Only footprint positions changed: no copper, and silkscreen is still the footprints' default reference text.
reset_board.py deleted the 14 parts the schematic dropped (TH301–TH305, R303, R308–R311, R316, R320, TP305, TP306), reloaded U301 (CC2340R5MODA footprint) and C308–C312 (now 0402) at their old spots, and added U302–U306, C313–C315 and R321; netlist_to_board.py set the nets. place_blocks.py then placed them (MCU_LAYOUT, SENSOR_LAYOUT); nothing else moved. No courtyard overlaps; DRC parity 0.
ANT_KEEPOUT dropped. The rev A5 rule area banned pours either side of the ST module's antenna. TI asks for the opposite: ground along the edge either side, and a no-copper area only under the antenna. The footprint carries that area (7.0 × 3.2 mm on the inner and bottom layers, 5.4 mm between the pads on F.Cu).MonolithDev:TI_DSG0008A_WSON-8-1EP_2x2mm_P0.5mm_EP0.9x1.6mm_Vias0.3mm. KiCad's ..._ThermalVias version had 0.2 mm via drills, below this board's 0.3 mm minimum (10 DRC errors). The schematic field was changed and the parts were reloaded in place.tools/place_parts.py; DRC clean apart from the unrouted connections. Board grew to 196 × 115 mm: the holder courtyards (94.7 mm) collided with corner holes, so the holder block moved right and the middle holes moved to x = 106 mm. USB notches at y = 32 and 68 mm.
place_parts.py lists every one in PORT_LAYOUT / LAYOUT as rows and columns, and the auto placer is only a fallback (it places nothing now).
tools/setup_board.py after place_parts.py: KiCad's python save rewrites the project file with default rules.Floorplan (board mm from the top-left corner):
Rev A8 (2026-10-14): 429 parts. Review 4's hardware fixes (item 41) and its documentation, BOM and procedure items (item 42); every review 4 item is closed or decided. The board is updated to match (placement only): 0 parity issues, no courtyard overlaps.
Rev A7 (2026-10-14): 411 parts. CC2340R5MODA MCU, TMP1075 sensors, one IRQ line (item 40). The board is updated to match (placement only).
Rev A6 (2026-10-14): 416 parts. Changes since rev A4:
ERC: 0 errors, 8 warnings, all the same item: TPS25751 unused GPIOs tied to GND (TI's datasheet says to do this; KiCad flags a bidirectional pin on a net driven by the GND power flag). tools/check_overlaps.py reports 0 text overlaps.
Board (routed 2026-10-17): routed and DRC-clean, fab outputs in fab/ (items 49–50); never ordered. The placement-stage notes from 2026-10-14 follow.
Board (placement, 2026-10-14): every footprint placed by block, no courtyard overlaps, 0 schematic-parity issues. The other DRC items:
If KiCad has the board open, revert/reload it before saving.
Cost (2 boards, 2026-10-15): bom_cost.csv (tools/bom_cost.py 2) gives $67.99 parts plus $40.50 JLC extended-part fees (27 unique extended parts × $3 ÷ 2 boards) = $108.49 per board. Before the fee cut (item 44) it was $124.28 (37 extended). At 5 boards the rev A8 BOM was $79.20. U301 (CC2340R5MODA) is costed at TI.com's $4.028 (qty 1-99; $2.189 at 1k+), consigned to JLC. JLC (C55046847) had 0 stock on 2026-10-14; TI.com has it in stock (2026-10-15, logged in; logged out it shows "Not available"). The STM32 module was $10.65. Not included: the PCB, assembly, shipping, cells, U201 and J301.
PWR_FLAGs (the diamonds) sit where each rail is sourced through a passive part; each sheet's NOTES says so.
Found while checking against datasheets:
BQ40Z50-R2 VCC (pin 26) goes through 100 Ω to the CHG/DSG FET common-drain node (R106), as in TI's reference schematic (fig. 9-1, R13). The description said VCC needs no external parts.
BQ40Z50-R2 PACK (pin 27) has an external 10 kΩ to PACK_P (R113), as in TI's reference (R15).
TPS70950 output cap is 2.2 µF (C205), not 1 µF. The TPS709 datasheet asks for ≥ 2.2 µF.
BQ25756 VAC comes straight from PPHV (before the input sense resistor) with 1 µF. The old netlist's 10 Ω series resistor is gone; that matches TI's typical application.
BQ25756 DRV_SUP is fed from REGN through 10 Ω (TI typical application). The old netlist tied the two together directly.
BQ25756 sense filters follow the datasheet pin descriptions on both shunts: 10 Ω in each lead, 0.47 µF differential, 0.1 µF from each side to PGND.
STM32WB1MMC: PB0/PB1/PB2 unused. ST calls these three pins RF-sensitive and says not to connect them if possible (DS14096 §7). NTC_EN moved from PB0 to PA8, EN_5V1 from PB1 to PA11, EN_5V2 from PB2 to PA12 (design review 2026-10-11), so the 2.7 pF guard caps C305–C307 were removed and PB0–PB2 carry no-connect flags. ANT_IN/ANT_OUT are joined by a 0 Ω resistor (R303) for the internal antenna. NRST has 100 nF.
PP5V bulk: a 220 µF 16 V polymer cap (C443/C543, ChuangHui SS221M160E7R7R4Z00ZZ, C25503905) was added on each port's PP5V. The TPS25751 table lists 120 µF minimum on PP5V (USB PD cSrcBulkShared), after derating. 2 × 22 µF + 10 µF wasn't enough, and a 100 µF MLCC keeps only about a third of its value at 5 V; polymer caps don't lose capacitance with DC bias.
TPS62177 SLEEP → PB4 (net 3V3_SLEEP). After reset PB4 is the JTAG NJTRST pin with its internal pull-up on (DS13258 table 15 note 8), which beats the TPS62177's weak internal pull-down (1.4 µA at 3.3 V), so the 3.3 V rail boots in normal mode. That is the safe way round (sleep mode only supplies 15 mA). Firmware must make PB4 a push-pull GPIO before using sleep mode, and drive it low rather than leaving it floating. FB is tied to GND, which TI recommends for the fixed-output part.
Status LED on PB5: 1 kΩ, green 0603, and a 0 Ω (R307) to pull for sleep measurements. Spare header J303 carries PA7 (NTC_TH5 since rev A5), PB8 and, for probing or overriding, NTC_EN, EN_5V1 and EN_5V2.
Gauge VSS = CELL_N (TI: "IC ground should be connected to the 1N cell tab"). The system GND is on the other side of the 1 mΩ shunt.
TPS25751 capacitors checked against datasheet table 6.4 (values are after derating): LDO_3V3 (C404/C504) 4.7 µF 0603 → 10 µF 25 V 0805 (≥ 5 µF needed); LDO_1V5 (C405/C505) 4.7 µF → 10 µF (4.5–12 µF); VBUS (C406/C506) 1 µF 35 V 0603 → 4.7 µF 50 V 0805 (1–10 µF, a 1 µF 0603 drops below 1 µF at 20 V); VIN_3V3 (C403/C503) 10 µF is fine.
Fuse F101: prosemi 1206FA-8A (C21261118), 1206, 8 A fast, 32 V, 300 A interrupt at 24 V. That allows about 6 A continuous after 75 % derating, inside the description's 5–7 A. The 2410 7 A alternative only lists an AC interrupt rating. D101: BAT54WS (C7502694, JLC preferred part). Rev A4 (2026-10-12): changed to prosemi 1206FA-15A (C2838894), same footprint and interrupt rating (300 A at 24 Vdc; the pack never exceeds 16.8 V): the 8 A part only allowed about 6 A continuous, i.e. 60–70 W out, short of the 100 W goal (about 10 A from the pack at the 12 V low end). 3.9 mΩ, about 0.4 W at 10 A. Holder-mode current is now limited by firmware and the gauge settings, not the fuse.
INA190s (U201/U202) are hand-soldered, bought from DigiKey/Mouser (decided 2026-10-11). JLC had only 7 INA190A5 and no INA190A1, and the in-stock look-alikes (INA180/181/185/296) draw tens of µA of input bias, which flows through R_MEAS and swamps µA readings. Both parts are excluded from the position file and have no LCSC number, so JLC leaves the pads empty; MPN and a Sourcing note are in their properties. Update 2026-10-13: JLC now stocks INA190A1IDDFR (C1852068, 1,700), so U202 is JLC-assembled (LCSC set, back in the position file). U201 (INA190A5, gain 500; 7 at JLC) stays hand-soldered. INA190A4 (gain 200, C1852066) would be the JLC option for U201, at 2 mV/µA and about 2.5 mA full scale. The INA21x family is no substitute: 15–35 µA input bias through R_MEAS and no enable pin.
PPHV bulk above 100 µF is kept. The TPS25751 table limits sink bulk to 100 µF (USB PD cSnkBulkPd) unless VBUS surge current is limited. The TPS25751D's PPHV sink switch ramps with a slew-rate loop (§6.9: 0.35–0.47 V/ms at setting 0, up to 3.8 V/ms at setting 3), so the BQ25756 input bank (about 125 µF effective at 20 V since rev A5 made C421 100 µF, item 24) charges at about C × SS = 0.06 A (setting 0), 0.5 A worst case at setting 3. The TPS25751 configuration must use PPHV soft-start setting 0 or 1; this is in the usb_port sheet notes.
Charger bulk is polymer plus MLCC, not all MLCC (2026-10-12). The 1210 X5R banks lost most of their value to DC bias (a 22 µF 35 V keeps about 8.5 µF at 20 V, a 47 µF 25 V about 12 µF at 16.8 V), so meeting the BQ25756's ≥ 80 µF effective per side (datasheet §6.3, TI asks for "a combination of ceramic and bulk capacitors", §7.2.1.2.5–6) took 10 + 7 parts per port. Each bank now has one solid polymer cap for the bulk and keeps only the MLCCs that carry the switching-frequency ripple next to the FETs:
docs/monolith_port1_bom.csv, removed 2026-10-14; in git tag product-draft-2026-10-09: 4 MLCC + 68 µF polymer per side). The production polymer is a ≤ 5 mm D-case 25 V part on the 20 V input; 25 V at 20 V is tight for a polymer cap, so 35 V is used here.Design-review fixes (rev A4, 2026-10-12) from ../../docs/devboard/schematic-review-2026-10-12.md. Item numbers refer to that review; its "Status" section lists every item.
MonolithDev:TI_RSM0032A_...; KiCad's generic part had a 2.8 mm pad.Open-question decisions (rev A4, 2026-10-12), see the review doc's "Decisions on the open questions":
Precision resistors rounded to stocked 1 % parts (2026-10-12). Only the two feedback dividers that set a voltage stay 0.1 %: R418/R419 (charge voltage, needs about ±1 %) and R433/R434 (PP5V, margin to the TPS25751's 4.9 V minimum). The rest move to UNI-ROYAL 1 % (all in stock at LCSC): R413 9.1k (ICHG 5.5 A), R414 3.6k (ILIM 5.6 A), R415/R416 1.8k/5.6k (TS network: hot 94.5 °C, warm 74 °C, cool 18.8 °C, cold −7 °C; an open NTC still reads as cold in charge mode, with more margin than before), R412/R410 40.2k, R409 137k (now 0603: no 0805 stock), R411 and R308–R311 10k. Unique 0.1 % parts drop from 10 to 4.
BQ25756 bootstrap diodes added (2026-10-12). TI's BQ25756 schematic checklist lists D2/D3, "BTST1/BTST2 diode-OR", as required Schottky diodes from DRV_SUP to each BTST node (the datasheet pin table only mentions the capacitor, and TI's typical application draws them). Each port now has D404/D405 (D504/D505): LRB521S-40T1G (LRC, C135802), 40 V 200 mA Schottky, SOD-523, anode on a new DRV_SUP label, cathode on the BTST cap. Placed in line with the BTST caps (D405 under C411 left of C413, D404 right of C412), clear of the SW1/SW2 copper. The production BOM (docs/monolith_port1_bom.csv, removed 2026-10-14; in git tag product-draft-2026-10-09) was missing them too and now lists D3/D4.
One NTC per cell (2026-10-12, rev 2 item 1 pulled into rev 1). Gauge TS2–TS4 are no longer tied to VSS: J105–J107 (2-pin, like J102) take a wired 10k 103AT NTC each, taped to BT102–BT104. All four headers sit beside the tap test point of the cell they watch (J102 moved from the gauge column to beside TP102). The welded pack's thermistors use the same headers. Keep the sensors insulated: each can is at its cell's negative terminal (up to about 12.6 V above VSS), the TS pins are rated 2.1 V. Enable TS2–TS4 in gauge data flash.
ESD caps across the protection FETs (2026-10-12). TI's BQ40Z50-R2 reference has two series pairs: C1/C2 (0.1 µF + 0.1 µF) across the back-to-back FET pair, cell side to pack side (sec. 9.2.2.1.1, fig. 9-2), and a second pair across PACK+/PACK− (sec. 9.2.2.1.5). Rev 1 only had the PACK pair (C107/C108, PACK_P to GND, unchanged). Added C110/C111 (0.1 µF 50 V 0603, C14663) from CELL_P to PACK_P, placed in the gap between Q101 and Q102; route them short and wide.
CHG_INH fails safe, plus a watchdog (rev A5, 2026-10-13; review 2 decisions D1–D3). R417/R517 changed from a 10k pull-down to a 47k pull-up to 3V3 (C25819). The MCU drives CHG_INH (PB8) low to allow charging; high, hi-Z, reset, a hang or an unprogrammed MCU all stop charging at CE. A dead pack still recovers from USB: with 3V3 down, CE reads low. Levels: MCU low gives CE = 3.3 V × 1k/48k = 0.07 V (VIL max 0.4 V); hi-Z gives about 3.25 V (VIH min 1.3 V). A 10k pull-up would only reach 0.30 V low. Charging needs the MCU in Run or Stop0–2 (GPIO state held), never Standby. PB8 low costs 138 µA (two 47k pull-ups), so it is low only while charging and high in idle. The full pin-by-state plan, reconciled with the 150 µA sleep budget, is ../../docs/devboard/mcu-io-power-states.md. A hang is cleared by the STM32 IWDG in hardware mode (option byte IWDG_SW = 0): it starts at every reset, firmware cannot stop it, and it runs from the LSI clock. During the reset CE goes high, so charging pauses until firmware allows it again. Bring-up consequence: flash the MCU before testing USB charging. Other decisions: ICHG stays 9.1k (5.5 A, D2); F101 stays 15 A on the condition that the gauge cut-off under load is 2.8 V/cell or higher (D3).
Review 2 follow-ups (rev A5, 2026-10-13).
F101 is JLC-placed again (rev A5, 2026-10-13). Hand-fitting it meant soldering next to an installed 16.8 V stack with no fuse, and since item 24 (BAT fed before F101) leaving it off no longer disconnected the gauge either. The loads were never at risk from it: everything is on PACK_P behind Q101/Q102, which stay off on a fresh gauge (FET_EN off, Mfg Status Init 0x0000). A reversed or missing cell finds no path (the DSG FET body diode blocks discharge, the CHG FET body diode blocks charge). Procedure:
Given up: measuring total pack drain across the F101 pads. Use R_MEAS for the 3V3 branch and the gauge's current reading for the rest.
SMD test loops instead of Keystone through-hole (rev A5, 2026-10-13). All 45 loop test points are now ronghe RH-S2761-46R (LCSC C55121754, about $0.12–0.20 each, about 10k in stock): an SMT loop 1.60 × 0.80 × 1.15 mm on an 0603 land pattern, the JLC-stocked equivalent of the Harwin S2761-46R (3.5 A). Footprint MonolithDev:TestPoint_Harwin_S2761_0603 (tools/make_footprints.py section 11): two 0603 pads, both pin 1 and marked jumpered, since the loop joins them. JLC places them with the rest; no through-hole assembly. They are small: fine for hook probes and mini-grabbers, but too small for a scope's alligator ground clip, so use a ground spring or a short ground lead on the GND loops. The bare 1.5 mm probe pads (TP306, TP307, TP413/TP513, TP414/TP514, TP206, TP207) stay pads.
Open-item pass (rev A5, 2026-10-13).
../../docs/devboard/power-budget.md.../../docs/devboard/bringup-config-checklist.md gathers every configuration item, with review 2's precharge correction.TH305 at the protection FETs (rev A5, 2026-10-13; review 2 A-7). Q101/Q102 dissipate about 1 W each at 100 W and nothing sensed them. TH305 (same Murata 10k NTC) sits between the two FETs right of C111, on PA7 (ADC1_IN2) with the same 10k 1 % / 0.1 µF divider from NTC_EN as TH301–TH304 (R320, C312 under J303). The PA7 net is now NTC_TH5 and still reaches J303 pin 2 for probing. Firmware: include it in the over-temperature and gauge cross-checks. It can be left unpopulated later.
Footprint checks and 3D models (2026-10-13).
Cell holder footprint fixed. Rendering the MYOUNG drawing showed a dia 2.25 hole for the + terminal's locating tab: the side view has a fork below the seating plane, 38.60 mm from centre. The footprint lacked it, so the holder would have sat on its tab. Added as NPTH at (-38.6, -11.5) and refreshed BT101-BT104; the silk gaps around it. Pads (7.5 × 9.0, 93.6 outer) and pegs (dia 4.0 at ±34, 8.5) were already right.
J301 uses Samtec's recommended land pattern for FTSH-1xx-xx-xxx-DV (rev G): 0.74 × 2.79 pads at ±2.035, courtyard covering the -K keying shroud. New footprint MonolithDev:Samtec_FTSH-105-01-xx-DV-K_2x05_P1.27mm. J301 moved 1.2 mm left; the "MCU" title moved below it.
3D models on 346 of 362 footprints (every physical part). Custom footprints borrow same-body KiCad models (make_footprints.py MODELS, pin 1 checked in a 3D render; KiCad turns positive Z angles clockwise):
place_parts.py re-points a KiCad-library footprint whose model KiCad 10 does not ship: the TS-1187A switches use the TL3342 model (same 5 mm 4-pad tact).
USB-C (J401/J501) model, measured from the maker's vector drawing. No STEP file exists from ShouHan, LCSC/EasyEDA (listed with no device) or the usual aggregators.
tools/drawing_extract/ pulls the outline strokes of every view out of ../../datasheets/usb-c-16pcb0.8-ip68.pdf, scaled at 10.888 pt/mm (cross-checked against the 10.25, 9.64, 7.45, 8.34 and 2.56 dimensions). tools/make_3d_usbc.py builds the solids from those measurements (OpenCascade).tools/verify_3d_usbc.py projects the model with hidden-line removal and overlays it on the drawing. Front, top and side views coincide; see 3dmodels/verification/usbc_overlay_*.png.Cell holders (BT101-BT104) and cells: tools/make_3d_holder.py.
3dmodels/source/, a SolidWorks export; MYOUNG publishes none), checked against MYOUNG's drawing by hidden-line overlay. Its top view matched.CELL_AXIS_Z.STM32WB1MMC, M24512 UFDFPN8 and the SMT test loops: tools/make_3d_simple.py, envelopes from the package drawings:
3dmodels/source/), checked against ST's fig. 11 and table 3: envelope, 1.372 height, centre-pad cluster and inner pad row match the footprint. ST's own CAD models are behind sign-in (UltraLibrarian, SamacSys, DigiKey/SnapMagic); drop that STEP into 3dmodels/source/ to replace it;Coverage: 346 of 362 footprints have models. The rest are mounting holes, bare probe pads and the copper net-tie links, which are not physical parts.
Silkscreen purpose and pinout labels (2026-10-13). tools/place_parts.py PART_LABELS / PIN_LABELS (0.8 mm text; placed before the test-point and reference labels so they get the spots next to the pins):
Sleep-current outputs on test loops instead of SMAs (rev A5, 2026-10-13). J201/J202 (vertical SMAs) are removed. OUT_LO and OUT_HI are probed on their existing loops TP201/TP202. Each has its own GND loop 4.5 mm away (TP208/TP209, same RH-S2761-46R, JLC-placed) for a short probe ground lead. The four sit in a row on the bottom edge under the amps: OUT_LO, GND, OUT_HI, GND. R204/R205 49.9 Ω stay: they keep probe and cable capacitance off the INA190 outputs (1 nF max). Use a 1 MΩ scope input. Nothing is left to hand-fit in this section except U201/U202.
Routing started: net classes, planes, port power stages (2026-10-13).
tools/route_power.py (re-runnable; it rebuilds only what it added, listed in tools/route_power.uuids). For each port:
("fix", ...) entry in place_parts.py: exact rotation, no automatic 0/180 flip.route_power.py's pack section:
tools/fanout_gnd.py, branch dev-board-autoroute):
tools/fanout_gnd.uuids..uuids file):
place_parts.pyroute_power.py (power, gate drive, Kelvin taps; hand-planned coordinates)fanout_gnd.pykicad-cli pcb drc (to a report)route_signals.py <report> (A* signal router)route_signals.py must get the DRC report of the board before its own tracks, since it removes them first.HAND list (sense pairs, MEAS±, antenna feed), which are routed by hand.route_signals.py and fanout_gnd.py remove their old tracks by editing the board file as text before loading (tools/pcb_text.py). Mass removal through pcbnew leaves dead SWIG wrappers, and once (right after a place_parts.py run) it silently left all 288 old fanout items in the saved board.route_power.py, branch claude-router): all DRC-clean before the signal router runs.
fix) so the module's antenna pin (6) and RF output (7) reach its pads without crossing.CONN_EXTRA), so port 2's copy follows J501's 36 mm offset:
tools/autoroute.py runs Freerouting 2.5.0 (Java 25; the native CLI build crashes) with the power routing locked.Second-level protection: BQ294700 + chemical fuse (2026-10-13, branch hand-review). Reverses the 2026-10-12 decision to rely on software as the second layer (rev2-changes.md 1b). Hardware now guards per-cell overvoltage independently of the gauge, its data flash and the MCU, as in TI's BQ40Z50-R2 reference (datasheet fig. 9-11, BQ2947 fig. 8-1). Gauge sheet, new block "SECOND-LEVEL PROTECTION":
BQ294700 and WSFB1514 (tools/make_symbols.py), footprint TLC_WSFB_4x3mm from the datasheet land pattern (tools/make_footprints.py section 13), and a 3D box model (tools/make_3d_simple.py).place_parts.py and the pack-path copper (route_power: CELL_P_RAW strip, F101 pads, CELL_P) still reference F101 and have to change, then re-run the routing workflow above.D103 fitted (2026-10-13, dev board and production). The 15 V Zener from Q102's gate (DSG_G) to its source (PACK_P) was DNP since review 1 (m1), as an option tied to C109. It is now placed (BZT52C15, SOD-123, LCSC C173427).
USB-C liquid detection (2026-10-14, both ports), TPS25751 datasheet sec. 9.2.2.2 / fig. 9-8. The product is sealed (IP65 enclosure, IP68 connector), but the receptacle cavity still gets wet. Water bridging VBUS to CC/SBU corrodes the contacts, and water between CC and GND can look like an attached sink and make the port turn VBUS on.
TPD2S300 and footprint TI_YFF0009_DSBGA-9_P0.4mm stay in the libraries, unused since item 39.place_parts.py no longer places D403.Schematic review 3 changes (2026-10-14, both ports). Review: ../../docs/devboard/schematic-review-3-2026-10-14.md.
MonolithDev:TPS25751D, a copy of KiCad's stock symbol (made by tools/make_symbols.py) with GPIO11 typed bidirectional as the datasheet says. ERC is down to the 8 expected GPIO-to-GND warnings, with no errors.../../docs/devboard/bringup-config-checklist.md):
Cost-down (2026-10-14). Details and datasheet checks: ../../docs/devboard/cost-down-2026-10-14.md.
L_Changjiang_FXL1040 footprint, which is the same land as the datasheet's.L_Coilank_APS0530 (tools/make_footprints.py section 15).Sourcing property, out of the position file).bom_cost.csv, regenerated by tools/bom_cost.py [boards]. It prices every LCSC part at JLC's actual buy quantity, U301 at the ST price, and the hand-soldered headers from LCSC. U201 and J301 are left unpriced.Charger FETs: discrete PGQ04N070 (cost-down A16, 2026-10-14). Each charger leg was one IAUC45N04S6L063H half-bridge ($1.16, only 62 at JLC). Each is now two JinYu PGQ04N070 (C49384056, $0.12, PDFN3333 on AGM_PDFN-8_3.3x3.3mm_P0.65mm): Q401/Q407 on the USB side (SW1), Q402/Q408 on the battery side (SW2), and the 5xx twins.
PGQ04N070 in tools/make_symbols.py.bringup-config-checklist.md §5).6-layer 1.6 mm board, TPD4S201 and the 1.6 mm USB-C connector (2026-10-14).
tools/setup_board.py, which now always rewrites the stack-up and keeps net classes it doesn't manage (Kelvin).TI_RGR0020C_VQFN-20-1EP_3.5x3.5mm_P0.5mm_EP2.05mm from the datasheet land pattern (pads 0.6 × 0.24 at ±1.65 mm, 2.05 mm exposed pad, four 0.3 mm vias). New symbol TPD4S201.tools/make_3d_usbc.py 1.6).reset_board.py (new REF,... force-reload option) reloaded the changed footprints and removed D402/D502 and C453/C553. Parity: 0 issues.Rev A7: CC2340R5MODA MCU, TMP1075 board sensors, one IRQ line (2026-10-14). Plan and pin budget: ../../docs/devboard/cc2340-pin-budget.md. Applied by tools/mcu_cc2340.py (one-shot, from the rev A6 sheets).
U301 → TI CC2340R5MODA (BLE-only module, 512 kB flash / 64 kB RAM, on-chip OTA updates), replacing the STM32WB1MMC ($19.90, 0 at JLC). New symbol and footprint TI_MHA0024A_CC2340R5MODA_7x10mm (SWRS349A p.63-64). The footprint carries the fig. 9-2 antenna keep-out as two rule areas.
Wiring per SWRS349A fig. 9-1:
Pins: 12 DIOs, 2 of them SWD, so 10 for the board, and only 4 analog. The new map has no spare pins:
| DIO | Signal |
|---|---|
| DIO6 / DIO8 | SCL / SDA |
| DIO18 / DIO20 | UART TX / RX |
| DIO12 | LED |
| DIO24 | CHG_INH |
| DIO3 / DIO4 | EN_5V1 / EN_5V2 |
| DIO21 | 3V3_SLEEP |
| DIO11 | IRQ_N |
Board NTCs → TMP1075 on I2C.
IRQ_N: the two TPS25751 IRQs, the gauge BTP (Q103) and the TMP1075 ALERTs share one open-drain net, replacing IRQ1/IRQ2/GAUGE_BTP.
R313 fitted at 470k (was DNP 100k). CC2340 pins float in reset, and the TPS62177's 1.4 µA SLEEP pull-down would otherwise put 3V3 in sleep mode (15 mA max) during boot. This costs 7 µA in S2.
Not done yet:
Sourcing property says so since rev A8). In stock at TI.com when logged in (2026-10-15).mcu-io-power-states.md and the bring-up checklist were rewritten for the CC2340 in rev A8 (item 42).Rev A8: review 4 pre-routing hardware fixes (2026-10-14). From ../../docs/devboard/schematic-review-4-2026-10-14.md. Applied by tools/review4_fixes.py (one-shot, from the rev A7 sheets). Part numbers checked against JLC's parts API the same day.
| Review item | Change | Part (LCSC) |
|---|---|---|
| A-1b | R313 470k → 220k: 3V3_SLEEP reads about 0.92 × VDDS in reset instead of 0.83 (VIH 0.8). 15 µA while firmware holds SLEEP low | 0603WAF2203T5E (C22961, basic) |
| A-5 | R314 100k → 47k (IRQ_N pull-up) | 0603WAF4702T5E (C25819) |
| A-6 | R304/R305 4.7k → 3.3k (SCL/SDA rise time; run the bus at 100 kHz) | 0603WAF3301T5E (C22978) |
| A-7 | R324 1k in series with J303 pin 2 (IRQ_N probe) | 0603WAF1001T5E (C21190) |
| A-9 | R322/R323 1k in series with J302 TX/RX. Connect a USB-UART adapter only with 3V3 up | 0603WAF1001T5E (C21190) |
| A-10 | C314 (Z60) placeholder 1p C0G, still DNP | GRM1555C1H1R0BA01D (C76952) |
| B-3 | R450/R451 (and 5xx) DNP snubber resistors 0805 → 1206 anti-surge 0.66 W. A 2010 or 0612 doesn't fit between Q401/Q408 and C443 | ERJ-P08J3R3V (C3998398, 0 stock; DNP) |
| C-3 | C401/C402 (CC caps) 330p → 220p C0G | CL05C221JB5NNNC (C307445) |
| C-4 | D401/D501 SMAJ22A → TVS2200DRVR flat clamp (28 V at 40 A 8/20 µs). Stock KiCad symbol Power_Protection:TVS2200DRV and footprint WSON-6-1EP_2x2mm_P0.65mm_EP1x1.6mm (TI DRV0006A pinout and 1.0 × 1.6 mm pad; KiCad's lands are 0.375 × 0.4 mm against TI's 0.3 × 0.45). Datasheet: ../datasheets/tvs2200.pdf | TVS2200DRVR (C523793, about 2.8k stock) |
| C-8 | TP415–TP421 (and 5xx), 1 mm pads: CC1, CC2, SBU_FLT, SBU1_SNS, SBU2_SNS, LIQ_PU, LIQ_PD | TestPoint_Pad_D1.0mm |
place_blocks.py):
check_overlaps.py finds 0 text overlaps; board DRC shows 0 parity issues and no courtyard overlaps.power-budget.md, circuit-description.md and the checklist's STM32 sections.Rev A8, part 2: review 4 documentation, BOM and procedure items closed (2026-10-14). Schematic edits by tools/review4_docs.py (one-shot, after review4_fixes.py; shared helpers in tools/sch_edit.py).
/MCU and Sensors/…); top-sheet address note names the CC2340 I2C0 and the TMP1075 addresses.Sourcing on U301 (TI.com, consigned) and J301 (hand-fit; Samtec to be replaced by an unkeyed header JLC stocks). J301 is out of the position file.bringup-config-checklist.md (with every review 4 CONFIG item: CCFG bootloader pin, IRQ_N rules, TMP1075 modes, I2C 100 kHz and bus clear, EN_5Vx first after reset, [NR] and Latch Limits, BTP_POL, [XL], EN_JEITA = 0, IBAT_REV interim, Q12/Q13, liquid-detect thresholds, INT_EVENT1 clear), mcu-io-power-states.md, power-budget.md (idle about 230–240 µA). Corrections in circuit-description.md §7–8, cost-down-2026-10-14.md (A3, A16) and cc2340-pin-budget.md.Sourcing); the bench measurements listed in the checklist §5. The ship-mode SOC threshold is 5 % (decided 2026-10-15).C432/C532 → hybrid polymer (2026-10-15). The battery-side bulk is the only bulk capacitor biased while the board idles (from PACK_P whenever the gauge FETs are on). Its leakage is therefore idle drain, and the JIERR MA25V100M6x6 solid polymer was specified at 0.2CV = 500 µA max each (review 4 B-4).
CP_Elec_6.3x7.7 (same pads as the 6.3 × 5.8; the can is taller).Fewer JLC extended parts for a 2-board build (2026-10-15). JLC charges $3 per unique extended part per order, so at 2 boards each costs $1.50 per board. Applied by tools/bom_fee_cut.py; 37 → 27 extended parts, $124.28 → $108.49 per board at 2 boards.
netlist_to_board.py only (no placement changes); DRC parity 0. ERC unchanged.Smaller passives (2026-10-16). Each resistor and capacitor moves to the smallest package that keeps its rating, with two rules: nothing smaller than 0402, and no JLC basic part becomes extended. 160 parts change footprint (113 symbols; the port sheet counts twice). Applied by tools/downsize_passives.py (one-shot). The netlist connectivity is unchanged, ERC is unchanged (8), extended parts stay at 27, and the cost is $108.49 → $107.93 per board at 2 boards. Part classes and MPNs were checked against JLC's parts API the same day.
0603 → 0402, all basic:
| Group | Part | Notes |
|---|---|---|
| 42 × 0.1 µF 50 V | C307331 | Same rating. C430/C438 (hot-loop HF) get lower ESL at 0402. |
| C450/C550 10 nF | C15195 | |
| C452/C552 1 µF | C52923, 25 V | LDO_3V3 rail |
| C405/C505 10 µF | C15525, 6.3 V | LDO_1V5 rail |
| C301 4.7 µF | C23733, 10 V | 3V3_MCU; about half the capacitance remains at 3.3 V |
Every basic resistor value with a basic 0402 part (UNI-ROYAL 0402WGF) moves too: 0R, 10R, 49.9, 100, 330, 1k, 3.3k, 4.7k, 5.1k, 10k, 22k, 47k, 51k, 100k and 1M. That includes R411/R511 10k and R434/R534 22k (both from 0805). The 0R parts that move are R1–R4, R202, R203, R307, R312 and R440/R540. The 10R parts that move are R425/R426/R428/R429 (the sense filters) and their port 2 copies.
One size down, basic:
Extended parts kept extended:
Kept as they were, and why:
Board: not updated yet. Run Tools → Update PCB from Schematic. That replaces the footprints in place, but the pads of parts already routed will no longer meet their traces.
Net tie R430/R530 removed (2026-10-16). It only kept VBAT_SYS and PACK_P as separate net names, which made routing the battery-side power path harder. Each charger's battery side is now PACK_P directly. In usb_port.kicad_sch, R430 became a wire, and the two VBAT_SYS labels became PACK_P power symbols (#PWR610/#PWR611, port 2 #PWR612/#PWR613). The */VBAT_SYS HighCurrent pattern was dropped from the project, since PACK_P is already HighCurrent. Netlist: R427/R527, R418/R518 and R429/R529 move to PACK_P, with no other change; ERC unchanged (8). The tie was out of the BOM, so cost is unchanged.
Charger gate resistors 10 Ω with turn-off diodes (2026-10-17, both ports). R444–R447 (R544–R547) went from 0 Ω to 10 Ω (C22859, 0603), to slow the switching edges. A BAT54WS (C7502694, SOD-323, the same part as D101, so no new JLC fee) sits across each: D406–D409 (D506–D509), cathode on the BQ25756 driver pin and anode on the FET gate. Turn-on goes through the 10 Ω; turn-off bypasses it through the diode, so the 45 ns dead time is kept (above 4.7 Ω without a diode, turn-off would eat it). The resistors' Notes named the wrong drivers and were rewritten. Applied by tools/gate_diodes.py (schematic) and tools/add_gate_diodes_board.py (board); the 8 diodes wait in a row below the board (y = 171 mm) for hand placement next to their resistors. Note: this makes review 4's B-1 (high-side gate drive margin) no better; check the gate waveforms at bring-up.
TMP1075 board sensors removed (2026-10-17, rev A8). U302–U306 and C308–C312 are gone from the MCU sheet and the board (they were parked off-board, unrouted). Board temperature now comes from parts already there (../../docs/devboard/circuit-description.md §6):
DAStatus2 (MAC 0x0072, readable sealed) returns TS1–TS4, cell temperature, FET temperature and the gauge die.TS_ADC, read through the TPS25751 I2Cr 4CC task on its I2Cc bus. The chargers' warm/hot limits (74 / 94.5 °C) act in charge and reverse mode without firmware.tools/remove_tmp1075.py; docs, bom_cost.py, place_blocks.py and tidy_fields.py updated.Routing finished (2026-10-17). Hand routing in KiCad did most of the board; the scripted finish pass (tools/finish_a_fixes.py … finish_h_fixes.py, one-shot, in order) did the rest, and a last hand round closed the remaining connections. Scripted: outline stray removed; all vias 0.45/0.3 mm; duplicate vias and zones removed; SDA/SCL and the CELL_N island taken off the In4 plane (CELL_N is a routed net, BT101− → RS101 is a 4 mm F.Cu pour); 34 parked parts placed (finish_c_place.py); 65 of 94 leftovers routed by the A* router route_signals6.py (In2 vertical / In3 horizontal, generated by make_router6.py); the two plane necks found by neck_bisect.py and nudged (finish_d_necks.py); two dangling-item and wedge clean-ups (finish_f_cleanup.py, finish_g_fixes.py, finish_h_fixes.py). A GND reference-via sprinkle (finish_d_gndvias.py) was rejected because it cut the power pours and was stripped again; don't repeat it. Silkscreen by finish_e_silk.py (re-runnable): refs only on J/JP/BT, abbreviated test-point net labels at 0.8 mm, header pin labels, section titles, board name and "FIT CELLS BEFORE USB"; 19 test-point labels in the 2.54 mm loop grids found no room and are not printed (TP402/404/407–409/418/421, TP509/510/512/513/518/519, TP104/107/201; J104/J301 refs). State: DRC 0 unconnected, 0 errors other than the known lib-footprint mismatches (U403/U503 known; U301/U404/U504 are silk trims on the board instances). check_routing_rules.py notes, left as they are: 563 In2/In3 direction deviations and eight segments on the In4 plane (port 1/2 SBU_FLT, SCL) from hand routing; 44 via rows under 0.3 mm plane webs (the 9-via stitch rows under SW1/SW2 and the RAC corridor are the ones that matter); 156 signal vias without a GND via within 1 mm. Known layout weakness for rev 2: each BQ25756 (U403/U503) sits 15–34 mm from its FET gates with 0.2 mm gate tracks (TI: ≥ 0.5 mm, short); the 5 V buck sits in between. Move the controller next to the FET block next revision.
Fab outputs (2026-10-17). tools/export_fab.py (re-runnable) refills the zones, plots gerbers with JLC's KiCad settings (Protel extensions, soldermask subtracted from silk, no X2/netlist attributes) plus Excellon drills (mm, PTH/NPTH separate, Gerber X2 maps) into fab/gerbers/ and fab/MonolithDev-gerbers.zip, and writes the JLC assembly files: fab/MonolithDev-bom.csv (Comment, Designator, Footprint, LCSC Part #; 85 lines) and fab/MonolithDev-cpl.csv (Designator, Mid X, Mid Y, Layer, Rotation; 317 parts, all top side). fab/MonolithDev-hand-fit.csv lists the 51 parts kept out of the JLC files and why: the 17 DNP parts, the hand-fit parts (holders, headers, the 1.5 mm probe pads, U201/U202, D105) and U301 (CC2340R5MODA, bought from TI, no LCSC number). Check the rotations in JLC's placement preview before confirming an order; KiCad and JLC disagree on the zero angle for some packages. Not ordered yet: the TI board is tested first.
Moot since the board was not built; they are kept as history. P0's open items are in ../Production/README.md.
Changes planned for the next board revision are listed in ../../docs/devboard/rev2-changes.md.
ANT_KEEPOUT (place_parts.py) banning tracks, vias and pours on all copper layers in the strip either side of and above the module (x 141–159, y 0–4.2 mm). The layout reset removed it. Rev A7: not re-added. TI wants ground on both sides of the CC2340 antenna, and the footprint carries the keep-out under it (Board, rev A7 update). Check BLE range at bring-up.MonolithDev.pretty holds the footprints KiCad doesn't ship, generated by tools/make_footprints.py from the datasheets in ../../datasheets/ (2026-10-11). Every symbol pin has a pad and every numbered pad a pin (checked against the netlist).
| Footprint | Used by | Source / notes |
|---|---|---|
BatteryHolder_MYOUNG_BH-21700-B1BJ001 | BT101–BT104 | MYOUNG drawing. Its "PCB layout, bottom view" is the top view flipped about the long axis; checked against the top view (+ on the left, left peg low). Pads 7.5 × 9.0, Ø4.0 holes for the Ø3.2 pegs. Add stitching vias under the pads in layout. |
USB_C_Receptacle_ShouHan_TYPE-C_16PCB1.6_IP68 (and ...16PCB0.8_IP68, unused since the 1.6 mm board) | J401, J501 | Shou Han recommended layout, the same for both variants (only the body depth through the board differs; tools/make_3d_usbc.py 1.6). Mid-mount: the footprint draws a 10.20 × 5.65 mm board-edge cutout on Edge.Cuts; origin is the board edge. Pad order matches KiCad's HRO TYPE-C-31-M-12. The maker's signal pads start right on the notch's back edge (5.65–6.65 mm from the edge); they're moved 0.2 mm inward (5.85–6.85 mm) for JLC's 0.2 mm copper-to-routed-edge minimum. |
Infineon_PG-TDSON-8-57_HalfBridge | unused since item 38 (was Q401, Q402, Q501, Q502) | Infineon land pattern and 0.15 mm stencil (datasheet p. 8). The drain pad (8) and the phase pad (3) sit beside their lead bars; Infineon joins each pair with copper under mask, so connect them with copper in layout. |
TI_MHA0024A_CC2340R5MODA_7x10mm | U301 (rev A7) | TI land pattern (SWRS349A p.64): side pads 1.1 × 0.6, bottom pads 0.6 × 1.1, 1.0 mm pitch. Fig. 9-2 antenna keep-out as two rule areas (F.Cu between the pads, all other layers 7.0 wide), both 3.2 mm deep from the antenna edge. No 3D model yet. |
TI_DSG0008A_WSON-8-1EP_2x2mm_P0.5mm_EP0.9x1.6mm_Vias0.3mm | U302–U306 (TMP1075, rev A7) | KiCad's Texas_DSG0008A_..._ThermalVias (TI land pattern) with its two exposed-pad vias at 0.3 mm drill (was 0.2) in the same 0.5 mm pads, joined to the planes solid. Filled and capped. |
ST_LGA-77_STM32WB1MMC_6.5x10mm | U301 until rev A6 | Pad centres read from the vector drawing in DS14096 fig. 11 (bottom view, mirrored). The drawing labels two centre pads "73"; the lower-middle one is 72 by the numbering order. 1:1 lands. |
ST_UFDFPN-8-1EP_2x3mm_P0.5mm_EP1.2x1.4mm | U402, U502 | ST recommended footprint (DS6520 fig. 16). Replaces KiCad's generic DFN-8 2 × 3, whose 0.61 × 2.2 exposed pad didn't fit this package. The exposed pad is pad 4 (VSS), which ST allows. |
TI_VQFN-36-1EP_RRV0036A_5x6mm_P0.5mm | U403, U503 | Antmicro open-hardware footprint (Apache-2.0, copy in tools/third_party/), checked against TI's RRV0036A land pattern. Add the exposed-pad thermal vias in layout. |
AGM_PDFN-8_3.3x3.3mm_P0.65mm | Q101, Q102; charger FETs Q401/Q402/Q407/Q408 (and 5xx) | AGM404AP1 package drawing (no land pattern given): 0.4 × 0.75 mm source/gate lands, one 2.45 mm drain land, 4-window paste. Replaces TDSON-8-1, which is the 5 × 6 mm Infineon package and could not have fitted this 3.3 × 3.3 mm part (caught by the board parity check). |
TI_RGR0020C_VQFN-20-1EP_3.5x3.5mm_P0.5mm_EP2.05mm | U405, U505 | TPD4S201 datasheet land pattern: 0.6 × 0.24 mm pads at ±1.65 mm, 2.05 mm exposed pad with four 0.3 mm vias. |
L_Coilank_APS0530 | L402, L502 | Coilank APS0530 drawing: 1.9 × 2.5 mm pads at ±2.05 mm. |
NetTie-2_SMD_3x3mm_Bridge3mm | (none since 2026-10-16) | Was R430/R530, the 10 A net tie from VBAT_SYS to PACK_P; removed in item 46. Footprint left in the library. |
python tools/make_symbols.pyThen in KiCad, Tools → Update Symbols from Library (or the MCP update_symbol_from_library).
| Qty | Value | Footprint | References |
|---|---|---|---|
| 47 | 0.1u 50V | Capacitor_SMD:C_0402_1005Metric | C101, C102, C103, C104, C106, C107, C108, C110, C111, C112, C113, C114, C115, C116, C117, C118 +31 |
| 17 | 100k | Resistor_SMD:R_0402_1005Metric | R114, R206, R208, R302, R315, R432, R436, R437, R441, R442, R443, R532, R536, R537, R541, R542 +1 |
| 12 | 1k | Resistor_SMD:R_0402_1005Metric | R119, R120, R121, R122, R317, R318, R319, R322, R323, R324, R435, R535 |
| 11 | 0R | Resistor_SMD:R_0402_1005Metric | R1, R2, R3, R4, R202, R203, R307, R312, R321, R440, R540 |
| 10 | 10R | Resistor_SMD:R_0603_1608Metric | R420, R444, R445, R446, R447, R520, R544, R545, R546, R547 |
| 10 | 22u 25V | Capacitor_SMD:C_1206_3216Metric | C431, C434, C435, C441, C442, C531, C534, C535, C541, C542 |
| 9 | 10k | Resistor_SMD:R_0402_1005Metric | R113, R404, R421, R422, R423, R504, R521, R522, R523 |
| 9 | BAT54WS | Diode_SMD:D_SOD-323 | D101, D406, D407, D408, D409, D506, D507, D508, D509 |
| 8 | 10R | Resistor_SMD:R_0402_1005Metric | R425, R426, R428, R429, R525, R526, R528, R529 |
| 8 | 22u 35V | Capacitor_SMD:C_1210_3225Metric | C420, C423, C424, C427, C520, C523, C524, C527 |
| 8 | PGQ04N070 | MonolithDev:AGM_PDFN-8_3.3x3.3mm_P0.65mm | Q401, Q402, Q407, Q408, Q501, Q502, Q507, Q508 |
| 7 | 100 | Resistor_SMD:R_0402_1005Metric | R105, R106, R107, R108, R115, R116, R123 |
| 7 | 10u 25V | Capacitor_SMD:C_0603_1608Metric | C205, C403, C404, C407, C503, C504, C507 |
| 7 | GND | TestPoint:TestPoint_Pad_D1.5mm | TP109, TP203, TP208, TP209, TP309, TP412, TP512 |
| 6 | 3.3k | Resistor_SMD:R_0402_1005Metric | R304, R305, R402, R403, R502, R503 |
| 6 | AO3400A | Package_TO_SOT_SMD:SOT-23 | Q103, Q104, Q405, Q406, Q505, Q506 |
| 6 | MountingHole_3.2mm_M3 | MountingHole:MountingHole_3.2mm_M3 | H1, H2, H3, H4, H5, H6 |
| 4 | 0.47u 25V | Capacitor_SMD:C_0603_1608Metric | C414, C417, C514, C517 |
| 4 | 0R | Resistor_SMD:R_0603_1608Metric | R448, R449, R548, R549 |
| 4 | 0R | Resistor_SMD:R_0805_2012Metric | R207, R301, R401, R501 |
| 4 | 100 | Resistor_SMD:R_1206_3216Metric | R101, R102, R103, R104 |
| 4 | 100u 35V | Capacitor_SMD:CP_Elec_6.3x7.7 | C421, C443, C521, C543 |
| 4 | 10u 50V | Capacitor_SMD:C_1206_3216Metric | C444, C445, C544, C545 |
| 4 | 1M | Resistor_SMD:R_0402_1005Metric | R438, R439, R538, R539 |
| 4 | 220p 50V | Capacitor_SMD:C_0402_1005Metric | C401, C402, C501, C502 |
| 4 | 3.3R | Resistor_SMD:R_1206_3216Metric | R450, R451, R550, R551 |
| 4 | 33p 50V | Capacitor_SMD:C_0603_1608Metric | C454, C455, C554, C555 |
| 4 | 4.7u 16V | Capacitor_SMD:C_0603_1608Metric | C410, C411, C510, C511 |
| 4 | 40.2k 1% | Resistor_SMD:R_0603_1608Metric | R410, R412, R510, R512 |
| 4 | 5.1k | Resistor_SMD:R_0402_1005Metric | R109, R111, R124, R126 |
| 4 | AO3401A | Package_TO_SOT_SMD:SOT-23 | Q403, Q404, Q503, Q504 |
| 4 | BH-21700-B1BJ001 | MonolithDev:BatteryHolder_MYOUNG_BH-21700-B1BJ001 | BT101, BT102, BT103, BT104 |
| 4 | LRB520S-40T1G | Diode_SMD:D_SOD-523 | D404, D405, D504, D505 |
| 3 | 47k | Resistor_SMD:R_0402_1005Metric | R314, R417, R517 |
| 2 | 1.8k 1% | Resistor_SMD:R_0603_1608Metric | R415, R515 |
| 2 | 10.0k 0.1% | Resistor_SMD:R_0402_1005Metric | R419, R519 |
| 2 | 100k 0.1% | Resistor_SMD:R_0402_1005Metric | R418, R518 |
| 2 | 100u 25V | Capacitor_SMD:CP_Elec_6.3x7.7 | C432, C532 |
| 2 | 10M | Resistor_SMD:R_0603_1608Metric | R110, R112 |
| 2 | 10k 1% | Resistor_SMD:R_0402_1005Metric | R411, R511 |
| 2 | 10k B3435 | Resistor_SMD:R_0603_1608Metric | TH401, TH501 |
| 2 | 10n 50V | Capacitor_SMD:C_0402_1005Metric | C450, C550 |
| 2 | 10p | Capacitor_SMD:C_0603_1608Metric | C447, C547 |
| 2 | 10u 6.3V | Capacitor_SMD:C_0402_1005Metric | C405, C505 |
| 2 | 120k | Resistor_SMD:R_0603_1608Metric | R433, R533 |
| 2 | 137k 1% | Resistor_SMD:R_0402_1005Metric | R409, R509 |
| 2 | 1p C0G | Capacitor_SMD:C_0402_1005Metric | C314, C315 |
| 2 | 1u 25V | Capacitor_SMD:C_0402_1005Metric | C452, C552 |
| 2 | 1u 50V (VAC) | Capacitor_SMD:C_0603_1608Metric | C409, C509 |
| 2 | 2.2u | Inductor_SMD:L_Changjiang_FXL1040 | L401, L501 |
| 2 | 2.2u 50V | Capacitor_SMD:C_0805_2012Metric | C105, C206 |
| 2 | 22k | Resistor_SMD:R_0402_1005Metric | R434, R534 |
| 2 | 3.3u | MonolithDev:L_Coilank_APS0530 | L402, L502 |
| 2 | 3.6k 1% | Resistor_SMD:R_0603_1608Metric | R414, R514 |
| 2 | 33n 50V | Capacitor_SMD:C_0603_1608Metric | C439, C539 |
| 2 | 4.7u 50V | Capacitor_SMD:C_1206_3216Metric | C406, C506 |
| 2 | 49.9 | Resistor_SMD:R_0402_1005Metric | R204, R205 |
| 2 | 5.6k 1% | Resistor_SMD:R_0603_1608Metric | R416, R516 |
| 2 | 5m 2W (RAC) | Resistor_SMD:R_2010_5025Metric | R424, R524 |
| 2 | 5m 2W (RBAT) | Resistor_SMD:R_2010_5025Metric | R427, R527 |
| 2 | 9.1k 1% | Resistor_SMD:R_0603_1608Metric | R413, R513 |
| 2 | AGM404AP1 | MonolithDev:AGM_PDFN-8_3.3x3.3mm_P0.65mm | Q101, Q102 |
| 2 | BQ25756RRVR | MonolithDev:TI_VQFN-36-1EP_RRV0036A_5x6mm_P0.5mm | U403, U503 |
| 2 | Bridged | Jumper:SolderJumper-2_P1.3mm_Bridged2Bar_RoundedPad1.0x1.5mm | R431, R531 |
| 2 | CC1 | TestPoint:TestPoint_Pad_D1.0mm | TP415, TP515 |
| 2 | CC2 | TestPoint:TestPoint_Pad_D1.0mm | TP416, TP516 |
| 2 | CE_N | TestPoint:TestPoint_Pad_D1.5mm | TP413, TP513 |
| 2 | I2CC logic analyzer | Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical | J402, J502 |
| 2 | I2CC_SCL | TestPoint:TestPoint_Pad_D1.5mm | TP408, TP508 |
| 2 | I2CC_SDA | TestPoint:TestPoint_Pad_D1.5mm | TP407, TP507 |
| 2 | IRQ_N | TestPoint:TestPoint_Pad_D1.5mm | TP107, TP304 |
| 2 | LDO_3V3 | TestPoint:TestPoint_Pad_D1.5mm | TP414, TP514 |
| 2 | LIQ_PD | TestPoint:TestPoint_Pad_D1.0mm | TP421, TP521 |
| 2 | LIQ_PU | TestPoint:TestPoint_Pad_D1.0mm | TP420, TP520 |
| 2 | M24512-DFMC6TG | MonolithDev:ST_UFDFPN-8-1EP_2x3mm_P0.5mm_EP1.2x1.4mm | U402, U502 |
| 2 | PG | TestPoint:TestPoint_Pad_D1.5mm | TP411, TP511 |
| 2 | PP5V | TestPoint:TestPoint_Pad_D1.5mm | TP403, TP503 |
| 2 | PPHV | TestPoint:TestPoint_Pad_D1.5mm | TP402, TP502 |
| 2 | REGN | TestPoint:TestPoint_Pad_D1.5mm | TP404, TP504 |
| 2 | SBU1_SNS | TestPoint:TestPoint_Pad_D1.0mm | TP418, TP518 |
The 347 most common of 430 parts.

MidwestMotorBoy/Battery-Bank
Monolith: an ultralight IP67 power bank for backpacking. 4S BAK 65E 21700 (91 Wh, under the 100 Wh airline limit), two bidirectional 100 W USB-C PD ports, Bluetooth LE (TI CC2340) with an iPhone app.

Serhio4522/SEM_hitachi-
Digitization of a Hitachi scanning electron microscope (SEM) — hardware design, FPGA firmware, and analog frontend schematics.

Seeed-Studio/OSHW-reCamera-Series
reCamera is a series of open-source AI cameras.

dudgeon/count-fidget
A lightweight, rechargeable two-key fidget that counts clicks, resets with a second key, and remembers its count while asleep or unpowered. Designed for a home-printed enclosure and professionally assembled electronics.

jackw01/scanlight
A better light source for scanning color negative film

amuzdgp3-prog/im-01-pulse-device
Отдельный модуль к системе обслуживания аппаратов 2.apixspb.ru. Устройство слушает импульсные выходы монетоприёмника и купюроприёмника, копит показания в FRAM и дважды в сутки передаёт их на сервер по LTE Cat.1.

igorwolfs/modular-processing-hw
MCU Breakout board with Hirose BM28B connector

marcoallegretti/Teresina-Rack
The goal is an open, self-fabricatable Daisy Patch SM-compatible Eurorack submodule: the same carrier interface and libDaisy application compatibility through a small Teresina firmware variant.

LimesKey/parsnip-node
A portable LoRa communicator. Custom 4-layer PCB (ESP32-S3 + E22P-915M30S LoRa + NEO-M9N GNSS), designed in KiCad for 915 MHz.
It measures 196 × 115 mm and has 6 copper layers, 1.6 mm thick.
430 parts, built around the BQ25756RRVR, M24512-DFMC6TG, CL05B104KB54PNC and CL31A226KAHNNNE. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
From the MidwestMotorBoy/Battery-Bank repository on GitHub, at the commit this page was made from: the board is hardware/DevBoard/MonolithDev.kicad_pcb and its schematic hardware/DevBoard/MonolithDev.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Its repository states no licence, so its author keeps all rights: ask MidwestMotorBoy before reusing the design.