aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatteo <email>2025-09-23 20:51:58 +0200
committermatteo <email>2025-09-23 20:51:58 +0200
commit8eebeceb16fc5ef15285c62d21b8ea65b9baf6ee (patch)
tree7b6ea54c9c4defe7ec36f7123cb3550ee818f13c
parent2e303c995c53a97a1c2eaecf77827f02567b8417 (diff)
working nrf52840 examples
-rw-r--r--examples/nrf52840/Cargo.toml2
-rw-r--r--examples/nrf52840/src/bin/usb_hid_keyboard.rs49
-rw-r--r--examples/nrf52840/src/bin/usb_hid_mouse.rs47
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"
28panic-probe = { version = "1.0.0", features = ["print-defmt"] } 28panic-probe = { version = "1.0.0", features = ["print-defmt"] }
29rand = { version = "0.9.0", default-features = false } 29rand = { version = "0.9.0", default-features = false }
30embedded-storage = "0.3.1" 30embedded-storage = "0.3.1"
31usbd-hid = "0.8.1" 31usbd-hid = { version = "0.8.1", features = ["defmt"] }
32serde = { version = "1.0.136", default-features = false } 32serde = { version = "1.0.136", default-features = false }
33embedded-hal = { version = "1.0" } 33embedded-hal = { version = "1.0" }
34embedded-hal-async = { version = "1.0" } 34embedded-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 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5 5
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
@@ -17,6 +17,7 @@ use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State};
17use embassy_usb::control::OutResponse; 17use embassy_usb::control::OutResponse;
18use embassy_usb::{Builder, Config, Handler}; 18use embassy_usb::{Builder, Config, Handler};
19use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 19use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
20use usbd_hid::hid_class::HidProtocolMode;
20use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
21 22
22bind_interrupts!(struct Irqs { 23bind_interrupts!(struct Irqs {
@@ -26,6 +27,8 @@ bind_interrupts!(struct Irqs {
26 27
27static SUSPENDED: AtomicBool = AtomicBool::new(false); 28static SUSPENDED: AtomicBool = AtomicBool::new(false);
28 29
30static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
31
29#[embassy_executor::main] 32#[embassy_executor::main]
30async fn main(_spawner: Spawner) { 33async fn main(_spawner: Spawner) {
31 let p = embassy_nrf::init(Default::default()); 34 let p = embassy_nrf::init(Default::default());
@@ -110,6 +113,11 @@ async fn main(_spawner: Spawner) {
110 if SUSPENDED.load(Ordering::Acquire) { 113 if SUSPENDED.load(Ordering::Acquire) {
111 info!("Triggering remote wakeup"); 114 info!("Triggering remote wakeup");
112 remote_wakeup.signal(()); 115 remote_wakeup.signal(());
116 } else if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
117 match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
118 Ok(()) => {}
119 Err(e) => warn!("Failed to send boot report: {:?}", e),
120 };
113 } else { 121 } else {
114 let report = KeyboardReport { 122 let report = KeyboardReport {
115 keycodes: [4, 0, 0, 0, 0, 0], 123 keycodes: [4, 0, 0, 0, 0, 0],
@@ -125,16 +133,23 @@ async fn main(_spawner: Spawner) {
125 133
126 button.wait_for_high().await; 134 button.wait_for_high().await;
127 info!("RELEASED"); 135 info!("RELEASED");
128 let report = KeyboardReport { 136 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
129 keycodes: [0, 0, 0, 0, 0, 0], 137 match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
130 leds: 0, 138 Ok(()) => {}
131 modifier: 0, 139 Err(e) => warn!("Failed to send boot report: {:?}", e),
132 reserved: 0, 140 };
133 }; 141 } else {
134 match writer.write_serialize(&report).await { 142 let report = KeyboardReport {
135 Ok(()) => {} 143 keycodes: [0, 0, 0, 0, 0, 0],
136 Err(e) => warn!("Failed to send report: {:?}", e), 144 leds: 0,
137 }; 145 modifier: 0,
146 reserved: 0,
147 };
148 match writer.write_serialize(&report).await {
149 Ok(()) => {}
150 Err(e) => warn!("Failed to send report: {:?}", e),
151 };
152 }
138 } 153 }
139 }; 154 };
140 155
@@ -160,6 +175,18 @@ impl RequestHandler for MyRequestHandler {
160 OutResponse::Accepted 175 OutResponse::Accepted
161 } 176 }
162 177
178 fn get_protocol(&self) -> HidProtocolMode {
179 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
180 info!("The current HID protocol mode is: {}", protocol);
181 protocol
182 }
183
184 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
185 info!("Switching to HID protocol mode: {}", protocol);
186 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
187 OutResponse::Accepted
188 }
189
163 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 190 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
164 info!("Set idle rate for {:?} to {:?}", id, dur); 191 info!("Set idle rate for {:?} to {:?}", id, dur);
165 } 192 }
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 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicU8, Ordering};
5
4use defmt::*; 6use defmt::*;
5use embassy_executor::Spawner; 7use embassy_executor::Spawner;
6use embassy_futures::join::join; 8use embassy_futures::join::join;
@@ -12,6 +14,7 @@ use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State};
12use embassy_usb::control::OutResponse; 14use embassy_usb::control::OutResponse;
13use embassy_usb::{Builder, Config}; 15use embassy_usb::{Builder, Config};
14use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; 16use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
17use usbd_hid::hid_class::HidProtocolMode;
15use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
16 19
17bind_interrupts!(struct Irqs { 20bind_interrupts!(struct Irqs {
@@ -19,6 +22,8 @@ bind_interrupts!(struct Irqs {
19 CLOCK_POWER => usb::vbus_detect::InterruptHandler; 22 CLOCK_POWER => usb::vbus_detect::InterruptHandler;
20}); 23});
21 24
25static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
26
22#[embassy_executor::main] 27#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 28async fn main(_spawner: Spawner) {
24 let p = embassy_nrf::init(Default::default()); 29 let p = embassy_nrf::init(Default::default());
@@ -84,16 +89,26 @@ async fn main(_spawner: Spawner) {
84 Timer::after_millis(500).await; 89 Timer::after_millis(500).await;
85 90
86 y = -y; 91 y = -y;
87 let report = MouseReport { 92
88 buttons: 0, 93 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
89 x: 0, 94 let buttons = 0u8;
90 y, 95 let x = 0i8;
91 wheel: 0, 96 match writer.write(&[buttons, x as u8, y as u8]).await {
92 pan: 0, 97 Ok(()) => {}
93 }; 98 Err(e) => warn!("Failed to send boot report: {:?}", e),
94 match writer.write_serialize(&report).await { 99 }
95 Ok(()) => {} 100 } else {
96 Err(e) => warn!("Failed to send report: {:?}", e), 101 let report = MouseReport {
102 buttons: 0,
103 x: 0,
104 y,
105 wheel: 0,
106 pan: 0,
107 };
108 match writer.write_serialize(&report).await {
109 Ok(()) => {}
110 Err(e) => warn!("Failed to send report: {:?}", e),
111 }
97 } 112 }
98 } 113 }
99 }; 114 };
@@ -116,6 +131,18 @@ impl RequestHandler for MyRequestHandler {
116 OutResponse::Accepted 131 OutResponse::Accepted
117 } 132 }
118 133
134 fn get_protocol(&self) -> HidProtocolMode {
135 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
136 info!("The current HID protocol mode is: {}", protocol);
137 protocol
138 }
139
140 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
141 info!("Switching to HID protocol mode: {}", protocol);
142 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
143 OutResponse::Accepted
144 }
145
119 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 146 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
120 info!("Set idle rate for {:?} to {:?}", id, dur); 147 info!("Set idle rate for {:?} to {:?}", id, dur);
121 } 148 }