diff options
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/lib.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/mod.rs | 92 | ||||
| -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.rs | 44 | ||||
| -rw-r--r-- | embassy-stm32/src/usb_otg/mod.rs | 163 |
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; | |||
| 79 | pub mod uid; | 79 | pub mod uid; |
| 80 | #[cfg(usart)] | 80 | #[cfg(usart)] |
| 81 | pub mod usart; | 81 | pub mod usart; |
| 82 | #[cfg(usb)] | 82 | #[cfg(any(usb, otg))] |
| 83 | pub mod usb; | 83 | pub mod usb; |
| 84 | #[cfg(otg)] | ||
| 85 | pub mod usb_otg; | ||
| 86 | #[cfg(iwdg)] | 84 | #[cfg(iwdg)] |
| 87 | pub mod wdg; | 85 | pub 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 | ||
| 3 | use crate::interrupt; | 3 | #[cfg_attr(usb, path = "usb.rs")] |
| 4 | use crate::rcc::RccPeripheral; | 4 | #[cfg_attr(otg, path = "otg.rs")] |
| 5 | mod _version; | ||
| 6 | pub use _version::*; | ||
| 5 | 7 | ||
| 6 | mod usb; | 8 | use crate::interrupt::typelevel::Interrupt; |
| 7 | pub use usb::*; | 9 | use crate::rcc::sealed::RccPeripheral; |
| 8 | 10 | ||
| 9 | pub(crate) mod sealed { | 11 | /// clock, power initialization stuff that's common for USB and OTG. |
| 10 | pub trait Instance { | 12 | fn 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))] |
| 16 | pub 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(); |
| 22 | pin_trait!(DpPin, Instance); | 69 | } |
| 23 | pin_trait!(DmPin, Instance); | ||
| 24 | |||
| 25 | foreach_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 | }; |
| 12 | use futures::future::poll_fn; | 12 | use futures::future::poll_fn; |
| 13 | 13 | ||
| 14 | use super::*; | ||
| 15 | use crate::gpio::sealed::AFType; | 14 | use crate::gpio::sealed::AFType; |
| 16 | use crate::interrupt; | 15 | use crate::interrupt; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 16 | use crate::interrupt::typelevel::Interrupt; |
| @@ -561,8 +560,7 @@ impl<'d, T: Instance> Bus<'d, T> { | |||
| 561 | 560 | ||
| 562 | impl<'d, T: Instance> Bus<'d, T> { | 561 | impl<'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 { | |||
| 1469 | fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool { | 1432 | fn 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 | ||
| 1437 | const MAX_EP_COUNT: usize = 9; | ||
| 1438 | |||
| 1439 | pub(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. | ||
| 1451 | pub trait Instance: sealed::Instance + RccPeripheral + 'static { | ||
| 1452 | /// Interrupt for this USB instance. | ||
| 1453 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | // Internal PHY pins | ||
| 1457 | pin_trait!(DpPin, Instance); | ||
| 1458 | pin_trait!(DmPin, Instance); | ||
| 1459 | |||
| 1460 | // External PHY pins | ||
| 1461 | pin_trait!(UlpiClkPin, Instance); | ||
| 1462 | pin_trait!(UlpiDirPin, Instance); | ||
| 1463 | pin_trait!(UlpiNxtPin, Instance); | ||
| 1464 | pin_trait!(UlpiStpPin, Instance); | ||
| 1465 | pin_trait!(UlpiD0Pin, Instance); | ||
| 1466 | pin_trait!(UlpiD1Pin, Instance); | ||
| 1467 | pin_trait!(UlpiD2Pin, Instance); | ||
| 1468 | pin_trait!(UlpiD3Pin, Instance); | ||
| 1469 | pin_trait!(UlpiD4Pin, Instance); | ||
| 1470 | pin_trait!(UlpiD5Pin, Instance); | ||
| 1471 | pin_trait!(UlpiD6Pin, Instance); | ||
| 1472 | pin_trait!(UlpiD7Pin, Instance); | ||
| 1473 | |||
| 1474 | foreach_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 | ||
| 15 | use super::{DmPin, DpPin, Instance}; | ||
| 16 | use crate::interrupt::typelevel::Interrupt; | ||
| 17 | use crate::pac::usb::regs; | 15 | use crate::pac::usb::regs; |
| 18 | use crate::pac::usb::vals::{EpType, Stat}; | 16 | use crate::pac::usb::vals::{EpType, Stat}; |
| 19 | use crate::pac::USBRAM; | 17 | use 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 | |||
| 1051 | pub(crate) mod sealed { | ||
| 1052 | pub trait Instance { | ||
| 1053 | fn regs() -> crate::pac::usb::Usb; | ||
| 1054 | } | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | /// USB instance trait. | ||
| 1058 | pub trait Instance: sealed::Instance + RccPeripheral + 'static { | ||
| 1059 | /// Interrupt for this USB instance. | ||
| 1060 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | // Internal PHY pins | ||
| 1064 | pin_trait!(DpPin, Instance); | ||
| 1065 | pin_trait!(DmPin, Instance); | ||
| 1066 | |||
| 1067 | foreach_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 | |||
| 3 | use crate::rcc::RccPeripheral; | ||
| 4 | use crate::{interrupt, peripherals}; | ||
| 5 | |||
| 6 | mod usb; | ||
| 7 | pub use usb::*; | ||
| 8 | |||
| 9 | // Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps | ||
| 10 | const MAX_EP_COUNT: usize = 9; | ||
| 11 | |||
| 12 | pub(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. | ||
| 24 | pub trait Instance: sealed::Instance + RccPeripheral { | ||
| 25 | /// Interrupt for this USB OTG instance. | ||
| 26 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 27 | } | ||
| 28 | |||
| 29 | // Internal PHY pins | ||
| 30 | pin_trait!(DpPin, Instance); | ||
| 31 | pin_trait!(DmPin, Instance); | ||
| 32 | |||
| 33 | // External PHY pins | ||
| 34 | pin_trait!(UlpiClkPin, Instance); | ||
| 35 | pin_trait!(UlpiDirPin, Instance); | ||
| 36 | pin_trait!(UlpiNxtPin, Instance); | ||
| 37 | pin_trait!(UlpiStpPin, Instance); | ||
| 38 | pin_trait!(UlpiD0Pin, Instance); | ||
| 39 | pin_trait!(UlpiD1Pin, Instance); | ||
| 40 | pin_trait!(UlpiD2Pin, Instance); | ||
| 41 | pin_trait!(UlpiD3Pin, Instance); | ||
| 42 | pin_trait!(UlpiD4Pin, Instance); | ||
| 43 | pin_trait!(UlpiD5Pin, Instance); | ||
| 44 | pin_trait!(UlpiD6Pin, Instance); | ||
| 45 | pin_trait!(UlpiD7Pin, Instance); | ||
| 46 | |||
| 47 | foreach_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 | ); | ||
