Merge pull request #2070 from embassy-rs/rcc-no-spaghetti
stm32/rcc: unify L4 and L5.
This commit is contained in:
		
						commit
						a7c6999670
					
				@ -58,7 +58,7 @@ rand_core = "0.6.3"
 | 
				
			|||||||
sdio-host = "0.5.0"
 | 
					sdio-host = "0.5.0"
 | 
				
			||||||
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
 | 
					embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
 | 
				
			||||||
critical-section = "1.1"
 | 
					critical-section = "1.1"
 | 
				
			||||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73e3f8a965a01fd5a168c3543b93ce49d475e130" }
 | 
					stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-5ecc410f93477d3d9314723ec26e637aa0c63b8f" }
 | 
				
			||||||
vcell = "0.1.3"
 | 
					vcell = "0.1.3"
 | 
				
			||||||
bxcan = "0.7.0"
 | 
					bxcan = "0.7.0"
 | 
				
			||||||
nb = "1.0.0"
 | 
					nb = "1.0.0"
 | 
				
			||||||
@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] }
 | 
				
			|||||||
[build-dependencies]
 | 
					[build-dependencies]
 | 
				
			||||||
proc-macro2 = "1.0.36"
 | 
					proc-macro2 = "1.0.36"
 | 
				
			||||||
quote = "1.0.15"
 | 
					quote = "1.0.15"
 | 
				
			||||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73e3f8a965a01fd5a168c3543b93ce49d475e130", default-features = false, features = ["metadata"]}
 | 
					stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-5ecc410f93477d3d9314723ec26e637aa0c63b8f", default-features = false, features = ["metadata"]}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[features]
 | 
					[features]
 | 
				
			||||||
 | 
				
			|||||||
@ -42,9 +42,7 @@ pub struct Config {
 | 
				
			|||||||
    // pll
 | 
					    // pll
 | 
				
			||||||
    pub pll: Option<Pll>,
 | 
					    pub pll: Option<Pll>,
 | 
				
			||||||
    pub pllsai1: Option<Pll>,
 | 
					    pub pllsai1: Option<Pll>,
 | 
				
			||||||
    #[cfg(any(
 | 
					    #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
				
			||||||
        stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
 | 
					 | 
				
			||||||
    ))]
 | 
					 | 
				
			||||||
    pub pllsai2: Option<Pll>,
 | 
					    pub pllsai2: Option<Pll>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // sysclk, buses.
 | 
					    // sysclk, buses.
 | 
				
			||||||
@ -73,9 +71,7 @@ impl Default for Config {
 | 
				
			|||||||
            apb2_pre: APBPrescaler::DIV1,
 | 
					            apb2_pre: APBPrescaler::DIV1,
 | 
				
			||||||
            pll: None,
 | 
					            pll: None,
 | 
				
			||||||
            pllsai1: None,
 | 
					            pllsai1: None,
 | 
				
			||||||
            #[cfg(any(
 | 
					            #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
				
			||||||
                stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
 | 
					 | 
				
			||||||
            ))]
 | 
					 | 
				
			||||||
            pllsai2: None,
 | 
					            pllsai2: None,
 | 
				
			||||||
            #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
 | 
					            #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
 | 
				
			||||||
            hsi48: true,
 | 
					            hsi48: true,
 | 
				
			||||||
