Skip to content

Commit 69fdb52

Browse files
committed
Improve RCC enable interface
1 parent cbf5c1b commit 69fdb52

File tree

16 files changed

+207
-219
lines changed

16 files changed

+207
-219
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
name = "stm32f1-hal"
1010
readme = "README.md"
1111
repository = "https://github.com/jw-mcu-rust/stm32f1-hal"
12-
version = "0.0.3"
12+
version = "0.0.4"
1313

1414
[package.metadata.docs.rs]
1515
features = ["stm32f103", "xG"]

src/afio/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ pub mod timer_remap;
44
pub mod uart_remap;
55

66
use crate::gpio::{self, Alternate, Cr, Debugger, Floating, Input, OpenDrain, PushPull};
7-
use crate::pac::{self, AFIO, RCC, afio};
8-
use crate::rcc::{Enable, Reset};
7+
use crate::pac::{self, AFIO, afio};
8+
use crate::rcc::Rcc;
99
use core::marker::PhantomData;
1010

1111
type MaprBits = <afio::mapr::MAPRrs as RegisterSpec>::Ux;
1212

1313
pub trait AfioInit {
14-
fn constrain(self, rcc: &mut RCC) -> Afio;
14+
fn constrain(self, rcc: &mut Rcc) -> Afio;
1515
}
1616

