aboutsummaryrefslogtreecommitdiff
path: root/examples/stm32l5
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2025-11-12 08:24:18 +0000
committerGitHub <[email protected]>2025-11-12 08:24:18 +0000
commit7201c6deb9d8c2b1fb380a58b9e879e394ed5f24 (patch)
treed33ddfb6b8038a25e319495649844c798689fdef /examples/stm32l5
parent0d1fc76a10863b85961a63db4a9e1e2807f35957 (diff)
parenta60b268186ff3accf68a3a6009d96ffca12221bd (diff)
Merge pull request #4691 from matteo-meluzzi/17-add-support-for-boot-protocol
Add support for changing hid protocol mode in embassy-usb
Diffstat (limited to 'examples/stm32l5')
-rw-r--r--examples/stm32l5/src/bin/usb_hid_mouse.rs56
1 files changed, 45 insertions, 11 deletions
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs
index b721f5b2e..d8f2de941 100644
--- a/examples/stm32l5/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32l5/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::usb::Driver;
8use embassy_stm32::{Config, bind_interrupts, peripherals, usb}; 10use embassy_stm32::{Config, bind_interrupts, peripherals, usb};
9use embassy_time::Timer; 11use embassy_time::Timer;
10use embassy_usb::Builder; 12use embassy_usb::Builder;
11use embassy_usb::class::hid::{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 usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; 17use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
14use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
@@ -17,6 +21,8 @@ bind_interrupts!(struct Irqs {
17 USB_FS => usb::InterruptHandler<peripherals::USB>; 21 USB_FS => usb::InterruptHandler<peripherals::USB>;
18}); 22});
19 23
24static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
25
20#[embassy_executor::main] 26#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 27async fn main(_spawner: Spawner) {
22 let mut config = Config::default(); 28 let mut config = Config::default();
@@ -48,6 +54,10 @@ async fn main(_spawner: Spawner) {
48 config.serial_number = Some("12345678"); 54 config.serial_number = Some("12345678");
49 config.max_power = 100; 55 config.max_power = 100;
50 config.max_packet_size_0 = 64; 56 config.max_packet_size_0 = 64;
57 config.composite_with_iads = false;
58 config.device_class = 0;
59 config.device_sub_class = 0;
60 config.device_protocol = 0;
51 61
52 // Create embassy-usb DeviceBuilder using the driver and config. 62 // Create embassy-usb DeviceBuilder using the driver and config.
53 // It needs some buffers for building the descriptors. 63 // It needs some buffers for building the descriptors.
@@ -73,6 +83,8 @@ async fn main(_spawner: Spawner) {
73 request_handler: Some(&mut request_handler), 83 request_handler: Some(&mut request_handler),
74 poll_ms: 60, 84 poll_ms: 60,
75 max_packet_size: 8, 85 max_packet_size: 8,
86 hid_subclass: HidSubclass::Boot,
87 hid_boot_protocol: HidBootProtocol::Mouse,
76 }; 88 };
77 89
78 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config); 90 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config);
@@ -90,16 +102,26 @@ async fn main(_spawner: Spawner) {
90 Timer::after_millis(500).await; 102 Timer::after_millis(500).await;
91 103
92 y = -y; 104 y = -y;
93 let report = MouseReport { 105
94 buttons: 0, 106 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
95 x: 0, 107 let buttons = 0u8;
96 y, 108 let x = 0i8;
97 wheel: 0, 109 match writer.write(&[buttons, x as u8, y as u8]).await {
98 pan: 0, 110 Ok(()) => {}
99 }; 111 Err(e) => warn!("Failed to send boot report: {:?}", e),
100 match writer.write_serialize(&report).await { 112 }
101 Ok(()) => {} 113 } else {
102 Err(e) => warn!("Failed to send report: {:?}", e), 114 let report = MouseReport {
115 buttons: 0,
116 x: 0,
117 y,
118 wheel: 0,
119 pan: 0,
120 };
121 match writer.write_serialize(&report).await {
122 Ok(()) => {}
123 Err(e) => warn!("Failed to send report: {:?}", e),
124 }
103 } 125 }
104 } 126 }
105 }; 127 };
@@ -122,6 +144,18 @@ impl RequestHandler for MyRequestHandler {
122 OutResponse::Accepted 144 OutResponse::Accepted
123 } 145 }
124 146
147 fn get_protocol(&self) -> HidProtocolMode {
148 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
149 info!("The current HID protocol mode is: {}", protocol);
150 protocol
151 }
152
153 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
154 info!("Switching to HID protocol mode: {}", protocol);
155 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
156 OutResponse::Accepted
157 }
158
125 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 159 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
126 info!("Set idle rate for {:?} to {:?}", id, dur); 160 info!("Set idle rate for {:?} to {:?}", id, dur);
127 } 161 }