1 | #![allow (unused)] |
2 | |
3 | use crate::pac::crs::vals::Syncsrc; |
4 | use crate::pac::{CRS, RCC}; |
5 | use crate::rcc::{self, SealedRccPeripheral}; |
6 | use crate::time::Hertz; |
7 | |
8 | /// HSI48 speed |
9 | pub const HSI48_FREQ: Hertz = Hertz(48_000_000); |
10 | |
11 | /// Configuration for the HSI48 clock |
12 | #[derive (Clone, Copy, Debug)] |
13 | pub struct Hsi48Config { |
14 | /// Enable CRS Sync from USB Start Of Frame (SOF) events. |
15 | /// Required if HSI48 is going to be used as USB clock. |
16 | /// |
17 | /// Other use cases of CRS are not supported yet. |
18 | pub sync_from_usb: bool, |
19 | } |
20 | |
21 | impl Default for Hsi48Config { |
22 | fn default() -> Self { |
23 | Self { sync_from_usb: false } |
24 | } |
25 | } |
26 | |
27 | pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz { |
28 | // Enable VREFINT reference for HSI48 oscillator |
29 | #[cfg (stm32l0)] |
30 | crate::pac::SYSCFG.cfgr3().modify(|w| { |
31 | w.set_enref_hsi48(true); |
32 | w.set_en_vrefint(true); |
33 | }); |
34 | |
35 | // Enable HSI48 |
36 | #[cfg (not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32h7rs, stm32u5, stm32wba, stm32f0)))] |
37 | let r = RCC.crrcr(); |
38 | #[cfg (any(stm32u5, stm32g0, stm32h5, stm32h7, stm32h7rs, stm32u5, stm32wba))] |
39 | let r = RCC.cr(); |
40 | #[cfg (any(stm32f0))] |
41 | let r = RCC.cr2(); |
42 | |
43 | r.modify(|w| w.set_hsi48on(true)); |
44 | while r.read().hsi48rdy() == false {} |
45 | |
46 | if config.sync_from_usb { |
47 | rcc::enable_and_reset::<crate::peripherals::CRS>(); |
48 | |
49 | CRS.cfgr().modify(|w| { |
50 | w.set_syncsrc(Syncsrc::USB); |
51 | }); |
52 | |
53 | // These are the correct settings for standard USB operation. If other settings |
54 | // are needed there will need to be additional config options for the CRS. |
55 | crate::pac::CRS.cr().modify(|w| { |
56 | w.set_autotrimen(true); |
57 | w.set_cen(true); |
58 | }); |
59 | } |
60 | |
61 | HSI48_FREQ |
62 | } |
63 | |