1#![no_std]
4#![cfg_attr(nightly, feature(doc_cfg))]
5#![deny(missing_docs)]
6
7pub mod gpio;
8
9#[doc(hidden)]
10pub mod peripheral {
11 pub use embassy_stm32::Peri;
12}
13
14#[cfg(feature = "external-interrupts")]
15#[doc(hidden)]
16pub mod extint_registry;
17
18#[cfg(feature = "i2c")]
19pub mod i2c;
20
21#[doc(hidden)]
22pub mod identity;
23
24#[cfg(feature = "spi")]
25pub mod spi;
26
27#[cfg(feature = "uart")]
28pub mod uart;
29
30#[cfg(feature = "storage")]
31#[doc(hidden)]
32pub mod storage;
33
34#[cfg(feature = "usb")]
35#[doc(hidden)]
36pub mod usb;
37
38#[cfg(feature = "eth")]
39#[doc(hidden)]
40pub mod eth;
41
42use embassy_stm32::Config;
43
44#[doc(hidden)]
45pub use embassy_stm32::{OptionalPeripherals, Peri, PeripheralType, Peripherals, interrupt};
46
47pub use embassy_stm32::peripherals;
48
49#[cfg(feature = "executor-interrupt")]
50pub(crate) use embassy_executor::InterruptExecutor as Executor;
51
52#[cfg(feature = "hwrng")]
53#[doc(hidden)]
54pub mod hwrng;
55
56#[cfg(feature = "executor-interrupt")]
57include!(concat!(env!("OUT_DIR"), "/swi.rs"));
58
59#[cfg(capability = "hw/stm32-dual-core")]
60use {core::mem::MaybeUninit, embassy_stm32::SharedData};
61
62#[cfg(capability = "hw/stm32-dual-core")]
64static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
65
66#[cfg(feature = "executor-interrupt")]
67#[doc(hidden)]
68pub static EXECUTOR: Executor = Executor::new();
69
70#[doc(hidden)]
71pub trait IntoPeripheral<'a, T: PeripheralType> {
72 fn into_hal_peripheral(self) -> Peri<'a, T>;
73}
74
75#[doc(hidden)]
76impl<'a, T: PeripheralType> IntoPeripheral<'a, T> for Peri<'a, T> {
77 fn into_hal_peripheral(self) -> Peri<'a, T> {
78 self
79 }
80}
81
82#[doc(hidden)]
83#[must_use]
84pub fn init() -> OptionalPeripherals {
85 let mut config = Config::default();
86 board_config(&mut config);
87
88 #[cfg(not(capability = "hw/stm32-dual-core"))]
89 let peripherals = embassy_stm32::init(config);
90
91 #[cfg(capability = "hw/stm32-dual-core")]
92 let peripherals = embassy_stm32::init_primary(config, &SHARED_DATA);
93
94 enable_flash_cache();
95
96 OptionalPeripherals::from(peripherals)
97}
98
99fn board_config(config: &mut Config) {
100 config.rcc = rcc_config();
101}
102
103fn rcc_config() -> embassy_stm32::rcc::Config {
105 #[allow(unused_mut, reason = "conditional compilation")]
106 let mut rcc = embassy_stm32::rcc::Config::default();
107
108 #[cfg(context = "st-b-l475e-iot01a")]
109 {
110 use embassy_stm32::rcc::*;
111
112 rcc.ls = LsConfig {
114 rtc: RtcClockSource::LSE,
115 lsi: false,
116 lse: Some(LseConfig {
117 frequency: embassy_stm32::time::Hertz(32768),
118 mode: LseMode::Oscillator(LseDrive::MediumHigh),
119 }),
120 };
121 rcc.hsi = false;
122 rcc.msi = Some(MSIRange::RANGE8M);
125 rcc.pll = Some(Pll {
126 source: PllSource::MSI,
127 prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None,
130 divq: None,
131 divr: Some(PllRDiv::DIV2), });
133 rcc.sys = Sysclk::PLL1_R;
134 rcc.pllsai1 = Some(Pll {
135 source: PllSource::MSI,
136 prediv: PllPreDiv::DIV1,
137 mul: PllMul::MUL12, divp: None,
139 divq: Some(PllQDiv::DIV2), divr: None,
141 });
142 rcc.mux.clk48sel = mux::Clk48sel::PLLSAI1_Q;
145 }
146
147 #[cfg(context = "st-nucleo-wb55")]
148 {
149 use embassy_stm32::rcc::*;
150
151 rcc.hsi48 = Some(Hsi48Config {
152 sync_from_usb: true,
153 }); rcc.sys = Sysclk::PLL1_R;
155 rcc.hse = Some(Hse {
156 freq: embassy_stm32::time::Hertz(32000000),
157 mode: HseMode::Oscillator,
158 prescaler: HsePrescaler::DIV1,
159 });
160 rcc.pll = Some(Pll {
161 source: PllSource::HSE,
162 prediv: PllPreDiv::DIV2,
163 mul: PllMul::MUL10,
164 divp: None,
165 divq: None,
166 divr: Some(PllRDiv::DIV2), });
168 rcc.mux.clk48sel = mux::Clk48sel::HSI48;
169 }
170
171 #[cfg(context = "st-nucleo-f401re")]
172 {
173 use embassy_stm32::rcc::*;
174 rcc.hse = Some(Hse {
175 freq: embassy_stm32::time::Hertz(8000000),
176 mode: HseMode::Bypass,
177 });
178 rcc.pll_src = PllSource::HSE;
179 rcc.pll = Some(Pll {
180 prediv: PllPreDiv::DIV4,
181 mul: PllMul::MUL168,
182 divp: Some(PllPDiv::DIV4),
183 divq: Some(PllQDiv::DIV7),
184 divr: None,
185 });
186 rcc.ahb_pre = AHBPrescaler::DIV1;
187 rcc.apb1_pre = APBPrescaler::DIV4;
188 rcc.apb2_pre = APBPrescaler::DIV2;
189 rcc.sys = Sysclk::PLL1_P;
190 }
191
192 #[cfg(context = "st-nucleo-f767zi")]
193 {
194 use embassy_stm32::rcc::*;
195 rcc.hse = Some(Hse {
196 freq: embassy_stm32::time::Hertz(8000000),
197 mode: HseMode::Bypass,
198 });
199 rcc.pll_src = PllSource::HSE;
200 rcc.pll = Some(Pll {
201 prediv: PllPreDiv::DIV4,
202 mul: PllMul::MUL216,
203 divp: Some(PllPDiv::DIV2),
204 divq: None,
205 divr: None,
206 });
207 rcc.ahb_pre = AHBPrescaler::DIV1;
208 rcc.apb1_pre = APBPrescaler::DIV4;
209 rcc.apb2_pre = APBPrescaler::DIV2;
210 rcc.sys = Sysclk::PLL1_P;
211 }
212
213 #[cfg(context = "stm32h755zi")]
214 {
215 use embassy_stm32::rcc::*;
216
217 rcc.hsi = Some(HSIPrescaler::DIV1);
218 rcc.csi = true;
219 rcc.hsi48 = Some(Hsi48Config {
220 sync_from_usb: true,
221 }); rcc.pll1 = Some(Pll {
223 source: PllSource::HSI,
224 prediv: PllPreDiv::DIV4,
225 mul: PllMul::MUL50,
226 divp: Some(PllDiv::DIV2),
227 divq: Some(PllDiv::DIV16), divr: None,
230 });
231 rcc.sys = Sysclk::PLL1_P; rcc.ahb_pre = AHBPrescaler::DIV2; rcc.apb1_pre = APBPrescaler::DIV2; rcc.apb2_pre = APBPrescaler::DIV2; rcc.apb3_pre = APBPrescaler::DIV2; rcc.apb4_pre = APBPrescaler::DIV2; rcc.voltage_scale = VoltageScale::Scale1;
238 rcc.supply_config = SupplyConfig::DirectSMPS;
240 rcc.mux.usbsel = mux::Usbsel::HSI48;
241 rcc.mux.spi123sel = mux::Saisel::PLL1_Q; }
245
246 #[cfg(context = "stm32h753zi")]
247 {
248 use embassy_stm32::rcc::*;
249
250 rcc.hsi = Some(HSIPrescaler::DIV1);
251 rcc.csi = true;
252 rcc.hsi48 = Some(Hsi48Config {
253 sync_from_usb: true,
254 }); rcc.pll1 = Some(Pll {
256 source: PllSource::HSI,
257 prediv: PllPreDiv::DIV4,
258 mul: PllMul::MUL50,
259 divp: Some(PllDiv::DIV2),
260 divq: Some(PllDiv::DIV16), divr: None,
262 });
263 rcc.sys = Sysclk::PLL1_P; rcc.ahb_pre = AHBPrescaler::DIV2; rcc.apb1_pre = APBPrescaler::DIV2; rcc.apb2_pre = APBPrescaler::DIV2; rcc.apb3_pre = APBPrescaler::DIV2; rcc.apb4_pre = APBPrescaler::DIV2; rcc.voltage_scale = VoltageScale::Scale1;
270 rcc.mux.usbsel = mux::Usbsel::HSI48;
271 rcc.mux.spi123sel = mux::Saisel::PLL1_Q; }
275
276 #[cfg(any(context = "stm32u073kc", context = "stm32u083mc"))]
277 {
278 use embassy_stm32::rcc::*;
279
280 rcc.hsi48 = Some(Hsi48Config {
281 sync_from_usb: true,
282 }); rcc.hsi = true;
285 rcc.sys = Sysclk::PLL1_R;
286 rcc.pll = Some(Pll {
287 source: PllSource::HSI,
288 prediv: PllPreDiv::DIV1,
289 mul: PllMul::MUL7,
290 divp: None,
291 divq: None,
292 divr: Some(PllRDiv::DIV2), });
294 rcc.mux.clk48sel = mux::Clk48sel::HSI48;
295 }
296
297 #[cfg(context = "st-steval-mkboxpro")]
298 {
299 use embassy_stm32::rcc::*;
300
301 rcc.ls = LsConfig {
302 rtc: RtcClockSource::LSE,
303 lsi: true,
304 lse: Some(LseConfig {
305 peripherals_clocked: true,
306 frequency: embassy_stm32::time::Hertz(32768),
307 mode: LseMode::Oscillator(LseDrive::MediumHigh),
308 }),
309 };
310 rcc.hsi = true;
311 rcc.hsi48 = Some(Hsi48Config {
312 sync_from_usb: true,
313 }); rcc.sys = Sysclk::PLL1_R;
315 rcc.hse = Some(Hse {
316 freq: embassy_stm32::time::Hertz(16_000_000),
317 mode: HseMode::Oscillator,
318 });
319 rcc.pll1 = Some(Pll {
320 source: PllSource::HSE,
321 prediv: PllPreDiv::DIV1,
322 mul: PllMul::MUL10,
323 divp: None,
324 divq: None,
325 divr: Some(PllDiv::DIV1), });
327 rcc.sys = Sysclk::PLL1_R;
328 rcc.mux.iclksel = mux::Iclksel::HSI48;
329 rcc.voltage_range = VoltageScale::RANGE1;
330 }
331
332 #[cfg(context = "stm32f042k6")]
333 {
334 use embassy_stm32::rcc::*;
335
336 rcc.hsi48 = Some(Hsi48Config {
337 sync_from_usb: true,
338 }); rcc.sys = Sysclk::HSI48;
340 rcc.pll = Some(Pll {
341 src: PllSource::HSI48,
342 prediv: PllPreDiv::DIV2,
343 mul: PllMul::MUL2,
344 });
345 }
346
347 #[cfg(context = "seeedstudio-lora-e5-mini")]
348 {
349 use embassy_stm32::rcc::*;
350
351 rcc.hse = Some(Hse {
352 freq: embassy_stm32::time::Hertz(32_000_000),
353 mode: HseMode::Bypass,
354 prescaler: HsePrescaler::DIV1,
355 });
356 rcc.ls = LsConfig::default_lse();
357 rcc.msi = None;
358 rcc.pll = Some(Pll {
359 source: PllSource::HSE,
360 prediv: PllPreDiv::DIV2,
361 mul: PllMul::MUL6,
362 divp: None,
363 divq: Some(PllQDiv::DIV2), divr: Some(PllRDiv::DIV2), });
366
367 rcc.sys = Sysclk::PLL1_R;
368 }
369
370 rcc
371}
372
373fn enable_flash_cache() {
374 #[cfg(any(context = "stm32f401re", context = "stm32f411re",))]
376 {
377 embassy_stm32::pac::FLASH
379 .acr()
380 .modify(|w| w.set_icrst(true));
381 embassy_stm32::pac::FLASH.acr().modify(|w| w.set_icen(true));
383 embassy_stm32::pac::FLASH
384 .acr()
385 .modify(|w| w.set_prften(true));
386 embassy_stm32::pac::FLASH
388 .acr()
389 .modify(|w| w.set_dcrst(true));
390 embassy_stm32::pac::FLASH
391 .acr()
392 .modify(|w| w.set_dcrst(false));
393 embassy_stm32::pac::FLASH.acr().modify(|w| w.set_dcen(true));
395 }
396}