|
1 | 1 | use crate::pac::RCC;
|
2 | 2 | use crate::time::{Hertz, U32Ext};
|
3 | 3 |
|
| 4 | +#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))] |
| 5 | +use crate::{ |
| 6 | + pac::CRS, |
| 7 | + syscfg::SYSCFG, |
| 8 | +}; |
| 9 | + |
| 10 | + |
4 | 11 | /// System clock mux source
|
5 | 12 | #[derive(Clone, Copy)]
|
6 | 13 | pub enum ClockSrc {
|
@@ -170,6 +177,45 @@ pub struct Rcc {
|
170 | 177 | pub(crate) rb: RCC,
|
171 | 178 | }
|
172 | 179 |
|
| 180 | +#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))] |
| 181 | +impl Rcc { |
| 182 | + pub fn enable_hsi48(&mut self, syscfg: &mut SYSCFG, crs: CRS) -> HSI48 { |
| 183 | + // Reset CRS peripheral |
| 184 | + self.rb.apb1rstr.modify(|_, w| w.crsrst().set_bit()); |
| 185 | + self.rb.apb1rstr.modify(|_, w| w.crsrst().clear_bit()); |
| 186 | + |
| 187 | + // Enable CRS peripheral |
| 188 | + self.rb.apb1enr.modify(|_, w| w.crsen().set_bit()); |
| 189 | + |
| 190 | + // Initialize CRS |
| 191 | + crs.cfgr.write(|w| |
| 192 | + // Select LSE as synchronization source |
| 193 | + unsafe { w.syncsrc().bits(0b01) } |
| 194 | + ); |
| 195 | + crs.cr.write(|w| |
| 196 | + w |
| 197 | + .autotrimen().set_bit() |
| 198 | + .cen().set_bit() |
| 199 | + ); |
| 200 | + |
| 201 | + // Enable VREFINT reference for HSI48 oscillator |
| 202 | + syscfg.syscfg.cfgr3.modify(|_, w| |
| 203 | + w |
| 204 | + .enref_rc48mhz().set_bit() |
| 205 | + .en_bgap().set_bit() |
| 206 | + ); |
| 207 | + |
| 208 | + // Select HSI48 as USB clock |
| 209 | + self.rb.ccipr.modify(|_, w| w.hsi48msel().set_bit()); |
| 210 | + |
| 211 | + // Enable dedicated USB clock |
| 212 | + self.rb.crrcr.modify(|_, w| w.hsi48on().set_bit()); |
| 213 | + while self.rb.crrcr.read().hsi48rdy().bit_is_clear() {}; |
| 214 | + |
| 215 | + HSI48(()) |
| 216 | + } |
| 217 | +} |
| 218 | + |
173 | 219 | /// Extension trait that freezes the `RCC` peripheral with provided clocks configuration
|
174 | 220 | pub trait RccExt {
|
175 | 221 | fn freeze(self, config: Config) -> Rcc;
|
@@ -310,6 +356,7 @@ impl RccExt for RCC {
|
310 | 356 |
|
311 | 357 | Rcc { rb: self, clocks }
|
312 | 358 | }
|
| 359 | + |
313 | 360 | }
|
314 | 361 |
|
315 | 362 | /// Frozen clock frequencies
|
@@ -362,3 +409,10 @@ impl Clocks {
|
362 | 409 | self.apb2_tim_clk
|
363 | 410 | }
|
364 | 411 | }
|
| 412 | + |
| 413 | + |
| 414 | +/// Token that exists only, if the HSI48 clock has been enabled |
| 415 | +/// |
| 416 | +/// You can get an instance of this struct by calling [`Rcc::enable_hsi48`]. |
| 417 | +#[derive(Clone, Copy)] |
| 418 | +pub struct HSI48(()); |
0 commit comments