Skip to content

Commit 6aad4bc

Browse files
committed
rcc: Add basic structure of RCC module
1 parent 2b401a5 commit 6aad4bc

File tree

3 files changed

+186
-3
lines changed

3 files changed

+186
-3
lines changed

src/rcc.rs

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,188 @@
1+
//! Reset and Clock Control
2+
//!
3+
4+
use crate::stm32::RCC;
5+
use crate::time::Hertz;
6+
7+
#[cfg(feature = "log")]
8+
use log::debug;
9+
110
mod core_clocks;
211
mod reset_reason;
12+
13+
pub use core_clocks::CoreClocks;
14+
pub use reset_reason::ResetReason;
15+
16+
/// Configuration of the core clocks
17+
pub struct Config {
18+
hse: Option<u32>,
19+
bypass_hse: bool,
20+
lse: Option<u32>,
21+
sys_ck: Option<u32>,
22+
per_ck: Option<u32>,
23+
audio_ck: Option<u32>,
24+
rcc_hclk: Option<u32>,
25+
rcc_pclk1: Option<u32>,
26+
rcc_pclk2: Option<u32>,
27+
rcc_pclk3: Option<u32>,
28+
#[cfg(feature = "rm0481")]
29+
rcc_pclk4: Option<u32>,
30+
}
31+
32+
/// Extension trait that constrains the `RCC` peripheral
33+
pub trait RccExt {
34+
/// Constrains the `RCC` peripheral so it plays nicely with the
35+
/// other abstractions
36+
fn constrain(self) -> Rcc;
37+
}
38+
39+
impl RccExt for RCC {
40+
fn constrain(self) -> Rcc {
41+
Rcc {
42+
config: Config {
43+
hse: None,
44+
bypass_hse: false,
45+
lse: None,
46+
sys_ck: None,
47+
per_ck: None,
48+
audio_ck: None,
49+
rcc_hclk: None,
50+
rcc_pclk1: None,
51+
rcc_pclk2: None,
52+
rcc_pclk3: None,
53+
#[cfg(feature = "rm0481")]
54+
rcc_pclk4: None,
55+
},
56+
rb: self,
57+
}
58+
}
59+
}
60+
61+
/// Constrained RCC peripheral
62+
///
63+
/// Generated by calling `constrain` on the PAC's RCC peripheral.
64+
///
65+
/// ```rust
66+
/// let dp = stm32::Peripherals::take().unwrap();
67+
/// let rcc = dp.RCC.constrain();
68+
/// ```
69+
pub struct Rcc {
70+
config: Config,
71+
pub(crate) rb: RCC,
72+
}
73+
74+
impl Rcc {
75+
/// Gets and clears the reason of why the mcu was reset
76+
pub fn get_reset_reason(&mut self) -> ResetReason {
77+
reset_reason::get_reset_reason(&mut self.rb)
78+
}
79+
}
80+
81+
/// Core Clock Distribution and Reset (CCDR)
82+
///
83+
/// Generated when the RCC is frozen. The configuration of the Sys_Ck `sys_ck`,
84+
/// AHB clocks `hclk`, APB clocks `pclkN` and PLL outputs `pllN_X_ck` are
85+
/// frozen. However the distribution of some clocks may still be modified and
86+
/// peripherals enabled / reset by passing this object to other implementations
87+
/// in this stack.
88+
pub struct Ccdr {
89+
/// A record of the frozen core clock frequencies
90+
pub clocks: CoreClocks,
91+
}
92+
93+
const MAX_SYSCLK_FREQ_HZ: u32 = 250_000_000;
94+
95+
/// Setter defintion for pclk 1 - 4
96+
macro_rules! pclk_setter {
97+
($($name:ident: $pclk:ident,)+) => {
98+
$(
99+
/// Set the peripheral clock frequency for APB
100+
/// peripherals.
101+
#[must_use]
102+
pub fn $name(mut self, freq: Hertz) -> Self {
103+
assert!(freq.raw() <= MAX_SYSCLK_FREQ_HZ,
104+
"Max frequency is {MAX_SYSCLK_FREQ_HZ}Hz");
105+
self.config.$pclk = Some(freq.raw());
106+
self
107+
}
108+
)+
109+
};
110+
}
111+
112+
impl Rcc {
113+
/// Uses HSE (external oscillator) instead of HSI (internal RC
114+
/// oscillator) as the clock source. Will result in a hang if an
115+
/// external oscillator is not connected or it fails to start.
116+
#[must_use]
117+
pub fn use_hse(mut self, freq: Hertz) -> Self {
118+
self.config.hse = Some(freq.raw());
119+
self
120+
}
121+
122+
/// Use an external clock signal rather than a crystal oscillator,
123+
/// bypassing the XTAL driver.
124+
#[must_use]
125+
pub fn bypass_hse(mut self) -> Self {
126+
self.config.bypass_hse = true;
127+
self
128+
}
129+
130+
/// Set SYSCLK frequency
131+
#[must_use]
132+
pub fn sys_ck(mut self, freq: Hertz) -> Self {
133+
assert!(
134+
freq.raw() <= MAX_SYSCLK_FREQ_HZ,
135+
"Max frequency is {MAX_SYSCLK_FREQ_HZ}Hz"
136+
);
137+
self.config.sys_ck = Some(freq.raw());
138+
self
139+
}
140+
141+
/// Set SYSCLK frequency - ALIAS
142+
#[must_use]
143+
pub fn sysclk(self, freq: Hertz) -> Self {
144+
self.sys_ck(freq)
145+
}
146+
147+
/// Set peripheral clock frequency
148+
#[must_use]
149+
pub fn per_ck(mut self, freq: Hertz) -> Self {
150+
self.config.per_ck = Some(freq.raw());
151+
self
152+
}
153+
154+
/// Set low speed external clock frequency
155+
pub fn lse_ck(mut self, freq: Hertz) -> Self {
156+
self.config.lse = Some(freq.raw());
157+
self
158+
}
159+
160+
/// Set external AUDIOCLK frequency
161+
#[must_use]
162+
pub fn audio_ck(mut self, freq: Hertz) -> Self {
163+
self.config.audio_ck = Some(freq.raw());
164+
self
165+
}
166+
167+
/// Set the peripheral clock frequency for AHB peripherals.
168+
#[must_use]
169+
pub fn hclk(mut self, freq: Hertz) -> Self {
170+
assert!(
171+
freq.raw() <= MAX_SYSCLK_FREQ_HZ,
172+
"Max frequency is {MAX_SYSCLK_FREQ_HZ}Hz"
173+
);
174+
self.config.rcc_hclk = Some(freq.raw());
175+
self
176+
}
177+
178+
pclk_setter! {
179+
pclk1: rcc_pclk1,
180+
pclk2: rcc_pclk2,
181+
pclk3: rcc_pclk3,
182+
}
183+
184+
#[cfg(feature = "rm0481")]
185+
pclk_setter! {
186+
pclk4: rcc_pclk4,
187+
}
188+
}

src/rcc/core_clocks.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ macro_rules! pll_getter {
7979
};
8080
}
8181

82-
#[allow(dead_code)]
8382
impl CoreClocks {
8483
/// Returns the frequency of AHB1,2,3 busses
8584
pub fn hclk(&self) -> Hertz {

src/rcc/reset_reason.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use core::fmt::Display;
55

66
/// Gets and clears the reason of why the mcu was reset
77
#[rustfmt::skip]
8-
#[allow(dead_code)]
98
pub fn get_reset_reason(rcc: &mut crate::stm32::RCC) -> ResetReason {
109
let reset_reason = rcc.rsr().read();
1110

@@ -55,7 +54,6 @@ pub fn get_reset_reason(rcc: &mut crate::stm32::RCC) -> ResetReason {
5554

5655
/// Gives the reason why the mcu was reset
5756
#[derive(Debug, Copy, Clone)]
58-
#[allow(dead_code)]
5957
pub enum ResetReason {
6058
/// The mcu went from not having power to having power and resetting
6159
PowerOnReset,

0 commit comments

Comments
 (0)