Molecule_RP2350B_RM2_v1 — Hardware Reference

RP2350B + CYW43439 (Raspberry Pi RM2) castellated molecule. This is the board fw_stationary and fw_arm target.

  • Source: adom-inc/adom-molecules — imported here on 2026-04-17
  • KiCad project name: Molecule_RP2350B_RM2_v1 (internal board name in .kicad_pro: Molecule RP2350B RM2 W v1.0)
  • Wiki page: molecules/molecule-rp2350b-rm2-v1-106000 — currently a stub (auto-imported 2025-10-10, no pin map or BOM detail)
  • Supersedes: the older hardware/pico2-2w-molecule-v20/ folder (wrong board). That folder should be removed once firmware is confirmed building against this one.
  • PCB: 4-layer (inferred from kicad_pcb stackup settings), USB Micro-B connector, 62 perimeter machine-pin contacts + 4 mounting pins
  • MCU: RP2350B in QFN-80 (U1). Not the Pico-W-style RP2350A — this is the full 80-pin variant with 48 GPIOs and 8 ADC channels

Files in this folder

File What it is
Molecule_RP2350B_RM2_v1.kicad_pro KiCad 9 project file
Molecule_RP2350B_RM2_v1.kicad_sch Schematic (flat, single sheet, ~30k lines)
Molecule_RP2350B_RM2_v1.kicad_pcb PCB layout (~62k lines)
Molecule_RP2350B_RM2_v1-0.step / *.wrl 3D models (STEP + VRML) of the assembled board
Molecule_RP2350B_RM2_v1-0 fancy big.step High-poly 3D model (24 MB)
MCU_RaspberryPi_RP2350.kicad_sym / .lib Local RP2350 symbol library
RP2350_80QFN_minimal.pretty/ Footprint library (RP2350 QFN-80, passives, USB micro-B)
RP2350_QFN80.step RP2350 QFN-80 3D body
jlcpcb/production_files/BOM-*.csv JLCPCB BOM
jlcpcb/production_files/CPL-*.csv JLCPCB component placement list
jlcpcb/production_files/GERBER-*.zip Manufacturing gerbers
fp-lib-table, sym-lib-table KiCad library index

Component summary (from BOM + CPL)

Ref Part LCSC Function
U1 RP2350B (QFN-80, 10×10 mm, 0.4 mm pitch, EP 3.4 mm) C42415655 MCU
U3 W25Q128JVPIQ C190862 16 MB (128 Mbit) QSPI XIP flash
U5 APS6404L-3SQR-ZR C3040877 8 MB (64 Mbit) QSPI PSRAM — footprint present but DNP on production boards (confirmed by project lead 2026-04-17)
U9 RM2 (CYW43439 radio module, Raspberry Pi) Wi-Fi 4 + BT/BLE
U100 AP2112K-3.3 (SOT-23-5) C51118 3.3 V LDO (600 mA, LDO_EN controlled)
Y1 ABM8-272-T3 (3.2×2.5 mm) C20625731 12 MHz crystal (MCU XIN/XOUT)
L1 3.3 µH (L_pol_2016 fp) C42411119 RP2350 internal-buck inductor (VREG_LX+1V1). BOM lists value as "3.3uF" — that is a BOM-field typo; footprint is an inductor and it sits on the VREG_LX net
L3 470 Ω @ 100 MHz ferrite bead (0603) C97853 EMI filter on +3V3 feed to U9 radio
D101 Red LED (0402) C130719 Power indicator (on +3V3 via R6 1 k)
D102, D103 Blue LEDs (0402) C130724 User LEDs
SW1 B3U-1000P momentary C231329 BOOT — pulls QSPI_SS low → USB bootloader
SW2 B3U-1000P momentary C231329 RST — chip reset (RUN line)
R7, R8 27 Ω C25100 USB D+/D− series termination
R3 33 Ω C25105 USB VBUS filter / series
R40 470 Ω — series POCI-to-DATA tie C25117 See "Radio wiring" below
R41 10 kΩ — IRQ pull to DATA tie C25744 See "Radio wiring" below
R12 10 kΩ C25744 Pull-up on QSPI_SS (BOOT button)
R1, R100 100 kΩ C25741 Pull-down / strap
R2, R4, R6, R101, R102, R103 1 kΩ C11702 LED current-limit + misc pull
R10 0 Ω C17168 Jumper
C3, C4 15 pF C1548 Crystal load caps
C6, C7 4.7 µF (small-pad 0402) C23733 VREG_LX / VREG_AVDD bypass
C9, C10 4.7 µF C23733 Bulk
C100, C101 10 µF C15525 +3V3 / +5V bulk
13× C2,C8,C11–C18,C20,C21,C23 100 nF C1525 Decoupling
MP1–MP4 ADOM_MEDIUM_PIN_SHORTER_CASTELLATED_v1 Mounting pins (corners)
MC1–MC53, MC58–MC60 ADOM_MEDIUM_CONTACT_CASTELLATED_WIDER Perimeter signal contacts (wider pads)
MC61, MC62 ADOM_MEDIUM_CONTACT Narrower radio GPIO1/GPIO0 contacts
MC54–MC57 pad not placed Silkscreen references exist in schematic but no footprint on PCB (reserved / spares)

