L-shape opens toward bottom-left; the two long outer edges carry the jack rows (CV top, MIDI right, ~52 mm each), USB-C on the short left edge beside the battery. Top arm = all CV analog + switching converters (noise kept far from radio); right arm = digital + MIDI + RM2 at the bottom-right corner for best antenna keepout. Target 2000 mAh cell -> ~70x58 mm bounding box, 50x35 mm notch. Renumbered build order.
22 KiB
Hardware Plan — flexible MIDI router (v1)
Status: draft 2026-08-21. Custom all-in-one PCB, L-shaped with a LiPo battery notch (~70×58 mm bounding box, 2000 mAh target), desktop, USB or battery powered, bipolar ±10 V CV via onboard ±12 V rails, 3.5 mm TRS MIDI (1 in + 3 mirror out), 4× stereo CV, 64×32 OLED + tact buttons (no encoder, low profile).
MCU target: develop/test on RP2040 (Pico W dev board — the firmware
already runs on it), product on RP2350. The RM2 radio module is compatible
with both. The Rust firmware builds for either via embassy-rp features
(rp2040 → thumbv6m-none-eabi; rp235xa for the RP2350A used in the Pico 2 W
→ thumbv8m.main-none-eabihf). Pin assignments below are RP2040/Pico-W; the
RP2350 product PCB keeps the Pico-2-W-compatible RM2 bus and reuses the same
peripheral choices.
See midi-router-architecture (session memory) for the software/firmware
architecture this hardware serves.
1. Block diagram
USB-C 5V ── BQ24075 (charger + power-path) ── SYS (~3.0-4.2 V)
│ │
LiPo cell (charge/discharge) ├── 3.3 V buck-boost ── RP2040 + flash + RM2
│ ├── +12 V boost ──┐
│ ├── −12 V inverter┤ CV op-amps (±12 V) ── 4× stereo TRS
MAX17048 fuel gauge (I2C) └── 4.096 V/2.048 V refs ── DAC ── diff-amp → ±10 V
│
RP2040: PIO0 SPI ── RM2 | USB DP/DM ── USB-MIDI composite | UART0 ── MIDI TRS
I2C0 ── keypad | SPI0 ── keypad LEDs | SPI1 ── DAC | I2C1 ── OLED + fuel gauge
UART0 RX ── MIDI in (6N138) UART0 TX ── MIDI out (×3 mirror jacks)
GPIOs ── 4× tact + charge-status LED
2. RP2040 pin map
Peripherals follow the Pico W reference for the RM2/CYW43 bus (so the cyw43 driver and our firmware work unchanged) and our existing keypad wiring.
| Function | RP2040 pins | Notes |
|---|---|---|
| USB device | GP14 (DM), GP15 (DP) | USB-C; CDC + MIDI composite |
| RM2 (CYW43) bus | GP29 (CLK), GP24 (DAT), GP25 (CS-out), GP23 (PWR), PIO0, DMA CH0/CH1 | copy Pico W |
| RM2 onboard LED | CYW43 WL_GPIO0 | status/heartbeat |
| Keypad buttons | GP4 (SDA), GP5 (SCL) | I2C0, expander @0x20 |
| Keypad LEDs | GP17 (CS), GP18 (SCK), GP19 (MOSI) | SPI0 tx-only, 4 MHz, APA102 |
| DAC (CV outs) | GP10 (SCK), GP11 (MOSI), GP13 (CS) | SPI1 tx-only, 16-bit DAC; MISO unused |
| DAC LDAC/RESET | GP20, GP21 | GPIO (optional, immediate-update) |
| MIDI TRS UART | GP0 (TX), GP1 (RX) | UART0 @31250 baud |
| OLED | GP2 (SDA), GP3 (SCL) | I2C1, SSD1306 64×32 |
| UI buttons | GP6, GP7, GP8, GP9 | 4× low-profile tact: Up/Down/Select/Back |
| SWD debug header | SWCLK, SWDIO | 2×3 header for Picoprobe (first-flash) |
| Spare | GP16, GP22, GP26-28 | status LEDs / future analog in |
No conflicts; GP14/15 (USB) and GP23-25/29 (CYW43) kept clear of everything else.
3. Power tree (USB + LiPo battery with power-path)
- USB-C 5 V → polyfuse + ESD → VBUS_5V → BQ24075 charger/power-path IC.
- VBUS present → device runs from VBUS and charges the cell; SYS output is the system rail.
- VBUS absent → battery powers SYS seamlessly (no glitch).
- SYS rail (~3.0-4.2 V) — the battery-voltage domain, the new system input.
- SYS → 3.3 V buck-boost (RT6150B-33GQW — already a buck-boost, so it holds 3.3 V through the whole SYS range, including battery sag) → RP2040, RM2, flash, DAC VDD, OLED, pull-ups.
- SYS → +12 V boost (TPS61088) → +12 V CV op-amp rail (input 3.0-4.2 V when on battery is fine; just draws more current at low voltage).
- SYS → −12 V inverter (TPS63700) → −12 V CV op-amp rail.
- 4.096 V reference (REF3040AIDBZ) and 2.048 V mid-ref (REF2040) — powered from +3V3 (post-buck, clean), NOT from SYS (sags with battery) or the 3.3 V rail directly (too noisy for 1 V/oct pitch).
- LiPo cell (single, 3.7 V nominal, ~1500-2000 mAh, integrated protection PCB) on BAT. Charge rate set by BQ24075 PROG pin (~500 mA to stay within USB 2.0; raise if using USB-C 1.5/3 A).
- MAX17048 fuel gauge (I2C1, shared with OLED) → battery state-of-charge on the OLED + low-battery warning in firmware.
Power budget (BLE-only): we use Bluetooth only, never WiFi TX. The cyw43 driver must load the WiFi firmware to bring up BT (BT-only init isn't supported yet), but WiFi never transmits → power stays at BLE levels, not WiFi-TX levels.
| Rail / consumer | Typical | Peak |
|---|---|---|
| RM2 (BLE TX, no WiFi TX) | ~30 mA @3.3 V | ~80 mA |
| RP2040 / RP2350 | ~30 mA | ~50 mA |
| DAC8568 | ~2 mA | ~2 mA |
| OPA4192 ×2 (quiescent) | ~9 mA @±12 V | ~9 mA |
| OLED SSD1306 | ~20 mA | ~40 mA |
| ±12 V rails load | ~20 mA @±12 V → ~60 mA @SYS (×2 converters, ~80% eff) | ~75 mA @SYS |
| MIDI out LED (brief) | — | ~15 mA @3.3 V |
| System draw from SYS | ~200-260 mA | ~340-400 mA |
Battery life: a 2000 mAh cell at ~250 mA avg → ~7-8 h (peak BLE + display); a 1500 mAh cell → ~5-6 h. SYS sags to ~3.3 V at end of discharge, all converters stay in regulation. When USB present, SYS = charge voltage (~4.2 V max); charge current limited to ~500 mA by default to respect USB 2.0 (battery tops up in ~3-4 h for a 1500 mAh cell).
Rationale: USB or battery operation via one power-path IC; the existing converters already accept the SYS voltage range (buck-boost on 3.3 V is the key — a plain buck would drop out near end-of-discharge). BLE-only keeps the budget comfortable; WiFi TX would push ~600 mA peak and halve battery life.
4. CV analog section (4 stereo = 8 channels, bipolar ±10 V)
- DAC: 8-channel 16-bit SPI (DAC8568IAPW), Vref = 4.096 V → 0-4.096 V out. 16-bit over ±10 V (20 V span) ≈ 0.3 mV/step ≈ 0.003 semitone at 1 V/oct — plenty for pitch.
- Bipolar scaling: each channel maps 0-4.096 V → −10 V…+10 V. Difference
amp:
Vout = 4.88·(Vdac − 2.048)where 2.048 V is the mid-reference (buffered divider from the 4.096 V ref, or REF2040). At Vdac=0 → −10 V, Vdac=2.048 → 0 V, Vdac=4.096 → +10 V. Per-channel gain/offset trimpot for pitch calibration (0.2 % ref → ~±20 mV untrimmed ≈ 0.02 semitone — trimmable to <1 mV). - Op-amps: OPA4192IPWR (quad, RRO, 25 µV offset) ×2 on the ±12 V rails. RRO needed to reach ±10 V cleanly on ±12 V (TL074 clips at ±~10.5 V — too close; OPA4192 swings to ±11.9 V).
- Per-channel model: every CV channel is an independent
(midi_channel, function, polarity)sink. The output stage is always bipolar-capable (±10 V); the function decides the mapping:- pitch → 0…+10 V (note/12, standard unipolar-positive on a bipolar output)
- gate → 0/+10 V (or 0/+5 V)
- velocity → 0…+10 V (vel/127·10)
- CC (unipolar) → 0…+10 V; CC (bipolar) → −10…+10 V (cc/127·20 − 10) Gate = a DAC channel driven to 0/+10 V (keeps routing uniform).
- Output protection: 1 kΩ series + bidirectional TVS per output (outputs swing negative) to TRS tip/ring.
5. MIDI TRS (3.5 mm) — 1 in + 3 mirror out, TRS-A wiring
- In (J3): tip → 220 Ω → 6N138 optocoupler LED → cathode to ring. Transistor: collector to 3.3 V via 1 k pull-up → UART0 RX (GP1); emitter to GND; base speed-up (1N4148 + 1 k). Isolated; powered from the input loop.
- Out (J4/J5/J6 — hardwired mirror): UART0 TX (GP0) → 220 Ω series → drives all 3 output jacks in parallel (tip = signal on each; ring = 3.3 V). One TX, three identical outputs — a hardwired MIDI-thru/splitter. All 3 jacks emit byte-for-byte the same stream; the router decides what's on that stream (per port-type routing), the 3 jacks are one logical "TRS out" port fanned out for cabling convenience. No per-jack channel separation.
- TRS-A: tip = signal, ring = return (Korg / Make Noise convention).
6. Display + UI
- OLED: SSD1306 64×32 (0.42"), I2C1. Small — UI is paginated (≈2 lines of small text); routing/CV assignments shown a few at a time.
- Buttons: 4× low-profile SMD tact (Up / Down / Select / Back) on GP6-9. No rotary encoder (height constraint).
7. RM2 radio module — risk largely eliminated
Use the Raspberry Pi Radio Module 2 (RM2, part RMC20452T): a CYW43439-based module (16.5 × 14.5 mm, 21 castellated pads) with integrated inverted-F PCB antenna and internal PA/LNA/T-R switch. Full modular radio approval in US/EU/ UK/CA (FCC ID 2ABCB-RMC2GW4B52) — no radio design or certification needed on the host board. Software-compatible with the Pico W SDK, so our cyw43 firmware works unchanged.
Host PCB responsibilities (from the RM2 datasheet):
- Mount the 21 castellated pads; route the gSPI host pins to RP2040 (Pico W pinout: CLK=GP29, DAT=GP24, CS=GP25, PWR=GP23, on PIO0 + DMA CH0/CH1).
- 3.3 V supply (no other rails).
- Antenna keepout area must remain free of metal per the datasheet for the module's PCB antenna to perform.
8. BOM (concrete parts)
| Ref | Part | Package | Notes |
|---|---|---|---|
| MCU | RP2040 (dev) / RP2350A (product) | QFN-56 / QFN-60 | dual target via embassy-rp features |
| Flash | W25Q32JVSSIQ | SOIC-8 | 32 Mb (4 MB) — Rust firmware + blobs ~870 KB UF2, headroom for router code |
| Radio | RM2 module RMC20452T | 16.5×14.5 mm, 21-pad | CYW43439 + PCB antenna, pre-certified |
| DAC | DAC8568IAPW | TSSOP-16 | 8-ch 16-bit SPI, external Vref mode (AD5668BRUZ-1 alt) |
| Op-amp | OPA4192IPWR ×2 | TSSOP-14 | quad RRO, 25 µV offset, on ±12 V rails — pitch-accurate |
| Vref | REF3040AIDBZ | SOT-23 | 4.096 V DAC ref, 0.2%, 30 ppm/°C |
| Mid-ref | REF2040AIDBZ (or buffered divider) | SOT-23 | 2.048 V bipolar offset reference |
| Calib | 8× trimpot (e.g. 3296W) | THT/SMD | per-channel gain/offset trim |
| MIDI opto | 6N138 | DIP-8 / SMD | MIDI in isolation |
| Charger | BQ24075DRCR | MSOP-10 | single-cell LiPo charger + power-path (SYS pin) |
| Fuel gauge | MAX17048G+T10 | TDFN-8 (or bare module) | LiPo SoC over I2C1 (optional) |
| Battery | LiPo 3.7 V, 1500-2000 mAh | cell w/ protection PCB | integrated DW01/FS8205A protection |
| 3.3 V reg | RT6150B-33GQW | QFN | buck-boost, 800 mA, Pico-proven (TPS62A01 alt) |
| +12 V boost | TPS61088 | QFN | 5→12 V, low-noise + LC filter |
| −12 V inverter | TPS63700 | SOT-23-6 / QFN | 5→−12 V, low-noise + LC filter (LM2611 alt) |
| Display | SSD1306 64×32 OLED | 0.42" I2C | — |
| Jacks | 8× 3.5 mm TRS | SMD | 1 MIDI in + 3 MIDI out (mirror) + 4 CV stereo |
| USB | USB-C receptacle | SMD | 5 V data + power |
| UI | 4× low-profile tact | SMD | Up/Down/Select/Back (no encoder) |
| Debug | 2×3 SWD header | THT | Picoprobe first-flash |
| — | polyfuse, bidirectional TVS array, passives | — | bipolar output protection + rail protection |
9. Risks / open items
- Bipolar ±10 V offset/gain calibration — the 2.048 V mid-ref and ×4.88 gain set the 0 V center and ±10 V span; 0.2 % ref → ~±20 mV untrimmed (≈0.02 semitone). Per-channel trimpots trim gain + offset to <1 mV; or calibrate in firmware (measure + store correction) to avoid trimpots.
- ±12 V rail noise on pitch — two switching converters (+12 V boost, −12 V inverter); LC filter both rails + 4.096 V/2.048 V refs are the pitch reference, not the rails, so op-amp PSRR + filtering keeps it clean.
- Custom RP2040 bring-up — needs a SWD header + Picoprobe; USB bootloader only works after first flash.
- 64×32 OLED UI — tight; menu must be paginated and minimal.
- Boost current budget — RM2 TX spikes + 8 CV op-amps + two converters; BLE-only keeps the system draw ~340-400 mA peak from SYS, plus up to ~500 mA battery charge from USB → USB-C 5 V/900 mA-1.5 A recommended (USB 2.0 500 mA only if charging paused or BLE-only/low charge rate).
- Battery sag at end-of-discharge — SYS can sag to ~3.3 V; the 3.3 V path must be a buck-boost (RT6150B is) or it drops out. Fuel gauge drives a low-battery warning in firmware; cut off at ~3.3 V to protect the cell.
- Charge thermal — BQ24075 thermal-regulates; keep it away from the CV references / DAC and away from the LiPo for thermal separation.
- LiPo shipping / safety — LiPo cells have shipping (UN3481) and safety considerations; use a protected cell, add a charge LED, follow charge-IC layout guidance.
- RM2 antenna keepout — follow the datasheet keepout; the one layout constraint the radio imposes.
10. Build order (hardware)
- Schematic (this doc is the spec).
- Board outline: L-shape, ~70×58 mm bounding box, bottom-left battery notch (50×35 mm for 2000 mAh cell). RM2 antenna keepout at bottom-right corner; USB-C left, CV top, MIDI right (§12).
- RM2 module footprint + antenna keepout.
- RP2040 + flash + USB + SWD.
- Power (BQ24075 power-path + LiPo, 3.3 V buck-boost, +12 V boost, −12 V inverter, 4.096 V + 2.048 V refs, MAX17048 fuel gauge).
- CV analog (DAC + difference-amp + offset + trim + bidir protection + TRS).
- MIDI TRS circuit.
- OLED + buttons.
- Keypad header (the Pimoroni keypad connects via a header or is integrated).
- PCB layout, DRC, review, fab.
11. Connection table (netlist source of truth)
Reference designators and net membership. RP2040 pins are logical GPIO names
(map to physical QFN pins in KiCad). A machine-importable KiCad netlist lives
at hardware/netlist.net.
Reference designators
| Ref | Part | Role |
|---|---|---|
| U1 | RP2040 | MCU |
| U2 | W25Q32JV | flash |
| MOD1 | RM2 (RMC20452T) | BLE/WiFi radio |
| U3 | RT6150B-33 | 3.3 V buck |
| U4 | TPS61088 | +12 V boost |
| U5 | TPS63700 | −12 V inverter |
| U6 | REF3040 | 4.096 V DAC reference |
| U7 | REF2040 | 2.048 V bipolar mid-reference |
| U8 | DAC8568 | 8-ch 16-bit SPI DAC |
| U9, U10 | OPA4192 | quad RRO op-amp ×2 (8 CV channels) |
| U11 | 6N138 | MIDI-in optocoupler |
| U12 | BQ24075 | single-cell LiPo charger + power-path |
| U13 | MAX17048 | LiPo fuel gauge (I2C) |
| BAT1 | LiPo cell | ~1500-2000 mAh, integrated protection |
| DISP1 | SSD1306 | 64×32 OLED (I2C) |
| J1 | USB-C | 5 V + USB data |
| J2 | 2×3 header | SWD (Picoprobe) |
| J3 | 3.5 mm TRS | MIDI in |
| J4, J5, J6 | 3.5 mm TRS | MIDI out (×3 hardwired mirror) |
| J7–J10 | 3.5 mm TRS | 4× stereo CV out |
| J11 | 2×5 header | Pimoroni keypad |
| SW1–SW4 | tact | UI (Up/Down/Select/Back) |
| FB1 | polyfuse | 5 V input protection |
| L1, L2 | inductors | boost/inverter LC filters |
| D1–D8 | bidirectional TVS | CV output protection |
| R_cal1–R_cal8 | — | per-channel calibration (see §4) |
Power nets (with battery power-path)
J1.VBUS ── FB1 ── VBUS_5V
VBUS_5V ── U12 (BQ24075 VBUS) ; USB input to charger/power-path
BAT1 ── U12 (BAT) ; LiPo cell
U12 (SYS) ── SYS rail (~3.0-4.2 V) ; system supply (USB or battery)
SYS ── U3 (RT6150B-33) ── +3V3 ; buck-boost: holds 3.3 V across SYS range
SYS ── U4 (TPS61088) + L1 LC ── +12V
SYS ── U5 (TPS63700) + L2 LC ── −12V
+3V3 ── U6 (REF3040) ── VREF4V096 ; refs from clean +3V3, not saggy SYS
+3V3 ── U7 (REF2040) ── VMID2V048
U13 (MAX17048) SDA/SCL ── I2C1 (shared with OLED) ; fuel gauge
U12 (STAT) ── U1.GPIO16 ; charge status (→ LED + firmware)
GND = J1.GND, BAT1.GND, all return paths
RM2 radio (Pico-W-compatible gSPI)
MOD1.CLK ── U1.GPIO29 (PIO0 SPI CLK)
MOD1.DAT ── U1.GPIO24 (PIO0 SPI DOUT/MOSI)
MOD1.CS ── U1.GPIO25 (output, CS)
MOD1.PWR ── U1.GPIO23 (output, power enable)
MOD1.IO0 ── (onboard LED, CYW43 WL_GPIO0 — status)
MOD1.VDD ── +3V3
MOD1.GND ── GND
MOD1 bus driven by U1 PIO0 + DMA CH0/CH1 (firmware copies Pico W)
USB + flash + SWD
J1.DP ── U1.GPIO15 (USB_DP)
J1.DM ── U1.GPIO14 (USB_DM)
U2.CS ── U1.QSPI_CS
U2.CLK ── U1.QSPI_SCK
U2.DQ0 ── U1.QSPI_SD0 ... DQ3 ── SD3 (QSPI flash)
U2.VDD ── +3V3
J2.SWDIO ── U1.SWDIO J2.SWCLK ── U1.SWCLK J2.GND ── GND
CV DAC (SPI1)
U8.SCLK ── U1.GPIO10
U8.DIN ── U1.GPIO11
U8.CS ── U1.GPIO13 (output)
U8.LDAC ── U1.GPIO20 (output, immediate-update / strobe)
U8.RSTB ── U1.GPIO21 (output, reset)
U8.VREF ── VREF4V096
U8.VDD ── +3V3
U8.VSS ── GND
U8.VOUTA..VOUTH ── 8 CV difference-amp inputs (see below)
CV analog (8 channels, bipolar ±10 V)
Per channel n (n=1..8): subtractor Vout = (Rfb/Rin)*(Vdac − VMID2V048),
Rin=10.0 k, Rfb=48.7 k (ratio 4.87 → ±9.98 V span; firmware calibrates exact).
One op-amp = 1/4 of an OPA4192 (U9 = ch1-4, U10 = ch5-8).
Channel 1 (J7.tip = pitch, J7.ring = gate):
U8.VOUTA ── Rin1a ── U9.1IN- ; Vdac into subtractor V-
VMID2V048 ── Rin1b ── U9.1IN+ ; mid-ref into V+
U9.1OUT ── Rfb1 ── U9.1IN- ; feedback
Rgnd1 (48.7k) ── U9.1IN+ ── GND ; balance resistor
U9.1OUT ── Rser1 (1k) ── D1 ── J7.tip
U9.1OUT ── (rail) +12V / −12V ; OPA4192 supply
Channel 2 (J7.ring): U8.VOUTB → U9.2... → J7.ring
...channels 3,4 → U9.3/4 → J8.tip/ring
...channels 5-8 → U10.1-4 → J9.tip/ring, J10.tip/ring
Pattern repeats: VOUTx → Rin → subtractor → Rfb feedback, Rgnd on V+, output → 1 k series → TVS → TRS tip/ring. U9/U10 V+ = +12 V, V− = −12 V.
MIDI TRS (3.5 mm, TRS-A)
MIDI in (J3):
J3.tip ── R_lim (220Ω) ── U11.LED-A (6N138 anode)
U11.LED-K ── J3.ring
U11.OC-collector ── +3V3 via R_pull (1k) ── U1.GPIO1 (UART0 RX)
U11.OC-emitter ── GND
U11.base ── 1N4148 + 1k speed-up ── GND/+3V3 (per 6N138 app note)
MIDI out — hardwired mirror (J4, J5, J6):
U1.GPIO0 (UART0 TX) ── R_lim (220Ω) ── MIDI_TX node
MIDI_TX ── J4.tip ── J5.tip ── J6.tip ; one TX fans to all 3 tips
J4.ring ── J5.ring ── J6.ring ── +3V3 ; common return
(all 3 jacks emit byte-for-byte the same stream — no per-jack isolation)
Display + UI + keypad
DISP1.SDA ── U1.GPIO2 (I2C1 SDA) DISP1.SCL ── U1.GPIO3 (I2C1 SCL)
DISP1.VDD ── +3V3 DISP1.GND ── GND
SW1 ── U1.GPIO6 SW2 ── U1.GPIO7 SW3 ── U1.GPIO8 SW4 ── U1.GPIO9
(each SW: other side to GND; internal pull-up)
Keypad header J11 (Pimoroni RGB Keypad):
J11.SDA ── U1.GPIO4 (I2C0 SDA) J11.SCL ── U1.GPIO5 (I2C0 SCL)
J11.CS ── U1.GPIO17 J11.SCK ── U1.GPIO18 J11.MOSI ── U1.GPIO19
J11.VDD ── +3V3 J11.GND ── GND
Spare GPIOs
U1.GPIO16, GPIO22, GPIO26, GPIO27, GPIO28 ── unassigned (status LEDs / analog in / future)
12. Board outline (L-shape, battery notch)
The LiPo cell is the single largest item, so the PCB is L-shaped — the 55-ish mm connector square with the bottom-left quadrant notched out for the battery. The two long outer edges of the L carry the two jack rows (each needs ~52 mm for 4 jacks); USB-C sits on the short left edge, right beside the battery — which is where BQ24075, MAX17048 and the cell pigtail want to be anyway.
═══════════════════════════════════════════
║ CV CV CV CV ║ top arm → CV analog
║ J7 J8 J9 J10 DAC·refs·opa·±12V ║ (DAC8568, REF3040/2040,
║ ║ 2× OPA4192, boost+inverter, LC)
║ USB-C ║
╚═══╗ ║
║ ║
B ║ MIDI MIDI MIDI MIDI ║ right arm → digital + MIDI
A ║ J6 J5 J4 J3 ║ (6N138, UART, RP2040, flash,
T ║ MCU · flash · RM2 ▼ keepout ║ RM2, SWD, keypad, OLED, btns)
║ SWD · keypad · OLED · SW1-4 ║
╚═══════════════════════════════════════╝
↑ battery notch (bottom-left, off-board cell)
Sizing (battery drives the notch):
| Cell | Pouch size | Notch | Bounding box |
|---|---|---|---|
| 1500 mAh | ~36 × 30 mm | 36 × 30 mm | ~56 × 55 mm |
| 2000 mAh (target) | ~50 × 35 mm | 50 × 35 mm | ~70 × 58 mm |
Both long arms clear the 52 mm the jacks need (top arm = full width, right arm = full height). USB-C (~9 mm) fits the short left edge either way. Target the 2000 mAh / ~70 × 58 mm outline; a 1500 mAh cell just shrinks the notch.
Edge assignment:
- Top edge: 4× CV jacks (J7–J10), full width.
- Right edge: 4× MIDI jacks (J3 in + J4/J5/J6 mirror out), full height.
- Left edge (short, top-arm left end): USB-C (J1).
- Bottom edge (short, right-arm bottom end): SWD header (J2), keypad header (J11), battery pigtail — accessible, non-user-facing.
Region assignment (the split is functional, not just compact):
- Top arm = all analog/CV + the two switching converters. Keeps the ±12 V boost/inverter noise up near the CV op-amps and far from the radio/MCU. Inductors + LC against the top edge; DAC8568, REF3040, REF2040, 2× OPA4192 follow.
- Right arm = digital + MIDI + radio. RP2040 + flash + RM2 + 6N138 + UART. RM2 at the bottom-right outer corner of the right arm — the point farthest from the battery, jacks, and switching converters — with its antenna keepout extending off the corner (best RF spot on an L-board).
- Battery + charger (bottom-left notch area): short USB-C → BQ24075 → cell traces, MAX17048 fuel gauge beside them.
- Inner L corner (top-right inside): quietest spot on the board — put the DAC→op-amp routing and the reference/analog star-ground here, sandwiched between the analog and digital arms but off both edges.