aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/src/bin/usb_hid_keyboard.rs80
-rwxr-xr-xexamples/rp/src/bin/usb_hid_mouse.rs54
-rw-r--r--examples/rp235x/src/bin/usb_hid_keyboard.rs77
-rw-r--r--examples/stm32f4/src/bin/usb_hid_keyboard.rs78
-rw-r--r--examples/stm32f4/src/bin/usb_hid_mouse.rs50
-rw-r--r--examples/stm32l5/src/bin/usb_hid_mouse.rs50
6 files changed, 282 insertions, 107 deletions
diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs
index adf91439e..2f6d169bf 100644
--- a/examples/rp/src/bin/usb_hid_keyboard.rs
+++ b/examples/rp/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;
@@ -10,7 +10,9 @@ use embassy_rp::bind_interrupts;
10use embassy_rp::gpio::{Input, Pull}; 10use embassy_rp::gpio::{Input, Pull};
11use embassy_rp::peripherals::USB; 11use embassy_rp::peripherals::USB;
12use embassy_rp::usb::{Driver, InterruptHandler}; 12use embassy_rp::usb::{Driver, InterruptHandler};
13use embassy_usb::class::hid::{HidBootProtocol, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State}; 13use embassy_usb::class::hid::{
14 HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State,
15};
14use embassy_usb::control::OutResponse; 16use embassy_usb::control::OutResponse;
15use embassy_usb::{Builder, Config, Handler}; 17use embassy_usb::{Builder, Config, Handler};
16use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 18use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
@@ -20,6 +22,8 @@ bind_interrupts!(struct Irqs {
20 USBCTRL_IRQ => InterruptHandler<USB>; 22 USBCTRL_IRQ => InterruptHandler<USB>;
21}); 23});
22 24
25static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
26
23#[embassy_executor::main] 27#[embassy_executor::main]
24async fn main(_spawner: Spawner) { 28async fn main(_spawner: Spawner) {
25 let p = embassy_rp::init(Default::default()); 29 let p = embassy_rp::init(Default::default());
@@ -92,30 +96,46 @@ async fn main(_spawner: Spawner) {
92 info!("Waiting for HIGH on pin 16"); 96 info!("Waiting for HIGH on pin 16");
93 signal_pin.wait_for_high().await; 97 signal_pin.wait_for_high().await;
94 info!("HIGH DETECTED"); 98 info!("HIGH DETECTED");
95 // Create a report with the A key pressed. (no shift modifier) 99
96 let report = KeyboardReport { 100 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
97 keycodes: [4, 0, 0, 0, 0, 0], 101 match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
98 leds: 0, 102 Ok(()) => {}
99 modifier: 0, 103 Err(e) => warn!("Failed to send boot report: {:?}", e),
100 reserved: 0, 104 };
101 }; 105 } else {
102 // Send the report. 106 // Create a report with the A key pressed. (no shift modifier)
103 match writer.write_serialize(&report).await { 107 let report = KeyboardReport {
104 Ok(()) => {} 108 keycodes: [4, 0, 0, 0, 0, 0],
105 Err(e) => warn!("Failed to send report: {:?}", e), 109 leds: 0,
106 }; 110 modifier: 0,
111 reserved: 0,
112 };
113 // Send the report.
114 match writer.write_serialize(&report).await {
115 Ok(()) => {}
116 Err(e) => warn!("Failed to send report: {:?}", e),
117 };
118 }
119
107 signal_pin.wait_for_low().await; 120 signal_pin.wait_for_low().await;
108 info!("LOW DETECTED"); 121 info!("LOW DETECTED");
109 let report = KeyboardReport { 122 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
110 keycodes: [0, 0, 0, 0, 0, 0], 123 match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
111 leds: 0, 124 Ok(()) => {}
112 modifier: 0, 125 Err(e) => warn!("Failed to send boot report: {:?}", e),
113 reserved: 0, 126 };
114 }; 127 } else {
115 match writer.write_serialize(&report).await { 128 let report = KeyboardReport {
116 Ok(()) => {} 129 keycodes: [0, 0, 0, 0, 0, 0],
117 Err(e) => warn!("Failed to send report: {:?}", e), 130 leds: 0,
118 }; 131 modifier: 0,
132 reserved: 0,
133 };
134 match writer.write_serialize(&report).await {
135 Ok(()) => {}
136 Err(e) => warn!("Failed to send report: {:?}", e),
137 };
138 }
119 } 139 }
120 }; 140 };
121 141
@@ -141,6 +161,18 @@ impl RequestHandler for MyRequestHandler {
141 OutResponse::Accepted 161 OutResponse::Accepted
142 } 162 }
143 163
164 fn get_protocol(&self) -> HidProtocolMode {
165 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
166 info!("The current HID protocol mode is: {}", protocol);
167 protocol
168 }
169
170 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
171 info!("Switching to HID protocol mode: {}", protocol);
172 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
173 OutResponse::Accepted
174 }
175
144 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 176 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
145 info!("Set idle rate for {:?} to {:?}", id, dur); 177 info!("Set idle rate for {:?} to {:?}", id, dur);
146 } 178 }
diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs
index 3e62e8891..dc331cbdd 100755
--- a/examples/rp/src/bin/usb_hid_mouse.rs
+++ b/examples/rp/src/bin/usb_hid_mouse.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_rp::clocks::RoscRng;
11use embassy_rp::peripherals::USB; 11use embassy_rp::peripherals::USB;
12use embassy_rp::usb::{Driver, InterruptHandler}; 12use embassy_rp::usb::{Driver, InterruptHandler};
13use embassy_time::Timer; 13use embassy_time::Timer;
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, Config, Handler}; 18use embassy_usb::{Builder, Config, Handler};
17use rand::Rng; 19use rand::Rng;
@@ -22,6 +24,8 @@ bind_interrupts!(struct Irqs {
22 USBCTRL_IRQ => InterruptHandler<USB>; 24 USBCTRL_IRQ => InterruptHandler<USB>;
23}); 25});
24 26
27static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
28
25#[embassy_executor::main] 29#[embassy_executor::main]
26async fn main(_spawner: Spawner) { 30async fn main(_spawner: Spawner) {
27 let p = embassy_rp::init(Default::default()); 31 let p = embassy_rp::init(Default::default());
@@ -89,17 +93,29 @@ async fn main(_spawner: Spawner) {
89 loop { 93 loop {
90 // every 1 second 94 // every 1 second
91 _ = Timer::after_secs(1).await; 95 _ = Timer::after_secs(1).await;
92 let report = MouseReport { 96
93 buttons: 0, 97 let x = rng.random_range(-100..100); // random small x movement
94 x: rng.random_range(-100..100), // random small x movement 98 let y = rng.random_range(-100..100); // random small y movement
95 y: rng.random_range(-100..100), // random small y movement 99
96 wheel: 0, 100 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
97 pan: 0, 101 let buttons = 0u8;
98 }; 102 match writer.write(&[buttons, x as u8, y as u8]).await {
99 // Send the report. 103 Ok(()) => {}
100 match writer.write_serialize(&report).await { 104 Err(e) => warn!("Failed to send boot report: {:?}", e),
101 Ok(()) => {} 105 }
102 Err(e) => warn!("Failed to send report: {:?}", e), 106 } else {
107 let report = MouseReport {
108 buttons: 0,
109 x,
110 y,
111 wheel: 0,
112 pan: 0,
113 };
114 // Send the report.
115 match writer.write_serialize(&report).await {
116 Ok(()) => {}
117 Err(e) => warn!("Failed to send report: {:?}", e),
118 }
103 } 119 }
104 } 120 }
105 }; 121 };
@@ -126,6 +142,18 @@ impl RequestHandler for MyRequestHandler {
126 OutResponse::Accepted 142 OutResponse::Accepted
127 } 143 }
128 144
145 fn get_protocol(&self) -> HidProtocolMode {
146 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
147 info!("The current HID protocol mode is: {}", protocol);
148 protocol
149 }
150
151 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
152 info!("Switching to HID protocol mode: {}", protocol);
153 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
154 OutResponse::Accepted
155 }
156
129 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 157 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
130 info!("Set idle rate for {:?} to {:?}", id, dur); 158 info!("Set idle rate for {:?} to {:?}", id, dur);
131 } 159 }
diff --git a/examples/rp235x/src/bin/usb_hid_keyboard.rs b/examples/rp235x/src/bin/usb_hid_keyboard.rs
index b740a07b3..d8f64c470 100644
--- a/examples/rp235x/src/bin/usb_hid_keyboard.rs
+++ b/examples/rp235x/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,7 @@ use embassy_rp::gpio::{Input, Pull};
11use embassy_rp::peripherals::USB; 11use embassy_rp::peripherals::USB;
12use embassy_rp::usb::{Driver as UsbDriver, InterruptHandler}; 12use embassy_rp::usb::{Driver as UsbDriver, InterruptHandler};
13use embassy_usb::class::hid::{ 13use embassy_usb::class::hid::{
14 HidBootProtocol, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State as HidState, 14 HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State as HidState,
15}; 15};
16use embassy_usb::control::OutResponse; 16use embassy_usb::control::OutResponse;
17use embassy_usb::{Builder, Config, Handler}; 17use embassy_usb::{Builder, Config, Handler};
@@ -22,6 +22,8 @@ bind_interrupts!(struct Irqs {
22 USBCTRL_IRQ => InterruptHandler<USB>; 22 USBCTRL_IRQ => InterruptHandler<USB>;
23}); 23});
24 24
25static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
26
25#[embassy_executor::main] 27#[embassy_executor::main]
26async fn main(_spawner: Spawner) { 28async fn main(_spawner: Spawner) {
27 let p = embassy_rp::init(Default::default()); 29 let p = embassy_rp::init(Default::default());
@@ -94,30 +96,45 @@ async fn main(_spawner: Spawner) {
94 info!("Waiting for HIGH on pin 16"); 96 info!("Waiting for HIGH on pin 16");
95 signal_pin.wait_for_high().await; 97 signal_pin.wait_for_high().await;
96 info!("HIGH DETECTED"); 98 info!("HIGH DETECTED");
97 // Create a report with the A key pressed. (no shift modifier) 99
98 let report = KeyboardReport { 100 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
99 keycodes: [4, 0, 0, 0, 0, 0], 101 match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
100 leds: 0, 102 Ok(()) => {}
101 modifier: 0, 103 Err(e) => warn!("Failed to send boot report: {:?}", e),
102 reserved: 0, 104 };
103 }; 105 } else {
104 // Send the report. 106 // Create a report with the A key pressed. (no shift modifier)
105 match writer.write_serialize(&report).await { 107 let report = KeyboardReport {
106 Ok(()) => {} 108 keycodes: [4, 0, 0, 0, 0, 0],
107 Err(e) => warn!("Failed to send report: {:?}", e), 109 leds: 0,
108 }; 110 modifier: 0,
111 reserved: 0,
112 };
113 // Send the report.
114 match writer.write_serialize(&report).await {
115 Ok(()) => {}
116 Err(e) => warn!("Failed to send report: {:?}", e),
117 };
118 }
109 signal_pin.wait_for_low().await; 119 signal_pin.wait_for_low().await;
110 info!("LOW DETECTED"); 120 info!("LOW DETECTED");
111 let report = KeyboardReport { 121 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
112 keycodes: [0, 0, 0, 0, 0, 0], 122 match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
113 leds: 0, 123 Ok(()) => {}
114 modifier: 0, 124 Err(e) => warn!("Failed to send boot report: {:?}", e),
115 reserved: 0, 125 };
116 }; 126 } else {
117 match writer.write_serialize(&report).await { 127 let report = KeyboardReport {
118 Ok(()) => {} 128 keycodes: [0, 0, 0, 0, 0, 0],
119 Err(e) => warn!("Failed to send report: {:?}", e), 129 leds: 0,
120 }; 130 modifier: 0,
131 reserved: 0,
132 };
133 match writer.write_serialize(&report).await {
134 Ok(()) => {}
135 Err(e) => warn!("Failed to send report: {:?}", e),
136 };
137 }
121 } 138 }
122 }; 139 };
123 140
@@ -143,6 +160,18 @@ impl RequestHandler for MyRequestHandler {
143 OutResponse::Accepted 160 OutResponse::Accepted
144 } 161 }
145 162
163 fn get_protocol(&self) -> HidProtocolMode {
164 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
165 info!("The current HID protocol mode is: {}", protocol);
166 protocol
167 }
168
169 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
170 info!("Switching to HID protocol mode: {}", protocol);
171 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
172 OutResponse::Accepted
173 }
174
146 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 175 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
147 info!("Set idle rate for {:?} to {:?}", id, dur); 176 info!("Set idle rate for {:?} to {:?}", id, dur);
148 } 177 }
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 }
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs
index f64fde3cb..8c7cdbef5 100644
--- a/examples/stm32l5/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs
@@ -1,13 +1,17 @@
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;
7use embassy_stm32::usb::Driver; 9use embassy_stm32::usb::Driver;
8use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 10use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_time::Timer; 11use embassy_time::Timer;
10use embassy_usb::class::hid::{HidBootProtocol, HidSubclass, HidWriter, ReportId, RequestHandler, State}; 12use embassy_usb::class::hid::{
13 HidBootProtocol, HidProtocolMode, HidSubclass, HidWriter, ReportId, RequestHandler, State,
14};
11use embassy_usb::control::OutResponse; 15use embassy_usb::control::OutResponse;
12use embassy_usb::Builder; 16use embassy_usb::Builder;
13use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; 17use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
@@ -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();
@@ -96,16 +102,26 @@ async fn main(_spawner: Spawner) {
96 Timer::after_millis(500).await; 102 Timer::after_millis(500).await;
97 103
98 y = -y; 104 y = -y;
99 let report = MouseReport { 105
100 buttons: 0, 106 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
101 x: 0, 107 let buttons = 0u8;
102 y, 108 let x = 0i8;
103 wheel: 0, 109 match writer.write(&[buttons, x as u8, y as u8]).await {
104 pan: 0, 110 Ok(()) => {}
105 }; 111 Err(e) => warn!("Failed to send boot report: {:?}", e),
106 match writer.write_serialize(&report).await { 112 }
107 Ok(()) => {} 113 } else {
108 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 }
109 } 125 }
110 } 126 }
111 }; 127 };
@@ -128,6 +144,18 @@ impl RequestHandler for MyRequestHandler {
128 OutResponse::Accepted 144 OutResponse::Accepted
129 } 145 }
130 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
131 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 159 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
132 info!("Set idle rate for {:?} to {:?}", id, dur); 160 info!("Set idle rate for {:?} to {:?}", id, dur);
133 } 161 }