diff options
| author | alexmoon <[email protected]> | 2022-04-13 13:09:08 -0400 |
|---|---|---|
| committer | alexmoon <[email protected]> | 2022-04-13 14:55:02 -0400 |
| commit | ff7c6b350e2338a0b1e4327f4b2eb0435468f313 (patch) | |
| tree | 1a045db7348d2562b9c8a19299467a30b62e501e /examples | |
| parent | 1d875fab2dc9d765ebf9f4b37112581301f2ed7e (diff) | |
Remove channel and make run future cancelable
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/nrf/src/bin/usb_hid_keyboard.rs | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs index fb3a198a7..32659dfbb 100644 --- a/examples/nrf/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf/src/bin/usb_hid_keyboard.rs | |||
| @@ -11,13 +11,14 @@ use embassy::channel::Channel; | |||
| 11 | use embassy::executor::Spawner; | 11 | use embassy::executor::Spawner; |
| 12 | use embassy::interrupt::InterruptExt; | 12 | use embassy::interrupt::InterruptExt; |
| 13 | use embassy::time::Duration; | 13 | use embassy::time::Duration; |
| 14 | use embassy::util::select; | ||
| 14 | use embassy_nrf::gpio::{Input, Pin, Pull}; | 15 | use embassy_nrf::gpio::{Input, Pin, Pull}; |
| 15 | use embassy_nrf::interrupt; | 16 | use embassy_nrf::interrupt; |
| 16 | use embassy_nrf::pac; | 17 | use embassy_nrf::pac; |
| 17 | use embassy_nrf::usb::Driver; | 18 | use embassy_nrf::usb::Driver; |
| 18 | use embassy_nrf::Peripherals; | 19 | use embassy_nrf::Peripherals; |
| 19 | use embassy_usb::control::OutResponse; | 20 | use embassy_usb::control::OutResponse; |
| 20 | use embassy_usb::{Config, DeviceCommand, DeviceStateHandler, UsbDeviceBuilder}; | 21 | use embassy_usb::{Config, DeviceStateHandler, UsbDeviceBuilder}; |
| 21 | use embassy_usb_hid::{HidClass, ReportId, RequestHandler, State}; | 22 | use embassy_usb_hid::{HidClass, ReportId, RequestHandler, State}; |
| 22 | use futures::future::join; | 23 | use futures::future::join; |
| 23 | use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; | 24 | use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; |
| @@ -25,7 +26,14 @@ use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; | |||
| 25 | use defmt_rtt as _; // global logger | 26 | use defmt_rtt as _; // global logger |
| 26 | use panic_probe as _; | 27 | use panic_probe as _; |
| 27 | 28 | ||
| 28 | static USB_COMMANDS: Channel<CriticalSectionRawMutex, DeviceCommand, 1> = Channel::new(); | 29 | #[derive(defmt::Format)] |
| 30 | enum Command { | ||
| 31 | Enable, | ||
| 32 | Disable, | ||
| 33 | RemoteWakeup, | ||
| 34 | } | ||
| 35 | |||
| 36 | static USB_COMMANDS: Channel<CriticalSectionRawMutex, Command, 1> = Channel::new(); | ||
| 29 | static SUSPENDED: AtomicBool = AtomicBool::new(false); | 37 | static SUSPENDED: AtomicBool = AtomicBool::new(false); |
| 30 | 38 | ||
| 31 | fn on_power_interrupt(_: *mut ()) { | 39 | fn on_power_interrupt(_: *mut ()) { |
| @@ -34,7 +42,7 @@ fn on_power_interrupt(_: *mut ()) { | |||
| 34 | if regs.events_usbdetected.read().bits() != 0 { | 42 | if regs.events_usbdetected.read().bits() != 0 { |
| 35 | regs.events_usbdetected.reset(); | 43 | regs.events_usbdetected.reset(); |
| 36 | info!("Vbus detected, enabling USB..."); | 44 | info!("Vbus detected, enabling USB..."); |
| 37 | if USB_COMMANDS.try_send(DeviceCommand::Enable).is_err() { | 45 | if USB_COMMANDS.try_send(Command::Enable).is_err() { |
| 38 | warn!("Failed to send enable command to USB channel"); | 46 | warn!("Failed to send enable command to USB channel"); |
| 39 | } | 47 | } |
| 40 | } | 48 | } |
| @@ -42,7 +50,7 @@ fn on_power_interrupt(_: *mut ()) { | |||
| 42 | if regs.events_usbremoved.read().bits() != 0 { | 50 | if regs.events_usbremoved.read().bits() != 0 { |
| 43 | regs.events_usbremoved.reset(); | 51 | regs.events_usbremoved.reset(); |
| 44 | info!("Vbus removed, disabling USB..."); | 52 | info!("Vbus removed, disabling USB..."); |
| 45 | if USB_COMMANDS.try_send(DeviceCommand::Disable).is_err() { | 53 | if USB_COMMANDS.try_send(Command::Disable).is_err() { |
| 46 | warn!("Failed to send disable command to USB channel"); | 54 | warn!("Failed to send disable command to USB channel"); |
| 47 | }; | 55 | }; |
| 48 | } | 56 | } |
| @@ -69,7 +77,6 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 69 | config.max_power = 100; | 77 | config.max_power = 100; |
| 70 | config.max_packet_size_0 = 64; | 78 | config.max_packet_size_0 = 64; |
| 71 | config.supports_remote_wakeup = true; | 79 | config.supports_remote_wakeup = true; |
| 72 | config.start_enabled = false; | ||
| 73 | 80 | ||
| 74 | // Create embassy-usb DeviceBuilder using the driver and config. | 81 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 75 | // It needs some buffers for building the descriptors. | 82 | // It needs some buffers for building the descriptors. |
| @@ -82,7 +89,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 82 | 89 | ||
| 83 | let mut state = State::<8, 1>::new(); | 90 | let mut state = State::<8, 1>::new(); |
| 84 | 91 | ||
| 85 | let mut builder = UsbDeviceBuilder::new_with_channel( | 92 | let mut builder = UsbDeviceBuilder::new( |
| 86 | driver, | 93 | driver, |
| 87 | config, | 94 | config, |
| 88 | &mut device_descriptor, | 95 | &mut device_descriptor, |
| @@ -90,7 +97,6 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 90 | &mut bos_descriptor, | 97 | &mut bos_descriptor, |
| 91 | &mut control_buf, | 98 | &mut control_buf, |
| 92 | Some(&device_state_handler), | 99 | Some(&device_state_handler), |
| 93 | &USB_COMMANDS, | ||
| 94 | ); | 100 | ); |
| 95 | 101 | ||
| 96 | // Create classes on the builder. | 102 | // Create classes on the builder. |
| @@ -107,7 +113,22 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 107 | let mut usb = builder.build(); | 113 | let mut usb = builder.build(); |
| 108 | 114 | ||
| 109 | // Run the USB device. | 115 | // Run the USB device. |
| 110 | let usb_fut = usb.run(); | 116 | let usb_fut = async { |
| 117 | enable_command().await; | ||
| 118 | loop { | ||
| 119 | match select(usb.run(), USB_COMMANDS.recv()).await { | ||
| 120 | embassy::util::Either::First(_) => defmt::unreachable!(), | ||
| 121 | embassy::util::Either::Second(cmd) => match cmd { | ||
| 122 | Command::Enable => warn!("Enable when already enabled!"), | ||
| 123 | Command::Disable => { | ||
| 124 | usb.disable().await; | ||
| 125 | enable_command().await; | ||
| 126 | } | ||
| 127 | Command::RemoteWakeup => unwrap!(usb.remote_wakeup().await), | ||
| 128 | }, | ||
| 129 | } | ||
| 130 | } | ||
| 131 | }; | ||
| 111 | 132 | ||
| 112 | let mut button = Input::new(p.P0_11.degrade(), Pull::Up); | 133 | let mut button = Input::new(p.P0_11.degrade(), Pull::Up); |
| 113 | 134 | ||
| @@ -121,7 +142,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 121 | 142 | ||
| 122 | if SUSPENDED.load(Ordering::Acquire) { | 143 | if SUSPENDED.load(Ordering::Acquire) { |
| 123 | info!("Triggering remote wakeup"); | 144 | info!("Triggering remote wakeup"); |
| 124 | USB_COMMANDS.send(DeviceCommand::RemoteWakeup).await; | 145 | USB_COMMANDS.send(Command::RemoteWakeup).await; |
| 125 | } else { | 146 | } else { |
| 126 | let report = KeyboardReport { | 147 | let report = KeyboardReport { |
| 127 | keycodes: [4, 0, 0, 0, 0, 0], | 148 | keycodes: [4, 0, 0, 0, 0, 0], |
| @@ -168,6 +189,15 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 168 | join(usb_fut, join(in_fut, out_fut)).await; | 189 | join(usb_fut, join(in_fut, out_fut)).await; |
| 169 | } | 190 | } |
| 170 | 191 | ||
| 192 | async fn enable_command() { | ||
| 193 | loop { | ||
| 194 | match USB_COMMANDS.recv().await { | ||
| 195 | Command::Enable => break, | ||
| 196 | cmd => warn!("Received command {:?} when disabled!", cmd), | ||
| 197 | } | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 171 | struct MyRequestHandler {} | 201 | struct MyRequestHandler {} |
| 172 | 202 | ||
| 173 | impl RequestHandler for MyRequestHandler { | 203 | impl RequestHandler for MyRequestHandler { |
| @@ -204,6 +234,16 @@ impl MyDeviceStateHandler { | |||
| 204 | } | 234 | } |
| 205 | 235 | ||
| 206 | impl DeviceStateHandler for MyDeviceStateHandler { | 236 | impl DeviceStateHandler for MyDeviceStateHandler { |
| 237 | fn enabled(&self, enabled: bool) { | ||
| 238 | self.configured.store(false, Ordering::Relaxed); | ||
| 239 | SUSPENDED.store(false, Ordering::Release); | ||
| 240 | if enabled { | ||
| 241 | info!("Device enabled"); | ||
| 242 | } else { | ||
| 243 | info!("Device disabled"); | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 207 | fn reset(&self) { | 247 | fn reset(&self) { |
| 208 | self.configured.store(false, Ordering::Relaxed); | 248 | self.configured.store(false, Ordering::Relaxed); |
| 209 | info!("Bus reset, the Vbus current limit is 100mA"); | 249 | info!("Bus reset, the Vbus current limit is 100mA"); |
| @@ -240,9 +280,4 @@ impl DeviceStateHandler for MyDeviceStateHandler { | |||
| 240 | } | 280 | } |
| 241 | } | 281 | } |
| 242 | } | 282 | } |
| 243 | |||
| 244 | fn disabled(&self) { | ||
| 245 | self.configured.store(false, Ordering::Relaxed); | ||
| 246 | info!("Device disabled"); | ||
| 247 | } | ||
| 248 | } | 283 | } |
