aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralexmoon <[email protected]>2022-04-06 22:10:18 -0400
committeralexmoon <[email protected]>2022-04-07 10:51:26 -0400
commit6abbfa9a92ec9feb03e30846bccb66272020601d (patch)
tree78ab2f5f6ccbb45e108520395252f0e6b45665a2
parenta1754ac8a820d9cae97cf214969faf3090b37c76 (diff)
Async-ify Driver::enable and UsbDeviceBuilder::build
-rw-r--r--embassy-nrf/src/usb.rs58
-rw-r--r--embassy-usb/src/builder.rs17
-rw-r--r--embassy-usb/src/driver.rs3
-rw-r--r--embassy-usb/src/lib.rs8
-rw-r--r--examples/nrf/src/bin/usb_hid_keyboard.rs2
-rw-r--r--examples/nrf/src/bin/usb_hid_mouse.rs2
-rw-r--r--examples/nrf/src/bin/usb_serial.rs2
-rw-r--r--examples/nrf/src/bin/usb_serial_multitask.rs2
8 files changed, 54 insertions, 40 deletions
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs
index b5e173078..0fcbe025d 100644
--- a/embassy-nrf/src/usb.rs
+++ b/embassy-nrf/src/usb.rs
@@ -140,6 +140,7 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
140 type EndpointIn = Endpoint<'d, T, In>; 140 type EndpointIn = Endpoint<'d, T, In>;
141 type ControlPipe = ControlPipe<'d, T>; 141 type ControlPipe = ControlPipe<'d, T>;
142 type Bus = Bus<'d, T>; 142 type Bus = Bus<'d, T>;
143 type EnableFuture = impl Future<Output = Self::Bus> + 'd;
143 144
144 fn alloc_endpoint_in( 145 fn alloc_endpoint_in(
145 &mut self, 146 &mut self,
@@ -191,35 +192,46 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
191 }) 192 })
192 } 193 }
193 194
194 fn enable(self) -> Self::Bus { 195 fn enable(self) -> Self::EnableFuture {
195 let regs = T::regs(); 196 async move {
196 197 let regs = T::regs();
197 errata::pre_enable();
198 198
199 regs.enable.write(|w| w.enable().enabled()); 199 errata::pre_enable();
200 200
201 // Wait until the peripheral is ready. 201 regs.enable.write(|w| w.enable().enabled());
202 while !regs.eventcause.read().ready().is_ready() {}
203 regs.eventcause.write(|w| w.ready().set_bit()); // Write 1 to clear.
204 202
205 errata::post_enable(); 203 // Wait until the peripheral is ready.
204 regs.intenset.write(|w| w.usbevent().set_bit());
205 poll_fn(|cx| {
206 BUS_WAKER.register(cx.waker());
207 if regs.eventcause.read().ready().is_ready() {
208 Poll::Ready(())
209 } else {
210 Poll::Pending
211 }
212 })
213 .await;
214 regs.eventcause.write(|w| w.ready().set_bit()); // Write 1 to clear.
206 215
207 unsafe { NVIC::unmask(pac::Interrupt::USBD) }; 216 errata::post_enable();
208 217
209 regs.intenset.write(|w| { 218 unsafe { NVIC::unmask(pac::Interrupt::USBD) };
210 w.usbreset().set_bit();
211 w.usbevent().set_bit();
212 w.epdata().set_bit();
213 w
214 });
215 // Enable the USB pullup, allowing enumeration.
216 regs.usbpullup.write(|w| w.connect().enabled());
217 trace!("enabled");
218 219
219 Bus { 220 regs.intenset.write(|w| {
220 phantom: PhantomData, 221 w.usbreset().set_bit();
221 alloc_in: self.alloc_in, 222 w.usbevent().set_bit();
222 alloc_out: self.alloc_out, 223 w.epdata().set_bit();
224 w
225 });
226 // Enable the USB pullup, allowing enumeration.
227 regs.usbpullup.write(|w| w.connect().enabled());
228 trace!("enabled");
229
230 Bus {
231 phantom: PhantomData,
232 alloc_in: self.alloc_in,
233 alloc_out: self.alloc_out,
234 }
223 } 235 }
224 } 236 }
225} 237}
diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs
index c8a9db7a4..4bbcd3e56 100644
--- a/embassy-usb/src/builder.rs
+++ b/embassy-usb/src/builder.rs
@@ -122,7 +122,7 @@ pub struct UsbDeviceBuilder<'d, D: Driver<'d>> {
122 interfaces: Vec<(u8, &'d mut dyn ControlHandler), MAX_INTERFACE_COUNT>, 122 interfaces: Vec<(u8, &'d mut dyn ControlHandler), MAX_INTERFACE_COUNT>,
123 control_buf: &'d mut [u8], 123 control_buf: &'d mut [u8],
124 124
125 bus: D, 125 driver: D,
126 next_interface_number: u8, 126 next_interface_number: u8,
127 next_string_index: u8, 127 next_string_index: u8,
128 128
@@ -139,7 +139,7 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> {
139 /// large enough for the length of the largest control request (in or out) 139 /// large enough for the length of the largest control request (in or out)
140 /// anticipated by any class added to the device. 140 /// anticipated by any class added to the device.
141 pub fn new( 141 pub fn new(
142 bus: D, 142 driver: D,
143 config: Config<'d>, 143 config: Config<'d>,
144 device_descriptor_buf: &'d mut [u8], 144 device_descriptor_buf: &'d mut [u8],
145 config_descriptor_buf: &'d mut [u8], 145 config_descriptor_buf: &'d mut [u8],
@@ -173,7 +173,7 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> {
173 bos_descriptor.bos(); 173 bos_descriptor.bos();
174 174
175 UsbDeviceBuilder { 175 UsbDeviceBuilder {
176 bus, 176 driver,
177 config, 177 config,
178 interfaces: Vec::new(), 178 interfaces: Vec::new(),
179 control_buf, 179 control_buf,
@@ -187,12 +187,12 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> {
187 } 187 }
188 188
189 /// Creates the [`UsbDevice`] instance with the configuration in this builder. 189 /// Creates the [`UsbDevice`] instance with the configuration in this builder.
190 pub fn build(mut self) -> UsbDevice<'d, D> { 190 pub async fn build(mut self) -> UsbDevice<'d, D> {
191 self.config_descriptor.end_configuration(); 191 self.config_descriptor.end_configuration();
192 self.bos_descriptor.end_bos(); 192 self.bos_descriptor.end_bos();
193 193
194 UsbDevice::build( 194 UsbDevice::build(
195 self.bus, 195 self.driver,
196 self.config, 196 self.config,
197 self.device_descriptor.into_buf(), 197 self.device_descriptor.into_buf(),
198 self.config_descriptor.into_buf(), 198 self.config_descriptor.into_buf(),
@@ -200,6 +200,7 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> {
200 self.interfaces, 200 self.interfaces,
201 self.control_buf, 201 self.control_buf,
202 ) 202 )
203 .await
203 } 204 }
204 205
205 /// Allocates a new interface number. 206 /// Allocates a new interface number.
@@ -251,7 +252,7 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> {
251 max_packet_size: u16, 252 max_packet_size: u16,
252 interval: u8, 253 interval: u8,
253 ) -> Result<D::EndpointIn, EndpointAllocError> { 254 ) -> Result<D::EndpointIn, EndpointAllocError> {
254 self.bus 255 self.driver
255 .alloc_endpoint_in(ep_addr, ep_type, max_packet_size, interval) 256 .alloc_endpoint_in(ep_addr, ep_type, max_packet_size, interval)
256 } 257 }
257 258
@@ -266,7 +267,7 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> {
266 max_packet_size: u16, 267 max_packet_size: u16,
267 interval: u8, 268 interval: u8,
268 ) -> Result<D::EndpointOut, EndpointAllocError> { 269 ) -> Result<D::EndpointOut, EndpointAllocError> {
269 self.bus 270 self.driver
270 .alloc_endpoint_out(ep_addr, ep_type, max_packet_size, interval) 271 .alloc_endpoint_out(ep_addr, ep_type, max_packet_size, interval)
271 } 272 }
272 273
@@ -306,7 +307,7 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> {
306 /// feasibly recoverable. 307 /// feasibly recoverable.
307 #[inline] 308 #[inline]
308 pub fn alloc_control_pipe(&mut self, max_packet_size: u16) -> D::ControlPipe { 309 pub fn alloc_control_pipe(&mut self, max_packet_size: u16) -> D::ControlPipe {
309 self.bus 310 self.driver
310 .alloc_control_pipe(max_packet_size) 311 .alloc_control_pipe(max_packet_size)
311 .expect("alloc_control_pipe failed") 312 .expect("alloc_control_pipe failed")
312 } 313 }
diff --git a/embassy-usb/src/driver.rs b/embassy-usb/src/driver.rs
index d3231cb45..01eb3d577 100644
--- a/embassy-usb/src/driver.rs
+++ b/embassy-usb/src/driver.rs
@@ -11,6 +11,7 @@ pub trait Driver<'a> {
11 type EndpointIn: EndpointIn + 'a; 11 type EndpointIn: EndpointIn + 'a;
12 type ControlPipe: ControlPipe + 'a; 12 type ControlPipe: ControlPipe + 'a;
13 type Bus: Bus + 'a; 13 type Bus: Bus + 'a;
14 type EnableFuture: Future<Output = Self::Bus> + 'a;
14 15
15 /// Allocates an endpoint and specified endpoint parameters. This method is called by the device 16 /// Allocates an endpoint and specified endpoint parameters. This method is called by the device
16 /// and class implementations to allocate endpoints, and can only be called before 17 /// and class implementations to allocate endpoints, and can only be called before
@@ -46,7 +47,7 @@ pub trait Driver<'a> {
46 47
47 /// Enables and initializes the USB peripheral. Soon after enabling the device will be reset, so 48 /// Enables and initializes the USB peripheral. Soon after enabling the device will be reset, so
48 /// there is no need to perform a USB reset in this method. 49 /// there is no need to perform a USB reset in this method.
49 fn enable(self) -> Self::Bus; 50 fn enable(self) -> Self::EnableFuture;
50 51
51 /// Indicates that `set_device_address` must be called before accepting the corresponding 52 /// Indicates that `set_device_address` must be called before accepting the corresponding
52 /// control transfer, not after. 53 /// control transfer, not after.
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs
index f833a86d8..e98cbdee3 100644
--- a/embassy-usb/src/lib.rs
+++ b/embassy-usb/src/lib.rs
@@ -72,7 +72,7 @@ pub struct UsbDevice<'d, D: Driver<'d>> {
72} 72}
73 73
74impl<'d, D: Driver<'d>> UsbDevice<'d, D> { 74impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
75 pub(crate) fn build( 75 pub(crate) async fn build(
76 mut driver: D, 76 mut driver: D,
77 config: Config<'d>, 77 config: Config<'d>,
78 device_descriptor: &'d [u8], 78 device_descriptor: &'d [u8],
@@ -80,17 +80,17 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
80 bos_descriptor: &'d [u8], 80 bos_descriptor: &'d [u8],
81 interfaces: Vec<(u8, &'d mut dyn ControlHandler), MAX_INTERFACE_COUNT>, 81 interfaces: Vec<(u8, &'d mut dyn ControlHandler), MAX_INTERFACE_COUNT>,
82 control_buf: &'d mut [u8], 82 control_buf: &'d mut [u8],
83 ) -> Self { 83 ) -> UsbDevice<'d, D> {
84 let control = driver 84 let control = driver
85 .alloc_control_pipe(config.max_packet_size_0 as u16) 85 .alloc_control_pipe(config.max_packet_size_0 as u16)
86 .expect("failed to alloc control endpoint"); 86 .expect("failed to alloc control endpoint");
87 87
88 // Enable the USB bus. 88 // Enable the USB bus.
89 // This prevent further allocation by consuming the driver. 89 // This prevent further allocation by consuming the driver.
90 let driver = driver.enable(); 90 let bus = driver.enable().await;
91 91
92 Self { 92 Self {
93 bus: driver, 93 bus,
94 config, 94 config,
95 control: ControlPipe::new(control), 95 control: ControlPipe::new(control),
96 device_descriptor, 96 device_descriptor,
diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs
index 51136292f..0812697e4 100644
--- a/examples/nrf/src/bin/usb_hid_keyboard.rs
+++ b/examples/nrf/src/bin/usb_hid_keyboard.rs
@@ -76,7 +76,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
76 ); 76 );
77 77
78 // Build the builder. 78 // Build the builder.
79 let mut usb = builder.build(); 79 let mut usb = builder.build().await;
80 80
81 // Run the USB device. 81 // Run the USB device.
82 let usb_fut = usb.run(); 82 let usb_fut = usb.run();
diff --git a/examples/nrf/src/bin/usb_hid_mouse.rs b/examples/nrf/src/bin/usb_hid_mouse.rs
index 741e234b6..ca9383827 100644
--- a/examples/nrf/src/bin/usb_hid_mouse.rs
+++ b/examples/nrf/src/bin/usb_hid_mouse.rs
@@ -74,7 +74,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
74 ); 74 );
75 75
76 // Build the builder. 76 // Build the builder.
77 let mut usb = builder.build(); 77 let mut usb = builder.build().await;
78 78
79 // Run the USB device. 79 // Run the USB device.
80 let usb_fut = usb.run(); 80 let usb_fut = usb.run();
diff --git a/examples/nrf/src/bin/usb_serial.rs b/examples/nrf/src/bin/usb_serial.rs
index 9437e835f..500be2ce8 100644
--- a/examples/nrf/src/bin/usb_serial.rs
+++ b/examples/nrf/src/bin/usb_serial.rs
@@ -60,7 +60,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
60 let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); 60 let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
61 61
62 // Build the builder. 62 // Build the builder.
63 let mut usb = builder.build(); 63 let mut usb = builder.build().await;
64 64
65 // Run the USB device. 65 // Run the USB device.
66 let usb_fut = usb.run(); 66 let usb_fut = usb.run();
diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs
index bef704417..1258bc53d 100644
--- a/examples/nrf/src/bin/usb_serial_multitask.rs
+++ b/examples/nrf/src/bin/usb_serial_multitask.rs
@@ -85,7 +85,7 @@ async fn main(spawner: Spawner, p: Peripherals) {
85 let class = CdcAcmClass::new(&mut builder, &mut res.serial_state, 64); 85 let class = CdcAcmClass::new(&mut builder, &mut res.serial_state, 64);
86 86
87 // Build the builder. 87 // Build the builder.
88 let usb = builder.build(); 88 let usb = builder.build().await;
89 89
90 unwrap!(spawner.spawn(usb_task(usb))); 90 unwrap!(spawner.spawn(usb_task(usb)));
91 unwrap!(spawner.spawn(echo_task(class))); 91 unwrap!(spawner.spawn(echo_task(class)));