1#[cfg_attr(usb, path = "usb.rs")]
4#[cfg_attr(otg, path = "otg.rs")]
5mod _version;
6pub use _version::*;
7
8use crate::interrupt::typelevel::Interrupt;
9use crate::rcc;
10
11fn common_init<T: Instance>() {
13 let freq = T::frequency();
16
17 #[cfg(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs)))]
19 if ![16_000_000, 19_200_000, 20_000_000, 24_000_000, 26_000_000, 32_000_000].contains(&freq.0) {
20 panic!(
21 "USB clock should be one of 16, 19.2, 20, 24, 26, 32Mhz but is {} Hz. Please double-check your RCC settings.",
22 freq.0
23 )
24 }
25 #[cfg(not(any(stm32h7rs, all(stm32u5, peri_usb_otg_hs))))]
29 if freq.0.abs_diff(48_000_000) > 120_000 {
30 panic!(
31 "USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.",
32 freq.0
33 )
34 }
35
36 #[cfg(any(stm32l4, stm32l5, stm32wb, stm32u0))]
37 critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true)));
38
39 #[cfg(pwr_h5)]
40 critical_section::with(|_| crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true)));
41
42 #[cfg(stm32h7)]
43 {
44 let internal_regulator = false;
48
49 critical_section::with(|_| {
51 crate::pac::PWR.cr3().modify(|w| {
52 w.set_usb33den(true);
53 w.set_usbregen(internal_regulator);
54 })
55 });
56
57 while !crate::pac::PWR.cr3().read().usb33rdy() {}
59 }
60
61 #[cfg(stm32h7rs)]
62 {
63 let internal_regulator = false;
67
68 critical_section::with(|_| {
70 crate::pac::PWR.csr2().modify(|w| {
71 w.set_usbregen(internal_regulator);
72 w.set_usb33den(true);
73 w.set_usbhsregen(true);
74 })
75 });
76
77 while !crate::pac::PWR.csr2().read().usb33rdy() {}
79 }
80
81 #[cfg(stm32u5)]
82 {
83 critical_section::with(|_| {
85 crate::pac::PWR.svmcr().modify(|w| {
86 w.set_usv(true);
87 w.set_uvmen(true);
88 })
89 });
90
91 while !crate::pac::PWR.svmsr().read().vddusbrdy() {}
93
94 #[cfg(peri_usb_otg_hs)]
96 {
97 crate::pac::PWR.vosr().modify(|w| {
98 w.set_usbpwren(true);
99 w.set_usbboosten(true);
100 });
101 while !crate::pac::PWR.vosr().read().usbboostrdy() {}
102 }
103 }
104
105 T::Interrupt::unpend();
106 unsafe { T::Interrupt::enable() };
107
108 rcc::enable_and_reset::<T>();
109}