1#![macro_use]
4
5pub mod vbus_detect;
6
7use core::future::{Future, poll_fn};
8use core::marker::PhantomData;
9use core::mem::MaybeUninit;
10use core::sync::atomic::{AtomicU32, Ordering, compiler_fence};
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 { w.0 |= mask } else { w.0 &= !mask }
334 });
335
336 let ready_mask = In::mask(i);
337 if enabled {
338 if !was_enabled {
339 READY_ENDPOINTS.fetch_or(ready_mask, Ordering::AcqRel);
340 }
341 } else {
342 READY_ENDPOINTS.fetch_and(!ready_mask, Ordering::AcqRel);
343 }
344
345 In::waker(i).wake();
346 }
347 Direction::Out => {
348 regs.epouten()
349 .modify(|w| if enabled { w.0 |= mask } else { w.0 &= !mask });
350
351 let ready_mask = Out::mask(i);
352 if enabled {
353 regs.size().epout(i).write(|_| ());
358 } else {
359 READY_ENDPOINTS.fetch_and(!ready_mask, Ordering::AcqRel);
360 }
361
362 Out::waker(i).wake();
363 }
364 }
365 }
366
367 #[inline]
368 async fn remote_wakeup(&mut self) -> Result<(), Unsupported> {
369 let regs = self.regs;
370
371 if regs.lowpower().read().lowpower() == vals::Lowpower::LOW_POWER {
372 errata::pre_wakeup();
373
374 regs.lowpower().write(|w| w.set_lowpower(vals::Lowpower::FORCE_NORMAL));
375
376 poll_fn(|cx| {
377 BUS_WAKER.register(cx.waker());
378 let regs = self.regs;
379 let r = regs.eventcause().read();
380
381 if regs.events_usbreset().read() != 0 {
382 Poll::Ready(())
383 } else if r.resume() {
384 Poll::Ready(())
385 } else if r.usbwuallowed() {
386 regs.eventcause().write(|w| w.set_usbwuallowed(true));
387 regs.dpdmvalue().write(|w| w.set_state(vals::State::RESUME));
388 regs.tasks_dpdmdrive().write_value(1);
389
390 Poll::Ready(())
391 } else {
392 Poll::Pending
393 }
394 })
395 .await;
396
397 errata::post_wakeup();
398 }
399
400 Ok(())
401 }
402}
403
404pub enum Out {}
406
407pub enum In {}
409
410trait EndpointDir {
411 fn waker(i: usize) -> &'static AtomicWaker;
412 fn mask(i: usize) -> u32;
413 fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool;
414}
415
416impl EndpointDir for In {
417 #[inline]
418 fn waker(i: usize) -> &'static AtomicWaker {
419 &EP_IN_WAKERS[i - 1]
420 }
421
422 #[inline]
423 fn mask(i: usize) -> u32 {
424 1 << i
425 }
426
427 #[inline]
428 fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool {
429 regs.epinen().read().in_(i)
430 }
431}
432
433impl EndpointDir for Out {
434 #[inline]
435 fn waker(i: usize) -> &'static AtomicWaker {
436 &EP_OUT_WAKERS[i - 1]
437 }
438
439 #[inline]
440 fn mask(i: usize) -> u32 {
441 1 << (i + 16)
442 }
443
444 #[inline]
445 fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool {
446 regs.epouten().read().out(i)
447 }
448}
449
450pub struct Endpoint<'d, Dir> {
452 regs: pac::usbd::Usbd,
453 info: EndpointInfo,
454 _phantom: PhantomData<(&'d (), Dir)>,
455}
456
457impl<'d, Dir> Endpoint<'d, Dir> {
458 fn new(regs: pac::usbd::Usbd, info: EndpointInfo) -> Self {
459 Self {
460 regs,
461 info,
462 _phantom: PhantomData,
463 }
464 }
465}
466
467impl<'d, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, Dir> {
468 fn info(&self) -> &EndpointInfo {
469 &self.info
470 }
471
472 async fn wait_enabled(&mut self) {
473 self.wait_enabled_state(true).await
474 }
475}
476
477#[allow(private_bounds)]
478impl<'d, Dir: EndpointDir> Endpoint<'d, Dir> {
479 fn wait_enabled_state(&mut self, state: bool) -> impl Future<Output = ()> + use<'_, 'd, Dir> {
480 let i = self.info.addr.index();
481 assert!(i != 0);
482
483 poll_fn(move |cx| {
484 Dir::waker(i).register(cx.waker());
485 if Dir::is_enabled(self.regs, i) == state {
486 Poll::Ready(())
487 } else {
488 Poll::Pending
489 }
490 })
491 }
492
493 pub fn wait_disabled(&mut self) -> impl Future<Output = ()> + use<'_, 'd, Dir> {
495 self.wait_enabled_state(false)
496 }
497}
498
499impl<'d, Dir> Endpoint<'d, Dir> {
500 async fn wait_data_ready(&mut self) -> Result<(), ()>
501 where
502 Dir: EndpointDir,
503 {
504 let i = self.info.addr.index();
505 assert!(i != 0);
506 poll_fn(|cx| {
507 Dir::waker(i).register(cx.waker());
508 let r = READY_ENDPOINTS.load(Ordering::Acquire);
509 if !Dir::is_enabled(self.regs, i) {
510 Poll::Ready(Err(()))
511 } else if r & Dir::mask(i) != 0 {
512 Poll::Ready(Ok(()))
513 } else {
514 Poll::Pending
515 }
516 })
517 .await?;
518
519 READY_ENDPOINTS.fetch_and(!Dir::mask(i), Ordering::AcqRel);
521
522 Ok(())
523 }
524}
525
526unsafe fn read_dma(regs: pac::usbd::Usbd, i: usize, buf: &mut [u8]) -> Result<usize, EndpointError> {
527 let size = regs.size().epout(i).read().0 as usize;
529 if size > buf.len() {
530 return Err(EndpointError::BufferOverflow);
531 }
532
533 regs.epout(i).ptr().write_value(buf.as_ptr() as u32);
534 regs.epout(i).maxcnt().write(|w| w.set_maxcnt(size as _));
536
537 dma_start();
538 regs.events_endepout(i).write_value(0);
539 regs.tasks_startepout(i).write_value(1);
540 while regs.events_endepout(i).read() == 0 {}
541 regs.events_endepout(i).write_value(0);
542 dma_end();
543
544 regs.size().epout(i).write(|_| ());
545
546 Ok(size)
547}
548
549unsafe fn write_dma(regs: pac::usbd::Usbd, i: usize, buf: &[u8]) {
550 assert!(buf.len() <= 64);
551
552 let mut ram_buf: MaybeUninit<[u8; 64]> = MaybeUninit::uninit();
553 let ptr = if !slice_in_ram(buf) {
554 let ptr = ram_buf.as_mut_ptr() as *mut u8;
556 core::ptr::copy_nonoverlapping(buf.as_ptr(), ptr, buf.len());
557 ptr
558 } else {
559 buf.as_ptr()
560 };
561
562 regs.epin(i).ptr().write_value(ptr as u32);
565 regs.epin(i).maxcnt().write(|w| w.set_maxcnt(buf.len() as u8));
566
567 regs.events_endepin(i).write_value(0);
568
569 dma_start();
570 regs.tasks_startepin(i).write_value(1);
571 while regs.events_endepin(i).read() == 0 {}
572 dma_end();
573}
574
575impl<'d> driver::EndpointOut for Endpoint<'d, Out> {
576 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> {
577 let i = self.info.addr.index();
578 assert!(i != 0);
579
580 self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?;
581
582 unsafe { read_dma(self.regs, i, buf) }
583 }
584}
585
586impl<'d> driver::EndpointIn for Endpoint<'d, In> {
587 async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> {
588 let i = self.info.addr.index();
589 assert!(i != 0);
590
591 self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?;
592
593 unsafe { write_dma(self.regs, i, buf) }
594
595 Ok(())
596 }
597}
598
599pub struct ControlPipe<'d> {
601 regs: pac::usbd::Usbd,
602 max_packet_size: u16,
603 _phantom: PhantomData<&'d ()>,
604}
605
606impl<'d> driver::ControlPipe for ControlPipe<'d> {
607 fn max_packet_size(&self) -> usize {
608 usize::from(self.max_packet_size)
609 }
610
611 async fn setup(&mut self) -> [u8; 8] {
612 let regs = self.regs;
613
614 regs.shorts().write(|_| ());
616
617 regs.intenset().write(|w| w.set_ep0setup(true));
619 poll_fn(|cx| {
620 EP0_WAKER.register(cx.waker());
621 let regs = self.regs;
622 if regs.events_ep0setup().read() != 0 {
623 Poll::Ready(())
624 } else {
625 Poll::Pending
626 }
627 })
628 .await;
629
630 regs.events_ep0setup().write_value(0);
631
632 let mut buf = [0; 8];
633 buf[0] = regs.bmrequesttype().read().0 as u8;
634 buf[1] = regs.brequest().read().0 as u8;
635 buf[2] = regs.wvaluel().read().0 as u8;
636 buf[3] = regs.wvalueh().read().0 as u8;
637 buf[4] = regs.windexl().read().0 as u8;
638 buf[5] = regs.windexh().read().0 as u8;
639 buf[6] = regs.wlengthl().read().0 as u8;
640 buf[7] = regs.wlengthh().read().0 as u8;
641
642 buf
643 }
644
645 async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> {
646 let regs = self.regs;
647
648 regs.events_ep0datadone().write_value(0);
649
650 regs.tasks_ep0rcvout().write_value(1);
652
653 regs.intenset().write(|w| {
655 w.set_usbreset(true);
656 w.set_ep0setup(true);
657 w.set_ep0datadone(true);
658 });
659 poll_fn(|cx| {
660 EP0_WAKER.register(cx.waker());
661 let regs = self.regs;
662 if regs.events_ep0datadone().read() != 0 {
663 Poll::Ready(Ok(()))
664 } else if regs.events_usbreset().read() != 0 {
665 trace!("aborted control data_out: usb reset");
666 Poll::Ready(Err(EndpointError::Disabled))
667 } else if regs.events_ep0setup().read() != 0 {
668 trace!("aborted control data_out: received another SETUP");
669 Poll::Ready(Err(EndpointError::Disabled))
670 } else {
671 Poll::Pending
672 }
673 })
674 .await?;
675
676 unsafe { read_dma(self.regs, 0, buf) }
677 }
678
679 async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> {
680 let regs = self.regs;
681 regs.events_ep0datadone().write_value(0);
682
683 regs.shorts().write(|w| w.set_ep0datadone_ep0status(last));
684
685 unsafe { write_dma(self.regs, 0, buf) }
687
688 regs.intenset().write(|w| {
689 w.set_usbreset(true);
690 w.set_ep0setup(true);
691 w.set_ep0datadone(true);
692 });
693
694 poll_fn(|cx| {
695 cx.waker().wake_by_ref();
696 EP0_WAKER.register(cx.waker());
697 let regs = self.regs;
698 if regs.events_ep0datadone().read() != 0 {
699 Poll::Ready(Ok(()))
700 } else if regs.events_usbreset().read() != 0 {
701 trace!("aborted control data_in: usb reset");
702 Poll::Ready(Err(EndpointError::Disabled))
703 } else if regs.events_ep0setup().read() != 0 {
704 trace!("aborted control data_in: received another SETUP");
705 Poll::Ready(Err(EndpointError::Disabled))
706 } else {
707 Poll::Pending
708 }
709 })
710 .await
711 }
712
713 async fn accept(&mut self) {
714 let regs = self.regs;
715 regs.tasks_ep0status().write_value(1);
716 }
717
718 async fn reject(&mut self) {
719 let regs = self.regs;
720 regs.tasks_ep0stall().write_value(1);
721 }
722
723 async fn accept_set_address(&mut self, _addr: u8) {
724 self.accept().await;
725 }
727}
728
729fn dma_start() {
730 compiler_fence(Ordering::Release);
731}
732
733fn dma_end() {
734 compiler_fence(Ordering::Acquire);
735}
736
737struct Allocator {
738 used: u16,
739}
740
741impl Allocator {
742 fn new() -> Self {
743 Self { used: 0 }
744 }
745
746 fn allocate(
747 &mut self,
748 ep_type: EndpointType,
749 ep_addr: Option<EndpointAddress>,
750 ) -> Result<usize, driver::EndpointAllocError> {
751 let alloc_index = if let Some(addr) = ep_addr {
765 let requested_index = addr.index();
767 match ep_type {
769 EndpointType::Isochronous => {
770 if requested_index != 8 {
771 return Err(driver::EndpointAllocError);
772 }
773 }
774 EndpointType::Control => return Err(driver::EndpointAllocError),
775 EndpointType::Interrupt | EndpointType::Bulk => {
776 if requested_index < 1 || requested_index > 7 {
777 return Err(driver::EndpointAllocError);
778 }
779 }
780 }
781 requested_index
782 } else {
783 match ep_type {
785 EndpointType::Isochronous => 8,
786 EndpointType::Control => return Err(driver::EndpointAllocError),
787 EndpointType::Interrupt | EndpointType::Bulk => {
788 let ones = (self.used >> 1).trailing_ones() as usize;
790 if ones >= 7 {
791 return Err(driver::EndpointAllocError);
792 }
793 ones + 1
794 }
795 }
796 };
797
798 if self.used & (1 << alloc_index) != 0 {
799 return Err(driver::EndpointAllocError);
800 }
801
802 self.used |= 1 << alloc_index;
803
804 Ok(alloc_index)
805 }
806}
807
808pub(crate) trait SealedInstance {
809 fn regs() -> pac::usbd::Usbd;
810}
811
812#[allow(private_bounds)]
814pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
815 type Interrupt: interrupt::typelevel::Interrupt;
817}
818
819macro_rules! impl_usb {
820 ($type:ident, $pac_type:ident, $irq:ident) => {
821 impl crate::usb::SealedInstance for peripherals::$type {
822 fn regs() -> pac::usbd::Usbd {
823 pac::$pac_type
824 }
825 }
826 impl crate::usb::Instance for peripherals::$type {
827 type Interrupt = crate::interrupt::typelevel::$irq;
828 }
829 };
830}
831
832mod errata {
833
834 #[cfg(any(feature = "nrf52840", feature = "nrf52833", feature = "nrf52820"))]
836 unsafe fn poke(addr: u32, val: u32) {
837 (addr as *mut u32).write_volatile(val);
838 }
839
840 #[cfg(feature = "nrf52840")]
842 unsafe fn peek(addr: u32) -> u32 {
843 (addr as *mut u32).read_volatile()
844 }
845
846 pub fn pre_enable() {
847 #[cfg(any(feature = "nrf52840", feature = "nrf52833", feature = "nrf52820"))]
849 unsafe {
850 poke(0x4006EC00, 0x00009375);
851 poke(0x4006ED14, 0x00000003);
852 poke(0x4006EC00, 0x00009375);
853 }
854
855 pre_wakeup();
856 }
857
858 pub fn post_enable() {
859 post_wakeup();
860
861 #[cfg(any(feature = "nrf52840", feature = "nrf52833", feature = "nrf52820"))]
863 unsafe {
864 poke(0x4006EC00, 0x00009375);
865 poke(0x4006ED14, 0x00000000);
866 poke(0x4006EC00, 0x00009375);
867 }
868 }
869
870 pub fn pre_wakeup() {
871 #[cfg(feature = "nrf52840")]
874 unsafe {
875 if peek(0x4006EC00) == 0x00000000 {
876 poke(0x4006EC00, 0x00009375);
877 }
878
879 poke(0x4006EC14, 0x000000C0);
880 poke(0x4006EC00, 0x00009375);
881 }
882 }
883
884 pub fn post_wakeup() {
885 #[cfg(feature = "nrf52840")]
888 unsafe {
889 if peek(0x4006EC00) == 0x00000000 {
890 poke(0x4006EC00, 0x00009375);
891 }
892
893 poke(0x4006EC14, 0x00000000);
894 poke(0x4006EC00, 0x00009375);
895 }
896 }
897}