aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-03-19 21:18:31 +0000
committerGitHub <[email protected]>2024-03-19 21:18:31 +0000
commit7bf4710f3fd89879eca6ca24ffdbd75c859971be (patch)
tree1389c39527c1513b86a9e727b223077305fcec25 /embassy-stm32/src
parent594d330a494a246bd2611e8793f34d08fde80b5c (diff)
parent4858a53a397c6e96f68340417a19274dd25b4ddc (diff)
Merge pull request #2711 from embassy-rs/stm32-usb-clock-check
stm32/usb: assert correct clock on init, set mux in all examples.
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/lib.rs8
-rw-r--r--embassy-stm32/src/usb/mod.rs92
-rw-r--r--embassy-stm32/src/usb/otg.rs (renamed from embassy-stm32/src/usb_otg/usb.rs)195
-rw-r--r--embassy-stm32/src/usb/usb.rs44
-rw-r--r--embassy-stm32/src/usb_otg/mod.rs163
5 files changed, 254 insertions, 248 deletions
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index b38b5c29d..9e26a3513 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -79,10 +79,8 @@ pub mod ucpd;
79pub mod uid; 79pub mod uid;
80#[cfg(usart)] 80#[cfg(usart)]
81pub mod usart; 81pub mod usart;
82#[cfg(usb)] 82#[cfg(any(usb, otg))]
83pub mod usb; 83pub mod usb;
84#[cfg(otg)]
85pub mod usb_otg;
86#[cfg(iwdg)] 84#[cfg(iwdg)]
87pub mod wdg; 85pub mod wdg;
88 86
@@ -107,10 +105,10 @@ pub use crate::_generated::interrupt;
107/// Example of how to bind one interrupt: 105/// Example of how to bind one interrupt:
108/// 106///
109/// ```rust,ignore 107/// ```rust,ignore
110/// use embassy_stm32::{bind_interrupts, usb_otg, peripherals}; 108/// use embassy_stm32::{bind_interrupts, usb, peripherals};
111/// 109///
112/// bind_interrupts!(struct Irqs { 110/// bind_interrupts!(struct Irqs {
113/// OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 111/// OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
114/// }); 112/// });
115/// ``` 113/// ```
116/// 114///
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs
index 4debd4e54..788f61f16 100644
--- a/embassy-stm32/src/usb/mod.rs
+++ b/embassy-stm32/src/usb/mod.rs
@@ -1,37 +1,69 @@
1//! Universal Serial Bus (USB) 1//! Universal Serial Bus (USB)
2 2
3use crate::interrupt; 3#[cfg_attr(usb, path = "usb.rs")]
4use crate::rcc::RccPeripheral; 4#[cfg_attr(otg, path = "otg.rs")]
5mod _version;
6pub use _version::*;
5 7
6mod usb; 8use crate::interrupt::typelevel::Interrupt;
7pub use usb::*; 9use crate::rcc::sealed::RccPeripheral;
8 10
9pub(crate) mod sealed { 11/// clock, power initialization stuff that's common for USB and OTG.
10 pub trait Instance { 12fn common_init<T: Instance>() {
11 fn regs() -> crate::pac::usb::Usb; 13 // Check the USB clock is enabled and running at exactly 48 MHz.
14 // frequency() will panic if not enabled
15 let freq = T::frequency();
16 // Check frequency is within the 0.25% tolerance allowed by the spec.
17 // Clock might not be exact 48Mhz due to rounding errors in PLL calculation, or if the user
18 // has tight clock restrictions due to something else (like audio).
19 if freq.0.abs_diff(48_000_000) > 120_000 {
20 panic!(
21 "USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.",
22 freq.0
23 )
12 } 24 }
13}
14 25
15/// USB instance trait. 26 #[cfg(any(stm32l4, stm32l5, stm32wb))]
16pub trait Instance: sealed::Instance + RccPeripheral + 'static { 27 critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true)));
17 /// Interrupt for this USB instance. 28
18 type Interrupt: interrupt::typelevel::Interrupt; 29 #[cfg(pwr_h5)]
19} 30 critical_section::with(|_| crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true)));
31
32 #[cfg(stm32h7)]
33 {
34 // If true, VDD33USB is generated by internal regulator from VDD50USB
35 // If false, VDD33USB and VDD50USB must be suplied directly with 3.3V (default on nucleo)
36 // TODO: unhardcode
37 let internal_regulator = false;
38
39 // Enable USB power
40 critical_section::with(|_| {
41 crate::pac::PWR.cr3().modify(|w| {
42 w.set_usb33den(true);
43 w.set_usbregen(internal_regulator);
44 })
45 });
46
47 // Wait for USB power to stabilize
48 while !crate::pac::PWR.cr3().read().usb33rdy() {}
49 }
50
51 #[cfg(stm32u5)]
52 {
53 // Enable USB power
54 critical_section::with(|_| {
55 crate::pac::PWR.svmcr().modify(|w| {
56 w.set_usv(true);
57 w.set_uvmen(true);
58 })
59 });
60
61 // Wait for USB power to stabilize
62 while !crate::pac::PWR.svmsr().read().vddusbrdy() {}
63 }
64
65 T::Interrupt::unpend();
66 unsafe { T::Interrupt::enable() };
20 67
21// Internal PHY pins 68 <T as RccPeripheral>::enable_and_reset();
22pin_trait!(DpPin, Instance); 69}
23pin_trait!(DmPin, Instance);
24
25foreach_interrupt!(
26 ($inst:ident, usb, $block:ident, LP, $irq:ident) => {
27 impl sealed::Instance for crate::peripherals::$inst {
28 fn regs() -> crate::pac::usb::Usb {
29 crate::pac::$inst
30 }
31 }
32
33 impl Instance for crate::peripherals::$inst {
34 type Interrupt = crate::interrupt::typelevel::$irq;
35 }
36 };
37);
diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb/otg.rs
index 373697ec8..80a08f3c5 100644
--- a/embassy-stm32/src/usb_otg/usb.rs
+++ b/embassy-stm32/src/usb/otg.rs
@@ -11,7 +11,6 @@ use embassy_usb_driver::{
11}; 11};
12use futures::future::poll_fn; 12use futures::future::poll_fn;
13 13
14use super::*;
15use crate::gpio::sealed::AFType; 14use crate::gpio::sealed::AFType;
16use crate::interrupt; 15use crate::interrupt;
17use crate::interrupt::typelevel::Interrupt; 16use crate::interrupt::typelevel::Interrupt;
@@ -561,8 +560,7 @@ impl<'d, T: Instance> Bus<'d, T> {
561 560
562impl<'d, T: Instance> Bus<'d, T> { 561impl<'d, T: Instance> Bus<'d, T> {
563 fn init(&mut self) { 562 fn init(&mut self) {
564 #[cfg(stm32l4)] 563 super::common_init::<T>();
565 critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true)));
566 564
567 #[cfg(stm32f7)] 565 #[cfg(stm32f7)]
568 { 566 {
@@ -590,22 +588,6 @@ impl<'d, T: Instance> Bus<'d, T> {
590 588
591 #[cfg(stm32h7)] 589 #[cfg(stm32h7)]
592 { 590 {
593 // If true, VDD33USB is generated by internal regulator from VDD50USB
594 // If false, VDD33USB and VDD50USB must be suplied directly with 3.3V (default on nucleo)
595 // TODO: unhardcode
596 let internal_regulator = false;
597
598 // Enable USB power
599 critical_section::with(|_| {
600 crate::pac::PWR.cr3().modify(|w| {
601 w.set_usb33den(true);
602 w.set_usbregen(internal_regulator);
603 })
604 });
605
606 // Wait for USB power to stabilize
607 while !crate::pac::PWR.cr3().read().usb33rdy() {}
608
609 // Enable ULPI clock if external PHY is used 591 // Enable ULPI clock if external PHY is used
610 let ulpien = !self.phy_type.internal(); 592 let ulpien = !self.phy_type.internal();
611 critical_section::with(|_| { 593 critical_section::with(|_| {
@@ -626,25 +608,6 @@ impl<'d, T: Instance> Bus<'d, T> {
626 }); 608 });
627 } 609 }
628 610
629 #[cfg(stm32u5)]
630 {
631 // Enable USB power
632 critical_section::with(|_| {
633 crate::pac::PWR.svmcr().modify(|w| {
634 w.set_usv(true);
635 w.set_uvmen(true);
636 })
637 });
638
639 // Wait for USB power to stabilize
640 while !crate::pac::PWR.svmsr().read().vddusbrdy() {}
641 }
642
643 <T as RccPeripheral>::enable_and_reset();
644
645 T::Interrupt::unpend();
646 unsafe { T::Interrupt::enable() };
647
648 let r = T::regs(); 611 let r = T::regs();
649 let core_id = r.cid().read().0; 612 let core_id = r.cid().read().0;
650 trace!("Core id {:08x}", core_id); 613 trace!("Core id {:08x}", core_id);
@@ -1469,3 +1432,159 @@ fn calculate_trdt(speed: vals::Dspd, ahb_freq: Hertz) -> u8 {
1469fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool { 1432fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool {
1470 r.cid().read().0 & 0xf000 == 0x1000 1433 r.cid().read().0 & 0xf000 == 0x1000
1471} 1434}
1435
1436// Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps
1437const MAX_EP_COUNT: usize = 9;
1438
1439pub(crate) mod sealed {
1440 pub trait Instance {
1441 const HIGH_SPEED: bool;
1442 const FIFO_DEPTH_WORDS: u16;
1443 const ENDPOINT_COUNT: usize;
1444
1445 fn regs() -> crate::pac::otg::Otg;
1446 fn state() -> &'static super::State<{ super::MAX_EP_COUNT }>;
1447 }
1448}
1449
1450/// USB instance trait.
1451pub trait Instance: sealed::Instance + RccPeripheral + 'static {
1452 /// Interrupt for this USB instance.
1453 type Interrupt: interrupt::typelevel::Interrupt;
1454}
1455
1456// Internal PHY pins
1457pin_trait!(DpPin, Instance);
1458pin_trait!(DmPin, Instance);
1459
1460// External PHY pins
1461pin_trait!(UlpiClkPin, Instance);
1462pin_trait!(UlpiDirPin, Instance);
1463pin_trait!(UlpiNxtPin, Instance);
1464pin_trait!(UlpiStpPin, Instance);
1465pin_trait!(UlpiD0Pin, Instance);
1466pin_trait!(UlpiD1Pin, Instance);
1467pin_trait!(UlpiD2Pin, Instance);
1468pin_trait!(UlpiD3Pin, Instance);
1469pin_trait!(UlpiD4Pin, Instance);
1470pin_trait!(UlpiD5Pin, Instance);
1471pin_trait!(UlpiD6Pin, Instance);
1472pin_trait!(UlpiD7Pin, Instance);
1473
1474foreach_interrupt!(
1475 (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => {
1476 impl sealed::Instance for crate::peripherals::USB_OTG_FS {
1477 const HIGH_SPEED: bool = false;
1478
1479 cfg_if::cfg_if! {
1480 if #[cfg(stm32f1)] {
1481 const FIFO_DEPTH_WORDS: u16 = 128;
1482 const ENDPOINT_COUNT: usize = 8;
1483 } else if #[cfg(any(
1484 stm32f2,
1485 stm32f401,
1486 stm32f405,
1487 stm32f407,
1488 stm32f411,
1489 stm32f415,
1490 stm32f417,
1491 stm32f427,
1492 stm32f429,
1493 stm32f437,
1494 stm32f439,
1495 ))] {
1496 const FIFO_DEPTH_WORDS: u16 = 320;
1497 const ENDPOINT_COUNT: usize = 4;
1498 } else if #[cfg(any(
1499 stm32f412,
1500 stm32f413,
1501 stm32f423,
1502 stm32f446,
1503 stm32f469,
1504 stm32f479,
1505 stm32f7,
1506 stm32l4,
1507 stm32u5,
1508 ))] {
1509 const FIFO_DEPTH_WORDS: u16 = 320;
1510 const ENDPOINT_COUNT: usize = 6;
1511 } else if #[cfg(stm32g0x1)] {
1512 const FIFO_DEPTH_WORDS: u16 = 512;
1513 const ENDPOINT_COUNT: usize = 8;
1514 } else if #[cfg(stm32h7)] {
1515 const FIFO_DEPTH_WORDS: u16 = 1024;
1516 const ENDPOINT_COUNT: usize = 9;
1517 } else if #[cfg(stm32u5)] {
1518 const FIFO_DEPTH_WORDS: u16 = 320;
1519 const ENDPOINT_COUNT: usize = 6;
1520 } else {
1521 compile_error!("USB_OTG_FS peripheral is not supported by this chip.");
1522 }
1523 }
1524
1525 fn regs() -> crate::pac::otg::Otg {
1526 crate::pac::USB_OTG_FS
1527 }
1528
1529 fn state() -> &'static State<MAX_EP_COUNT> {
1530 static STATE: State<MAX_EP_COUNT> = State::new();
1531 &STATE
1532 }
1533 }
1534
1535 impl Instance for crate::peripherals::USB_OTG_FS {
1536 type Interrupt = crate::interrupt::typelevel::$irq;
1537 }
1538 };
1539
1540 (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => {
1541 impl sealed::Instance for crate::peripherals::USB_OTG_HS {
1542 const HIGH_SPEED: bool = true;
1543
1544 cfg_if::cfg_if! {
1545 if #[cfg(any(
1546 stm32f2,
1547 stm32f405,
1548 stm32f407,
1549 stm32f415,
1550 stm32f417,
1551 stm32f427,
1552 stm32f429,
1553 stm32f437,
1554 stm32f439,
1555 ))] {
1556 const FIFO_DEPTH_WORDS: u16 = 1024;
1557 const ENDPOINT_COUNT: usize = 6;
1558 } else if #[cfg(any(
1559 stm32f446,
1560 stm32f469,
1561 stm32f479,
1562 stm32f7,
1563 stm32h7,
1564 ))] {
1565 const FIFO_DEPTH_WORDS: u16 = 1024;
1566 const ENDPOINT_COUNT: usize = 9;
1567 } else if #[cfg(stm32u5)] {
1568 const FIFO_DEPTH_WORDS: u16 = 1024;
1569 const ENDPOINT_COUNT: usize = 9;
1570 } else {
1571 compile_error!("USB_OTG_HS peripheral is not supported by this chip.");
1572 }
1573 }
1574
1575 fn regs() -> crate::pac::otg::Otg {
1576 // OTG HS registers are a superset of FS registers
1577 unsafe { crate::pac::otg::Otg::from_ptr(crate::pac::USB_OTG_HS.as_ptr()) }
1578 }
1579
1580 fn state() -> &'static State<MAX_EP_COUNT> {
1581 static STATE: State<MAX_EP_COUNT> = State::new();
1582 &STATE
1583 }
1584 }
1585
1586 impl Instance for crate::peripherals::USB_OTG_HS {
1587 type Interrupt = crate::interrupt::typelevel::$irq;
1588 }
1589 };
1590);
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index be321a19b..1fb2c9ebb 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -12,8 +12,6 @@ use embassy_usb_driver::{
12 Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, 12 Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported,
13}; 13};
14 14
15use super::{DmPin, DpPin, Instance};
16use crate::interrupt::typelevel::Interrupt;
17use crate::pac::usb::regs; 15use crate::pac::usb::regs;
18use crate::pac::usb::vals::{EpType, Stat}; 16use crate::pac::usb::vals::{EpType, Stat};
19use crate::pac::USBRAM; 17use crate::pac::USBRAM;
@@ -259,18 +257,10 @@ impl<'d, T: Instance> Driver<'d, T> {
259 dm: impl Peripheral<P = impl DmPin<T>> + 'd, 257 dm: impl Peripheral<P = impl DmPin<T>> + 'd,
260 ) -> Self { 258 ) -> Self {
261 into_ref!(dp, dm); 259 into_ref!(dp, dm);
262 T::Interrupt::unpend();
263 unsafe { T::Interrupt::enable() };
264 260
265 let regs = T::regs(); 261 super::common_init::<T>();
266
267 #[cfg(any(stm32l4, stm32l5, stm32wb))]
268 crate::pac::PWR.cr2().modify(|w| w.set_usv(true));
269 262
270 #[cfg(pwr_h5)] 263 let regs = T::regs();
271 crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true));
272
273 <T as RccPeripheral>::enable_and_reset();
274 264
275 regs.cntr().write(|w| { 265 regs.cntr().write(|w| {
276 w.set_pdwn(false); 266 w.set_pdwn(false);
@@ -1057,3 +1047,33 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
1057 }); 1047 });
1058 } 1048 }
1059} 1049}
1050
1051pub(crate) mod sealed {
1052 pub trait Instance {
1053 fn regs() -> crate::pac::usb::Usb;
1054 }
1055}
1056
1057/// USB instance trait.
1058pub trait Instance: sealed::Instance + RccPeripheral + 'static {
1059 /// Interrupt for this USB instance.
1060 type Interrupt: interrupt::typelevel::Interrupt;
1061}
1062
1063// Internal PHY pins
1064pin_trait!(DpPin, Instance);
1065pin_trait!(DmPin, Instance);
1066
1067foreach_interrupt!(
1068 ($inst:ident, usb, $block:ident, LP, $irq:ident) => {
1069 impl sealed::Instance for crate::peripherals::$inst {
1070 fn regs() -> crate::pac::usb::Usb {
1071 crate::pac::$inst
1072 }
1073 }
1074
1075 impl Instance for crate::peripherals::$inst {
1076 type Interrupt = crate::interrupt::typelevel::$irq;
1077 }
1078 };
1079);
diff --git a/embassy-stm32/src/usb_otg/mod.rs b/embassy-stm32/src/usb_otg/mod.rs
deleted file mode 100644
index 0649e684b..000000000
--- a/embassy-stm32/src/usb_otg/mod.rs
+++ /dev/null
@@ -1,163 +0,0 @@
1//! USB On The Go (OTG)
2
3use crate::rcc::RccPeripheral;
4use crate::{interrupt, peripherals};
5
6mod usb;
7pub use usb::*;
8
9// Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps
10const MAX_EP_COUNT: usize = 9;
11
12pub(crate) mod sealed {
13 pub trait Instance {
14 const HIGH_SPEED: bool;
15 const FIFO_DEPTH_WORDS: u16;
16 const ENDPOINT_COUNT: usize;
17
18 fn regs() -> crate::pac::otg::Otg;
19 fn state() -> &'static super::State<{ super::MAX_EP_COUNT }>;
20 }
21}
22
23/// USB OTG instance.
24pub trait Instance: sealed::Instance + RccPeripheral {
25 /// Interrupt for this USB OTG instance.
26 type Interrupt: interrupt::typelevel::Interrupt;
27}
28
29// Internal PHY pins
30pin_trait!(DpPin, Instance);
31pin_trait!(DmPin, Instance);
32
33// External PHY pins
34pin_trait!(UlpiClkPin, Instance);
35pin_trait!(UlpiDirPin, Instance);
36pin_trait!(UlpiNxtPin, Instance);
37pin_trait!(UlpiStpPin, Instance);
38pin_trait!(UlpiD0Pin, Instance);
39pin_trait!(UlpiD1Pin, Instance);
40pin_trait!(UlpiD2Pin, Instance);
41pin_trait!(UlpiD3Pin, Instance);
42pin_trait!(UlpiD4Pin, Instance);
43pin_trait!(UlpiD5Pin, Instance);
44pin_trait!(UlpiD6Pin, Instance);
45pin_trait!(UlpiD7Pin, Instance);
46
47foreach_interrupt!(
48 (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => {
49 impl sealed::Instance for peripherals::USB_OTG_FS {
50 const HIGH_SPEED: bool = false;
51
52 cfg_if::cfg_if! {
53 if #[cfg(stm32f1)] {
54 const FIFO_DEPTH_WORDS: u16 = 128;
55 const ENDPOINT_COUNT: usize = 8;
56 } else if #[cfg(any(
57 stm32f2,
58 stm32f401,
59 stm32f405,
60 stm32f407,
61 stm32f411,
62 stm32f415,
63 stm32f417,
64 stm32f427,
65 stm32f429,
66 stm32f437,
67 stm32f439,
68 ))] {
69 const FIFO_DEPTH_WORDS: u16 = 320;
70 const ENDPOINT_COUNT: usize = 4;
71 } else if #[cfg(any(
72 stm32f412,
73 stm32f413,
74 stm32f423,
75 stm32f446,
76 stm32f469,
77 stm32f479,
78 stm32f7,
79 stm32l4,
80 stm32u5,
81 ))] {
82 const FIFO_DEPTH_WORDS: u16 = 320;
83 const ENDPOINT_COUNT: usize = 6;
84 } else if #[cfg(stm32g0x1)] {
85 const FIFO_DEPTH_WORDS: u16 = 512;
86 const ENDPOINT_COUNT: usize = 8;
87 } else if #[cfg(stm32h7)] {
88 const FIFO_DEPTH_WORDS: u16 = 1024;
89 const ENDPOINT_COUNT: usize = 9;
90 } else if #[cfg(stm32u5)] {
91 const FIFO_DEPTH_WORDS: u16 = 320;
92 const ENDPOINT_COUNT: usize = 6;
93 } else {
94 compile_error!("USB_OTG_FS peripheral is not supported by this chip.");
95 }
96 }
97
98 fn regs() -> crate::pac::otg::Otg {
99 crate::pac::USB_OTG_FS
100 }
101
102 fn state() -> &'static State<MAX_EP_COUNT> {
103 static STATE: State<MAX_EP_COUNT> = State::new();
104 &STATE
105 }
106 }
107
108 impl Instance for peripherals::USB_OTG_FS {
109 type Interrupt = crate::interrupt::typelevel::$irq;
110 }
111 };
112
113 (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => {
114 impl sealed::Instance for peripherals::USB_OTG_HS {
115 const HIGH_SPEED: bool = true;
116
117 cfg_if::cfg_if! {
118 if #[cfg(any(
119 stm32f2,
120 stm32f405,
121 stm32f407,
122 stm32f415,
123 stm32f417,
124 stm32f427,
125 stm32f429,
126 stm32f437,
127 stm32f439,
128 ))] {
129 const FIFO_DEPTH_WORDS: u16 = 1024;
130 const ENDPOINT_COUNT: usize = 6;
131 } else if #[cfg(any(
132 stm32f446,
133 stm32f469,
134 stm32f479,
135 stm32f7,
136 stm32h7,
137 ))] {
138 const FIFO_DEPTH_WORDS: u16 = 1024;
139 const ENDPOINT_COUNT: usize = 9;
140 } else if #[cfg(stm32u5)] {
141 const FIFO_DEPTH_WORDS: u16 = 1024;
142 const ENDPOINT_COUNT: usize = 9;
143 } else {
144 compile_error!("USB_OTG_HS peripheral is not supported by this chip.");
145 }
146 }
147
148 fn regs() -> crate::pac::otg::Otg {
149 // OTG HS registers are a superset of FS registers
150 unsafe { crate::pac::otg::Otg::from_ptr(crate::pac::USB_OTG_HS.as_ptr()) }
151 }
152
153 fn state() -> &'static State<MAX_EP_COUNT> {
154 static STATE: State<MAX_EP_COUNT> = State::new();
155 &STATE
156 }
157 }
158
159 impl Instance for peripherals::USB_OTG_HS {
160 type Interrupt = crate::interrupt::typelevel::$irq;
161 }
162 };
163);