diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 5258e4c7..20c5155a 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f0f06b4c95bd9e185e4aa5f2e1d4b76ba84f1594" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-a7bf7f02d1e0bc720c24dbb8881677a298890365" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f0f06b4c95bd9e185e4aa5f2e1d4b76ba84f1594", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-a7bf7f02d1e0bc720c24dbb8881677a298890365", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index a6a83088..3f85d9e6 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -52,7 +52,11 @@ fn main() { "rcc" => { for pin in p.pins { if pin.signal.starts_with("MCO") { - singletons.push(pin.signal.replace('_', "").to_string()); + let name = pin.signal.replace('_', "").to_string(); + if !singletons.contains(&name) { + println!("cargo:rustc-cfg={}", name.to_ascii_lowercase()); + singletons.push(name); + } } } singletons.push(p.name.to_string()); diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index 5ba958a0..ad106ce3 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -1,16 +1,8 @@ -use core::marker::PhantomData; - -use embassy_hal_internal::into_ref; -use stm32_metapac::rcc::vals::{Mco1, Mco2, Mcopre}; - -use crate::gpio::sealed::AFType; -use crate::gpio::Speed; use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; -use crate::{peripherals, Peripheral}; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); @@ -197,164 +189,6 @@ fn setup_pll( } } -pub enum McoClock { - DIV1, - DIV2, - DIV3, - DIV4, - DIV5, -} - -impl McoClock { - fn into_raw(&self) -> Mcopre { - match self { - McoClock::DIV1 => Mcopre::DIV1, - McoClock::DIV2 => Mcopre::DIV2, - McoClock::DIV3 => Mcopre::DIV3, - McoClock::DIV4 => Mcopre::DIV4, - McoClock::DIV5 => Mcopre::DIV5, - } - } -} - -#[derive(Copy, Clone)] -pub enum Mco1Source { - Hsi, - Lse, - Hse, - Pll, -} - -impl Default for Mco1Source { - fn default() -> Self { - Self::Hsi - } -} - -pub trait McoSource { - type Raw; - - fn into_raw(&self) -> Self::Raw; -} - -impl McoSource for Mco1Source { - type Raw = Mco1; - fn into_raw(&self) -> Self::Raw { - match self { - Mco1Source::Hsi => Mco1::HSI, - Mco1Source::Lse => Mco1::LSE, - Mco1Source::Hse => Mco1::HSE, - Mco1Source::Pll => Mco1::PLL, - } - } -} - -#[derive(Copy, Clone)] -pub enum Mco2Source { - SysClk, - Plli2s, - Hse, - Pll, -} - -impl Default for Mco2Source { - fn default() -> Self { - Self::SysClk - } -} - -impl McoSource for Mco2Source { - type Raw = Mco2; - fn into_raw(&self) -> Self::Raw { - match self { - Mco2Source::SysClk => Mco2::SYSCLK, - Mco2Source::Plli2s => Mco2::PLLI2S, - Mco2Source::Hse => Mco2::HSE, - Mco2Source::Pll => Mco2::PLL, - } - } -} - -pub(crate) mod sealed { - use stm32_metapac::rcc::vals::Mcopre; - pub trait McoInstance { - type Source; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre); - } -} - -pub trait McoInstance: sealed::McoInstance + 'static {} - -pin_trait!(McoPin, McoInstance); - -impl sealed::McoInstance for peripherals::MCO1 { - type Source = Mco1; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre) { - RCC.cfgr().modify(|w| { - w.set_mco1(source); - w.set_mco1pre(prescaler); - }); - match source { - Mco1::PLL => { - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - } - Mco1::HSI => { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - } - _ => {} - } - } -} -impl McoInstance for peripherals::MCO1 {} - -impl sealed::McoInstance for peripherals::MCO2 { - type Source = Mco2; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre) { - RCC.cfgr().modify(|w| { - w.set_mco2(source); - w.set_mco2pre(prescaler); - }); - match source { - Mco2::PLL => { - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - } - #[cfg(not(stm32f410))] - Mco2::PLLI2S => { - RCC.cr().modify(|w| w.set_plli2son(true)); - while !RCC.cr().read().plli2srdy() {} - } - _ => {} - } - } -} -impl McoInstance for peripherals::MCO2 {} - -pub struct Mco<'d, T: McoInstance> { - phantom: PhantomData<&'d mut T>, -} - -impl<'d, T: McoInstance> Mco<'d, T> { - pub fn new( - _peri: impl Peripheral
+ 'd, - pin: impl Peripheral
> + 'd,
- source: impl McoSource + 'd,
- pin: impl Peripheral > + 'd,
- source: impl McoSource + 'd,
pin: impl Peripheral > + 'd,
source: T::Source,
- prescaler: T::Prescaler,
+ #[cfg(not(stm32f1))] prescaler: McoPrescaler,
) -> Self {
into_ref!(pin);
- #[cfg(not(stm32wl))]
- assert!(
- 1 <= prescaler && prescaler <= 15,
- "Mco prescaler must be between 1 and 15. Refer to the reference manual for more information."
- );
-
critical_section::with(|_| unsafe {
- T::apply_clock_settings(source, prescaler);
+ T::apply_clock_settings(
+ source,
+ #[cfg(not(stm32f1))]
+ prescaler,
+ );
pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
pin.set_speed(Speed::VeryHigh);
});
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index f7e3ecdb..a3299089 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -7,9 +7,7 @@ use crate::time::Hertz;
pub(crate) mod bd;
mod bus;
-#[cfg(any(stm32h5, stm32h7, stm32wl))]
mod mco;
-#[cfg(any(stm32h5, stm32h7, stm32wl))]
pub use mco::*;
#[cfg_attr(rcc_f0, path = "f0.rs")]
diff --git a/examples/stm32f4/src/bin/mco.rs b/examples/stm32f4/src/bin/mco.rs
index 2b9ceebc..5144a78c 100644
--- a/examples/stm32f4/src/bin/mco.rs
+++ b/examples/stm32f4/src/bin/mco.rs
@@ -5,7 +5,7 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed};
-use embassy_stm32::rcc::{Mco, Mco1Source, Mco2Source, McoClock};
+use embassy_stm32::rcc::{Mco, Mco1Source, Mco2Source, McoPrescaler};
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@@ -14,8 +14,8 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
- let _mco1 = Mco::new(p.MCO1, p.PA8, Mco1Source::Hsi, McoClock::DIV1);
- let _mco2 = Mco::new(p.MCO2, p.PC9, Mco2Source::Pll, McoClock::DIV4);
+ let _mco1 = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV1);
+ let _mco2 = Mco::new(p.MCO2, p.PC9, Mco2Source::PLL, McoPrescaler::DIV4);
let mut led = Output::new(p.PB7, Level::High, Speed::Low);
loop {
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs
index de8ddc29..0ea8b449 100644
--- a/examples/stm32h7/src/bin/camera.rs
+++ b/examples/stm32h7/src/bin/camera.rs
@@ -6,7 +6,7 @@ use embassy_executor::Spawner;
use embassy_stm32::dcmi::{self, *};
use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_stm32::i2c::I2c;
-use embassy_stm32::rcc::{Mco, Mco1Source};
+use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler};
use embassy_stm32::time::khz;
use embassy_stm32::{bind_interrupts, i2c, peripherals, Config};
use embassy_time::{Duration, Timer};
@@ -49,7 +49,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(config);
defmt::info!("Hello World!");
- let mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, 3);
+ let mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV3);
let mut led = Output::new(p.PE3, Level::High, Speed::Low);
let cam_i2c = I2c::new(
diff --git a/examples/stm32h7/src/bin/mco.rs b/examples/stm32h7/src/bin/mco.rs
index 9d6d805a..de89aee2 100644
--- a/examples/stm32h7/src/bin/mco.rs
+++ b/examples/stm32h7/src/bin/mco.rs
@@ -5,7 +5,7 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed};
-use embassy_stm32::rcc::{Mco, Mco1Source};
+use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler};
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) {
let mut led = Output::new(p.PB14, Level::High, Speed::Low);
- let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, 8);
+ let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV8);
loop {
info!("high");
diff --git a/examples/stm32l4/src/bin/mco.rs b/examples/stm32l4/src/bin/mco.rs
index dea0c66e..8d35af78 100644
--- a/examples/stm32l4/src/bin/mco.rs
+++ b/examples/stm32l4/src/bin/mco.rs
@@ -5,7 +5,7 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed};
-use embassy_stm32::rcc::{Mco, Mco1Source, McoClock};
+use embassy_stm32::rcc::{Mco, McoPrescaler, McoSource};
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
- let _mco = Mco::new(p.MCO, p.PA8, Mco1Source::Hsi16, McoClock::DIV1);
+ let _mco = Mco::new(p.MCO, p.PA8, McoSource::HSI16, McoPrescaler::DIV1);
let mut led = Output::new(p.PB14, Level::High, Speed::Low);