Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stm32: add MCO for all chips #2021

Merged
merged 2 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions embassy-stm32/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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]
Expand Down
35 changes: 10 additions & 25 deletions embassy-stm32/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ 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") {
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());
}
Expand Down Expand Up @@ -751,25 +753,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! {
Expand Down
166 changes: 0 additions & 166 deletions embassy-stm32/src/rcc/f4.rs
Original file line number Diff line number Diff line change
@@ -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);
Expand Down Expand Up @@ -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<P = T> + 'd,
pin: impl Peripheral<P = impl McoPin<T>> + 'd,
source: impl McoSource<Raw = T::Source>,
prescaler: McoClock,
) -> Self {
into_ref!(pin);

critical_section::with(|_| unsafe {
T::apply_clock_settings(source.into_raw(), prescaler.into_raw());
pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
pin.set_speed(Speed::VeryHigh);
});

Self { phantom: PhantomData }
}
}

fn flash_setup(sysclk: u32) {
use crate::pac::flash::vals::Latency;

Expand Down
132 changes: 0 additions & 132 deletions embassy-stm32/src/rcc/l4.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
use core::marker::PhantomData;

use embassy_hal_internal::into_ref;
use stm32_metapac::rcc::regs::Cfgr;
use stm32_metapac::rcc::vals::{Mcopre, Mcosel};

pub use super::bus::{AHBPrescaler, APBPrescaler};
use crate::gpio::sealed::AFType;
use crate::gpio::Speed;
use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw};
use crate::pac::{FLASH, 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);
Expand Down Expand Up @@ -263,131 +256,6 @@ impl Default for Config {
}
}

pub enum McoClock {
DIV1,
DIV2,
DIV4,
DIV8,
DIV16,
}

impl McoClock {
fn into_raw(&self) -> Mcopre {
match self {
McoClock::DIV1 => Mcopre::DIV1,
McoClock::DIV2 => Mcopre::DIV2,
McoClock::DIV4 => Mcopre::DIV4,
McoClock::DIV8 => Mcopre::DIV8,
McoClock::DIV16 => Mcopre::DIV16,
}
}
}

#[derive(Copy, Clone)]
pub enum Mco1Source {
Disabled,
Lse,
Lsi,
Hse,
Hsi16,
PllClk,
SysClk,
Msi,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
Hsi48,
}

impl Default for Mco1Source {
fn default() -> Self {
Self::Hsi16
}
}

pub trait McoSource {
type Raw;

fn into_raw(&self) -> Self::Raw;
}

impl McoSource for Mco1Source {
type Raw = Mcosel;
fn into_raw(&self) -> Self::Raw {
match self {
Mco1Source::Disabled => Mcosel::NOCLOCK,
Mco1Source::Lse => Mcosel::LSE,
Mco1Source::Lsi => Mcosel::LSI,
Mco1Source::Hse => Mcosel::HSE,
Mco1Source::Hsi16 => Mcosel::HSI16,
Mco1Source::PllClk => Mcosel::PLL,
Mco1Source::SysClk => Mcosel::SYSCLK,
Mco1Source::Msi => Mcosel::MSI,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
Mco1Source::Hsi48 => Mcosel::HSI48,
}
}
}

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::MCO {
type Source = Mcosel;

unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre) {
RCC.cfgr().modify(|w| {
w.set_mcosel(source);
w.set_mcopre(prescaler);
});

match source {
Mcosel::HSI16 => {
RCC.cr().modify(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
}
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
Mcosel::HSI48 => {
RCC.crrcr().modify(|w| w.set_hsi48on(true));
while !RCC.crrcr().read().hsi48rdy() {}
}
_ => {}
}
}
}

impl McoInstance for peripherals::MCO {}

pub struct Mco<'d, T: McoInstance> {
phantom: PhantomData<&'d mut T>,
}

impl<'d, T: McoInstance> Mco<'d, T> {
pub fn new(
_peri: impl Peripheral<P = T> + 'd,
pin: impl Peripheral<P = impl McoPin<T>> + 'd,
source: impl McoSource<Raw = T::Source>,
prescaler: McoClock,
) -> Self {
into_ref!(pin);

critical_section::with(|_| unsafe {
T::apply_clock_settings(source.into_raw(), prescaler.into_raw());
pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
pin.set_speed(Speed::VeryHigh);
});

Self { phantom: PhantomData }
}
}

pub(crate) unsafe fn init(config: Config) {
// Switch to MSI to prevent problems with PLL configuration.
if !RCC.cr().read().msion() {
Expand Down
Loading