On hardware
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.
| Binary | Board | Panel | Driver |
|---|---|---|---|
badger2040 | Badger 2040 | 296x128 monochrome e-ink | UC8151 over SPI |
tufty2040 | Tufty 2040 | 320x240 colour IPS LCD | ST7789v 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-rp → pio → pio-proc → proc-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 runand a debugger: a Raspberry Pi Debug Probe or a second Pico running picoprobe, wired to the SWD pads. -
The target, which
rust-toolchain.tomlalready 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.md | everything 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.md | your first screen on a board: a board is data, the palette trap, and the panel driver seam — compiled by docs-test/ |
| docs/contributing.md | the three workspaces, the target, the gate, the five review steps, and how a commit is written |
| docs-test/README.md | the 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.
Edit this page on GitHubIt lives in xpui-rp2040; a correction goes there.