Perimeter contact map (MC1..MC62)

Verified against the KiCad schematic and PCB netlist; matches /home/adom/project/rp2350b_rm2_pinmap.md (which is itself derived from this project). Reproduced here for self-contained reference.

MC Silk Net RP2350 pin Notes
MC1 22 GPIO22 / SCK0 22 SPI0 SCK, I²C1 SDA
MC2 21 GPIO21 / CS0 21 SPI0 CSn, I²C0 SCL
MC3 20 GPIO20 / CIPO0 20 SPI0 RX, I²C0 SDA
MC4 19 GPIO19 19 SPI0 TX, I²C1 SCL
MC5 18 GPIO18 18 SPI0 SCK, I²C1 SDA
MC6 17 GPIO17 17 SPI0 CSn, I²C0 SCL
MC7 16 GPIO16 16 SPI0 RX, I²C0 SDA
MC8 15 GPIO15 14
MC9 14 GPIO14 13
MC10 13 GPIO13 12
MC11 12 GPIO12 11
MC12 11 GPIO11 9
MC13 10 GPIO10 8
MC14 9 GPIO9 7
MC15 8 GPIO8 6
MC16 7 GPIO7 4
MC17 6 GPIO6 3
MC18 5 GPIO5 2 SPI0 CSn, I²C0 SCL
MC19 4 GPIO4 1 SPI0 RX, I²C0 SDA — firmware uses this pair
MC20 3 GPIO3 80
MC21 2 GPIO2 79
MC22 Rx1 GPIO1 78 UART0 RX (default)
MC23 Tx0 GPIO0 77 UART0 TX (default)
MC24 RST RUN / RST 35 Active-low reset (SW2)
MC25 BOOT BOOT Press-to-bootsel (SW1 → QSPI_SS pulled low)
MC26 USB+ USB_D+ via R7 27 Ω → pin 67 USB FS
MC27 USB− USB_D− via R8 27 Ω → pin 66 USB FS
MC28 SWD SWD_IO 34
MC29 SWD SWD_CLK 33
MC30 LDO EN LDO_EN — (to U100 pin 3) Pull high to enable 3.3 V LDO
MC31–MC38 4740 GPIO47..GPIO40 / ADC7..ADC0 58..49 All eight ADC channels exposed
MC39–MC48 3930 GPIO39..GPIO30 48..38
MC49 29 GPIO29 / RADIO_D 37 Shared: WL_DATA + HOST_WAKE + POCI-tied — see "Radio wiring"
MC50 28 GPIO28 / RADIO_CLK 36 WL_CLK
MC51 27 GPIO27 / RADIO_CS 28 WL_CS
MC52 26 GPIO26 / RADIO_ON 27 WL_REG_ON (also gates BT power)
MC53 IO 2 RADIO_GPIO2 — (U9 C3) CYW43 module GPIO2 — not wired to MCU
MC54–MC57 (pad not placed) Reserved
MC58 25 GPIO25 26
MC59 24 GPIO24 25
MC60 23 GPIO23 / COPI0 23
MC61 IO 1 RADIO_GPIO1 — (U9 C4) CYW43 module GPIO1 — not wired to MCU
MC62 IO 0 RADIO_GPIO0 / LED — (U9 B1) CYW43 module GPIO0 (drives WL LED on stock Pico-W firmware)

RP2350B die pins not routed to any MC: 5, 10, 15, 24, 29, 32, 41, 50, 51, 59, 60, 62, 64, 65, 68, 69, 76 (GND / +3V3 / +1V1 power), 30/31 (crystal), 61/63 (VREG), 66/67 (USB D−/D+ internal — reach MC26/MC27 through R7/R8/R3), 70–75 (QSPI flash/PSRAM bus to U3/U5).

Radio wiring (U9 — RM2 / CYW43439) ← most important new detail

The RM2 module uses the gSPI 3-wire protocol: one bidirectional data line, a clock, a chip-select, and a power-enable. Host-wake and module-response arrive back on the same data line.

