Pimoroni Badger 2040

Pimoroni Badger 2040.

  • Raspberry Pi RP2040
  • E Ink display, 2.9 inch, black and white, 296 x 128 pixels
  • one white LED
  • Buttons: 5 buttons on front (a, b , c, up , down), 2 buttons (reset, boot) on back
  • 2MB of QSPI flash supporting XiP
  • USB-C connector for power and programming
  • JST-PH connector for attaching a battery (input range 2.7V - 6V) - no charge circuit on board
  • High-precision voltage reference for battery level monitoring
  • Qw/ST (Qwiic/STEMMA QT) connector

back to microcontrollers page.

Links

Pimoroni Badger 2040, Badger 2040 W, Rustne Kretser, Adventures into Badger2040 hacking, Programing in Rust the XIAO RP2040 board, xiao-rp2040-playground,

Github Pimoroni badger2040, fatfingers23 rusty-badger,

crates.io pimoroni_badger2040,

rp2040-rustboot, rmk, github HaoboGu/rmk, rp2040-async-i2c, pico-dvi-rs, PicoDVI, rp-embassy-playground,

History

2025-06-09: rust - elf2uf2-rs works

tingo@kg-core2:~/personal/projects/2025/rust/embedded/rp2040/badger_2040/badger2040-test $ more .cargo/config.toml
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# Choose a default "cargo run" tool (see README for more info)
# - `probe-rs` provides flashing and defmt via a hardware debugger, and stack unwind on panic
# - elf2uf2-rs loads firmware over USB when the rp2040 is in boot mode
# runner = "probe-rs run --chip RP2040 --protocol swd"
runner = "elf2uf2-rs -d"
#runner = "probe-rs run --chip RP2040 --protocol swd"
linker = "flip-link"
rustflags = [
  "-C", "link-arg=--nmagic",
  "-C", "link-arg=-Tlink.x",
  "-C", "link-arg=-Tdefmt.x",

  # Code-size optimizations.
  #   trap unreachable can save a lot of space, but requires nightly compiler.
  #   uncomment the next line if you wish to enable it
  # "-Z", "trap-unreachable=no",
  "-C", "no-vectorize-loops",
]

[build]
target = "thumbv6m-none-eabi"

[env]
DEFMT_LOG = "debug"

testing

tingo@kg-core2:~/personal/projects/2025/rust/embedded/rp2040/badger_2040/badger2040-test $ cargo run --example badger_blinky
    Finished `dev` profile [optimized + debuginfo] target(s) in 0.03s
     Running `elf2uf2-rs -d target/thumbv6m-none-eabi/debug/examples/badger_blinky`
Error: "Unable to find mounted pico"
tingo@kg-core2:~/personal/projects/2025/rust/embedded/rp2040/badger_2040/badger2040-test $ cargo run --example badger_blinky
    Finished `dev` profile [optimized + debuginfo] target(s) in 0.02s
     Running `elf2uf2-rs -d target/thumbv6m-none-eabi/debug/examples/badger_blinky`
Found pico uf2 disk /media/RPI_RP2_E0C9125B0D9B_s1
Transfering program to pico
8.50 KB / 8.50 KB [===================================================================================================================] 100.00 % 77.00 MB/s 

but it is cumbersome, because of all steps: 1) boot RP2040 in bootloader mode (hold down boot, press reset) 2) mount the disk drive 3) cargo run ... 4) unmount the diskdrive

2025-06-09: rust - install newer probe-rs-tools

tingo@kg-core2:~ $ cargo install probe-rs-tools
    Updating crates.io index
  Downloaded probe-rs-tools v0.29.0
  Downloaded 1 crate (264.2KiB) in 1.20s
error: binary `cargo-embed` already exists in destination as part of `probe-rs v0.22.0`
binary `cargo-flash` already exists in destination as part of `probe-rs v0.22.0`
binary `probe-rs` already exists in destination as part of `probe-rs v0.22.0`
Add --force to overwrite

try with force

