Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Hardware

What RS-Key runs on, and the build knobs you need for a board other than the reference one. The full knob reference is in build.md. This page is the short version.

Supported boards

Waveshare RP2350-One — a blue USB-A stick board Waveshare RP2350-Zero — a small blue USB-C stick board TenStar RP2350-USB — a black USB-A stick board Waveshare RP2350-Touch-LCD-2.8 — a board with a 2.8-inch touch screen
RP2350-One
reference · USB-A
WS2812 on GPIO16
RP2350-Zero
mini stick · USB-C
TenStar RP2350-USB
USB-A stick
WS2812 on GP22
RP2350-Touch-LCD-2.8
trusted display · 2.8″ LCD

Board photos: Waveshare (RP2350-One / Zero / Touch-LCD-2.8).

Any RP2350 board with a USB connector should work. Development and on-device testing happen on the Waveshare RP2350-One, where the WS2812 status LED on GPIO16 works out of the box. Boards without an addressable LED run fine. The indicator is optional and the firmware just runs dark. A board whose LED sits behind a power gate — the Seeed XIAO RP2350 powers its WS2812 through GP23 — lights up once that enable pin is set with LED_POWER_PIN (below).

The RP2350’s dual Cortex-M33, 520 KB SRAM, hardware TRNG, OTP fuses, and glitch detectors do the work. There is no secure element and no debugger requirement: the firmware flashes over USB BOOTSEL, so a bare board and a USB cable are enough.

Defaults and the knobs to change them

The default build targets a 4 MB flash chip with the LED on GPIO16, uses BOOTSEL for user presence, and assumes a standard 12 MHz crystal. For a different board, three compile-time knobs usually cover it:

KnobDefaultWhen to change it
FLASH_SIZE4MA board with a different QSPI flash chip (e.g. 8M). build.rs regenerates memory.x from it. Must be ≤ 16 MB and leave ≥ 1 MB for code after the KV store; a 2 MB board also needs a smaller KVMAIN (below).
KVMAIN1408KA 2 MB board (Seeed XIAO RP2350, Waveshare RP2350-Zero-CM): the default 1408K KV main partition leaves too little for the ~900K image. Shrink it — FLASH_SIZE=2M KVMAIN=896K — to fit. A fully provisioned key uses only a few hundred KB. See build.md.
LED_PIN16A board that uses GPIO16 for something else, or wires its addressable LED elsewhere (RP2350A: GPIO 0..=29).
LED_POWER_PINnoneA board whose LED sits behind a power gate that must be driven high to light it (e.g. the Seeed XIAO RP2350’s WS2812 on GP23). Set the enable GPIO; it must differ from LED_PIN and any GPIO PRESENCE_PIN.
USR_LED_PINnoneA board with a nuisance onboard user LED that lights by default (the Seeed XIAO RP2350’s active-low USR LED on GP25). Set the GPIO to park it off at boot; flip USR_LED_ACTIVE_HIGH=1 for an active-high LED. Must differ from LED_PIN, LED_POWER_PIN, and any GPIO PRESENCE_PIN.
PRESENCE_PINbootselA board with a dedicated user-presence button on a GPIO. Set a pin number (0..=29); active-low with a pull-up by default (e.g. 0 for GPIO0-to-GND).
PRESENCE_ACTIVE_HIGH0A presence button/sensor that reads high when pressed (a capacitive touch sensor, or a button to VCC). 1 flips the GPIO to pull-down + active-high. Only with a GPIO PRESENCE_PIN.
LED_KINDws2812ws2812 (addressable RGB, default), gpio (plain on/off), pimoroni (3-pin PWM RGB), or none (no indicator). See build.md.
LED_ORDERrgbA ws2812 board whose red and green come out swapped (blue fine): set grb (the WS2812B standard). The Waveshare RP2350-One is rgb; most other parts are grb.
MAX_LEDS8A board with more than 8 daisy-chained addressable LEDs. The buffer ceiling; the actual connected count is set at runtime (guides/led.md).
# example: an 8 MB board with a plain LED on GPIO25
env FLASH_SIZE=8M LED_KIND=gpio LED_PIN=25 cargo build --release -p firmware

# example: a 16 MB TenStar RP2350-USB — WS2812 on GP22, standard GRB order
env FLASH_SIZE=16M LED_PIN=22 LED_ORDER=grb cargo build --release -p firmware

# example: a Seeed XIAO RP2350 — WS2812 on GP22, GRB, power-gated by GP23 (driven high),
# its active-low USR LED on GP25 parked off, and its 2 MB flash (smaller KVMAIN)
env FLASH_SIZE=2M KVMAIN=896K LED_PIN=22 LED_ORDER=grb LED_POWER_PIN=23 USR_LED_PIN=25 cargo build --release -p firmware

# example: WS2812 on GP22 and a button-to-GND on GP0 (active-low)
env LED_PIN=22 PRESENCE_PIN=0 cargo build --release -p firmware

# example: an active-high capacitive touch sensor on GP0
env PRESENCE_PIN=0 PRESENCE_ACTIVE_HIGH=1 cargo build --release -p firmware

The four LED knobs (LED_PIN / LED_KIND / LED_ORDER / MAX_LEDS) set only the boot defaults. A non-none build compiles all three backends, so the pin, driver, wire order, and buffer ceiling are also changeable at runtime (no reflash) with rsk hw or PicoForge, which write them to the device’s phy record (guides/led.md). The build knobs still matter for picking a lean none build and for the out-of-the-box default.

Most RP2350A boards work with at most a one-line change. Everything else (USB descriptors, applets, flash layout) is board-independent.

Enclosures

A bare board works fine, but a printed case makes it pocketable. Three community designs fit the boards above:

The two Printables designs are licensed CC BY-SA 4.0: print, sell, and remix them freely, as long as you credit the authors and keep any derivative under the same license. Check the MakerWorld design’s own license on its page before reusing it. All are third-party designs, linked for convenience, not part of this project.

What the hardware does not give you

The OTP fuses and secure boot (production.md) are real hardening, but the RP2350 is a general-purpose microcontroller, not a certified secure element. Physical attacks are out of scope: decapping, microprobing, fault injection beyond the on-chip glitch detectors, power/EM side channels. See the threat model and limitations.