Initial import: Rust BLE-MIDI keypad for Pico W

Port of the C/BTstack BLE-MIDI keypad firmware to Rust (embassy + cyw43 +
trouble). 16-pad RGB keypad (APA102 SPI + I2C button expander), BLE-MIDI 1.0
GATT server (full codec: sysex, running-status, real-time), octave display
on BOOTSEL, onboard LED heartbeat, USB serial logging.

- src/keypad.rs      Pimoroni RGB Keypad driver
- src/midi_keypad.rs pad->Note On/Off + LED response state machine
- src/codec.rs       BLE-MIDI 1.0 codec (port of rppicomidi, MIT)
- src/main.rs        cyw43 BT bring-up + trouble GATT + MIDI pump
- src/octave.rs      octave digit display on BOOTSEL

GPL-3.0-or-later; codec.rs retains its MIT (rppicomidi) attribution.
This commit is contained in:
2026-08-21 08:44:19 +02:00
commit d2bebc9e7b
18 changed files with 4330 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
[package]
name = "rgb-keypad"
version = "0.1.0"
edition = "2021"
resolver = "2"
[dependencies]
embassy-executor = { version = "0.10", default-features = false, features = ["platform-cortex-m", "executor-thread", "defmt", "executor-interrupt"] }
embassy-time = { version = "0.5", default-features = false, features = ["defmt", "defmt-timestamp-uptime"] }
embassy-rp = { version = "0.10", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp2040"] }
embassy-sync = { version = "0.8", features = ["defmt"] }
embassy-futures = "0.1.2"
embassy-usb = { version = "0.6", default-features = false, features = ["defmt"] }
embassy-usb-logger = { version = "0.6", default-features = false }
log = "0.4"
# BLE: cyw43 (CYW43439 BT controller on Pico W) + trouble (BLE host / GATT).
# trouble-host 0.8.0 is unreleased on crates.io, so we pull it from git; it must
# match the bt-hci version used by cyw43, hence the embassy/cyw43 git patch
# below pins everything to a known-compatible revision (the same one the
# upstream rp-pico-w example uses).
trouble-host = { git = "https://github.com/embassy-rs/trouble", rev = "4eea72088fdbb91326a3ac95160b3154fdff802a", features = ["derive", "gatt", "defmt", "default-packet-pool-mtu-128"] }
cyw43 = { version = "0.7", features = ["defmt", "firmware-logs", "bluetooth"] }
cyw43-pio = { version = "0.10", features = ["defmt"] }
defmt = "1.0"
defmt-rtt = "1.0"
panic-probe = { version = "1.0", features = ["print-defmt"] }
cortex-m = { version = "0.7.6" }
cortex-m-rt = "0.7.0"
static_cell = "2"
portable-atomic = { version = "1.5", features = ["critical-section"] }
heapless = "0.8"
embedded-hal-async = "1.0"
[profile.release]
debug = 2
opt-level = "s"
# Pin the embassy + cyw43 crates to the same git revision the upstream
# rp-pico-w Bluetooth example validates, so cyw43's bt-hci and trouble's
# bt-hci unify on one version (released crates pull incompatible bt-hci majors).
[patch.crates-io]
cyw43 = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }
cyw43-pio = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }
embassy-rp = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }
embassy-sync = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }
embassy-executor = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }
embassy-time = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }
embassy-usb = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }
embassy-usb-driver = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }
embassy-usb-logger = { git = "https://github.com/embassy-rs/embassy.git", rev = "3cd51e6d8eb6aff8b0d64d9e56a75a538bcfc65a" }