Files
midi-router/docs/hardware-plan.md
T
nils afb07dd1c0 Hardware plan: deepen + design bipolar ±10V CV from the start
- Power budget (BLE-only, never WiFi TX) with concrete mA table.
- Bipolar CV section: ±12V rails (boost + inverter), DAC 0-4.096V -> ±10V
  via difference amp with 2.048V mid-ref, per-channel gain/offset trim,
  OPA4192 on ±12V, bidirectional TVS. Function+polarity decides mapping
  (pitch stays 0..+10V standard on a bipolar output).
- Concrete BOM table (part numbers, packages, alternates).
- Risks updated for bipolar calibration + ±12V rail noise.
- Build order updated.
2026-08-21 11:02:11 +02:00

11 KiB
Raw Blame History

Hardware Plan — flexible MIDI router (v1)

Status: draft 2026-08-21. Custom all-in-one PCB, desktop, USB-powered, bipolar ±10 V CV via onboard ±12 V rails, 3.5 mm TRS MIDI, 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 ──┬── 3.3 V buck ── RP2040 + W25Q16 flash + RM2 module (CYW43439, BLE/WiFi)
           │                   │
           │                   ├── PIO0 SPI ── RM2 (CYW43439 gSPI, Pico-W pinout)
           │                   ├── USB DP/DM ── (USB-MIDI composite, CDC+MIDI)
           │                   ├── UART0 ──── MIDI TRS in (6N138) / out
           │                   ├── I2C0 ───── Pimoroni RGB Keypad (buttons)
           │                   ├── SPI0 ───── Pimoroni RGB Keypad (APA102 LEDs)
           │                   ├── SPI1 ───── 8-ch 16-bit DAC (CV outs)
           │                   ├── I2C1 ───── 64×32 SSD1306 OLED
           │                   └── GPIOs ──── 4× tact buttons (UI)
           │
           └── ±12 V rails (boost + inverter) ── CV op-amps ── 4× stereo TRS (8 CV/gate)
                  │
   4.096 V ref ── DAC (0-4.096 V) ── op-amp gain ×4.88, offset −10 V ── ±10 V ── 1 k + bidir TVS ── TRS tip/ring

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-only, with CV boost)

  • USB-C 5 V → polyfuse + ESD → VBUS_5V.
  • VBUS_5V → 3.3 V buck (RT6150B-33GQW) → RP2040, RM2, flash, DAC VDD, OLED, pull-ups.
  • VBUS_5V → +12 V boost (TPS61088 + LC filter) → +12 V CV op-amp rail.
  • VBUS_5V → −12 V inverter (TPS63700 + LC filter) → −12 V CV op-amp rail. Both rails feed the bipolar CV op-amps. Low current (~20 mA each), LC-filtered.
  • 4.096 V reference (REF3040AIDBZ) for the DAC, and a 2.048 V mid-ref (buffered divider or REF2040) for the bipolar offset — NOT the 3.3 V rail (too noisy for 1 V/oct pitch).

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 (op-amps + DAC out) ~20 mA @12 V → ~50 mA @5 V (×2 converters, ~85% eff) ~60 mA @5 V
MIDI out LED (brief) — ~15 mA @3.3 V
Total from 5 V ~180-230 mA ~330-380 mA

Fits USB 2.0 (500 mA) with headroom; USB-C default (900 mA) is comfortable. If WiFi TX were ever enabled, RM2 spikes to ~350 mA and the total approaches ~650 mA — stay BLE-only or require a USB-C 1.5 A/3 A source.

Rationale: USB-only power (single cable, no external PSU) while delivering bipolar ±10 V CV via two small low-current rails. The LC filters + dedicated Vref keep pitch clean.

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) — 2 jacks (in + out), TRS-A wiring

  • In: 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: UART0 TX (GP0) → 220 Ω → tip; ring to 3.3 V. (3.3 V/220 Ω ≈ 15 mA, fine for MIDI-out LED.)
  • 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
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 6× 3.5 mm TRS SMD 2 MIDI + 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

  1. 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.
  2. ±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.
  3. Custom RP2040 bring-up — needs a SWD header + Picoprobe; USB bootloader only works after first flash.
  4. 64×32 OLED UI — tight; menu must be paginated and minimal.
  5. Boost current budget — RM2 TX spikes + 8 CV op-amps + two converters on a single USB 5 V/500 mA port is tight; BLE-only keeps it ~330-380 mA peak (fits), but specify USB-C 5 V/900 mA for headroom.
  6. RM2 antenna keepout — follow the datasheet keepout; the one layout constraint the radio imposes.

10. Build order (hardware)

  1. Schematic (this doc is the spec).
  2. RM2 module footprint + antenna keepout.
  3. RP2040 + flash + USB + SWD.
  4. Power (3.3 V buck, +12 V boost, −12 V inverter, 4.096 V + 2.048 V refs).
  5. CV analog (DAC + difference-amp + offset + trim + bidir protection + TRS).
  6. MIDI TRS circuit.
  7. OLED + buttons.
  8. Keypad header (the Pimoroni keypad connects via a header or is integrated).
  9. PCB layout, DRC, review, fab.