Merge #714
714: add more clock options for l4 and l5 r=Dirbaio a=ant32 - added an assert so it panics if pll48div is not 48Mhz - added MSI as a clock source for PLL - removed hsi48 option for MCUs mentioned in l4 rcc presentation - copied some code from l4 to l5, but don't have a way of testing it. Co-authored-by: Philip A Reimer <antreimer@gmail.com>
This commit is contained in:
commit
6d0e6d563d
3 changed files with 51 additions and 5 deletions
|
@ -96,6 +96,7 @@ pub enum APBPrescaler {
|
|||
pub enum PLLSource {
|
||||
HSI16,
|
||||
HSE(Hertz),
|
||||
MSI(MSIRange),
|
||||
}
|
||||
|
||||
seq_macro::seq!(N in 8..=86 {
|
||||
|
@ -192,6 +193,7 @@ impl From<PLLSource> for Pllsrc {
|
|||
match val {
|
||||
PLLSource::HSI16 => Pllsrc::HSI16,
|
||||
PLLSource::HSE(_) => Pllsrc::HSE,
|
||||
PLLSource::MSI(_) => Pllsrc::MSI,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -275,6 +277,7 @@ pub struct Config {
|
|||
Option<PLLSAI1QDiv>,
|
||||
Option<PLLSAI1PDiv>,
|
||||
)>,
|
||||
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
|
||||
pub hsi48: bool,
|
||||
}
|
||||
|
||||
|
@ -287,6 +290,7 @@ impl Default for Config {
|
|||
apb1_pre: APBPrescaler::NotDivided,
|
||||
apb2_pre: APBPrescaler::NotDivided,
|
||||
pllsai1: None,
|
||||
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
|
||||
hsi48: false,
|
||||
}
|
||||
}
|
||||
|
@ -341,6 +345,18 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
while !RCC.cr().read().hsirdy() {}
|
||||
HSI16_FREQ
|
||||
}
|
||||
PLLSource::MSI(range) => {
|
||||
// Enable MSI
|
||||
RCC.cr().write(|w| {
|
||||
let bits: Msirange = range.into();
|
||||
w.set_msirange(bits);
|
||||
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() {}
|
||||
range.into()
|
||||
}
|
||||
};
|
||||
|
||||
// Disable PLL
|
||||
|
@ -366,7 +382,9 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
});
|
||||
|
||||
// Enable as clock source for USB, RNG if PLL48 divisor is provided
|
||||
if pll48div.is_some() {
|
||||
if let Some(pll48div) = pll48div {
|
||||
let freq = (src_freq / prediv.to_div() * mul.to_mul()) / pll48div.to_div();
|
||||
assert!(freq == 48_000_000);
|
||||
RCC.ccipr().modify(|w| {
|
||||
w.set_clk48sel(0b10);
|
||||
});
|
||||
|
@ -408,6 +426,7 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
}
|
||||
};
|
||||
|
||||
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
|
||||
if config.hsi48 {
|
||||
RCC.crrcr().modify(|w| w.set_hsi48on(true));
|
||||
while !RCC.crrcr().read().hsi48rdy() {}
|
||||
|
|
|
@ -96,6 +96,7 @@ pub enum APBPrescaler {
|
|||
pub enum PLLSource {
|
||||
HSI16,
|
||||
HSE(Hertz),
|
||||
MSI(MSIRange),
|
||||
}
|
||||
|
||||
seq_macro::seq!(N in 8..=86 {
|
||||
|
@ -192,6 +193,7 @@ impl From<PLLSource> for Pllsrc {
|
|||
match val {
|
||||
PLLSource::HSI16 => Pllsrc::HSI16,
|
||||
PLLSource::HSE(_) => Pllsrc::HSE,
|
||||
PLLSource::MSI(_) => Pllsrc::MSI,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -275,6 +277,7 @@ pub struct Config {
|
|||
Option<PLLSAI1QDiv>,
|
||||
Option<PLLSAI1PDiv>,
|
||||
)>,
|
||||
pub hsi48: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -286,6 +289,7 @@ impl Default for Config {
|
|||
apb1_pre: APBPrescaler::NotDivided,
|
||||
apb2_pre: APBPrescaler::NotDivided,
|
||||
pllsai1: None,
|
||||
hsi48: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -339,6 +343,18 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
while !RCC.cr().read().hsirdy() {}
|
||||
HSI16_FREQ
|
||||
}
|
||||
PLLSource::MSI(range) => {
|
||||
// Enable MSI
|
||||
RCC.cr().write(|w| {
|
||||
let bits: Msirange = range.into();
|
||||
w.set_msirange(bits);
|
||||
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() {}
|
||||
range.into()
|
||||
}
|
||||
};
|
||||
|
||||
// Disable PLL
|
||||
|
@ -364,7 +380,9 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
});
|
||||
|
||||
// Enable as clock source for USB, RNG if PLL48 divisor is provided
|
||||
if pll48div.is_some() {
|
||||
if let Some(pll48div) = pll48div {
|
||||
let freq = (src_freq / prediv.to_div() * mul.to_mul()) / pll48div.to_div();
|
||||
assert!(freq == 48_000_000);
|
||||
RCC.ccipr1().modify(|w| {
|
||||
w.set_clk48msel(0b10);
|
||||
});
|
||||
|
@ -406,6 +424,14 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
}
|
||||
};
|
||||
|
||||
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_clk48msel(0));
|
||||
}
|
||||
|
||||
// Set flash wait states
|
||||
// VCORE Range 0 (performance), others TODO
|
||||
FLASH.acr().modify(|w| {
|
||||
|
|
|
@ -12,12 +12,13 @@ use panic_probe as _;
|
|||
|
||||
fn config() -> Config {
|
||||
let mut config = Config::default();
|
||||
// 72Mhz clock (16 / 1 * 18 / 4)
|
||||
config.rcc.mux = ClockSrc::PLL(
|
||||
PLLSource::HSI16,
|
||||
PLLClkDiv::Div2,
|
||||
PLLClkDiv::Div4,
|
||||
PLLSrcDiv::Div1,
|
||||
PLLMul::Mul8,
|
||||
Some(PLLClkDiv::Div2),
|
||||
PLLMul::Mul18,
|
||||
Some(PLLClkDiv::Div6), // 48Mhz (16 / 1 * 18 / 6)
|
||||
);
|
||||
config
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue