This commit is contained in:
Ulf Lilleengen 2021-05-26 13:08:14 +02:00
parent c501b162fc
commit ea67940743

View file

@ -1,7 +1,7 @@
use crate::clock::Clock; use crate::clock::Clock;
use crate::interrupt; use crate::interrupt;
use crate::pac; use crate::pac;
use crate::pac::peripherals::{self, TIM2}; use crate::pac::peripherals::{self, RCC, TIM2};
use crate::time::Hertz; use crate::time::Hertz;
use crate::time::U32Ext; use crate::time::U32Ext;
use pac::rcc::vals; use pac::rcc::vals;
@ -195,7 +195,6 @@ impl Config {
/// RCC peripheral /// RCC peripheral
pub struct Rcc { pub struct Rcc {
clocks: Clocks, clocks: Clocks,
rb: pac::rcc::Rcc,
} }
/* /*
@ -267,38 +266,47 @@ impl Rcc {
/// Extension trait that freezes the `RCC` peripheral with provided clocks configuration /// Extension trait that freezes the `RCC` peripheral with provided clocks configuration
pub trait RccExt { pub trait RccExt {
unsafe fn freeze(self, config: Config) -> Rcc; fn freeze(self, config: Config) -> Rcc;
} }
impl RccExt for pac::rcc::Rcc { impl RccExt for RCC {
// `cfgr` is almost always a constant, so make sure it can be constant-propagated properly by // `cfgr` is almost always a constant, so make sure it can be constant-propagated properly by
// marking this function and all `Config` constructors and setters as `#[inline]`. // marking this function and all `Config` constructors and setters as `#[inline]`.
// This saves ~900 Bytes for the `pwr.rs` example. // This saves ~900 Bytes for the `pwr.rs` example.
#[inline] #[inline]
unsafe fn freeze(self, cfgr: Config) -> Rcc { fn freeze(self, cfgr: Config) -> Rcc {
let rcc = pac::RCC;
let (sys_clk, sw) = match cfgr.mux { let (sys_clk, sw) = match cfgr.mux {
ClockSrc::MSI(range) => { ClockSrc::MSI(range) => {
// Set MSI range // Set MSI range
self.icscr().write(|w| w.set_msirange(range.into())); unsafe {
rcc.icscr().write(|w| w.set_msirange(range.into()));
}
// Enable MSI // Enable MSI
self.cr().write(|w| w.set_msion(Pllon::ENABLED)); unsafe {
while !self.cr().read().msirdy() {} rcc.cr().write(|w| w.set_msion(Pllon::ENABLED));
while !rcc.cr().read().msirdy() {}
}
let freq = 32_768 * (1 << (range as u8 + 1)); let freq = 32_768 * (1 << (range as u8 + 1));
(freq, Sw::MSI) (freq, Sw::MSI)
} }
ClockSrc::HSI16 => { ClockSrc::HSI16 => {
// Enable HSI16 // Enable HSI16
self.cr().write(|w| w.set_hsi16on(Pllon::ENABLED)); unsafe {
while !self.cr().read().hsi16rdyf() {} rcc.cr().write(|w| w.set_hsi16on(Pllon::ENABLED));
while !rcc.cr().read().hsi16rdyf() {}
}
(HSI_FREQ, Sw::HSI16) (HSI_FREQ, Sw::HSI16)
} }
ClockSrc::HSE(freq) => { ClockSrc::HSE(freq) => {
// Enable HSE // Enable HSE
self.cr().write(|w| w.set_hseon(Pllon::ENABLED)); unsafe {
while !self.cr().read().hserdy() {} rcc.cr().write(|w| w.set_hseon(Pllon::ENABLED));
while !rcc.cr().read().hserdy() {}
}
(freq.0, Sw::HSE) (freq.0, Sw::HSE)
} }
@ -306,21 +314,27 @@ impl RccExt for pac::rcc::Rcc {
let freq = match src { let freq = match src {
PLLSource::HSE(freq) => { PLLSource::HSE(freq) => {
// Enable HSE // Enable HSE
self.cr().write(|w| w.set_hseon(Pllon::ENABLED)); unsafe {
while !self.cr().read().hserdy() {} rcc.cr().write(|w| w.set_hseon(Pllon::ENABLED));
while !rcc.cr().read().hserdy() {}
}
freq.0 freq.0
} }
PLLSource::HSI16 => { PLLSource::HSI16 => {
// Enable HSI // Enable HSI
self.cr().write(|w| w.set_hsi16on(Pllon::ENABLED)); unsafe {
while !self.cr().read().hsi16rdyf() {} rcc.cr().write(|w| w.set_hsi16on(Pllon::ENABLED));
while !rcc.cr().read().hsi16rdyf() {}
}
HSI_FREQ HSI_FREQ
} }
}; };
// Disable PLL // Disable PLL
self.cr().modify(|w| w.set_pllon(Pllon::DISABLED)); unsafe {
while self.cr().read().pllrdy() {} rcc.cr().modify(|w| w.set_pllon(Pllon::DISABLED));
while rcc.cr().read().pllrdy() {}
}
let freq = match mul { let freq = match mul {
PLLMul::Mul3 => freq * 3, PLLMul::Mul3 => freq * 3,
@ -341,26 +355,30 @@ impl RccExt for pac::rcc::Rcc {
}; };
assert!(freq <= 32_u32.mhz().0); assert!(freq <= 32_u32.mhz().0);
self.cfgr().write(move |w| { unsafe {
w.set_pllmul(mul.into()); rcc.cfgr().write(move |w| {
w.set_plldiv(div.into()); w.set_pllmul(mul.into());
w.set_pllsrc(src.into()); w.set_plldiv(div.into());
}); w.set_pllsrc(src.into());
});
// Enable PLL // Enable PLL
self.cr().modify(|w| w.set_pllon(Pllon::ENABLED)); rcc.cr().modify(|w| w.set_pllon(Pllon::ENABLED));
while !self.cr().read().pllrdy() {} while !rcc.cr().read().pllrdy() {}
}
(freq, Sw::PLL) (freq, Sw::PLL)
} }
}; };
self.cfgr().modify(|w| { unsafe {
w.set_sw(sw.into()); rcc.cfgr().modify(|w| {
w.set_hpre(cfgr.ahb_pre.into()); w.set_sw(sw.into());
w.set_ppre(0, cfgr.apb1_pre.into()); w.set_hpre(cfgr.ahb_pre.into());
w.set_ppre(1, cfgr.apb2_pre.into()); w.set_ppre(0, cfgr.apb1_pre.into());
}); w.set_ppre(1, cfgr.apb2_pre.into());
});
}
let ahb_freq: u32 = match cfgr.ahb_pre { let ahb_freq: u32 = match cfgr.ahb_pre {
AHBPrescaler::NotDivided => sys_clk, AHBPrescaler::NotDivided => sys_clk,
@ -403,7 +421,7 @@ impl RccExt for pac::rcc::Rcc {
apb2_pre, apb2_pre,
}; };
Rcc { rb: self, clocks } Rcc { clocks }
} }
} }
@ -570,7 +588,6 @@ pub type SystemClock = Clock<TIM2>;
pub unsafe fn init(config: Config) -> SystemClock { pub unsafe fn init(config: Config) -> SystemClock {
let rcc = pac::RCC; let rcc = pac::RCC;
let enabled = vals::Iophen::ENABLED; let enabled = vals::Iophen::ENABLED;
rcc.iopenr().write(|w| { rcc.iopenr().write(|w| {
w.set_iopaen(enabled); w.set_iopaen(enabled);
@ -581,7 +598,8 @@ pub unsafe fn init(config: Config) -> SystemClock {
w.set_iophen(enabled); w.set_iophen(enabled);
}); });
let r = rcc.freeze(config); let r = <peripherals::RCC as embassy::util::Steal>::steal();
let r = r.freeze(config);
rcc.apb1enr().modify(|w| w.set_tim2en(Lptimen::ENABLED)); rcc.apb1enr().modify(|w| w.set_tim2en(Lptimen::ENABLED));
rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); rcc.apb1rstr().modify(|w| w.set_tim2rst(true));