aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/clock.rs1
-rw-r--r--embassy-stm32/src/rcc/l0/mod.rs109
2 files changed, 70 insertions, 40 deletions
diff --git a/embassy-stm32/src/clock.rs b/embassy-stm32/src/clock.rs
index f79cab4ab..aa83c5b45 100644
--- a/embassy-stm32/src/clock.rs
+++ b/embassy-stm32/src/clock.rs
@@ -10,7 +10,6 @@ use embassy::time::{Clock as EmbassyClock, TICKS_PER_SECOND};
10 10
11use crate::interrupt::{CriticalSection, Interrupt, Mutex}; 11use crate::interrupt::{CriticalSection, Interrupt, Mutex};
12use crate::pac::timer::TimGp16; 12use crate::pac::timer::TimGp16;
13use crate::rcc::get_freqs;
14use crate::time::Hertz; 13use crate::time::Hertz;
15 14
16// Clock timekeeping works with something we call "periods", which are time intervals 15// Clock timekeeping works with something we call "periods", which are time intervals
diff --git a/embassy-stm32/src/rcc/l0/mod.rs b/embassy-stm32/src/rcc/l0/mod.rs
index f911f7fbd..fdfb1b921 100644
--- a/embassy-stm32/src/rcc/l0/mod.rs
+++ b/embassy-stm32/src/rcc/l0/mod.rs
@@ -1,11 +1,13 @@
1use crate::pac; 1use crate::pac;
2use crate::peripherals::{self, RCC}; 2use crate::peripherals::{self, CRS, RCC, SYSCFG};
3use crate::rcc::{set_freqs, Clocks}; 3use crate::rcc::{get_freqs, set_freqs, Clocks};
4use crate::time::Hertz; 4use crate::time::Hertz;
5use crate::time::U32Ext; 5use crate::time::U32Ext;
6use core::marker::PhantomData;
6use embassy::util::Unborrow; 7use embassy::util::Unborrow;
8use embassy_extras::unborrow;
7use pac::rcc::vals; 9use pac::rcc::vals;
8use vals::{Hpre, Msirange, Plldiv, Pllmul, Pllon, Pllsrc, Ppre, Sw}; 10use vals::{Dbgen, Hpre, Lptimen, Msirange, Plldiv, Pllmul, Pllon, Pllsrc, Ppre, Sw};
9 11
10/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, 12/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC,
11/// and with the addition of the init function to configure a system clock. 13/// and with the addition of the init function to configure a system clock.
@@ -227,56 +229,85 @@ impl Config {
227} 229}
228 230
229/// RCC peripheral 231/// RCC peripheral
230pub struct Rcc {} 232pub struct Rcc<'d> {
233 _rb: peripherals::RCC,
234 phantom: PhantomData<&'d mut peripherals::RCC>,
235}
231 236
232impl Rcc { 237impl<'d> Rcc<'d> {
233 pub fn new(_rcc: impl Unborrow<Target = peripherals::RCC> + 'static) -> Self { 238 pub fn new(rcc: impl Unborrow<Target = peripherals::RCC> + 'd) -> Self {
234 Self {} 239 unborrow!(rcc);
240 Self {
241 _rb: rcc,
242 phantom: PhantomData,
243 }
235 } 244 }
236}
237 245
238/* 246 // Safety: RCC init must have been called
239 pub fn enable_lse(&mut self, _: &PWR) -> LSE { 247 pub fn clocks(&self) -> &'static Clocks {
240 self.rb.csr.modify(|_, w| { 248 unsafe { get_freqs() }
241 // Enable LSE clock
242 w.lseon().set_bit()
243 });
244 while self.rb.csr.read().lserdy().bit_is_clear() {}
245 LSE(())
246 } 249 }
247}
248impl Rcc {
249 pub fn enable_hsi48(&mut self, syscfg: &mut SYSCFG, crs: CRS) -> HSI48 {
250 // Reset CRS peripheral
251 self.rb.apb1rstr.modify(|_, w| w.crsrst().set_bit());
252 self.rb.apb1rstr.modify(|_, w| w.crsrst().clear_bit());
253 250
254 // Enable CRS peripheral 251 /*
255 self.rb.apb1enr.modify(|_, w| w.crsen().set_bit()); 252 pub fn enable_lse(&mut self, _: &PWR) -> LSE {
253 self.rb.csr.modify(|_, w| {
254 // Enable LSE clock
255 w.lseon().set_bit()
256 });
257 while self.rb.csr.read().lserdy().bit_is_clear() {}
258 LSE(())
259 }
260 }
261
262 impl Rcc {
263 */
264 pub fn enable_hsi48(&mut self, _syscfg: &mut SYSCFG, _crs: CRS) -> HSI48 {
265 let rcc = pac::RCC;
266 unsafe {
267 // Reset SYSCFG peripheral
268 rcc.apb2rstr().modify(|w| w.set_syscfgrst(true));
269 rcc.apb2rstr().modify(|w| w.set_syscfgrst(false));
270
271 // Enable SYSCFG peripheral
272 rcc.apb2enr().modify(|w| w.set_syscfgen(Dbgen::ENABLED));
273
274 // Reset CRS peripheral
275 rcc.apb1rstr().modify(|w| w.set_crsrst(true));
276 rcc.apb1rstr().modify(|w| w.set_crsrst(false));
277
278 // Enable CRS peripheral
279 rcc.apb1enr().modify(|w| w.set_crsen(Lptimen::ENABLED));
280
281 // Initialize CRS
282 let crs = pac::CRS;
283 crs.cfgr().write(|w|
256 284
257 // Initialize CRS
258 crs.cfgr.write(|w|
259 // Select LSE as synchronization source 285 // Select LSE as synchronization source
260 unsafe { w.syncsrc().bits(0b01) }); 286 w.set_syncsrc(0b01));
261 crs.cr 287 crs.cr().modify(|w| {
262 .modify(|_, w| w.autotrimen().set_bit().cen().set_bit()); 288 w.set_autotrimen(true);
289 w.set_cen(true);
290 });
263 291
264 // Enable VREFINT reference for HSI48 oscillator 292 // Enable VREFINT reference for HSI48 oscillator
265 syscfg 293 let syscfg = pac::SYSCFG;
266 .syscfg 294 syscfg.cfgr3().modify(|w| {
267 .cfgr3 295 w.set_enref_hsi48(true);
268 .modify(|_, w| w.enref_hsi48().set_bit().en_vrefint().set_bit()); 296 w.set_en_vrefint(true);
297 });
269 298
270 // Select HSI48 as USB clock 299 // Select HSI48 as USB clock
271 self.rb.ccipr.modify(|_, w| w.hsi48msel().set_bit()); 300 rcc.ccipr().modify(|w| w.set_hsi48msel(true));
272 301
273 // Enable dedicated USB clock 302 // Enable dedicated USB clock
274 self.rb.crrcr.modify(|_, w| w.hsi48on().set_bit()); 303 rcc.crrcr().modify(|w| w.set_hsi48on(true));
275 while self.rb.crrcr.read().hsi48rdy().bit_is_clear() {} 304 while !rcc.crrcr().read().hsi48rdy() {}
305 }
276 306
277 HSI48(()) 307 HSI48(())
278 } 308 }
279} 309}
310/*
280 311
281impl Rcc { 312impl Rcc {
282 /// Configure MCO (Microcontroller Clock Output). 313 /// Configure MCO (Microcontroller Clock Output).