diff options
| author | matteo <email> | 2025-10-01 18:56:38 +0200 |
|---|---|---|
| committer | matteo <email> | 2025-10-01 18:56:38 +0200 |
| commit | 176649e71ad442ca9856af6c11989b0b2f228c4b (patch) | |
| tree | b425294213a520f09c24dd215c00efadfad69149 /examples/rp/src/bin | |
| parent | d79d433d02ab154e5f8570392fd0ca1ffdf9cac1 (diff) | |
update hid mouse and keyboard examples
Diffstat (limited to 'examples/rp/src/bin')
| -rw-r--r-- | examples/rp/src/bin/usb_hid_keyboard.rs | 80 | ||||
| -rwxr-xr-x | examples/rp/src/bin/usb_hid_mouse.rs | 54 |
2 files changed, 97 insertions, 37 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 | ||
| 4 | use core::sync::atomic::{AtomicBool, Ordering}; | 4 | use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; |
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| @@ -10,7 +10,9 @@ use embassy_rp::bind_interrupts; | |||
| 10 | use embassy_rp::gpio::{Input, Pull}; | 10 | use embassy_rp::gpio::{Input, Pull}; |
| 11 | use embassy_rp::peripherals::USB; | 11 | use embassy_rp::peripherals::USB; |
| 12 | use embassy_rp::usb::{Driver, InterruptHandler}; | 12 | use embassy_rp::usb::{Driver, InterruptHandler}; |
| 13 | use embassy_usb::class::hid::{HidBootProtocol, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State}; | 13 | use embassy_usb::class::hid::{ |
| 14 | HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State, | ||
| 15 | }; | ||
| 14 | use embassy_usb::control::OutResponse; | 16 | use embassy_usb::control::OutResponse; |
| 15 | use embassy_usb::{Builder, Config, Handler}; | 17 | use embassy_usb::{Builder, Config, Handler}; |
| 16 | use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; | 18 | use 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 | ||
| 25 | static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8); | ||
| 26 | |||
| 23 | #[embassy_executor::main] | 27 | #[embassy_executor::main] |
| 24 | async fn main(_spawner: Spawner) { | 28 | async 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 | ||
| 4 | use core::sync::atomic::{AtomicBool, Ordering}; | 4 | use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; |
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| @@ -11,7 +11,9 @@ use embassy_rp::clocks::RoscRng; | |||
| 11 | use embassy_rp::peripherals::USB; | 11 | use embassy_rp::peripherals::USB; |
| 12 | use embassy_rp::usb::{Driver, InterruptHandler}; | 12 | use embassy_rp::usb::{Driver, InterruptHandler}; |
| 13 | use embassy_time::Timer; | 13 | use embassy_time::Timer; |
| 14 | use embassy_usb::class::hid::{HidBootProtocol, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State}; | 14 | use embassy_usb::class::hid::{ |
| 15 | HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State, | ||
| 16 | }; | ||
| 15 | use embassy_usb::control::OutResponse; | 17 | use embassy_usb::control::OutResponse; |
| 16 | use embassy_usb::{Builder, Config, Handler}; | 18 | use embassy_usb::{Builder, Config, Handler}; |
| 17 | use rand::Rng; | 19 | use rand::Rng; |
| @@ -22,6 +24,8 @@ bind_interrupts!(struct Irqs { | |||
| 22 | USBCTRL_IRQ => InterruptHandler<USB>; | 24 | USBCTRL_IRQ => InterruptHandler<USB>; |
| 23 | }); | 25 | }); |
| 24 | 26 | ||
| 27 | static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8); | ||
| 28 | |||
| 25 | #[embassy_executor::main] | 29 | #[embassy_executor::main] |
| 26 | async fn main(_spawner: Spawner) { | 30 | async 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 | } |
