aboutsummaryrefslogtreecommitdiff
path: root/examples/stm32f4
diff options
context:
space:
mode:
authormatteo <email>2025-10-01 18:56:38 +0200
committermatteo <email>2025-10-01 18:56:38 +0200
commit176649e71ad442ca9856af6c11989b0b2f228c4b (patch)
treeb425294213a520f09c24dd215c00efadfad69149 /examples/stm32f4
parentd79d433d02ab154e5f8570392fd0ca1ffdf9cac1 (diff)
update hid mouse and keyboard examples
Diffstat (limited to 'examples/stm32f4')
-rw-r--r--examples/stm32f4/src/bin/usb_hid_keyboard.rs78
-rw-r--r--examples/stm32f4/src/bin/usb_hid_mouse.rs50
2 files changed, 93 insertions, 35 deletions
diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs
index 5521a8240..86b6fa95f 100644
--- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs
+++ b/examples/stm32f4/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;
@@ -11,7 +11,9 @@ use embassy_stm32::gpio::Pull;
11use embassy_stm32::time::Hertz; 11use embassy_stm32::time::Hertz;
12use embassy_stm32::usb::Driver; 12use embassy_stm32::usb::Driver;
13use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 13use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
14use embassy_usb::class::hid::{HidBootProtocol, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State}; 14use embassy_usb::class::hid::{
15 HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State,
16};
15use embassy_usb::control::OutResponse; 17use embassy_usb::control::OutResponse;
16use embassy_usb::{Builder, Handler}; 18use embassy_usb::{Builder, Handler};
17use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 19use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
@@ -21,6 +23,8 @@ bind_interrupts!(struct Irqs {
21 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; 23 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
22}); 24});
23 25
26static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
27
24// If you are trying this and your USB device doesn't connect, the most 28// If you are trying this and your USB device doesn't connect, the most
25// common issues are the RCC config and vbus_detection 29// common issues are the RCC config and vbus_detection
26// 30//
@@ -127,32 +131,46 @@ async fn main(_spawner: Spawner) {
127 button.wait_for_rising_edge().await; 131 button.wait_for_rising_edge().await;
128 // signal_pin.wait_for_high().await; 132 // signal_pin.wait_for_high().await;
129 info!("Button pressed!"); 133 info!("Button pressed!");
130 // Create a report with the A key pressed. (no shift modifier) 134 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
131 let report = KeyboardReport { 135 match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
132 keycodes: [4, 0, 0, 0, 0, 0], 136 Ok(()) => {}
133 leds: 0, 137 Err(e) => warn!("Failed to send boot report: {:?}", e),
134 modifier: 0, 138 };
135 reserved: 0, 139 } else {
136 }; 140 // Create a report with the A key pressed. (no shift modifier)
137 // Send the report. 141 let report = KeyboardReport {
138 match writer.write_serialize(&report).await { 142 keycodes: [4, 0, 0, 0, 0, 0],
139 Ok(()) => {} 143 leds: 0,
140 Err(e) => warn!("Failed to send report: {:?}", e), 144 modifier: 0,
141 }; 145 reserved: 0,
146 };
147 // Send the report.
148 match writer.write_serialize(&report).await {
149 Ok(()) => {}
150 Err(e) => warn!("Failed to send report: {:?}", e),
151 };
152 }
142 153
143 button.wait_for_falling_edge().await; 154 button.wait_for_falling_edge().await;
144 // signal_pin.wait_for_low().await; 155 // signal_pin.wait_for_low().await;
145 info!("Button released!"); 156 info!("Button released!");
146 let report = KeyboardReport { 157 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
147 keycodes: [0, 0, 0, 0, 0, 0], 158 match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
148 leds: 0, 159 Ok(()) => {}
149 modifier: 0, 160 Err(e) => warn!("Failed to send boot report: {:?}", e),
150 reserved: 0, 161 };
151 }; 162 } else {
152 match writer.write_serialize(&report).await { 163 let report = KeyboardReport {
153 Ok(()) => {} 164 keycodes: [0, 0, 0, 0, 0, 0],
154 Err(e) => warn!("Failed to send report: {:?}", e), 165 leds: 0,
155 }; 166 modifier: 0,
167 reserved: 0,
168 };
169 match writer.write_serialize(&report).await {
170 Ok(()) => {}
171 Err(e) => warn!("Failed to send report: {:?}", e),
172 };
173 }
156 } 174 }
157 }; 175 };
158 176
@@ -178,6 +196,18 @@ impl RequestHandler for MyRequestHandler {
178 OutResponse::Accepted 196 OutResponse::Accepted
179 } 197 }
180 198
199 fn get_protocol(&self) -> HidProtocolMode {
200 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
201 info!("The current HID protocol mode is: {}", protocol);
202 protocol
203 }
204
205 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
206 info!("Switching to HID protocol mode: {}", protocol);
207 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
208 OutResponse::Accepted
209 }
210
181 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 211 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
182 info!("Set idle rate for {:?} to {:?}", id, dur); 212 info!("Set idle rate for {:?} to {:?}", id, dur);
183 } 213 }
diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs
index 5cfa0aec4..977db4c15 100644
--- a/examples/stm32f4/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32f4/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;
@@ -8,7 +10,9 @@ use embassy_stm32::time::Hertz;
8use embassy_stm32::usb::Driver; 10use embassy_stm32::usb::Driver;
9use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 11use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_time::Timer; 12use embassy_time::Timer;
11use embassy_usb::class::hid::{HidBootProtocol, HidSubclass, HidWriter, ReportId, RequestHandler, State}; 13use embassy_usb::class::hid::{
14 HidBootProtocol, HidProtocolMode, HidSubclass, HidWriter, ReportId, RequestHandler, State,
15};
12use embassy_usb::control::OutResponse; 16use embassy_usb::control::OutResponse;
13use embassy_usb::Builder; 17use embassy_usb::Builder;
14use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; 18use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
@@ -18,6 +22,8 @@ bind_interrupts!(struct Irqs {
18 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; 22 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
19}); 23});
20 24
25static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
26
21// If you are trying this and your USB device doesn't connect, the most 27// If you are trying this and your USB device doesn't connect, the most
22// common issues are the RCC config and vbus_detection 28// common issues are the RCC config and vbus_detection
23// 29//
@@ -114,16 +120,26 @@ async fn main(_spawner: Spawner) {
114 Timer::after_millis(500).await; 120 Timer::after_millis(500).await;
115 121
116 y = -y; 122 y = -y;
117 let report = MouseReport { 123
118 buttons: 0, 124 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
119 x: 0, 125 let buttons = 0u8;
120 y, 126 let x = 0i8;
121 wheel: 0, 127 match writer.write(&[buttons, x as u8, y as u8]).await {
122 pan: 0, 128 Ok(()) => {}
123 }; 129 Err(e) => warn!("Failed to send boot report: {:?}", e),
124 match writer.write_serialize(&report).await { 130 }
125 Ok(()) => {} 131 } else {
126 Err(e) => warn!("Failed to send report: {:?}", e), 132 let report = MouseReport {
133 buttons: 0,
134 x: 0,
135 y,
136 wheel: 0,
137 pan: 0,
138 };
139 match writer.write_serialize(&report).await {
140 Ok(()) => {}
141 Err(e) => warn!("Failed to send report: {:?}", e),
142 }
127 } 143 }
128 } 144 }
129 }; 145 };
@@ -146,6 +162,18 @@ impl RequestHandler for MyRequestHandler {
146 OutResponse::Accepted 162 OutResponse::Accepted
147 } 163 }
148 164
165 fn get_protocol(&self) -> HidProtocolMode {
166 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
167 info!("The current HID protocol mode is: {}", protocol);
168 protocol
169 }
170
171 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
172 info!("Switching to HID protocol mode: {}", protocol);
173 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
174 OutResponse::Accepted
175 }
176
149 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 177 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
150 info!("Set idle rate for {:?} to {:?}", id, dur); 178 info!("Set idle rate for {:?} to {:?}", id, dur);
151 } 179 }