tingo@kg-core2:~ $ cargo install probe-rs-tools --force
    Updating crates.io index
  Installing probe-rs-tools v0.29.0
    Updating crates.io index
     Locking 438 packages to latest compatible versions
      Adding cargo_metadata v0.19.2 (available: v0.20.0)
      Adding goblin v0.9.3 (available: v0.10.0)
      Adding rustyline v15.0.0 (available: v16.0.0)
      Adding scroll v0.12.0 (available: v0.13.0)
      Adding zip v2.4.2 (available: v4.0.0)
[..]
   Compiling nusb v0.1.14
error[E0412]: cannot find type `DeviceId` in module `crate::platform`
  --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/enumeration.rs:11:49
   |
11 | pub struct DeviceId(pub(crate) crate::platform::DeviceId);
   |                                                 ^^^^^^^^ not found in `crate::platform`
   |
help: consider importing this struct through its public re-export
   |
7  + use crate::DeviceId;
   |
help: if you import `DeviceId`, refer to it directly
   |
11 - pub struct DeviceId(pub(crate) crate::platform::DeviceId);
11 + pub struct DeviceId(pub(crate) DeviceId);
   |

error[E0412]: cannot find type `Device` in module `crate::platform`
  --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/device.rs:40:35
   |
40 |     backend: Arc<crate::platform::Device>,
   |                                   ^^^^^^ not found in `crate::platform`
   |
help: consider importing this struct through its public re-export
   |
1  + use crate::Device;
   |
help: if you import `Device`, refer to it directly
   |
40 -     backend: Arc<crate::platform::Device>,
40 +     backend: Arc<Device>,
   |

error[E0433]: failed to resolve: could not find `Device` in `platform`
  --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/device.rs:45:33
   |
45 |         let backend = platform::Device::from_device_info(d)?;
   |                                 ^^^^^^ could not find `Device` in `platform`
   |
help: consider importing this struct through its public re-export
   |
1  + use crate::Device;
   |
help: if you import `Device`, refer to it directly
   |
45 -         let backend = platform::Device::from_device_info(d)?;
45 +         let backend = Device::from_device_info(d)?;
   |

error[E0412]: cannot find type `Interface` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/device.rs:357:28
    |
357 |     backend: Arc<platform::Interface>,
    |                            ^^^^^^^^^ not found in `platform`
    |
help: consider importing this struct through its public re-export
    |
1   + use crate::Interface;
    |
help: if you import `Interface`, refer to it directly
    |
357 -     backend: Arc<platform::Interface>,
357 +     backend: Arc<Interface>,
    |

error[E0412]: cannot find type `Interface` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/transfer/queue.rs:112:30
    |
112 |     interface: Arc<platform::Interface>,
    |                              ^^^^^^^^^ not found in `platform`
    |
help: consider importing this struct through its public re-export
    |
1   + use crate::Interface;
    |
help: if you import `Interface`, refer to it directly
    |
112 -     interface: Arc<platform::Interface>,
112 +     interface: Arc<Interface>,
    |

error[E0412]: cannot find type `TransferData` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/transfer/queue.rs:117:48
    |
117 |     pending: VecDeque<TransferHandle<platform::TransferData>>,
    |                                                ^^^^^^^^^^^^ not found in `platform`

error[E0412]: cannot find type `TransferData` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/transfer/queue.rs:120:45
    |
120 |     cached: Option<TransferHandle<platform::TransferData>>,
    |                                             ^^^^^^^^^^^^ not found in `platform`

error[E0412]: cannot find type `TransferData` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/transfer/queue.rs:128:15
    |
128 |     platform::TransferData: PlatformSubmit<R>,
    |               ^^^^^^^^^^^^ not found in `platform`

error[E0412]: cannot find type `Interface` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/transfer/queue.rs:131:34
    |
131 |         interface: Arc<platform::Interface>,
    |                                  ^^^^^^^^^ not found in `platform`
    |
help: consider importing this struct through its public re-export
    |
1   + use crate::Interface;
    |
help: if you import `Interface`, refer to it directly
    |
131 -         interface: Arc<platform::Interface>,
131 +         interface: Arc<Interface>,
    |

error[E0412]: cannot find type `TransferData` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/transfer/mod.rs:155:40
    |
155 |     transfer: TransferHandle<platform::TransferData>,
    |                                        ^^^^^^^^^^^^ not found in `platform`

