diff options
| author | shakencodes <[email protected]> | 2023-10-06 14:36:16 -0700 |
|---|---|---|
| committer | shakencodes <[email protected]> | 2023-10-06 14:37:36 -0700 |
| commit | 68c4820ddecce77c2cbf67d20f5643f5d5ca18fc (patch) | |
| tree | 3529e0d30c5c819227955f91ca586f58be26b76c /embassy-stm32 | |
| parent | f30fc949ff34683bd9b9330d09583da4a35428ea (diff) | |
Add MCO support for stm32wl family
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/build.rs | 31 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mco.rs | 24 | ||||
| -rw-r--r-- | 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 f825dbeeb..a6a83088c 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -50,12 +50,10 @@ fn main() { | |||
| 50 | // We *shouldn't* have singletons for these, but the HAL currently requires | 50 | // We *shouldn't* have singletons for these, but the HAL currently requires |
| 51 | // singletons, for using with RccPeripheral to enable/disable clocks to them. | 51 | // singletons, for using with RccPeripheral to enable/disable clocks to them. |
| 52 | "rcc" => { | 52 | "rcc" => { |
| 53 | if r.version.starts_with("h5") || r.version.starts_with("h7") || r.version.starts_with("f4") { | 53 | for pin in p.pins { |
| 54 | singletons.push("MCO1".to_string()); | 54 | if pin.signal.starts_with("MCO") { |
| 55 | singletons.push("MCO2".to_string()); | 55 | singletons.push(pin.signal.replace('_', "").to_string()); |
| 56 | } | 56 | } |
| 57 | if r.version.starts_with("l4") { | ||
| 58 | singletons.push("MCO".to_string()); | ||
| 59 | } | 57 | } |
| 60 | singletons.push(p.name.to_string()); | 58 | singletons.push(p.name.to_string()); |
| 61 | } | 59 | } |
| @@ -751,25 +749,8 @@ fn main() { | |||
| 751 | let af = pin.af.unwrap_or(0); | 749 | let af = pin.af.unwrap_or(0); |
| 752 | 750 | ||
| 753 | // MCO is special | 751 | // MCO is special |
| 754 | if pin.signal.starts_with("MCO_") { | 752 | if pin.signal.starts_with("MCO") { |
| 755 | // Supported in H7 only for now | 753 | peri = format_ident!("{}", pin.signal.replace('_', "")); |
| 756 | if regs.version.starts_with("h5") | ||
| 757 | || regs.version.starts_with("h7") | ||
| 758 | || regs.version.starts_with("f4") | ||
| 759 | { | ||
| 760 | peri = format_ident!("{}", pin.signal.replace('_', "")); | ||
| 761 | } else { | ||
| 762 | continue; | ||
| 763 | } | ||
| 764 | } | ||
| 765 | |||
| 766 | if pin.signal == "MCO" { | ||
| 767 | // Supported in H7 only for now | ||
| 768 | if regs.version.starts_with("l4") { | ||
| 769 | peri = format_ident!("MCO"); | ||
| 770 | } else { | ||
| 771 | continue; | ||
| 772 | } | ||
| 773 | } | 754 | } |
| 774 | 755 | ||
| 775 | g.extend(quote! { | 756 | g.extend(quote! { |
diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index 2453ed821..85665fd2b 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; | |||
| 4 | 4 | ||
| 5 | use crate::gpio::sealed::AFType; | 5 | use crate::gpio::sealed::AFType; |
| 6 | use crate::gpio::Speed; | 6 | use crate::gpio::Speed; |
| 7 | #[cfg(not(stm32wl))] | ||
| 7 | pub use crate::pac::rcc::vals::{Mco1 as Mco1Source, Mco2 as Mco2Source}; | 8 | pub use crate::pac::rcc::vals::{Mco1 as Mco1Source, Mco2 as Mco2Source}; |
| 9 | #[cfg(stm32wl)] | ||
| 10 | pub use crate::pac::rcc::vals::{Mcopre, Mcosel}; | ||
| 8 | use crate::pac::RCC; | 11 | use crate::pac::RCC; |
| 9 | use crate::{peripherals, Peripheral}; | 12 | use crate::{peripherals, Peripheral}; |
| 10 | 13 | ||
| 11 | pub(crate) mod sealed { | 14 | pub(crate) mod sealed { |
| 12 | pub trait McoInstance { | 15 | pub trait McoInstance { |
| 13 | type Source; | 16 | type Source; |
| 14 | unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8); | 17 | type Prescaler; |
| 18 | unsafe fn apply_clock_settings(source: Self::Source, prescaler: Self::Prescaler); | ||
| 15 | } | 19 | } |
| 16 | } | 20 | } |
| 17 | 21 | ||
| @@ -20,11 +24,12 @@ pub trait McoInstance: sealed::McoInstance + 'static {} | |||
| 20 | pin_trait!(McoPin, McoInstance); | 24 | pin_trait!(McoPin, McoInstance); |
| 21 | 25 | ||
| 22 | macro_rules! impl_peri { | 26 | macro_rules! impl_peri { |
| 23 | ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { | 27 | ($peri:ident, $source:ident, $prescaler:ident, $set_source:ident, $set_prescaler:ident) => { |
| 24 | impl sealed::McoInstance for peripherals::$peri { | 28 | impl sealed::McoInstance for peripherals::$peri { |
| 25 | type Source = $source; | 29 | type Source = $source; |
| 30 | type Prescaler = $prescaler; | ||
| 26 | 31 | ||
| 27 | unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8) { | 32 | unsafe fn apply_clock_settings(source: Self::Source, prescaler: Self::Prescaler) { |
| 28 | RCC.cfgr().modify(|w| { | 33 | RCC.cfgr().modify(|w| { |
| 29 | w.$set_source(source); | 34 | w.$set_source(source); |
| 30 | w.$set_prescaler(prescaler); | 35 | w.$set_prescaler(prescaler); |
| @@ -36,8 +41,12 @@ macro_rules! impl_peri { | |||
| 36 | }; | 41 | }; |
| 37 | } | 42 | } |
| 38 | 43 | ||
| 39 | impl_peri!(MCO1, Mco1Source, set_mco1, set_mco1pre); | 44 | #[cfg(not(stm32wl))] |
| 40 | impl_peri!(MCO2, Mco2Source, set_mco2, set_mco2pre); | 45 | impl_peri!(MCO1, Mco1Source, u8, set_mco1, set_mco1pre); |
| 46 | #[cfg(not(stm32wl))] | ||
| 47 | impl_peri!(MCO2, Mco2Source, u8, set_mco2, set_mco2pre); | ||
| 48 | #[cfg(stm32wl)] | ||
| 49 | impl_peri!(MCO, Mcosel, Mcopre, set_mcosel, set_mcopre); | ||
| 41 | 50 | ||
| 42 | pub struct Mco<'d, T: McoInstance> { | 51 | pub struct Mco<'d, T: McoInstance> { |
| 43 | phantom: PhantomData<&'d mut T>, | 52 | phantom: PhantomData<&'d mut T>, |
| @@ -46,15 +55,16 @@ pub struct Mco<'d, T: McoInstance> { | |||
| 46 | impl<'d, T: McoInstance> Mco<'d, T> { | 55 | impl<'d, T: McoInstance> Mco<'d, T> { |
| 47 | /// Create a new MCO instance. | 56 | /// Create a new MCO instance. |
| 48 | /// | 57 | /// |
| 49 | /// `prescaler` must be between 1 and 15. | 58 | /// `prescaler` must be between 1 and 15 for implementations not using Presel enum. |
| 50 | pub fn new( | 59 | pub fn new( |
| 51 | _peri: impl Peripheral<P = T> + 'd, | 60 | _peri: impl Peripheral<P = T> + 'd, |
| 52 | pin: impl Peripheral<P = impl McoPin<T>> + 'd, | 61 | pin: impl Peripheral<P = impl McoPin<T>> + 'd, |
| 53 | source: T::Source, | 62 | source: T::Source, |
| 54 | prescaler: u8, | 63 | prescaler: T::Prescaler, |
| 55 | ) -> Self { | 64 | ) -> Self { |
| 56 | into_ref!(pin); | 65 | into_ref!(pin); |
| 57 | 66 | ||
| 67 | #[cfg(not(stm32wl))] | ||
| 58 | assert!( | 68 | assert!( |
| 59 | 1 <= prescaler && prescaler <= 15, | 69 | 1 <= prescaler && prescaler <= 15, |
| 60 | "Mco prescaler must be between 1 and 15. Refer to the reference manual for more information." | 70 | "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 bf497ca12..f7e3ecdbc 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -7,9 +7,9 @@ use crate::time::Hertz; | |||
| 7 | 7 | ||
| 8 | pub(crate) mod bd; | 8 | pub(crate) mod bd; |
| 9 | mod bus; | 9 | mod bus; |
| 10 | #[cfg(any(stm32h5, stm32h7))] | 10 | #[cfg(any(stm32h5, stm32h7, stm32wl))] |
| 11 | mod mco; | 11 | mod mco; |
| 12 | #[cfg(any(stm32h5, stm32h7))] | 12 | #[cfg(any(stm32h5, stm32h7, stm32wl))] |
| 13 | pub use mco::*; | 13 | pub use mco::*; |
| 14 | 14 | ||
| 15 | #[cfg_attr(rcc_f0, path = "f0.rs")] | 15 | #[cfg_attr(rcc_f0, path = "f0.rs")] |
