1#![macro_use]
4
5pub mod vbus_detect;
6
7use core::future::{poll_fn, Future};
8use core::marker::PhantomData;
9use core::mem::MaybeUninit;
10use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
11use core::task::Poll;
12
13use cortex_m::peripheral::NVIC;
14use embassy_hal_internal::{Peri, PeripheralType};
15use embassy_sync::waitqueue::AtomicWaker;
16use embassy_usb_driver as driver;
17use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported};
18
19use self::vbus_detect::VbusDetect;
20use crate::interrupt::typelevel::Interrupt;
21use crate::pac::usbd::vals;
22use crate::util::slice_in_ram;
23use crate::{interrupt, pac};
24
25static BUS_WAKER: AtomicWaker = AtomicWaker::new();
26static EP0_WAKER: AtomicWaker = AtomicWaker::new();
27static EP_IN_WAKERS: [AtomicWaker; 8] = [const { AtomicWaker::new() }; 8];
28static EP_OUT_WAKERS: [AtomicWaker; 8] = [const { AtomicWaker::new() }; 8];
29static READY_ENDPOINTS: AtomicU32 = AtomicU32::new(0);
30
31pub struct InterruptHandler<T: Instance> {
33 _phantom: PhantomData<T>,
34}
35
36impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
37 unsafe fn on_interrupt() {
38 let regs = T::regs();
39
40 if regs.events_usbreset().read() != 0 {
41 regs.intenclr().write(|w| w.set_usbreset(true));
42 BUS_WAKER.wake();
43 EP0_WAKER.wake();
44 }
45
46 if regs.events_ep0setup().read() != 0 {
47 regs.intenclr().write(|w| w.set_ep0setup(true));
48 EP0_WAKER.wake();
49 }
50
51 if regs.events_ep0datadone().read() != 0 {
52 regs.intenclr().write(|w| w.set_ep0datadone(true));
53 EP0_WAKER.wake();
54 }
55
56 if regs.events_usbevent().read() != 0 {
66 regs.events_usbevent().write_value(0);
67 BUS_WAKER.wake();
68 }
69
70 if regs.events_epdata().read() != 0 {
71 regs.events_epdata().write_value(0);
72
73 let r = regs.epdatastatus().read();
74 regs.epdatastatus().write_value(r);
75 READY_ENDPOINTS.fetch_or(r.0, Ordering::AcqRel);
76 for i in 1..=7 {
77 if r.0 & In::mask(i) != 0 {
78 In::waker(i).wake();
79 }
80 if r.0 & Out::mask(i) != 0 {
81 Out::waker(i).wake();
82 }
83 }
84 }
85 }
86}
87
88pub struct Driver<'d, V: VbusDetect> {
90 regs: pac::usbd::Usbd,
91 alloc_in: Allocator,
92 alloc_out: Allocator,
93 vbus_detect: V,
94 _phantom: PhantomData<&'d ()>,
95}
96
97impl<'d, V: VbusDetect> Driver<'d, V> {
98 pub fn new<T: Instance>(
100 _usb: Peri<'d, T>,
101 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
102 vbus_detect: V,
103 ) -> Self {
104 T::Interrupt::unpend();
105 unsafe { T::Interrupt::enable() };
106
107 Self {
108 regs: crate::pac::USBD,
109 alloc_in: Allocator::new(),
110 alloc_out: Allocator::new(),
111 vbus_detect,
112 _phantom: PhantomData,
113 }
114 }
115}
116
117impl<'d, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, V> {
118 type EndpointOut = Endpoint<'d, Out>;
119 type EndpointIn = Endpoint<'d, In>;
120 type ControlPipe = ControlPipe<'d>;
121 type Bus = Bus<'d, V>;
122
123 fn alloc_endpoint_in(
124 &mut self,
125 ep_type: EndpointType,
126 ep_addr: Option<EndpointAddress>,
127 packet_size: u16,
128 interval_ms: u8,
129 ) -> Result<Self::EndpointIn, driver::EndpointAllocError> {
130 let index = self.alloc_in.allocate(ep_type, ep_addr)?;
131 let ep_addr = EndpointAddress::from_parts(index, Direction::In);
132 Ok(Endpoint::new(
133 self.regs,
134 EndpointInfo {
135 addr: ep_addr,
136 ep_type,
137 max_packet_size: packet_size,
138 interval_ms,
139 },
140 ))
141 }
142
143 fn alloc_endpoint_out(
144 &mut self,
145 ep_type: EndpointType,
146 ep_addr: Option<EndpointAddress>,
147 packet_size: u16,
148 interval_ms: u8,
149 ) -> Result<Self::EndpointOut, driver::EndpointAllocError> {
150 let index = self.alloc_out.allocate(ep_type, ep_addr)?;
151 let ep_addr = EndpointAddress::from_parts(index, Direction::Out);
152 Ok(Endpoint::new(
153 self.regs,
154 EndpointInfo {
155 addr: ep_addr,
156 ep_type,
157 max_packet_size: packet_size,
158 interval_ms,
159 },
160 ))
161 }
162
163 fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
164 (
165 Bus {
166 regs: self.regs,
167 power_available: false,
168 vbus_detect: self.vbus_detect,
169 _phantom: PhantomData,
170 },
171 ControlPipe {
172 regs: self.regs,
173 max_packet_size: control_max_packet_size,
174 _phantom: PhantomData,
175 },
176 )
177 }
178}
179
180pub struct Bus<'d, V: VbusDetect> {
182 regs: pac::usbd::Usbd,
183 power_available: bool,
184 vbus_detect: V,
185 _phantom: PhantomData<&'d ()>,
186}
187
188impl<'d, V: VbusDetect> driver::Bus for Bus<'d, V> {
189 async fn enable(&mut self) {
190 let regs = self.regs;
191
192 errata::pre_enable();
193
194 regs.enable().write(|w| w.set_enable(true));
195
196 regs.intenset().write(|w| w.set_usbevent(true));
198 poll_fn(|cx| {
199 BUS_WAKER.register(cx.waker());
200 if regs.eventcause().read().ready() {
201 Poll::Ready(())
202 } else {
203 Poll::Pending
204 }
205 })
206 .await;
207 regs.eventcause().write(|w| w.set_ready(true));
208
209 errata::post_enable();
210
211 unsafe { NVIC::unmask(pac::Interrupt::USBD) };
212
213 regs.intenset().write(|w| {
214 w.set_usbreset(true);
215 w.set_usbevent(true);
216 w.set_epdata(true);
217 });
218
219 if self.vbus_detect.wait_power_ready().await.is_ok() {
220 regs.usbpullup().write(|w| w.set_connect(true));
222 trace!("enabled");
223 } else {
224 trace!("usb power not ready due to usb removal");
225 }
226 }
227
228 async fn disable(&mut self) {
229 let regs = self.regs;
230 regs.enable().write(|x| x.set_enable(false));
231 }
232
233 fn poll(&mut self) -> impl Future<Output = Event> {
234 poll_fn(|cx| {
235 BUS_WAKER.register(cx.waker());
236 let regs = self.regs;
237
238 if regs.events_usbreset().read() != 0 {
239 regs.events_usbreset().write_value(0);
240 regs.intenset().write(|w| w.set_usbreset(true));
241
242 regs.epinen().write(|w| w.0 = 0x01);
244 regs.epouten().write(|w| w.0 = 0x01);
245 READY_ENDPOINTS.store(In::mask(0), Ordering::Release);
246 for i in 1..=7 {
247 In::waker(i).wake();
248 Out::waker(i).wake();
249 }
250
251 return Poll::Ready(Event::Reset);
252 }
253
254 let r = regs.eventcause().read();
255
256 if r.isooutcrc() {
257 regs.eventcause().write(|w| w.set_isooutcrc(true));
258 trace!("USB event: isooutcrc");
259 }
260 if r.usbwuallowed() {
261 regs.eventcause().write(|w| w.set_usbwuallowed(true));
262 trace!("USB event: usbwuallowed");
263 }
264 if r.suspend() {
265 regs.eventcause().write(|w| w.set_suspend(true));
266 regs.lowpower().write(|w| w.set_lowpower(vals::Lowpower::LOW_POWER));
267 return Poll::Ready(Event::Suspend);
268 }
269 if r.resume() {
270 regs.eventcause().write(|w| w.set_resume(true));
271 return Poll::Ready(Event::Resume);
272 }
273 if r.ready() {
274 regs.eventcause().write(|w| w.set_ready(true));
275 trace!("USB event: ready");
276 }
277
278 if self.vbus_detect.is_usb_detected() != self.power_available {
279 self.power_available = !self.power_available;
280 if self.power_available {
281 trace!("Power event: available");
282 return Poll::Ready(Event::PowerDetected);
283 } else {
284 trace!("Power event: removed");
285 return Poll::Ready(Event::PowerRemoved);
286 }
287 }
288
289 Poll::Pending
290 })
291 }
292
293 fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) {
294 let regs = self.regs;
295 if ep_addr.index() == 0 {
296 if stalled {
297 regs.tasks_ep0stall().write_value(1);
298 }
299 } else {
300 regs.epstall().write(|w| {
301 w.set_ep(ep_addr.index() as u8 & 0b111);
302 w.set_io(match ep_addr.direction() {
303 Direction::In => vals::Io::IN,
304 Direction::Out => vals::Io::OUT,
305 });
306 w.set_stall(stalled);
307 });
308 }
309 }
310
311 fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool {
312 let regs = self.regs;
313 let i = ep_addr.index();
314 match ep_addr.direction() {
315 Direction::Out => regs.halted().epout(i).read().getstatus() == vals::Getstatus::HALTED,
316 Direction::In => regs.halted().epin(i).read().getstatus() == vals::Getstatus::HALTED,
317 }
318 }
319
320 fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) {
321 let regs = self.regs;
322
323 let i = ep_addr.index();
324 let mask = 1 << i;
325
326 debug!("endpoint_set_enabled {:?} {}", ep_addr, enabled);
327
328 match ep_addr.direction() {
329 Direction::In => {
330 let mut was_enabled = false;
331 regs.epinen().modify(|w| {
332 was_enabled = (w.0 & mask) != 0;
333 if enabled {
334 w.0 |= mask
335 } else {
336 w.0 &= !mask
337 }
338 });
339
340 let ready_mask = In::mask(i);
341 if enabled {
342 if !was_enabled {
343 READY_ENDPOINTS.fetch_or(ready_mask, Ordering::AcqRel);
344 }
345 } else {
346 READY_ENDPOINTS.fetch_and(!ready_mask, Ordering::AcqRel);
347 }
348
349 In::waker(i).wake();
350 }
351 Direction::Out => {
352 regs.epouten()
353 .modify(|w| if enabled { w.0 |= mask } else { w.0 &= !mask });
354
355 let ready_mask = Out::mask(i);
356 if enabled {
357 regs.size().epout(i).write(|_| ());
362 } else {
363 READY_ENDPOINTS.fetch_and(!ready_mask, Ordering::AcqRel);
364 }
365
366 Out::waker(i).wake();
367 }
368 }
369 }
370
371 #[inline]
372 async fn remote_wakeup(&mut self) -> Result<(), Unsupported> {
373 let regs = self.regs;
374
375 if regs.lowpower().read().lowpower() == vals::Lowpower::LOW_POWER {
376 errata::pre_wakeup();
377
378 regs.lowpower().write(|w| w.set_lowpower(vals::Lowpower::FORCE_NORMAL));
379
380 poll_fn(|cx| {
381 BUS_WAKER.register(cx.waker());
382 let regs = self.regs;
383 let r = regs.eventcause().read();
384
385 if regs.events_usbreset().read() != 0 {
386 Poll::Ready(())
387 } else if r.resume() {
388 Poll::Ready(())
389 } else if r.usbwuallowed() {
390 regs.eventcause().write(|w| w.set_usbwuallowed(true));
391 regs.dpdmvalue().write(|w| w.set_state(vals::State::RESUME));
392 regs.tasks_dpdmdrive().write_value(1);
393
394 Poll::Ready(())
395 } else {
396 Poll::Pending
397 }
398 })
399 .await;
400
401 errata::post_wakeup();
402 }
403
404 Ok(())
405 }
406}
407
408pub enum Out {}
410
411pub enum In {}
413
414trait EndpointDir {
415 fn waker(i: usize) -> &'static AtomicWaker;
416 fn mask(i: usize) -> u32;
417 fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool;
418}
419
420impl EndpointDir for In {
421 #[inline]
422 fn waker(i: usize) -> &'static AtomicWaker {
423 &EP_IN_WAKERS[i - 1]
424 }
425
426 #[inline]
427 fn mask(i: usize) -> u32 {
428 1 << i
429 }
430
431 #[inline]
432 fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool {
433 regs.epinen().read().in_(i)
434 }
435}
436
437impl EndpointDir for Out {
438 #[inline]
439 fn waker(i: usize) -> &'static AtomicWaker {
440 &EP_OUT_WAKERS[i - 1]
441 }
442
443 #[inline]
444 fn mask(i: usize) -> u32 {
445 1 << (i + 16)
446 }
447
448 #[inline]
449 fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool {
450 regs.epouten().read().out(i)
451 }
452}
453
454pub struct Endpoint<'d, Dir> {
456 regs: pac::usbd::Usbd,
457 info: EndpointInfo,
458 _phantom: PhantomData<(&'d (), Dir)>,
459}
460
461impl<'d, Dir> Endpoint<'d, Dir> {
462 fn new(regs: pac::usbd::Usbd, info: EndpointInfo) -> Self {
463 Self {
464 regs,
465 info,
466 _phantom: PhantomData,
467 }
468 }
469}
470
471impl<'d, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, Dir> {
472 fn info(&self) -> &EndpointInfo {
473 &self.info
474 }
475
476 async fn wait_enabled(&mut self) {
477 self.wait_enabled_state(true).await
478 }
479}
480
481#[allow(private_bounds)]
482impl<'d, Dir: EndpointDir> Endpoint<'d, Dir> {
483 fn wait_enabled_state(&mut self, state: bool) -> impl Future<Output = ()> + use<'_, 'd, Dir> {
484 let i = self.info.addr.index();
485 assert!(i != 0);
486
487 poll_fn(move |cx| {
488 Dir::waker(i).register(cx.waker());
489 if Dir::is_enabled(self.regs, i) == state {
490 Poll::Ready(())
491 } else {
492 Poll::Pending
493 }
494 })
495 }
496
497 pub fn wait_disabled(&mut self) -> impl Future<Output = ()> + use<'_, 'd, Dir> {
499 self.wait_enabled_state(false)
500 }
501}
502
503impl<'d, Dir> Endpoint<'d, Dir> {
504 async fn wait_data_ready(&mut self) -> Result<(), ()>
505 where
506 Dir: EndpointDir,
507 {
508 let i = self.info.addr.index();
509 assert!(i != 0);
510 poll_fn(|cx| {
511 Dir::waker(i).register(cx.waker());
512 let r = READY_ENDPOINTS.load(Ordering::Acquire);
513 if !Dir::is_enabled(self.regs, i) {
514 Poll::Ready(Err(()))
515 } else if r & Dir::mask(i) != 0 {
516 Poll::Ready(Ok(()))
517 } else {
518 Poll::Pending
519 }
520 })
521 .await?;
522
523 READY_ENDPOINTS.fetch_and(!Dir::mask(i), Ordering::AcqRel);
525
526 Ok(())
527 }
528}
529
530unsafe fn read_dma(regs: pac::usbd::Usbd, i: usize, buf: &mut [u8]) -> Result<usize, EndpointError> {
531 let size = regs.size().epout(i).read().0 as usize;
533 if size > buf.len() {
534 return Err(EndpointError::BufferOverflow);
535 }
536
537 regs.epout(i).ptr().write_value(buf.as_ptr() as u32);
538 regs.epout(i).maxcnt().write(|w| w.set_maxcnt(size as _));
540
541 dma_start();
542 regs.events_endepout(i).write_value(0);
543 regs.tasks_startepout(i).write_value(1);
544 while regs.events_endepout(i).read() == 0 {}
545 regs.events_endepout(i).write_value(0);
546 dma_end();
547
548 regs.size().epout(i).write(|_| ());
549
550 Ok(size)
551}
552
553unsafe fn write_dma(regs: pac::usbd::Usbd, i: usize, buf: &[u8]) {
554 assert!(buf.len() <= 64);
555
556 let mut ram_buf: MaybeUninit<[u8; 64]> = MaybeUninit::uninit();
557 let ptr = if !slice_in_ram(buf) {
558 let ptr = ram_buf.as_mut_ptr() as *mut u8;
560 core::ptr::copy_nonoverlapping(buf.as_ptr(), ptr, buf.len());
561 ptr
562 } else {
563 buf.as_ptr()
564 };
565
566 regs.epin(i).ptr().write_value(ptr as u32);
569 regs.epin(i).maxcnt().write(|w| w.set_maxcnt(buf.len() as u8));
570
571 regs.events_endepin(i).write_value(0);
572
573 dma_start();
574 regs.tasks_startepin(i).write_value(1);
575 while regs.events_endepin(i).read() == 0 {}
576 dma_end();
577}
578
579impl<'d> driver::EndpointOut for Endpoint<'d, Out> {
580 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> {
581 let i = self.info.addr.index();
582 assert!(i != 0);
583
584 self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?;
585
586 unsafe { read_dma(self.regs, i, buf) }
587 }
588}
589
590impl<'d> driver::EndpointIn for Endpoint<'d, In> {
591 async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> {
592 let i = self.info.addr.index();
593 assert!(i != 0);
594
595 self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?;
596
597 unsafe { write_dma(self.regs, i, buf) }
598
599 Ok(())
600 }
601}
602
603pub struct ControlPipe<'d> {
605 regs: pac::usbd::Usbd,
606 max_packet_size: u16,
607 _phantom: PhantomData<&'d ()>,
608}
609
610impl<'d> driver::ControlPipe for ControlPipe<'d> {
611 fn max_packet_size(&self) -> usize {
612 usize::from(self.max_packet_size)
613 }
614
615 async fn setup(&mut self) -> [u8; 8] {
616 let regs = self.regs;
617
618 regs.shorts().write(|_| ());
620
621 regs.intenset().write(|w| w.set_ep0setup(true));
623 poll_fn(|cx| {
624 EP0_WAKER.register(cx.waker());
625 let regs = self.regs;
626 if regs.events_ep0setup().read() != 0 {
627 Poll::Ready(())
628 } else {
629 Poll::Pending
630 }
631 })
632 .await;
633
634 regs.events_ep0setup().write_value(0);
635
636 let mut buf = [0; 8];
637 buf[0] = regs.bmrequesttype().read().0 as u8;
638 buf[1] = regs.brequest().read().0 as u8;
639 buf[2] = regs.wvaluel().read().0 as u8;
640 buf[3] = regs.wvalueh().read().0 as u8;
641 buf[4] = regs.windexl().read().0 as u8;
642 buf[5] = regs.windexh().read().0 as u8;
643 buf[6] = regs.wlengthl().read().0 as u8;
644 buf[7] = regs.wlengthh().read().0 as u8;
645
646 buf
647 }
648
649 async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> {
650 let regs = self.regs;
651
652 regs.events_ep0datadone().write_value(0);
653
654 regs.tasks_ep0rcvout().write_value(1);
656
657 regs.intenset().write(|w| {
659 w.set_usbreset(true);
660 w.set_ep0setup(true);
661 w.set_ep0datadone(true);
662 });
663 poll_fn(|cx| {
664 EP0_WAKER.register(cx.waker());
665 let regs = self.regs;
666 if regs.events_ep0datadone().read() != 0 {
667 Poll::Ready(Ok(()))
668 } else if regs.events_usbreset().read() != 0 {
669 trace!("aborted control data_out: usb reset");
670 Poll::Ready(Err(EndpointError::Disabled))
671 } else if regs.events_ep0setup().read() != 0 {
672 trace!("aborted control data_out: received another SETUP");
673 Poll::Ready(Err(EndpointError::Disabled))
674 } else {
675 Poll::Pending
676 }
677 })
678 .await?;
679
680 unsafe { read_dma(self.regs, 0, buf) }
681 }
682
683 async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> {
684 let regs = self.regs;
685 regs.events_ep0datadone().write_value(0);
686
687 regs.shorts().write(|w| w.set_ep0datadone_ep0status(last));
688
689 unsafe { write_dma(self.regs, 0, buf) }
691
692 regs.intenset().write(|w| {
693 w.set_usbreset(true);
694 w.set_ep0setup(true);
695 w.set_ep0datadone(true);
696 });
697
698 poll_fn(|cx| {
699 cx.waker().wake_by_ref();
700 EP0_WAKER.register(cx.waker());
701 let regs = self.regs;
702 if regs.events_ep0datadone().read() != 0 {
703 Poll::Ready(Ok(()))
704 } else if regs.events_usbreset().read() != 0 {
705 trace!("aborted control data_in: usb reset");
706 Poll::Ready(Err(EndpointError::Disabled))
707 } else if regs.events_ep0setup().read() != 0 {
708 trace!("aborted control data_in: received another SETUP");
709 Poll::Ready(Err(EndpointError::Disabled))
710 } else {
711 Poll::Pending
712 }
713 })
714 .await
715 }
716
717 async fn accept(&mut self) {
718 let regs = self.regs;
719 regs.tasks_ep0status().write_value(1);
720 }
721
722 async fn reject(&mut self) {
723 let regs = self.regs;
724 regs.tasks_ep0stall().write_value(1);
725 }
726
727 async fn accept_set_address(&mut self, _addr: u8) {
728 self.accept().await;
729 }
731}
732
733fn dma_start() {
734 compiler_fence(Ordering::Release);
735}
736
737fn dma_end() {
738 compiler_fence(Ordering::Acquire);
739}
740
741struct Allocator {
742 used: u16,
743}
744
745impl Allocator {
746 fn new() -> Self {
747 Self { used: 0 }
748 }
749
750 fn allocate(
751 &mut self,
752 ep_type: EndpointType,
753 ep_addr: Option<EndpointAddress>,
754 ) -> Result<usize, driver::EndpointAllocError> {
755 let alloc_index = if let Some(addr) = ep_addr {
769 let requested_index = addr.index();
771 match ep_type {
773 EndpointType::Isochronous => {
774 if requested_index != 8 {
775 return Err(driver::EndpointAllocError);
776 }
777 }
778 EndpointType::Control => return Err(driver::EndpointAllocError),
779 EndpointType::Interrupt | EndpointType::Bulk => {
780 if requested_index < 1 || requested_index > 7 {
781 return Err(driver::EndpointAllocError);
782 }
783 }
784 }
785 requested_index
786 } else {
787 match ep_type {
789 EndpointType::Isochronous => 8,
790 EndpointType::Control => return Err(driver::EndpointAllocError),
791 EndpointType::Interrupt | EndpointType::Bulk => {
792 let ones = (self.used >> 1).trailing_ones() as usize;
794 if ones >= 7 {
795 return Err(driver::EndpointAllocError);
796 }
797 ones + 1
798 }
799 }
800 };
801
802 if self.used & (1 << alloc_index) != 0 {
803 return Err(driver::EndpointAllocError);
804 }
805
806 self.used |= 1 << alloc_index;
807
808 Ok(alloc_index)
809 }
810}
811
812pub(crate) trait SealedInstance {
813 fn regs() -> pac::usbd::Usbd;
814}
815
816#[allow(private_bounds)]
818pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
819 type Interrupt: interrupt::typelevel::Interrupt;
821}
822
823macro_rules! impl_usb {
824 ($type:ident, $pac_type:ident, $irq:ident) => {
825 impl crate::usb::SealedInstance for peripherals::$type {
826 fn regs() -> pac::usbd::Usbd {
827 pac::$pac_type
828 }
829 }
830 impl crate::usb::Instance for peripherals::$type {
831 type Interrupt = crate::interrupt::typelevel::$irq;
832 }
833 };
834}
835
836mod errata {
837
838 #[cfg(any(feature = "nrf52840", feature = "nrf52833", feature = "nrf52820"))]
840 unsafe fn poke(addr: u32, val: u32) {
841 (addr as *mut u32).write_volatile(val);
842 }
843
844 #[cfg(feature = "nrf52840")]
846 unsafe fn peek(addr: u32) -> u32 {
847 (addr as *mut u32).read_volatile()
848 }
849
850 pub fn pre_enable() {
851 #[cfg(any(feature = "nrf52840", feature = "nrf52833", feature = "nrf52820"))]
853 unsafe {
854 poke(0x4006EC00, 0x00009375);
855 poke(0x4006ED14, 0x00000003);
856 poke(0x4006EC00, 0x00009375);
857 }
858
859 pre_wakeup();
860 }
861
862 pub fn post_enable() {
863 post_wakeup();
864
865 #[cfg(any(feature = "nrf52840", feature = "nrf52833", feature = "nrf52820"))]
867 unsafe {
868 poke(0x4006EC00, 0x00009375);
869 poke(0x4006ED14, 0x00000000);
870 poke(0x4006EC00, 0x00009375);
871 }
872 }
873
874 pub fn pre_wakeup() {
875 #[cfg(feature = "nrf52840")]
878 unsafe {
879 if peek(0x4006EC00) == 0x00000000 {
880 poke(0x4006EC00, 0x00009375);
881 }
882
883 poke(0x4006EC14, 0x000000C0);
884 poke(0x4006EC00, 0x00009375);
885 }
886 }
887
888 pub fn post_wakeup() {
889 #[cfg(feature = "nrf52840")]
892 unsafe {
893 if peek(0x4006EC00) == 0x00000000 {
894 poke(0x4006EC00, 0x00009375);
895 }
896
897 poke(0x4006EC14, 0x00000000);
898 poke(0x4006EC00, 0x00009375);
899 }
900 }
901}