aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authoralexmoon <[email protected]>2022-04-13 13:09:08 -0400
committeralexmoon <[email protected]>2022-04-13 14:55:02 -0400
commitff7c6b350e2338a0b1e4327f4b2eb0435468f313 (patch)
tree1a045db7348d2562b9c8a19299467a30b62e501e /examples
parent1d875fab2dc9d765ebf9f4b37112581301f2ed7e (diff)
Remove channel and make run future cancelable
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf/src/bin/usb_hid_keyboard.rs63
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;
11use embassy::executor::Spawner; 11use embassy::executor::Spawner;
12use embassy::interrupt::InterruptExt; 12use embassy::interrupt::InterruptExt;
13use embassy::time::Duration; 13use embassy::time::Duration;
14use embassy::util::select;
14use embassy_nrf::gpio::{Input, Pin, Pull}; 15use embassy_nrf::gpio::{Input, Pin, Pull};
15use embassy_nrf::interrupt; 16use embassy_nrf::interrupt;
16use embassy_nrf::pac; 17use embassy_nrf::pac;
17use embassy_nrf::usb::Driver; 18use embassy_nrf::usb::Driver;
18use embassy_nrf::Peripherals; 19use embassy_nrf::Peripherals;
19use embassy_usb::control::OutResponse; 20use embassy_usb::control::OutResponse;
20use embassy_usb::{Config, DeviceCommand, DeviceStateHandler, UsbDeviceBuilder}; 21use embassy_usb::{Config, DeviceStateHandler, UsbDeviceBuilder};
21use embassy_usb_hid::{HidClass, ReportId, RequestHandler, State}; 22use embassy_usb_hid::{HidClass, ReportId, RequestHandler, State};
22use futures::future::join; 23use futures::future::join;
23use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 24use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
@@ -25,7 +26,14 @@ use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
25use defmt_rtt as _; // global logger 26use defmt_rtt as _; // global logger
26use panic_probe as _; 27use panic_probe as _;
27 28
28static USB_COMMANDS: Channel<CriticalSectionRawMutex, DeviceCommand, 1> = Channel::new(); 29#[derive(defmt::Format)]
30enum Command {
31 Enable,
32 Disable,
33 RemoteWakeup,
34}
35
36static USB_COMMANDS: Channel<CriticalSectionRawMutex, Command, 1> = Channel::new();
29static SUSPENDED: AtomicBool = AtomicBool::new(false); 37static SUSPENDED: AtomicBool = AtomicBool::new(false);
30 38
31fn on_power_interrupt(_: *mut ()) { 39fn 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
192async 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
171struct MyRequestHandler {} 201struct MyRequestHandler {}
172 202
173impl RequestHandler for MyRequestHandler { 203impl RequestHandler for MyRequestHandler {
@@ -204,6 +234,16 @@ impl MyDeviceStateHandler {
204} 234}
205 235
206impl DeviceStateHandler for MyDeviceStateHandler { 236impl 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}