1717
impl AfioInit for AFIO {
18-
fn constrain(self, rcc: &mut RCC) -> Afio {
19-
AFIO::enable(rcc);
20-
AFIO::reset(rcc);
18+
fn constrain(self, rcc: &mut Rcc) -> Afio {
19+
rcc.enable(&self);
20+
rcc.reset(&self);
2121

2222
Afio {
2323
_reg: self,

src/gpio/mod.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@
7575
7676
use core::marker::PhantomData;
7777

78-
use crate::afio;
79-
use crate::pac::{EXTI, RCC};
78+
use crate::{afio, pac::EXTI, rcc::Rcc};
8079

8180
mod partially_erased;
8281
pub use partially_erased::{PEPin, PartiallyErasedPin};
@@ -132,13 +131,13 @@ pub trait GpioExt {
132131
/// Splits the GPIO block into independent pins and registers.
133132
///
134133
/// This resets the state of the GPIO block.
135-
fn split(self, rcc: &mut RCC) -> Self::Parts;
134+
fn split(self, rcc: &mut Rcc) -> Self::Parts;
136135

137136
/// Splits the GPIO block into independent pins and registers without resetting its state.
138137
///
139138
/// # Safety
140139
/// Make sure that all pins modes are set in reset state.
141-
unsafe fn split_without_reset(self, rcc: &mut RCC) -> Self::Parts;
140+
unsafe fn split_without_reset(self, rcc: &mut Rcc) -> Self::Parts;
142141
}
143142

144143
/// Marker trait for active states.
@@ -368,8 +367,8 @@ macro_rules! gpio {
368367
]) => {
369368
/// GPIO
370369
pub mod $gpiox {
371-
use crate::pac::{$GPIOX, RCC};
372-
use crate::rcc::{Enable, Reset};
370+
use crate::pac::$GPIOX;
371+
use crate::rcc::Rcc;
373372
use super::{Active, Floating, GpioExt, Input, PartiallyErasedPin, ErasedPin, Pin, Cr};
374373
#[allow(unused)]
375374
use super::Debugger;
@@ -393,9 +392,9 @@ macro_rules! gpio {
393392
impl GpioExt for $GPIOX {
394393
type Parts = Parts;
395394

396-
fn split(self, rcc: &mut RCC) -> Parts {
397-
$GPIOX::enable(rcc);
398-
$GPIOX::reset(rcc);
395+
fn split(self, rcc: &mut Rcc) -> Parts {
396+
rcc.enable(&self);
397+
rcc.reset(&self);
399398

400399
Parts {
401400
crl: Cr::<$port_id, false>,
@@ -406,8 +405,8 @@ macro_rules! gpio {
406405
}
407406
}
408407

409-
unsafe fn split_without_reset(self, rcc: &mut RCC) -> Parts {
410-
$GPIOX::enable(rcc);
408+
unsafe fn split_without_reset(self, rcc: &mut Rcc) -> Parts {
409+
rcc.enable(&self);
411410

412411
Parts {
413412
crl: Cr::<$port_id, false>,

src/rcc/mod.rs

Lines changed: 137 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,143 @@ pub struct Rcc {
4545
pub(crate) rb: RCC,
4646
}
4747

48+
impl Rcc {
49+
/// Applies the clock configuration and returns a `Clocks` struct that signifies that the
50+
/// clocks are frozen, and contains the frequencies used. After this function is called,
51+
/// the clocks can not change
52+
///
53+
/// Usage:
54+
///
55+
/// ```rust
56+
/// let dp = pac::Peripherals::take().unwrap();
57+
/// let mut flash = dp.FLASH.constrain();
58+
/// let cfg = rcc::Config::hse(8.MHz()).sysclk(72.MHz());
59+
/// let mut rcc = dp.RCC.constrain().freeze(cfg, &mut flash.acr);
60+
/// ```
61+
#[allow(unused_variables)]
62+
#[inline(always)]
63+
pub fn freeze(self, cfg: impl Into<RawConfig>, acr: &mut ACR) -> Self {
64+
let cfg = cfg.into();
65+
let clocks = cfg.get_clocks();
66+
// adjust flash wait states
67+
#[cfg(any(feature = "stm32f103", feature = "connectivity"))]
68+
unsafe {
69+
acr.acr().write(|w| {
70+
w.latency().bits(if clocks.sysclk <= MHz(24) {
71+
0b000
72+
} else if clocks.sysclk <= MHz(48) {
73+
0b001
74+
} else {
75+
0b010
76+
})
77+
});
78+
}
79+
80+
let rcc = unsafe { &*RCC::ptr() };
81+
82+
if cfg.hse.is_some() {
83+
// enable HSE and wait for it to be ready
84+
85+
rcc.cr().modify(|_, w| {
86+
if cfg.hse_bypass {
87+
w.hsebyp().bypassed();
88+
}
89+
w.hseon().set_bit()
90+
});
91+
92+
while rcc.cr().read().hserdy().bit_is_clear() {}
93+
}
94+
95+
if let Some(pllmul_bits) = cfg.pllmul {
96+
// enable PLL and wait for it to be ready
97+
98+
#[allow(unused_unsafe)]
99+
rcc.cfgr().modify(|_, w| unsafe {
100+
w.pllmul().bits(pllmul_bits).pllsrc().bit(cfg.hse.is_some())
101+
});
102+
103+
rcc.cr().modify(|_, w| w.pllon().set_bit());
104+
105+
while rcc.cr().read().pllrdy().bit_is_clear() {}
106+
}
107+
108+
// set prescalers and clock source
109+
#[cfg(feature = "connectivity")]
110+
rcc.cfgr().modify(|_, w| unsafe {
111+
w.adcpre().variant(cfg.adcpre);
112+
w.ppre2().bits(cfg.ppre2 as u8);
113+
w.ppre1().bits(cfg.ppre1 as u8);
114+
w.hpre().bits(cfg.hpre as u8);
115+
w.otgfspre().variant(cfg.usbpre);
116+
w.sw().bits(if cfg.pllmul.is_some() {
117+
// PLL
118+
0b10
119+
} else if cfg.hse.is_some() {
120+
// HSE
121+
0b1
122+
} else {
123+
// HSI
124+
0b0
125+
})
126+
});
127+
128+
#[cfg(feature = "stm32f103")]
129+
rcc.cfgr().modify(|_, w| unsafe {
130+
w.adcpre().variant(cfg.adcpre);
131+
w.ppre2().bits(cfg.ppre2 as u8);
132+
w.ppre1().bits(cfg.ppre1 as u8);
133+
w.hpre().bits(cfg.hpre as u8);
134+
w.usbpre().variant(cfg.usbpre);
135+
w.sw().bits(if cfg.pllmul.is_some() {
136+
// PLL
137+
0b10
138+
} else {
139+
// HSE or HSI
140+
u8::from(cfg.hse.is_some())
141+
})
142+
});
143+
144+
#[cfg(any(feature = "stm32f100", feature = "stm32f101"))]
145+
rcc.cfgr().modify(|_, w| unsafe {
146+
w.adcpre().variant(cfg.adcpre);
147+
w.ppre2().bits(cfg.ppre2 as u8);
148+
w.ppre1().bits(cfg.ppre1 as u8);
149+
w.hpre().bits(cfg.hpre as u8);
150+
w.sw().bits(if cfg.pllmul.is_some() {
151+
// PLL
152+
0b10
153+
} else if cfg.hse.is_some() {
154+
// HSE
155+
0b1
156+
} else {
157+
// HSI
158+
0b0
159+
})
160+
});
161+
162+
Self {
163+
rb: self.rb,
164+
clocks,
165+
}
166+
}
167+
168+
pub fn enable<T: Enable>(&mut self, _periph: &T) {
169+
T::enable(self);
170+
}
171+
172+
pub fn reset<T: Reset>(&mut self, _periph: &T) {
173+
T::reset(self);
174+
}
175+
176+
pub fn get_clock<T: BusClock>(&self, _periph: &T) -> Hertz {
177+
T::clock(&self.clocks)
178+
}
179+
180+
pub fn get_timer_clock<T: BusTimerClock>(&self, _periph: &T) -> Hertz {
181+
T::timer_clock(&self.clocks)
182+
}
183+
}
184+
48185
impl Deref for Rcc {
49186
type Target = RCC;
50187
fn deref(&self) -> &Self::Target {
@@ -186,127 +323,6 @@ impl Config {
186323
}
187324
}
188325

189-
impl Rcc {
190-
/// Applies the clock configuration and returns a `Clocks` struct that signifies that the
191-
/// clocks are frozen, and contains the frequencies used. After this function is called,
192-
/// the clocks can not change
193-
///
194-
/// Usage:
195-
///
196-
/// ```rust
197-
/// let dp = pac::Peripherals::take().unwrap();
198-
/// let mut flash = dp.FLASH.constrain();
199-
/// let cfg = rcc::Config::hse(8.MHz()).sysclk(72.MHz());
200-
/// let mut rcc = dp.RCC.constrain().freeze(cfg, &mut flash.acr);
201-
/// ```
202-
#[allow(unused_variables)]
203-
#[inline(always)]
204-
pub fn freeze(self, cfg: impl Into<RawConfig>, acr: &mut ACR) -> Self {
205-
let cfg = cfg.into();
206-
let clocks = cfg.get_clocks();
207-
// adjust flash wait states
208-
#[cfg(any(feature = "stm32f103", feature = "connectivity"))]
209-
unsafe {
210-
acr.acr().write(|w| {
211-
w.latency().bits(if clocks.sysclk <= MHz(24) {
212-
0b000
213-
} else if clocks.sysclk <= MHz(48) {
214-
0b001
215-
} else {
216-
0b010
217-
})
218-
});
219-
}
220-
221-
let rcc = unsafe { &*RCC::ptr() };
222-
223-
if cfg.hse.is_some() {
224-
// enable HSE and wait for it to be ready
225-
226-
rcc.cr().modify(|_, w| {
227-
if cfg.hse_bypass {
228-
w.hsebyp().bypassed();
229-
}
230-
w.hseon().set_bit()
231-
});
232-
233-
while rcc.cr().read().hserdy().bit_is_clear() {}
234-
}
235-
236-
if let Some(pllmul_bits) = cfg.pllmul {
237-
// enable PLL and wait for it to be ready
238-
239-
#[allow(unused_unsafe)]
240-
rcc.cfgr().modify(|_, w| unsafe {
241-
w.pllmul().bits(pllmul_bits).pllsrc().bit(cfg.hse.is_some())
242-
});
243-
244-
rcc.cr().modify(|_, w| w.pllon().set_bit());
245-
246-
while rcc.cr().read().pllrdy().bit_is_clear() {}
247-
}
248-
249-
// set prescalers and clock source
250-
#[cfg(feature = "connectivity")]
251-
rcc.cfgr().modify(|_, w| unsafe {
252-
w.adcpre().variant(cfg.adcpre);
253-
w.ppre2().bits(cfg.ppre2 as u8);
254-
w.ppre1().bits(cfg.ppre1 as u8);
255-
w.hpre().bits(cfg.hpre as u8);
256-
w.otgfspre().variant(cfg.usbpre);
257-
w.sw().bits(if cfg.pllmul.is_some() {
258-
// PLL
259-
0b10
260-
} else if cfg.hse.is_some() {
261-
// HSE
262-
0b1
263-
} else {
264-
// HSI
265-
0b0
266-
})
267-
});
268-
269-
#[cfg(feature = "stm32f103")]
270-
rcc.cfgr().modify(|_, w| unsafe {
271-
w.adcpre().variant(cfg.adcpre);
272-
w.ppre2().bits(cfg.ppre2 as u8);
273-
w.ppre1().bits(cfg.ppre1 as u8);
274-
w.hpre().bits(cfg.hpre as u8);
275-
w.usbpre().variant(cfg.usbpre);
276-
w.sw().bits(if cfg.pllmul.is_some() {
277-
// PLL
278-
0b10
279-
} else {
280-
// HSE or HSI
281-
u8::from(cfg.hse.is_some())
282-
})
283-
});
284-
285-
#[cfg(any(feature = "stm32f100", feature = "stm32f101"))]
286-
rcc.cfgr().modify(|_, w| unsafe {
287-
w.adcpre().variant(cfg.adcpre);
288-
w.ppre2().bits(cfg.ppre2 as u8);
289-
w.ppre1().bits(cfg.ppre1 as u8);
290-
w.hpre().bits(cfg.hpre as u8);
291-
w.sw().bits(if cfg.pllmul.is_some() {
292-
// PLL
293-
0b10
294-
} else if cfg.hse.is_some() {
295-
// HSE
296-
0b1
297-
} else {
298-
// HSI
299-
0b0
300-
})
301-
});
302-
303-
Self {
304-
rb: self.rb,
305-
clocks,
306-
}
307-
}
308-
}
309-
310326
pub trait BkpExt {
311327
/// Enables write access to the registers in the backup domain
312328
fn constrain(self, pwr: &mut PWR, rcc: &mut RCC) -> BackupDomain;

src/timer/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ impl<TIM: Instance + Steal> Timer<TIM> {
6868
/// Initialize timer
6969
pub fn new(tim: TIM, mcu: &mut Mcu) -> Self {
7070
// Enable and reset the timer peripheral
71-
TIM::enable(&mut mcu.rcc);
72-
TIM::reset(&mut mcu.rcc);
71+
mcu.rcc.enable(&tim);
72+
mcu.rcc.reset(&tim);
7373

7474
Self {
75-
clk: TIM::timer_clock(&mcu.rcc.clocks),
75+
clk: mcu.rcc.get_timer_clock(&tim),
7676
tim,
7777
}
7878
}

0 commit comments

Comments
 (0)