Skip to content

Commit 4e3d066

Browse files
authored
Merge pull request #3779 from algesten/fix/f107-rcc
Full RCC support for STM32F107
2 parents 195b1a5 + 4743501 commit 4e3d066

File tree

2 files changed

+91
-5
lines changed

2 files changed

+91
-5
lines changed

embassy-stm32/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1387,7 +1387,7 @@ fn main() {
13871387
for e in rcc_registers.ir.enums {
13881388
fn is_rcc_name(e: &str) -> bool {
13891389
match e {
1390-
"Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true,
1390+
"Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" | "Prediv1" | "Prediv2" => true,
13911391
"Timpre" | "Pllrclkpre" => false,
13921392
e if e.ends_with("pre") || e.ends_with("pres") || e.ends_with("div") || e.ends_with("mul") => true,
13931393
_ => false,

embassy-stm32/src/rcc/f013.rs

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ pub use crate::pac::rcc::vals::Adcpre as ADCPrescaler;
44
#[cfg(stm32f3)]
55
pub use crate::pac::rcc::vals::Adcpres as AdcPllPrescaler;
66
use crate::pac::rcc::vals::Pllsrc;
7-
#[cfg(stm32f1)]
7+
#[cfg(all(stm32f1, not(stm32f107)))]
88
pub use crate::pac::rcc::vals::Pllxtpre as PllPreDiv;
99
#[cfg(any(stm32f0, stm32f3))]
1010
pub use crate::pac::rcc::vals::Prediv as PllPreDiv;
1111
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Pllmul as PllMul, Ppre as APBPrescaler, Sw as Sysclk};
12+
#[cfg(stm32f107)]
13+
pub use crate::pac::rcc::vals::{I2s2src, Pll2mul as Pll2Mul, Prediv1 as PllPreDiv, Prediv1src, Usbpre as UsbPre};
1214
use crate::pac::{FLASH, RCC};
1315
use crate::time::Hertz;
1416

@@ -37,6 +39,8 @@ pub enum PllSource {
3739
HSI,
3840
#[cfg(rcc_f0v4)]
3941
HSI48,
42+
#[cfg(stm32f107)]
43+
PLL2,
4044
}
4145

4246
#[derive(Clone, Copy)]
@@ -52,6 +56,12 @@ pub struct Pll {
5256
pub mul: PllMul,
5357
}
5458

59+
#[cfg(stm32f107)]
60+
#[derive(Clone, Copy)]
61+
pub struct Pll2Or3 {
62+
pub mul: Pll2Mul,
63+
}
64+
5565
#[cfg(all(stm32f3, not(rcc_f37)))]
5666
#[derive(Clone, Copy)]
5767
pub enum AdcClockSource {
@@ -85,6 +95,12 @@ pub struct Config {
8595
pub sys: Sysclk,
8696

8797
pub pll: Option<Pll>,
98+
#[cfg(stm32f107)]
99+
pub pll2: Option<Pll2Or3>,
100+
#[cfg(stm32f107)]
101+
pub pll3: Option<Pll2Or3>,
102+
#[cfg(stm32f107)]
103+
pub prediv2: PllPreDiv,
88104

89105
pub ahb_pre: AHBPrescaler,
90106
pub apb1_pre: APBPrescaler,
@@ -99,6 +115,11 @@ pub struct Config {
99115
#[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
100116
pub adc34: AdcClockSource,
101117

118+
#[cfg(stm32f107)]
119+
pub i2s2_src: I2s2src,
120+
#[cfg(stm32f107)]
121+
pub i2s3_src: I2s2src,
122+
102123
/// Per-peripheral kernel clock selection muxes
103124
pub mux: super::mux::ClockMux,
104125

@@ -114,6 +135,14 @@ impl Default for Config {
114135
hsi48: Some(Default::default()),
115136
sys: Sysclk::HSI,
116137
pll: None,
138+
139+
#[cfg(stm32f107)]
140+
pll2: None,
141+
#[cfg(stm32f107)]
142+
pll3: None,
143+
#[cfg(stm32f107)]
144+
prediv2: PllPreDiv::DIV1,
145+
117146
ahb_pre: AHBPrescaler::DIV1,
118147
apb1_pre: APBPrescaler::DIV1,
119148
#[cfg(not(stm32f0))]
@@ -129,6 +158,11 @@ impl Default for Config {
129158
#[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
130159
adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
131160

161+
#[cfg(stm32f107)]
162+
i2s2_src: I2s2src::SYS,
163+
#[cfg(stm32f107)]
164+
i2s3_src: I2s2src::SYS,
165+
132166
mux: Default::default(),
133167
}
134168
}
@@ -175,6 +209,28 @@ pub(crate) unsafe fn init(config: Config) {
175209
#[cfg(not(crs))]
176210
let hsi48: Option<Hertz> = None;
177211

212+
// PLL2 and PLL3
213+
// Configure this before PLL since PLL2 can be the source for PLL.
214+
#[cfg(stm32f107)]
215+
{
216+
// Common prediv for PLL2 and PLL3
217+
RCC.cfgr2().modify(|w| w.set_prediv2(config.prediv2));
218+
219+
// Configure PLL2
220+
if let Some(pll2) = config.pll2 {
221+
RCC.cfgr2().modify(|w| w.set_pll2mul(pll2.mul));
222+
RCC.cr().modify(|w| w.set_pll2on(true));
223+
while !RCC.cr().read().pll2rdy() {}
224+
}
225+
226+
// Configure PLL3
227+
if let Some(pll3) = config.pll3 {
228+
RCC.cfgr2().modify(|w| w.set_pll3mul(pll3.mul));
229+
RCC.cr().modify(|w| w.set_pll3on(true));
230+
while !RCC.cr().read().pll3rdy() {}
231+
}
232+
}
233+
178234
// Enable PLL
179235
let pll = config.pll.map(|pll| {
180236
let (src_val, src_freq) = match pll.src {
@@ -187,21 +243,44 @@ pub(crate) unsafe fn init(config: Config) {
187243
}
188244
(Pllsrc::HSI_DIV2, unwrap!(hsi))
189245
}
190-
PllSource::HSE => (Pllsrc::HSE_DIV_PREDIV, unwrap!(hse)),
246+
PllSource::HSE => {
247+
#[cfg(stm32f107)]
248+
RCC.cfgr2().modify(|w| w.set_prediv1src(Prediv1src::HSE));
249+
250+
(Pllsrc::HSE_DIV_PREDIV, unwrap!(hse))
251+
}
191252
#[cfg(rcc_f0v4)]
192253
PllSource::HSI48 => (Pllsrc::HSI48_DIV_PREDIV, unwrap!(hsi48)),
254+
#[cfg(stm32f107)]
255+
PllSource::PLL2 => {
256+
if config.pll2.is_none() {
257+
panic!("if PLL source is PLL2, Config::pll2 must also be set.");
258+
}
259+
RCC.cfgr2().modify(|w| w.set_prediv1src(Prediv1src::PLL2));
260+
261+
let pll2 = unwrap!(config.pll2);
262+
let in_freq = hse.unwrap() / config.prediv2;
263+
let pll2freq = in_freq * pll2.mul;
264+
265+
(Pllsrc::HSE_DIV_PREDIV, pll2freq)
266+
}
193267
};
194268
let in_freq = src_freq / pll.prediv;
269+
195270
rcc_assert!(max::PLL_IN.contains(&in_freq));
196271
let out_freq = in_freq * pll.mul;
197272
rcc_assert!(max::PLL_OUT.contains(&out_freq));
198273

199274
#[cfg(not(stm32f1))]
200275
RCC.cfgr2().modify(|w| w.set_prediv(pll.prediv));
276+
277+
#[cfg(stm32f107)]
278+
RCC.cfgr2().modify(|w| w.set_prediv1(pll.prediv));
279+
201280
RCC.cfgr().modify(|w| {
202281
w.set_pllmul(pll.mul);
203282
w.set_pllsrc(src_val);
204-
#[cfg(stm32f1)]
283+
#[cfg(all(stm32f1, not(stm32f107)))]
205284
w.set_pllxtpre(pll.prediv);
206285
});
207286
RCC.cr().modify(|w| w.set_pllon(true));
@@ -213,7 +292,7 @@ pub(crate) unsafe fn init(config: Config) {
213292
#[cfg(stm32f3)]
214293
let pll_mul_2 = pll.map(|pll| pll * 2u32);
215294

216-
#[cfg(any(rcc_f1, rcc_f1cl, stm32f3))]
295+
#[cfg(any(rcc_f1, rcc_f1cl, stm32f3, stm32f107))]
217296
let usb = match pll {
218297
Some(Hertz(72_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1_5),
219298
Some(Hertz(48_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1),
@@ -293,6 +372,13 @@ pub(crate) unsafe fn init(config: Config) {
293372
w.set_adcpre(config.adc_pre);
294373
});
295374

375+
// I2S2 and I2S3
376+
#[cfg(stm32f107)]
377+
{
378+
RCC.cfgr2().modify(|w| w.set_i2s2src(config.i2s2_src));
379+
RCC.cfgr2().modify(|w| w.set_i2s3src(config.i2s3_src));
380+
}
381+
296382
// Wait for the new prescalers to kick in
297383
// "The clocks are divided with the new prescaler factor from
298384
// 1 to 16 AHB cycles after write"

0 commit comments

Comments
 (0)