From 30f8cda48ed507d4d689de41f7140a70f7a2ba73 Mon Sep 17 00:00:00 2001 From: Nick Mello Date: Sat, 18 Jul 2026 20:32:58 -0500 Subject: [PATCH] keyboard: Update reporting logic Updates the reporting logic to wait for any key press or depress before reading all keys and sending an update of all of the keys Signed-off-by: Nicholas Mello --- Cargo.lock | 145 ++++++++++++++++++++++++++++++++++++++++++------ Cargo.toml | 3 + src/keyboard.rs | 53 ++++++------------ src/main.rs | 12 ++++ src/usb.rs | 10 ++++ 5 files changed, 171 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd7b8c2..4ed43c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,7 +36,10 @@ dependencies = [ "embassy-sync", "embassy-time", "embassy-usb", + "embedded-alloc", + "futures-util", "panic-probe", + "portable-atomic", "usbd-hid", ] @@ -76,6 +79,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "bit-set" version = "0.8.0" @@ -173,6 +182,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "const-default" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" + [[package]] name = "cordyceps" version = "0.3.4" @@ -212,7 +227,7 @@ checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -276,7 +291,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.118", ] [[package]] @@ -287,7 +302,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -324,7 +339,7 @@ dependencies = [ "defmt-parser", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -411,7 +426,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -587,6 +602,18 @@ dependencies = [ "embedded-io-async 0.7.0", ] +[[package]] +name = "embedded-alloc" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db634e07f552215f7a3572dc0a4d29760c637fcea5a8c18d2cc291f782c216c" +dependencies = [ + "const-default", + "critical-section", + "linked_list_allocator", + "rlsf", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -720,9 +747,12 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" +dependencies = [ + "portable-atomic", +] [[package]] name = "futures-sink" @@ -730,6 +760,26 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +[[package]] +name = "futures-task" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" + +[[package]] +name = "futures-util" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "portable-atomic", + "portable-atomic-util", + "slab", +] + [[package]] name = "generator" version = "0.8.9" @@ -888,6 +938,12 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +[[package]] +name = "linked_list_allocator" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b23ac50abb8261cb38c6e2a7192d3302e0836dac1628f6a93b82b4fad185897" + [[package]] name = "litrs" version = "1.0.0" @@ -994,7 +1050,7 @@ checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1118,14 +1174,26 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" +dependencies = [ + "critical-section", +] + +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] [[package]] name = "precomputed-hash" @@ -1152,7 +1220,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1238,6 +1306,19 @@ version = "0.8.53" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" +[[package]] +name = "rlsf" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1646a59a9734b8b7a0ac51689388a60fe1625d4b956348e9de07591a1478457a" +dependencies = [ + "cfg-if", + "const-default", + "libc", + "rustversion", + "svgbobdoc", +] + [[package]] name = "rp-pac" version = "7.0.0" @@ -1334,7 +1415,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1374,6 +1455,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + [[package]] name = "smallvec" version = "1.15.2" @@ -1432,6 +1519,30 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "svgbobdoc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50" +dependencies = [ + "base64", + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-width", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.118" @@ -1478,7 +1589,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1509,7 +1620,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1618,7 +1729,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn", + "syn 2.0.118", "usbd-hid-descriptors", ] @@ -1715,5 +1826,5 @@ checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] diff --git a/Cargo.toml b/Cargo.toml index 4d71fe6..6c95269 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,5 +13,8 @@ embassy-rp = { version = "0.10.0", features = ["chrono", "defmt", "rp2040", "rt" embassy-sync = { version = "0.8.0", features = ["defmt"] } embassy-time = "0.5.1" embassy-usb = { version = "0.6.0", features = ["defmt"] } +embedded-alloc = "0.7.0" +futures-util = { version = "0.3.33", default-features = false, features = ["alloc", "portable-atomic-alloc"] } panic-probe = { version = "1.0.0", features = ["defmt"] } +portable-atomic = { version = "1.14.0", default-features = false, features = ["critical-section"] } usbd-hid = { version = "0.10.0", features = ["defmt"] } diff --git a/src/keyboard.rs b/src/keyboard.rs index 9fbced5..e52216b 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -1,45 +1,14 @@ -use crate::usb::{KeyboardAction, KeyboardEvent}; -use defmt::*; +use crate::usb::KeyboardEvent; use embassy_rp::gpio::Input; use embassy_sync::blocking_mutex::raw::RawMutex; use embassy_sync::channel::Sender; +use futures_util::stream::{FuturesUnordered, StreamExt}; pub struct Key<'a> { button: Input<'a>, value: char, } -impl Key<'_> { - pub async fn process<'ch, M, const N: usize>( - &mut self, - sender: Sender<'ch, M, KeyboardEvent, N>, - ) where - M: RawMutex, - { - loop { - self.button.wait_for_high().await; - info!("Button {} pressed", self.value); - - sender - .send(KeyboardEvent { - key: self.value, - action: KeyboardAction::Press, - }) - .await; - - self.button.wait_for_low().await; - info!("Button {} unpressed", self.value); - - sender - .send(KeyboardEvent { - key: self.value, - action: KeyboardAction::Depress, - }) - .await; - } - } -} - impl Key<'_> { #[allow(unused)] pub async fn set_value(mut self, value: char) { @@ -80,7 +49,21 @@ impl<'d, const KEY_N: usize> Keyboard<'d, KEY_N> { where M: RawMutex, { - // TODO: Make this a loop that is concatinated together - self.keys[0].as_mut().unwrap().process(sender).await; + loop { + self.keys + .iter_mut() + .filter_map(|opt| opt.as_mut().map(|s| s.button.wait_for_any_edge())) + .collect::>() + .next() + .await; + for key in self.keys.iter_mut().filter_map(|opt| opt.as_mut()) { + sender + .send(KeyboardEvent { + key: key.value, + action: key.button.get_level().into(), + }) + .await; + } + } } } diff --git a/src/main.rs b/src/main.rs index e96bccd..94f9f6a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver, InterruptHandler}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; +use embedded_alloc::LlffHeap as Heap; use {defmt_rtt as _, panic_probe as _}; @@ -23,8 +24,19 @@ bind_interrupts!(struct Irqs { USBCTRL_IRQ => InterruptHandler; }); +#[global_allocator] +static HEAP: Heap = Heap::empty(); + #[embassy_executor::main] async fn main(_spawner: Spawner) { + static mut HEAP_MEM: [u8; 4096] = [0; 4096]; + unsafe { + HEAP.init( + core::ptr::addr_of!(HEAP_MEM) as usize, + core::mem::size_of::<[u8; 4096]>(), + ); + } + let keyboard_events: Channel = Channel::new(); let p = embassy_rp::init(Default::default()); diff --git a/src/usb.rs b/src/usb.rs index dcbd87a..b68fecb 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -2,6 +2,7 @@ use core::cell::OnceCell; use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use defmt::*; use embassy_futures::join::join; +use embassy_rp::gpio::Level; use embassy_rp::peripherals::USB; use embassy_rp::usb::Driver; use embassy_sync::blocking_mutex::raw::RawMutex; @@ -23,6 +24,15 @@ pub enum KeyboardAction { Depress, } +impl From for KeyboardAction { + fn from(value: Level) -> Self { + match value { + Level::Low => KeyboardAction::Depress, + Level::High => KeyboardAction::Press, + } + } +} + #[derive(Clone, Copy)] pub struct KeyboardEvent { pub key: char,