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::Peripheral;
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, 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)]
71#[must_use]
72pub fn init() -> OptionalPeripherals {
73 let mut config = Config::default();
74 board_config(&mut config);
75
76 #[cfg(not(capability = "hw/stm32-dual-core"))]
77 let peripherals = embassy_stm32::init(config);
78
79 #[cfg(capability = "hw/stm32-dual-core")]
80 let peripherals = embassy_stm32::init_primary(config, &SHARED_DATA);
81
82 enable_flash_cache();
83
84 OptionalPeripherals::from(peripherals)
85}
86
87fn board_config(config: &mut Config) {
88 config.rcc = rcc_config();
89}
90
91#[expect(clippy::too_many_lines)]
93fn rcc_config() -> embassy_stm32::rcc::Config {
94 #[allow(unused_mut, reason = "conditional compilation")]
95 let mut rcc = embassy_stm32::rcc::Config::default();
96
97 #[cfg(context = "st-b-l475e-iot01a")]
98 {
99 use embassy_stm32::rcc::*;
100
101 rcc.ls = LsConfig {
103 rtc: RtcClockSource::LSE,
104 lsi: false,
105 lse: Some(LseConfig {
106 frequency: embassy_stm32::time::Hertz(32768),
107 mode: LseMode::Oscillator(LseDrive::MediumHigh),
108 }),
109 };
110 rcc.hsi = false;
111 rcc.msi = Some(MSIRange::RANGE8M);
114 rcc.pll = Some(Pll {
115 source: PllSource::MSI,
116 prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None,
119 divq: None,
120 divr: Some(PllRDiv::DIV2), });
122 rcc.sys = Sysclk::PLL1_R;
123 rcc.pllsai1 = Some(Pll {
124 source: PllSource::MSI,
125 prediv: PllPreDiv::DIV1,
126 mul: PllMul::MUL12, divp: None,
128 divq: Some(PllQDiv::DIV2), divr: None,
130 });
131 rcc.mux.clk48sel = mux::Clk48sel::PLLSAI1_Q;
134 }
135
136 #[cfg(context = "st-nucleo-wb55")]
137 {
138 use embassy_stm32::rcc::*;
139
140 rcc.hsi48 = Some(Hsi48Config {
141 sync_from_usb: true,
142 }); rcc.sys = Sysclk::PLL1_R;
144 rcc.hse = Some(Hse {
145 freq: embassy_stm32::time::Hertz(32000000),
146 mode: HseMode::Oscillator,
147 prescaler: HsePrescaler::DIV1,
148 });
149 rcc.pll = Some(Pll {
150 source: PllSource::HSE,
151 prediv: PllPreDiv::DIV2,
152 mul: PllMul::MUL10,
153 divp: None,
154 divq: None,
155 divr: Some(PllRDiv::DIV2), });
157 rcc.mux.clk48sel = mux::Clk48sel::HSI48;
158 }
159
160 #[cfg(context = "st-nucleo-f401re")]
161 {
162 use embassy_stm32::rcc::*;
163 rcc.hse = Some(Hse {
164 freq: embassy_stm32::time::Hertz(8000000),
165 mode: HseMode::Bypass,
166 });
167 rcc.pll_src = PllSource::HSE;
168 rcc.pll = Some(Pll {
169 prediv: PllPreDiv::DIV4,
170 mul: PllMul::MUL168,
171 divp: Some(PllPDiv::DIV4),
172 divq: Some(PllQDiv::DIV7),
173 divr: None,
174 });
175 rcc.ahb_pre = AHBPrescaler::DIV1;
176 rcc.apb1_pre = APBPrescaler::DIV4;
177 rcc.apb2_pre = APBPrescaler::DIV2;
178 rcc.sys = Sysclk::PLL1_P;
179 }
180
181 #[cfg(context = "st-nucleo-f767zi")]
182 {
183 use embassy_stm32::rcc::*;
184 rcc.hse = Some(Hse {
185 freq: embassy_stm32::time::Hertz(8000000),
186 mode: HseMode::Bypass,
187 });
188 rcc.pll_src = PllSource::HSE;
189 rcc.pll = Some(Pll {
190 prediv: PllPreDiv::DIV4,
191 mul: PllMul::MUL216,
192 divp: Some(PllPDiv::DIV2),
193 divq: None,
194 divr: None,
195 });
196 rcc.ahb_pre = AHBPrescaler::DIV1;
197 rcc.apb1_pre = APBPrescaler::DIV4;
198 rcc.apb2_pre = APBPrescaler::DIV2;
199 rcc.sys = Sysclk::PLL1_P;
200 }
201
202 #[cfg(context = "stm32h755zi")]
203 {
204 use embassy_stm32::rcc::*;
205
206 rcc.hsi = Some(HSIPrescaler::DIV1);
207 rcc.csi = true;
208 rcc.hsi48 = Some(Hsi48Config {
209 sync_from_usb: true,
210 }); rcc.pll1 = Some(Pll {
212 source: PllSource::HSI,
213 prediv: PllPreDiv::DIV4,
214 mul: PllMul::MUL50,
215 divp: Some(PllDiv::DIV2),
216 divq: Some(PllDiv::DIV16), divr: None,
219 });
220 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;
227 rcc.supply_config = SupplyConfig::DirectSMPS;
229 rcc.mux.usbsel = mux::Usbsel::HSI48;
230 rcc.mux.spi123sel = mux::Saisel::PLL1_Q; }
234
235 #[cfg(context = "stm32h753zi")]
236 {
237 use embassy_stm32::rcc::*;
238
239 rcc.hsi = Some(HSIPrescaler::DIV1);
240 rcc.csi = true;
241 rcc.hsi48 = Some(Hsi48Config {
242 sync_from_usb: true,
243 }); rcc.pll1 = Some(Pll {
245 source: PllSource::HSI,
246 prediv: PllPreDiv::DIV4,
247 mul: PllMul::MUL50,
248 divp: Some(PllDiv::DIV2),
249 divq: Some(PllDiv::DIV16), divr: None,
251 });
252 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;
259 rcc.mux.usbsel = mux::Usbsel::HSI48;
260 rcc.mux.spi123sel = mux::Saisel::PLL1_Q; }
264
265 #[cfg(any(context = "stm32u073kc", context = "stm32u083mc"))]
266 {
267 use embassy_stm32::rcc::*;
268
269 rcc.hsi48 = Some(Hsi48Config {
270 sync_from_usb: true,
271 }); rcc.hsi = true;
274 rcc.sys = Sysclk::PLL1_R;
275 rcc.pll = Some(Pll {
276 source: PllSource::HSI,
277 prediv: PllPreDiv::DIV1,
278 mul: PllMul::MUL7,
279 divp: None,
280 divq: None,
281 divr: Some(PllRDiv::DIV2), });
283 rcc.mux.clk48sel = mux::Clk48sel::HSI48;
284 }
285
286 #[cfg(context = "st-steval-mkboxpro")]
287 {
288 use embassy_stm32::rcc::*;
289
290 rcc.ls = LsConfig {
291 rtc: RtcClockSource::LSE,
292 lsi: true,
293 lse: Some(LseConfig {
294 peripherals_clocked: true,
295 frequency: embassy_stm32::time::Hertz(32768),
296 mode: LseMode::Oscillator(LseDrive::MediumHigh),
297 }),
298 };
299 rcc.hsi = true;
300 rcc.hsi48 = Some(Hsi48Config {
301 sync_from_usb: true,
302 }); rcc.sys = Sysclk::PLL1_R;
304 rcc.hse = Some(Hse {
305 freq: embassy_stm32::time::Hertz(16_000_000),
306 mode: HseMode::Oscillator,
307 });
308 rcc.pll1 = Some(Pll {
309 source: PllSource::HSE,
310 prediv: PllPreDiv::DIV1,
311 mul: PllMul::MUL10,
312 divp: None,
313 divq: None,
314 divr: Some(PllDiv::DIV1), });
316 rcc.sys = Sysclk::PLL1_R;
317 rcc.mux.iclksel = mux::Iclksel::HSI48;
318 rcc.voltage_range = VoltageScale::RANGE1;
319 }
320
321 #[cfg(context = "stm32f042k6")]
322 {
323 use embassy_stm32::rcc::*;
324
325 rcc.hsi48 = Some(Hsi48Config {
326 sync_from_usb: true,
327 }); rcc.sys = Sysclk::HSI48;
329 rcc.pll = Some(Pll {
330 src: PllSource::HSI48,
331 prediv: PllPreDiv::DIV2,
332 mul: PllMul::MUL2,
333 });
334 }
335
336 #[cfg(context = "seeedstudio-lora-e5-mini")]
337 {
338 use embassy_stm32::rcc::*;
339
340 rcc.hse = Some(Hse {
341 freq: embassy_stm32::time::Hertz(32_000_000),
342 mode: HseMode::Bypass,
343 prescaler: HsePrescaler::DIV1,
344 });
345 rcc.ls = LsConfig::default_lse();
346 rcc.msi = None;
347 rcc.pll = Some(Pll {
348 source: PllSource::HSE,
349 prediv: PllPreDiv::DIV2,
350 mul: PllMul::MUL6,
351 divp: None,
352 divq: Some(PllQDiv::DIV2), divr: Some(PllRDiv::DIV2), });
355
356 rcc.sys = Sysclk::PLL1_R;
357 }
358
359 rcc
360}
361
362fn enable_flash_cache() {
363 #[cfg(any(context = "stm32f401re", context = "stm32f411re",))]
365 {
366 embassy_stm32::pac::FLASH
368 .acr()
369 .modify(|w| w.set_icrst(true));
370 embassy_stm32::pac::FLASH.acr().modify(|w| w.set_icen(true));
372 embassy_stm32::pac::FLASH
373 .acr()
374 .modify(|w| w.set_prften(true));
375 embassy_stm32::pac::FLASH
377 .acr()
378 .modify(|w| w.set_dcrst(true));
379 embassy_stm32::pac::FLASH
380 .acr()
381 .modify(|w| w.set_dcrst(false));
382 embassy_stm32::pac::FLASH.acr().modify(|w| w.set_dcen(true));
384 }
385}