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:
commit
3de01bc223
@ -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-73b8c37ae74fc28b247188c989fd99400611bd6b" }
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8381654ade324de3945c3c755d359686e957e99b" }
|
||||||
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-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]
|
[features]
|
||||||
|
@ -7,7 +7,6 @@ pub use crate::pac::rcc::vals::{
|
|||||||
Pllr as PllR, Ppre as APBPrescaler,
|
Pllr as PllR, Ppre as APBPrescaler,
|
||||||
};
|
};
|
||||||
use crate::pac::{PWR, RCC};
|
use crate::pac::{PWR, RCC};
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
|
||||||
use crate::rcc::{set_freqs, Clocks};
|
use crate::rcc::{set_freqs, Clocks};
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
|
|
||||||
@ -67,23 +66,13 @@ pub struct Pll {
|
|||||||
pub enum Clock48MhzSrc {
|
pub enum Clock48MhzSrc {
|
||||||
/// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the
|
/// 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.
|
/// 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
|
/// 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
|
/// PLL needs to be using the HSE source to comply with the USB specification for oscillator
|
||||||
/// tolerance.
|
/// tolerance.
|
||||||
PllQ,
|
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
|
/// Clocks configutation
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub mux: ClockSrc,
|
pub mux: ClockSrc,
|
||||||
@ -102,12 +91,6 @@ pub struct Config {
|
|||||||
pub ls: super::LsConfig,
|
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 {
|
impl Default for Config {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Config {
|
fn default() -> Config {
|
||||||
@ -118,7 +101,7 @@ impl Default for Config {
|
|||||||
apb2_pre: APBPrescaler::DIV1,
|
apb2_pre: APBPrescaler::DIV1,
|
||||||
low_power_run: false,
|
low_power_run: false,
|
||||||
pll: None,
|
pll: None,
|
||||||
clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(None)),
|
clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(Default::default())),
|
||||||
adc12_clock_source: Adcsel::DISABLE,
|
adc12_clock_source: Adcsel::DISABLE,
|
||||||
adc345_clock_source: Adcsel::DISABLE,
|
adc345_clock_source: Adcsel::DISABLE,
|
||||||
ls: Default::default(),
|
ls: Default::default(),
|
||||||
@ -288,33 +271,8 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
|
|
||||||
crate::pac::rcc::vals::Clk48sel::PLL1_Q
|
crate::pac::rcc::vals::Clk48sel::PLL1_Q
|
||||||
}
|
}
|
||||||
Clock48MhzSrc::Hsi48(crs_config) => {
|
Clock48MhzSrc::Hsi48(config) => {
|
||||||
// Enable HSI48
|
super::init_hsi48(config);
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
crate::pac::rcc::vals::Clk48sel::HSI48
|
crate::pac::rcc::vals::Clk48sel::HSI48
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -21,9 +21,6 @@ pub const HSI_FREQ: Hertz = Hertz(64_000_000);
|
|||||||
/// CSI speed
|
/// CSI speed
|
||||||
pub const CSI_FREQ: Hertz = Hertz(4_000_000);
|
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);
|
const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000);
|
||||||
#[cfg(any(stm32h5, pwr_h7rm0455))]
|
#[cfg(any(stm32h5, pwr_h7rm0455))]
|
||||||
const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000);
|
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 hsi: Option<HSIPrescaler>,
|
||||||
pub hse: Option<Hse>,
|
pub hse: Option<Hse>,
|
||||||
pub csi: bool,
|
pub csi: bool,
|
||||||
pub hsi48: bool,
|
pub hsi48: Option<super::Hsi48Config>,
|
||||||
pub sys: Sysclk,
|
pub sys: Sysclk,
|
||||||
|
|
||||||
pub pll1: Option<Pll>,
|
pub pll1: Option<Pll>,
|
||||||
@ -155,7 +152,7 @@ impl Default for Config {
|
|||||||
hsi: Some(HSIPrescaler::DIV1),
|
hsi: Some(HSIPrescaler::DIV1),
|
||||||
hse: None,
|
hse: None,
|
||||||
csi: false,
|
csi: false,
|
||||||
hsi48: false,
|
hsi48: Some(Default::default()),
|
||||||
sys: Sysclk::HSI,
|
sys: Sysclk::HSI,
|
||||||
pll1: None,
|
pll1: None,
|
||||||
pll2: None,
|
pll2: None,
|
||||||
@ -301,14 +298,7 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Configure HSI48.
|
// Configure HSI48.
|
||||||
RCC.cr().modify(|w| w.set_hsi48on(config.hsi48));
|
let _hsi48 = config.hsi48.map(super::init_hsi48);
|
||||||
let _hsi48 = match config.hsi48 {
|
|
||||||
false => None,
|
|
||||||
true => {
|
|
||||||
while !RCC.cr().read().hsi48rdy() {}
|
|
||||||
Some(CSI_FREQ)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Configure CSI.
|
// Configure CSI.
|
||||||
RCC.cr().modify(|w| w.set_csion(config.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,
|
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,
|
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::pac::{FLASH, PWR, RCC};
|
||||||
use crate::rcc::{set_freqs, Clocks};
|
use crate::rcc::{set_freqs, Clocks};
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
@ -47,7 +45,7 @@ pub struct Config {
|
|||||||
pub hsi: bool,
|
pub hsi: bool,
|
||||||
pub hse: Option<Hse>,
|
pub hse: Option<Hse>,
|
||||||
#[cfg(crs)]
|
#[cfg(crs)]
|
||||||
pub hsi48: bool,
|
pub hsi48: Option<super::Hsi48Config>,
|
||||||
|
|
||||||
pub pll: Option<Pll>,
|
pub pll: Option<Pll>,
|
||||||
|
|
||||||
@ -68,7 +66,7 @@ impl Default for Config {
|
|||||||
hse: None,
|
hse: None,
|
||||||
hsi: false,
|
hsi: false,
|
||||||
#[cfg(crs)]
|
#[cfg(crs)]
|
||||||
hsi48: false,
|
hsi48: Some(Default::default()),
|
||||||
|
|
||||||
pll: None,
|
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);
|
let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre);
|
||||||
|
|
||||||
#[cfg(crs)]
|
#[cfg(crs)]
|
||||||
if config.hsi48 {
|
let _hsi48 = config.hsi48.map(|config| {
|
||||||
// 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);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Select HSI48 as USB clock
|
// Select HSI48 as USB clock
|
||||||
RCC.ccipr().modify(|w| w.set_hsi48msel(true));
|
RCC.ccipr().modify(|w| w.set_hsi48msel(true));
|
||||||
|
super::init_hsi48(config)
|
||||||
// Enable dedicated USB clock
|
});
|
||||||
RCC.crrcr().modify(|w| w.set_hsi48on(true));
|
|
||||||
while !RCC.crrcr().read().hsi48rdy() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_freqs(Clocks {
|
set_freqs(Clocks {
|
||||||
sys: sys_clk,
|
sys: sys_clk,
|
||||||
|
@ -58,8 +58,8 @@ pub struct Config {
|
|||||||
pub msi: Option<MSIRange>,
|
pub msi: Option<MSIRange>,
|
||||||
pub hsi: bool,
|
pub hsi: bool,
|
||||||
pub hse: Option<Hse>,
|
pub hse: Option<Hse>,
|
||||||
#[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
|
#[cfg(crs)]
|
||||||
pub hsi48: bool,
|
pub hsi48: Option<super::Hsi48Config>,
|
||||||
|
|
||||||
// pll
|
// pll
|
||||||
pub pll: Option<Pll>,
|
pub pll: Option<Pll>,
|
||||||
@ -108,8 +108,8 @@ impl Default for Config {
|
|||||||
pllsai1: None,
|
pllsai1: None,
|
||||||
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
|
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
|
||||||
pllsai2: None,
|
pllsai2: None,
|
||||||
#[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
|
#[cfg(crs)]
|
||||||
hsi48: true,
|
hsi48: Some(Default::default()),
|
||||||
#[cfg(any(stm32l4, stm32l5, stm32wb))]
|
#[cfg(any(stm32l4, stm32l5, stm32wb))]
|
||||||
clk48_src: Clk48Src::HSI48,
|
clk48_src: Clk48Src::HSI48,
|
||||||
ls: Default::default(),
|
ls: Default::default(),
|
||||||
@ -126,7 +126,8 @@ pub const WPAN_DEFAULT: Config = Config {
|
|||||||
prescaler: HsePrescaler::DIV1,
|
prescaler: HsePrescaler::DIV1,
|
||||||
}),
|
}),
|
||||||
mux: ClockSrc::PLL1_R,
|
mux: ClockSrc::PLL1_R,
|
||||||
hsi48: true,
|
#[cfg(crs)]
|
||||||
|
hsi48: Some(super::Hsi48Config { sync_from_usb: false }),
|
||||||
msi: None,
|
msi: None,
|
||||||
hsi: false,
|
hsi: false,
|
||||||
clk48_src: Clk48Src::PLL1_Q,
|
clk48_src: Clk48Src::PLL1_Q,
|
||||||
@ -216,15 +217,10 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
hse.freq
|
hse.freq
|
||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
|
#[cfg(crs)]
|
||||||
let hsi48 = config.hsi48.then(|| {
|
let _hsi48 = config.hsi48.map(super::init_hsi48);
|
||||||
RCC.crrcr().modify(|w| w.set_hsi48on(true));
|
#[cfg(not(crs))]
|
||||||
while !RCC.crrcr().read().hsi48rdy() {}
|
let _hsi48: Option<Hertz> = None;
|
||||||
|
|
||||||
Hertz(48_000_000)
|
|
||||||
});
|
|
||||||
#[cfg(any(stm32l47x, stm32l48x))]
|
|
||||||
let hsi48 = None;
|
|
||||||
|
|
||||||
let _plls = [
|
let _plls = [
|
||||||
&config.pll,
|
&config.pll,
|
||||||
@ -275,7 +271,7 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src));
|
RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src));
|
||||||
#[cfg(any(stm32l4, stm32l5, stm32wb))]
|
#[cfg(any(stm32l4, stm32l5, stm32wb))]
|
||||||
let _clk48 = match config.clk48_src {
|
let _clk48 = match config.clk48_src {
|
||||||
Clk48Src::HSI48 => hsi48,
|
Clk48Src::HSI48 => _hsi48,
|
||||||
Clk48Src::MSI => msi,
|
Clk48Src::MSI => msi,
|
||||||
Clk48Src::PLLSAI1_Q => pllsai1.q,
|
Clk48Src::PLLSAI1_Q => pllsai1.q,
|
||||||
Clk48Src::PLL1_Q => pll.q,
|
Clk48Src::PLL1_Q => pll.q,
|
||||||
|
@ -9,6 +9,11 @@ mod mco;
|
|||||||
pub use bd::*;
|
pub use bd::*;
|
||||||
pub use mco::*;
|
pub use mco::*;
|
||||||
|
|
||||||
|
#[cfg(crs)]
|
||||||
|
mod hsi48;
|
||||||
|
#[cfg(crs)]
|
||||||
|
pub use hsi48::*;
|
||||||
|
|
||||||
#[cfg_attr(rcc_f0, path = "f0.rs")]
|
#[cfg_attr(rcc_f0, path = "f0.rs")]
|
||||||
#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")]
|
#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")]
|
||||||
#[cfg_attr(rcc_f2, path = "f2.rs")]
|
#[cfg_attr(rcc_f2, path = "f2.rs")]
|
||||||
|
@ -115,7 +115,7 @@ pub struct Config {
|
|||||||
pub apb1_pre: APBPrescaler,
|
pub apb1_pre: APBPrescaler,
|
||||||
pub apb2_pre: APBPrescaler,
|
pub apb2_pre: APBPrescaler,
|
||||||
pub apb3_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
|
/// 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
|
/// device. In particular, system clocks exceeding 110 MHz require `RANGE1`, and system clocks
|
||||||
/// exceeding 55 MHz require at least `RANGE2`.
|
/// exceeding 55 MHz require at least `RANGE2`.
|
||||||
@ -189,7 +189,7 @@ impl Default for Config {
|
|||||||
apb1_pre: APBPrescaler::DIV1,
|
apb1_pre: APBPrescaler::DIV1,
|
||||||
apb2_pre: APBPrescaler::DIV1,
|
apb2_pre: APBPrescaler::DIV1,
|
||||||
apb3_pre: APBPrescaler::DIV1,
|
apb3_pre: APBPrescaler::DIV1,
|
||||||
hsi48: true,
|
hsi48: Some(Default::default()),
|
||||||
voltage_range: VoltageScale::RANGE3,
|
voltage_range: VoltageScale::RANGE3,
|
||||||
ls: Default::default(),
|
ls: Default::default(),
|
||||||
}
|
}
|
||||||
@ -322,10 +322,7 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if config.hsi48 {
|
let _hsi48 = config.hsi48.map(super::init_hsi48);
|
||||||
RCC.cr().modify(|w| w.set_hsi48on(true));
|
|
||||||
while !RCC.cr().read().hsi48rdy() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The clock source is ready
|
// The clock source is ready
|
||||||
// Calculate and set the flash wait states
|
// Calculate and set the flash wait states
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use defmt::{panic, *};
|
use defmt::{panic, *};
|
||||||
use embassy_executor::Spawner;
|
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::time::Hertz;
|
||||||
use embassy_stm32::usb::{self, Driver, Instance};
|
use embassy_stm32::usb::{self, Driver, Instance};
|
||||||
use embassy_stm32::{bind_interrupts, peripherals, Config};
|
use embassy_stm32::{bind_interrupts, peripherals, Config};
|
||||||
@ -41,9 +41,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
if USE_HSI48 {
|
if USE_HSI48 {
|
||||||
// Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
|
// 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 {
|
config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true }));
|
||||||
sync_src: CrsSyncSource::Usb,
|
|
||||||
})));
|
|
||||||
} else {
|
} else {
|
||||||
config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ);
|
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) -> ! {
|
async fn main(spawner: Spawner) -> ! {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.rcc.hsi = None;
|
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 {
|
config.rcc.hse = Some(Hse {
|
||||||
freq: Hertz(8_000_000),
|
freq: Hertz(8_000_000),
|
||||||
mode: HseMode::BypassDigital,
|
mode: HseMode::BypassDigital,
|
||||||
|
@ -4,9 +4,6 @@
|
|||||||
|
|
||||||
use defmt::{panic, *};
|
use defmt::{panic, *};
|
||||||
use embassy_executor::Spawner;
|
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::time::Hertz;
|
||||||
use embassy_stm32::usb::{Driver, Instance};
|
use embassy_stm32::usb::{Driver, Instance};
|
||||||
use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config};
|
use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config};
|
||||||
@ -23,26 +20,29 @@ 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.hsi = None;
|
{
|
||||||
config.rcc.hsi48 = true; // needed for usb
|
use embassy_stm32::rcc::*;
|
||||||
config.rcc.hse = Some(Hse {
|
config.rcc.hsi = None;
|
||||||
freq: Hertz(8_000_000),
|
config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
|
||||||
mode: HseMode::BypassDigital,
|
config.rcc.hse = Some(Hse {
|
||||||
});
|
freq: Hertz(8_000_000),
|
||||||
config.rcc.pll1 = Some(Pll {
|
mode: HseMode::BypassDigital,
|
||||||
source: PllSource::HSE,
|
});
|
||||||
prediv: PllPreDiv::DIV2,
|
config.rcc.pll1 = Some(Pll {
|
||||||
mul: PllMul::MUL125,
|
source: PllSource::HSE,
|
||||||
divp: Some(PllDiv::DIV2), // 250mhz
|
prediv: PllPreDiv::DIV2,
|
||||||
divq: None,
|
mul: PllMul::MUL125,
|
||||||
divr: None,
|
divp: Some(PllDiv::DIV2), // 250mhz
|
||||||
});
|
divq: None,
|
||||||
config.rcc.ahb_pre = AHBPrescaler::DIV2;
|
divr: None,
|
||||||
config.rcc.apb1_pre = APBPrescaler::DIV4;
|
});
|
||||||
config.rcc.apb2_pre = APBPrescaler::DIV2;
|
config.rcc.ahb_pre = AHBPrescaler::DIV2;
|
||||||
config.rcc.apb3_pre = APBPrescaler::DIV4;
|
config.rcc.apb1_pre = APBPrescaler::DIV4;
|
||||||
config.rcc.sys = Sysclk::PLL1_P;
|
config.rcc.apb2_pre = APBPrescaler::DIV2;
|
||||||
config.rcc.voltage_scale = VoltageScale::Scale0;
|
config.rcc.apb3_pre = APBPrescaler::DIV4;
|
||||||
|
config.rcc.sys = Sysclk::PLL1_P;
|
||||||
|
config.rcc.voltage_scale = VoltageScale::Scale0;
|
||||||
|
}
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
@ -36,7 +36,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
use embassy_stm32::rcc::*;
|
use embassy_stm32::rcc::*;
|
||||||
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
||||||
config.rcc.csi = true;
|
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 {
|
config.rcc.pll1 = Some(Pll {
|
||||||
source: PllSource::HSI,
|
source: PllSource::HSI,
|
||||||
prediv: PllPreDiv::DIV4,
|
prediv: PllPreDiv::DIV4,
|
||||||
|
@ -37,7 +37,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
use embassy_stm32::rcc::*;
|
use embassy_stm32::rcc::*;
|
||||||
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
||||||
config.rcc.csi = true;
|
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 {
|
config.rcc.pll1 = Some(Pll {
|
||||||
source: PllSource::HSI,
|
source: PllSource::HSI,
|
||||||
prediv: PllPreDiv::DIV4,
|
prediv: PllPreDiv::DIV4,
|
||||||
|
@ -19,7 +19,6 @@ async fn main(_spawner: Spawner) {
|
|||||||
use embassy_stm32::rcc::*;
|
use embassy_stm32::rcc::*;
|
||||||
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
||||||
config.rcc.csi = true;
|
config.rcc.csi = true;
|
||||||
config.rcc.hsi48 = true; // needed for RNG
|
|
||||||
config.rcc.pll1 = Some(Pll {
|
config.rcc.pll1 = Some(Pll {
|
||||||
source: PllSource::HSI,
|
source: PllSource::HSI,
|
||||||
prediv: PllPreDiv::DIV4,
|
prediv: PllPreDiv::DIV4,
|
||||||
|
@ -15,7 +15,7 @@ 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.hsi48 = true; // needed for RNG.
|
config.rcc.hsi48 = Some(Default::default()); // needed for RNG
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
use embassy_stm32::rcc::*;
|
use embassy_stm32::rcc::*;
|
||||||
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
||||||
config.rcc.csi = true;
|
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 {
|
config.rcc.pll1 = Some(Pll {
|
||||||
source: PllSource::HSI,
|
source: PllSource::HSI,
|
||||||
prediv: PllPreDiv::DIV4,
|
prediv: PllPreDiv::DIV4,
|
||||||
|
@ -11,8 +11,7 @@ use {defmt_rtt as _, panic_probe as _};
|
|||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut config = Config::default();
|
let config = Config::default();
|
||||||
config.rcc.hsi48 = true;
|
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
let button = Input::new(p.PB2, Pull::Up);
|
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]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut config = embassy_stm32::Config::default();
|
let mut config = embassy_stm32::Config::default();
|
||||||
|
config.rcc.hsi = true;
|
||||||
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
|
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
|
||||||
config.rcc.hsi48 = true;
|
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
let mut spi_config = spi::Config::default();
|
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]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut config = embassy_stm32::Config::default();
|
let mut config = embassy_stm32::Config::default();
|
||||||
|
config.rcc.hsi = true;
|
||||||
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
|
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
|
||||||
config.rcc.hsi48 = true;
|
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
let mut spi_config = spi::Config::default();
|
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]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut config = embassy_stm32::Config::default();
|
let mut config = embassy_stm32::Config::default();
|
||||||
|
config.rcc.hsi = true;
|
||||||
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
|
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
|
||||||
config.rcc.hsi48 = true;
|
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
let mut spi_config = spi::Config::default();
|
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]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut config = embassy_stm32::Config::default();
|
let mut config = embassy_stm32::Config::default();
|
||||||
|
config.rcc.hsi = true;
|
||||||
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
|
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
|
||||||
config.rcc.hsi48 = true;
|
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
let mut spi_config = spi::Config::default();
|
let mut spi_config = spi::Config::default();
|
||||||
|
@ -90,7 +90,7 @@ async fn main(spawner: Spawner) {
|
|||||||
divq: None,
|
divq: None,
|
||||||
divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2)
|
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);
|
let dp = embassy_stm32::init(config);
|
||||||
|
@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let mut config = Config::default();
|
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.mux = ClockSrc::PLL1_R;
|
||||||
config.rcc.hsi = true;
|
config.rcc.hsi = true;
|
||||||
config.rcc.pll = Some(Pll {
|
config.rcc.pll = Some(Pll {
|
||||||
|
@ -29,8 +29,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
n: Plln::MUL10,
|
n: Plln::MUL10,
|
||||||
r: Plldiv::DIV1,
|
r: Plldiv::DIV1,
|
||||||
});
|
});
|
||||||
//config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz);
|
config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
|
||||||
config.rcc.hsi48 = true;
|
|
||||||
|
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ pub fn config() -> Config {
|
|||||||
{
|
{
|
||||||
use embassy_stm32::rcc::*;
|
use embassy_stm32::rcc::*;
|
||||||
config.rcc.hsi = None;
|
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 {
|
config.rcc.hse = Some(Hse {
|
||||||
freq: Hertz(8_000_000),
|
freq: Hertz(8_000_000),
|
||||||
mode: HseMode::BypassDigital,
|
mode: HseMode::BypassDigital,
|
||||||
@ -332,7 +332,7 @@ pub fn config() -> Config {
|
|||||||
use embassy_stm32::rcc::*;
|
use embassy_stm32::rcc::*;
|
||||||
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
||||||
config.rcc.csi = true;
|
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 {
|
config.rcc.pll1 = Some(Pll {
|
||||||
source: PllSource::HSI,
|
source: PllSource::HSI,
|
||||||
prediv: PllPreDiv::DIV4,
|
prediv: PllPreDiv::DIV4,
|
||||||
@ -364,7 +364,7 @@ pub fn config() -> Config {
|
|||||||
use embassy_stm32::rcc::*;
|
use embassy_stm32::rcc::*;
|
||||||
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
||||||
config.rcc.csi = true;
|
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 {
|
config.rcc.pll1 = Some(Pll {
|
||||||
source: PllSource::HSI,
|
source: PllSource::HSI,
|
||||||
prediv: PllPreDiv::DIV4,
|
prediv: PllPreDiv::DIV4,
|
||||||
|
Loading…
Reference in New Issue
Block a user