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 = "ethernet")]
40#[doc(hidden)]
41pub mod ethernet;
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>: private::Sealed {
73 fn into_hal_peripheral(self) -> Peri<'a, T>;
74}
75
76impl<T: PeripheralType> private::Sealed for Peri<'_, T> {}
77
78#[doc(hidden)]
79impl<'a, T: PeripheralType> IntoPeripheral<'a, T> for Peri<'a, T> {
80 fn into_hal_peripheral(self) -> Peri<'a, T> {
81 self
82 }
83}
84
85mod private {
86 pub trait Sealed {}
87}
88
89#[doc(hidden)]
90#[must_use]
91pub fn init() -> OptionalPeripherals {
92 let mut config = Config::default();
93 board_config(&mut config);
94
95 #[cfg(not(capability = "hw/stm32-dual-core"))]
96 let peripherals = embassy_stm32::init(config);
97
98 #[cfg(capability = "hw/stm32-dual-core")]
99 let peripherals = embassy_stm32::init_primary(config, &SHARED_DATA);
100
101 enable_flash_cache();
102
103 OptionalPeripherals::from(peripherals)
104}
105
106fn board_config(config: &mut Config) {
107 cfg_select! {
108 feature = "rcc-config-override" => {
109 unsafe extern "Rust" {
110 fn __ariel_os_rcc_config() -> embassy_stm32::rcc::Config;
111 }
112 config.rcc = unsafe { __ariel_os_rcc_config() };
113 }
114 _ => {
115 config.rcc = rcc_config();
116 }
117 }
118}
119
120#[cfg_attr(feature = "rcc-config-override", expect(dead_code))]
122fn rcc_config() -> embassy_stm32::rcc::Config {
123 #[allow(unused_mut, reason = "conditional compilation")]
124 let mut rcc = embassy_stm32::rcc::Config::default();
125
126 #[cfg(context = "st-b-l475e-iot01a")]
127 {
128 use embassy_stm32::rcc::*;
129
130 rcc.ls = LsConfig {
132 rtc: RtcClockSource::LSE,
133 lsi: false,
134 lse: Some(LseConfig {
135 frequency: embassy_stm32::time::Hertz(32768),
136 mode: LseMode::Oscillator(LseDrive::MediumHigh),
137 }),
138 };
139 rcc.hsi = false;
140 rcc.msi = Some(MSIRange::RANGE8M);
143 rcc.pll = Some(Pll {
144 source: PllSource::MSI,
145 prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None,
148 divq: None,
149 divr: Some(PllRDiv::DIV2), });
151 rcc.sys = Sysclk::PLL1_R;
152 rcc.pllsai1 = Some(Pll {
153 source: PllSource::MSI,
154 prediv: PllPreDiv::DIV1,
155 mul: PllMul::MUL12, divp: None,
157 divq: Some(PllQDiv::DIV2), divr: None,
159 });
160 rcc.mux.clk48sel = mux::Clk48sel::PLLSAI1_Q;
163 }
164
165 #[cfg(context = "st-nucleo-wb55")]
166 {
167 use embassy_stm32::rcc::*;
168
169 rcc.hsi48 = Some(Hsi48Config {
170 sync_from_usb: true,
171 }); rcc.sys = Sysclk::PLL1_R;
173 rcc.hse = Some(Hse {
174 freq: embassy_stm32::time::Hertz(32000000),
175 mode: HseMode::Oscillator,
176 prescaler: HsePrescaler::DIV1,
177 });
178 rcc.pll = Some(Pll {
179 source: PllSource::HSE,
180 prediv: PllPreDiv::DIV2,
181 mul: PllMul::MUL10,
182 divp: None,
183 divq: None,
184 divr: Some(PllRDiv::DIV2), });
186 rcc.mux.clk48sel = mux::Clk48sel::HSI48;
187 }
188
189 #[cfg(any(context = "stm32f303cb", context = "stm32f303re"))]
190 {
191 use embassy_stm32::rcc::*;
192
193 rcc.hse = Some(Hse {
194 freq: embassy_stm32::time::Hertz(8000000),
195 mode: HseMode::Oscillator,
196 });
197 rcc.pll = Some(Pll {
198 src: PllSource::HSE,
199 prediv: PllPreDiv::DIV1,
200 mul: PllMul::MUL9,
201 });
202 rcc.ahb_pre = AHBPrescaler::DIV1;
203 rcc.apb1_pre = APBPrescaler::DIV4;
204 rcc.apb2_pre = APBPrescaler::DIV2;
205 rcc.sys = Sysclk::PLL1_P; }
207
208 #[cfg(context = "st-nucleo-f401re")]
209 {
210 use embassy_stm32::rcc::*;
211 rcc.hse = Some(Hse {
212 freq: embassy_stm32::time::Hertz(8000000),
213 mode: HseMode::Bypass,
214 });
215 rcc.pll_src = PllSource::HSE;
216 rcc.pll = Some(Pll {
217 prediv: PllPreDiv::DIV4,
218 mul: PllMul::MUL168,
219 divp: Some(PllPDiv::DIV4),
220 divq: Some(PllQDiv::DIV7),
221 divr: None,
222 });
223 rcc.ahb_pre = AHBPrescaler::DIV1;
224 rcc.apb1_pre = APBPrescaler::DIV4;
225 rcc.apb2_pre = APBPrescaler::DIV2;
226 rcc.sys = Sysclk::PLL1_P;
227 }
228
229 #[cfg(context = "st-nucleo-f767zi")]
230 {
231 use embassy_stm32::rcc::*;
232 rcc.hse = Some(Hse {
233 freq: embassy_stm32::time::Hertz(8000000),
234 mode: HseMode::Bypass,
235 });
236 rcc.pll_src = PllSource::HSE;
237 rcc.pll = Some(Pll {
238 prediv: PllPreDiv::DIV4,
239 mul: PllMul::MUL216,
240 divp: Some(PllPDiv::DIV2),
241 divq: None,
242 divr: None,
243 });
244 rcc.ahb_pre = AHBPrescaler::DIV1;
245 rcc.apb1_pre = APBPrescaler::DIV4;
246 rcc.apb2_pre = APBPrescaler::DIV2;
247 rcc.sys = Sysclk::PLL1_P;
248 }
249
250 #[cfg(context = "stm32h755zi")]
251 {
252 use embassy_stm32::rcc::*;
253
254 rcc.hsi = Some(HSIPrescaler::DIV1);
255 rcc.csi = true;
256 rcc.hsi48 = Some(Hsi48Config {
257 sync_from_usb: true,
258 }); rcc.pll1 = Some(Pll {
260 source: PllSource::HSI,
261 prediv: PllPreDiv::DIV4,
262 mul: PllMul::MUL50,
263 divp: Some(PllDiv::DIV2),
264 divq: Some(PllDiv::DIV16), divr: None,
267 });
268 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;
275 rcc.supply_config = SupplyConfig::DirectSMPS;
277 rcc.mux.usbsel = mux::Usbsel::HSI48;
278 rcc.mux.spi123sel = mux::Saisel::PLL1_Q; }
282
283 #[cfg(context = "stm32h753zi")]
284 {
285 use embassy_stm32::rcc::*;
286
287 rcc.hsi = Some(HSIPrescaler::DIV1);
288 rcc.csi = true;
289 rcc.hsi48 = Some(Hsi48Config {
290 sync_from_usb: true,
291 }); rcc.pll1 = Some(Pll {
293 source: PllSource::HSI,
294 prediv: PllPreDiv::DIV4,
295 mul: PllMul::MUL50,
296 divp: Some(PllDiv::DIV2),
297 divq: Some(PllDiv::DIV16), divr: None,
299 });
300 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;
307 rcc.mux.usbsel = mux::Usbsel::HSI48;
308 rcc.mux.spi123sel = mux::Saisel::PLL1_Q; }
312
313 #[cfg(any(context = "stm32u073kc", context = "stm32u083mc"))]
314 {
315 use embassy_stm32::rcc::*;
316
317 rcc.hsi48 = Some(Hsi48Config {
318 sync_from_usb: true,
319 }); rcc.hsi = true;
322 rcc.sys = Sysclk::PLL1_R;
323 rcc.pll = Some(Pll {
324 source: PllSource::HSI,
325 prediv: PllPreDiv::DIV1,
326 mul: PllMul::MUL7,
327 divp: None,
328 divq: None,
329 divr: Some(PllRDiv::DIV2), });
331 rcc.mux.clk48sel = mux::Clk48sel::HSI48;
332 }
333
334 #[cfg(context = "st-steval-mkboxpro")]
335 {
336 use embassy_stm32::rcc::*;
337
338 rcc.ls = LsConfig {
339 rtc: RtcClockSource::LSE,
340 lsi: true,
341 lse: Some(LseConfig {
342 peripherals_clocked: true,
343 frequency: embassy_stm32::time::Hertz(32768),
344 mode: LseMode::Oscillator(LseDrive::MediumHigh),
345 }),
346 };
347 rcc.hsi = true;
348 rcc.hsi48 = Some(Hsi48Config {
349 sync_from_usb: true,
350 }); rcc.sys = Sysclk::PLL1_R;
352 rcc.hse = Some(Hse {
353 freq: embassy_stm32::time::Hertz(16_000_000),
354 mode: HseMode::Oscillator,
355 });
356 rcc.pll1 = Some(Pll {
357 source: PllSource::HSE,
358 prediv: PllPreDiv::DIV1,
359 mul: PllMul::MUL10,
360 divp: None,
361 divq: None,
362 divr: Some(PllDiv::DIV1), });
364 rcc.sys = Sysclk::PLL1_R;
365 rcc.mux.iclksel = mux::Iclksel::HSI48;
366 rcc.voltage_range = VoltageScale::RANGE1;
367 }
368
369 #[cfg(context = "stm32f042k6")]
370 {
371 use embassy_stm32::rcc::*;
372
373 rcc.hsi48 = Some(Hsi48Config {
374 sync_from_usb: true,
375 }); rcc.sys = Sysclk::HSI48;
377 rcc.pll = Some(Pll {
378 src: PllSource::HSI48,
379 prediv: PllPreDiv::DIV2,
380 mul: PllMul::MUL2,
381 });
382 }
383
384 #[cfg(context = "seeedstudio-lora-e5-mini")]
385 {
386 use embassy_stm32::rcc::*;
387
388 rcc.hse = Some(Hse {
389 freq: embassy_stm32::time::Hertz(32_000_000),
390 mode: HseMode::Bypass,
391 prescaler: HsePrescaler::DIV1,
392 });
393 rcc.ls = LsConfig::default_lse();
394 rcc.msi = None;
395 rcc.pll = Some(Pll {
396 source: PllSource::HSE,
397 prediv: PllPreDiv::DIV2,
398 mul: PllMul::MUL6,
399 divp: None,
400 divq: Some(PllQDiv::DIV2), divr: Some(PllRDiv::DIV2), });
403
404 rcc.sys = Sysclk::PLL1_R;
405 }
406
407 #[cfg(context = "st-nucleo-wba65ri")]
408 {
409 use embassy_stm32::rcc::*;
410
411 rcc.hse = Some(Hse {
412 prescaler: HsePrescaler::DIV1,
413 });
414 rcc.pll1 = Some(Pll {
415 source: PllSource::HSE,
416 prediv: PllPreDiv::DIV2, mul: PllMul::MUL12, divp: Some(PllDiv::DIV6), divq: None,
420 divr: Some(PllDiv::DIV2), frac: None,
422 });
423 rcc.sys = Sysclk::PLL1_R;
424 rcc.voltage_scale = VoltageScale::RANGE1;
425 rcc.mux.otghssel = Otghssel::HSE; }
427
428 rcc
429}
430
431fn enable_flash_cache() {
432 #[cfg(any(context = "stm32f401re", context = "stm32f411re",))]
434 {
435 embassy_stm32::pac::FLASH
437 .acr()
438 .modify(|w| w.set_icrst(true));
439 embassy_stm32::pac::FLASH.acr().modify(|w| w.set_icen(true));
441 embassy_stm32::pac::FLASH
442 .acr()
443 .modify(|w| w.set_prften(true));
444 embassy_stm32::pac::FLASH
446 .acr()
447 .modify(|w| w.set_dcrst(true));
448 embassy_stm32::pac::FLASH
449 .acr()
450 .modify(|w| w.set_dcrst(false));
451 embassy_stm32::pac::FLASH.acr().modify(|w| w.set_dcen(true));
453 }
454}