aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-08-24 23:46:07 +0200
committerDario Nieuwenhuis <[email protected]>2022-08-25 00:03:55 +0200
commita730e2cd0f4f282a78cc5d9897c584ec4f5a44a3 (patch)
treebae14ab23330d99b06c462746615dc2efbc45ad8 /embassy-rp/src
parentf11aa9720be6b5f608becb3472e4fd13de324080 (diff)
rp: add usb device support.
Diffstat (limited to 'embassy-rp/src')
-rw-r--r--embassy-rp/src/lib.rs37
-rw-r--r--embassy-rp/src/usb.rs846
2 files changed, 883 insertions, 0 deletions
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 8c053a4f7..bc31b4798 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -10,6 +10,8 @@ pub mod interrupt;
10pub mod spi; 10pub mod spi;
11pub mod timer; 11pub mod timer;
12pub mod uart; 12pub mod uart;
13#[cfg(feature = "nightly")]
14pub mod usb;
13 15
14mod clocks; 16mod clocks;
15mod reset; 17mod reset;
@@ -80,6 +82,8 @@ embassy_hal_common::peripherals! {
80 DMA_CH9, 82 DMA_CH9,
81 DMA_CH10, 83 DMA_CH10,
82 DMA_CH11, 84 DMA_CH11,
85
86 USB,
83} 87}
84 88
85#[link_section = ".boot2"] 89#[link_section = ".boot2"]
@@ -109,3 +113,36 @@ pub fn init(_config: config::Config) -> Peripherals {
109 113
110 peripherals 114 peripherals
111} 115}
116
117/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes.
118trait RegExt<T: Copy> {
119 unsafe fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
120 unsafe fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
121 unsafe fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
122}
123
124impl<T: Default + Copy, A: pac::common::Write> RegExt<T> for pac::common::Reg<T, A> {
125 unsafe fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
126 let mut val = Default::default();
127 let res = f(&mut val);
128 let ptr = (self.ptr() as *mut u8).add(0x1000) as *mut T;
129 ptr.write_volatile(val);
130 res
131 }
132
133 unsafe fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
134 let mut val = Default::default();
135 let res = f(&mut val);
136 let ptr = (self.ptr() as *mut u8).add(0x2000) as *mut T;
137 ptr.write_volatile(val);
138 res
139 }
140
141 unsafe fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
142 let mut val = Default::default();
143 let res = f(&mut val);
144 let ptr = (self.ptr() as *mut u8).add(0x3000) as *mut T;
145 ptr.write_volatile(val);
146 res
147 }
148}
diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs
new file mode 100644
index 000000000..82eafdefd
--- /dev/null
+++ b/embassy-rp/src/usb.rs
@@ -0,0 +1,846 @@
1use core::marker::PhantomData;
2use core::slice;
3use core::sync::atomic::Ordering;
4use core::task::Poll;
5
6use atomic_polyfill::compiler_fence;
7use embassy_hal_common::into_ref;
8use embassy_sync::waitqueue::AtomicWaker;
9use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported};
10use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
11use futures::future::poll_fn;
12use futures::Future;
13
14use crate::interrupt::{Interrupt, InterruptExt};
15use crate::{pac, peripherals, Peripheral, RegExt};
16
17pub(crate) mod sealed {
18 pub trait Instance {
19 fn regs() -> crate::pac::usb::Usb;
20 fn dpram() -> crate::pac::usb_dpram::UsbDpram;
21 }
22}
23
24pub trait Instance: sealed::Instance + 'static {
25 type Interrupt: Interrupt;
26}
27
28impl crate::usb::sealed::Instance for peripherals::USB {
29 fn regs() -> pac::usb::Usb {
30 pac::USBCTRL_REGS
31 }
32 fn dpram() -> crate::pac::usb_dpram::UsbDpram {
33 pac::USBCTRL_DPRAM
34 }
35}
36
37impl crate::usb::Instance for peripherals::USB {
38 type Interrupt = crate::interrupt::USBCTRL_IRQ;
39}
40
41const EP_COUNT: usize = 16;
42const EP_MEMORY_SIZE: usize = 4096;
43const EP_MEMORY: *mut u8 = pac::USBCTRL_DPRAM.0;
44
45const NEW_AW: AtomicWaker = AtomicWaker::new();
46static BUS_WAKER: AtomicWaker = NEW_AW;
47static EP_IN_WAKERS: [AtomicWaker; EP_COUNT] = [NEW_AW; EP_COUNT];
48static EP_OUT_WAKERS: [AtomicWaker; EP_COUNT] = [NEW_AW; EP_COUNT];
49
50struct EndpointBuffer<T: Instance> {
51 addr: u16,
52 len: u16,
53 _phantom: PhantomData<T>,
54}
55
56impl<T: Instance> EndpointBuffer<T> {
57 const fn new(addr: u16, len: u16) -> Self {
58 Self {
59 addr,
60 len,
61 _phantom: PhantomData,
62 }
63 }
64
65 fn read(&mut self, buf: &mut [u8]) {
66 assert!(buf.len() <= self.len as usize);
67 compiler_fence(Ordering::SeqCst);
68 let mem = unsafe { slice::from_raw_parts(EP_MEMORY.add(self.addr as _), buf.len()) };
69 buf.copy_from_slice(mem);
70 compiler_fence(Ordering::SeqCst);
71 }
72
73 fn write(&mut self, buf: &[u8]) {
74 assert!(buf.len() <= self.len as usize);
75 compiler_fence(Ordering::SeqCst);
76 let mem = unsafe { slice::from_raw_parts_mut(EP_MEMORY.add(self.addr as _), buf.len()) };
77 mem.copy_from_slice(buf);
78 compiler_fence(Ordering::SeqCst);
79 }
80}
81
82#[derive(Debug, Clone, Copy)]
83#[cfg_attr(feature = "defmt", derive(defmt::Format))]
84struct EndpointData {
85 ep_type: EndpointType, // only valid if used
86 max_packet_size: u16,
87 used: bool,
88}
89
90impl EndpointData {
91 const fn new() -> Self {
92 Self {
93 ep_type: EndpointType::Bulk,
94 max_packet_size: 0,
95 used: false,
96 }
97 }
98}
99
100pub struct Driver<'d, T: Instance> {
101 phantom: PhantomData<&'d mut T>,
102 ep_in: [EndpointData; EP_COUNT],
103 ep_out: [EndpointData; EP_COUNT],
104 ep_mem_free: u16, // first free address in EP mem, in bytes.
105}
106
107impl<'d, T: Instance> Driver<'d, T> {
108 pub fn new(_usb: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd) -> Self {
109 into_ref!(irq);
110 irq.set_handler(Self::on_interrupt);
111 irq.unpend();
112 irq.enable();
113
114 let regs = T::regs();
115 unsafe {
116 // zero fill regs
117 let p = regs.0 as *mut u32;
118 for i in 0..0x9c / 4 {
119 p.add(i).write_volatile(0)
120 }
121
122 // zero fill epmem
123 let p = EP_MEMORY as *mut u32;
124 for i in 0..0x100 / 4 {
125 p.add(i).write_volatile(0)
126 }
127
128 regs.usb_muxing().write(|w| {
129 w.set_to_phy(true);
130 w.set_softcon(true);
131 });
132 regs.usb_pwr().write(|w| {
133 w.set_vbus_detect(true);
134 w.set_vbus_detect_override_en(true);
135 });
136 regs.main_ctrl().write(|w| {
137 w.set_controller_en(true);
138 });
139 }
140
141 // Initialize the bus so that it signals that power is available
142 BUS_WAKER.wake();
143
144 Self {
145 phantom: PhantomData,
146 ep_in: [EndpointData::new(); EP_COUNT],
147 ep_out: [EndpointData::new(); EP_COUNT],
148 ep_mem_free: 0x180, // data buffer region
149 }
150 }
151
152 fn on_interrupt(_: *mut ()) {
153 unsafe {
154 let regs = T::regs();
155 //let x = regs.istr().read().0;
156 //trace!("USB IRQ: {:08x}", x);
157
158 let ints = regs.ints().read();
159
160 if ints.bus_reset() {
161 regs.inte().write_clear(|w| w.set_bus_reset(true));
162 BUS_WAKER.wake();
163 }
164 if ints.dev_resume_from_host() {
165 regs.inte().write_clear(|w| w.set_dev_resume_from_host(true));
166 BUS_WAKER.wake();
167 }
168 if ints.dev_suspend() {
169 regs.inte().write_clear(|w| w.set_dev_suspend(true));
170 BUS_WAKER.wake();
171 }
172 if ints.setup_req() {
173 regs.inte().write_clear(|w| w.set_setup_req(true));
174 EP_OUT_WAKERS[0].wake();
175 }
176
177 if ints.buff_status() {
178 let s = regs.buff_status().read();
179 regs.buff_status().write_value(s);
180
181 for i in 0..EP_COUNT {
182 if s.ep_in(i) {
183 EP_IN_WAKERS[i].wake();
184 }
185 if s.ep_out(i) {
186 EP_OUT_WAKERS[i].wake();
187 }
188 }
189 }
190 }
191 }
192
193 fn alloc_endpoint<D: Dir>(
194 &mut self,
195 ep_type: EndpointType,
196 max_packet_size: u16,
197 interval: u8,
198 ) -> Result<Endpoint<'d, T, D>, driver::EndpointAllocError> {
199 trace!(
200 "allocating type={:?} mps={:?} interval={}, dir={:?}",
201 ep_type,
202 max_packet_size,
203 interval,
204 D::dir()
205 );
206
207 let alloc = match D::dir() {
208 UsbDirection::Out => &mut self.ep_out,
209 UsbDirection::In => &mut self.ep_in,
210 };
211
212 let index = alloc.iter_mut().enumerate().find(|(i, ep)| {
213 if *i == 0 {
214 return false; // reserved for control pipe
215 }
216 !ep.used
217 });
218
219 let (index, ep) = index.ok_or(EndpointAllocError)?;
220 assert!(!ep.used);
221
222 if max_packet_size > 64 {
223 warn!("max_packet_size too high: {}", max_packet_size);
224 return Err(EndpointAllocError);
225 }
226
227 // ep mem addrs must be 64-byte aligned, so there's no point in trying
228 // to allocate smaller chunks to save memory.
229 let len = 64;
230
231 let addr = self.ep_mem_free;
232 if addr + len > EP_MEMORY_SIZE as _ {
233 warn!("Endpoint memory full");
234 return Err(EndpointAllocError);
235 }
236 self.ep_mem_free += len;
237
238 let buf = EndpointBuffer {
239 addr,
240 len,
241 _phantom: PhantomData,
242 };
243
244 trace!(" index={} addr={} len={}", index, buf.addr, buf.len);
245
246 ep.ep_type = ep_type;
247 ep.used = true;
248 ep.max_packet_size = max_packet_size;
249
250 let ep_type_reg = match ep_type {
251 EndpointType::Bulk => pac::usb_dpram::vals::EpControlEndpointType::BULK,
252 EndpointType::Control => pac::usb_dpram::vals::EpControlEndpointType::CONTROL,
253 EndpointType::Interrupt => pac::usb_dpram::vals::EpControlEndpointType::INTERRUPT,
254 EndpointType::Isochronous => pac::usb_dpram::vals::EpControlEndpointType::ISOCHRONOUS,
255 };
256
257 match D::dir() {
258 UsbDirection::Out => unsafe {
259 T::dpram().ep_out_control(index - 1).write(|w| {
260 w.set_enable(false);
261 w.set_buffer_address(addr);
262 w.set_interrupt_per_buff(true);
263 w.set_endpoint_type(ep_type_reg);
264 })
265 },
266 UsbDirection::In => unsafe {
267 T::dpram().ep_in_control(index - 1).write(|w| {
268 w.set_enable(false);
269 w.set_buffer_address(addr);
270 w.set_interrupt_per_buff(true);
271 w.set_endpoint_type(ep_type_reg);
272 })
273 },
274 }
275
276 Ok(Endpoint {
277 _phantom: PhantomData,
278 info: EndpointInfo {
279 addr: EndpointAddress::from_parts(index, D::dir()),
280 ep_type,
281 max_packet_size,
282 interval,
283 },
284 buf,
285 })
286 }
287}
288
289impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
290 type EndpointOut = Endpoint<'d, T, Out>;
291 type EndpointIn = Endpoint<'d, T, In>;
292 type ControlPipe = ControlPipe<'d, T>;
293 type Bus = Bus<'d, T>;
294
295 fn alloc_endpoint_in(
296 &mut self,
297 ep_type: EndpointType,
298 max_packet_size: u16,
299 interval: u8,
300 ) -> Result<Self::EndpointIn, driver::EndpointAllocError> {
301 self.alloc_endpoint(ep_type, max_packet_size, interval)
302 }
303
304 fn alloc_endpoint_out(
305 &mut self,
306 ep_type: EndpointType,
307 max_packet_size: u16,
308 interval: u8,
309 ) -> Result<Self::EndpointOut, driver::EndpointAllocError> {
310 self.alloc_endpoint(ep_type, max_packet_size, interval)
311 }
312
313 fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
314 let regs = T::regs();
315 unsafe {
316 regs.inte().write(|w| {
317 w.set_bus_reset(true);
318 w.set_buff_status(true);
319 w.set_dev_resume_from_host(true);
320 w.set_dev_suspend(true);
321 w.set_setup_req(true);
322 });
323 regs.int_ep_ctrl().write(|w| {
324 w.set_int_ep_active(0xFFFE); // all EPs
325 });
326 regs.sie_ctrl().write(|w| {
327 w.set_ep0_int_1buf(true);
328 w.set_pullup_en(true);
329 })
330 }
331 trace!("enabled");
332
333 (
334 Bus {
335 phantom: PhantomData,
336 inited: false,
337 ep_out: self.ep_out,
338 },
339 ControlPipe {
340 _phantom: PhantomData,
341 max_packet_size: control_max_packet_size,
342 },
343 )
344 }
345}
346
347pub struct Bus<'d, T: Instance> {
348 phantom: PhantomData<&'d mut T>,
349 ep_out: [EndpointData; EP_COUNT],
350 inited: bool,
351}
352
353impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
354 type PollFuture<'a> = impl Future<Output = Event> + 'a where Self: 'a;
355
356 fn poll<'a>(&'a mut self) -> Self::PollFuture<'a> {
357 poll_fn(move |cx| unsafe {
358 BUS_WAKER.register(cx.waker());
359
360 if !self.inited {
361 self.inited = true;
362 return Poll::Ready(Event::PowerDetected);
363 }
364
365 let regs = T::regs();
366 let siestatus = regs.sie_status().read();
367
368 if siestatus.resume() {
369 regs.sie_status().write(|w| w.set_resume(true));
370 return Poll::Ready(Event::Resume);
371 }
372
373 if siestatus.bus_reset() {
374 regs.sie_status().write(|w| {
375 w.set_bus_reset(true);
376 w.set_setup_rec(true);
377 });
378 regs.buff_status().write(|w| w.0 = 0xFFFF_FFFF);
379 regs.addr_endp().write(|w| w.set_address(0));
380
381 for i in 1..EP_COUNT {
382 T::dpram().ep_in_control(i - 1).modify(|w| w.set_enable(false));
383 T::dpram().ep_out_control(i - 1).modify(|w| w.set_enable(false));
384 }
385
386 for w in &EP_IN_WAKERS {
387 w.wake()
388 }
389 for w in &EP_OUT_WAKERS {
390 w.wake()
391 }
392 return Poll::Ready(Event::Reset);
393 }
394
395 if siestatus.suspended() {
396 regs.sie_status().write(|w| w.set_suspended(true));
397 return Poll::Ready(Event::Suspend);
398 }
399
400 // no pending event. Reenable all irqs.
401 regs.inte().write_set(|w| {
402 w.set_bus_reset(true);
403 w.set_dev_resume_from_host(true);
404 w.set_dev_suspend(true);
405 });
406 Poll::Pending
407 })
408 }
409
410 #[inline]
411 fn set_address(&mut self, addr: u8) {
412 let regs = T::regs();
413 trace!("setting addr: {}", addr);
414 unsafe { regs.addr_endp().write(|w| w.set_address(addr)) }
415 }
416
417 fn endpoint_set_stalled(&mut self, _ep_addr: EndpointAddress, _stalled: bool) {
418 todo!();
419 }
420
421 fn endpoint_is_stalled(&mut self, _ep_addr: EndpointAddress) -> bool {
422 todo!();
423 }
424
425 fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) {
426 trace!("set_enabled {:?} {}", ep_addr, enabled);
427 if ep_addr.index() == 0 {
428 return;
429 }
430
431 let n = ep_addr.index();
432 match ep_addr.direction() {
433 UsbDirection::In => unsafe {
434 T::dpram().ep_in_control(n - 1).modify(|w| w.set_enable(enabled));
435 T::dpram().ep_in_buffer_control(ep_addr.index()).write(|w| {
436 w.set_pid(0, true); // first packet is DATA0, but PID is flipped before
437 });
438 EP_IN_WAKERS[n].wake();
439 },
440 UsbDirection::Out => unsafe {
441 T::dpram().ep_out_control(n - 1).modify(|w| w.set_enable(enabled));
442
443 T::dpram().ep_out_buffer_control(ep_addr.index()).write(|w| {
444 w.set_pid(0, false);
445 w.set_length(0, self.ep_out[n].max_packet_size);
446 });
447 cortex_m::asm::delay(12);
448 T::dpram().ep_out_buffer_control(ep_addr.index()).write(|w| {
449 w.set_pid(0, false);
450 w.set_length(0, self.ep_out[n].max_packet_size);
451 w.set_available(0, true);
452 });
453 EP_OUT_WAKERS[n].wake();
454 },
455 }
456 }
457
458 type EnableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
459
460 fn enable(&mut self) -> Self::EnableFuture<'_> {
461 async move {}
462 }
463
464 type DisableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
465
466 fn disable(&mut self) -> Self::DisableFuture<'_> {
467 async move {}
468 }
469
470 type RemoteWakeupFuture<'a> = impl Future<Output = Result<(), Unsupported>> + 'a where Self: 'a;
471
472 fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_> {
473 async move { Err(Unsupported) }
474 }
475}
476
477trait Dir {
478 fn dir() -> UsbDirection;
479 fn waker(i: usize) -> &'static AtomicWaker;
480}
481
482pub enum In {}
483impl Dir for In {
484 fn dir() -> UsbDirection {
485 UsbDirection::In
486 }
487
488 #[inline]
489 fn waker(i: usize) -> &'static AtomicWaker {
490 &EP_IN_WAKERS[i]
491 }
492}
493
494pub enum Out {}
495impl Dir for Out {
496 fn dir() -> UsbDirection {
497 UsbDirection::Out
498 }
499
500 #[inline]
501 fn waker(i: usize) -> &'static AtomicWaker {
502 &EP_OUT_WAKERS[i]
503 }
504}
505
506pub struct Endpoint<'d, T: Instance, D> {
507 _phantom: PhantomData<(&'d mut T, D)>,
508 info: EndpointInfo,
509 buf: EndpointBuffer<T>,
510}
511
512impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> {
513 fn info(&self) -> &EndpointInfo {
514 &self.info
515 }
516
517 type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
518
519 fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> {
520 async move {
521 trace!("wait_enabled IN WAITING");
522 let index = self.info.addr.index();
523 poll_fn(|cx| {
524 EP_OUT_WAKERS[index].register(cx.waker());
525 let val = unsafe { T::dpram().ep_in_control(self.info.addr.index() - 1).read() };
526 if val.enable() {
527 Poll::Ready(())
528 } else {
529 Poll::Pending
530 }
531 })
532 .await;
533 trace!("wait_enabled IN OK");
534 }
535 }
536}
537
538impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, Out> {
539 fn info(&self) -> &EndpointInfo {
540 &self.info
541 }
542
543 type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
544
545 fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> {
546 async move {
547 trace!("wait_enabled OUT WAITING");
548 let index = self.info.addr.index();
549 poll_fn(|cx| {
550 EP_OUT_WAKERS[index].register(cx.waker());
551 let val = unsafe { T::dpram().ep_out_control(self.info.addr.index() - 1).read() };
552 if val.enable() {
553 Poll::Ready(())
554 } else {
555 Poll::Pending
556 }
557 })
558 .await;
559 trace!("wait_enabled OUT OK");
560 }
561 }
562}
563
564impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
565 type ReadFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
566
567 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
568 async move {
569 trace!("READ WAITING, buf.len() = {}", buf.len());
570 let index = self.info.addr.index();
571 let val = poll_fn(|cx| unsafe {
572 EP_OUT_WAKERS[index].register(cx.waker());
573 let val = T::dpram().ep_out_buffer_control(index).read();
574 if val.available(0) {
575 Poll::Pending
576 } else {
577 Poll::Ready(val)
578 }
579 })
580 .await;
581
582 let rx_len = val.length(0) as usize;
583 if rx_len > buf.len() {
584 return Err(EndpointError::BufferOverflow);
585 }
586 self.buf.read(&mut buf[..rx_len]);
587
588 trace!("READ OK, rx_len = {}", rx_len);
589
590 unsafe {
591 let pid = !val.pid(0);
592 T::dpram().ep_out_buffer_control(index).write(|w| {
593 w.set_pid(0, pid);
594 w.set_length(0, self.info.max_packet_size);
595 });
596 cortex_m::asm::delay(12);
597 T::dpram().ep_out_buffer_control(index).write(|w| {
598 w.set_pid(0, pid);
599 w.set_length(0, self.info.max_packet_size);
600 w.set_available(0, true);
601 });
602 }
603
604 Ok(rx_len)
605 }
606 }
607}
608
609impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
610 type WriteFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
611
612 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
613 async move {
614 if buf.len() > self.info.max_packet_size as usize {
615 return Err(EndpointError::BufferOverflow);
616 }
617
618 trace!("WRITE WAITING");
619
620 let index = self.info.addr.index();
621 let val = poll_fn(|cx| unsafe {
622 EP_IN_WAKERS[index].register(cx.waker());
623 let val = T::dpram().ep_in_buffer_control(index).read();
624 if val.available(0) {
625 Poll::Pending
626 } else {
627 Poll::Ready(val)
628 }
629 })
630 .await;
631
632 self.buf.write(buf);
633
634 unsafe {
635 let pid = !val.pid(0);
636 T::dpram().ep_in_buffer_control(index).write(|w| {
637 w.set_pid(0, pid);
638 w.set_length(0, buf.len() as _);
639 w.set_full(0, true);
640 });
641 cortex_m::asm::delay(12);
642 T::dpram().ep_in_buffer_control(index).write(|w| {
643 w.set_pid(0, pid);
644 w.set_length(0, buf.len() as _);
645 w.set_full(0, true);
646 w.set_available(0, true);
647 });
648 }
649
650 trace!("WRITE OK");
651
652 Ok(())
653 }
654 }
655}
656
657pub struct ControlPipe<'d, T: Instance> {
658 _phantom: PhantomData<&'d mut T>,
659 max_packet_size: u16,
660}
661
662impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
663 type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a;
664 type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
665 type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
666 type AcceptFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
667 type RejectFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
668
669 fn max_packet_size(&self) -> usize {
670 64
671 }
672
673 fn setup<'a>(&'a mut self) -> Self::SetupFuture<'a> {
674 async move {
675 loop {
676 trace!("SETUP read waiting");
677 let regs = T::regs();
678 unsafe { regs.inte().write_set(|w| w.set_setup_req(true)) };
679
680 poll_fn(|cx| unsafe {
681 EP_OUT_WAKERS[0].register(cx.waker());
682 let regs = T::regs();
683 if regs.sie_status().read().setup_rec() {
684 Poll::Ready(())
685 } else {
686 Poll::Pending
687 }
688 })
689 .await;
690
691 let mut buf = [0; 8];
692 EndpointBuffer::<T>::new(0, 8).read(&mut buf);
693
694 let regs = T::regs();
695 unsafe {
696 regs.sie_status().write(|w| w.set_setup_rec(true));
697
698 // set PID to 0, so (after toggling) first DATA is PID 1
699 T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false));
700 T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false));
701 }
702
703 trace!("SETUP read ok");
704 return buf;
705 }
706 }
707 }
708
709 fn data_out<'a>(&'a mut self, buf: &'a mut [u8], _first: bool, _last: bool) -> Self::DataOutFuture<'a> {
710 async move {
711 unsafe {
712 let bufcontrol = T::dpram().ep_out_buffer_control(0);
713 let pid = !bufcontrol.read().pid(0);
714 bufcontrol.write(|w| {
715 w.set_length(0, self.max_packet_size);
716 w.set_pid(0, pid);
717 });
718 cortex_m::asm::delay(12);
719 bufcontrol.write(|w| {
720 w.set_length(0, self.max_packet_size);
721 w.set_pid(0, pid);
722 w.set_available(0, true);
723 });
724 }
725
726 trace!("control: data_out len={} first={} last={}", buf.len(), _first, _last);
727 let val = poll_fn(|cx| unsafe {
728 EP_OUT_WAKERS[0].register(cx.waker());
729 let val = T::dpram().ep_out_buffer_control(0).read();
730 if val.available(0) {
731 Poll::Pending
732 } else {
733 Poll::Ready(val)
734 }
735 })
736 .await;
737
738 let rx_len = val.length(0) as _;
739 trace!("control data_out DONE, rx_len = {}", rx_len);
740
741 if rx_len > buf.len() {
742 return Err(EndpointError::BufferOverflow);
743 }
744 EndpointBuffer::<T>::new(0x100, 64).read(&mut buf[..rx_len]);
745
746 Ok(rx_len)
747 }
748 }
749
750 fn data_in<'a>(&'a mut self, buf: &'a [u8], _first: bool, _last: bool) -> Self::DataInFuture<'a> {
751 async move {
752 trace!("control: data_in len={} first={} last={}", buf.len(), _first, _last);
753
754 if buf.len() > 64 {
755 return Err(EndpointError::BufferOverflow);
756 }
757 EndpointBuffer::<T>::new(0x100, 64).write(buf);
758
759 unsafe {
760 let bufcontrol = T::dpram().ep_in_buffer_control(0);
761 let pid = !bufcontrol.read().pid(0);
762 bufcontrol.write(|w| {
763 w.set_length(0, buf.len() as _);
764 w.set_pid(0, pid);
765 w.set_full(0, true);
766 });
767 cortex_m::asm::delay(12);
768 bufcontrol.write(|w| {
769 w.set_length(0, buf.len() as _);
770 w.set_pid(0, pid);
771 w.set_full(0, true);
772 w.set_available(0, true);
773 });
774 }
775
776 poll_fn(|cx| unsafe {
777 EP_IN_WAKERS[0].register(cx.waker());
778 let bufcontrol = T::dpram().ep_in_buffer_control(0);
779 if bufcontrol.read().available(0) {
780 Poll::Pending
781 } else {
782 Poll::Ready(())
783 }
784 })
785 .await;
786 trace!("control: data_in DONE");
787
788 if _last {
789 // prepare status phase right away.
790 unsafe {
791 let bufcontrol = T::dpram().ep_out_buffer_control(0);
792 bufcontrol.write(|w| {
793 w.set_length(0, 0);
794 w.set_pid(0, true);
795 });
796 cortex_m::asm::delay(12);
797 bufcontrol.write(|w| {
798 w.set_length(0, 0);
799 w.set_pid(0, true);
800 w.set_available(0, true);
801 });
802 }
803 }
804
805 Ok(())
806 }
807 }
808
809 fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a> {
810 async move {
811 trace!("control: accept");
812
813 unsafe {
814 let bufcontrol = T::dpram().ep_in_buffer_control(0);
815 bufcontrol.write(|w| {
816 w.set_length(0, 0);
817 w.set_pid(0, true);
818 w.set_full(0, true);
819 });
820 cortex_m::asm::delay(12);
821 bufcontrol.write(|w| {
822 w.set_length(0, 0);
823 w.set_pid(0, true);
824 w.set_full(0, true);
825 w.set_available(0, true);
826 });
827 }
828 }
829 }
830
831 fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a> {
832 async move {
833 trace!("control: reject");
834
835 let regs = T::regs();
836 unsafe {
837 regs.ep_stall_arm().write_set(|w| {
838 w.set_ep0_in(true);
839 w.set_ep0_out(true);
840 });
841 T::dpram().ep_out_buffer_control(0).write(|w| w.set_stall(true));
842 T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true));
843 }
844 }
845 }
846}