diff options
| -rw-r--r-- | embassy-stm32/src/clock.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l0/mod.rs | 109 |
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 | ||
| 11 | use crate::interrupt::{CriticalSection, Interrupt, Mutex}; | 11 | use crate::interrupt::{CriticalSection, Interrupt, Mutex}; |
| 12 | use crate::pac::timer::TimGp16; | 12 | use crate::pac::timer::TimGp16; |
| 13 | use crate::rcc::get_freqs; | ||
| 14 | use crate::time::Hertz; | 13 | use 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 @@ | |||
| 1 | use crate::pac; | 1 | use crate::pac; |
| 2 | use crate::peripherals::{self, RCC}; | 2 | use crate::peripherals::{self, CRS, RCC, SYSCFG}; |
| 3 | use crate::rcc::{set_freqs, Clocks}; | 3 | use crate::rcc::{get_freqs, set_freqs, Clocks}; |
| 4 | use crate::time::Hertz; | 4 | use crate::time::Hertz; |
| 5 | use crate::time::U32Ext; | 5 | use crate::time::U32Ext; |
| 6 | use core::marker::PhantomData; | ||
| 6 | use embassy::util::Unborrow; | 7 | use embassy::util::Unborrow; |
| 8 | use embassy_extras::unborrow; | ||
| 7 | use pac::rcc::vals; | 9 | use pac::rcc::vals; |
| 8 | use vals::{Hpre, Msirange, Plldiv, Pllmul, Pllon, Pllsrc, Ppre, Sw}; | 10 | use 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 |
| 230 | pub struct Rcc {} | 232 | pub struct Rcc<'d> { |
| 233 | _rb: peripherals::RCC, | ||
| 234 | phantom: PhantomData<&'d mut peripherals::RCC>, | ||
| 235 | } | ||
| 231 | 236 | ||
| 232 | impl Rcc { | 237 | impl<'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 | } | ||
| 248 | impl 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 | ||
| 281 | impl Rcc { | 312 | impl Rcc { |
| 282 | /// Configure MCO (Microcontroller Clock Output). | 313 | /// Configure MCO (Microcontroller Clock Output). |
