From 8eebeceb16fc5ef15285c62d21b8ea65b9baf6ee Mon Sep 17 00:00:00 2001 From: matteo Date: Tue, 23 Sep 2025 20:51:58 +0200 Subject: working nrf52840 examples --- examples/nrf52840/Cargo.toml | 2 +- examples/nrf52840/src/bin/usb_hid_keyboard.rs | 49 +++++++++++++++++++++------ examples/nrf52840/src/bin/usb_hid_mouse.rs | 47 +++++++++++++++++++------ 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 452e83b7e..9a1fc080e 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -28,7 +28,7 @@ cortex-m-rt = "0.7.0" panic-probe = { version = "1.0.0", features = ["print-defmt"] } rand = { version = "0.9.0", default-features = false } embedded-storage = "0.3.1" -usbd-hid = "0.8.1" +usbd-hid = { version = "0.8.1", features = ["defmt"] } serde = { version = "1.0.136", default-features = false } embedded-hal = { version = "1.0" } embedded-hal-async = { version = "1.0" } diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs index 0f0d830c6..a4931099a 100644 --- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs @@ -1,7 +1,7 @@ #![no_std] #![no_main] -use core::sync::atomic::{AtomicBool, Ordering}; +use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use defmt::*; use embassy_executor::Spawner; @@ -17,6 +17,7 @@ use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Config, Handler}; use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; +use usbd_hid::hid_class::HidProtocolMode; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -26,6 +27,8 @@ bind_interrupts!(struct Irqs { static SUSPENDED: AtomicBool = AtomicBool::new(false); +static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_nrf::init(Default::default()); @@ -110,6 +113,11 @@ async fn main(_spawner: Spawner) { if SUSPENDED.load(Ordering::Acquire) { info!("Triggering remote wakeup"); remote_wakeup.signal(()); + } else if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 { + match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await { + Ok(()) => {} + Err(e) => warn!("Failed to send boot report: {:?}", e), + }; } else { let report = KeyboardReport { keycodes: [4, 0, 0, 0, 0, 0], @@ -125,16 +133,23 @@ async fn main(_spawner: Spawner) { button.wait_for_high().await; info!("RELEASED"); - let report = KeyboardReport { - keycodes: [0, 0, 0, 0, 0, 0], - leds: 0, - modifier: 0, - reserved: 0, - }; - match writer.write_serialize(&report).await { - Ok(()) => {} - Err(e) => warn!("Failed to send report: {:?}", e), - }; + if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 { + match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await { + Ok(()) => {} + Err(e) => warn!("Failed to send boot report: {:?}", e), + }; + } else { + let report = KeyboardReport { + keycodes: [0, 0, 0, 0, 0, 0], + leds: 0, + modifier: 0, + reserved: 0, + }; + match writer.write_serialize(&report).await { + Ok(()) => {} + Err(e) => warn!("Failed to send report: {:?}", e), + }; + } } }; @@ -160,6 +175,18 @@ impl RequestHandler for MyRequestHandler { OutResponse::Accepted } + fn get_protocol(&self) -> HidProtocolMode { + let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed)); + info!("The current HID protocol mode is: {}", protocol); + protocol + } + + fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse { + info!("Switching to HID protocol mode: {}", protocol); + HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed); + OutResponse::Accepted + } + fn set_idle_ms(&mut self, id: Option, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs index b3d90354b..6ec8a2d33 100644 --- a/examples/nrf52840/src/bin/usb_hid_mouse.rs +++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs @@ -1,6 +1,8 @@ #![no_std] #![no_main] +use core::sync::atomic::{AtomicU8, Ordering}; + use defmt::*; use embassy_executor::Spawner; use embassy_futures::join::join; @@ -12,6 +14,7 @@ use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Config}; use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; +use usbd_hid::hid_class::HidProtocolMode; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -19,6 +22,8 @@ bind_interrupts!(struct Irqs { CLOCK_POWER => usb::vbus_detect::InterruptHandler; }); +static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_nrf::init(Default::default()); @@ -84,16 +89,26 @@ async fn main(_spawner: Spawner) { Timer::after_millis(500).await; y = -y; - let report = MouseReport { - buttons: 0, - x: 0, - y, - wheel: 0, - pan: 0, - }; - match writer.write_serialize(&report).await { - Ok(()) => {} - Err(e) => warn!("Failed to send report: {:?}", e), + + if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 { + let buttons = 0u8; + let x = 0i8; + match writer.write(&[buttons, x as u8, y as u8]).await { + Ok(()) => {} + Err(e) => warn!("Failed to send boot report: {:?}", e), + } + } else { + let report = MouseReport { + buttons: 0, + x: 0, + y, + wheel: 0, + pan: 0, + }; + match writer.write_serialize(&report).await { + Ok(()) => {} + Err(e) => warn!("Failed to send report: {:?}", e), + } } } }; @@ -116,6 +131,18 @@ impl RequestHandler for MyRequestHandler { OutResponse::Accepted } + fn get_protocol(&self) -> HidProtocolMode { + let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed)); + info!("The current HID protocol mode is: {}", protocol); + protocol + } + + fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse { + info!("Switching to HID protocol mode: {}", protocol); + HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed); + OutResponse::Accepted + } + fn set_idle_ms(&mut self, id: Option, dur: u32) { info!("Set idle rate for {:?} to {:?}", id, dur); } -- cgit