From 68c4820ddecce77c2cbf67d20f5643f5d5ca18fc Mon Sep 17 00:00:00 2001 From: shakencodes Date: Fri, 6 Oct 2023 14:36:16 -0700 Subject: [PATCH] Add MCO support for stm32wl family --- embassy-stm32/build.rs | 31 ++++++------------------------- embassy-stm32/src/rcc/mco.rs | 24 +++++++++++++++++------- embassy-stm32/src/rcc/mod.rs | 4 ++-- 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index f825dbeebc..a6a83088cb 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -50,12 +50,10 @@ fn main() { // We *shouldn't* have singletons for these, but the HAL currently requires // singletons, for using with RccPeripheral to enable/disable clocks to them. "rcc" => { - if r.version.starts_with("h5") || r.version.starts_with("h7") || r.version.starts_with("f4") { - singletons.push("MCO1".to_string()); - singletons.push("MCO2".to_string()); - } - if r.version.starts_with("l4") { - singletons.push("MCO".to_string()); + for pin in p.pins { + if pin.signal.starts_with("MCO") { + singletons.push(pin.signal.replace('_', "").to_string()); + } } singletons.push(p.name.to_string()); } @@ -751,25 +749,8 @@ fn main() { let af = pin.af.unwrap_or(0); // MCO is special - if pin.signal.starts_with("MCO_") { - // Supported in H7 only for now - if regs.version.starts_with("h5") - || regs.version.starts_with("h7") - || regs.version.starts_with("f4") - { - peri = format_ident!("{}", pin.signal.replace('_', "")); - } else { - continue; - } - } - - if pin.signal == "MCO" { - // Supported in H7 only for now - if regs.version.starts_with("l4") { - peri = format_ident!("MCO"); - } else { - continue; - } + if pin.signal.starts_with("MCO") { + peri = format_ident!("{}", pin.signal.replace('_', "")); } g.extend(quote! { diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index 2453ed8211..85665fd2bc 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs @@ -4,14 +4,18 @@ use embassy_hal_internal::into_ref; use crate::gpio::sealed::AFType; use crate::gpio::Speed; +#[cfg(not(stm32wl))] pub use crate::pac::rcc::vals::{Mco1 as Mco1Source, Mco2 as Mco2Source}; +#[cfg(stm32wl)] +pub use crate::pac::rcc::vals::{Mcopre, Mcosel}; use crate::pac::RCC; use crate::{peripherals, Peripheral}; pub(crate) mod sealed { pub trait McoInstance { type Source; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8); + type Prescaler; + unsafe fn apply_clock_settings(source: Self::Source, prescaler: Self::Prescaler); } } @@ -20,11 +24,12 @@ pub trait McoInstance: sealed::McoInstance + 'static {} pin_trait!(McoPin, McoInstance); macro_rules! impl_peri { - ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { + ($peri:ident, $source:ident, $prescaler:ident, $set_source:ident, $set_prescaler:ident) => { impl sealed::McoInstance for peripherals::$peri { type Source = $source; + type Prescaler = $prescaler; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8) { + unsafe fn apply_clock_settings(source: Self::Source, prescaler: Self::Prescaler) { RCC.cfgr().modify(|w| { w.$set_source(source); w.$set_prescaler(prescaler); @@ -36,8 +41,12 @@ macro_rules! impl_peri { }; } -impl_peri!(MCO1, Mco1Source, set_mco1, set_mco1pre); -impl_peri!(MCO2, Mco2Source, set_mco2, set_mco2pre); +#[cfg(not(stm32wl))] +impl_peri!(MCO1, Mco1Source, u8, set_mco1, set_mco1pre); +#[cfg(not(stm32wl))] +impl_peri!(MCO2, Mco2Source, u8, set_mco2, set_mco2pre); +#[cfg(stm32wl)] +impl_peri!(MCO, Mcosel, Mcopre, set_mcosel, set_mcopre); pub struct Mco<'d, T: McoInstance> { phantom: PhantomData<&'d mut T>, @@ -46,15 +55,16 @@ pub struct Mco<'d, T: McoInstance> { impl<'d, T: McoInstance> Mco<'d, T> { /// Create a new MCO instance. /// - /// `prescaler` must be between 1 and 15. + /// `prescaler` must be between 1 and 15 for implementations not using Presel enum. pub fn new( _peri: impl Peripheral

+ 'd, pin: impl Peripheral

> + 'd, source: T::Source, - prescaler: u8, + prescaler: T::Prescaler, ) -> 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." diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index bf497ca124..f7e3ecdbcf 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -7,9 +7,9 @@ use crate::time::Hertz; pub(crate) mod bd; mod bus; -#[cfg(any(stm32h5, stm32h7))] +#[cfg(any(stm32h5, stm32h7, stm32wl))] mod mco; -#[cfg(any(stm32h5, stm32h7))] +#[cfg(any(stm32h5, stm32h7, stm32wl))] pub use mco::*; #[cfg_attr(rcc_f0, path = "f0.rs")]