On hardware

On this page

xpui-rp2040

Two firmware binaries that flash the gallery to a Pimoroni board: the same screens the simulator runs, the same crate, and no device-specific code in them at all. What differs between the two is a Board, a Palette, and which pin is wired to what; the frame loop, the button handling and the heap are shared.

BinaryBoardPanelDriver
badger2040Badger 2040296x128 monochrome e-inkUC8151 over SPI
tufty2040Tufty 2040320x240 colour IPS LCDST7789v over an 8-bit parallel bus

Using it

For a firmware, using it is building it and flashing it. Both binaries:

cargo build --release --bin badger2040
cargo build --release --bin tufty2040

No --target: .cargo/config.toml sets thumbv6m-none-eabi for every command run at this repository's root or below, which is every command here. Naming it as well changes nothing.

The ELF lands in target/thumbv6m-none-eabi/release/. This crate is its own workspace, so it has a target/ of its own — see its own workspace.

Flash over USB, no probe. Install the tool first — it is a compile, and the board should not be sitting in bootloader mode while it runs:

cargo install elf2uf2-rs

Then hold BOOTSEL, plug the board in, wait for the RPI-RP2 drive, and from the repository root:

elf2uf2-rs -d target/thumbv6m-none-eabi/release/badger2040

-d converts and copies in one step; the board reboots into the firmware by itself. Without -d you get a .uf2 beside the ELF to drag across yourself.

Flash with a probe. From this directory:

cargo install probe-rs-tools
cargo run --release --bin badger2040

.cargo/config.toml points the runner at probe-rs run --chip RP2040 --protocol swd. This crate's release profile keeps the symbol table — see the note on it in Cargo.toml — so a probe session shows names, and the RTT log arrives without any extra flag.

The one warning you will see

warning: the following packages contain code that will be rejected by a future
version of Rust: proc-macro-error2 v2.0.1

Not ours, and not fixable here. It arrives four levels down — embassy-rppiopio-procproc-macro-error2 — where that crate re-exports proc_macro in a way rust-lang/rust#127909 is phasing out. 2.0.1 is the newest published version and still has it, so there is nothing to upgrade into.

It is a cargo future-incompatibility report about a dependency's own source, not a warning about this workspace, and it fails no gate. It is also a build-time proc-macro running on your laptop: nothing it affects is compiled into what the board runs. It goes away when proc-macro-error2 publishes a fix or embassy-rp moves off pio-proc; the only way to force it sooner is a [patch] onto a fork of somebody else's crate, which is a worse thing to own than a warning.

Requirements

  • One of the two boards. No extra hardware to flash over USB — both appear as a mass-storage device when you hold BOOTSEL while plugging them in.

  • Optional, for cargo run and a debugger: a Raspberry Pi Debug Probe or a second Pico running picoprobe, wired to the SWD pads.

  • The target, which rust-toolchain.toml already lists:

    rustup target add thumbv6m-none-eabi   # only if it is somehow missing

Checking it

./build-and-test.sh          # format, the board's lint, and the prose
./build-and-test.sh all      # the above, plus linking both firmware images

The checks are in xtask/ — this repository's own list, in Rust, holding nothing it does not run — and one command reaches all three of this repository's workspaces. How a change is reviewed is in docs/contributing.md.

Where next

docs/hardware.mdeverything past a first flash: what each key does, why this is its own workspace, where the memory goes, the pins, the release profile, one loop for both boards, and what running it proved
docs/tutorial.mdyour first screen on a board: a board is data, the palette trap, and the panel driver seam — compiled by docs-test/
docs/contributing.mdthe three workspaces, the target, the gate, the five review steps, and how a commit is written
docs-test/README.mdthe crate with no code that compiles the tutorial, and why it needs the host triple named

Where it sits

Every arrow is a dependency in a Cargo.toml, and they all point inward toward xpui, which depends on nothing at all. That is the rule the organisation is arranged around: a backend can be written without the framework knowing it exists, and a firmware reaches whatever it needs directly rather than through whoever happens to sit above it.

xpuithe frameworkxpui-chromecomponentsxpui-boardsseven devicesxpui-backendstwo backendsxpui-simulatora windowxpui-gallerythe appxpui-rp2040firmwarexpui-esp32firmwarexpui-cppa C++ hostxpui-devthe umbrella

Edit this page on GitHubIt lives in xpui-rp2040; a correction goes there.