Skip to content

Commit e2f4163

Browse files
lthieryhannobraun
authored andcommitted
Refactor USB to allow reuse of enable 48 MHz
1 parent 7acca3e commit e2f4163

File tree

2 files changed

+58
-37
lines changed

2 files changed

+58
-37
lines changed

src/rcc.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
use crate::pac::RCC;
22
use crate::time::{Hertz, U32Ext};
33

4+
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
5+
use crate::{
6+
pac::CRS,
7+
syscfg::SYSCFG,
8+
};
9+
10+
411
/// System clock mux source
512
#[derive(Clone, Copy)]
613
pub enum ClockSrc {
@@ -170,6 +177,45 @@ pub struct Rcc {
170177
pub(crate) rb: RCC,
171178
}
172179

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+
173219
/// Extension trait that freezes the `RCC` peripheral with provided clocks configuration
174220
pub trait RccExt {
175221
fn freeze(self, config: Config) -> Rcc;
@@ -310,6 +356,7 @@ impl RccExt for RCC {
310356

311357
Rcc { rb: self, clocks }
312358
}
359+
313360
}
314361

315362
/// Frozen clock frequencies
@@ -362,3 +409,10 @@ impl Clocks {
362409
self.apb2_tim_clk
363410
}
364411
}
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(());

src/usb.rs

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818
//! fits together.
1919
2020

21-
use crate::{
22-
pac,
23-
rcc::Rcc,
24-
syscfg::SYSCFG,
21+
use crate::rcc::{
22+
HSI48,
23+
Rcc,
2524
};
2625

2726

@@ -30,39 +29,7 @@ use crate::{
3029
/// This method takes care of the platform-specific bits of the USB
3130
/// initialization. After calling this method, you need `stm32-usbd` to actually
3231
/// do anything useful with the USB peripheral.
33-
pub fn init(rcc: &mut Rcc, syscfg: &mut SYSCFG, crs: pac::CRS) {
34-
// Reset CRS peripheral
35-
rcc.rb.apb1rstr.modify(|_, w| w.crsrst().set_bit());
36-
rcc.rb.apb1rstr.modify(|_, w| w.crsrst().clear_bit());
37-
38-
// Enable CRS peripheral
39-
rcc.rb.apb1enr.modify(|_, w| w.crsen().set_bit());
40-
41-
// Initialize CRS
42-
crs.cfgr.write(|w|
43-
// Select LSE as synchronization source
44-
unsafe { w.syncsrc().bits(0b01) }
45-
);
46-
crs.cr.write(|w|
47-
w
48-
.autotrimen().set_bit()
49-
.cen().set_bit()
50-
);
51-
52-
// Enable VREFINT reference for HSI48 oscillator
53-
syscfg.syscfg.cfgr3.modify(|_, w|
54-
w
55-
.enref_rc48mhz().set_bit()
56-
.en_bgap().set_bit()
57-
);
58-
59-
// Select HSI48 as USB clock
60-
rcc.rb.ccipr.modify(|_, w| w.hsi48msel().set_bit());
61-
62-
// Enable dedicated USB clock
63-
rcc.rb.crrcr.modify(|_, w| w.hsi48on().set_bit());
64-
while rcc.rb.crrcr.read().hsi48rdy().bit_is_clear() {};
65-
32+
pub fn init(rcc: &mut Rcc, _: HSI48) {
6633
// Reset USB peripheral
6734
rcc.rb.apb1rstr.modify(|_, w| w.usbrst().set_bit());
6835
rcc.rb.apb1rstr.modify(|_, w| w.usbrst().clear_bit());

0 commit comments

Comments
 (0)