Merge pull request #2145 from embassy-rs/rcc-no-spaghetti
stm32/rcc: add shared code for hsi48 with crs support.
This commit is contained in:
		@@ -58,7 +58,7 @@ rand_core = "0.6.3"
 | 
			
		||||
sdio-host = "0.5.0"
 | 
			
		||||
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
 | 
			
		||||
critical-section = "1.1"
 | 
			
		||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73b8c37ae74fc28b247188c989fd99400611bd6b" }
 | 
			
		||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8381654ade324de3945c3c755d359686e957e99b" }
 | 
			
		||||
vcell = "0.1.3"
 | 
			
		||||
bxcan = "0.7.0"
 | 
			
		||||
nb = "1.0.0"
 | 
			
		||||
@@ -76,7 +76,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-73b8c37ae74fc28b247188c989fd99400611bd6b", default-features = false, features = ["metadata"]}
 | 
			
		||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8381654ade324de3945c3c755d359686e957e99b", default-features = false, features = ["metadata"]}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[features]
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ pub use crate::pac::rcc::vals::{
 | 
			
		||||
    Pllr as PllR, Ppre as APBPrescaler,
 | 
			
		||||
};
 | 
			
		||||
use crate::pac::{PWR, RCC};
 | 
			
		||||
use crate::rcc::sealed::RccPeripheral;
 | 
			
		||||
use crate::rcc::{set_freqs, Clocks};
 | 
			
		||||
use crate::time::Hertz;
 | 
			
		||||
 | 
			
		||||
