Add MCO support for stm32wl family

This commit is contained in:
shakencodes 2023-10-06 14:36:16 -07:00
parent f30fc949ff
commit 68c4820dde
3 changed files with 25 additions and 34 deletions

View File

@ -50,12 +50,10 @@ fn main() {
// We *shouldn't* have singletons for these, but the HAL currently requires // We *shouldn't* have singletons for these, but the HAL currently requires
// singletons, for using with RccPeripheral to enable/disable clocks to them. // singletons, for using with RccPeripheral to enable/disable clocks to them.
"rcc" => { "rcc" => {
if r.version.starts_with("h5") || r.version.starts_with("h7") || r.version.starts_with("f4") { for pin in p.pins {
singletons.push("MCO1".to_string()); if pin.signal.starts_with("MCO") {
singletons.push("MCO2".to_string()); singletons.push(pin.signal.replace('_', "").to_string());
} }
if r.version.starts_with("l4") {
singletons.push("MCO".to_string());
} }
singletons.push(p.name.to_string()); singletons.push(p.name.to_string());
} }
@ -751,25 +749,8 @@ fn main() {
let af = pin.af.unwrap_or(0); let af = pin.af.unwrap_or(0);
// MCO is special // MCO is special
if pin.signal.starts_with("MCO_") { if pin.signal.starts_with("MCO") {
// Supported in H7 only for now peri = format_ident!("{}", pin.signal.replace('_', ""));
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;
}
} }
g.extend(quote! { g.extend(quote! {

View File

@ -4,14 +4,18 @@ use embassy_hal_internal::into_ref;
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::gpio::Speed; use crate::gpio::Speed;
#[cfg(not(stm32wl))]
pub use crate::pac::rcc::vals::{Mco1 as Mco1Source, Mco2 as Mco2Source}; 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::pac::RCC;
use crate::{peripherals, Peripheral}; use crate::{peripherals, Peripheral};
pub(crate) mod sealed { pub(crate) mod sealed {
pub trait McoInstance { pub trait McoInstance {
type Source; 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); pin_trait!(McoPin, McoInstance);
macro_rules! impl_peri { 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 { impl sealed::McoInstance for peripherals::$peri {
type Source = $source; 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| { RCC.cfgr().modify(|w| {
w.$set_source(source); w.$set_source(source);
w.$set_prescaler(prescaler); w.$set_prescaler(prescaler);
@ -36,8 +41,12 @@ macro_rules! impl_peri {
}; };
} }
impl_peri!(MCO1, Mco1Source, set_mco1, set_mco1pre); #[cfg(not(stm32wl))]
impl_peri!(MCO2, Mco2Source, set_mco2, set_mco2pre); 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> { pub struct Mco<'d, T: McoInstance> {
phantom: PhantomData<&'d mut T>, phantom: PhantomData<&'d mut T>,
@ -46,15 +55,16 @@ pub struct Mco<'d, T: McoInstance> {
impl<'d, T: McoInstance> Mco<'d, T> { impl<'d, T: McoInstance> Mco<'d, T> {
/// Create a new MCO instance. /// 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( pub fn new(
_peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
pin: impl Peripheral<P = impl McoPin<T>> + 'd, pin: impl Peripheral<P = impl McoPin<T>> + 'd,
source: T::Source, source: T::Source,
prescaler: u8, prescaler: T::Prescaler,
) -> Self { ) -> Self {
into_ref!(pin); into_ref!(pin);
#[cfg(not(stm32wl))]
assert!( assert!(
1 <= prescaler && prescaler <= 15, 1 <= prescaler && prescaler <= 15,
"Mco prescaler must be between 1 and 15. Refer to the reference manual for more information." "Mco prescaler must be between 1 and 15. Refer to the reference manual for more information."

View File

@ -7,9 +7,9 @@ use crate::time::Hertz;
pub(crate) mod bd; pub(crate) mod bd;
mod bus; mod bus;
#[cfg(any(stm32h5, stm32h7))] #[cfg(any(stm32h5, stm32h7, stm32wl))]
mod mco; mod mco;
#[cfg(any(stm32h5, stm32h7))] #[cfg(any(stm32h5, stm32h7, stm32wl))]
pub use mco::*; pub use mco::*;
#[cfg_attr(rcc_f0, path = "f0.rs")] #[cfg_attr(rcc_f0, path = "f0.rs")]