aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhuntc <[email protected]>2022-07-09 16:40:10 +1000
committerhuntc <[email protected]>2022-07-09 17:57:31 +1000
commit8785fbc6f1a1227115d3ffa6a6c19035bed6ef8c (patch)
tree9eb563b60aa6d3c86724efb7ade94f6e2f4804ac
parent81796d29b44f1b052d7631bc8677525d5aa70b50 (diff)
Trait for UsbSupply
Eliminated a signal by using a simpler trait method that returns whether VBus power is available. Also includes a UsbSupply that can be signalled for use with the nRF softdevice. Includes the requirement for waiting for power to become available.
-rw-r--r--embassy-nrf/src/usb.rs224
-rw-r--r--examples/nrf/src/bin/usb_ethernet.rs12
-rw-r--r--examples/nrf/src/bin/usb_hid_keyboard.rs71
-rw-r--r--examples/nrf/src/bin/usb_hid_mouse.rs10
-rw-r--r--examples/nrf/src/bin/usb_serial.rs8
-rw-r--r--examples/nrf/src/bin/usb_serial_multitask.rs13
6 files changed, 173 insertions, 165 deletions
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs
index 973fe16f8..9b6e6e83d 100644
--- a/embassy-nrf/src/usb.rs
+++ b/embassy-nrf/src/usb.rs
@@ -25,63 +25,163 @@ static EP0_WAKER: AtomicWaker = NEW_AW;
25static EP_IN_WAKERS: [AtomicWaker; 8] = [NEW_AW; 8]; 25static EP_IN_WAKERS: [AtomicWaker; 8] = [NEW_AW; 8];
26static EP_OUT_WAKERS: [AtomicWaker; 8] = [NEW_AW; 8]; 26static EP_OUT_WAKERS: [AtomicWaker; 8] = [NEW_AW; 8];
27static READY_ENDPOINTS: AtomicU32 = AtomicU32::new(0); 27static READY_ENDPOINTS: AtomicU32 = AtomicU32::new(0);
28static POWER_AVAILABLE: AtomicBool = AtomicBool::new(false);
29 28
30pub struct Driver<'d, T: Instance> { 29/// There are multiple ways to detect USB power. The behavior
30/// here provides a hook into determining whether it is.
31pub trait UsbSupply {
32 fn is_usb_detected(&self) -> bool;
33
34 type UsbPowerReadyFuture<'a>: Future<Output = Result<(), ()>> + 'a
35 where
36 Self: 'a;
37 fn wait_power_ready(&mut self) -> Self::UsbPowerReadyFuture<'_>;
38}
39
40pub struct Driver<'d, T: Instance, P: UsbSupply> {
31 phantom: PhantomData<&'d mut T>, 41 phantom: PhantomData<&'d mut T>,
32 alloc_in: Allocator, 42 alloc_in: Allocator,
33 alloc_out: Allocator, 43 alloc_out: Allocator,
44 usb_supply: P,
45}
46
47/// Uses the POWER peripheral to detect when power is available
48/// for USB. Unsuitable for usage with the nRF softdevice.
49#[cfg(not(feature = "_nrf5340-app"))]
50pub struct PowerUsb {}
51
52/// Can be used to signal that power is available. Particularly suited for
53/// use with the nRF softdevice.
54pub struct SignalledSupply {
55 usb_detected: AtomicBool,
56 power_ready: AtomicBool,
57}
58
59static POWER_WAKER: AtomicWaker = NEW_AW;
60
61#[cfg(not(feature = "_nrf5340-app"))]
62impl PowerUsb {
63 pub fn new(power_irq: impl Interrupt) -> Self {
64 let regs = unsafe { &*pac::POWER::ptr() };
65
66 power_irq.set_handler(Self::on_interrupt);
67 power_irq.unpend();
68 power_irq.enable();
69
70 regs.intenset
71 .write(|w| w.usbdetected().set().usbremoved().set().usbpwrrdy().set());
72
73 Self {}
74 }
75
76 #[cfg(not(feature = "_nrf5340-app"))]
77 fn on_interrupt(_: *mut ()) {
78 let regs = unsafe { &*pac::POWER::ptr() };
79
80 if regs.events_usbdetected.read().bits() != 0 {
81 regs.events_usbdetected.reset();
82 BUS_WAKER.wake();
83 }
84
85 if regs.events_usbremoved.read().bits() != 0 {
86 regs.events_usbremoved.reset();
87 BUS_WAKER.wake();
88 POWER_WAKER.wake();
89 }
90
91 if regs.events_usbpwrrdy.read().bits() != 0 {
92 regs.events_usbpwrrdy.reset();
93 POWER_WAKER.wake();
94 }
95 }
34} 96}
35 97
36impl<'d, T: Instance> Driver<'d, T> { 98#[cfg(not(feature = "_nrf5340-app"))]
37 pub fn new(_usb: impl Unborrow<Target = T> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd) -> Self { 99impl UsbSupply for PowerUsb {
38 Self::with_power_state(_usb, irq, true) 100 fn is_usb_detected(&self) -> bool {
101 let regs = unsafe { &*pac::POWER::ptr() };
102 regs.usbregstatus.read().vbusdetect().is_vbus_present()
39 } 103 }
40 104
41 /// Establish a new device that then puts the USB device into an initial power state. 105 type UsbPowerReadyFuture<'a> = impl Future<Output = Result<(), ()>> + 'a where Self: 'a;
42 /// Required when using the nRF softdevice where power is unavailable until 106 fn wait_power_ready(&mut self) -> Self::UsbPowerReadyFuture<'_> {
43 /// notified by it, at which time the the [`Self::power()`] method should then be called. 107 poll_fn(move |cx| {
44 pub fn with_power_state( 108 POWER_WAKER.register(cx.waker());
109 let regs = unsafe { &*pac::POWER::ptr() };
110
111 if regs.usbregstatus.read().outputrdy().is_ready() {
112 Poll::Ready(Ok(()))
113 } else if !self.is_usb_detected() {
114 Poll::Ready(Err(()))
115 } else {
116 Poll::Pending
117 }
118 })
119 }
120}
121
122impl SignalledSupply {
123 pub fn new(usb_detected: bool, power_ready: bool) -> Self {
124 BUS_WAKER.wake();
125
126 Self {
127 usb_detected: AtomicBool::new(usb_detected),
128 power_ready: AtomicBool::new(power_ready),
129 }
130 }
131
132 pub fn detected(&self, detected: bool) {
133 self.usb_detected.store(detected, Ordering::Relaxed);
134 self.power_ready.store(false, Ordering::Relaxed);
135 BUS_WAKER.wake();
136 POWER_WAKER.wake();
137 }
138
139 pub fn ready(&self) {
140 self.power_ready.store(true, Ordering::Relaxed);
141 POWER_WAKER.wake();
142 }
143}
144
145impl UsbSupply for SignalledSupply {
146 fn is_usb_detected(&self) -> bool {
147 self.usb_detected.load(Ordering::Relaxed)
148 }
149
150 type UsbPowerReadyFuture<'a> = impl Future<Output = Result<(), ()>> + 'a where Self: 'a;
151 fn wait_power_ready(&mut self) -> Self::UsbPowerReadyFuture<'_> {
152 poll_fn(move |cx| {
153 POWER_WAKER.register(cx.waker());
154
155 if self.power_ready.load(Ordering::Relaxed) {
156 Poll::Ready(Ok(()))
157 } else if !self.usb_detected.load(Ordering::Relaxed) {
158 Poll::Ready(Err(()))
159 } else {
160 Poll::Pending
161 }
162 })
163 }
164}
165
166impl<'d, T: Instance, P: UsbSupply> Driver<'d, T, P> {
167 pub fn new(
45 _usb: impl Unborrow<Target = T> + 'd, 168 _usb: impl Unborrow<Target = T> + 'd,
46 irq: impl Unborrow<Target = T::Interrupt> + 'd, 169 irq: impl Unborrow<Target = T::Interrupt> + 'd,
47 power_available: bool, 170 usb_supply: P,
48 ) -> Self { 171 ) -> Self {
49 unborrow!(irq); 172 unborrow!(irq);
50 irq.set_handler(Self::on_interrupt); 173 irq.set_handler(Self::on_interrupt);
51 irq.unpend(); 174 irq.unpend();
52 irq.enable(); 175 irq.enable();
53 176
54 // Initialize the bus so that it signals that power is available.
55 // Not required when using with_power_management as we then rely on the irq.
56 POWER_AVAILABLE.store(power_available, Ordering::Relaxed);
57 BUS_WAKER.wake();
58
59 Self { 177 Self {
60 phantom: PhantomData, 178 phantom: PhantomData,
61 alloc_in: Allocator::new(), 179 alloc_in: Allocator::new(),
62 alloc_out: Allocator::new(), 180 alloc_out: Allocator::new(),
181 usb_supply,
63 } 182 }
64 } 183 }
65 184
66 /// Establish a new device that then uses the POWER peripheral to
67 /// detect USB power detected/removed events are handled.
68 #[cfg(not(feature = "_nrf5340-app"))]
69 pub fn with_power_management(
70 _usb: impl Unborrow<Target = T> + 'd,
71 irq: impl Unborrow<Target = T::Interrupt> + 'd,
72 power_irq: impl Interrupt,
73 ) -> Self {
74 let regs = unsafe { &*pac::POWER::ptr() };
75
76 power_irq.set_handler(Self::on_power_interrupt);
77 power_irq.unpend();
78 power_irq.enable();
79
80 regs.intenset.write(|w| w.usbdetected().set().usbremoved().set());
81
82 Self::with_power_state(_usb, irq, regs.usbregstatus.read().vbusdetect().is_vbus_present())
83 }
84
85 fn on_interrupt(_: *mut ()) { 185 fn on_interrupt(_: *mut ()) {
86 let regs = T::regs(); 186 let regs = T::regs();
87 187
@@ -131,46 +231,13 @@ impl<'d, T: Instance> Driver<'d, T> {
131 } 231 }
132 } 232 }
133 } 233 }
134
135 #[cfg(not(feature = "_nrf5340-app"))]
136 fn on_power_interrupt(_: *mut ()) {
137 let regs = unsafe { &*pac::POWER::ptr() };
138
139 let mut power_changed = false;
140 let mut power_available = false;
141
142 if regs.events_usbdetected.read().bits() != 0 {
143 regs.events_usbdetected.reset();
144 power_changed = true;
145 power_available = true;
146 }
147
148 if regs.events_usbremoved.read().bits() != 0 {
149 regs.events_usbremoved.reset();
150 power_changed = true;
151 power_available = false;
152 }
153
154 if power_changed {
155 POWER_AVAILABLE.store(power_available, Ordering::Relaxed);
156 BUS_WAKER.wake();
157 }
158 }
159
160 /// Manually declare that USB power is available or unavailable.
161 /// Useful in scenarios where power management cannot be managed
162 /// automatically e.g. when dealing with the nrf-softdevice.
163 pub fn power(available: bool) {
164 POWER_AVAILABLE.store(available, Ordering::Relaxed);
165 BUS_WAKER.wake();
166 }
167} 234}
168 235
169impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> { 236impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P> {
170 type EndpointOut = Endpoint<'d, T, Out>; 237 type EndpointOut = Endpoint<'d, T, Out>;
171 type EndpointIn = Endpoint<'d, T, In>; 238 type EndpointIn = Endpoint<'d, T, In>;
172 type ControlPipe = ControlPipe<'d, T>; 239 type ControlPipe = ControlPipe<'d, T>;
173 type Bus = Bus<'d, T>; 240 type Bus = Bus<'d, T, P>;
174 241
175 fn alloc_endpoint_in( 242 fn alloc_endpoint_in(
176 &mut self, 243 &mut self,
@@ -209,6 +276,7 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
209 Bus { 276 Bus {
210 phantom: PhantomData, 277 phantom: PhantomData,
211 power_available: false, 278 power_available: false,
279 usb_supply: self.usb_supply,
212 }, 280 },
213 ControlPipe { 281 ControlPipe {
214 _phantom: PhantomData, 282 _phantom: PhantomData,
@@ -218,12 +286,13 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
218 } 286 }
219} 287}
220 288
221pub struct Bus<'d, T: Instance> { 289pub struct Bus<'d, T: Instance, P: UsbSupply> {
222 phantom: PhantomData<&'d mut T>, 290 phantom: PhantomData<&'d mut T>,
223 power_available: bool, 291 power_available: bool,
292 usb_supply: P,
224} 293}
225 294
226impl<'d, T: Instance> driver::Bus for Bus<'d, T> { 295impl<'d, T: Instance, P: UsbSupply> driver::Bus for Bus<'d, T, P> {
227 type EnableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; 296 type EnableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
228 type DisableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; 297 type DisableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
229 type PollFuture<'a> = impl Future<Output = Event> + 'a where Self: 'a; 298 type PollFuture<'a> = impl Future<Output = Event> + 'a where Self: 'a;
@@ -260,9 +329,14 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
260 w.epdata().set_bit(); 329 w.epdata().set_bit();
261 w 330 w
262 }); 331 });
263 // Enable the USB pullup, allowing enumeration. 332
264 regs.usbpullup.write(|w| w.connect().enabled()); 333 if self.usb_supply.wait_power_ready().await.is_ok() {
265 trace!("enabled"); 334 // Enable the USB pullup, allowing enumeration.
335 regs.usbpullup.write(|w| w.connect().enabled());
336 trace!("enabled");
337 } else {
338 trace!("usb power not ready due to usb removal");
339 }
266 } 340 }
267 } 341 }
268 342
@@ -318,7 +392,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
318 trace!("USB event: ready"); 392 trace!("USB event: ready");
319 } 393 }
320 394
321 if POWER_AVAILABLE.load(Ordering::Relaxed) != self.power_available { 395 if self.usb_supply.is_usb_detected() != self.power_available {
322 self.power_available = !self.power_available; 396 self.power_available = !self.power_available;
323 if self.power_available { 397 if self.power_available {
324 trace!("Power event: available"); 398 trace!("Power event: available");
diff --git a/examples/nrf/src/bin/usb_ethernet.rs b/examples/nrf/src/bin/usb_ethernet.rs
index a20321fe8..e57cdaf63 100644
--- a/examples/nrf/src/bin/usb_ethernet.rs
+++ b/examples/nrf/src/bin/usb_ethernet.rs
@@ -15,14 +15,14 @@ use embassy::util::Forever;
15use embassy_net::tcp::TcpSocket; 15use embassy_net::tcp::TcpSocket;
16use embassy_net::{PacketBox, PacketBoxExt, PacketBuf, Stack, StackResources}; 16use embassy_net::{PacketBox, PacketBoxExt, PacketBuf, Stack, StackResources};
17use embassy_nrf::rng::Rng; 17use embassy_nrf::rng::Rng;
18use embassy_nrf::usb::Driver; 18use embassy_nrf::usb::{Driver, PowerUsb};
19use embassy_nrf::{interrupt, pac, peripherals, Peripherals}; 19use embassy_nrf::{interrupt, pac, peripherals, Peripherals};
20use embassy_usb::{Builder, Config, UsbDevice}; 20use embassy_usb::{Builder, Config, UsbDevice};
21use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State}; 21use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State};
22use embedded_io::asynch::{Read, Write}; 22use embedded_io::asynch::{Read, Write};
23use {defmt_rtt as _, panic_probe as _}; 23use {defmt_rtt as _, panic_probe as _};
24 24
25type MyDriver = Driver<'static, peripherals::USBD>; 25type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>;
26 26
27macro_rules! forever { 27macro_rules! forever {
28 ($val:expr) => {{ 28 ($val:expr) => {{
@@ -84,19 +84,15 @@ async fn net_task(stack: &'static Stack<Device>) -> ! {
84#[embassy::main] 84#[embassy::main]
85async fn main(spawner: Spawner, p: Peripherals) { 85async fn main(spawner: Spawner, p: Peripherals) {
86 let clock: pac::CLOCK = unsafe { mem::transmute(()) }; 86 let clock: pac::CLOCK = unsafe { mem::transmute(()) };
87 let power: pac::POWER = unsafe { mem::transmute(()) };
88 87
89 info!("Enabling ext hfosc..."); 88 info!("Enabling ext hfosc...");
90 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); 89 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
91 while clock.events_hfclkstarted.read().bits() != 1 {} 90 while clock.events_hfclkstarted.read().bits() != 1 {}
92 91
93 info!("Waiting for vbus...");
94 while !power.usbregstatus.read().vbusdetect().is_vbus_present() {}
95 info!("vbus OK");
96
97 // Create the driver, from the HAL. 92 // Create the driver, from the HAL.
98 let irq = interrupt::take!(USBD); 93 let irq = interrupt::take!(USBD);
99 let driver = Driver::new(p.USBD, irq); 94 let power_irq = interrupt::take!(POWER_CLOCK);
95 let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
100 96
101 // Create embassy-usb Config 97 // Create embassy-usb Config
102 let mut config = Config::new(0xc0de, 0xcafe); 98 let mut config = Config::new(0xc0de, 0xcafe);
diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs
index 97ec861d8..539ae6f16 100644
--- a/examples/nrf/src/bin/usb_hid_keyboard.rs
+++ b/examples/nrf/src/bin/usb_hid_keyboard.rs
@@ -10,10 +10,9 @@ use defmt::*;
10use embassy::channel::signal::Signal; 10use embassy::channel::signal::Signal;
11use embassy::executor::Spawner; 11use embassy::executor::Spawner;
12use embassy::time::Duration; 12use embassy::time::Duration;
13use embassy::util::{select, select3, Either, Either3}; 13use embassy::util::{select, Either};
14use embassy_nrf::gpio::{Input, Pin, Pull}; 14use embassy_nrf::gpio::{Input, Pin, Pull};
15use embassy_nrf::interrupt::InterruptExt; 15use embassy_nrf::usb::{Driver, PowerUsb};
16use embassy_nrf::usb::Driver;
17use embassy_nrf::{interrupt, pac, Peripherals}; 16use embassy_nrf::{interrupt, pac, Peripherals};
18use embassy_usb::control::OutResponse; 17use embassy_usb::control::OutResponse;
19use embassy_usb::{Builder, Config, DeviceStateHandler}; 18use embassy_usb::{Builder, Config, DeviceStateHandler};
@@ -22,29 +21,11 @@ use futures::future::join;
22use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 21use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
23use {defmt_rtt as _, panic_probe as _}; 22use {defmt_rtt as _, panic_probe as _};
24 23
25static ENABLE_USB: Signal<bool> = Signal::new();
26static SUSPENDED: AtomicBool = AtomicBool::new(false); 24static SUSPENDED: AtomicBool = AtomicBool::new(false);
27 25
28fn on_power_interrupt(_: *mut ()) {
29 let regs = unsafe { &*pac::POWER::ptr() };
30
31 if regs.events_usbdetected.read().bits() != 0 {
32 regs.events_usbdetected.reset();
33 info!("Vbus detected, enabling USB...");
34 ENABLE_USB.signal(true);
35 }
36
37 if regs.events_usbremoved.read().bits() != 0 {
38 regs.events_usbremoved.reset();
39 info!("Vbus removed, disabling USB...");
40 ENABLE_USB.signal(false);
41 }
42}
43
44#[embassy::main] 26#[embassy::main]
45async fn main(_spawner: Spawner, p: Peripherals) { 27async fn main(_spawner: Spawner, p: Peripherals) {
46 let clock: pac::CLOCK = unsafe { mem::transmute(()) }; 28 let clock: pac::CLOCK = unsafe { mem::transmute(()) };
47 let power: pac::POWER = unsafe { mem::transmute(()) };
48 29
49 info!("Enabling ext hfosc..."); 30 info!("Enabling ext hfosc...");
50 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); 31 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
@@ -52,7 +33,8 @@ async fn main(_spawner: Spawner, p: Peripherals) {
52 33
53 // Create the driver, from the HAL. 34 // Create the driver, from the HAL.
54 let irq = interrupt::take!(USBD); 35 let irq = interrupt::take!(USBD);
55 let driver = Driver::new(p.USBD, irq); 36 let power_irq = interrupt::take!(POWER_CLOCK);
37 let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
56 38
57 // Create embassy-usb Config 39 // Create embassy-usb Config
58 let mut config = Config::new(0xc0de, 0xcafe); 40 let mut config = Config::new(0xc0de, 0xcafe);
@@ -100,31 +82,11 @@ async fn main(_spawner: Spawner, p: Peripherals) {
100 82
101 // Run the USB device. 83 // Run the USB device.
102 let usb_fut = async { 84 let usb_fut = async {
103 enable_command().await;
104 loop { 85 loop {
105 match select(usb.run_until_suspend(), ENABLE_USB.wait()).await { 86 usb.run_until_suspend().await;
106 Either::First(_) => {} 87 match select(usb.wait_resume(), remote_wakeup.wait()).await {
107 Either::Second(enable) => { 88 Either::First(_) => (),
108 if enable { 89 Either::Second(_) => unwrap!(usb.remote_wakeup().await),
109 warn!("Enable when already enabled!");
110 } else {
111 usb.disable().await;
112 enable_command().await;
113 }
114 }
115 }
116
117 match select3(usb.wait_resume(), ENABLE_USB.wait(), remote_wakeup.wait()).await {
118 Either3::First(_) => (),
119 Either3::Second(enable) => {
120 if enable {
121 warn!("Enable when already enabled!");
122 } else {
123 usb.disable().await;
124 enable_command().await;
125 }
126 }
127 Either3::Third(_) => unwrap!(usb.remote_wakeup().await),
128 } 90 }
129 } 91 }
130 }; 92 };
@@ -174,28 +136,11 @@ async fn main(_spawner: Spawner, p: Peripherals) {
174 reader.run(false, &request_handler).await; 136 reader.run(false, &request_handler).await;
175 }; 137 };
176 138
177 let power_irq = interrupt::take!(POWER_CLOCK);
178 power_irq.set_handler(on_power_interrupt);
179 power_irq.unpend();
180 power_irq.enable();
181
182 power.intenset.write(|w| w.usbdetected().set().usbremoved().set());
183
184 // Run everything concurrently. 139 // Run everything concurrently.
185 // If we had made everything `'static` above instead, we could do this using separate tasks instead. 140 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
186 join(usb_fut, join(in_fut, out_fut)).await; 141 join(usb_fut, join(in_fut, out_fut)).await;
187} 142}
188 143
189async fn enable_command() {
190 loop {
191 if ENABLE_USB.wait().await {
192 break;
193 } else {
194 warn!("Received disable signal when already disabled!");
195 }
196 }
197}
198
199struct MyRequestHandler {} 144struct MyRequestHandler {}
200 145
201impl RequestHandler for MyRequestHandler { 146impl RequestHandler for MyRequestHandler {
diff --git a/examples/nrf/src/bin/usb_hid_mouse.rs b/examples/nrf/src/bin/usb_hid_mouse.rs
index 9c44e5cc8..516e7ea95 100644
--- a/examples/nrf/src/bin/usb_hid_mouse.rs
+++ b/examples/nrf/src/bin/usb_hid_mouse.rs
@@ -8,7 +8,7 @@ use core::mem;
8use defmt::*; 8use defmt::*;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 10use embassy::time::{Duration, Timer};
11use embassy_nrf::usb::Driver; 11use embassy_nrf::usb::{Driver, PowerUsb};
12use embassy_nrf::{interrupt, pac, Peripherals}; 12use embassy_nrf::{interrupt, pac, Peripherals};
13use embassy_usb::control::OutResponse; 13use embassy_usb::control::OutResponse;
14use embassy_usb::{Builder, Config}; 14use embassy_usb::{Builder, Config};
@@ -20,19 +20,15 @@ use {defmt_rtt as _, panic_probe as _};
20#[embassy::main] 20#[embassy::main]
21async fn main(_spawner: Spawner, p: Peripherals) { 21async fn main(_spawner: Spawner, p: Peripherals) {
22 let clock: pac::CLOCK = unsafe { mem::transmute(()) }; 22 let clock: pac::CLOCK = unsafe { mem::transmute(()) };
23 let power: pac::POWER = unsafe { mem::transmute(()) };
24 23
25 info!("Enabling ext hfosc..."); 24 info!("Enabling ext hfosc...");
26 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); 25 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
27 while clock.events_hfclkstarted.read().bits() != 1 {} 26 while clock.events_hfclkstarted.read().bits() != 1 {}
28 27
29 info!("Waiting for vbus...");
30 while !power.usbregstatus.read().vbusdetect().is_vbus_present() {}
31 info!("vbus OK");
32
33 // Create the driver, from the HAL. 28 // Create the driver, from the HAL.
34 let irq = interrupt::take!(USBD); 29 let irq = interrupt::take!(USBD);
35 let driver = Driver::new(p.USBD, irq); 30 let power_irq = interrupt::take!(POWER_CLOCK);
31 let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
36 32
37 // Create embassy-usb Config 33 // Create embassy-usb Config
38 let mut config = Config::new(0xc0de, 0xcafe); 34 let mut config = Config::new(0xc0de, 0xcafe);
diff --git a/examples/nrf/src/bin/usb_serial.rs b/examples/nrf/src/bin/usb_serial.rs
index 7c1d8cbb8..d2200dc5d 100644
--- a/examples/nrf/src/bin/usb_serial.rs
+++ b/examples/nrf/src/bin/usb_serial.rs
@@ -7,7 +7,7 @@ use core::mem;
7 7
8use defmt::{info, panic}; 8use defmt::{info, panic};
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy_nrf::usb::{Driver, Instance}; 10use embassy_nrf::usb::{Driver, Instance, PowerUsb, UsbSupply};
11use embassy_nrf::{interrupt, pac, Peripherals}; 11use embassy_nrf::{interrupt, pac, Peripherals};
12use embassy_usb::driver::EndpointError; 12use embassy_usb::driver::EndpointError;
13use embassy_usb::{Builder, Config}; 13use embassy_usb::{Builder, Config};
@@ -26,7 +26,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
26 // Create the driver, from the HAL. 26 // Create the driver, from the HAL.
27 let irq = interrupt::take!(USBD); 27 let irq = interrupt::take!(USBD);
28 let power_irq = interrupt::take!(POWER_CLOCK); 28 let power_irq = interrupt::take!(POWER_CLOCK);
29 let driver = Driver::with_power_management(p.USBD, irq, power_irq); 29 let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
30 30
31 // Create embassy-usb Config 31 // Create embassy-usb Config
32 let mut config = Config::new(0xc0de, 0xcafe); 32 let mut config = Config::new(0xc0de, 0xcafe);
@@ -97,7 +97,9 @@ impl From<EndpointError> for Disconnected {
97 } 97 }
98} 98}
99 99
100async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { 100async fn echo<'d, T: Instance + 'd, P: UsbSupply + 'd>(
101 class: &mut CdcAcmClass<'d, Driver<'d, T, P>>,
102) -> Result<(), Disconnected> {
101 let mut buf = [0; 64]; 103 let mut buf = [0; 64];
102 loop { 104 loop {
103 let n = class.read_packet(&mut buf).await?; 105 let n = class.read_packet(&mut buf).await?;
diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs
index dc503e67c..3806da5a0 100644
--- a/examples/nrf/src/bin/usb_serial_multitask.rs
+++ b/examples/nrf/src/bin/usb_serial_multitask.rs
@@ -8,14 +8,14 @@ use core::mem;
8use defmt::{info, panic, unwrap}; 8use defmt::{info, panic, unwrap};
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::util::Forever; 10use embassy::util::Forever;
11use embassy_nrf::usb::Driver; 11use embassy_nrf::usb::{Driver, PowerUsb};
12use embassy_nrf::{interrupt, pac, peripherals, Peripherals}; 12use embassy_nrf::{interrupt, pac, peripherals, Peripherals};
13use embassy_usb::driver::EndpointError; 13use embassy_usb::driver::EndpointError;
14use embassy_usb::{Builder, Config, UsbDevice}; 14use embassy_usb::{Builder, Config, UsbDevice};
15use embassy_usb_serial::{CdcAcmClass, State}; 15use embassy_usb_serial::{CdcAcmClass, State};
16use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
17 17
18type MyDriver = Driver<'static, peripherals::USBD>; 18type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>;
19 19
20#[embassy::task] 20#[embassy::task]
21async fn usb_task(mut device: UsbDevice<'static, MyDriver>) { 21async fn usb_task(mut device: UsbDevice<'static, MyDriver>) {
@@ -35,19 +35,14 @@ async fn echo_task(mut class: CdcAcmClass<'static, MyDriver>) {
35#[embassy::main] 35#[embassy::main]
36async fn main(spawner: Spawner, p: Peripherals) { 36async fn main(spawner: Spawner, p: Peripherals) {
37 let clock: pac::CLOCK = unsafe { mem::transmute(()) }; 37 let clock: pac::CLOCK = unsafe { mem::transmute(()) };
38 let power: pac::POWER = unsafe { mem::transmute(()) };
39 38
40 info!("Enabling ext hfosc..."); 39 info!("Enabling ext hfosc...");
41 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); 40 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
42 while clock.events_hfclkstarted.read().bits() != 1 {} 41 while clock.events_hfclkstarted.read().bits() != 1 {}
43
44 info!("Waiting for vbus...");
45 while !power.usbregstatus.read().vbusdetect().is_vbus_present() {}
46 info!("vbus OK");
47
48 // Create the driver, from the HAL. 42 // Create the driver, from the HAL.
49 let irq = interrupt::take!(USBD); 43 let irq = interrupt::take!(USBD);
50 let driver = Driver::new(p.USBD, irq); 44 let power_irq = interrupt::take!(POWER_CLOCK);
45 let driver = Driver::new(p.USBD, irq, PowerUsb::new(power_irq));
51 46
52 // Create embassy-usb Config 47 // Create embassy-usb Config
53 let mut config = Config::new(0xc0de, 0xcafe); 48 let mut config = Config::new(0xc0de, 0xcafe);