@@ -67,23 +66,13 @@ pub struct Pll {
 | 
			
		||||
pub enum Clock48MhzSrc {
 | 
			
		||||
    /// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the
 | 
			
		||||
    /// oscillator to comply with the USB specification for oscillator tolerance.
 | 
			
		||||
    Hsi48(Option<CrsConfig>),
 | 
			
		||||
    Hsi48(super::Hsi48Config),
 | 
			
		||||
    /// Use the PLLQ output. The PLL must be configured to output a 48MHz clock. For USB usage the
 | 
			
		||||
    /// PLL needs to be using the HSE source to comply with the USB specification for oscillator
 | 
			
		||||
    /// tolerance.
 | 
			
		||||
    PllQ,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Sets the sync source for the Clock Recovery System (CRS).
 | 
			
		||||
pub enum CrsSyncSource {
 | 
			
		||||
    /// Use an external GPIO to sync the CRS.
 | 
			
		||||
    Gpio,
 | 
			
		||||
    /// Use the Low Speed External oscillator to sync the CRS.
 | 
			
		||||
    Lse,
 | 
			
		||||
    /// Use the USB SOF to sync the CRS.
 | 
			
		||||
    Usb,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Clocks configutation
 | 
			
		||||
pub struct Config {
 | 
			
		||||
    pub mux: ClockSrc,
 | 
			
		||||
@@ -102,12 +91,6 @@ pub struct Config {
 | 
			
		||||
    pub ls: super::LsConfig,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator.
 | 
			
		||||
pub struct CrsConfig {
 | 
			
		||||
    /// Sync source for the CRS.
 | 
			
		||||
    pub sync_src: CrsSyncSource,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for Config {
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn default() -> Config {
 | 
			
		||||
@@ -118,7 +101,7 @@ impl Default for Config {
 | 
			
		||||
            apb2_pre: APBPrescaler::DIV1,
 | 
			
		||||
            low_power_run: false,
 | 
			
		||||
            pll: None,
 | 
			
		||||
            clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(None)),
 | 
			
		||||
            clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(Default::default())),
 | 
			
		||||
            adc12_clock_source: Adcsel::DISABLE,
 | 
			
		||||
            adc345_clock_source: Adcsel::DISABLE,
 | 
			
		||||
            ls: Default::default(),
 | 
			
		||||
@@ -288,33 +271,8 @@ pub(crate) unsafe fn init(config: Config) {
 | 
			
		||||
 | 
			
		||||
                crate::pac::rcc::vals::Clk48sel::PLL1_Q
 | 
			
		||||
            }
 | 
			
		||||
            Clock48MhzSrc::Hsi48(crs_config) => {
 | 
			
		||||
                // Enable HSI48
 | 
			
		||||
                RCC.crrcr().modify(|w| w.set_hsi48on(true));
 | 
			
		||||
                // Wait for HSI48 to turn on
 | 
			
		||||
                while RCC.crrcr().read().hsi48rdy() == false {}
 | 
			
		||||
 | 
			
		||||
                // Enable and setup CRS if needed
 | 
			
		||||
                if let Some(crs_config) = crs_config {
 | 
			
		||||
                    crate::peripherals::CRS::enable_and_reset();
 | 
			
		||||
 | 
			
		||||
                    let sync_src = match crs_config.sync_src {
 | 
			
		||||
                        CrsSyncSource::Gpio => crate::pac::crs::vals::Syncsrc::GPIO,
 | 
			
		||||
                        CrsSyncSource::Lse => crate::pac::crs::vals::Syncsrc::LSE,
 | 
			
		||||
                        CrsSyncSource::Usb => crate::pac::crs::vals::Syncsrc::USB,
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    crate::pac::CRS.cfgr().modify(|w| {
 | 
			
		||||
                        w.set_syncsrc(sync_src);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    // These are the correct settings for standard USB operation. If other settings
 | 
			
		||||
                    // are needed there will need to be additional config options for the CRS.
 | 
			
		||||
                    crate::pac::CRS.cr().modify(|w| {
 | 
			
		||||
                        w.set_autotrimen(true);
 | 
			
		||||
                        w.set_cen(true);
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            Clock48MhzSrc::Hsi48(config) => {
 | 
			
		||||
                super::init_hsi48(config);
 | 
			
		||||
                crate::pac::rcc::vals::Clk48sel::HSI48
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 
 | 
			
		||||
@@ -21,9 +21,6 @@ pub const HSI_FREQ: Hertz = Hertz(64_000_000);
 | 
			
		||||
/// CSI speed
 | 
			
		||||
pub const CSI_FREQ: Hertz = Hertz(4_000_000);
 | 
			
		||||
 | 
			
		||||
/// HSI48 speed
 | 
			
		||||
pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
 | 
			
		||||
 | 
			
		||||
const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000);
 | 
			
		||||
#[cfg(any(stm32h5, pwr_h7rm0455))]
 | 
			
		||||
const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000);
 | 
			
		||||
@@ -126,7 +123,7 @@ pub struct Config {
 | 
			
		||||
    pub hsi: Option<HSIPrescaler>,
 | 
			
		||||
    pub hse: Option<Hse>,
 | 
			
		||||
    pub csi: bool,
 | 
			
		||||
    pub hsi48: bool,
 | 
			
		||||
    pub hsi48: Option<super::Hsi48Config>,
 | 
			
		||||
    pub sys: Sysclk,
 | 
			
		||||
 | 
			
		||||
    pub pll1: Option<Pll>,
 | 
			
		||||
@@ -155,7 +152,7 @@ impl Default for Config {
 | 
			
		||||
            hsi: Some(HSIPrescaler::DIV1),
 | 
			
		||||
            hse: None,
 | 
			
		||||
            csi: false,
 | 
			
		||||
            hsi48: false,
 | 
			
		||||
            hsi48: Some(Default::default()),
 | 
			
		||||
            sys: Sysclk::HSI,
 | 
			
		||||
            pll1: None,
 | 
			
		||||
            pll2: None,
 | 
			
		||||
@@ -301,14 +298,7 @@ pub(crate) unsafe fn init(config: Config) {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Configure HSI48.
 | 
			
		||||
    RCC.cr().modify(|w| w.set_hsi48on(config.hsi48));
 | 
			
		||||
    let _hsi48 = match config.hsi48 {
 | 
			
		||||
        false => None,
 | 
			
		||||
        true => {
 | 
			
		||||
            while !RCC.cr().read().hsi48rdy() {}
 | 
			
		||||
            Some(CSI_FREQ)
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    let _hsi48 = config.hsi48.map(super::init_hsi48);
 | 
			
		||||
 | 
			
		||||
    // Configure CSI.
 | 
			
		||||
    RCC.cr().modify(|w| w.set_csion(config.csi));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										62
									
								
								embassy-stm32/src/rcc/hsi48.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								embassy-stm32/src/rcc/hsi48.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
#![allow(unused)]
 | 
			
		||||
 | 
			
		||||
use crate::pac::crs::vals::Syncsrc;
 | 
			
		||||
use crate::pac::{CRS, RCC};
 | 
			
		||||
use crate::rcc::sealed::RccPeripheral;
 | 
			
		||||
use crate::time::Hertz;
 | 
			
		||||
 | 
			
		||||
/// HSI48 speed
 | 
			
		||||
pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
 | 
			
		||||
 | 
			
		||||
/// Configuration for the HSI48 clock
 | 
			
		||||
#[derive(Clone, Copy, Debug)]
 | 
			
		||||
pub struct Hsi48Config {
 | 
			
		||||
    /// Enable CRS Sync from USB Start Of Frame (SOF) events.
 | 
			
		||||
    /// Required if HSI48 is going to be used as USB clock.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Other use cases of CRS are not supported yet.
 | 
			
		||||
    pub sync_from_usb: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for Hsi48Config {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self { sync_from_usb: false }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz {
 | 
			
		||||
    // Enable VREFINT reference for HSI48 oscillator
 | 
			
		||||
    #[cfg(stm32l0)]
 | 
			
		||||
    crate::pac::SYSCFG.cfgr3().modify(|w| {
 | 
			
		||||
        w.set_enref_hsi48(true);
 | 
			
		||||
        w.set_en_vrefint(true);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Enable HSI48
 | 
			
		||||
    #[cfg(not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba, stm32f0)))]
 | 
			
		||||
    let r = RCC.crrcr();
 | 
			
		||||
    #[cfg(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba))]
 | 
			
		||||
    let r = RCC.cr();
 | 
			
		||||
    #[cfg(any(stm32f0))]
 | 
			
		||||
    let r = RCC.cr2();
 | 
			
		||||
 | 
			
		||||
    r.modify(|w| w.set_hsi48on(true));
 | 
			
		||||
    while r.read().hsi48rdy() == false {}
 | 
			
		||||
 | 
			
		||||
    if config.sync_from_usb {
 | 
			
		||||
        crate::peripherals::CRS::enable_and_reset();
 | 
			
		||||
 | 
			
		||||
        CRS.cfgr().modify(|w| {
 | 
			
		||||
            w.set_syncsrc(Syncsrc::USB);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // These are the correct settings for standard USB operation. If other settings
 | 
			
		||||
        // are needed there will need to be additional config options for the CRS.
 | 
			
		||||
        crate::pac::CRS.cr().modify(|w| {
 | 
			
		||||
            w.set_autotrimen(true);
 | 
			
		||||
            w.set_cen(true);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    HSI48_FREQ
 | 
			
		||||
}
 | 
			
		||||
@@ -3,8 +3,6 @@ pub use crate::pac::rcc::vals::{
 | 
			
		||||
    Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Plldiv as PllDiv, Pllmul as PLLMul, Pllmul as PllMul,
 | 
			
		||||
    Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc,
 | 
			
		||||
};
 | 
			
		||||
#[cfg(crs)]
 | 
			
		||||
use crate::pac::{crs, CRS, SYSCFG};
 | 
			
		||||
use crate::pac::{FLASH, PWR, RCC};
 | 
			
		||||
use crate::rcc::{set_freqs, Clocks};
 | 
			
		||||
use crate::time::Hertz;
 | 
			
		||||
@@ -47,7 +45,7 @@ pub struct Config {
 | 
			
		||||
    pub hsi: bool,
 | 
			
		||||
    pub hse: Option<Hse>,
 | 
			
		||||
    #[cfg(crs)]
 | 
			
		||||
    pub hsi48: bool,
 | 
			
		||||
    pub hsi48: Option<super::Hsi48Config>,
 | 
			
		||||
 | 
			
		||||
    pub pll: Option<Pll>,
 | 
			
		||||
 | 
			
		||||
@@ -68,7 +66,7 @@ impl Default for Config {
 | 
			
		||||
            hse: None,
 | 
			
		||||
            hsi: false,
 | 
			
		||||
            #[cfg(crs)]
 | 
			
		||||
            hsi48: false,
 | 
			
		||||
            hsi48: Some(Default::default()),
 | 
			
		||||
 | 
			
		||||
            pll: None,
 | 
			
		||||
 | 
			
		||||
@@ -174,37 +172,11 @@ pub(crate) unsafe fn init(config: Config) {
 | 
			
		||||
    let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre);
 | 
			
		||||
 | 
			
		||||
    #[cfg(crs)]
 | 
			
		||||
    if config.hsi48 {
 | 
			
		||||
        // Reset CRS peripheral
 | 
			
		||||
        RCC.apb1rstr().modify(|w| w.set_crsrst(true));
 | 
			
		||||
        RCC.apb1rstr().modify(|w| w.set_crsrst(false));
 | 
			
		||||
 | 
			
		||||
        // Enable CRS peripheral
 | 
			
		||||
        RCC.apb1enr().modify(|w| w.set_crsen(true));
 | 
			
		||||
 | 
			
		||||
        // Initialize CRS
 | 
			
		||||
        CRS.cfgr().write(|w|
 | 
			
		||||
 | 
			
		||||
        // Select LSE as synchronization source
 | 
			
		||||
        w.set_syncsrc(crs::vals::Syncsrc::LSE));
 | 
			
		||||
        CRS.cr().modify(|w| {
 | 
			
		||||
            w.set_autotrimen(true);
 | 
			
		||||
            w.set_cen(true);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Enable VREFINT reference for HSI48 oscillator
 | 
			
		||||
        SYSCFG.cfgr3().modify(|w| {
 | 
			
		||||
            w.set_enref_hsi48(true);
 | 
			
		||||
            w.set_en_vrefint(true);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    let _hsi48 = config.hsi48.map(|config| {
 | 
			
		||||
        // Select HSI48 as USB clock
 | 
			
		||||
        RCC.ccipr().modify(|w| w.set_hsi48msel(true));
 | 
			
		||||
 | 
			
		||||
        // Enable dedicated USB clock
 | 
			
		||||
        RCC.crrcr().modify(|w| w.set_hsi48on(true));
 | 
			
		||||
        while !RCC.crrcr().read().hsi48rdy() {}
 | 
			
		||||
    }
 | 
			
		||||
        super::init_hsi48(config)
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    set_freqs(Clocks {
 | 
			
		||||
        sys: sys_clk,
 | 
			
		||||
 
 | 
			
		||||
@@ -58,8 +58,8 @@ pub struct Config {
 | 
			
		||||
    pub msi: Option<MSIRange>,
 | 
			
		||||
    pub hsi: bool,
 | 
			
		||||
    pub hse: Option<Hse>,
 | 
			
		||||
    #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
 | 
			
		||||
    pub hsi48: bool,
 | 
			
		||||
    #[cfg(crs)]
 | 
			
		||||
    pub hsi48: Option<super::Hsi48Config>,
 | 
			
		||||
 | 
			
		||||
    // pll
 | 
			
		||||
    pub pll: Option<Pll>,
 | 
			
		||||
@@ -108,8 +108,8 @@ impl Default for Config {
 | 
			
		||||
            pllsai1: None,
 | 
			
		||||
            #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
 | 
			
		||||
            pllsai2: None,
 | 
			
		||||
            #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
 | 
			
		||||
            hsi48: true,
 | 
			
		||||
            #[cfg(crs)]
 | 
			
		||||
            hsi48: Some(Default::default()),
 | 
			
		||||
            #[cfg(any(stm32l4, stm32l5, stm32wb))]
 | 
			
		||||
            clk48_src: Clk48Src::HSI48,
 | 
			
		||||
            ls: Default::default(),
 | 
			
		||||
@@ -126,7 +126,8 @@ pub const WPAN_DEFAULT: Config = Config {
 | 
			
		||||
        prescaler: HsePrescaler::DIV1,
 | 
			
		||||
    }),
 | 
			
		||||
    mux: ClockSrc::PLL1_R,
 | 
			
		||||
    hsi48: true,
 | 
			
		||||
    #[cfg(crs)]
 | 
			
		||||
    hsi48: Some(super::Hsi48Config { sync_from_usb: false }),
 | 
			
		||||
    msi: None,
 | 
			
		||||
    hsi: false,
 | 
			
		||||
    clk48_src: Clk48Src::PLL1_Q,
 | 
			
		||||
@@ -216,15 +217,10 @@ pub(crate) unsafe fn init(config: Config) {
 | 
			
		||||
        hse.freq
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
 | 
			
		||||
    let hsi48 = config.hsi48.then(|| {
 | 
			
		||||
        RCC.crrcr().modify(|w| w.set_hsi48on(true));
 | 
			
		||||
        while !RCC.crrcr().read().hsi48rdy() {}
 | 
			
		||||
 | 
			
		||||
        Hertz(48_000_000)
 | 
			
		||||
    });
 | 
			
		||||
    #[cfg(any(stm32l47x, stm32l48x))]
 | 
			
		||||
    let hsi48 = None;
 | 
			
		||||
    #[cfg(crs)]
 | 
			
		||||
    let _hsi48 = config.hsi48.map(super::init_hsi48);
 | 
			
		||||
    #[cfg(not(crs))]
 | 
			
		||||
    let _hsi48: Option<Hertz> = None;
 | 
			
		||||
 | 
			
		||||
    let _plls = [
 | 
			
		||||
        &config.pll,
 | 
			
		||||
@@ -275,7 +271,7 @@ pub(crate) unsafe fn init(config: Config) {
 | 
			
		||||
    RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src));
 | 
			
		||||
    #[cfg(any(stm32l4, stm32l5, stm32wb))]
 | 
			
		||||
    let _clk48 = match config.clk48_src {
 | 
			
		||||
        Clk48Src::HSI48 => hsi48,
 | 
			
		||||
        Clk48Src::HSI48 => _hsi48,
 | 
			
		||||
        Clk48Src::MSI => msi,
 | 
			
		||||
        Clk48Src::PLLSAI1_Q => pllsai1.q,
 | 
			
		||||
        Clk48Src::PLL1_Q => pll.q,
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,11 @@ mod mco;
 | 
			
		||||
pub use bd::*;
 | 
			
		||||
pub use mco::*;
 | 
			
		||||
 | 
			
		||||
#[cfg(crs)]
 | 
			
		||||
mod hsi48;
 | 
			
		||||
#[cfg(crs)]
 | 
			
		||||
pub use hsi48::*;
 | 
			
		||||
 | 
			
		||||
#[cfg_attr(rcc_f0, path = "f0.rs")]
 | 
			
		||||
#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")]
 | 
			
		||||
#[cfg_attr(rcc_f2, path = "f2.rs")]
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,7 @@ pub struct Config {
 | 
			
		||||
    pub apb1_pre: APBPrescaler,
 | 
			
		||||
    pub apb2_pre: APBPrescaler,
 | 
			
		||||
    pub apb3_pre: APBPrescaler,
 | 
			
		||||
    pub hsi48: bool,
 | 
			
		||||
    pub hsi48: Option<super::Hsi48Config>,
 | 
			
		||||
    /// The voltage range influences the maximum clock frequencies for different parts of the
 | 
			
		||||
    /// device. In particular, system clocks exceeding 110 MHz require `RANGE1`, and system clocks
 | 
			
		||||
    /// exceeding 55 MHz require at least `RANGE2`.
 | 
			
		||||
@@ -189,7 +189,7 @@ impl Default for Config {
 | 
			
		||||
            apb1_pre: APBPrescaler::DIV1,
 | 
			
		||||
            apb2_pre: APBPrescaler::DIV1,
 | 
			
		||||
            apb3_pre: APBPrescaler::DIV1,
 | 
			
		||||
            hsi48: true,
 | 
			
		||||
            hsi48: Some(Default::default()),
 | 
			
		||||
            voltage_range: VoltageScale::RANGE3,
 | 
			
		||||
            ls: Default::default(),
 | 
			
		||||
        }
 | 
			
		||||
@@ -322,10 +322,7 @@ pub(crate) unsafe fn init(config: Config) {
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if config.hsi48 {
 | 
			
		||||
        RCC.cr().modify(|w| w.set_hsi48on(true));
 | 
			
		||||
        while !RCC.cr().read().hsi48rdy() {}
 | 
			
		||||
    }
 | 
			
		||||
    let _hsi48 = config.hsi48.map(super::init_hsi48);
 | 
			
		||||
 | 
			
		||||
    // The clock source is ready
 | 
			
		||||
    // Calculate and set the flash wait states
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
use defmt::{panic, *};
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, CrsConfig, CrsSyncSource, Pll, PllM, PllN, PllQ, PllR, PllSrc};
 | 
			
		||||
use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSrc};
 | 
			
		||||
use embassy_stm32::time::Hertz;
 | 
			
		||||
use embassy_stm32::usb::{self, Driver, Instance};
 | 
			
		||||
use embassy_stm32::{bind_interrupts, peripherals, Config};
 | 
			
		||||
@@ -41,9 +41,7 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
 | 
			
		||||
    if USE_HSI48 {
 | 
			
		||||
        // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
 | 
			
		||||
        config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Some(CrsConfig {
 | 
			
		||||
            sync_src: CrsSyncSource::Usb,
 | 
			
		||||
        })));
 | 
			
		||||
        config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true }));
 | 
			
		||||
    } else {
 | 
			
		||||
        config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ async fn net_task(stack: &'static Stack<Device>) -> ! {
 | 
			
		||||
async fn main(spawner: Spawner) -> ! {
 | 
			
		||||
    let mut config = Config::default();
 | 
			
		||||
    config.rcc.hsi = None;
 | 
			
		||||
    config.rcc.hsi48 = true; // needed for rng
 | 
			
		||||
    config.rcc.hsi48 = Some(Default::default()); // needed for RNG
 | 
			
		||||
    config.rcc.hse = Some(Hse {
 | 
			
		||||
        freq: Hertz(8_000_000),
 | 
			
		||||
        mode: HseMode::BypassDigital,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,6 @@
 | 
			
		||||
 | 
			
		||||
use defmt::{panic, *};
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_stm32::rcc::{
 | 
			
		||||
    AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllDiv, PllMul, PllPreDiv, PllSource, Sysclk, VoltageScale,
 | 
			
		||||
};
 | 
			
		||||
use embassy_stm32::time::Hertz;
 | 
			
		||||
use embassy_stm32::usb::{Driver, Instance};
 | 
			
		||||
use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config};
 | 
			
		||||
@@ -23,8 +20,10 @@ bind_interrupts!(struct Irqs {
 | 
			
		||||
#[embassy_executor::main]
 | 
			
		||||
async fn main(_spawner: Spawner) {
 | 
			
		||||
    let mut config = Config::default();
 | 
			
		||||
    {
 | 
			
		||||
        use embassy_stm32::rcc::*;
 | 
			
		||||
        config.rcc.hsi = None;
 | 
			
		||||
    config.rcc.hsi48 = true; // needed for usb
 | 
			
		||||
        config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
 | 
			
		||||
        config.rcc.hse = Some(Hse {
 | 
			
		||||
            freq: Hertz(8_000_000),
 | 
			
		||||
            mode: HseMode::BypassDigital,
 | 
			
		||||
@@ -43,6 +42,7 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
        config.rcc.apb3_pre = APBPrescaler::DIV4;
 | 
			
		||||
        config.rcc.sys = Sysclk::PLL1_P;
 | 
			
		||||
        config.rcc.voltage_scale = VoltageScale::Scale0;
 | 
			
		||||
    }
 | 
			
		||||
    let p = embassy_stm32::init(config);
 | 
			
		||||
 | 
			
		||||
    info!("Hello World!");
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ async fn main(spawner: Spawner) -> ! {
 | 
			
		||||
        use embassy_stm32::rcc::*;
 | 
			
		||||
        config.rcc.hsi = Some(HSIPrescaler::DIV1);
 | 
			
		||||
        config.rcc.csi = true;
 | 
			
		||||
        config.rcc.hsi48 = true; // needed for RNG
 | 
			
		||||
        config.rcc.hsi48 = Some(Default::default()); // needed for RNG
 | 
			
		||||
        config.rcc.pll1 = Some(Pll {
 | 
			
		||||
            source: PllSource::HSI,
 | 
			
		||||
            prediv: PllPreDiv::DIV4,
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ async fn main(spawner: Spawner) -> ! {
 | 
			
		||||
        use embassy_stm32::rcc::*;
 | 
			
		||||
        config.rcc.hsi = Some(HSIPrescaler::DIV1);
 | 
			
		||||
        config.rcc.csi = true;
 | 
			
		||||
        config.rcc.hsi48 = true; // needed for RNG
 | 
			
		||||
        config.rcc.hsi48 = Some(Default::default()); // needed for RNG
 | 
			
		||||
        config.rcc.pll1 = Some(Pll {
 | 
			
		||||
            source: PllSource::HSI,
 | 
			
		||||
            prediv: PllPreDiv::DIV4,
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
        use embassy_stm32::rcc::*;
 | 
			
		||||
        config.rcc.hsi = Some(HSIPrescaler::DIV1);
 | 
			
		||||
        config.rcc.csi = true;
 | 
			
		||||
        config.rcc.hsi48 = true; // needed for RNG
 | 
			
		||||
        config.rcc.pll1 = Some(Pll {
 | 
			
		||||
            source: PllSource::HSI,
 | 
			
		||||
            prediv: PllPreDiv::DIV4,
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ bind_interrupts!(struct Irqs {
 | 
			
		||||
#[embassy_executor::main]
 | 
			
		||||
async fn main(_spawner: Spawner) {
 | 
			
		||||
    let mut config = Config::default();
 | 
			
		||||
    config.rcc.hsi48 = true; // needed for RNG.
 | 
			
		||||
    config.rcc.hsi48 = Some(Default::default()); // needed for RNG
 | 
			
		||||
    let p = embassy_stm32::init(config);
 | 
			
		||||
    info!("Hello World!");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
        use embassy_stm32::rcc::*;
 | 
			
		||||
        config.rcc.hsi = Some(HSIPrescaler::DIV1);
 | 
			
		||||
        config.rcc.csi = true;
 | 
			
		||||
        config.rcc.hsi48 = true; // needed for USB
 | 
			
		||||
        config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
 | 
			
		||||
        config.rcc.pll1 = Some(Pll {
 | 
			
		||||
            source: PllSource::HSI,
 | 
			
		||||
            prediv: PllPreDiv::DIV4,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,7 @@ use {defmt_rtt as _, panic_probe as _};
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::main]
 | 
			
		||||
async fn main(_spawner: Spawner) {
 | 
			
		||||
    let mut config = Config::default();
 | 
			
		||||
    config.rcc.hsi48 = true;
 | 
			
		||||
    let config = Config::default();
 | 
			
		||||
    let p = embassy_stm32::init(config);
 | 
			
		||||
 | 
			
		||||
    let button = Input::new(p.PB2, Pull::Up);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel
 | 
			
		||||
#[embassy_executor::main]
 | 
			
		||||
async fn main(_spawner: Spawner) {
 | 
			
		||||
    let mut config = embassy_stm32::Config::default();
 | 
			
		||||
    config.rcc.hsi = true;
 | 
			
		||||
    config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
 | 
			
		||||
    config.rcc.hsi48 = true;
 | 
			
		||||
    let p = embassy_stm32::init(config);
 | 
			
		||||
 | 
			
		||||
    let mut spi_config = spi::Config::default();
 | 
			
		||||
 
 | 
			
		||||
@@ -33,8 +33,8 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th
 | 
			
		||||
#[embassy_executor::main]
 | 
			
		||||
async fn main(_spawner: Spawner) {
 | 
			
		||||
    let mut config = embassy_stm32::Config::default();
 | 
			
		||||
    config.rcc.hsi = true;
 | 
			
		||||
    config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
 | 
			
		||||
    config.rcc.hsi48 = true;
 | 
			
		||||
    let p = embassy_stm32::init(config);
 | 
			
		||||
 | 
			
		||||
    let mut spi_config = spi::Config::default();
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel
 | 
			
		||||
#[embassy_executor::main]
 | 
			
		||||
async fn main(_spawner: Spawner) {
 | 
			
		||||
    let mut config = embassy_stm32::Config::default();
 | 
			
		||||
    config.rcc.hsi = true;
 | 
			
		||||
    config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
 | 
			
		||||
    config.rcc.hsi48 = true;
 | 
			
		||||
    let p = embassy_stm32::init(config);
 | 
			
		||||
 | 
			
		||||
    let mut spi_config = spi::Config::default();
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel
 | 
			
		||||
#[embassy_executor::main]
 | 
			
		||||
async fn main(_spawner: Spawner) {
 | 
			
		||||
    let mut config = embassy_stm32::Config::default();
 | 
			
		||||
    config.rcc.hsi = true;
 | 
			
		||||
    config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
 | 
			
		||||
    config.rcc.hsi48 = true;
 | 
			
		||||
    let p = embassy_stm32::init(config);
 | 
			
		||||
 | 
			
		||||
    let mut spi_config = spi::Config::default();
 | 
			
		||||
 
 | 
			
		||||
@@ -90,7 +90,7 @@ async fn main(spawner: Spawner) {
 | 
			
		||||
            divq: None,
 | 
			
		||||
            divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2)
 | 
			
		||||
        });
 | 
			
		||||
        config.rcc.hsi48 = true; // needed for rng
 | 
			
		||||
        config.rcc.hsi48 = Some(Default::default()); // needed for RNG
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let dp = embassy_stm32::init(config);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
    info!("Hello World!");
 | 
			
		||||
 | 
			
		||||
    let mut config = Config::default();
 | 
			
		||||
    config.rcc.hsi48 = true;
 | 
			
		||||
    config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
 | 
			
		||||
    config.rcc.mux = ClockSrc::PLL1_R;
 | 
			
		||||
    config.rcc.hsi = true;
 | 
			
		||||
    config.rcc.pll = Some(Pll {
 | 
			
		||||
 
 | 
			
		||||
@@ -29,8 +29,7 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
        n: Plln::MUL10,
 | 
			
		||||
        r: Plldiv::DIV1,
 | 
			
		||||
    });
 | 
			
		||||
    //config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz);
 | 
			
		||||
    config.rcc.hsi48 = true;
 | 
			
		||||
    config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
 | 
			
		||||
 | 
			
		||||
    let p = embassy_stm32::init(config);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -306,7 +306,7 @@ pub fn config() -> Config {
 | 
			
		||||
    {
 | 
			
		||||
        use embassy_stm32::rcc::*;
 | 
			
		||||
        config.rcc.hsi = None;
 | 
			
		||||
        config.rcc.hsi48 = true; // needed for rng
 | 
			
		||||
        config.rcc.hsi48 = Some(Default::default()); // needed for RNG
 | 
			
		||||
        config.rcc.hse = Some(Hse {
 | 
			
		||||
            freq: Hertz(8_000_000),
 | 
			
		||||
            mode: HseMode::BypassDigital,
 | 
			
		||||
@@ -332,7 +332,7 @@ pub fn config() -> Config {
 | 
			
		||||
        use embassy_stm32::rcc::*;
 | 
			
		||||
        config.rcc.hsi = Some(HSIPrescaler::DIV1);
 | 
			
		||||
        config.rcc.csi = true;
 | 
			
		||||
        config.rcc.hsi48 = true; // needed for RNG
 | 
			
		||||
        config.rcc.hsi48 = Some(Default::default()); // needed for RNG
 | 
			
		||||
        config.rcc.pll1 = Some(Pll {
 | 
			
		||||
            source: PllSource::HSI,
 | 
			
		||||
            prediv: PllPreDiv::DIV4,
 | 
			
		||||
@@ -364,7 +364,7 @@ pub fn config() -> Config {
 | 
			
		||||
        use embassy_stm32::rcc::*;
 | 
			
		||||
        config.rcc.hsi = Some(HSIPrescaler::DIV1);
 | 
			
		||||
        config.rcc.csi = true;
 | 
			
		||||
        config.rcc.hsi48 = true; // needed for RNG
 | 
			
		||||
        config.rcc.hsi48 = Some(Default::default()); // needed for RNG
 | 
			
		||||
        config.rcc.pll1 = Some(Pll {
 | 
			
		||||
            source: PllSource::HSI,
 | 
			
		||||
            prediv: PllPreDiv::DIV4,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user