aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--embassy-stm32/build.rs28
-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
-rw-r--r--examples/stm32f4/src/bin/usb_ethernet.rs9
-rw-r--r--examples/stm32f4/src/bin/usb_hid_keyboard.rs9
-rw-r--r--examples/stm32f4/src/bin/usb_hid_mouse.rs9
-rw-r--r--examples/stm32f4/src/bin/usb_raw.rs9
-rw-r--r--examples/stm32f4/src/bin/usb_serial.rs9
-rw-r--r--examples/stm32f7/src/bin/usb_serial.rs9
-rw-r--r--examples/stm32h7/src/bin/usb_serial.rs9
-rw-r--r--examples/stm32l4/src/bin/usb_serial.rs36
-rw-r--r--examples/stm32l5/src/bin/usb_ethernet.rs28
-rw-r--r--examples/stm32l5/src/bin/usb_hid_mouse.rs28
-rw-r--r--examples/stm32l5/src/bin/usb_serial.rs28
-rw-r--r--examples/stm32u5/src/bin/usb_serial.rs9
18 files changed, 375 insertions, 347 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index fe5236ed6..ee224da67 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -826,20 +826,20 @@ fn main() {
826 (("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)), 826 (("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)),
827 (("usb", "DP"), quote!(crate::usb::DpPin)), 827 (("usb", "DP"), quote!(crate::usb::DpPin)),
828 (("usb", "DM"), quote!(crate::usb::DmPin)), 828 (("usb", "DM"), quote!(crate::usb::DmPin)),
829 (("otg", "DP"), quote!(crate::usb_otg::DpPin)), 829 (("otg", "DP"), quote!(crate::usb::DpPin)),
830 (("otg", "DM"), quote!(crate::usb_otg::DmPin)), 830 (("otg", "DM"), quote!(crate::usb::DmPin)),
831 (("otg", "ULPI_CK"), quote!(crate::usb_otg::UlpiClkPin)), 831 (("otg", "ULPI_CK"), quote!(crate::usb::UlpiClkPin)),
832 (("otg", "ULPI_DIR"), quote!(crate::usb_otg::UlpiDirPin)), 832 (("otg", "ULPI_DIR"), quote!(crate::usb::UlpiDirPin)),
833 (("otg", "ULPI_NXT"), quote!(crate::usb_otg::UlpiNxtPin)), 833 (("otg", "ULPI_NXT"), quote!(crate::usb::UlpiNxtPin)),
834 (("otg", "ULPI_STP"), quote!(crate::usb_otg::UlpiStpPin)), 834 (("otg", "ULPI_STP"), quote!(crate::usb::UlpiStpPin)),
835 (("otg", "ULPI_D0"), quote!(crate::usb_otg::UlpiD0Pin)), 835 (("otg", "ULPI_D0"), quote!(crate::usb::UlpiD0Pin)),
836 (("otg", "ULPI_D1"), quote!(crate::usb_otg::UlpiD1Pin)), 836 (("otg", "ULPI_D1"), quote!(crate::usb::UlpiD1Pin)),
837 (("otg", "ULPI_D2"), quote!(crate::usb_otg::UlpiD2Pin)), 837 (("otg", "ULPI_D2"), quote!(crate::usb::UlpiD2Pin)),
838 (("otg", "ULPI_D3"), quote!(crate::usb_otg::UlpiD3Pin)), 838 (("otg", "ULPI_D3"), quote!(crate::usb::UlpiD3Pin)),
839 (("otg", "ULPI_D4"), quote!(crate::usb_otg::UlpiD4Pin)), 839 (("otg", "ULPI_D4"), quote!(crate::usb::UlpiD4Pin)),
840 (("otg", "ULPI_D5"), quote!(crate::usb_otg::UlpiD5Pin)), 840 (("otg", "ULPI_D5"), quote!(crate::usb::UlpiD5Pin)),
841 (("otg", "ULPI_D6"), quote!(crate::usb_otg::UlpiD6Pin)), 841 (("otg", "ULPI_D6"), quote!(crate::usb::UlpiD6Pin)),
842 (("otg", "ULPI_D7"), quote!(crate::usb_otg::UlpiD7Pin)), 842 (("otg", "ULPI_D7"), quote!(crate::usb::UlpiD7Pin)),
843 (("can", "TX"), quote!(crate::can::TxPin)), 843 (("can", "TX"), quote!(crate::can::TxPin)),
844 (("can", "RX"), quote!(crate::can::RxPin)), 844 (("can", "RX"), quote!(crate::can::RxPin)),
845 (("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)), 845 (("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)),
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);
diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs
index a196259a8..405cce6bc 100644
--- a/examples/stm32f4/src/bin/usb_ethernet.rs
+++ b/examples/stm32f4/src/bin/usb_ethernet.rs
@@ -7,8 +7,8 @@ use embassy_net::tcp::TcpSocket;
7use embassy_net::{Stack, StackResources}; 7use embassy_net::{Stack, StackResources};
8use embassy_stm32::rng::{self, Rng}; 8use embassy_stm32::rng::{self, Rng};
9use embassy_stm32::time::Hertz; 9use embassy_stm32::time::Hertz;
10use embassy_stm32::usb_otg::Driver; 10use embassy_stm32::usb::Driver;
11use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 11use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
12use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; 12use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState};
13use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; 13use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
14use embassy_usb::{Builder, UsbDevice}; 14use embassy_usb::{Builder, UsbDevice};
@@ -36,7 +36,7 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
36} 36}
37 37
38bind_interrupts!(struct Irqs { 38bind_interrupts!(struct Irqs {
39 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 39 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
40 HASH_RNG => rng::InterruptHandler<peripherals::RNG>; 40 HASH_RNG => rng::InterruptHandler<peripherals::RNG>;
41}); 41});
42 42
@@ -63,13 +63,14 @@ async fn main(spawner: Spawner) {
63 config.rcc.apb1_pre = APBPrescaler::DIV4; 63 config.rcc.apb1_pre = APBPrescaler::DIV4;
64 config.rcc.apb2_pre = APBPrescaler::DIV2; 64 config.rcc.apb2_pre = APBPrescaler::DIV2;
65 config.rcc.sys = Sysclk::PLL1_P; 65 config.rcc.sys = Sysclk::PLL1_P;
66 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
66 } 67 }
67 let p = embassy_stm32::init(config); 68 let p = embassy_stm32::init(config);
68 69
69 // Create the driver, from the HAL. 70 // Create the driver, from the HAL.
70 static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new(); 71 static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new();
71 let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..]; 72 let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..];
72 let mut config = embassy_stm32::usb_otg::Config::default(); 73 let mut config = embassy_stm32::usb::Config::default();
73 config.vbus_detection = true; 74 config.vbus_detection = true;
74 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); 75 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config);
75 76
diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs
index 19b5971fb..6c25a0a64 100644
--- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs
+++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs
@@ -8,8 +8,8 @@ use embassy_executor::Spawner;
8use embassy_stm32::exti::ExtiInput; 8use embassy_stm32::exti::ExtiInput;
9use embassy_stm32::gpio::Pull; 9use embassy_stm32::gpio::Pull;
10use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
11use embassy_stm32::usb_otg::Driver; 11use embassy_stm32::usb::Driver;
12use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 12use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
13use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; 13use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State};
14use embassy_usb::control::OutResponse; 14use embassy_usb::control::OutResponse;
15use embassy_usb::{Builder, Handler}; 15use embassy_usb::{Builder, Handler};
@@ -18,7 +18,7 @@ use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
18use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
19 19
20bind_interrupts!(struct Irqs { 20bind_interrupts!(struct Irqs {
21 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 21 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
22}); 22});
23 23
24#[embassy_executor::main] 24#[embassy_executor::main]
@@ -42,12 +42,13 @@ async fn main(_spawner: Spawner) {
42 config.rcc.apb1_pre = APBPrescaler::DIV4; 42 config.rcc.apb1_pre = APBPrescaler::DIV4;
43 config.rcc.apb2_pre = APBPrescaler::DIV2; 43 config.rcc.apb2_pre = APBPrescaler::DIV2;
44 config.rcc.sys = Sysclk::PLL1_P; 44 config.rcc.sys = Sysclk::PLL1_P;
45 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
45 } 46 }
46 let p = embassy_stm32::init(config); 47 let p = embassy_stm32::init(config);
47 48
48 // Create the driver, from the HAL. 49 // Create the driver, from the HAL.
49 let mut ep_out_buffer = [0u8; 256]; 50 let mut ep_out_buffer = [0u8; 256];
50 let mut config = embassy_stm32::usb_otg::Config::default(); 51 let mut config = embassy_stm32::usb::Config::default();
51 config.vbus_detection = true; 52 config.vbus_detection = true;
52 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 53 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
53 54
diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs
index c98792880..d4725d597 100644
--- a/examples/stm32f4/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32f4/src/bin/usb_hid_mouse.rs
@@ -4,8 +4,8 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
7use embassy_stm32::usb_otg::Driver; 7use embassy_stm32::usb::Driver;
8use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_time::Timer; 9use embassy_time::Timer;
10use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; 10use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State};
11use embassy_usb::control::OutResponse; 11use embassy_usb::control::OutResponse;
@@ -15,7 +15,7 @@ use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
15use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
16 16
17bind_interrupts!(struct Irqs { 17bind_interrupts!(struct Irqs {
18 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 18 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
19}); 19});
20 20
21#[embassy_executor::main] 21#[embassy_executor::main]
@@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) {
39 config.rcc.apb1_pre = APBPrescaler::DIV4; 39 config.rcc.apb1_pre = APBPrescaler::DIV4;
40 config.rcc.apb2_pre = APBPrescaler::DIV2; 40 config.rcc.apb2_pre = APBPrescaler::DIV2;
41 config.rcc.sys = Sysclk::PLL1_P; 41 config.rcc.sys = Sysclk::PLL1_P;
42 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
42 } 43 }
43 let p = embassy_stm32::init(config); 44 let p = embassy_stm32::init(config);
44 45
45 // Create the driver, from the HAL. 46 // Create the driver, from the HAL.
46 let mut ep_out_buffer = [0u8; 256]; 47 let mut ep_out_buffer = [0u8; 256];
47 let mut config = embassy_stm32::usb_otg::Config::default(); 48 let mut config = embassy_stm32::usb::Config::default();
48 config.vbus_detection = true; 49 config.vbus_detection = true;
49 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
50 51
diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs
index afff55187..15a98ff8b 100644
--- a/examples/stm32f4/src/bin/usb_raw.rs
+++ b/examples/stm32f4/src/bin/usb_raw.rs
@@ -52,8 +52,8 @@
52use defmt::*; 52use defmt::*;
53use embassy_executor::Spawner; 53use embassy_executor::Spawner;
54use embassy_stm32::time::Hertz; 54use embassy_stm32::time::Hertz;
55use embassy_stm32::usb_otg::Driver; 55use embassy_stm32::usb::Driver;
56use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 56use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
57use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; 57use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType};
58use embassy_usb::msos::{self, windows_version}; 58use embassy_usb::msos::{self, windows_version};
59use embassy_usb::types::InterfaceNumber; 59use embassy_usb::types::InterfaceNumber;
@@ -66,7 +66,7 @@ use {defmt_rtt as _, panic_probe as _};
66const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"]; 66const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"];
67 67
68bind_interrupts!(struct Irqs { 68bind_interrupts!(struct Irqs {
69 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 69 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
70}); 70});
71 71
72#[embassy_executor::main] 72#[embassy_executor::main]
@@ -92,12 +92,13 @@ async fn main(_spawner: Spawner) {
92 config.rcc.apb1_pre = APBPrescaler::DIV4; 92 config.rcc.apb1_pre = APBPrescaler::DIV4;
93 config.rcc.apb2_pre = APBPrescaler::DIV2; 93 config.rcc.apb2_pre = APBPrescaler::DIV2;
94 config.rcc.sys = Sysclk::PLL1_P; 94 config.rcc.sys = Sysclk::PLL1_P;
95 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
95 } 96 }
96 let p = embassy_stm32::init(config); 97 let p = embassy_stm32::init(config);
97 98
98 // Create the driver, from the HAL. 99 // Create the driver, from the HAL.
99 let mut ep_out_buffer = [0u8; 256]; 100 let mut ep_out_buffer = [0u8; 256];
100 let mut config = embassy_stm32::usb_otg::Config::default(); 101 let mut config = embassy_stm32::usb::Config::default();
101 config.vbus_detection = true; 102 config.vbus_detection = true;
102 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 103 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
103 104
diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs
index 58d994a61..6080b34a8 100644
--- a/examples/stm32f4/src/bin/usb_serial.rs
+++ b/examples/stm32f4/src/bin/usb_serial.rs
@@ -4,8 +4,8 @@
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
7use embassy_stm32::usb_otg::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
8use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
10use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
11use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -13,7 +13,7 @@ use futures::future::join;
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
14 14
15bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
16 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 16 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
17}); 17});
18 18
19#[embassy_executor::main] 19#[embassy_executor::main]
@@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) {
39 config.rcc.apb1_pre = APBPrescaler::DIV4; 39 config.rcc.apb1_pre = APBPrescaler::DIV4;
40 config.rcc.apb2_pre = APBPrescaler::DIV2; 40 config.rcc.apb2_pre = APBPrescaler::DIV2;
41 config.rcc.sys = Sysclk::PLL1_P; 41 config.rcc.sys = Sysclk::PLL1_P;
42 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
42 } 43 }
43 let p = embassy_stm32::init(config); 44 let p = embassy_stm32::init(config);
44 45
45 // Create the driver, from the HAL. 46 // Create the driver, from the HAL.
46 let mut ep_out_buffer = [0u8; 256]; 47 let mut ep_out_buffer = [0u8; 256];
47 let mut config = embassy_stm32::usb_otg::Config::default(); 48 let mut config = embassy_stm32::usb::Config::default();
48 config.vbus_detection = true; 49 config.vbus_detection = true;
49 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
50 51
diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs
index 97daf6bd1..26ecf3bc8 100644
--- a/examples/stm32f7/src/bin/usb_serial.rs
+++ b/examples/stm32f7/src/bin/usb_serial.rs
@@ -4,8 +4,8 @@
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
7use embassy_stm32::usb_otg::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
8use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
10use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
11use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -13,7 +13,7 @@ use futures::future::join;
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
14 14
15bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
16 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 16 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
17}); 17});
18 18
19#[embassy_executor::main] 19#[embassy_executor::main]
@@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) {
39 config.rcc.apb1_pre = APBPrescaler::DIV4; 39 config.rcc.apb1_pre = APBPrescaler::DIV4;
40 config.rcc.apb2_pre = APBPrescaler::DIV2; 40 config.rcc.apb2_pre = APBPrescaler::DIV2;
41 config.rcc.sys = Sysclk::PLL1_P; 41 config.rcc.sys = Sysclk::PLL1_P;
42 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
42 } 43 }
43 let p = embassy_stm32::init(config); 44 let p = embassy_stm32::init(config);
44 45
45 // Create the driver, from the HAL. 46 // Create the driver, from the HAL.
46 let mut ep_out_buffer = [0u8; 256]; 47 let mut ep_out_buffer = [0u8; 256];
47 let mut config = embassy_stm32::usb_otg::Config::default(); 48 let mut config = embassy_stm32::usb::Config::default();
48 config.vbus_detection = true; 49 config.vbus_detection = true;
49 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
50 51
diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs
index d81efb541..c3ddda72a 100644
--- a/examples/stm32h7/src/bin/usb_serial.rs
+++ b/examples/stm32h7/src/bin/usb_serial.rs
@@ -3,8 +3,8 @@
3 3
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::usb_otg::{Driver, Instance}; 6use embassy_stm32::usb::{Driver, Instance};
7use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 7use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
8use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 8use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
9use embassy_usb::driver::EndpointError; 9use embassy_usb::driver::EndpointError;
10use embassy_usb::Builder; 10use embassy_usb::Builder;
@@ -12,7 +12,7 @@ use futures::future::join;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14bind_interrupts!(struct Irqs { 14bind_interrupts!(struct Irqs {
15 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 15 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
16}); 16});
17 17
18#[embassy_executor::main] 18#[embassy_executor::main]
@@ -40,12 +40,13 @@ async fn main(_spawner: Spawner) {
40 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 40 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
41 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 41 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
42 config.rcc.voltage_scale = VoltageScale::Scale1; 42 config.rcc.voltage_scale = VoltageScale::Scale1;
43 config.rcc.mux.usbsel = mux::Usbsel::HSI48;
43 } 44 }
44 let p = embassy_stm32::init(config); 45 let p = embassy_stm32::init(config);
45 46
46 // Create the driver, from the HAL. 47 // Create the driver, from the HAL.
47 let mut ep_out_buffer = [0u8; 256]; 48 let mut ep_out_buffer = [0u8; 256];
48 let mut config = embassy_stm32::usb_otg::Config::default(); 49 let mut config = embassy_stm32::usb::Config::default();
49 config.vbus_detection = true; 50 config.vbus_detection = true;
50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 51 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
51 52
diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs
index 9247e56a1..047234d60 100644
--- a/examples/stm32l4/src/bin/usb_serial.rs
+++ b/examples/stm32l4/src/bin/usb_serial.rs
@@ -4,9 +4,8 @@
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use defmt_rtt as _; // global logger 5use defmt_rtt as _; // global logger
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::rcc::*; 7use embassy_stm32::usb::{Driver, Instance};
8use embassy_stm32::usb_otg::{Driver, Instance}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config};
10use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
11use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
12use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -14,7 +13,7 @@ use futures::future::join;
14use panic_probe as _; 13use panic_probe as _;
15 14
16bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
17 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 16 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
18}); 17});
19 18
20#[embassy_executor::main] 19#[embassy_executor::main]
@@ -22,23 +21,26 @@ async fn main(_spawner: Spawner) {
22 info!("Hello World!"); 21 info!("Hello World!");
23 22
24 let mut config = Config::default(); 23 let mut config = Config::default();
25 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB 24 {
26 config.rcc.sys = Sysclk::PLL1_R; 25 use embassy_stm32::rcc::*;
27 config.rcc.hsi = true; 26 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
28 config.rcc.pll = Some(Pll { 27 config.rcc.sys = Sysclk::PLL1_R;
29 source: PllSource::HSI, 28 config.rcc.hsi = true;
30 prediv: PllPreDiv::DIV1, 29 config.rcc.pll = Some(Pll {
31 mul: PllMul::MUL10, 30 source: PllSource::HSI,
32 divp: None, 31 prediv: PllPreDiv::DIV1,
33 divq: None, 32 mul: PllMul::MUL10,
34 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2) 33 divp: None,
35 }); 34 divq: None,
36 35 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2)
36 });
37 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
38 }
37 let p = embassy_stm32::init(config); 39 let p = embassy_stm32::init(config);
38 40
39 // Create the driver, from the HAL. 41 // Create the driver, from the HAL.
40 let mut ep_out_buffer = [0u8; 256]; 42 let mut ep_out_buffer = [0u8; 256];
41 let mut config = embassy_stm32::usb_otg::Config::default(); 43 let mut config = embassy_stm32::usb::Config::default();
42 config.vbus_detection = true; 44 config.vbus_detection = true;
43 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 45 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
44 46
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs
index f6d8b16d0..dc1e7022d 100644
--- a/examples/stm32l5/src/bin/usb_ethernet.rs
+++ b/examples/stm32l5/src/bin/usb_ethernet.rs
@@ -5,7 +5,6 @@ use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_net::tcp::TcpSocket; 6use embassy_net::tcp::TcpSocket;
7use embassy_net::{Stack, StackResources}; 7use embassy_net::{Stack, StackResources};
8use embassy_stm32::rcc::*;
9use embassy_stm32::rng::Rng; 8use embassy_stm32::rng::Rng;
10use embassy_stm32::usb::Driver; 9use embassy_stm32::usb::Driver;
11use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config}; 10use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config};
@@ -44,17 +43,22 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
44#[embassy_executor::main] 43#[embassy_executor::main]
45async fn main(spawner: Spawner) { 44async fn main(spawner: Spawner) {
46 let mut config = Config::default(); 45 let mut config = Config::default();
47 config.rcc.hsi = true; 46 {
48 config.rcc.sys = Sysclk::PLL1_R; 47 use embassy_stm32::rcc::*;
49 config.rcc.pll = Some(Pll { 48 config.rcc.hsi = true;
50 // 80Mhz clock (16 / 1 * 10 / 2) 49 config.rcc.sys = Sysclk::PLL1_R;
51 source: PllSource::HSI, 50 config.rcc.pll = Some(Pll {
52 prediv: PllPreDiv::DIV1, 51 // 80Mhz clock (16 / 1 * 10 / 2)
53 mul: PllMul::MUL10, 52 source: PllSource::HSI,
54 divp: None, 53 prediv: PllPreDiv::DIV1,
55 divq: None, 54 mul: PllMul::MUL10,
56 divr: Some(PllRDiv::DIV2), 55 divp: None,
57 }); 56 divq: None,
57 divr: Some(PllRDiv::DIV2),
58 });
59 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
60 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
61 }
58 let p = embassy_stm32::init(config); 62 let p = embassy_stm32::init(config);
59 63
60 // Create the driver, from the HAL. 64 // Create the driver, from the HAL.
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs
index c51ed96e0..b86fba455 100644
--- a/examples/stm32l5/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs
@@ -4,7 +4,6 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_futures::join::join; 6use embassy_futures::join::join;
7use embassy_stm32::rcc::*;
8use embassy_stm32::usb::Driver; 7use embassy_stm32::usb::Driver;
9use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_time::Timer; 9use embassy_time::Timer;
@@ -21,17 +20,22 @@ bind_interrupts!(struct Irqs {
21#[embassy_executor::main] 20#[embassy_executor::main]
22async fn main(_spawner: Spawner) { 21async fn main(_spawner: Spawner) {
23 let mut config = Config::default(); 22 let mut config = Config::default();
24 config.rcc.hsi = true; 23 {
25 config.rcc.sys = Sysclk::PLL1_R; 24 use embassy_stm32::rcc::*;
26 config.rcc.pll = Some(Pll { 25 config.rcc.hsi = true;
27 // 80Mhz clock (16 / 1 * 10 / 2) 26 config.rcc.sys = Sysclk::PLL1_R;
28 source: PllSource::HSI, 27 config.rcc.pll = Some(Pll {
29 prediv: PllPreDiv::DIV1, 28 // 80Mhz clock (16 / 1 * 10 / 2)
30 mul: PllMul::MUL10, 29 source: PllSource::HSI,
31 divp: None, 30 prediv: PllPreDiv::DIV1,
32 divq: None, 31 mul: PllMul::MUL10,
33 divr: Some(PllRDiv::DIV2), 32 divp: None,
34 }); 33 divq: None,
34 divr: Some(PllRDiv::DIV2),
35 });
36 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
37 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
38 }
35 let p = embassy_stm32::init(config); 39 let p = embassy_stm32::init(config);
36 40
37 // Create the driver, from the HAL. 41 // Create the driver, from the HAL.
diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs
index 87987f2ce..5e2378b58 100644
--- a/examples/stm32l5/src/bin/usb_serial.rs
+++ b/examples/stm32l5/src/bin/usb_serial.rs
@@ -4,7 +4,6 @@
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_futures::join::join; 6use embassy_futures::join::join;
7use embassy_stm32::rcc::*;
8use embassy_stm32::usb::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
9use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
@@ -19,17 +18,22 @@ bind_interrupts!(struct Irqs {
19#[embassy_executor::main] 18#[embassy_executor::main]
20async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
21 let mut config = Config::default(); 20 let mut config = Config::default();
22 config.rcc.hsi = true; 21 {
23 config.rcc.sys = Sysclk::PLL1_R; 22 use embassy_stm32::rcc::*;
24 config.rcc.pll = Some(Pll { 23 config.rcc.hsi = true;
25 // 80Mhz clock (16 / 1 * 10 / 2) 24 config.rcc.sys = Sysclk::PLL1_R;
26 source: PllSource::HSI, 25 config.rcc.pll = Some(Pll {
27 prediv: PllPreDiv::DIV1, 26 // 80Mhz clock (16 / 1 * 10 / 2)
28 mul: PllMul::MUL10, 27 source: PllSource::HSI,
29 divp: None, 28 prediv: PllPreDiv::DIV1,
30 divq: None, 29 mul: PllMul::MUL10,
31 divr: Some(PllRDiv::DIV2), 30 divp: None,
32 }); 31 divq: None,
32 divr: Some(PllRDiv::DIV2),
33 });
34 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
35 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
36 }
33 let p = embassy_stm32::init(config); 37 let p = embassy_stm32::init(config);
34 38
35 info!("Hello World!"); 39 info!("Hello World!");
diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs
index 61851e5a2..33e02ce3b 100644
--- a/examples/stm32u5/src/bin/usb_serial.rs
+++ b/examples/stm32u5/src/bin/usb_serial.rs
@@ -4,8 +4,8 @@
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use defmt_rtt as _; // global logger 5use defmt_rtt as _; // global logger
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::usb_otg::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
8use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
10use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
11use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -13,7 +13,7 @@ use futures::future::join;
13use panic_probe as _; 13use panic_probe as _;
14 14
15bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
16 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 16 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
17}); 17});
18 18
19#[embassy_executor::main] 19#[embassy_executor::main]
@@ -35,13 +35,14 @@ async fn main(_spawner: Spawner) {
35 config.rcc.sys = Sysclk::PLL1_R; 35 config.rcc.sys = Sysclk::PLL1_R;
36 config.rcc.voltage_range = VoltageScale::RANGE1; 36 config.rcc.voltage_range = VoltageScale::RANGE1;
37 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB 37 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
38 config.rcc.mux.iclksel = mux::Iclksel::HSI48; // USB uses ICLK
38 } 39 }
39 40
40 let p = embassy_stm32::init(config); 41 let p = embassy_stm32::init(config);
41 42
42 // Create the driver, from the HAL. 43 // Create the driver, from the HAL.
43 let mut ep_out_buffer = [0u8; 256]; 44 let mut ep_out_buffer = [0u8; 256];
44 let mut config = embassy_stm32::usb_otg::Config::default(); 45 let mut config = embassy_stm32::usb::Config::default();
45 config.vbus_detection = false; 46 config.vbus_detection = false;
46 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 47 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
47 48