diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/nrf/src/bin/usb_hid_keyboard.rs | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs index 32659dfbb..5f03f5126 100644 --- a/examples/nrf/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf/src/bin/usb_hid_keyboard.rs | |||
| @@ -6,12 +6,11 @@ | |||
| 6 | use core::mem; | 6 | use core::mem; |
| 7 | use core::sync::atomic::{AtomicBool, Ordering}; | 7 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 8 | use defmt::*; | 8 | use defmt::*; |
| 9 | use embassy::blocking_mutex::raw::CriticalSectionRawMutex; | 9 | use embassy::channel::Signal; |
| 10 | use embassy::channel::Channel; | ||
| 11 | use embassy::executor::Spawner; | 10 | use embassy::executor::Spawner; |
| 12 | use embassy::interrupt::InterruptExt; | 11 | use embassy::interrupt::InterruptExt; |
| 13 | use embassy::time::Duration; | 12 | use embassy::time::Duration; |
| 14 | use embassy::util::select; | 13 | use embassy::util::{select, select3, Either, Either3}; |
| 15 | use embassy_nrf::gpio::{Input, Pin, Pull}; | 14 | use embassy_nrf::gpio::{Input, Pin, Pull}; |
| 16 | use embassy_nrf::interrupt; | 15 | use embassy_nrf::interrupt; |
| 17 | use embassy_nrf::pac; | 16 | use embassy_nrf::pac; |
| @@ -26,14 +25,7 @@ use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; | |||
| 26 | use defmt_rtt as _; // global logger | 25 | use defmt_rtt as _; // global logger |
| 27 | use panic_probe as _; | 26 | use panic_probe as _; |
| 28 | 27 | ||
| 29 | #[derive(defmt::Format)] | 28 | static ENABLE_USB: Signal<bool> = Signal::new(); |
| 30 | enum Command { | ||
| 31 | Enable, | ||
| 32 | Disable, | ||
| 33 | RemoteWakeup, | ||
| 34 | } | ||
| 35 | |||
| 36 | static USB_COMMANDS: Channel<CriticalSectionRawMutex, Command, 1> = Channel::new(); | ||
| 37 | static SUSPENDED: AtomicBool = AtomicBool::new(false); | 29 | static SUSPENDED: AtomicBool = AtomicBool::new(false); |
| 38 | 30 | ||
| 39 | fn on_power_interrupt(_: *mut ()) { | 31 | fn on_power_interrupt(_: *mut ()) { |
| @@ -42,17 +34,13 @@ fn on_power_interrupt(_: *mut ()) { | |||
| 42 | if regs.events_usbdetected.read().bits() != 0 { | 34 | if regs.events_usbdetected.read().bits() != 0 { |
| 43 | regs.events_usbdetected.reset(); | 35 | regs.events_usbdetected.reset(); |
| 44 | info!("Vbus detected, enabling USB..."); | 36 | info!("Vbus detected, enabling USB..."); |
| 45 | if USB_COMMANDS.try_send(Command::Enable).is_err() { | 37 | ENABLE_USB.signal(true); |
| 46 | warn!("Failed to send enable command to USB channel"); | ||
| 47 | } | ||
| 48 | } | 38 | } |
| 49 | 39 | ||
| 50 | if regs.events_usbremoved.read().bits() != 0 { | 40 | if regs.events_usbremoved.read().bits() != 0 { |
| 51 | regs.events_usbremoved.reset(); | 41 | regs.events_usbremoved.reset(); |
| 52 | info!("Vbus removed, disabling USB..."); | 42 | info!("Vbus removed, disabling USB..."); |
| 53 | if USB_COMMANDS.try_send(Command::Disable).is_err() { | 43 | ENABLE_USB.signal(false); |
| 54 | warn!("Failed to send disable command to USB channel"); | ||
| 55 | }; | ||
| 56 | } | 44 | } |
| 57 | } | 45 | } |
| 58 | 46 | ||
| @@ -112,20 +100,35 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 112 | // Build the builder. | 100 | // Build the builder. |
| 113 | let mut usb = builder.build(); | 101 | let mut usb = builder.build(); |
| 114 | 102 | ||
| 103 | let remote_wakeup = Signal::new(); | ||
| 104 | |||
| 115 | // Run the USB device. | 105 | // Run the USB device. |
| 116 | let usb_fut = async { | 106 | let usb_fut = async { |
| 117 | enable_command().await; | 107 | enable_command().await; |
| 118 | loop { | 108 | loop { |
| 119 | match select(usb.run(), USB_COMMANDS.recv()).await { | 109 | match select(usb.run_until_suspend(), ENABLE_USB.wait()).await { |
| 120 | embassy::util::Either::First(_) => defmt::unreachable!(), | 110 | Either::First(_) => {} |
| 121 | embassy::util::Either::Second(cmd) => match cmd { | 111 | Either::Second(enable) => { |
| 122 | Command::Enable => warn!("Enable when already enabled!"), | 112 | if enable { |
| 123 | Command::Disable => { | 113 | warn!("Enable when already enabled!"); |
| 114 | } else { | ||
| 115 | usb.disable().await; | ||
| 116 | enable_command().await; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | match select3(usb.wait_resume(), ENABLE_USB.wait(), remote_wakeup.wait()).await { | ||
| 122 | Either3::First(_) => (), | ||
| 123 | Either3::Second(enable) => { | ||
| 124 | if enable { | ||
| 125 | warn!("Enable when already enabled!"); | ||
| 126 | } else { | ||
| 124 | usb.disable().await; | 127 | usb.disable().await; |
| 125 | enable_command().await; | 128 | enable_command().await; |
| 126 | } | 129 | } |
| 127 | Command::RemoteWakeup => unwrap!(usb.remote_wakeup().await), | 130 | } |
| 128 | }, | 131 | Either3::Third(_) => unwrap!(usb.remote_wakeup().await), |
| 129 | } | 132 | } |
| 130 | } | 133 | } |
| 131 | }; | 134 | }; |
| @@ -142,7 +145,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 142 | 145 | ||
| 143 | if SUSPENDED.load(Ordering::Acquire) { | 146 | if SUSPENDED.load(Ordering::Acquire) { |
| 144 | info!("Triggering remote wakeup"); | 147 | info!("Triggering remote wakeup"); |
| 145 | USB_COMMANDS.send(Command::RemoteWakeup).await; | 148 | remote_wakeup.signal(()); |
| 146 | } else { | 149 | } else { |
| 147 | let report = KeyboardReport { | 150 | let report = KeyboardReport { |
| 148 | keycodes: [4, 0, 0, 0, 0, 0], | 151 | keycodes: [4, 0, 0, 0, 0, 0], |
| @@ -191,9 +194,10 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 191 | 194 | ||
| 192 | async fn enable_command() { | 195 | async fn enable_command() { |
| 193 | loop { | 196 | loop { |
| 194 | match USB_COMMANDS.recv().await { | 197 | if ENABLE_USB.wait().await { |
| 195 | Command::Enable => break, | 198 | break; |
| 196 | cmd => warn!("Received command {:?} when disabled!", cmd), | 199 | } else { |
| 200 | warn!("Received disable signal when already disabled!"); | ||
| 197 | } | 201 | } |
| 198 | } | 202 | } |
| 199 | } | 203 | } |
