diff options
| author | chemicstry <[email protected]> | 2023-02-23 17:38:52 +0200 |
|---|---|---|
| committer | chemicstry <[email protected]> | 2023-02-23 17:38:52 +0200 |
| commit | 896764bb8562b483ceecb39db2827061fc90d598 (patch) | |
| tree | 85b7cb86e1cc354d1453fed5d83af5e7c630bdbe | |
| parent | 42462681bd604750dfe8fa709453edf43c25b09d (diff) | |
stm32/sdmmc: Refactor TypeId into a macro
| -rw-r--r-- | embassy-stm32/src/sdmmc/mod.rs | 100 |
1 files changed, 61 insertions, 39 deletions
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 0bcd42bc2..2d91286fa 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs | |||
| @@ -491,7 +491,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { | |||
| 491 | bus_width, | 491 | bus_width, |
| 492 | &mut self.card, | 492 | &mut self.card, |
| 493 | &mut self.signalling, | 493 | &mut self.signalling, |
| 494 | Self::kernel_clock(), | 494 | T::kernel_clk(), |
| 495 | &mut self.clock, | 495 | &mut self.clock, |
| 496 | T::state(), | 496 | T::state(), |
| 497 | self.config.data_transfer_timeout, | 497 | self.config.data_transfer_timeout, |
| @@ -563,44 +563,6 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { | |||
| 563 | regs.data_interrupts(false); | 563 | regs.data_interrupts(false); |
| 564 | state.wake(); | 564 | state.wake(); |
| 565 | } | 565 | } |
| 566 | |||
| 567 | /// Returns kernel clock (SDIOCLK) for the SD-card facing domain | ||
| 568 | fn kernel_clock() -> Hertz { | ||
| 569 | cfg_if::cfg_if! { | ||
| 570 | // TODO, these could not be implemented, because required clocks are not exposed in RCC: | ||
| 571 | // - H7 uses pll1_q_ck or pll2_r_ck depending on SDMMCSEL | ||
| 572 | // - L1 uses pll48 | ||
| 573 | // - L4 uses clk48(pll48) | ||
| 574 | // - L4+, L5, U5 uses clk48(pll48) or PLLSAI3CLK(PLLP) depending on SDMMCSEL | ||
| 575 | if #[cfg(stm32f1)] { | ||
| 576 | // F1 uses AHB1(HCLK), which is correct in PAC | ||
| 577 | T::frequency() | ||
| 578 | } else if #[cfg(any(stm32f2, stm32f4))] { | ||
| 579 | // F2, F4 always use pll48 | ||
| 580 | critical_section::with(|_| unsafe { | ||
| 581 | crate::rcc::get_freqs().pll48 | ||
| 582 | }).expect("PLL48 is required for SDIO") | ||
| 583 | } else if #[cfg(stm32f7)] { | ||
| 584 | critical_section::with(|_| unsafe { | ||
| 585 | use core::any::TypeId; | ||
| 586 | let sdmmcsel = if TypeId::of::<T>() == TypeId::of::<crate::peripherals::SDMMC1>() { | ||
| 587 | crate::pac::RCC.dckcfgr2().read().sdmmc1sel() | ||
| 588 | } else { | ||
| 589 | crate::pac::RCC.dckcfgr2().read().sdmmc2sel() | ||
| 590 | }; | ||
| 591 | |||
| 592 | if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { | ||
| 593 | crate::rcc::get_freqs().sys | ||
| 594 | } else { | ||
| 595 | crate::rcc::get_freqs().pll48.expect("PLL48 is required for SDMMC") | ||
| 596 | } | ||
| 597 | }) | ||
| 598 | } else { | ||
| 599 | // Use default peripheral clock and hope it works | ||
| 600 | T::frequency() | ||
| 601 | } | ||
| 602 | } | ||
| 603 | } | ||
| 604 | } | 566 | } |
| 605 | 567 | ||
| 606 | impl<'d, T: Instance, Dma> Drop for Sdmmc<'d, T, Dma> { | 568 | impl<'d, T: Instance, Dma> Drop for Sdmmc<'d, T, Dma> { |
| @@ -1580,6 +1542,7 @@ pub(crate) mod sealed { | |||
| 1580 | 1542 | ||
| 1581 | fn inner() -> SdmmcInner; | 1543 | fn inner() -> SdmmcInner; |
| 1582 | fn state() -> &'static AtomicWaker; | 1544 | fn state() -> &'static AtomicWaker; |
| 1545 | fn kernel_clk() -> Hertz; | ||
| 1583 | } | 1546 | } |
| 1584 | 1547 | ||
| 1585 | pub trait Pins<T: Instance> {} | 1548 | pub trait Pins<T: Instance> {} |
| @@ -1607,6 +1570,61 @@ cfg_if::cfg_if! { | |||
| 1607 | } | 1570 | } |
| 1608 | } | 1571 | } |
| 1609 | 1572 | ||
| 1573 | cfg_if::cfg_if! { | ||
| 1574 | // TODO, these could not be implemented, because required clocks are not exposed in RCC: | ||
| 1575 | // - H7 uses pll1_q_ck or pll2_r_ck depending on SDMMCSEL | ||
| 1576 | // - L1 uses pll48 | ||
| 1577 | // - L4 uses clk48(pll48) | ||
| 1578 | // - L4+, L5, U5 uses clk48(pll48) or PLLSAI3CLK(PLLP) depending on SDMMCSEL | ||
| 1579 | if #[cfg(stm32f1)] { | ||
| 1580 | // F1 uses AHB1(HCLK), which is correct in PAC | ||
| 1581 | macro_rules! kernel_clk { | ||
| 1582 | ($inst:ident) => { | ||
| 1583 | peripherals::$inst::frequency() | ||
| 1584 | } | ||
| 1585 | } | ||
| 1586 | } else if #[cfg(any(stm32f2, stm32f4))] { | ||
| 1587 | // F2, F4 always use pll48 | ||
| 1588 | macro_rules! kernel_clk { | ||
| 1589 | ($inst:ident) => { | ||
| 1590 | critical_section::with(|_| unsafe { | ||
| 1591 | crate::rcc::get_freqs().pll48 | ||
| 1592 | }).expect("PLL48 is required for SDIO") | ||
| 1593 | } | ||
| 1594 | } | ||
| 1595 | } else if #[cfg(stm32f7)] { | ||
| 1596 | macro_rules! kernel_clk { | ||
| 1597 | (SDMMC1) => { | ||
| 1598 | critical_section::with(|_| unsafe { | ||
| 1599 | let sdmmcsel = crate::pac::RCC.dckcfgr2().read().sdmmc1sel(); | ||
| 1600 | if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { | ||
| 1601 | crate::rcc::get_freqs().sys | ||
| 1602 | } else { | ||
| 1603 | crate::rcc::get_freqs().pll48.expect("PLL48 is required for SDMMC") | ||
| 1604 | } | ||
| 1605 | }) | ||
| 1606 | }; | ||
| 1607 | (SDMMC2) => { | ||
| 1608 | critical_section::with(|_| unsafe { | ||
| 1609 | let sdmmcsel = crate::pac::RCC.dckcfgr2().read().sdmmc2sel(); | ||
| 1610 | if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { | ||
| 1611 | crate::rcc::get_freqs().sys | ||
| 1612 | } else { | ||
| 1613 | crate::rcc::get_freqs().pll48.expect("PLL48 is required for SDMMC") | ||
| 1614 | } | ||
| 1615 | }) | ||
| 1616 | }; | ||
| 1617 | } | ||
| 1618 | } else { | ||
| 1619 | // Use default peripheral clock and hope it works | ||
| 1620 | macro_rules! kernel_clk { | ||
| 1621 | ($inst:ident) => { | ||
| 1622 | peripherals::$inst::frequency() | ||
| 1623 | } | ||
| 1624 | } | ||
| 1625 | } | ||
| 1626 | } | ||
| 1627 | |||
| 1610 | foreach_peripheral!( | 1628 | foreach_peripheral!( |
| 1611 | (sdmmc, $inst:ident) => { | 1629 | (sdmmc, $inst:ident) => { |
| 1612 | impl sealed::Instance for peripherals::$inst { | 1630 | impl sealed::Instance for peripherals::$inst { |
| @@ -1621,6 +1639,10 @@ foreach_peripheral!( | |||
| 1621 | static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new(); | 1639 | static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new(); |
| 1622 | &WAKER | 1640 | &WAKER |
| 1623 | } | 1641 | } |
| 1642 | |||
| 1643 | fn kernel_clk() -> Hertz { | ||
| 1644 | kernel_clk!($inst) | ||
| 1645 | } | ||
| 1624 | } | 1646 | } |
| 1625 | 1647 | ||
| 1626 | impl Instance for peripherals::$inst {} | 1648 | impl Instance for peripherals::$inst {} |
