aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorMartin Algesten <[email protected]>2025-01-16 11:56:46 +0100
committerMartin Algesten <[email protected]>2025-01-16 15:31:41 +0100
commit9a159a8db0638ea2971eed130a2ae34743da640a (patch)
treebd52dd064e69a26156ade2c2b9ac74999762845a /embassy-stm32
parent169f9c27aa33a279aad51a92b52fc047a54b82af (diff)
Full RCC support for STM32F107
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/rcc/f013.rs112
1 files changed, 109 insertions, 3 deletions
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs
index 57c5cd5b2..27e43fa56 100644
--- a/embassy-stm32/src/rcc/f013.rs
+++ b/embassy-stm32/src/rcc/f013.rs
@@ -4,11 +4,15 @@ pub use crate::pac::rcc::vals::Adcpre as ADCPrescaler;
4#[cfg(stm32f3)] 4#[cfg(stm32f3)]
5pub use crate::pac::rcc::vals::Adcpres as AdcPllPrescaler; 5pub use crate::pac::rcc::vals::Adcpres as AdcPllPrescaler;
6use crate::pac::rcc::vals::Pllsrc; 6use crate::pac::rcc::vals::Pllsrc;
7#[cfg(stm32f1)] 7#[cfg(all(stm32f1, not(stm32f107)))]
8pub use crate::pac::rcc::vals::Pllxtpre as PllPreDiv; 8pub use crate::pac::rcc::vals::Pllxtpre as PllPreDiv;
9#[cfg(any(stm32f0, stm32f3))] 9#[cfg(any(stm32f0, stm32f3))]
10pub use crate::pac::rcc::vals::Prediv as PllPreDiv; 10pub use crate::pac::rcc::vals::Prediv as PllPreDiv;
11pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Pllmul as PllMul, Ppre as APBPrescaler, Sw as Sysclk}; 11pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Pllmul as PllMul, Ppre as APBPrescaler, Sw as Sysclk};
12#[cfg(stm32f107)]
13pub use crate::pac::rcc::vals::{
14 I2s2src, Pll2mul as Pll2Mul, Prediv1 as PllPreDiv, Prediv1src as PreDiv1Src, Usbpre as UsbPre,
15};
12use crate::pac::{FLASH, RCC}; 16use crate::pac::{FLASH, RCC};
13use crate::time::Hertz; 17use crate::time::Hertz;
14 18
@@ -52,6 +56,12 @@ pub struct Pll {
52 pub mul: PllMul, 56 pub mul: PllMul,
53} 57}
54 58
59#[cfg(stm32f107)]
60#[derive(Clone, Copy)]
61pub struct Pll2Or3 {
62 pub mul: Pll2Mul,
63}
64
55#[cfg(all(stm32f3, not(rcc_f37)))] 65#[cfg(all(stm32f3, not(rcc_f37)))]
56#[derive(Clone, Copy)] 66#[derive(Clone, Copy)]
57pub enum AdcClockSource { 67pub enum AdcClockSource {
@@ -85,6 +95,14 @@ pub struct Config {
85 pub sys: Sysclk, 95 pub sys: Sysclk,
86 96
87 pub pll: Option<Pll>, 97 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 prediv1_src: Option<PreDiv1Src>,
104 #[cfg(stm32f107)]
105 pub prediv2: Option<PllPreDiv>,
88 106
89 pub ahb_pre: AHBPrescaler, 107 pub ahb_pre: AHBPrescaler,
90 pub apb1_pre: APBPrescaler, 108 pub apb1_pre: APBPrescaler,
@@ -99,6 +117,11 @@ pub struct Config {
99 #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))] 117 #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
100 pub adc34: AdcClockSource, 118 pub adc34: AdcClockSource,
101 119
120 #[cfg(stm32f107)]
121 pub i2s2_src: Option<I2s2src>,
122 #[cfg(stm32f107)]
123 pub i2s3_src: Option<I2s2src>,
124
102 /// Per-peripheral kernel clock selection muxes 125 /// Per-peripheral kernel clock selection muxes
103 pub mux: super::mux::ClockMux, 126 pub mux: super::mux::ClockMux,
104 127
@@ -114,6 +137,16 @@ impl Default for Config {
114 hsi48: Some(Default::default()), 137 hsi48: Some(Default::default()),
115 sys: Sysclk::HSI, 138 sys: Sysclk::HSI,
116 pll: None, 139 pll: None,
140
141 #[cfg(stm32f107)]
142 pll2: None,
143 #[cfg(stm32f107)]
144 pll3: None,
145 #[cfg(stm32f107)]
146 prediv1_src: None,
147 #[cfg(stm32f107)]
148 prediv2: None,
149
117 ahb_pre: AHBPrescaler::DIV1, 150 ahb_pre: AHBPrescaler::DIV1,
118 apb1_pre: APBPrescaler::DIV1, 151 apb1_pre: APBPrescaler::DIV1,
119 #[cfg(not(stm32f0))] 152 #[cfg(not(stm32f0))]
@@ -129,6 +162,11 @@ impl Default for Config {
129 #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))] 162 #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
130 adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1), 163 adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
131 164
165 #[cfg(stm32f107)]
166 i2s2_src: None,
167 #[cfg(stm32f107)]
168 i2s3_src: None,
169
132 mux: Default::default(), 170 mux: Default::default(),
133 } 171 }
134 } 172 }
@@ -169,6 +207,13 @@ pub(crate) unsafe fn init(config: Config) {
169 } 207 }
170 }; 208 };
171 209
210 #[cfg(stm32f107)]
211 let pll2freq = config.pll2.map(|pll2| {
212 let prediv2 = config.prediv2.unwrap_or(PllPreDiv::DIV1);
213 let in_freq = hse.unwrap() / (prediv2.to_bits() + 1);
214 in_freq * pll2.mul
215 });
216
172 // configure HSI48 217 // configure HSI48
173 #[cfg(crs)] 218 #[cfg(crs)]
174 let hsi48 = config.hsi48.map(|config| super::init_hsi48(config)); 219 let hsi48 = config.hsi48.map(|config| super::init_hsi48(config));
@@ -177,6 +222,8 @@ pub(crate) unsafe fn init(config: Config) {
177 222
178 // Enable PLL 223 // Enable PLL
179 let pll = config.pll.map(|pll| { 224 let pll = config.pll.map(|pll| {
225 #[cfg(stm32f107)]
226 let prediv1_src = config.prediv1_src.unwrap_or(PreDiv1Src::HSE);
180 let (src_val, src_freq) = match pll.src { 227 let (src_val, src_freq) = match pll.src {
181 #[cfg(any(rcc_f0v3, rcc_f0v4, rcc_f3v3))] 228 #[cfg(any(rcc_f0v3, rcc_f0v4, rcc_f3v3))]
182 PllSource::HSI => (Pllsrc::HSI_DIV_PREDIV, unwrap!(hsi)), 229 PllSource::HSI => (Pllsrc::HSI_DIV_PREDIV, unwrap!(hsi)),
@@ -187,21 +234,39 @@ pub(crate) unsafe fn init(config: Config) {
187 } 234 }
188 (Pllsrc::HSI_DIV2, unwrap!(hsi)) 235 (Pllsrc::HSI_DIV2, unwrap!(hsi))
189 } 236 }
237 #[cfg(not(stm32f107))]
190 PllSource::HSE => (Pllsrc::HSE_DIV_PREDIV, unwrap!(hse)), 238 PllSource::HSE => (Pllsrc::HSE_DIV_PREDIV, unwrap!(hse)),
239 #[cfg(stm32f107)]
240 PllSource::HSE => (
241 Pllsrc::HSE_DIV_PREDIV,
242 match prediv1_src {
243 PreDiv1Src::HSE => unwrap!(hse),
244 PreDiv1Src::PLL2 => unwrap!(pll2freq),
245 },
246 ),
191 #[cfg(rcc_f0v4)] 247 #[cfg(rcc_f0v4)]
192 PllSource::HSI48 => (Pllsrc::HSI48_DIV_PREDIV, unwrap!(hsi48)), 248 PllSource::HSI48 => (Pllsrc::HSI48_DIV_PREDIV, unwrap!(hsi48)),
193 }; 249 };
250 #[cfg(not(stm32f107))]
194 let in_freq = src_freq / pll.prediv; 251 let in_freq = src_freq / pll.prediv;
252
253 #[cfg(stm32f107)]
254 let in_freq = src_freq / (pll.prediv.to_bits() + 1);
255
195 rcc_assert!(max::PLL_IN.contains(&in_freq)); 256 rcc_assert!(max::PLL_IN.contains(&in_freq));
196 let out_freq = in_freq * pll.mul; 257 let out_freq = in_freq * pll.mul;
197 rcc_assert!(max::PLL_OUT.contains(&out_freq)); 258 rcc_assert!(max::PLL_OUT.contains(&out_freq));
198 259
199 #[cfg(not(stm32f1))] 260 #[cfg(not(stm32f1))]
200 RCC.cfgr2().modify(|w| w.set_prediv(pll.prediv)); 261 RCC.cfgr2().modify(|w| w.set_prediv(pll.prediv));
262
263 #[cfg(stm32f107)]
264 RCC.cfgr2().modify(|w| w.set_prediv1(pll.prediv));
265
201 RCC.cfgr().modify(|w| { 266 RCC.cfgr().modify(|w| {
202 w.set_pllmul(pll.mul); 267 w.set_pllmul(pll.mul);
203 w.set_pllsrc(src_val); 268 w.set_pllsrc(src_val);
204 #[cfg(stm32f1)] 269 #[cfg(all(stm32f1, not(stm32f107)))]
205 w.set_pllxtpre(pll.prediv); 270 w.set_pllxtpre(pll.prediv);
206 }); 271 });
207 RCC.cr().modify(|w| w.set_pllon(true)); 272 RCC.cr().modify(|w| w.set_pllon(true));
@@ -210,10 +275,39 @@ pub(crate) unsafe fn init(config: Config) {
210 out_freq 275 out_freq
211 }); 276 });
212 277
278 // Prediv1 Source Mux (HSE or PLL2)
279 #[cfg(stm32f107)]
280 if let Some(prediv1_src) = config.prediv1_src {
281 RCC.cfgr2().modify(|w| w.set_prediv1src(prediv1_src));
282 }
283
284 // pll2 and pll3
285 #[cfg(stm32f107)]
286 {
287 // Common prediv for PLL2 and PLL3
288 if let Some(prediv) = config.prediv2 {
289 RCC.cfgr2().modify(|w| w.set_prediv2(prediv));
290 }
291
292 // Configure PLL2
293 if let Some(pll2) = config.pll2 {
294 RCC.cfgr2().modify(|w| w.set_pll2mul(pll2.mul));
295 RCC.cr().modify(|w| w.set_pll2on(true));
296 while !RCC.cr().read().pll2rdy() {}
297 }
298
299 // Configure PLL3
300 if let Some(pll3) = config.pll3 {
301 RCC.cfgr2().modify(|w| w.set_pll3mul(pll3.mul));
302 RCC.cr().modify(|w| w.set_pll3on(true));
303 while !RCC.cr().read().pll3rdy() {}
304 }
305 }
306
213 #[cfg(stm32f3)] 307 #[cfg(stm32f3)]
214 let pll_mul_2 = pll.map(|pll| pll * 2u32); 308 let pll_mul_2 = pll.map(|pll| pll * 2u32);
215 309
216 #[cfg(any(rcc_f1, rcc_f1cl, stm32f3))] 310 #[cfg(any(rcc_f1, rcc_f1cl, stm32f3, stm32f107))]
217 let usb = match pll { 311 let usb = match pll {
218 Some(Hertz(72_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1_5), 312 Some(Hertz(72_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1_5),
219 Some(Hertz(48_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1), 313 Some(Hertz(48_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1),
@@ -293,6 +387,18 @@ pub(crate) unsafe fn init(config: Config) {
293 w.set_adcpre(config.adc_pre); 387 w.set_adcpre(config.adc_pre);
294 }); 388 });
295 389
390 // I2S2 and I2S3
391 #[cfg(stm32f107)]
392 {
393 if let Some(i2s2_src) = config.i2s2_src {
394 RCC.cfgr2().modify(|w| w.set_i2s2src(i2s2_src));
395 }
396
397 if let Some(i2s3_src) = config.i2s3_src {
398 RCC.cfgr2().modify(|w| w.set_i2s3src(i2s3_src));
399 }
400 }
401
296 // Wait for the new prescalers to kick in 402 // Wait for the new prescalers to kick in
297 // "The clocks are divided with the new prescaler factor from 403 // "The clocks are divided with the new prescaler factor from
298 // 1 to 16 AHB cycles after write" 404 // 1 to 16 AHB cycles after write"