error[E0412]: cannot find type `TransferData` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/transfer/mod.rs:160:58
    |
160 |     pub(crate) fn new(transfer: TransferHandle<platform::TransferData>) -> TransferFuture<D> {
    |                                                          ^^^^^^^^^^^^ not found in `platform`

error[E0412]: cannot find type `TransferData` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/transfer/mod.rs:170:15
    |
170 |     platform::TransferData: PlatformSubmit<D>,
    |               ^^^^^^^^^^^^ not found in `platform`

error[E0412]: cannot find type `HotplugWatch` in module `crate::platform`
  --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/hotplug.rs:14:53
   |
14 | pub struct HotplugWatch(pub(crate) crate::platform::HotplugWatch);
   |                                                     ^^^^^^^^^^^^ not found in `crate::platform`

error[E0425]: cannot find function `list_devices` in module `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/lib.rs:149:15
    |
149 |     platform::list_devices()
    |               ^^^^^^^^^^^^ not found in `platform`

error[E0433]: failed to resolve: could not find `HotplugWatch` in `platform`
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/lib.rs:188:40
    |
188 |     Ok(hotplug::HotplugWatch(platform::HotplugWatch::new()?))
    |                                        ^^^^^^^^^^^^ could not find `HotplugWatch` in `platform`
    |
help: consider importing this struct
    |
117 + use crate::hotplug::HotplugWatch;
    |
help: if you import `HotplugWatch`, refer to it directly
    |
188 -     Ok(hotplug::HotplugWatch(platform::HotplugWatch::new()?))
188 +     Ok(hotplug::HotplugWatch(HotplugWatch::new()?))
    |

error[E0308]: mismatched types
  --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/enumeration.rs:71:25
   |
71 |     pub fn id(&self) -> DeviceId {
   |            --           ^^^^^^^^ expected `DeviceId`, found `()`
   |            |
   |            implicitly returns `()` as its body has no tail or `return` expression

error[E0599]: no method named `control_in_blocking` found for reference `&Device` in the current scope
   --> /home/tingo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nusb-0.1.14/src/device.rs:164:28
    |
164 |             let len = self.control_in_blocking(
    |                       -----^^^^^^^^^^^^^^^^^^^ method not found in `&Device`

   Compiling num-bigint v0.4.6
Some errors have detailed explanations: E0308, E0412, E0425, E0433, E0599.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `nusb` (lib) due to 17 previous errors
warning: build failed, waiting for other jobs to finish...
error: failed to compile `probe-rs-tools v0.29.0`, intermediate artifacts can be found at `/tmp/cargo-installQqjfOg`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.

ok, so that didn't work.

2025-06-09: set up an initial rust project

tingo@kg-core2:~/personal/projects/2025/rust/embedded/rp2040/badger_2040 $ cargo generate --git https://github.com/rp-rs/rp2040-project-template
🤷   Project Name: badger2040_test
⚠️   Renaming project called `badger2040_test` to `badger2040-test`...
🔧   Destination: /zs/tingo/personal/projects/2025/rust/embedded/rp2040/badger_2040/badger2040-test ...
🔧   project-name: badger2040-test ...
🔧   Generating template ...
✔ 🤷   Which flashing method do you intend to use? · probe-rs
🔧   Moving generated files into: `/zs/tingo/personal/projects/2025/rust/embedded/rp2040/badger_2040/badger2040-test`...
🔧   Initializing a fresh Git repository
✨   Done! New project created /zs/tingo/personal/projects/2025/rust/embedded/rp2040/badger_2040/badger2040-test

2025-06-09: I created this page.

2025-06-08: I paid VAT NOK 89.- and handling fee NOK 46.- a total of NOK 135.-

2025-06-05: the package arrived, straight into my mailbox. Tracking from Posten indicated that there is VAT NOK 89.- and handling fee NOK 46.- a total of NOK 135.- to pay.

2025-05-28: the package shipped.

2025-05-27: Both Badger 2040 W and Badger 2040 has been out of stock with Pimoroni for a while now. I saw that Elektor had one Badger 2040 in their sale, so I ordered it. USD 27.54 plus US 20.- in shipping, a total of USD 47.65, which is about NOK 508.97 with PayPal rates.