RM2 pad Module function Net on board RP2350 pin
A1, A4, A7, B4, C1, C7 GND GND
A3 SCLK GPIO28/RADIO_CLK (net 74) GPIO28 (die pin 36)
A5 PICO (host→module data) GPIO29/RADIO_D (net 64) GPIO29 (die pin 37)
A6 POCI (module→host data) Net-(U9-POCI) (net 65) → R40 (470 Ω) → GPIO29/RADIO_D
B1 GPIO0 (module) RADIO_GPIO0/LED (net 72) → MC62 only
B2 ~CS GPIO27/RADIO_CS (net 70) GPIO27 (die pin 28)
B3 IRQ (host-wake) Net-(U9-IRQ) (net 66) → R41 (10 kΩ) → GPIO29/RADIO_D
B5 WLON (Wi-Fi enable) GPIO26/RADIO_ON (net 71) GPIO26 (die pin 27)
B6 BTON (BT enable) GPIO26/RADIO_ON (net 71) tied to WLON — same GPIO26
B7 VDDIO Net-(U9-VDDBAT) (net 63) +3.3 V (tied to VDDBAT)
C2 VDDBAT Net-(U9-VDDBAT) (net 63) +3.3 V (through L3 ferrite from the main rail)
C3 GPIO2 RADIO_GPIO2 (net 68) → MC53 only
C4 GPIO1 RADIO_GPIO1 (net 73) → MC61 only
A2, C5, C6 NC (unconnected)

The critical "single-GPIO radio" trick: R40 (470 Ω) ties the module's POCI back onto the same trace as PICO, and R41 (10 kΩ) weakly ties IRQ onto that same trace. The MCU drives GPIO29 when writing to the module, releases it (input) to read, and senses the IRQ as a level change on the same line. This is exactly the Pico-W convention and matches the CYW43 SDK driver's WL_DATA_OUT = WL_DATA_IN = WL_HOST_WAKE = <same pin> configuration.