@ -106,6 +102,11 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
        while RCC.cfgr().read().sws() != ClockSrc::MSI {}
 | 
					        while RCC.cfgr().read().sws() != ClockSrc::MSI {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(stm32l5)]
 | 
				
			||||||
 | 
					    crate::pac::PWR.cr1().modify(|w| {
 | 
				
			||||||
 | 
					        w.set_vos(crate::pac::pwr::vals::Vos::RANGE0);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let rtc = config.ls.init();
 | 
					    let rtc = config.ls.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let msi = config.msi.map(|range| {
 | 
					    let msi = config.msi.map(|range| {
 | 
				
			||||||
@ -153,14 +154,12 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
    let _plls = [
 | 
					    let _plls = [
 | 
				
			||||||
        &config.pll,
 | 
					        &config.pll,
 | 
				
			||||||
        &config.pllsai1,
 | 
					        &config.pllsai1,
 | 
				
			||||||
        #[cfg(any(
 | 
					        #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
				
			||||||
            stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
 | 
					 | 
				
			||||||
        ))]
 | 
					 | 
				
			||||||
        &config.pllsai2,
 | 
					        &config.pllsai2,
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // L4 has shared PLLSRC, PLLM, check it's equal in all PLLs.
 | 
					    // L4 has shared PLLSRC, PLLM, check it's equal in all PLLs.
 | 
				
			||||||
    #[cfg(all(stm32l4, not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))))]
 | 
					    #[cfg(all(stm32l4, not(rcc_l4plus)))]
 | 
				
			||||||
    match get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) {
 | 
					    match get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) {
 | 
				
			||||||
        Err(()) => panic!("Source must be equal across all enabled PLLs."),
 | 
					        Err(()) => panic!("Source must be equal across all enabled PLLs."),
 | 
				
			||||||
        Ok(None) => {}
 | 
					        Ok(None) => {}
 | 
				
			||||||
@ -171,7 +170,7 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // L4+ has shared PLLSRC, check it's equal in all PLLs.
 | 
					    // L4+ has shared PLLSRC, check it's equal in all PLLs.
 | 
				
			||||||
    #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))]
 | 
					    #[cfg(any(rcc_l4plus))]
 | 
				
			||||||
    match get_equal(_plls.into_iter().flatten().map(|p| p.source)) {
 | 
					    match get_equal(_plls.into_iter().flatten().map(|p| p.source)) {
 | 
				
			||||||
        Err(()) => panic!("Source must be equal across all enabled PLLs."),
 | 
					        Err(()) => panic!("Source must be equal across all enabled PLLs."),
 | 
				
			||||||
        Ok(None) => {}
 | 
					        Ok(None) => {}
 | 
				
			||||||
@ -183,9 +182,7 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
    let pll_input = PllInput { hse, hsi16, msi };
 | 
					    let pll_input = PllInput { hse, hsi16, msi };
 | 
				
			||||||
    let pll = init_pll(PllInstance::Pll, config.pll, &pll_input);
 | 
					    let pll = init_pll(PllInstance::Pll, config.pll, &pll_input);
 | 
				
			||||||
    let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input);
 | 
					    let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input);
 | 
				
			||||||
    #[cfg(any(
 | 
					    #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
				
			||||||
        stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
 | 
					 | 
				
			||||||
    ))]
 | 
					 | 
				
			||||||
    let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input);
 | 
					    let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let sys_clk = match config.mux {
 | 
					    let sys_clk = match config.mux {
 | 
				
			||||||
@ -202,12 +199,13 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
        Clk48Src::PLL_Q => pll._q,
 | 
					        Clk48Src::PLL_Q => pll._q,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))]
 | 
					    #[cfg(rcc_l4plus)]
 | 
				
			||||||
    assert!(sys_clk.0 <= 120_000_000);
 | 
					    assert!(sys_clk.0 <= 120_000_000);
 | 
				
			||||||
    #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))]
 | 
					    #[cfg(all(stm32l4, not(rcc_l4plus)))]
 | 
				
			||||||
    assert!(sys_clk.0 <= 80_000_000);
 | 
					    assert!(sys_clk.0 <= 80_000_000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Set flash wait states
 | 
					    // Set flash wait states
 | 
				
			||||||
 | 
					    #[cfg(stm32l4)]
 | 
				
			||||||
    FLASH.acr().modify(|w| {
 | 
					    FLASH.acr().modify(|w| {
 | 
				
			||||||
        w.set_latency(match sys_clk.0 {
 | 
					        w.set_latency(match sys_clk.0 {
 | 
				
			||||||
            0..=16_000_000 => 0,
 | 
					            0..=16_000_000 => 0,
 | 
				
			||||||
@ -217,6 +215,18 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
            _ => 4,
 | 
					            _ => 4,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    // VCORE Range 0 (performance), others TODO
 | 
				
			||||||
 | 
					    #[cfg(stm32l5)]
 | 
				
			||||||
 | 
					    FLASH.acr().modify(|w| {
 | 
				
			||||||
 | 
					        w.set_latency(match sys_clk.0 {
 | 
				
			||||||
 | 
					            0..=20_000_000 => 0,
 | 
				
			||||||
 | 
					            0..=40_000_000 => 1,
 | 
				
			||||||
 | 
					            0..=60_000_000 => 2,
 | 
				
			||||||
 | 
					            0..=80_000_000 => 3,
 | 
				
			||||||
 | 
					            0..=100_000_000 => 4,
 | 
				
			||||||
 | 
					            _ => 5,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RCC.cfgr().modify(|w| {
 | 
					    RCC.cfgr().modify(|w| {
 | 
				
			||||||
        w.set_sw(config.mux);
 | 
					        w.set_sw(config.mux);
 | 
				
			||||||
@ -274,6 +284,7 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[allow(unused)]
 | 
				
			||||||
fn get_equal<T: Eq>(mut iter: impl Iterator<Item = T>) -> Result<Option<T>, ()> {
 | 
					fn get_equal<T: Eq>(mut iter: impl Iterator<Item = T>) -> Result<Option<T>, ()> {
 | 
				
			||||||
    let Some(x) = iter.next() else { return Ok(None) };
 | 
					    let Some(x) = iter.next() else { return Ok(None) };
 | 
				
			||||||
    if !iter.all(|y| y == x) {
 | 
					    if !iter.all(|y| y == x) {
 | 
				
			||||||
@ -299,9 +310,7 @@ struct PllOutput {
 | 
				
			|||||||
enum PllInstance {
 | 
					enum PllInstance {
 | 
				
			||||||
    Pll,
 | 
					    Pll,
 | 
				
			||||||
    Pllsai1,
 | 
					    Pllsai1,
 | 
				
			||||||
    #[cfg(any(
 | 
					    #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
				
			||||||
        stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
 | 
					 | 
				
			||||||
    ))]
 | 
					 | 
				
			||||||
    Pllsai2,
 | 
					    Pllsai2,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -316,9 +325,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
 | 
				
			|||||||
            RCC.cr().modify(|w| w.set_pllsai1on(false));
 | 
					            RCC.cr().modify(|w| w.set_pllsai1on(false));
 | 
				
			||||||
            while RCC.cr().read().pllsai1rdy() {}
 | 
					            while RCC.cr().read().pllsai1rdy() {}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        #[cfg(any(
 | 
					        #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
				
			||||||
            stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
 | 
					 | 
				
			||||||
        ))]
 | 
					 | 
				
			||||||
        PllInstance::Pllsai2 => {
 | 
					        PllInstance::Pllsai2 => {
 | 
				
			||||||
            RCC.cr().modify(|w| w.set_pllsai2on(false));
 | 
					            RCC.cr().modify(|w| w.set_pllsai2on(false));
 | 
				
			||||||
            while RCC.cr().read().pllsai2rdy() {}
 | 
					            while RCC.cr().read().pllsai2rdy() {}
 | 
				
			||||||
@ -342,6 +349,12 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
 | 
				
			|||||||
    let q = pll.divq.map(|div| vco_freq / div);
 | 
					    let q = pll.divq.map(|div| vco_freq / div);
 | 
				
			||||||
    let r = pll.divr.map(|div| vco_freq / div);
 | 
					    let r = pll.divr.map(|div| vco_freq / div);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(stm32l5)]
 | 
				
			||||||
 | 
					    if instance == PllInstance::Pllsai2 {
 | 
				
			||||||
 | 
					        assert!(q.is_none(), "PLLSAI2_Q is not available on L5");
 | 
				
			||||||
 | 
					        assert!(r.is_none(), "PLLSAI2_R is not available on L5");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    macro_rules! write_fields {
 | 
					    macro_rules! write_fields {
 | 
				
			||||||
        ($w:ident) => {
 | 
					        ($w:ident) => {
 | 
				
			||||||
            $w.set_plln(pll.mul);
 | 
					            $w.set_plln(pll.mul);
 | 
				
			||||||
@ -367,17 +380,15 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
 | 
				
			|||||||
            write_fields!(w);
 | 
					            write_fields!(w);
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| {
 | 
					        PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| {
 | 
				
			||||||
            #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx, stm32l5))]
 | 
					            #[cfg(any(rcc_l4plus, stm32l5))]
 | 
				
			||||||
            w.set_pllm(pll.prediv);
 | 
					            w.set_pllm(pll.prediv);
 | 
				
			||||||
            #[cfg(stm32l5)]
 | 
					            #[cfg(stm32l5)]
 | 
				
			||||||
            w.set_pllsrc(pll.source);
 | 
					            w.set_pllsrc(pll.source);
 | 
				
			||||||
            write_fields!(w);
 | 
					            write_fields!(w);
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        #[cfg(any(
 | 
					        #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
				
			||||||
            stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
 | 
					 | 
				
			||||||
        ))]
 | 
					 | 
				
			||||||
        PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| {
 | 
					        PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| {
 | 
				
			||||||
            #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx, stm32l5))]
 | 
					            #[cfg(any(rcc_l4plus, stm32l5))]
 | 
				
			||||||
            w.set_pllm(pll.prediv);
 | 
					            w.set_pllm(pll.prediv);
 | 
				
			||||||
            #[cfg(stm32l5)]
 | 
					            #[cfg(stm32l5)]
 | 
				
			||||||
            w.set_pllsrc(pll.source);
 | 
					            w.set_pllsrc(pll.source);
 | 
				
			||||||
@ -395,9 +406,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
 | 
				
			|||||||
            RCC.cr().modify(|w| w.set_pllsai1on(true));
 | 
					            RCC.cr().modify(|w| w.set_pllsai1on(true));
 | 
				
			||||||
            while !RCC.cr().read().pllsai1rdy() {}
 | 
					            while !RCC.cr().read().pllsai1rdy() {}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        #[cfg(any(
 | 
					        #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
				
			||||||
            stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
 | 
					 | 
				
			||||||
        ))]
 | 
					 | 
				
			||||||
        PllInstance::Pllsai2 => {
 | 
					        PllInstance::Pllsai2 => {
 | 
				
			||||||
            RCC.cr().modify(|w| w.set_pllsai2on(true));
 | 
					            RCC.cr().modify(|w| w.set_pllsai2on(true));
 | 
				
			||||||
            while !RCC.cr().read().pllsai2rdy() {}
 | 
					            while !RCC.cr().read().pllsai2rdy() {}
 | 
				
			||||||
@ -1,291 +0,0 @@
 | 
				
			|||||||
use crate::pac::rcc::regs::Cfgr;
 | 
					 | 
				
			||||||
pub use crate::pac::rcc::vals::{
 | 
					 | 
				
			||||||
    Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv,
 | 
					 | 
				
			||||||
    Pllr as PllRDiv, Ppre as APBPrescaler,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
 | 
					 | 
				
			||||||
use crate::pac::{FLASH, PWR, RCC};
 | 
					 | 
				
			||||||
use crate::rcc::{set_freqs, Clocks};
 | 
					 | 
				
			||||||
use crate::time::Hertz;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// HSI speed
 | 
					 | 
				
			||||||
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// System clock mux source
 | 
					 | 
				
			||||||
#[derive(Clone, Copy)]
 | 
					 | 
				
			||||||
pub enum ClockSrc {
 | 
					 | 
				
			||||||
    MSI(MSIRange),
 | 
					 | 
				
			||||||
    PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option<PllQDiv>),
 | 
					 | 
				
			||||||
    HSE(Hertz),
 | 
					 | 
				
			||||||
    HSI16,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// PLL clock input source
 | 
					 | 
				
			||||||
#[derive(Clone, Copy)]
 | 
					 | 
				
			||||||
pub enum PLLSource {
 | 
					 | 
				
			||||||
    HSI16,
 | 
					 | 
				
			||||||
    HSE(Hertz),
 | 
					 | 
				
			||||||
    MSI(MSIRange),
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<PLLSource> for Pllsrc {
 | 
					 | 
				
			||||||
    fn from(val: PLLSource) -> Pllsrc {
 | 
					 | 
				
			||||||
        match val {
 | 
					 | 
				
			||||||
            PLLSource::HSI16 => Pllsrc::HSI16,
 | 
					 | 
				
			||||||
            PLLSource::HSE(_) => Pllsrc::HSE,
 | 
					 | 
				
			||||||
            PLLSource::MSI(_) => Pllsrc::MSI,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Clocks configutation
 | 
					 | 
				
			||||||
pub struct Config {
 | 
					 | 
				
			||||||
    pub mux: ClockSrc,
 | 
					 | 
				
			||||||
    pub ahb_pre: AHBPrescaler,
 | 
					 | 
				
			||||||
    pub apb1_pre: APBPrescaler,
 | 
					 | 
				
			||||||
    pub apb2_pre: APBPrescaler,
 | 
					 | 
				
			||||||
    pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
 | 
					 | 
				
			||||||
    pub hsi48: bool,
 | 
					 | 
				
			||||||
    pub ls: super::LsConfig,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Default for Config {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn default() -> Config {
 | 
					 | 
				
			||||||
        Config {
 | 
					 | 
				
			||||||
            mux: ClockSrc::MSI(MSIRange::RANGE4M),
 | 
					 | 
				
			||||||
            ahb_pre: AHBPrescaler::DIV1,
 | 
					 | 
				
			||||||
            apb1_pre: APBPrescaler::DIV1,
 | 
					 | 
				
			||||||
            apb2_pre: APBPrescaler::DIV1,
 | 
					 | 
				
			||||||
            pllsai1: None,
 | 
					 | 
				
			||||||
            hsi48: false,
 | 
					 | 
				
			||||||
            ls: Default::default(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) unsafe fn init(config: Config) {
 | 
					 | 
				
			||||||
    // Switch to MSI to prevent problems with PLL configuration.
 | 
					 | 
				
			||||||
    if !RCC.cr().read().msion() {
 | 
					 | 
				
			||||||
        // Turn on MSI and configure it to 4MHz.
 | 
					 | 
				
			||||||
        RCC.cr().modify(|w| {
 | 
					 | 
				
			||||||
            w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0].
 | 
					 | 
				
			||||||
            w.set_msirange(MSIRange::RANGE4M);
 | 
					 | 
				
			||||||
            w.set_msipllen(false);
 | 
					 | 
				
			||||||
            w.set_msion(true)
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Wait until MSI is running
 | 
					 | 
				
			||||||
        while !RCC.cr().read().msirdy() {}
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if RCC.cfgr().read().sws() != Sw::MSI {
 | 
					 | 
				
			||||||
        // Set MSI as a clock source, reset prescalers.
 | 
					 | 
				
			||||||
        RCC.cfgr().write_value(Cfgr::default());
 | 
					 | 
				
			||||||
        // Wait for clock switch status bits to change.
 | 
					 | 
				
			||||||
        while RCC.cfgr().read().sws() != Sw::MSI {}
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let rtc = config.ls.init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0));
 | 
					 | 
				
			||||||
    let (sys_clk, sw) = match config.mux {
 | 
					 | 
				
			||||||
        ClockSrc::MSI(range) => {
 | 
					 | 
				
			||||||
            // Enable MSI
 | 
					 | 
				
			||||||
            RCC.cr().write(|w| {
 | 
					 | 
				
			||||||
                w.set_msirange(range);
 | 
					 | 
				
			||||||
                w.set_msirgsel(true);
 | 
					 | 
				
			||||||
                w.set_msion(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // If LSE is enabled, enable calibration of MSI
 | 
					 | 
				
			||||||
                w.set_msipllen(config.ls.lse.is_some());
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            while !RCC.cr().read().msirdy() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Enable as clock source for USB, RNG if running at 48 MHz
 | 
					 | 
				
			||||||
            if range == MSIRange::RANGE48M {
 | 
					 | 
				
			||||||
                RCC.ccipr1().modify(|w| {
 | 
					 | 
				
			||||||
                    w.set_clk48sel(0b11);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            (msirange_to_hertz(range), Sw::MSI)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ClockSrc::HSI16 => {
 | 
					 | 
				
			||||||
            // Enable HSI16
 | 
					 | 
				
			||||||
            RCC.cr().write(|w| w.set_hsion(true));
 | 
					 | 
				
			||||||
            while !RCC.cr().read().hsirdy() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            (HSI_FREQ, Sw::HSI16)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ClockSrc::HSE(freq) => {
 | 
					 | 
				
			||||||
            // Enable HSE
 | 
					 | 
				
			||||||
            RCC.cr().write(|w| w.set_hseon(true));
 | 
					 | 
				
			||||||
            while !RCC.cr().read().hserdy() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            (freq, Sw::HSE)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ClockSrc::PLL(src, divr, prediv, mul, divq) => {
 | 
					 | 
				
			||||||
            let src_freq = match src {
 | 
					 | 
				
			||||||
                PLLSource::HSE(freq) => {
 | 
					 | 
				
			||||||
                    // Enable HSE
 | 
					 | 
				
			||||||
                    RCC.cr().write(|w| w.set_hseon(true));
 | 
					 | 
				
			||||||
                    while !RCC.cr().read().hserdy() {}
 | 
					 | 
				
			||||||
                    freq
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                PLLSource::HSI16 => {
 | 
					 | 
				
			||||||
                    // Enable HSI
 | 
					 | 
				
			||||||
                    RCC.cr().write(|w| w.set_hsion(true));
 | 
					 | 
				
			||||||
                    while !RCC.cr().read().hsirdy() {}
 | 
					 | 
				
			||||||
                    HSI_FREQ
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                PLLSource::MSI(range) => {
 | 
					 | 
				
			||||||
                    // Enable MSI
 | 
					 | 
				
			||||||
                    RCC.cr().write(|w| {
 | 
					 | 
				
			||||||
                        w.set_msirange(range);
 | 
					 | 
				
			||||||
                        w.set_msipllen(false); // should be turned on if LSE is started
 | 
					 | 
				
			||||||
                        w.set_msirgsel(true);
 | 
					 | 
				
			||||||
                        w.set_msion(true);
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                    while !RCC.cr().read().msirdy() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    msirange_to_hertz(range)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Disable PLL
 | 
					 | 
				
			||||||
            RCC.cr().modify(|w| w.set_pllon(false));
 | 
					 | 
				
			||||||
            while RCC.cr().read().pllrdy() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let freq = src_freq / prediv * mul / divr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            RCC.pllcfgr().write(move |w| {
 | 
					 | 
				
			||||||
                w.set_plln(mul);
 | 
					 | 
				
			||||||
                w.set_pllm(prediv);
 | 
					 | 
				
			||||||
                w.set_pllr(divr);
 | 
					 | 
				
			||||||
                if let Some(divq) = divq {
 | 
					 | 
				
			||||||
                    w.set_pllq(divq);
 | 
					 | 
				
			||||||
                    w.set_pllqen(true);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                w.set_pllsrc(src.into());
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Enable as clock source for USB, RNG if PLL48 divisor is provided
 | 
					 | 
				
			||||||
            if let Some(divq) = divq {
 | 
					 | 
				
			||||||
                let freq = src_freq / prediv * mul / divq;
 | 
					 | 
				
			||||||
                assert!(freq.0 == 48_000_000);
 | 
					 | 
				
			||||||
                RCC.ccipr1().modify(|w| {
 | 
					 | 
				
			||||||
                    w.set_clk48sel(0b10);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 {
 | 
					 | 
				
			||||||
                RCC.pllsai1cfgr().write(move |w| {
 | 
					 | 
				
			||||||
                    w.set_plln(mul);
 | 
					 | 
				
			||||||
                    w.set_pllm(prediv);
 | 
					 | 
				
			||||||
                    if let Some(r_div) = r_div {
 | 
					 | 
				
			||||||
                        w.set_pllr(r_div);
 | 
					 | 
				
			||||||
                        w.set_pllren(true);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    if let Some(q_div) = q_div {
 | 
					 | 
				
			||||||
                        w.set_pllq(q_div);
 | 
					 | 
				
			||||||
                        w.set_pllqen(true);
 | 
					 | 
				
			||||||
                        let freq = src_freq / prediv * mul / q_div;
 | 
					 | 
				
			||||||
                        if freq.0 == 48_000_000 {
 | 
					 | 
				
			||||||
                            RCC.ccipr1().modify(|w| {
 | 
					 | 
				
			||||||
                                w.set_clk48sel(0b1);
 | 
					 | 
				
			||||||
                            });
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    if let Some(p_div) = p_div {
 | 
					 | 
				
			||||||
                        w.set_pllp(p_div);
 | 
					 | 
				
			||||||
                        w.set_pllpen(true);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                RCC.cr().modify(|w| w.set_pllsai1on(true));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Enable PLL
 | 
					 | 
				
			||||||
            RCC.cr().modify(|w| w.set_pllon(true));
 | 
					 | 
				
			||||||
            while !RCC.cr().read().pllrdy() {}
 | 
					 | 
				
			||||||
            RCC.pllcfgr().modify(|w| w.set_pllren(true));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            (freq, Sw::PLL)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if config.hsi48 {
 | 
					 | 
				
			||||||
        RCC.crrcr().modify(|w| w.set_hsi48on(true));
 | 
					 | 
				
			||||||
        while !RCC.crrcr().read().hsi48rdy() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable as clock source for USB, RNG and SDMMC
 | 
					 | 
				
			||||||
        RCC.ccipr1().modify(|w| w.set_clk48sel(0));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Set flash wait states
 | 
					 | 
				
			||||||
    // VCORE Range 0 (performance), others TODO
 | 
					 | 
				
			||||||
    FLASH.acr().modify(|w| {
 | 
					 | 
				
			||||||
        w.set_latency(match sys_clk.0 {
 | 
					 | 
				
			||||||
            0..=20_000_000 => 0,
 | 
					 | 
				
			||||||
            0..=40_000_000 => 1,
 | 
					 | 
				
			||||||
            0..=60_000_000 => 2,
 | 
					 | 
				
			||||||
            0..=80_000_000 => 3,
 | 
					 | 
				
			||||||
            0..=100_000_000 => 4,
 | 
					 | 
				
			||||||
            _ => 5,
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    RCC.cfgr().modify(|w| {
 | 
					 | 
				
			||||||
        w.set_sw(sw);
 | 
					 | 
				
			||||||
        w.set_hpre(config.ahb_pre);
 | 
					 | 
				
			||||||
        w.set_ppre1(config.apb1_pre);
 | 
					 | 
				
			||||||
        w.set_ppre2(config.apb2_pre);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let ahb_freq = sys_clk / config.ahb_pre;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
 | 
					 | 
				
			||||||
        APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
 | 
					 | 
				
			||||||
        pre => {
 | 
					 | 
				
			||||||
            let freq = ahb_freq / pre;
 | 
					 | 
				
			||||||
            (freq, freq * 2u32)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
 | 
					 | 
				
			||||||
        APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
 | 
					 | 
				
			||||||
        pre => {
 | 
					 | 
				
			||||||
            let freq = ahb_freq / pre;
 | 
					 | 
				
			||||||
            (freq, freq * 2u32)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    set_freqs(Clocks {
 | 
					 | 
				
			||||||
        sys: sys_clk,
 | 
					 | 
				
			||||||
        hclk1: ahb_freq,
 | 
					 | 
				
			||||||
        hclk2: ahb_freq,
 | 
					 | 
				
			||||||
        hclk3: ahb_freq,
 | 
					 | 
				
			||||||
        pclk1: apb1_freq,
 | 
					 | 
				
			||||||
        pclk2: apb2_freq,
 | 
					 | 
				
			||||||
        pclk1_tim: apb1_tim_freq,
 | 
					 | 
				
			||||||
        pclk2_tim: apb2_tim_freq,
 | 
					 | 
				
			||||||
        rtc,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn msirange_to_hertz(range: Msirange) -> Hertz {
 | 
					 | 
				
			||||||
    match range {
 | 
					 | 
				
			||||||
        MSIRange::RANGE100K => Hertz(100_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE200K => Hertz(200_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE400K => Hertz(400_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE800K => Hertz(800_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE1M => Hertz(1_000_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE2M => Hertz(2_000_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE4M => Hertz(4_000_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE8M => Hertz(8_000_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE16M => Hertz(16_000_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE24M => Hertz(24_000_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE32M => Hertz(32_000_000),
 | 
					 | 
				
			||||||
        MSIRange::RANGE48M => Hertz(48_000_000),
 | 
					 | 
				
			||||||
        _ => unreachable!(),
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -20,8 +20,7 @@ pub use mco::*;
 | 
				
			|||||||
#[cfg_attr(rcc_g4, path = "g4.rs")]
 | 
					#[cfg_attr(rcc_g4, path = "g4.rs")]
 | 
				
			||||||
#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")]
 | 
					#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")]
 | 
				
			||||||
#[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")]
 | 
					#[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")]
 | 
				
			||||||
#[cfg_attr(any(rcc_l4, rcc_l4plus), path = "l4.rs")]
 | 
					#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5), path = "l4l5.rs")]
 | 
				
			||||||
#[cfg_attr(rcc_l5, path = "l5.rs")]
 | 
					 | 
				
			||||||
#[cfg_attr(rcc_u5, path = "u5.rs")]
 | 
					#[cfg_attr(rcc_u5, path = "u5.rs")]
 | 
				
			||||||
#[cfg_attr(rcc_wb, path = "wb.rs")]
 | 
					#[cfg_attr(rcc_wb, path = "wb.rs")]
 | 
				
			||||||
#[cfg_attr(rcc_wba, path = "wba.rs")]
 | 
					#[cfg_attr(rcc_wba, path = "wba.rs")]
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use defmt::*;
 | 
					use defmt::*;
 | 
				
			||||||
use embassy_executor::Spawner;
 | 
					use embassy_executor::Spawner;
 | 
				
			||||||
use embassy_stm32::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv};
 | 
					use embassy_stm32::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv};
 | 
				
			||||||
use embassy_stm32::rng::Rng;
 | 
					use embassy_stm32::rng::Rng;
 | 
				
			||||||
use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
 | 
					use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
 | 
				
			||||||
use {defmt_rtt as _, panic_probe as _};
 | 
					use {defmt_rtt as _, panic_probe as _};
 | 
				
			||||||
@ -16,13 +16,17 @@ bind_interrupts!(struct Irqs {
 | 
				
			|||||||
#[embassy_executor::main]
 | 
					#[embassy_executor::main]
 | 
				
			||||||
async fn main(_spawner: Spawner) {
 | 
					async fn main(_spawner: Spawner) {
 | 
				
			||||||
    let mut config = Config::default();
 | 
					    let mut config = Config::default();
 | 
				
			||||||
    config.rcc.mux = ClockSrc::PLL(
 | 
					    config.rcc.hsi16 = true;
 | 
				
			||||||
        PLLSource::HSI16,
 | 
					    config.rcc.mux = ClockSrc::PLL;
 | 
				
			||||||
        PllRDiv::DIV2,
 | 
					    config.rcc.pll = Some(Pll {
 | 
				
			||||||
        PllPreDiv::DIV1,
 | 
					        // 64Mhz clock (16 / 1 * 8 / 2)
 | 
				
			||||||
        PllMul::MUL8,
 | 
					        source: PLLSource::HSI16,
 | 
				
			||||||
        Some(PllQDiv::DIV2),
 | 
					        prediv: PllPreDiv::DIV1,
 | 
				
			||||||
    );
 | 
					        mul: PllMul::MUL8,
 | 
				
			||||||
 | 
					        divp: None,
 | 
				
			||||||
 | 
					        divq: None,
 | 
				
			||||||
 | 
					        divr: Some(PllRDiv::DIV2),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
    let p = embassy_stm32::init(config);
 | 
					    let p = embassy_stm32::init(config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
				
			|||||||
@ -45,8 +45,17 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
 | 
				
			|||||||
#[embassy_executor::main]
 | 
					#[embassy_executor::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner) {
 | 
				
			||||||
    let mut config = Config::default();
 | 
					    let mut config = Config::default();
 | 
				
			||||||
    config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None);
 | 
					    config.rcc.hsi16 = true;
 | 
				
			||||||
    config.rcc.hsi48 = true;
 | 
					    config.rcc.mux = ClockSrc::PLL;
 | 
				
			||||||
 | 
					    config.rcc.pll = Some(Pll {
 | 
				
			||||||
 | 
					        // 80Mhz clock (16 / 1 * 10 / 2)
 | 
				
			||||||
 | 
					        source: PLLSource::HSI16,
 | 
				
			||||||
 | 
					        prediv: PllPreDiv::DIV1,
 | 
				
			||||||
 | 
					        mul: PllMul::MUL10,
 | 
				
			||||||
 | 
					        divp: None,
 | 
				
			||||||
 | 
					        divq: None,
 | 
				
			||||||
 | 
					        divr: Some(PllRDiv::DIV2),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
    let p = embassy_stm32::init(config);
 | 
					    let p = embassy_stm32::init(config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create the driver, from the HAL.
 | 
					    // Create the driver, from the HAL.
 | 
				
			||||||
 | 
				
			|||||||
@ -22,8 +22,17 @@ bind_interrupts!(struct Irqs {
 | 
				
			|||||||
#[embassy_executor::main]
 | 
					#[embassy_executor::main]
 | 
				
			||||||
async fn main(_spawner: Spawner) {
 | 
					async fn main(_spawner: Spawner) {
 | 
				
			||||||
    let mut config = Config::default();
 | 
					    let mut config = Config::default();
 | 
				
			||||||
    config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None);
 | 
					    config.rcc.hsi16 = true;
 | 
				
			||||||
    config.rcc.hsi48 = true;
 | 
					    config.rcc.mux = ClockSrc::PLL;
 | 
				
			||||||
 | 
					    config.rcc.pll = Some(Pll {
 | 
				
			||||||
 | 
					        // 80Mhz clock (16 / 1 * 10 / 2)
 | 
				
			||||||
 | 
					        source: PLLSource::HSI16,
 | 
				
			||||||
 | 
					        prediv: PllPreDiv::DIV1,
 | 
				
			||||||
 | 
					        mul: PllMul::MUL10,
 | 
				
			||||||
 | 
					        divp: None,
 | 
				
			||||||
 | 
					        divq: None,
 | 
				
			||||||
 | 
					        divr: Some(PllRDiv::DIV2),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
    let p = embassy_stm32::init(config);
 | 
					    let p = embassy_stm32::init(config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create the driver, from the HAL.
 | 
					    // Create the driver, from the HAL.
 | 
				
			||||||
 | 
				
			|||||||
@ -20,8 +20,17 @@ bind_interrupts!(struct Irqs {
 | 
				
			|||||||
#[embassy_executor::main]
 | 
					#[embassy_executor::main]
 | 
				
			||||||
async fn main(_spawner: Spawner) {
 | 
					async fn main(_spawner: Spawner) {
 | 
				
			||||||
    let mut config = Config::default();
 | 
					    let mut config = Config::default();
 | 
				
			||||||
    config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None);
 | 
					    config.rcc.hsi16 = true;
 | 
				
			||||||
    config.rcc.hsi48 = true;
 | 
					    config.rcc.mux = ClockSrc::PLL;
 | 
				
			||||||
 | 
					    config.rcc.pll = Some(Pll {
 | 
				
			||||||
 | 
					        // 80Mhz clock (16 / 1 * 10 / 2)
 | 
				
			||||||
 | 
					        source: PLLSource::HSI16,
 | 
				
			||||||
 | 
					        prediv: PllPreDiv::DIV1,
 | 
				
			||||||
 | 
					        mul: PllMul::MUL10,
 | 
				
			||||||
 | 
					        divp: None,
 | 
				
			||||||
 | 
					        divq: None,
 | 
				
			||||||
 | 
					        divr: Some(PllRDiv::DIV2),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
    let p = embassy_stm32::init(config);
 | 
					    let p = embassy_stm32::init(config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
				
			|||||||
@ -302,14 +302,17 @@ pub fn config() -> Config {
 | 
				
			|||||||
    #[cfg(any(feature = "stm32l552ze"))]
 | 
					    #[cfg(any(feature = "stm32l552ze"))]
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        use embassy_stm32::rcc::*;
 | 
					        use embassy_stm32::rcc::*;
 | 
				
			||||||
        config.rcc.mux = ClockSrc::PLL(
 | 
					        config.rcc.hsi16 = true;
 | 
				
			||||||
 | 
					        config.rcc.mux = ClockSrc::PLL;
 | 
				
			||||||
 | 
					        config.rcc.pll = Some(Pll {
 | 
				
			||||||
            // 110Mhz clock (16 / 4 * 55 / 2)
 | 
					            // 110Mhz clock (16 / 4 * 55 / 2)
 | 
				
			||||||
            PLLSource::HSI16,
 | 
					            source: PLLSource::HSI16,
 | 
				
			||||||
            PllRDiv::DIV2,
 | 
					            prediv: PllPreDiv::DIV4,
 | 
				
			||||||
            PllPreDiv::DIV4,
 | 
					            mul: PllMul::MUL55,
 | 
				
			||||||
            PllMul::MUL55,
 | 
					            divp: None,
 | 
				
			||||||
            None,
 | 
					            divq: None,
 | 
				
			||||||
        );
 | 
					            divr: Some(PllRDiv::DIV2),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(feature = "stm32u585ai")]
 | 
					    #[cfg(feature = "stm32u585ai")]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user