Repository navigation
Feather USB Host
How to bring up the firmware on a Feather RP2040 instead of the custom OpenRB
board. The Feather is the FEATHER build target — the original bring-up target the
custom board was later derived from — so it's the easiest way to try openrb-pico with
off-the-shelf hardware and no SWD probe.
TL;DR: grab
openrb-pico_FEATHER.uf2from the latest release, hold BOOTSEL while plugging the Feather into your PC, drag the.uf2onto theRPI-RP2drive, plug the Feather's USB-C into the console, authenticate with a real Xbox controller until the board LED lights, then connect your drums (USB-MIDI into the host port, or serial/DIN MIDI to GPIO1).
| Board | Adafruit Feather RP2040 with USB Type A Host (product 5723) — recommended. Its USB-A host port + 5 V load switch are already wired to the exact GPIOs the firmware expects (see §3). A plain Feather RP2040 works too but you must hand-wire the host port yourself (§3, caveat). |
| Instrument | A rhythm-game drum kit, read over USB MIDI (plugged into the host port) or serial/DIN MIDI (wired to the UART). |
| Cables | USB-C (Feather ↔ console, the device side) + a USB-MIDI cable or a MIDI-DIN front end on the host/UART side. |
| Optional | A USB-serial adapter on the debug UART (§6) if you want boot logs — only useful with a logging build. |
The RP2040's native USB is the device side (what the console sees as the Xbox pro-drum controller). A second, bit-banged USB host is synthesized in PIO (Pico-PIO-USB) on GPIO16/17 — that's where a USB-MIDI instrument plugs in; a serial/DIN-MIDI instrument instead wires to the UART (§5). The two USB roles are independent.
Option A — download (fastest). From the
releases page, download
openrb-pico_FEATHER.uf2. This is the release build: logging is compiled out and
the low-latency timing is baked in.
Option B — build from source. Everything runs in Docker (see
BUILDING.md):
scripts/build.sh # builds BOTH board targets into build/
# release variant (logging compiled out) into build-release/:
cmake --preset release && cmake --build build-release -j"$(nproc)"Board selection is a compile-time define (ORB_BOARD_ID), not a runtime switch — every
configure builds both targets, so you just pick the right artifact:
-
build-release/openrb-pico_FEATHER.uf2— release, no logging (ship this). -
build/openrb-pico_FEATHER.uf2— default build, UART logging on (use this for bring-up so you can watch the boot; see §6).
Defined in modules/board/pins_rp2040_usbh.h;
actuation in modules/board/actuators.cpp.
| Function | GPIO | Notes |
|---|---|---|
| USB host D+ | GPIO16 | PIO-USB. pin_usb_host_dp
|
| USB host D- | GPIO17 | PIO-USB requires D- = D+ + 1 |
| USB host 5 V enable | GPIO18 | firmware-driven VBUS/5 V switch (pin_5v_en) — Feather only |
| Serial-MIDI RX (from kit's MIDI OUT) | GPIO1 |
uart0, 31250 baud
|
| Serial-MIDI TX | GPIO0 | uart0 |
| Debug UART TX | GPIO24 |
uart1, 115200 baud |
| Debug UART RX | GPIO25 | uart1 |
| Status LED | GPIO13 | pin_led |
On the Feather RP2040 USB Host variant, GPIO16/17/18 already go to the on-board USB-A host receptacle and its 5 V load switch — nothing to wire for USB.
Hand-wiring a plain Feather RP2040 (advanced, undocumented): solder a USB-A receptacle with D+ → GPIO16, D- → GPIO17, VBUS → 5 V (gated by GPIO18), GND → GND. The repo does not document pull-up/series-resistor values for a hand-wired host port — the tested topology is the USB-Host Feather variant. Proceed at your own risk.
A plain Feather has no SWD header, so use the RP2040 UF2 bootloader:
- Hold the BOOTSEL button while plugging the Feather's USB-C into your PC.
- It mounts as a mass-storage drive named
RPI-RP2. - Drag
openrb-pico_FEATHER.uf2onto that drive. - The Feather reboots automatically into the firmware.
The
scripts/flash.shhelper flashes over SWD and defaults toCUSTOM_REV_0_1; it's only relevant if you've wired a CMSIS-DAP probe. For a Feather, UF2 drag-drop above is the path.
Xbox authentication (needed each power-up). The adapter passes Xbox's security handshake by borrowing a real controller's credentials, so first:
- Plug an official Xbox One / Series X|S controller into the USB host port.
- Connect the Feather's USB-C to the console.
- Wait for the board LED to light up — that means authentication succeeded. You can now unplug the controller.
Then get your instrument in. The Feather has a single USB host port, so pick one:
-
Serial-MIDI hat (FeatherWing). Stack a MIDI FeatherWing and feed your kit's MIDI into
it — the firmware reads serial MIDI on
uart0(RX = GPIO1, 31250 baud —modules/service/midi.cpp). This leaves the USB port free for the auth controller. - USB hub on the host port. Plug a hub in and connect the auth controller and your USB-MIDI kit (and anything else, like a USB log stick) together.
- Swap on the single port. After the LED lights, unplug the auth controller and plug your USB-MIDI kit straight into the port.
Either way, the Feather's USB-C stays connected to the console and presents as the pro-drums controller.
- The LED on GPIO13 lights when Xbox authentication completes (§5) — that's the signal the adapter is ready, and on a single-port setup that it's safe to swap the auth controller for your drums.
- Release build: logging is compiled out, so the debug UART is intentionally silent — a quiet UART is expected and is not a failure signal.
-
Want boot logs? Flash the default (non-release) build
(
build/openrb-pico_FEATHER.uf2) and attach a USB-serial adapter to the debug UART (GPIO24 TX / GPIO25 RX, 115200 baud). A healthy boot ends with the Xbox One handshake (CMD_POWER_MODE,CMD_LED_MODE,CMD_AUTHENTICATE) — seeBUILDING.md.
The CPU runs at 120 MHz on both boards
(modules/app/main.cpp — set_sys_clock_khz(120000, …));
there's no Feather-specific clock change.
| FEATHER | CUSTOM_REV_0_1 | |
|---|---|---|
| GPIO18 | firmware-driven 5 V enable (set_usb_host() toggles it) |
CH334R hub RESET# (reset_usb_hub()) — not a 5 V enable |
| Downstream USB power | firmware can cut/restore VBUS via GPIO18 | VBUS is hard-wired +5 V (can't be gated in firmware) |
| USB hub | optional; controller can be direct | CH334R hub is in the signal path (hardwired) |
| LED | GPIO13 | GPIO23 |
This is why the custom board's warm-reset / hub-wedge recovery machinery (a whole class of "power-cycle the hub to un-wedge it" behaviour) doesn't apply to a Feather: the Feather can just toggle GPIO18 to power-cycle its downstream port, and with the controller plugged in directly there's no CH334R to accumulate bad state. Background on the hub/clock/PIO-USB choices lives in the Design history.
-
RPI-RP2drive never appears — you didn't catch BOOTSEL; unplug, hold BOOTSEL before plugging in, keep holding until it mounts. - LED never lights (authentication didn't complete) — make sure a genuine Xbox One / Series X|S controller is in the host port (GPIO16/17, not the native USB-C) during auth, and that the Feather's USB-C is connected to the console; power-cycle and retry. Third-party controllers may not authenticate.
- No drum hits register — first confirm the LED lit (auth done). For a serial kit, check MIDI OUT → GPIO1 (RX) and GND and that it sends standard 31250-baud MIDI. Flash the logging build (§6) to watch the parser.
-
Timing feels off / notes drop or double — the release build ships aggressive
low-latency values (
trigger_hold15 ms,on_delay5 ms inmodules/service/adapter.h); raise them and rebuild if your setup needs more margin.
-
BUILDING.md— build / flash / debug workflow (Docker). -
modules/board/pins_rp2040_usbh.h— the Feather pin map. -
modules/board/actuators.cpp— the GPIO18 5 V-enable vs hub-reset split. - Design history — PIO-USB / clock / hub rationale.
- Adafruit Feather RP2040 USB Host (5723).
Getting started
Features
Background
Repo