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