Firmware CYW43 pin overrides (matches Caleb's working build):

add_compile_definitions(
    CYW43_DEFAULT_PIN_WL_REG_ON=26u
    CYW43_DEFAULT_PIN_WL_DATA_OUT=29u
    CYW43_DEFAULT_PIN_WL_DATA_IN=29u
    CYW43_DEFAULT_PIN_WL_HOST_WAKE=29u
    CYW43_DEFAULT_PIN_WL_CLOCK=28u
    CYW43_DEFAULT_PIN_WL_CS=27u
    CYW43_USES_VSYS_PIN=0
)

Power architecture

+5V (MC pad, USB VBUS or external)
 │
 ├─ L3 (470 Ω ferrite) ─ C9 4.7 µF ─→ +3V3 feed to U9 radio
 │
 └─ U100 AP2112K-3.3 (LDO, EN=LDO_EN pin) ─→ +3V3 rail
       │
       ├─ U1 VDDIO rails (pins 5, 10, 15, 24, 41, 50, 64, 68, 76)
       ├─ U3 W25Q128 flash VDD
       ├─ U5 APS6404 PSRAM VDD  *(DNP)*
       ├─ U9 VDDIO / VDDBAT (through L3)
       ├─ Pull-ups: QSPI_SS (R12), BOOT, RST, etc.
       └─ R6 1 k + D101 red (power LED)

+3V3 → U1 pin 69 (VREG_VIN) → internal buck →
       pin 63 VREG_LX ─ L1 3.3 µH ─ pin 61 VREG_AVDD → +1V1 core rail
       (C6, C7 4.7 µF on VREG_LX; C100 / C101 10 µF bulk)
  • +5V enters on one of the MC pads (not labeled in the BOM table above — check PCB silk).
  • LDO_EN (MC30) must be pulled high for the board to power up. Typical pattern: tie to +5V through R41 or similar pull-up on the carrier, or drive from an upstream host.
  • The RP2350 internal buck SMPS runs from +3V3, uses L1/C6/C7 on VREG_LX/VREG_AVDD, and produces the core +1V1 itself. No external +1V1 supply is required.
  • L3 ferrite bead isolates the radio's +3V3 from digital switching noise on the MCU's +3V3 — important for clean Wi-Fi TX.

QSPI bus (U1 → U3, optional U5)

Net U3 flash pin U5 PSRAM pin MCU QSPI function
QSPI_SCLK CLK SCLK Shared clock
QSPI_SD0 DI / IO0 SI / IO0 Shared data line 0
QSPI_SD1 DO / IO1 SO / IO1 Shared data line 1
QSPI_SD2 /WP / IO2 SIO2 Shared data line 2
QSPI_SD3 /HOLD / IO3 SIO3 Shared data line 3
FLASH_SS CS XIP flash chip select (primary)
FLASH2_SS CE# Second chip select — would drive the PSRAM if populated
QSPI_SS (via R12 10 kΩ + SW1 BOOT) Doubles as BOOTSEL strap at reset
  • PSRAM is DNP on production boards (user confirmed 2026-04-17). Firmware must not assume PSRAM is available. The RP2350 SDK PICO_USE_PSRAM option should stay off.
  • Flash is 16 MB (128 Mbit) W25Q128JV — significantly larger than the 4 MB on stock Pico 2 W, so XIP code / large firmware blobs (BHI360/BHI385 patches, look-up tables) fit without squeezing.

Delta vs existing project pin maps

Cross-checked against /home/adom/project/rp2350b_rm2_pinmap.md and /home/adom/project/MoleculePinMapping.md. Those files are accurate for MC1–MC62 contact numbering and silk labels, with one small caveat and several net-level details they don't cover:

In the existing docs:

  • Full MC → GPIO table ✓ (matches the schematic)
  • Radio-pin identification (GPIO26/27/28/29) ✓
  • Boot/reset/USB/SWD contacts ✓
  • Firmware board_config.h expectations ✓

Not in the existing docs, added here:

  1. R40 (470 Ω) + R41 (10 kΩ) bridge topology that makes the single-wire gSPI work — POCI and IRQ tied back onto the GPIO29/RADIO_D net. Explains why WL_DATA_IN == WL_DATA_OUT == WL_HOST_WAKE in Caleb's firmware and confirms HOST_WAKE does not need a separate GPIO.
  2. U9 B5 (WLON) and B6 (BTON) are both tied to GPIO26/RADIO_ON — one GPIO enables both Wi-Fi and Bluetooth rails. Firmware can't sequence them separately.
  3. U5 APS6404L QSPI PSRAM (8 MB) is footprinted but DNP. Existing docs don't mention PSRAM at all. Important because (a) the schematic has FLASH2_SS as a real net even though no chip is soldered, and (b) a future populated revision would use FLASH2_SS as the PSRAM chip-select — code should not assume the net is NC.
  4. U3 flash is W25Q128JV (16 MB) — the existing docs don't specify size. Matters for linker scripts and XIP layout.
  5. L3 470 Ω ferrite bead on the radio's +3V3 feed — firmware/EMI detail that isn't in the pin map but is essential for understanding any Wi-Fi TX behavior.
  6. L1 is labeled "3.3uF" in the BOM CSV but is physically an inductor (3.3 µH) for the RP2350 internal buck converter. A BOM typo — flagged here so nobody trusts it blindly.
  7. MC54–MC57 are reserved silk positions with no footprint placed — BOM confirms these are absent. Existing docs noted "pad not placed"; this file confirms it matches the CPL.
  8. RP2350B (80-pin) variant is confirmed — not the 60-pin RP2350A. All 48 GPIOs and 8 ADCs are routed out.
  9. Internal +1V1 rail is generated by the RP2350's own buck converter (L1 / VREG_LX / VREG_AVDD), not an external regulator. Firmware doesn't need to enable an external +1V1 supply.
  10. Silk pin Tx0 on MC23 and Rx1 on MC22 are the UART0 default pin pair, not just generic GPIO0/GPIO1 — handy for boot logging via stdio_uart.

Gotchas for firmware bring-up

  • LDO_EN must be high or nothing runs. When you first power the bare molecule on a breadboard, remember to tie MC30 to +5 V (or a host GPIO that does).
  • Do not enable PICO_USE_PSRAM. The PSRAM is DNP. Setting this will break the flash XIP at boot because the RP2350 boot ROM may try to probe FLASH2_SS.
  • Do not assume WL_DATA_IN is a separate GPIO when porting CYW43 code that was written for a module with a 4-wire SPI — this board shares data/in/out/host-wake on GPIO29.
  • GPIO26 gates both Wi-Fi and Bluetooth. Don't drop it while doing a Wi-Fi-only workflow expecting BT to stay up from a prior enable — it won't.
  • USB differential pair is through 27 Ω series resistors (R7, R8) routed from die pins 66/67 out to MC26/MC27. That's standard but worth noting if you're adding ESD / CM choke downstream.
  • 12 MHz crystal (Y1) matches the Pico SDK default; no custom PICO_XOSC_STARTUP_DELAY_MULTIPLIER needed.
  • 4-layer board. If you respin the carrier, route the radio ground return on an adjacent layer — the RM2's RF performance is sensitive to return-path integrity under L3.
  • The wiki page is a stub. If you want the rest of the team to find this information, the publish step is still outstanding — see "Publishing to the wiki" below.

Publishing to the wiki (TODO)

The page molecules/molecule-rp2350b-rm2-v1-106000 exists but has no body content, no photo annotations, no pin table, no BOM. The content of this README could be published there with:

adom-wiki page edit molecules/molecule-rp2350b-rm2-v1-106000 \
    --field content \
    --body-md /home/adom/project/bosch-sensortec-demo/hardware/molecule_rp2350b_rm2_v1/README.md

Before doing that, confirm discovery triggers with the project lead (current stub has none).