aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/rust.yml18
-rw-r--r--embassy-macros/Cargo.toml1
-rw-r--r--embassy-macros/src/chip/stm32.rs28
-rw-r--r--embassy-macros/src/lib.rs6
-rw-r--r--embassy-stm32-examples/.cargo/config.toml28
-rw-r--r--embassy-stm32-examples/Cargo.toml53
-rw-r--r--embassy-stm32-examples/build.rs31
-rw-r--r--embassy-stm32-examples/memory.x5
-rw-r--r--embassy-stm32-examples/src/bin/can.rs57
-rw-r--r--embassy-stm32-examples/src/bin/exti.rs57
-rw-r--r--embassy-stm32-examples/src/bin/hello.rs42
-rw-r--r--embassy-stm32-examples/src/bin/rtc_async.rs40
-rw-r--r--embassy-stm32-examples/src/bin/serial.rs80
-rw-r--r--embassy-stm32-examples/src/bin/usb_serial.rs119
-rw-r--r--embassy-stm32-examples/src/example_common.rs17
-rw-r--r--embassy-stm32/Cargo.toml53
-rw-r--r--embassy-stm32/src/can.rs120
-rw-r--r--embassy-stm32/src/exti.rs790
-rw-r--r--embassy-stm32/src/f4/mod.rs4
-rw-r--r--embassy-stm32/src/f4/rtc.rs505
-rw-r--r--embassy-stm32/src/f4/serial.rs357
-rw-r--r--embassy-stm32/src/f4/spi.rs492
-rw-r--r--embassy-stm32/src/f4/system.rs61
-rw-r--r--embassy-stm32/src/fmt.rs114
-rw-r--r--embassy-stm32/src/interrupt.rs1042
-rw-r--r--embassy-stm32/src/l0/mod.rs2
-rw-r--r--embassy-stm32/src/l0/rtc.rs372
-rw-r--r--embassy-stm32/src/l0/system.rs17
-rw-r--r--embassy-stm32/src/lib.rs478
29 files changed, 1 insertions, 4988 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index cf70e2e5c..97c668aca 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -55,24 +55,6 @@ jobs:
55 - package: embassy-nrf 55 - package: embassy-nrf
56 target: thumbv7em-none-eabi 56 target: thumbv7em-none-eabi
57 features: nrf52840,defmt 57 features: nrf52840,defmt
58 - package: embassy-stm32-examples
59 target: thumbv7em-none-eabi
60 features: stm32f405
61 - package: embassy-stm32
62 target: thumbv7em-none-eabi
63 features: stm32f405
64 - package: embassy-stm32
65 target: thumbv7em-none-eabi
66 features: stm32f446
67 - package: embassy-stm32
68 target: thumbv7em-none-eabi
69 features: stm32f405,defmt
70 - package: embassy-stm32
71 target: thumbv6m-none-eabi
72 features: stm32l0x2
73 - package: embassy-stm32
74 target: thumbv6m-none-eabi
75 features: stm32l0x2,defmt
76 - package: embassy-rp-examples 58 - package: embassy-rp-examples
77 target: thumbv6m-none-eabi 59 target: thumbv6m-none-eabi
78 60
diff --git a/embassy-macros/Cargo.toml b/embassy-macros/Cargo.toml
index 6da2a5868..265a0c083 100644
--- a/embassy-macros/Cargo.toml
+++ b/embassy-macros/Cargo.toml
@@ -14,7 +14,6 @@ proc-macro2 = "1.0.24"
14proc-macro = true 14proc-macro = true
15 15
16[features] 16[features]
17stm32 = []
18nrf = [] 17nrf = []
19rp = [] 18rp = []
20std = [] 19std = []
diff --git a/embassy-macros/src/chip/stm32.rs b/embassy-macros/src/chip/stm32.rs
deleted file mode 100644
index 3f299650c..000000000
--- a/embassy-macros/src/chip/stm32.rs
+++ /dev/null
@@ -1,28 +0,0 @@
1use crate::path::ModulePrefix;
2use proc_macro2::TokenStream;
3use quote::quote;
4
5pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream {
6 let embassy_path = embassy_prefix.append("embassy").path();
7 let embassy_stm32_path = embassy_prefix.append("embassy_stm32").path();
8
9 quote!(
10 use #embassy_stm32_path::{rtc, interrupt, Peripherals, pac, hal::rcc::RccExt, hal::time::U32Ext};
11
12 unsafe { #embassy_stm32_path::system::configure(#config) };
13
14 let (dp, clocks) = Peripherals::take().unwrap();
15
16 let mut rtc = rtc::RTC::new(dp.TIM2, interrupt::take!(TIM2), clocks);
17 let rtc = unsafe { make_static(&mut rtc) };
18 rtc.start();
19 let mut alarm = rtc.alarm1();
20
21 unsafe { #embassy_path::time::set_clock(rtc) };
22
23 let alarm = unsafe { make_static(&mut alarm) };
24 executor.set_alarm(alarm);
25
26 unsafe { Peripherals::set_peripherals(clocks) };
27 )
28}
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index 590289f94..d91549ca7 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -267,10 +267,6 @@ pub fn interrupt_take(item: TokenStream) -> TokenStream {
267#[path = "chip/nrf.rs"] 267#[path = "chip/nrf.rs"]
268mod chip; 268mod chip;
269 269
270#[cfg(feature = "stm32")]
271#[path = "chip/stm32.rs"]
272mod chip;
273
274#[cfg(feature = "rp")] 270#[cfg(feature = "rp")]
275#[path = "chip/rp.rs"] 271#[path = "chip/rp.rs"]
276mod chip; 272mod chip;
@@ -284,7 +280,7 @@ struct MainArgs {
284 config: Option<syn::LitStr>, 280 config: Option<syn::LitStr>,
285} 281}
286 282
287#[cfg(any(feature = "nrf", feature = "stm32", feature = "rp"))] 283#[cfg(any(feature = "nrf", feature = "rp"))]
288#[proc_macro_attribute] 284#[proc_macro_attribute]
289pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { 285pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
290 let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs); 286 let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs);
diff --git a/embassy-stm32-examples/.cargo/config.toml b/embassy-stm32-examples/.cargo/config.toml
deleted file mode 100644
index 3ccca879d..000000000
--- a/embassy-stm32-examples/.cargo/config.toml
+++ /dev/null
@@ -1,28 +0,0 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2runner = "probe-run --chip STM32F401CCUx"
3
4rustflags = [
5 # LLD (shipped with the Rust toolchain) is used as the default linker
6 "-C", "link-arg=--nmagic",
7 "-C", "link-arg=-Tlink.x",
8 "-C", "link-arg=-Tdefmt.x",
9
10 # if you run into problems with LLD switch to the GNU linker by commenting out
11 # this line
12 # "-C", "linker=arm-none-eabi-ld",
13
14 # if you need to link to pre-compiled C libraries provided by a C toolchain
15 # use GCC as the linker by commenting out both lines above and then
16 # uncommenting the three lines below
17 # "-C", "linker=arm-none-eabi-gcc",
18 # "-C", "link-arg=-Wl,-Tlink.x",
19 # "-C", "link-arg=-nostartfiles",
20
21 # Code-size optimizations.
22 "-Z", "trap-unreachable=no",
23 "-C", "inline-threshold=5",
24 "-C", "no-vectorize-loops",
25]
26
27[build]
28target = "thumbv7em-none-eabi"
diff --git a/embassy-stm32-examples/Cargo.toml b/embassy-stm32-examples/Cargo.toml
deleted file mode 100644
index bdb1ca84a..000000000
--- a/embassy-stm32-examples/Cargo.toml
+++ /dev/null
@@ -1,53 +0,0 @@
1[package]
2authors = ["Dario Nieuwenhuis <[email protected]>"]
3edition = "2018"
4name = "embassy-stm32f4-examples"
5version = "0.1.0"
6
7[features]
8default = [
9 "defmt-default",
10]
11defmt-default = []
12defmt-trace = []
13defmt-debug = []
14defmt-info = []
15defmt-warn = []
16defmt-error = []
17
18stm32f401 = ["embassy-stm32/stm32f401"]
19stm32f405 = ["embassy-stm32/stm32f405"]
20stm32f407 = ["embassy-stm32/stm32f407"]
21stm32f410 = ["embassy-stm32/stm32f410"]
22stm32f411 = ["embassy-stm32/stm32f411"]
23stm32f412 = ["embassy-stm32/stm32f412"]
24stm32f413 = ["embassy-stm32/stm32f413"]
25stm32f415 = ["embassy-stm32/stm32f405"]
26stm32f417 = ["embassy-stm32/stm32f407"]
27stm32f423 = ["embassy-stm32/stm32f413"]
28stm32f427 = ["embassy-stm32/stm32f427"]
29stm32f429 = ["embassy-stm32/stm32f429"]
30stm32f437 = ["embassy-stm32/stm32f427"]
31stm32f439 = ["embassy-stm32/stm32f429"]
32stm32f446 = ["embassy-stm32/stm32f446"]
33stm32f469 = ["embassy-stm32/stm32f469"]
34stm32f479 = ["embassy-stm32/stm32f469"]
35
36
37[dependencies]
38embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] }
39embassy-traits = { version = "0.1.0", path = "../embassy-traits", features = ["defmt"] }
40embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" }
41embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
42
43defmt = "0.2.0"
44defmt-rtt = "0.2.0"
45
46cortex-m = "0.7.1"
47cortex-m-rt = "0.6.13"
48embedded-hal = { version = "0.2.4" }
49panic-probe = { version = "0.2.0", features = ["print-defmt"] }
50futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
51rtt-target = { version = "0.3", features = ["cortex-m"] }
52bxcan = "0.5.0"
53usb-device = "0.2.7"
diff --git a/embassy-stm32-examples/build.rs b/embassy-stm32-examples/build.rs
deleted file mode 100644
index d534cc3df..000000000
--- a/embassy-stm32-examples/build.rs
+++ /dev/null
@@ -1,31 +0,0 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31}
diff --git a/embassy-stm32-examples/memory.x b/embassy-stm32-examples/memory.x
deleted file mode 100644
index efa700b8a..000000000
--- a/embassy-stm32-examples/memory.x
+++ /dev/null
@@ -1,5 +0,0 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x08000000, LENGTH = 64K
4 RAM : ORIGIN = 0x20000000, LENGTH = 32K
5}
diff --git a/embassy-stm32-examples/src/bin/can.rs b/embassy-stm32-examples/src/bin/can.rs
deleted file mode 100644
index 72272212e..000000000
--- a/embassy-stm32-examples/src/bin/can.rs
+++ /dev/null
@@ -1,57 +0,0 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(type_alias_impl_trait)]
5#![feature(min_type_alias_impl_trait)]
6#![feature(impl_trait_in_bindings)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use example_common::{panic, *};
11
12use bxcan::filter::Mask32;
13use cortex_m_rt::entry;
14use embassy::executor::Executor;
15use embassy::util::Forever;
16use embassy_stm32::hal::prelude::*;
17use embassy_stm32::hal::{can::Can, stm32};
18use embassy_stm32::{can, interrupt};
19
20#[embassy::task]
21async fn run(dp: stm32::Peripherals, _cp: cortex_m::Peripherals) {
22 let gpioa = dp.GPIOA.split();
23
24 let rx = gpioa.pa11.into_alternate_af9();
25 let tx = gpioa.pa12.into_alternate_af9();
26 let mut can = bxcan::Can::new(Can::new(dp.CAN1, (tx, rx)));
27
28 // APB1 (PCLK1): 24MHz, Bit rate: 20kBit/s, Sample Point 87.5%
29 // Value was calculated with http://www.bittiming.can-wiki.info/
30 can.modify_config().set_bit_timing(0x001c_004a);
31 // Configure filters so that can frames can be received.
32 can.modify_filters().enable_bank(0, Mask32::accept_all());
33
34 let mut can = can::Can::new(can, interrupt::take!(CAN1_TX), interrupt::take!(CAN1_RX0));
35
36 let _frame = can.receive().await;
37}
38
39static EXECUTOR: Forever<Executor> = Forever::new();
40
41#[entry]
42fn main() -> ! {
43 let dp = stm32::Peripherals::take().unwrap();
44 let cp = cortex_m::peripheral::Peripherals::take().unwrap();
45
46 dp.DBGMCU.cr.modify(|_, w| {
47 w.dbg_sleep().set_bit();
48 w.dbg_standby().set_bit();
49 w.dbg_stop().set_bit()
50 });
51 dp.RCC.ahb1enr.modify(|_, w| w.dma1en().enabled());
52
53 let executor = EXECUTOR.put(Executor::new());
54 executor.run(|spawner| {
55 unwrap!(spawner.spawn(run(dp, cp)));
56 });
57}
diff --git a/embassy-stm32-examples/src/bin/exti.rs b/embassy-stm32-examples/src/bin/exti.rs
deleted file mode 100644
index e13b23bac..000000000
--- a/embassy-stm32-examples/src/bin/exti.rs
+++ /dev/null
@@ -1,57 +0,0 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(min_type_alias_impl_trait)]
5#![feature(impl_trait_in_bindings)]
6#![feature(type_alias_impl_trait)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use example_common::{panic, *};
11
12use cortex_m_rt::entry;
13use embassy::executor::Executor;
14use embassy::traits::gpio::*;
15use embassy::util::Forever;
16use embassy_stm32::exti::ExtiPin;
17use embassy_stm32::hal::prelude::*;
18use embassy_stm32::interrupt;
19use embassy_stm32::pac as stm32;
20use futures::pin_mut;
21
22#[embassy::task]
23async fn run(dp: stm32::Peripherals, _cp: cortex_m::Peripherals) {
24 let gpioa = dp.GPIOA.split();
25
26 let button = gpioa.pa0.into_pull_up_input();
27 let mut syscfg = dp.SYSCFG.constrain();
28
29 let mut pin = ExtiPin::new(button, interrupt::take!(EXTI0), &mut syscfg);
30
31 info!("Starting loop");
32
33 loop {
34 pin.wait_for_rising_edge().await;
35 info!("edge detected!");
36 }
37}
38
39static EXECUTOR: Forever<Executor> = Forever::new();
40
41#[entry]
42fn main() -> ! {
43 let dp = stm32::Peripherals::take().unwrap();
44 let cp = cortex_m::peripheral::Peripherals::take().unwrap();
45
46 dp.DBGMCU.cr.modify(|_, w| {
47 w.dbg_sleep().set_bit();
48 w.dbg_standby().set_bit();
49 w.dbg_stop().set_bit()
50 });
51 dp.RCC.ahb1enr.modify(|_, w| w.dma1en().enabled());
52
53 let executor = EXECUTOR.put(Executor::new());
54 executor.run(|spawner| {
55 unwrap!(spawner.spawn(run(dp, cp)));
56 });
57}
diff --git a/embassy-stm32-examples/src/bin/hello.rs b/embassy-stm32-examples/src/bin/hello.rs
deleted file mode 100644
index b851482d4..000000000
--- a/embassy-stm32-examples/src/bin/hello.rs
+++ /dev/null
@@ -1,42 +0,0 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(min_type_alias_impl_trait)]
5#![feature(impl_trait_in_bindings)]
6#![feature(type_alias_impl_trait)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use example_common::*;
11
12use cortex_m_rt::entry;
13use embassy_stm32::hal::prelude::*;
14
15#[entry]
16fn main() -> ! {
17 info!("Hello World!");
18
19 let p = embassy_stm32::pac::Peripherals::take().unwrap();
20
21 p.DBGMCU.cr.modify(|_, w| {
22 w.dbg_sleep().set_bit();
23 w.dbg_standby().set_bit();
24 w.dbg_stop().set_bit()
25 });
26 p.RCC.ahb1enr.modify(|_, w| w.dma1en().enabled());
27
28 let gpioa = p.GPIOA.split();
29 let gpioc = p.GPIOC.split();
30
31 let mut led = gpioc.pc13.into_push_pull_output();
32 let button = gpioa.pa0.into_pull_up_input();
33 led.set_low().unwrap();
34
35 loop {
36 if button.is_high().unwrap() {
37 led.set_low().unwrap();
38 } else {
39 led.set_high().unwrap();
40 }
41 }
42}
diff --git a/embassy-stm32-examples/src/bin/rtc_async.rs b/embassy-stm32-examples/src/bin/rtc_async.rs
deleted file mode 100644
index b780c3c10..000000000
--- a/embassy-stm32-examples/src/bin/rtc_async.rs
+++ /dev/null
@@ -1,40 +0,0 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6
7#[path = "../example_common.rs"]
8mod example_common;
9use example_common::*;
10
11use defmt::panic;
12use embassy;
13
14use embassy::executor::Spawner;
15use embassy::time::{Duration, Timer};
16use embassy_stm32;
17use embassy_stm32::hal;
18
19#[embassy::task]
20async fn run1() {
21 loop {
22 info!("BIG INFREQUENT TICK");
23 Timer::after(Duration::from_ticks(32768 * 2 as u64)).await;
24 }
25}
26
27#[embassy::task]
28async fn run2() {
29 loop {
30 info!("tick");
31 Timer::after(Duration::from_ticks(13000 as u64)).await;
32 }
33}
34
35#[embassy::main(config = "embassy_stm32::system::Config::new().use_hse(16)")]
36async fn main(spawner: Spawner) {
37 let (dp, clocks) = embassy_stm32::Peripherals::take().unwrap();
38
39 spawner.spawn(run1()).unwrap();
40}
diff --git a/embassy-stm32-examples/src/bin/serial.rs b/embassy-stm32-examples/src/bin/serial.rs
deleted file mode 100644
index c48ba746b..000000000
--- a/embassy-stm32-examples/src/bin/serial.rs
+++ /dev/null
@@ -1,80 +0,0 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(min_type_alias_impl_trait)]
5#![feature(impl_trait_in_bindings)]
6#![feature(type_alias_impl_trait)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use example_common::{panic, *};
11
12use cortex_m::singleton;
13use cortex_m_rt::entry;
14use embassy::executor::{Executor, Spawner};
15use embassy::traits::uart::{Read, ReadUntilIdle, Write};
16use embassy::util::Forever;
17use embassy_stm32::hal::dma::StreamsTuple;
18use embassy_stm32::hal::prelude::*;
19use embassy_stm32::hal::serial::config::Config;
20use embassy_stm32::interrupt;
21use embassy_stm32::pac as stm32;
22use embassy_stm32::serial;
23use futures::pin_mut;
24
25#[embassy::main(config = "embassy_stm32::system::Config::new().use_hse(16).sysclk(48).pclk1(24)")]
26async fn main(spawner: Spawner) {
27 let (dp, clocks) = embassy_stm32::Peripherals::take().unwrap();
28 let cp = cortex_m::peripheral::Peripherals::take().unwrap();
29
30 dp.DBGMCU.cr.modify(|_, w| {
31 w.dbg_sleep().set_bit();
32 w.dbg_standby().set_bit();
33 w.dbg_stop().set_bit()
34 });
35
36 // https://gist.github.com/thalesfragoso/a07340c5df6eee3b04c42fdc69ecdcb1
37 let gpioa = dp.GPIOA.split();
38 let streams = StreamsTuple::new(dp.DMA2);
39
40 let _serial = unsafe {
41 serial::Serial::new(
42 dp.USART1,
43 (streams.7, streams.2),
44 (
45 gpioa.pa9.into_alternate_af7(),
46 gpioa.pa10.into_alternate_af7(),
47 ),
48 interrupt::take!(DMA2_STREAM7),
49 interrupt::take!(DMA2_STREAM2),
50 interrupt::take!(USART1),
51 Config::default().baudrate(9600.bps()),
52 clocks,
53 )
54 };
55
56 let streams = StreamsTuple::new(dp.DMA1);
57
58 let mut serial = unsafe {
59 serial::Serial::new(
60 dp.USART2,
61 (streams.6, streams.5),
62 (
63 gpioa.pa2.into_alternate_af7(),
64 gpioa.pa3.into_alternate_af7(),
65 ),
66 interrupt::take!(DMA1_STREAM6),
67 interrupt::take!(DMA1_STREAM5),
68 interrupt::take!(USART2),
69 Config::default().baudrate(9600.bps()),
70 clocks,
71 )
72 };
73 pin_mut!(serial);
74
75 let buf = singleton!(: [u8; 30] = [0; 30]).unwrap();
76
77 buf[5] = 0x01;
78 serial.as_mut().write(buf).await.unwrap();
79 serial.as_mut().read_until_idle(buf).await.unwrap();
80}
diff --git a/embassy-stm32-examples/src/bin/usb_serial.rs b/embassy-stm32-examples/src/bin/usb_serial.rs
deleted file mode 100644
index 38656b979..000000000
--- a/embassy-stm32-examples/src/bin/usb_serial.rs
+++ /dev/null
@@ -1,119 +0,0 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4#![feature(min_type_alias_impl_trait)]
5#![feature(impl_trait_in_bindings)]
6
7#[path = "../example_common.rs"]
8mod example_common;
9use example_common::*;
10
11use cortex_m_rt::entry;
12use defmt::panic;
13use embassy::executor::{Executor, Spawner};
14use embassy::interrupt::InterruptExt;
15use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
16use embassy::time::{Duration, Timer};
17use embassy::util::Forever;
18use embassy_extras::usb::usb_serial::UsbSerial;
19use embassy_extras::usb::Usb;
20use embassy_stm32::hal::otg_fs::{UsbBus, USB};
21use embassy_stm32::hal::prelude::*;
22use embassy_stm32::{interrupt, pac, rtc};
23use futures::future::{select, Either};
24use futures::pin_mut;
25use usb_device::bus::UsbBusAllocator;
26use usb_device::prelude::*;
27
28#[embassy::task]
29async fn run1(bus: &'static mut UsbBusAllocator<UsbBus<USB>>) {
30 info!("Async task");
31
32 let mut read_buf = [0u8; 128];
33 let mut write_buf = [0u8; 128];
34 let serial = UsbSerial::new(bus, &mut read_buf, &mut write_buf);
35
36 let device = UsbDeviceBuilder::new(bus, UsbVidPid(0x16c0, 0x27dd))
37 .manufacturer("Fake company")
38 .product("Serial port")
39 .serial_number("TEST")
40 .device_class(0x02)
41 .build();
42
43 let irq = interrupt::take!(OTG_FS);
44 irq.set_priority(interrupt::Priority::P3);
45
46 let usb = Usb::new(device, serial, irq);
47 pin_mut!(usb);
48 usb.as_mut().start();
49
50 let (mut read_interface, mut write_interface) = usb.as_ref().take_serial_0();
51
52 let mut buf = [0u8; 64];
53 loop {
54 let mut n = 0;
55 let left = {
56 let recv_fut = async {
57 loop {
58 let byte = unwrap!(read_interface.read_byte().await);
59 unwrap!(write_interface.write_byte(byte).await);
60 buf[n] = byte;
61
62 n += 1;
63 if byte == b'\n' || byte == b'\r' || n == buf.len() {
64 break;
65 }
66 }
67 };
68 pin_mut!(recv_fut);
69
70 let timeout = Timer::after(Duration::from_ticks(32768 * 10));
71
72 match select(recv_fut, timeout).await {
73 Either::Left(_) => true,
74 Either::Right(_) => false,
75 }
76 };
77
78 if left {
79 for c in buf[..n].iter_mut() {
80 if 0x61 <= *c && *c <= 0x7a {
81 *c &= !0x20;
82 }
83 }
84 unwrap!(write_interface.write_byte(b'\n').await);
85 unwrap!(write_interface.write_all(&buf[..n]).await);
86 unwrap!(write_interface.write_byte(b'\n').await);
87 } else {
88 unwrap!(write_interface.write_all(b"\r\nSend something\r\n").await);
89 }
90 }
91}
92
93static USB_BUS: Forever<UsbBusAllocator<UsbBus<USB>>> = Forever::new();
94
95#[embassy::main(
96 config = "embassy_stm32::system::Config::new().use_hse(25).sysclk(48).require_pll48clk()"
97)]
98async fn main(spawner: Spawner) -> ! {
99 static mut EP_MEMORY: [u32; 1024] = [0; 1024];
100
101 info!("Hello World!");
102
103 let (p, clocks) = embassy_stm32::Peripherals::take().unwrap();
104
105 let gpioa = p.GPIOA.split();
106 let usb = USB {
107 usb_global: p.OTG_FS_GLOBAL,
108 usb_device: p.OTG_FS_DEVICE,
109 usb_pwrclk: p.OTG_FS_PWRCLK,
110 pin_dm: gpioa.pa11.into_alternate_af10(),
111 pin_dp: gpioa.pa12.into_alternate_af10(),
112 hclk: clocks.hclk(),
113 };
114 // Rust analyzer isn't recognizing the static ref magic `cortex-m` does
115 #[allow(unused_unsafe)]
116 let usb_bus = USB_BUS.put(UsbBus::new(usb, unsafe { &mut EP_MEMORY }));
117
118 spawner.spawn(run1(usb_bus)).unwrap();
119}
diff --git a/embassy-stm32-examples/src/example_common.rs b/embassy-stm32-examples/src/example_common.rs
deleted file mode 100644
index 54d633837..000000000
--- a/embassy-stm32-examples/src/example_common.rs
+++ /dev/null
@@ -1,17 +0,0 @@
1#![macro_use]
2
3use defmt_rtt as _; // global logger
4use panic_probe as _;
5
6pub use defmt::*;
7
8use core::sync::atomic::{AtomicUsize, Ordering};
9
10defmt::timestamp! {"{=u64}", {
11 static COUNT: AtomicUsize = AtomicUsize::new(0);
12 // NOTE(no-CAS) `timestamps` runs with interrupts disabled
13 let n = COUNT.load(Ordering::Relaxed);
14 COUNT.store(n + 1, Ordering::Relaxed);
15 n as u64
16 }
17}
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
deleted file mode 100644
index 1eeb2d21d..000000000
--- a/embassy-stm32/Cargo.toml
+++ /dev/null
@@ -1,53 +0,0 @@
1[package]
2name = "embassy-stm32"
3version = "0.1.0"
4authors = ["Dario Nieuwenhuis <[email protected]>"]
5edition = "2018"
6
7[features]
8defmt-trace = [ ]
9defmt-debug = [ ]
10defmt-info = [ ]
11defmt-warn = [ ]
12defmt-error = [ ]
13
14stm32f401 = ["stm32f4xx-hal/stm32f401"]
15stm32f405 = ["stm32f4xx-hal/stm32f405"]
16stm32f407 = ["stm32f4xx-hal/stm32f407"]
17stm32f410 = ["stm32f4xx-hal/stm32f410"]
18stm32f411 = ["stm32f4xx-hal/stm32f411"]
19stm32f412 = ["stm32f4xx-hal/stm32f412"]
20stm32f413 = ["stm32f4xx-hal/stm32f413"]
21stm32f415 = ["stm32f4xx-hal/stm32f405"]
22stm32f417 = ["stm32f4xx-hal/stm32f407"]
23stm32f423 = ["stm32f4xx-hal/stm32f413"]
24stm32f427 = ["stm32f4xx-hal/stm32f427"]
25stm32f429 = ["stm32f4xx-hal/stm32f429"]
26stm32f437 = ["stm32f4xx-hal/stm32f427"]
27stm32f439 = ["stm32f4xx-hal/stm32f429"]
28stm32f446 = ["stm32f4xx-hal/stm32f446"]
29stm32f469 = ["stm32f4xx-hal/stm32f469"]
30stm32f479 = ["stm32f4xx-hal/stm32f469"]
31
32stm32l0x1 = ["stm32l0xx-hal/stm32l0x1"]
33stm32l0x2 = ["stm32l0xx-hal/stm32l0x2"]
34stm32l0x3 = ["stm32l0xx-hal/stm32l0x3"]
35
36[dependencies]
37embassy = { version = "0.1.0", path = "../embassy" }
38embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"]}
39embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
40
41atomic-polyfill = "0.1.1"
42critical-section = "0.2.1"
43defmt = { version = "0.2.0", optional = true }
44log = { version = "0.4.11", optional = true }
45cortex-m-rt = "0.6.13"
46cortex-m = "0.7.1"
47embedded-hal = { version = "0.2.4" }
48embedded-dma = { version = "0.1.2" }
49bxcan = "0.5.0"
50nb = "*"
51stm32f4xx-hal = { version = "0.9.0", features = ["rt", "can", "usb_fs"], optional = true }
52stm32l0xx-hal = { version = "0.7.0", features = ["rt"], optional = true }
53futures = { version = "0.3.5", default-features = false, features = ["async-await"] }
diff --git a/embassy-stm32/src/can.rs b/embassy-stm32/src/can.rs
deleted file mode 100644
index f97e900ea..000000000
--- a/embassy-stm32/src/can.rs
+++ /dev/null
@@ -1,120 +0,0 @@
1//! Async low power Serial.
2//!
3//! The peripheral is autmatically enabled and disabled as required to save power.
4//! Lowest power consumption can only be guaranteed if the send receive futures
5//! are dropped correctly (e.g. not using `mem::forget()`).
6
7use bxcan;
8use bxcan::Interrupts;
9use core::future::Future;
10use embassy::interrupt::Interrupt;
11use embassy::util::InterruptFuture;
12use nb;
13use nb::block;
14
15use crate::interrupt;
16
17/// Interface to the Serial peripheral
18pub struct Can<T: Instance> {
19 can: bxcan::Can<T>,
20 tx_int: T::TInterrupt,
21 rx_int: T::RInterrupt,
22}
23
24impl<T: Instance> Can<T> {
25 pub fn new(mut can: bxcan::Can<T>, tx_int: T::TInterrupt, rx_int: T::RInterrupt) -> Self {
26 // Sync to the bus and start normal operation.
27 can.enable_interrupts(
28 Interrupts::TRANSMIT_MAILBOX_EMPTY | Interrupts::FIFO0_MESSAGE_PENDING,
29 );
30 block!(can.enable()).unwrap();
31
32 Can {
33 can: can,
34 tx_int: tx_int,
35 rx_int: rx_int,
36 }
37 }
38
39 /// Sends can frame.
40 ///
41 /// This method async-blocks until the frame is transmitted.
42 pub fn transmit<'a>(&'a mut self, frame: &'a bxcan::Frame) -> impl Future<Output = ()> + 'a {
43 async move {
44 let fut = InterruptFuture::new(&mut self.tx_int);
45 // Infallible
46 self.can.transmit(frame).unwrap();
47
48 fut.await;
49 }
50 }
51
52 /// Receive can frame.
53 ///
54 /// This method async-blocks until the frame is received.
55 pub fn receive<'a>(&'a mut self) -> impl Future<Output = bxcan::Frame> + 'a {
56 async move {
57 let mut frame: Option<bxcan::Frame>;
58
59 loop {
60 let fut = InterruptFuture::new(&mut self.rx_int);
61 frame = match self.can.receive() {
62 Ok(frame) => Some(frame),
63 Err(nb::Error::WouldBlock) => None,
64 Err(nb::Error::Other(_)) => None, // Ignore overrun errors.
65 };
66 if frame.is_some() {
67 break;
68 }
69 fut.await;
70 }
71
72 frame.unwrap()
73 }
74 }
75}
76
77mod private {
78 pub trait Sealed {}
79}
80
81pub trait Instance: bxcan::Instance + private::Sealed {
82 type TInterrupt: Interrupt;
83 type RInterrupt: Interrupt;
84}
85
86macro_rules! can {
87 ($($can:ident => ($tint:ident, $rint:ident),)+) => {
88 $(
89 impl private::Sealed for crate::hal::can::Can<crate::pac::$can> {}
90 impl Instance for crate::hal::can::Can<crate::pac::$can> {
91 type TInterrupt = interrupt::$tint;
92 type RInterrupt = interrupt::$rint;
93 }
94 )+
95 }
96}
97
98#[cfg(any(
99 feature = "stm32f401",
100 feature = "stm32f405",
101 feature = "stm32f407",
102 feature = "stm32f410",
103 feature = "stm32f411",
104 feature = "stm32f412",
105 feature = "stm32f413",
106 feature = "stm32f415",
107 feature = "stm32f417",
108 feature = "stm32f423",
109 feature = "stm32f427",
110 feature = "stm32f429",
111 feature = "stm32f437",
112 feature = "stm32f439",
113 feature = "stm32f446",
114 feature = "stm32f469",
115 feature = "stm32f479",
116))]
117can! {
118 CAN1 => (CAN1_TX, CAN1_RX0),
119 CAN2 => (CAN2_TX, CAN2_RX0),
120}
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
deleted file mode 100644
index 3d83c2d53..000000000
--- a/embassy-stm32/src/exti.rs
+++ /dev/null
@@ -1,790 +0,0 @@
1use core::future::Future;
2use core::mem;
3use cortex_m;
4
5use crate::hal::gpio;
6
7#[cfg(any(
8 feature = "stm32f401",
9 feature = "stm32f405",
10 feature = "stm32f407",
11 feature = "stm32f410",
12 feature = "stm32f411",
13 feature = "stm32f412",
14 feature = "stm32f413",
15 feature = "stm32f415",
16 feature = "stm32f417",
17 feature = "stm32f423",
18 feature = "stm32f427",
19 feature = "stm32f429",
20 feature = "stm32f437",
21 feature = "stm32f439",
22 feature = "stm32f446",
23 feature = "stm32f469",
24 feature = "stm32f479",
25))]
26use crate::hal::syscfg::SysCfg;
27
28#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
29use crate::hal::syscfg::SYSCFG as SysCfg;
30
31use embassy::traits::gpio::{
32 WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge,
33};
34use embassy::util::InterruptFuture;
35
36use embedded_hal::digital::v2 as digital;
37
38use crate::interrupt;
39
40pub struct ExtiPin<T: Instance> {
41 pin: T,
42 interrupt: T::Interrupt,
43}
44
45impl<T: Instance> ExtiPin<T> {
46 pub fn new(mut pin: T, interrupt: T::Interrupt, syscfg: &mut SysCfg) -> Self {
47 critical_section::with(|_| {
48 pin.make_source(syscfg);
49 });
50
51 Self { pin, interrupt }
52 }
53}
54
55impl<T: Instance + digital::OutputPin> digital::OutputPin for ExtiPin<T> {
56 type Error = T::Error;
57
58 fn set_low(&mut self) -> Result<(), Self::Error> {
59 self.pin.set_low()
60 }
61
62 fn set_high(&mut self) -> Result<(), Self::Error> {
63 self.pin.set_high()
64 }
65}
66
67impl<T: Instance + digital::StatefulOutputPin> digital::StatefulOutputPin for ExtiPin<T> {
68 fn is_set_low(&self) -> Result<bool, Self::Error> {
69 self.pin.is_set_low()
70 }
71
72 fn is_set_high(&self) -> Result<bool, Self::Error> {
73 self.pin.is_set_high()
74 }
75}
76
77impl<T: Instance + digital::ToggleableOutputPin> digital::ToggleableOutputPin for ExtiPin<T> {
78 type Error = T::Error;
79
80 fn toggle(&mut self) -> Result<(), Self::Error> {
81 self.pin.toggle()
82 }
83}
84
85impl<T: Instance + digital::InputPin> digital::InputPin for ExtiPin<T> {
86 type Error = T::Error;
87
88 fn is_high(&self) -> Result<bool, Self::Error> {
89 self.pin.is_high()
90 }
91
92 fn is_low(&self) -> Result<bool, Self::Error> {
93 self.pin.is_low()
94 }
95}
96
97impl<T: Instance + digital::InputPin + 'static> ExtiPin<T> {
98 fn wait_for_state<'a>(&'a mut self, state: bool) -> impl Future<Output = ()> + 'a {
99 async move {
100 let fut = InterruptFuture::new(&mut self.interrupt);
101 let pin = &mut self.pin;
102 critical_section::with(|_| {
103 pin.trigger_edge(if state {
104 EdgeOption::Rising
105 } else {
106 EdgeOption::Falling
107 });
108 });
109
110 if (state && self.pin.is_high().unwrap_or(false))
111 || (!state && self.pin.is_low().unwrap_or(false))
112 {
113 return;
114 }
115
116 fut.await;
117
118 self.pin.clear_pending_bit();
119 }
120 }
121}
122
123impl<T: Instance + 'static> ExtiPin<T> {
124 fn wait_for_edge<'a>(&'a mut self, state: EdgeOption) -> impl Future<Output = ()> + 'a {
125 self.pin.clear_pending_bit();
126 async move {
127 let fut = InterruptFuture::new(&mut self.interrupt);
128 let pin = &mut self.pin;
129 critical_section::with(|_| {
130 pin.trigger_edge(state);
131 });
132
133 fut.await;
134
135 self.pin.clear_pending_bit();
136 }
137 }
138}
139
140impl<T: Instance + digital::InputPin + 'static> WaitForHigh for ExtiPin<T> {
141 type Future<'a> = impl Future<Output = ()> + 'a;
142
143 fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
144 self.wait_for_state(true)
145 }
146}
147
148impl<T: Instance + digital::InputPin + 'static> WaitForLow for ExtiPin<T> {
149 type Future<'a> = impl Future<Output = ()> + 'a;
150
151 fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
152 self.wait_for_state(false)
153 }
154}
155
156/*
157 Irq Handler Description
158 EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0
159 EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1
160 EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2
161 EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3
162 EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4
163 EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9
164 EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15
165*/
166
167impl<T: Instance + 'static> WaitForRisingEdge for ExtiPin<T> {
168 type Future<'a> = impl Future<Output = ()> + 'a;
169
170 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> {
171 self.wait_for_edge(EdgeOption::Rising)
172 }
173}
174
175impl<T: Instance + 'static> WaitForFallingEdge for ExtiPin<T> {
176 type Future<'a> = impl Future<Output = ()> + 'a;
177
178 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> {
179 self.wait_for_edge(EdgeOption::Falling)
180 }
181}
182
183impl<T: Instance + 'static> WaitForAnyEdge for ExtiPin<T> {
184 type Future<'a> = impl Future<Output = ()> + 'a;
185
186 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
187 self.wait_for_edge(EdgeOption::RisingFalling)
188 }
189}
190
191mod private {
192 pub trait Sealed {}
193}
194
195#[derive(Copy, Clone)]
196pub enum EdgeOption {
197 Rising,
198 Falling,
199 RisingFalling,
200}
201
202pub trait WithInterrupt: private::Sealed {
203 type Interrupt: interrupt::Interrupt;
204}
205
206pub trait Instance: WithInterrupt {
207 fn make_source(&mut self, syscfg: &mut SysCfg);
208 fn clear_pending_bit(&mut self);
209 fn trigger_edge(&mut self, edge: EdgeOption);
210}
211
212macro_rules! exti {
213 ($set:ident, [
214 $($INT:ident => $pin:ident,)+
215 ]) => {
216 $(
217 impl<T> private::Sealed for gpio::$set::$pin<T> {}
218 impl<T> WithInterrupt for gpio::$set::$pin<T> {
219 type Interrupt = interrupt::$INT;
220 }
221
222 #[cfg(any(
223 feature = "stm32f401",
224 feature = "stm32f405",
225 feature = "stm32f407",
226 feature = "stm32f410",
227 feature = "stm32f411",
228 feature = "stm32f412",
229 feature = "stm32f413",
230 feature = "stm32f415",
231 feature = "stm32f417",
232 feature = "stm32f423",
233 feature = "stm32f427",
234 feature = "stm32f429",
235 feature = "stm32f437",
236 feature = "stm32f439",
237 feature = "stm32f446",
238 feature = "stm32f469",
239 feature = "stm32f479",
240 ))]
241 impl<T> Instance for gpio::$set::$pin<gpio::Input<T>> {
242 fn make_source(&mut self, syscfg: &mut SysCfg) {
243 use crate::hal::gpio::ExtiPin;
244 self.make_interrupt_source(syscfg);
245 }
246
247 fn clear_pending_bit(&mut self) {
248 use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg};
249
250 self.clear_interrupt_pending_bit();
251 }
252
253 fn trigger_edge(&mut self, edge: EdgeOption) {
254 use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg};
255 use crate::pac::EXTI;
256 let mut exti: EXTI = unsafe { mem::transmute(()) };
257 let edge = match edge {
258 EdgeOption::Falling => Edge::FALLING,
259 EdgeOption::Rising => Edge::RISING,
260 EdgeOption::RisingFalling => Edge::RISING_FALLING,
261 };
262 self.trigger_on_edge(&mut exti, edge);
263 self.enable_interrupt(&mut exti);
264 }
265 }
266
267 #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
268 impl<T> Instance for gpio::$set::$pin<T> {
269 fn make_source(&mut self, syscfg: &mut SysCfg) {}
270
271 fn clear_pending_bit(&mut self) {
272 use crate::hal::{
273 exti::{Exti, ExtiLine, GpioLine, TriggerEdge},
274 syscfg::SYSCFG,
275 };
276
277 Exti::unpend(GpioLine::from_raw_line(self.pin_number()).unwrap());
278 }
279
280 fn trigger_edge(&mut self, edge: EdgeOption) {
281 use crate::hal::{
282 exti::{Exti, ExtiLine, GpioLine, TriggerEdge},
283 syscfg::SYSCFG,
284 };
285
286 use crate::pac::EXTI;
287
288 let edge = match edge {
289 EdgeOption::Falling => TriggerEdge::Falling,
290 EdgeOption::Rising => TriggerEdge::Rising,
291 EdgeOption::RisingFalling => TriggerEdge::Both,
292 };
293
294 let exti: EXTI = unsafe { mem::transmute(()) };
295 let mut exti = Exti::new(exti);
296 let port = self.port();
297 let mut syscfg: SYSCFG = unsafe { mem::transmute(()) };
298 let line = GpioLine::from_raw_line(self.pin_number()).unwrap();
299 exti.listen_gpio(&mut syscfg, port, line, edge);
300 }
301 }
302 )+
303 };
304}
305
306#[cfg(any(
307 feature = "stm32f401",
308 feature = "stm32f405",
309 feature = "stm32f407",
310 feature = "stm32f410",
311 feature = "stm32f411",
312 feature = "stm32f412",
313 feature = "stm32f413",
314 feature = "stm32f415",
315 feature = "stm32f417",
316 feature = "stm32f423",
317 feature = "stm32f427",
318 feature = "stm32f429",
319 feature = "stm32f437",
320 feature = "stm32f439",
321 feature = "stm32f446",
322 feature = "stm32f469",
323 feature = "stm32f479"
324))]
325exti!(gpioa, [
326 EXTI0 => PA0,
327 EXTI1 => PA1,
328 EXTI2 => PA2,
329 EXTI3 => PA3,
330 EXTI4 => PA4,
331 EXTI9_5 => PA5,
332 EXTI9_5 => PA6,
333 EXTI9_5 => PA7,
334 EXTI9_5 => PA8,
335 EXTI9_5 => PA9,
336 EXTI15_10 => PA10,
337 EXTI15_10 => PA11,
338 EXTI15_10 => PA12,
339 EXTI15_10 => PA13,
340 EXTI15_10 => PA14,
341 EXTI15_10 => PA15,
342]);
343
344#[cfg(any(
345 feature = "stm32f401",
346 feature = "stm32f405",
347 feature = "stm32f407",
348 feature = "stm32f410",
349 feature = "stm32f411",
350 feature = "stm32f412",
351 feature = "stm32f413",
352 feature = "stm32f415",
353 feature = "stm32f417",
354 feature = "stm32f423",
355 feature = "stm32f427",
356 feature = "stm32f429",
357 feature = "stm32f437",
358 feature = "stm32f439",
359 feature = "stm32f446",
360 feature = "stm32f469",
361 feature = "stm32f479"
362))]
363exti!(gpiob, [
364 EXTI0 => PB0,
365 EXTI1 => PB1,
366 EXTI2 => PB2,
367 EXTI3 => PB3,
368 EXTI4 => PB4,
369 EXTI9_5 => PB5,
370 EXTI9_5 => PB6,
371 EXTI9_5 => PB7,
372 EXTI9_5 => PB8,
373 EXTI9_5 => PB9,
374 EXTI15_10 => PB10,
375 EXTI15_10 => PB11,
376 EXTI15_10 => PB12,
377 EXTI15_10 => PB13,
378 EXTI15_10 => PB14,
379 EXTI15_10 => PB15,
380]);
381
382#[cfg(any(
383 feature = "stm32f401",
384 feature = "stm32f405",
385 feature = "stm32f407",
386 feature = "stm32f410",
387 feature = "stm32f411",
388 feature = "stm32f412",
389 feature = "stm32f413",
390 feature = "stm32f415",
391 feature = "stm32f417",
392 feature = "stm32f423",
393 feature = "stm32f427",
394 feature = "stm32f429",
395 feature = "stm32f437",
396 feature = "stm32f439",
397 feature = "stm32f446",
398 feature = "stm32f469",
399 feature = "stm32f479"
400))]
401exti!(gpioc, [
402 EXTI0 => PC0,
403 EXTI1 => PC1,
404 EXTI2 => PC2,
405 EXTI3 => PC3,
406 EXTI4 => PC4,
407 EXTI9_5 => PC5,
408 EXTI9_5 => PC6,
409 EXTI9_5 => PC7,
410 EXTI9_5 => PC8,
411 EXTI9_5 => PC9,
412 EXTI15_10 => PC10,
413 EXTI15_10 => PC11,
414 EXTI15_10 => PC12,
415 EXTI15_10 => PC13,
416 EXTI15_10 => PC14,
417 EXTI15_10 => PC15,
418]);
419
420#[cfg(any(
421 feature = "stm32f401",
422 feature = "stm32f405",
423 feature = "stm32f407",
424 feature = "stm32f411",
425 feature = "stm32f412",
426 feature = "stm32f413",
427 feature = "stm32f415",
428 feature = "stm32f417",
429 feature = "stm32f423",
430 feature = "stm32f427",
431 feature = "stm32f429",
432 feature = "stm32f437",
433 feature = "stm32f439",
434 feature = "stm32f446",
435 feature = "stm32f469",
436 feature = "stm32f479"
437))]
438exti!(gpiod, [
439 EXTI0 => PD0,
440 EXTI1 => PD1,
441 EXTI2 => PD2,
442 EXTI3 => PD3,
443 EXTI4 => PD4,
444 EXTI9_5 => PD5,
445 EXTI9_5 => PD6,
446 EXTI9_5 => PD7,
447 EXTI9_5 => PD8,
448 EXTI9_5 => PD9,
449 EXTI15_10 => PD10,
450 EXTI15_10 => PD11,
451 EXTI15_10 => PD12,
452 EXTI15_10 => PD13,
453 EXTI15_10 => PD14,
454 EXTI15_10 => PD15,
455]);
456
457#[cfg(any(
458 feature = "stm32f401",
459 feature = "stm32f405",
460 feature = "stm32f407",
461 feature = "stm32f411",
462 feature = "stm32f412",
463 feature = "stm32f413",
464 feature = "stm32f415",
465 feature = "stm32f417",
466 feature = "stm32f423",
467 feature = "stm32f427",
468 feature = "stm32f429",
469 feature = "stm32f437",
470 feature = "stm32f439",
471 feature = "stm32f446",
472 feature = "stm32f469",
473 feature = "stm32f479"
474))]
475exti!(gpioe, [
476 EXTI0 => PE0,
477 EXTI1 => PE1,
478 EXTI2 => PE2,
479 EXTI3 => PE3,
480 EXTI4 => PE4,
481 EXTI9_5 => PE5,
482 EXTI9_5 => PE6,
483 EXTI9_5 => PE7,
484 EXTI9_5 => PE8,
485 EXTI9_5 => PE9,
486 EXTI15_10 => PE10,
487 EXTI15_10 => PE11,
488 EXTI15_10 => PE12,
489 EXTI15_10 => PE13,
490 EXTI15_10 => PE14,
491 EXTI15_10 => PE15,
492]);
493
494#[cfg(any(
495 feature = "stm32f405",
496 feature = "stm32f407",
497 feature = "stm32f412",
498 feature = "stm32f413",
499 feature = "stm32f415",
500 feature = "stm32f417",
501 feature = "stm32f423",
502 feature = "stm32f427",
503 feature = "stm32f429",
504 feature = "stm32f437",
505 feature = "stm32f439",
506 feature = "stm32f446",
507 feature = "stm32f469",
508 feature = "stm32f479"
509))]
510exti!(gpiof, [
511 EXTI0 => PF0,
512 EXTI1 => PF1,
513 EXTI2 => PF2,
514 EXTI3 => PF3,
515 EXTI4 => PF4,
516 EXTI9_5 => PF5,
517 EXTI9_5 => PF6,
518 EXTI9_5 => PF7,
519 EXTI9_5 => PF8,
520 EXTI9_5 => PF9,
521 EXTI15_10 => PF10,
522 EXTI15_10 => PF11,
523 EXTI15_10 => PF12,
524 EXTI15_10 => PF13,
525 EXTI15_10 => PF14,
526 EXTI15_10 => PF15,
527]);
528
529#[cfg(any(
530 feature = "stm32f405",
531 feature = "stm32f407",
532 feature = "stm32f412",
533 feature = "stm32f413",
534 feature = "stm32f415",
535 feature = "stm32f417",
536 feature = "stm32f423",
537 feature = "stm32f427",
538 feature = "stm32f429",
539 feature = "stm32f437",
540 feature = "stm32f439",
541 feature = "stm32f446",
542 feature = "stm32f469",
543 feature = "stm32f479"
544))]
545exti!(gpiog, [
546 EXTI0 => PG0,
547 EXTI1 => PG1,
548 EXTI2 => PG2,
549 EXTI3 => PG3,
550 EXTI4 => PG4,
551 EXTI9_5 => PG5,
552 EXTI9_5 => PG6,
553 EXTI9_5 => PG7,
554 EXTI9_5 => PG8,
555 EXTI9_5 => PG9,
556 EXTI15_10 => PG10,
557 EXTI15_10 => PG11,
558 EXTI15_10 => PG12,
559 EXTI15_10 => PG13,
560 EXTI15_10 => PG14,
561 EXTI15_10 => PG15,
562]);
563
564#[cfg(any(
565 feature = "stm32f405",
566 feature = "stm32f407",
567 feature = "stm32f410",
568 feature = "stm32f411",
569 feature = "stm32f412",
570 feature = "stm32f413",
571 feature = "stm32f415",
572 feature = "stm32f417",
573 feature = "stm32f423",
574 feature = "stm32f427",
575 feature = "stm32f429",
576 feature = "stm32f437",
577 feature = "stm32f439",
578 feature = "stm32f446",
579 feature = "stm32f469",
580 feature = "stm32f479"
581))]
582exti!(gpioh, [
583 EXTI0 => PH0,
584 EXTI1 => PH1,
585 EXTI2 => PH2,
586 EXTI3 => PH3,
587 EXTI4 => PH4,
588 EXTI9_5 => PH5,
589 EXTI9_5 => PH6,
590 EXTI9_5 => PH7,
591 EXTI9_5 => PH8,
592 EXTI9_5 => PH9,
593 EXTI15_10 => PH10,
594 EXTI15_10 => PH11,
595 EXTI15_10 => PH12,
596 EXTI15_10 => PH13,
597 EXTI15_10 => PH14,
598 EXTI15_10 => PH15,
599]);
600
601#[cfg(any(feature = "stm32f401"))]
602exti!(gpioh, [
603 EXTI0 => PH0,
604 EXTI1 => PH1,
605]);
606
607#[cfg(any(
608 feature = "stm32f405",
609 feature = "stm32f407",
610 feature = "stm32f415",
611 feature = "stm32f417",
612 feature = "stm32f427",
613 feature = "stm32f429",
614 feature = "stm32f437",
615 feature = "stm32f439",
616 feature = "stm32f469",
617 feature = "stm32f479"
618))]
619exti!(gpioi, [
620 EXTI0 => PI0,
621 EXTI1 => PI1,
622 EXTI2 => PI2,
623 EXTI3 => PI3,
624 EXTI4 => PI4,
625 EXTI9_5 => PI5,
626 EXTI9_5 => PI6,
627 EXTI9_5 => PI7,
628 EXTI9_5 => PI8,
629 EXTI9_5 => PI9,
630 EXTI15_10 => PI10,
631 EXTI15_10 => PI11,
632 EXTI15_10 => PI12,
633 EXTI15_10 => PI13,
634 EXTI15_10 => PI14,
635 EXTI15_10 => PI15,
636]);
637
638#[cfg(any(
639 feature = "stm32f427",
640 feature = "stm32f429",
641 feature = "stm32f437",
642 feature = "stm32f439",
643 feature = "stm32f469",
644 feature = "stm32f479"
645))]
646exti!(gpioj, [
647 EXTI0 => PJ0,
648 EXTI1 => PJ1,
649 EXTI2 => PJ2,
650 EXTI3 => PJ3,
651 EXTI4 => PJ4,
652 EXTI9_5 => PJ5,
653 EXTI9_5 => PJ6,
654 EXTI9_5 => PJ7,
655 EXTI9_5 => PJ8,
656 EXTI9_5 => PJ9,
657 EXTI15_10 => PJ10,
658 EXTI15_10 => PJ11,
659 EXTI15_10 => PJ12,
660 EXTI15_10 => PJ13,
661 EXTI15_10 => PJ14,
662 EXTI15_10 => PJ15,
663]);
664
665#[cfg(any(
666 feature = "stm32f427",
667 feature = "stm32f429",
668 feature = "stm32f437",
669 feature = "stm32f439",
670 feature = "stm32f469",
671 feature = "stm32f479"
672))]
673exti!(gpiok, [
674 EXTI0 => PK0,
675 EXTI1 => PK1,
676 EXTI2 => PK2,
677 EXTI3 => PK3,
678 EXTI4 => PK4,
679 EXTI9_5 => PK5,
680 EXTI9_5 => PK6,
681 EXTI9_5 => PK7,
682]);
683
684#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
685exti!(gpioa, [
686 EXTI0_1 => PA0,
687 EXTI0_1 => PA1,
688 EXTI2_3 => PA2,
689 EXTI2_3 => PA3,
690 EXTI4_15 => PA4,
691 EXTI4_15 => PA5,
692 EXTI4_15 => PA6,
693 EXTI4_15 => PA7,
694 EXTI4_15 => PA8,
695 EXTI4_15 => PA9,
696 EXTI4_15 => PA10,
697 EXTI4_15 => PA11,
698 EXTI4_15 => PA12,
699 EXTI4_15 => PA13,
700 EXTI4_15 => PA14,
701 EXTI4_15 => PA15,
702]);
703
704#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
705exti!(gpiob, [
706 EXTI0_1 => PB0,
707 EXTI0_1 => PB1,
708 EXTI2_3 => PB2,
709 EXTI2_3 => PB3,
710 EXTI4_15 => PB4,
711 EXTI4_15 => PB5,
712 EXTI4_15 => PB6,
713 EXTI4_15 => PB7,
714 EXTI4_15 => PB8,
715 EXTI4_15 => PB9,
716 EXTI4_15 => PB10,
717 EXTI4_15 => PB11,
718 EXTI4_15 => PB12,
719 EXTI4_15 => PB13,
720 EXTI4_15 => PB14,
721 EXTI4_15 => PB15,
722]);
723
724#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
725exti!(gpioc, [
726 EXTI0_1 => PC0,
727 EXTI0_1 => PC1,
728 EXTI2_3 => PC2,
729 EXTI2_3 => PC3,
730 EXTI4_15 => PC4,
731 EXTI4_15 => PC5,
732 EXTI4_15 => PC6,
733 EXTI4_15 => PC7,
734 EXTI4_15 => PC8,
735 EXTI4_15 => PC9,
736 EXTI4_15 => PC10,
737 EXTI4_15 => PC11,
738 EXTI4_15 => PC12,
739 EXTI4_15 => PC13,
740 EXTI4_15 => PC14,
741 EXTI4_15 => PC15,
742]);
743
744#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
745exti!(gpiod, [
746 EXTI0_1 => PD0,
747 EXTI0_1 => PD1,
748 EXTI2_3 => PD2,
749 EXTI2_3 => PD3,
750 EXTI4_15 => PD4,
751 EXTI4_15 => PD5,
752 EXTI4_15 => PD6,
753 EXTI4_15 => PD7,
754 EXTI4_15 => PD8,
755 EXTI4_15 => PD9,
756 EXTI4_15 => PD10,
757 EXTI4_15 => PD11,
758 EXTI4_15 => PD12,
759 EXTI4_15 => PD13,
760 EXTI4_15 => PD14,
761 EXTI4_15 => PD15,
762]);
763
764#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
765exti!(gpioe, [
766 EXTI0_1 => PE0,
767 EXTI0_1 => PE1,
768 EXTI2_3 => PE2,
769 EXTI2_3 => PE3,
770 EXTI4_15 => PE4,
771 EXTI4_15 => PE5,
772 EXTI4_15 => PE6,
773 EXTI4_15 => PE7,
774 EXTI4_15 => PE8,
775 EXTI4_15 => PE9,
776 EXTI4_15 => PE10,
777 EXTI4_15 => PE11,
778 EXTI4_15 => PE12,
779 EXTI4_15 => PE13,
780 EXTI4_15 => PE14,
781 EXTI4_15 => PE15,
782]);
783
784#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
785exti!(gpioh, [
786 EXTI0_1 => PH0,
787 EXTI0_1 => PH1,
788 EXTI4_15 => PH9,
789 EXTI4_15 => PH10,
790]);
diff --git a/embassy-stm32/src/f4/mod.rs b/embassy-stm32/src/f4/mod.rs
deleted file mode 100644
index 9549b3ed6..000000000
--- a/embassy-stm32/src/f4/mod.rs
+++ /dev/null
@@ -1,4 +0,0 @@
1pub mod rtc;
2pub mod serial;
3pub mod spi;
4pub mod system;
diff --git a/embassy-stm32/src/f4/rtc.rs b/embassy-stm32/src/f4/rtc.rs
deleted file mode 100644
index df7a82d87..000000000
--- a/embassy-stm32/src/f4/rtc.rs
+++ /dev/null
@@ -1,505 +0,0 @@
1use crate::hal::bb;
2use crate::hal::rcc::Clocks;
3use core::cell::Cell;
4use core::convert::TryInto;
5use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
6use critical_section::CriticalSection;
7use embassy::interrupt::InterruptExt;
8use embassy::time::{Clock, TICKS_PER_SECOND};
9use embassy::util::CriticalSectionMutex as Mutex;
10
11use crate::interrupt;
12use crate::interrupt::Interrupt;
13
14// RTC timekeeping works with something we call "periods", which are time intervals
15// of 2^15 ticks. The RTC counter value is 16 bits, so one "overflow cycle" is 2 periods.
16//
17// A `period` count is maintained in parallel to the RTC hardware `counter`, like this:
18// - `period` and `counter` start at 0
19// - `period` is incremented on overflow (at counter value 0)
20// - `period` is incremented "midway" between overflows (at counter value 0x8000)
21//
22// Therefore, when `period` is even, counter is in 0..0x7FFF. When odd, counter is in 0x8000..0xFFFF
23// This allows for now() to return the correct value even if it races an overflow.
24//
25// To get `now()`, `period` is read first, then `counter` is read. If the counter value matches
26// the expected range for the `period` parity, we're done. If it doesn't, this means that
27// a new period start has raced us between reading `period` and `counter`, so we assume the `counter` value
28// corresponds to the next period.
29//
30// `period` is a 32bit integer, so It overflows on 2^32 * 2^15 / 32768 seconds of uptime, which is 136 years.
31fn calc_now(period: u32, counter: u16) -> u64 {
32 ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64)
33}
34
35struct AlarmState {
36 timestamp: Cell<u64>,
37 callback: Cell<Option<(fn(*mut ()), *mut ())>>,
38}
39
40impl AlarmState {
41 fn new() -> Self {
42 Self {
43 timestamp: Cell::new(u64::MAX),
44 callback: Cell::new(None),
45 }
46 }
47}
48
49// TODO: This is sometimes wasteful, try to find a better way
50const ALARM_COUNT: usize = 3;
51
52/// RTC timer that can be used by the executor and to set alarms.
53///
54/// It can work with Timers 2, 3, 4, 5, 9 and 12. Timers 9 and 12 only have one alarm available,
55/// while the others have three each.
56/// This timer works internally with a unit of 2^15 ticks, which means that if a call to
57/// [`embassy::time::Clock::now`] is blocked for that amount of ticks the returned value will be
58/// wrong (an old value). The current default tick rate is 32768 ticks per second.
59pub struct RTC<T: Instance> {
60 rtc: T,
61 irq: T::Interrupt,
62
63 /// Number of 2^23 periods elapsed since boot.
64 period: AtomicU32,
65
66 /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled.
67 alarms: Mutex<[AlarmState; ALARM_COUNT]>,
68
69 clocks: Clocks,
70}
71
72impl<T: Instance> RTC<T> {
73 pub fn new(rtc: T, irq: T::Interrupt, clocks: Clocks) -> Self {
74 Self {
75 rtc,
76 irq,
77 period: AtomicU32::new(0),
78 alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]),
79 clocks,
80 }
81 }
82
83 pub fn start(&'static self) {
84 self.rtc.enable_clock();
85 self.rtc.stop_and_reset();
86
87 let multiplier = if T::ppre(&self.clocks) == 1 { 1 } else { 2 };
88 let freq = T::pclk(&self.clocks) * multiplier;
89 let psc = freq / TICKS_PER_SECOND as u32 - 1;
90 let psc: u16 = psc.try_into().unwrap();
91
92 self.rtc.set_psc_arr(psc, u16::MAX);
93 // Mid-way point
94 self.rtc.set_compare(0, 0x8000);
95 self.rtc.set_compare_interrupt(0, true);
96
97 self.irq.set_handler(|ptr| unsafe {
98 let this = &*(ptr as *const () as *const Self);
99 this.on_interrupt();
100 });
101 self.irq.set_handler_context(self as *const _ as *mut _);
102 self.irq.unpend();
103 self.irq.enable();
104
105 self.rtc.start();
106 }
107
108 fn on_interrupt(&self) {
109 if self.rtc.overflow_interrupt_status() {
110 self.rtc.overflow_clear_flag();
111 self.next_period();
112 }
113
114 // Half overflow
115 if self.rtc.compare_interrupt_status(0) {
116 self.rtc.compare_clear_flag(0);
117 self.next_period();
118 }
119
120 for n in 1..=ALARM_COUNT {
121 if self.rtc.compare_interrupt_status(n) {
122 self.rtc.compare_clear_flag(n);
123 critical_section::with(|cs| self.trigger_alarm(n, cs));
124 }
125 }
126 }
127
128 fn next_period(&self) {
129 critical_section::with(|cs| {
130 let period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
131 let t = (period as u64) << 15;
132
133 for n in 1..=ALARM_COUNT {
134 let alarm = &self.alarms.borrow(cs)[n - 1];
135 let at = alarm.timestamp.get();
136
137 let diff = at - t;
138 if diff < 0xc000 {
139 self.rtc.set_compare(n, at as u16);
140 self.rtc.set_compare_interrupt(n, true);
141 }
142 }
143 })
144 }
145
146 fn trigger_alarm(&self, n: usize, cs: CriticalSection) {
147 self.rtc.set_compare_interrupt(n, false);
148
149 let alarm = &self.alarms.borrow(cs)[n - 1];
150 alarm.timestamp.set(u64::MAX);
151
152 // Call after clearing alarm, so the callback can set another alarm.
153 if let Some((f, ctx)) = alarm.callback.get() {
154 f(ctx);
155 }
156 }
157
158 fn set_alarm_callback(&self, n: usize, callback: fn(*mut ()), ctx: *mut ()) {
159 critical_section::with(|cs| {
160 let alarm = &self.alarms.borrow(cs)[n - 1];
161 alarm.callback.set(Some((callback, ctx)));
162 })
163 }
164
165 fn set_alarm(&self, n: usize, timestamp: u64) {
166 critical_section::with(|cs| {
167 let alarm = &self.alarms.borrow(cs)[n - 1];
168 alarm.timestamp.set(timestamp);
169
170 let t = self.now();
171 if timestamp <= t {
172 self.trigger_alarm(n, cs);
173 return;
174 }
175
176 let diff = timestamp - t;
177 if diff < 0xc000 {
178 let safe_timestamp = timestamp.max(t + 3);
179 self.rtc.set_compare(n, safe_timestamp as u16);
180 self.rtc.set_compare_interrupt(n, true);
181 } else {
182 self.rtc.set_compare_interrupt(n, false);
183 }
184 })
185 }
186
187 pub fn alarm1(&'static self) -> Alarm<T> {
188 Alarm { n: 1, rtc: self }
189 }
190 pub fn alarm2(&'static self) -> Option<Alarm<T>> {
191 if T::REAL_ALARM_COUNT >= 2 {
192 Some(Alarm { n: 2, rtc: self })
193 } else {
194 None
195 }
196 }
197 pub fn alarm3(&'static self) -> Option<Alarm<T>> {
198 if T::REAL_ALARM_COUNT >= 3 {
199 Some(Alarm { n: 3, rtc: self })
200 } else {
201 None
202 }
203 }
204}
205
206impl<T: Instance> embassy::time::Clock for RTC<T> {
207 fn now(&self) -> u64 {
208 let period = self.period.load(Ordering::Relaxed);
209 compiler_fence(Ordering::Acquire);
210 let counter = self.rtc.counter();
211 calc_now(period, counter)
212 }
213}
214
215pub struct Alarm<T: Instance> {
216 n: usize,
217 rtc: &'static RTC<T>,
218}
219
220impl<T: Instance> embassy::time::Alarm for Alarm<T> {
221 fn set_callback(&self, callback: fn(*mut ()), ctx: *mut ()) {
222 self.rtc.set_alarm_callback(self.n, callback, ctx);
223 }
224
225 fn set(&self, timestamp: u64) {
226 self.rtc.set_alarm(self.n, timestamp);
227 }
228
229 fn clear(&self) {
230 self.rtc.set_alarm(self.n, u64::MAX);
231 }
232}
233
234mod sealed {
235 pub trait Sealed {}
236}
237
238pub trait Instance: sealed::Sealed + Sized + 'static {
239 type Interrupt: Interrupt;
240 const REAL_ALARM_COUNT: usize;
241
242 fn enable_clock(&self);
243 fn set_compare(&self, n: usize, value: u16);
244 fn set_compare_interrupt(&self, n: usize, enable: bool);
245 fn compare_interrupt_status(&self, n: usize) -> bool;
246 fn compare_clear_flag(&self, n: usize);
247 fn overflow_interrupt_status(&self) -> bool;
248 fn overflow_clear_flag(&self);
249 // This method should ensure that the values are really updated before returning
250 fn set_psc_arr(&self, psc: u16, arr: u16);
251 fn stop_and_reset(&self);
252 fn start(&self);
253 fn counter(&self) -> u16;
254 fn ppre(clocks: &Clocks) -> u8;
255 fn pclk(clocks: &Clocks) -> u32;
256}
257
258#[allow(unused_macros)]
259macro_rules! impl_timer {
260 ($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 3) => {
261 mod $module {
262 use super::*;
263 use crate::hal::pac::{$TYPE, RCC};
264
265 impl sealed::Sealed for $TYPE {}
266
267 impl Instance for $TYPE {
268 type Interrupt = interrupt::$INT;
269 const REAL_ALARM_COUNT: usize = 3;
270
271 fn enable_clock(&self) {
272 // NOTE(unsafe) It will only be used for atomic operations
273 unsafe {
274 let rcc = &*RCC::ptr();
275
276 bb::set(&rcc.$apbenr, $enrbit);
277 bb::set(&rcc.$apbrstr, $rstrbit);
278 bb::clear(&rcc.$apbrstr, $rstrbit);
279 }
280 }
281
282 fn set_compare(&self, n: usize, value: u16) {
283 // NOTE(unsafe) these registers accept all the range of u16 values
284 match n {
285 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
286 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
287 2 => self.ccr3.write(|w| unsafe { w.bits(value.into()) }),
288 3 => self.ccr4.write(|w| unsafe { w.bits(value.into()) }),
289 _ => {}
290 }
291 }
292
293 fn set_compare_interrupt(&self, n: usize, enable: bool) {
294 if n > 3 {
295 return;
296 }
297 let bit = n as u8 + 1;
298 unsafe {
299 if enable {
300 bb::set(&self.dier, bit);
301 } else {
302 bb::clear(&self.dier, bit);
303 }
304 }
305 }
306
307 fn compare_interrupt_status(&self, n: usize) -> bool {
308 let status = self.sr.read();
309 match n {
310 0 => status.cc1if().bit_is_set(),
311 1 => status.cc2if().bit_is_set(),
312 2 => status.cc3if().bit_is_set(),
313 3 => status.cc4if().bit_is_set(),
314 _ => false,
315 }
316 }
317
318 fn compare_clear_flag(&self, n: usize) {
319 if n > 3 {
320 return;
321 }
322 let bit = n as u8 + 1;
323 unsafe {
324 bb::clear(&self.sr, bit);
325 }
326 }
327
328 fn overflow_interrupt_status(&self) -> bool {
329 self.sr.read().uif().bit_is_set()
330 }
331
332 fn overflow_clear_flag(&self) {
333 unsafe {
334 bb::clear(&self.sr, 0);
335 }
336 }
337
338 fn set_psc_arr(&self, psc: u16, arr: u16) {
339 // NOTE(unsafe) All u16 values are valid
340 self.psc.write(|w| unsafe { w.bits(psc.into()) });
341 self.arr.write(|w| unsafe { w.bits(arr.into()) });
342
343 unsafe {
344 // Set URS, generate update, clear URS
345 bb::set(&self.cr1, 2);
346 self.egr.write(|w| w.ug().set_bit());
347 bb::clear(&self.cr1, 2);
348 }
349 }
350
351 fn stop_and_reset(&self) {
352 unsafe {
353 bb::clear(&self.cr1, 0);
354 }
355 self.cnt.reset();
356 }
357
358 fn start(&self) {
359 unsafe { bb::set(&self.cr1, 0) }
360 }
361
362 fn counter(&self) -> u16 {
363 self.cnt.read().bits() as u16
364 }
365
366 fn ppre(clocks: &Clocks) -> u8 {
367 clocks.$ppre()
368 }
369
370 fn pclk(clocks: &Clocks) -> u32 {
371 clocks.$pclk().0
372 }
373 }
374 }
375 };
376
377 ($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 1) => {
378 mod $module {
379 use super::*;
380 use crate::hal::pac::{$TYPE, RCC};
381
382 impl sealed::Sealed for $TYPE {}
383
384 impl Instance for $TYPE {
385 type Interrupt = interrupt::$INT;
386 const REAL_ALARM_COUNT: usize = 1;
387
388 fn enable_clock(&self) {
389 // NOTE(unsafe) It will only be used for atomic operations
390 unsafe {
391 let rcc = &*RCC::ptr();
392
393 bb::set(&rcc.$apbenr, $enrbit);
394 bb::set(&rcc.$apbrstr, $rstrbit);
395 bb::clear(&rcc.$apbrstr, $rstrbit);
396 }
397 }
398
399 fn set_compare(&self, n: usize, value: u16) {
400 // NOTE(unsafe) these registers accept all the range of u16 values
401 match n {
402 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
403 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
404 _ => {}
405 }
406 }
407
408 fn set_compare_interrupt(&self, n: usize, enable: bool) {
409 if n > 1 {
410 return;
411 }
412 let bit = n as u8 + 1;
413 unsafe {
414 if enable {
415 bb::set(&self.dier, bit);
416 } else {
417 bb::clear(&self.dier, bit);
418 }
419 }
420 }
421
422 fn compare_interrupt_status(&self, n: usize) -> bool {
423 let status = self.sr.read();
424 match n {
425 0 => status.cc1if().bit_is_set(),
426 1 => status.cc2if().bit_is_set(),
427 _ => false,
428 }
429 }
430
431 fn compare_clear_flag(&self, n: usize) {
432 if n > 1 {
433 return;
434 }
435 let bit = n as u8 + 1;
436 unsafe {
437 bb::clear(&self.sr, bit);
438 }
439 }
440
441 fn overflow_interrupt_status(&self) -> bool {
442 self.sr.read().uif().bit_is_set()
443 }
444
445 fn overflow_clear_flag(&self) {
446 unsafe {
447 bb::clear(&self.sr, 0);
448 }
449 }
450
451 fn set_psc_arr(&self, psc: u16, arr: u16) {
452 // NOTE(unsafe) All u16 values are valid
453 self.psc.write(|w| unsafe { w.bits(psc.into()) });
454 self.arr.write(|w| unsafe { w.bits(arr.into()) });
455
456 unsafe {
457 // Set URS, generate update, clear URS
458 bb::set(&self.cr1, 2);
459 self.egr.write(|w| w.ug().set_bit());
460 bb::clear(&self.cr1, 2);
461 }
462 }
463
464 fn stop_and_reset(&self) {
465 unsafe {
466 bb::clear(&self.cr1, 0);
467 }
468 self.cnt.reset();
469 }
470
471 fn start(&self) {
472 unsafe { bb::set(&self.cr1, 0) }
473 }
474
475 fn counter(&self) -> u16 {
476 self.cnt.read().bits() as u16
477 }
478
479 fn ppre(clocks: &Clocks) -> u8 {
480 clocks.$ppre()
481 }
482
483 fn pclk(clocks: &Clocks) -> u32 {
484 clocks.$pclk().0
485 }
486 }
487 }
488 };
489}
490
491#[cfg(not(feature = "stm32f410"))]
492impl_timer!(tim2: (TIM2, TIM2, apb1enr, 0, apb1rstr, 0, ppre1, pclk1), 3);
493
494#[cfg(not(feature = "stm32f410"))]
495impl_timer!(tim3: (TIM3, TIM3, apb1enr, 1, apb1rstr, 1, ppre1, pclk1), 3);
496
497#[cfg(not(feature = "stm32f410"))]
498impl_timer!(tim4: (TIM4, TIM4, apb1enr, 2, apb1rstr, 2, ppre1, pclk1), 3);
499
500impl_timer!(tim5: (TIM5, TIM5, apb1enr, 3, apb1rstr, 3, ppre1, pclk1), 3);
501
502impl_timer!(tim9: (TIM9, TIM1_BRK_TIM9, apb2enr, 16, apb2rstr, 16, ppre2, pclk2), 1);
503
504#[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411")))]
505impl_timer!(tim12: (TIM12, TIM8_BRK_TIM12, apb1enr, 6, apb1rstr, 6, ppre1, pclk1), 1);
diff --git a/embassy-stm32/src/f4/serial.rs b/embassy-stm32/src/f4/serial.rs
deleted file mode 100644
index 78aaa8944..000000000
--- a/embassy-stm32/src/f4/serial.rs
+++ /dev/null
@@ -1,357 +0,0 @@
1//! Async Serial.
2
3use core::future::Future;
4use core::marker::PhantomData;
5use embassy::interrupt::Interrupt;
6use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write};
7use embassy::util::InterruptFuture;
8use futures::{select_biased, FutureExt};
9
10use crate::hal::{
11 dma,
12 dma::config::DmaConfig,
13 dma::traits::{Channel, DMASet, PeriAddress, Stream},
14 dma::{MemoryToPeripheral, PeripheralToMemory, Transfer},
15 rcc::Clocks,
16 serial,
17 serial::config::{Config as SerialConfig, DmaConfig as SerialDmaConfig},
18 serial::{Event as SerialEvent, Pins},
19};
20use crate::interrupt;
21use crate::pac;
22
23/// Interface to the Serial peripheral
24pub struct Serial<
25 USART: PeriAddress<MemSize = u8> + WithInterrupt,
26 TSTREAM: Stream + WithInterrupt,
27 RSTREAM: Stream + WithInterrupt,
28 CHANNEL: Channel,
29> {
30 tx_stream: Option<TSTREAM>,
31 rx_stream: Option<RSTREAM>,
32 usart: Option<USART>,
33 tx_int: TSTREAM::Interrupt,
34 rx_int: RSTREAM::Interrupt,
35 usart_int: USART::Interrupt,
36 channel: PhantomData<CHANNEL>,
37}
38
39// static mut INSTANCE: *const Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> = ptr::null_mut();
40
41impl<USART, TSTREAM, RSTREAM, CHANNEL> Serial<USART, TSTREAM, RSTREAM, CHANNEL>
42where
43 USART: serial::Instance
44 + PeriAddress<MemSize = u8>
45 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
46 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
47 + WithInterrupt,
48 TSTREAM: Stream + WithInterrupt,
49 RSTREAM: Stream + WithInterrupt,
50 CHANNEL: Channel,
51{
52 // Leaking futures is forbidden!
53 pub unsafe fn new<PINS>(
54 usart: USART,
55 streams: (TSTREAM, RSTREAM),
56 pins: PINS,
57 tx_int: TSTREAM::Interrupt,
58 rx_int: RSTREAM::Interrupt,
59 usart_int: USART::Interrupt,
60 mut config: SerialConfig,
61 clocks: Clocks,
62 ) -> Self
63 where
64 PINS: Pins<USART>,
65 {
66 config.dma = SerialDmaConfig::TxRx;
67
68 let (usart, _) = serial::Serial::new(usart, pins, config, clocks)
69 .unwrap()
70 .release();
71
72 let (tx_stream, rx_stream) = streams;
73
74 Serial {
75 tx_stream: Some(tx_stream),
76 rx_stream: Some(rx_stream),
77 usart: Some(usart),
78 tx_int: tx_int,
79 rx_int: rx_int,
80 usart_int: usart_int,
81 channel: PhantomData,
82 }
83 }
84}
85
86impl<USART, TSTREAM, RSTREAM, CHANNEL> Read for Serial<USART, TSTREAM, RSTREAM, CHANNEL>
87where
88 USART: serial::Instance
89 + PeriAddress<MemSize = u8>
90 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
91 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
92 + WithInterrupt
93 + 'static,
94 TSTREAM: Stream + WithInterrupt + 'static,
95 RSTREAM: Stream + WithInterrupt + 'static,
96 CHANNEL: Channel + 'static,
97{
98 type ReadFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
99
100 /// Receives serial data.
101 ///
102 /// The future is pending until the buffer is completely filled.
103 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
104 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) };
105
106 async move {
107 let rx_stream = self.rx_stream.take().unwrap();
108 let usart = self.usart.take().unwrap();
109
110 let mut rx_transfer = Transfer::init(
111 rx_stream,
112 usart,
113 static_buf,
114 None,
115 DmaConfig::default()
116 .transfer_complete_interrupt(true)
117 .memory_increment(true)
118 .double_buffer(false),
119 );
120
121 let fut = InterruptFuture::new(&mut self.rx_int);
122 rx_transfer.start(|_usart| {});
123 fut.await;
124
125 let (rx_stream, usart, _, _) = rx_transfer.free();
126 self.rx_stream.replace(rx_stream);
127 self.usart.replace(usart);
128
129 Ok(())
130 }
131 }
132}
133
134impl<USART, TSTREAM, RSTREAM, CHANNEL> Write for Serial<USART, TSTREAM, RSTREAM, CHANNEL>
135where
136 USART: serial::Instance
137 + PeriAddress<MemSize = u8>
138 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
139 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
140 + WithInterrupt
141 + 'static,
142 TSTREAM: Stream + WithInterrupt + 'static,
143 RSTREAM: Stream + WithInterrupt + 'static,
144 CHANNEL: Channel + 'static,
145{
146 type WriteFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
147
148 /// Sends serial data.
149 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
150 #[allow(mutable_transmutes)]
151 let static_buf = unsafe { core::mem::transmute::<&'a [u8], &'static mut [u8]>(buf) };
152
153 async move {
154 let tx_stream = self.tx_stream.take().unwrap();
155 let usart = self.usart.take().unwrap();
156
157 let mut tx_transfer = Transfer::init(
158 tx_stream,
159 usart,
160 static_buf,
161 None,
162 DmaConfig::default()
163 .transfer_complete_interrupt(true)
164 .memory_increment(true)
165 .double_buffer(false),
166 );
167
168 let fut = InterruptFuture::new(&mut self.tx_int);
169
170 tx_transfer.start(|_usart| {});
171 fut.await;
172
173 let (tx_stream, usart, _buf, _) = tx_transfer.free();
174
175 self.tx_stream.replace(tx_stream);
176 self.usart.replace(usart);
177
178 Ok(())
179 }
180 }
181}
182
183impl<USART, TSTREAM, RSTREAM, CHANNEL> ReadUntilIdle for Serial<USART, TSTREAM, RSTREAM, CHANNEL>
184where
185 USART: serial::Instance
186 + PeriAddress<MemSize = u8>
187 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
188 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
189 + WithInterrupt
190 + 'static,
191 TSTREAM: Stream + WithInterrupt + 'static,
192 RSTREAM: Stream + WithInterrupt + 'static,
193 CHANNEL: Channel + 'static,
194{
195 type ReadUntilIdleFuture<'a> = impl Future<Output = Result<usize, Error>> + 'a;
196
197 /// Receives serial data.
198 ///
199 /// The future is pending until either the buffer is completely full, or the RX line falls idle after receiving some data.
200 ///
201 /// Returns the number of bytes read.
202 fn read_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a> {
203 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) };
204
205 async move {
206 let rx_stream = self.rx_stream.take().unwrap();
207 let usart = self.usart.take().unwrap();
208
209 unsafe {
210 /* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */
211 (*USART::ptr()).cr1.modify(|_, w| w.idleie().set_bit());
212
213 /* __HAL_UART_CLEAR_IDLEFLAG(&uart->UartHandle); */
214 (*USART::ptr()).sr.read();
215 (*USART::ptr()).dr.read();
216 };
217
218 let mut rx_transfer = Transfer::init(
219 rx_stream,
220 usart,
221 static_buf,
222 None,
223 DmaConfig::default()
224 .transfer_complete_interrupt(true)
225 .memory_increment(true)
226 .double_buffer(false),
227 );
228
229 let total_bytes = RSTREAM::get_number_of_transfers() as usize;
230
231 let fut = InterruptFuture::new(&mut self.rx_int);
232 let fut_idle = InterruptFuture::new(&mut self.usart_int);
233
234 rx_transfer.start(|_usart| {});
235
236 futures::future::select(fut, fut_idle).await;
237
238 let (rx_stream, usart, _, _) = rx_transfer.free();
239
240 let remaining_bytes = RSTREAM::get_number_of_transfers() as usize;
241
242 unsafe {
243 (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit());
244 }
245 self.rx_stream.replace(rx_stream);
246 self.usart.replace(usart);
247
248 Ok(total_bytes - remaining_bytes)
249 }
250 }
251}
252
253mod private {
254 pub trait Sealed {}
255}
256
257pub trait WithInterrupt: private::Sealed {
258 type Interrupt: Interrupt;
259}
260
261macro_rules! dma {
262 ($($PER:ident => ($dma:ident, $stream:ident),)+) => {
263 $(
264 impl private::Sealed for dma::$stream<pac::$dma> {}
265 impl WithInterrupt for dma::$stream<pac::$dma> {
266 type Interrupt = interrupt::$PER;
267 }
268 )+
269 }
270 }
271
272macro_rules! usart {
273 ($($PER:ident => ($usart:ident),)+) => {
274 $(
275 impl private::Sealed for pac::$usart {}
276 impl WithInterrupt for pac::$usart {
277 type Interrupt = interrupt::$PER;
278 }
279 )+
280 }
281}
282
283dma! {
284 DMA2_STREAM0 => (DMA2, Stream0),
285 DMA2_STREAM1 => (DMA2, Stream1),
286 DMA2_STREAM2 => (DMA2, Stream2),
287 DMA2_STREAM3 => (DMA2, Stream3),
288 DMA2_STREAM4 => (DMA2, Stream4),
289 DMA2_STREAM5 => (DMA2, Stream5),
290 DMA2_STREAM6 => (DMA2, Stream6),
291 DMA2_STREAM7 => (DMA2, Stream7),
292 DMA1_STREAM0 => (DMA1, Stream0),
293 DMA1_STREAM1 => (DMA1, Stream1),
294 DMA1_STREAM2 => (DMA1, Stream2),
295 DMA1_STREAM3 => (DMA1, Stream3),
296 DMA1_STREAM4 => (DMA1, Stream4),
297 DMA1_STREAM5 => (DMA1, Stream5),
298 DMA1_STREAM6 => (DMA1, Stream6),
299}
300
301#[cfg(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411",))]
302usart! {
303 USART1 => (USART1),
304 USART2 => (USART2),
305 USART6 => (USART6),
306}
307
308#[cfg(any(feature = "stm32f405", feature = "stm32f407"))]
309usart! {
310 USART1 => (USART1),
311 USART2 => (USART2),
312 USART3 => (USART3),
313 USART6 => (USART6),
314
315 UART4 => (UART4),
316 UART5 => (UART5),
317}
318
319#[cfg(feature = "stm32f412")]
320usart! {
321 USART1 => (USART1),
322 USART2 => (USART2),
323 USART3 => (USART3),
324 USART6 => (USART6),
325}
326
327#[cfg(feature = "stm32f413")]
328usart! {
329 USART1 => (USART1),
330 USART2 => (USART2),
331 USART3 => (USART3),
332 USART6 => (USART6),
333 USART7 => (USART7),
334 USART8 => (USART8),
335
336 UART5 => (UART5),
337 UART9 => (UART9),
338 UART10 => (UART10),
339}
340
341#[cfg(any(
342 feature = "stm32f427",
343 feature = "stm32f429",
344 feature = "stm32f446",
345 feature = "stm32f469"
346))]
347usart! {
348 USART1 => (USART1),
349 USART2 => (USART2),
350 USART3 => (USART3),
351 USART6 => (USART6),
352
353 UART4 => (UART4),
354 UART5 => (UART5),
355// UART7 => (UART7),
356// UART8 => (UART8),
357}
diff --git a/embassy-stm32/src/f4/spi.rs b/embassy-stm32/src/f4/spi.rs
deleted file mode 100644
index d02c78106..000000000
--- a/embassy-stm32/src/f4/spi.rs
+++ /dev/null
@@ -1,492 +0,0 @@
1//! Async SPI
2
3use embassy::time;
4
5use core::{future::Future, marker::PhantomData, mem, ops::Deref, pin::Pin, ptr};
6use embassy::{interrupt::Interrupt, traits::spi::FullDuplex, util::InterruptFuture};
7use nb;
8
9pub use crate::hal::spi::{Mode, Phase, Polarity};
10use crate::hal::{
11 bb, dma,
12 dma::config::DmaConfig,
13 dma::traits::{Channel, DMASet, PeriAddress, Stream},
14 dma::{MemoryToPeripheral, PeripheralToMemory, Transfer},
15 rcc::Clocks,
16 spi::Pins,
17 time::Hertz,
18};
19use crate::interrupt;
20use crate::pac;
21use futures::future;
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25#[non_exhaustive]
26pub enum Error {
27 TxBufferTooLong,
28 RxBufferTooLong,
29 Overrun,
30 ModeFault,
31 Crc,
32}
33
34fn read_sr<T: Instance>(spi: &T) -> nb::Result<u8, Error> {
35 let sr = spi.sr.read();
36 Err(if sr.ovr().bit_is_set() {
37 nb::Error::Other(Error::Overrun)
38 } else if sr.modf().bit_is_set() {
39 nb::Error::Other(Error::ModeFault)
40 } else if sr.crcerr().bit_is_set() {
41 nb::Error::Other(Error::Crc)
42 } else if sr.rxne().bit_is_set() {
43 // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
44 // reading a half-word)
45 return Ok(unsafe { ptr::read_volatile(&spi.dr as *const _ as *const u8) });
46 } else {
47 nb::Error::WouldBlock
48 })
49}
50
51fn write_sr<T: Instance>(spi: &T, byte: u8) -> nb::Result<(), Error> {
52 let sr = spi.sr.read();
53 Err(if sr.ovr().bit_is_set() {
54 // Read from the DR to clear the OVR bit
55 let _ = spi.dr.read();
56 nb::Error::Other(Error::Overrun)
57 } else if sr.modf().bit_is_set() {
58 // Write to CR1 to clear MODF
59 spi.cr1.modify(|_r, w| w);
60 nb::Error::Other(Error::ModeFault)
61 } else if sr.crcerr().bit_is_set() {
62 // Clear the CRCERR bit
63 spi.sr.modify(|_r, w| {
64 w.crcerr().clear_bit();
65 w
66 });
67 nb::Error::Other(Error::Crc)
68 } else if sr.txe().bit_is_set() {
69 // NOTE(write_volatile) see note above
70 unsafe { ptr::write_volatile(&spi.dr as *const _ as *mut u8, byte) }
71 return Ok(());
72 } else {
73 nb::Error::WouldBlock
74 })
75}
76
77/// Interface to the Serial peripheral
78pub struct Spi<
79 SPI: PeriAddress<MemSize = u8> + WithInterrupt,
80 TSTREAM: Stream + WithInterrupt,
81 RSTREAM: Stream + WithInterrupt,
82 CHANNEL: Channel,
83> {
84 tx_stream: Option<TSTREAM>,
85 rx_stream: Option<RSTREAM>,
86 spi: Option<SPI>,
87 tx_int: TSTREAM::Interrupt,
88 rx_int: RSTREAM::Interrupt,
89 spi_int: SPI::Interrupt,
90 channel: PhantomData<CHANNEL>,
91}
92
93impl<SPI, TSTREAM, RSTREAM, CHANNEL> Spi<SPI, TSTREAM, RSTREAM, CHANNEL>
94where
95 SPI: Instance
96 + PeriAddress<MemSize = u8>
97 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
98 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
99 + WithInterrupt,
100 TSTREAM: Stream + WithInterrupt,
101 RSTREAM: Stream + WithInterrupt,
102 CHANNEL: Channel,
103{
104 // Leaking futures is forbidden!
105 pub unsafe fn new<PINS>(
106 spi: SPI,
107 streams: (TSTREAM, RSTREAM),
108 pins: PINS,
109 tx_int: TSTREAM::Interrupt,
110 rx_int: RSTREAM::Interrupt,
111 spi_int: SPI::Interrupt,
112 mode: Mode,
113 freq: Hertz,
114 clocks: Clocks,
115 ) -> Self
116 where
117 PINS: Pins<SPI>,
118 {
119 let (tx_stream, rx_stream) = streams;
120
121 // let spi1: crate::pac::SPI1 = unsafe { mem::transmute(()) };
122 // let mut hspi = crate::hal::spi::Spi::spi1(
123 // spi1,
124 // (
125 // crate::hal::spi::NoSck,
126 // crate::hal::spi::NoMiso,
127 // crate::hal::spi::NoMosi,
128 // ),
129 // mode,
130 // freq,
131 // clocks,
132 // );
133
134 unsafe { SPI::enable_clock() };
135
136 let clock = SPI::clock_speed(clocks);
137
138 // disable SS output
139 // spi.cr2
140 // .write(|w| w.ssoe().clear_bit().rxdmaen().set_bit().txdmaen().set_bit());
141 spi.cr2.write(|w| w.ssoe().clear_bit());
142
143 let br = match clock.0 / freq.0 {
144 0 => unreachable!(),
145 1..=2 => 0b000,
146 3..=5 => 0b001,
147 6..=11 => 0b010,
148 12..=23 => 0b011,
149 24..=47 => 0b100,
150 48..=95 => 0b101,
151 96..=191 => 0b110,
152 _ => 0b111,
153 };
154
155 // mstr: master configuration
156 // lsbfirst: MSB first
157 // ssm: enable software slave management (NSS pin free for other uses)
158 // ssi: set nss high = master mode
159 // dff: 8 bit frames
160 // bidimode: 2-line unidirectional
161 // spe: enable the SPI bus
162 spi.cr1.write(|w| {
163 w.cpha()
164 .bit(mode.phase == Phase::CaptureOnSecondTransition)
165 .cpol()
166 .bit(mode.polarity == Polarity::IdleHigh)
167 .mstr()
168 .set_bit()
169 .br()
170 .bits(br)
171 .lsbfirst()
172 .clear_bit()
173 .ssm()
174 .set_bit()
175 .ssi()
176 .set_bit()
177 .rxonly()
178 .clear_bit()
179 .dff()
180 .clear_bit()
181 .bidimode()
182 .clear_bit()
183 .spe()
184 .set_bit()
185 });
186
187 Self {
188 tx_stream: Some(tx_stream),
189 rx_stream: Some(rx_stream),
190 spi: Some(spi),
191 tx_int: tx_int,
192 rx_int: rx_int,
193 spi_int: spi_int,
194 channel: PhantomData,
195 }
196 }
197}
198
199impl<SPI, TSTREAM, RSTREAM, CHANNEL> FullDuplex<u8> for Spi<SPI, TSTREAM, RSTREAM, CHANNEL>
200where
201 SPI: Instance
202 + PeriAddress<MemSize = u8>
203 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
204 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
205 + WithInterrupt
206 + 'static,
207 TSTREAM: Stream + WithInterrupt + 'static,
208 RSTREAM: Stream + WithInterrupt + 'static,
209 CHANNEL: Channel + 'static,
210{
211 type Error = Error;
212
213 type WriteFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
214 type ReadFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
215 type WriteReadFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
216
217 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
218 #[allow(mutable_transmutes)]
219 let static_buf: &'static mut [u8] = unsafe { mem::transmute(buf) };
220
221 async move {
222 let rx_stream = self.rx_stream.take().unwrap();
223 let spi = self.spi.take().unwrap();
224
225 spi.cr2.modify(|_, w| w.errie().set_bit());
226
227 let mut rx_transfer = Transfer::init(
228 rx_stream,
229 spi,
230 static_buf,
231 None,
232 DmaConfig::default()
233 .transfer_complete_interrupt(true)
234 .memory_increment(true)
235 .double_buffer(false),
236 );
237
238 let fut = InterruptFuture::new(&mut self.rx_int);
239 let fut_err = InterruptFuture::new(&mut self.spi_int);
240
241 rx_transfer.start(|_spi| {});
242 future::select(fut, fut_err).await;
243
244 let (rx_stream, spi, _buf, _) = rx_transfer.free();
245
246 spi.cr2.modify(|_, w| w.errie().clear_bit());
247 self.rx_stream.replace(rx_stream);
248 self.spi.replace(spi);
249
250 Ok(())
251 }
252 }
253
254 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
255 #[allow(mutable_transmutes)]
256 let static_buf: &'static mut [u8] = unsafe { mem::transmute(buf) };
257
258 async move {
259 let tx_stream = self.tx_stream.take().unwrap();
260 let spi = self.spi.take().unwrap();
261
262 spi.cr2
263 .modify(|_, w| w.errie().set_bit().txeie().set_bit().rxneie().set_bit());
264
265 // let mut tx_transfer = Transfer::init(
266 // tx_stream,
267 // spi,
268 // static_buf,
269 // None,
270 // DmaConfig::default()
271 // .transfer_complete_interrupt(true)
272 // .memory_increment(true)
273 // .double_buffer(false),
274 // );
275 //
276 // let fut = InterruptFuture::new(&mut self.tx_int);
277 //
278 // tx_transfer.start(|_spi| {});
279 // fut.await;
280
281 // let (tx_stream, spi, _buf, _) = tx_transfer.free();
282
283 for i in 0..(static_buf.len() - 1) {
284 let byte = static_buf[i];
285 loop {
286 match write_sr(&spi, byte) {
287 Ok(()) => break,
288 _ => {}
289 }
290 InterruptFuture::new(&mut self.spi_int).await;
291 }
292 }
293
294 spi.cr2.modify(|_, w| {
295 w.errie()
296 .clear_bit()
297 .txeie()
298 .clear_bit()
299 .rxneie()
300 .clear_bit()
301 });
302 self.tx_stream.replace(tx_stream);
303 self.spi.replace(spi);
304
305 Ok(())
306 }
307 }
308
309 fn read_write<'a>(
310 &'a mut self,
311 read_buf: &'a mut [u8],
312 write_buf: &'a [u8],
313 ) -> Self::WriteReadFuture<'a> {
314 #[allow(mutable_transmutes)]
315 let write_static_buf: &'static mut [u8] = unsafe { mem::transmute(write_buf) };
316 let read_static_buf: &'static mut [u8] = unsafe { mem::transmute(read_buf) };
317
318 async move {
319 let tx_stream = self.tx_stream.take().unwrap();
320 let rx_stream = self.rx_stream.take().unwrap();
321 let spi_tx = self.spi.take().unwrap();
322 let spi_rx: SPI = unsafe { mem::transmute_copy(&spi_tx) };
323
324 spi_rx
325 .cr2
326 .modify(|_, w| w.errie().set_bit().txeie().set_bit().rxneie().set_bit());
327
328 // let mut tx_transfer = Transfer::init(
329 // tx_stream,
330 // spi_tx,
331 // write_static_buf,
332 // None,
333 // DmaConfig::default()
334 // .transfer_complete_interrupt(true)
335 // .memory_increment(true)
336 // .double_buffer(false),
337 // );
338 //
339 // let mut rx_transfer = Transfer::init(
340 // rx_stream,
341 // spi_rx,
342 // read_static_buf,
343 // None,
344 // DmaConfig::default()
345 // .transfer_complete_interrupt(true)
346 // .memory_increment(true)
347 // .double_buffer(false),
348 // );
349 //
350 // let tx_fut = InterruptFuture::new(&mut self.tx_int);
351 // let rx_fut = InterruptFuture::new(&mut self.rx_int);
352 // let rx_fut_err = InterruptFuture::new(&mut self.spi_int);
353 //
354 // rx_transfer.start(|_spi| {});
355 // tx_transfer.start(|_spi| {});
356 //
357 // time::Timer::after(time::Duration::from_millis(500)).await;
358 //
359 // // tx_fut.await;
360 // // future::select(rx_fut, rx_fut_err).await;
361 //
362 // let (rx_stream, spi_rx, _buf, _) = rx_transfer.free();
363 // let (tx_stream, _, _buf, _) = tx_transfer.free();
364
365 for i in 0..(read_static_buf.len() - 1) {
366 let byte = write_static_buf[i];
367 loop {
368 let fut = InterruptFuture::new(&mut self.spi_int);
369 match write_sr(&spi_tx, byte) {
370 Ok(()) => break,
371 _ => {}
372 }
373 fut.await;
374 }
375
376 loop {
377 let fut = InterruptFuture::new(&mut self.spi_int);
378 match read_sr(&spi_tx) {
379 Ok(byte) => {
380 read_static_buf[i] = byte;
381 break;
382 }
383 _ => {}
384 }
385 fut.await;
386 }
387 }
388
389 spi_rx.cr2.modify(|_, w| {
390 w.errie()
391 .clear_bit()
392 .txeie()
393 .clear_bit()
394 .rxneie()
395 .clear_bit()
396 });
397 self.rx_stream.replace(rx_stream);
398 self.tx_stream.replace(tx_stream);
399 self.spi.replace(spi_rx);
400
401 Ok(())
402 }
403 }
404}
405
406mod private {
407 pub trait Sealed {}
408}
409
410pub trait WithInterrupt: private::Sealed {
411 type Interrupt: Interrupt;
412}
413
414pub trait Instance: Deref<Target = pac::spi1::RegisterBlock> + private::Sealed {
415 unsafe fn enable_clock();
416 fn clock_speed(clocks: Clocks) -> Hertz;
417}
418
419macro_rules! dma {
420 ($($PER:ident => ($dma:ident, $stream:ident),)+) => {
421 $(
422 impl private::Sealed for dma::$stream<pac::$dma> {}
423 impl WithInterrupt for dma::$stream<pac::$dma> {
424 type Interrupt = interrupt::$PER;
425 }
426 )+
427 }
428 }
429
430macro_rules! spi {
431 ($($PER:ident => ($SPI:ident, $pclkX:ident, $apbXenr:ident, $en:expr),)+) => {
432 $(
433 impl private::Sealed for pac::$SPI {}
434 impl Instance for pac::$SPI {
435 unsafe fn enable_clock() {
436 const EN_BIT: u8 = $en;
437 // NOTE(unsafe) self reference will only be used for atomic writes with no side effects.
438 let rcc = &(*pac::RCC::ptr());
439 // Enable clock.
440 bb::set(&rcc.$apbXenr, EN_BIT);
441 // Stall the pipeline to work around erratum 2.1.13 (DM00037591)
442 cortex_m::asm::dsb();
443 }
444
445 fn clock_speed(clocks: Clocks) -> Hertz {
446 clocks.$pclkX()
447 }
448 }
449 impl WithInterrupt for pac::$SPI {
450 type Interrupt = interrupt::$PER;
451 }
452 )+
453 }
454}
455
456dma! {
457 DMA2_STREAM0 => (DMA2, Stream0),
458 DMA2_STREAM1 => (DMA2, Stream1),
459 DMA2_STREAM2 => (DMA2, Stream2),
460 DMA2_STREAM3 => (DMA2, Stream3),
461 DMA2_STREAM4 => (DMA2, Stream4),
462 DMA2_STREAM5 => (DMA2, Stream5),
463 DMA2_STREAM6 => (DMA2, Stream6),
464 DMA2_STREAM7 => (DMA2, Stream7),
465 DMA1_STREAM0 => (DMA1, Stream0),
466 DMA1_STREAM1 => (DMA1, Stream1),
467 DMA1_STREAM2 => (DMA1, Stream2),
468 DMA1_STREAM3 => (DMA1, Stream3),
469 DMA1_STREAM4 => (DMA1, Stream4),
470 DMA1_STREAM5 => (DMA1, Stream5),
471 DMA1_STREAM6 => (DMA1, Stream6),
472}
473
474#[cfg(any(
475 feature = "stm32f401",
476 feature = "stm32f410",
477 feature = "stm32f411",
478 feature = "stm32f446",
479))]
480spi! {
481 SPI1 => (SPI1, pclk2, apb2enr, 12),
482 SPI2 => (SPI2, pclk1, apb2enr, 14),
483// SPI6 => (SPI6, pclk2, apb2enr, 21),
484 SPI4 => (SPI3, pclk2, apb2enr, 13),
485// SPI5 => (SPI3, pclk2, apb2enr, 20),
486}
487
488#[cfg(any(feature = "stm32f405", feature = "stm32f407"))]
489spi! {
490 SPI1 => (SPI1, pclk2, apb2enr, 12),
491 SPI3 => (SPI3, pclk1, apb2enr, 15),
492}
diff --git a/embassy-stm32/src/f4/system.rs b/embassy-stm32/src/f4/system.rs
deleted file mode 100644
index fb739272a..000000000
--- a/embassy-stm32/src/f4/system.rs
+++ /dev/null
@@ -1,61 +0,0 @@
1use crate::{hal::prelude::*, pac, Peripherals};
2
3#[derive(Default)]
4pub struct Config {
5 pub use_hse: Option<u32>,
6 pub sysclk: Option<u32>,
7 pub pclk1: Option<u32>,
8 pub require_pll48clk: bool,
9}
10
11impl Config {
12 pub fn new() -> Self {
13 Default::default()
14 }
15
16 pub fn use_hse(mut self, freq: u32) -> Self {
17 self.use_hse = Some(freq);
18 self
19 }
20
21 pub fn sysclk(mut self, freq: u32) -> Self {
22 self.sysclk = Some(freq);
23 self
24 }
25
26 pub fn pclk1(mut self, freq: u32) -> Self {
27 self.pclk1 = Some(freq);
28 self
29 }
30
31 pub fn require_pll48clk(mut self) -> Self {
32 self.require_pll48clk = true;
33 self
34 }
35}
36
37/// safety: must only call once.
38pub unsafe fn configure(config: Config) {
39 let dp = pac::Peripherals::take().unwrap();
40 let mut cfgr = dp.RCC.constrain().cfgr;
41
42 if let Some(hz) = config.use_hse {
43 cfgr = cfgr.use_hse(hz.mhz());
44 };
45
46 if let Some(hz) = config.sysclk {
47 cfgr = cfgr.sysclk(hz.mhz());
48 };
49
50 if let Some(hz) = config.pclk1 {
51 cfgr = cfgr.pclk1(hz.mhz());
52 };
53
54 if config.require_pll48clk {
55 cfgr = cfgr.require_pll48clk();
56 };
57
58 let clocks = cfgr.freeze();
59
60 unsafe { Peripherals::set_peripherals(clocks) };
61}
diff --git a/embassy-stm32/src/fmt.rs b/embassy-stm32/src/fmt.rs
deleted file mode 100644
index 160642ccd..000000000
--- a/embassy-stm32/src/fmt.rs
+++ /dev/null
@@ -1,114 +0,0 @@
1#![macro_use]
2#![allow(clippy::module_inception)]
3#![allow(unused)]
4
5#[cfg(all(feature = "defmt", feature = "log"))]
6compile_error!("You may not enable both `defmt` and `log` features.");
7
8pub use fmt::*;
9
10#[cfg(feature = "defmt")]
11mod fmt {
12 pub use defmt::{
13 assert, assert_eq, assert_ne, debug, debug_assert, debug_assert_eq, debug_assert_ne, error,
14 info, panic, todo, trace, unreachable, unwrap, warn,
15 };
16}
17
18#[cfg(feature = "log")]
19mod fmt {
20 pub use core::{
21 assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo,
22 unreachable,
23 };
24 pub use log::{debug, error, info, trace, warn};
25}
26
27#[cfg(not(any(feature = "defmt", feature = "log")))]
28mod fmt {
29 #![macro_use]
30
31 pub use core::{
32 assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo,
33 unreachable,
34 };
35
36 macro_rules! trace {
37 ($($msg:expr),+ $(,)?) => {
38 ()
39 };
40 }
41
42 macro_rules! debug {
43 ($($msg:expr),+ $(,)?) => {
44 ()
45 };
46 }
47
48 macro_rules! info {
49 ($($msg:expr),+ $(,)?) => {
50 ()
51 };
52 }
53
54 macro_rules! warn {
55 ($($msg:expr),+ $(,)?) => {
56 ()
57 };
58 }
59
60 macro_rules! error {
61 ($($msg:expr),+ $(,)?) => {
62 ()
63 };
64 }
65}
66
67#[cfg(not(feature = "defmt"))]
68macro_rules! unwrap {
69 ($arg:expr) => {
70 match $crate::fmt::Try::into_result($arg) {
71 ::core::result::Result::Ok(t) => t,
72 ::core::result::Result::Err(e) => {
73 ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
74 }
75 }
76 };
77 ($arg:expr, $($msg:expr),+ $(,)? ) => {
78 match $crate::fmt::Try::into_result($arg) {
79 ::core::result::Result::Ok(t) => t,
80 ::core::result::Result::Err(e) => {
81 ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
82 }
83 }
84 }
85}
86
87#[derive(Debug, Copy, Clone, Eq, PartialEq)]
88pub struct NoneError;
89
90pub trait Try {
91 type Ok;
92 type Error;
93 fn into_result(self) -> Result<Self::Ok, Self::Error>;
94}
95
96impl<T> Try for Option<T> {
97 type Ok = T;
98 type Error = NoneError;
99
100 #[inline]
101 fn into_result(self) -> Result<T, NoneError> {
102 self.ok_or(NoneError)
103 }
104}
105
106impl<T, E> Try for Result<T, E> {
107 type Ok = T;
108 type Error = E;
109
110 #[inline]
111 fn into_result(self) -> Self {
112 self
113 }
114}
diff --git a/embassy-stm32/src/interrupt.rs b/embassy-stm32/src/interrupt.rs
deleted file mode 100644
index 76dea28f6..000000000
--- a/embassy-stm32/src/interrupt.rs
+++ /dev/null
@@ -1,1042 +0,0 @@
1//! Interrupt management
2//!
3//! This module implements an API for managing interrupts compatible with
4//! nrf_softdevice::interrupt. Intended for switching between the two at compile-time.
5
6// Re-exports
7pub use embassy::interrupt::{declare, take, Interrupt};
8pub use embassy_extras::interrupt::Priority4 as Priority;
9
10#[cfg(feature = "stm32f401")]
11mod irqs {
12 use super::*;
13 declare!(PVD);
14 declare!(TAMP_STAMP);
15 declare!(RTC_WKUP);
16 declare!(FLASH);
17 declare!(RCC);
18 declare!(EXTI0);
19 declare!(EXTI1);
20 declare!(EXTI2);
21 declare!(EXTI3);
22 declare!(EXTI4);
23 declare!(DMA1_STREAM0);
24 declare!(DMA1_STREAM1);
25 declare!(DMA1_STREAM2);
26 declare!(DMA1_STREAM3);
27 declare!(DMA1_STREAM4);
28 declare!(DMA1_STREAM5);
29 declare!(DMA1_STREAM6);
30 declare!(ADC);
31 declare!(EXTI9_5);
32 declare!(TIM1_BRK_TIM9);
33 declare!(TIM1_UP_TIM10);
34 declare!(TIM1_TRG_COM_TIM11);
35 declare!(TIM1_CC);
36 declare!(TIM2);
37 declare!(TIM3);
38 declare!(TIM4);
39 declare!(I2C1_EV);
40 declare!(I2C1_ER);
41 declare!(I2C2_EV);
42 declare!(I2C2_ER);
43 declare!(SPI1);
44 declare!(SPI2);
45 declare!(USART1);
46 declare!(USART2);
47 declare!(EXTI15_10);
48 declare!(RTC_ALARM);
49 declare!(OTG_FS_WKUP);
50 declare!(DMA1_STREAM7);
51 declare!(SDIO);
52 declare!(TIM5);
53 declare!(SPI3);
54 declare!(DMA2_STREAM0);
55 declare!(DMA2_STREAM1);
56 declare!(DMA2_STREAM2);
57 declare!(DMA2_STREAM3);
58 declare!(DMA2_STREAM4);
59 declare!(OTG_FS);
60 declare!(DMA2_STREAM5);
61 declare!(DMA2_STREAM6);
62 declare!(DMA2_STREAM7);
63 declare!(USART6);
64 declare!(I2C3_EV);
65 declare!(I2C3_ER);
66 declare!(FPU);
67 declare!(SPI4);
68}
69
70#[cfg(feature = "stm32f405")]
71mod irqs {
72 use super::*;
73 declare!(WWDG);
74 declare!(PVD);
75 declare!(TAMP_STAMP);
76 declare!(RTC_WKUP);
77 // declare!(FLASH);
78 declare!(RCC);
79 declare!(EXTI0);
80 declare!(EXTI1);
81 declare!(EXTI2);
82 declare!(EXTI3);
83 declare!(EXTI4);
84 declare!(DMA1_STREAM0);
85 declare!(DMA1_STREAM1);
86 declare!(DMA1_STREAM2);
87 declare!(DMA1_STREAM3);
88 declare!(DMA1_STREAM4);
89 declare!(DMA1_STREAM5);
90 declare!(DMA1_STREAM6);
91 declare!(ADC);
92 declare!(CAN1_TX);
93 declare!(CAN1_RX0);
94 declare!(CAN1_RX1);
95 declare!(CAN1_SCE);
96 declare!(EXTI9_5);
97 declare!(TIM1_BRK_TIM9);
98 declare!(TIM1_UP_TIM10);
99 declare!(TIM1_TRG_COM_TIM11);
100 declare!(TIM1_CC);
101 declare!(TIM2);
102 declare!(TIM3);
103 declare!(TIM4);
104 declare!(I2C1_EV);
105 declare!(I2C1_ER);
106 declare!(I2C2_EV);
107 declare!(I2C2_ER);
108 declare!(SPI1);
109 declare!(SPI2);
110 declare!(USART1);
111 declare!(USART2);
112 declare!(USART3);
113 declare!(EXTI15_10);
114 declare!(RTC_ALARM);
115 declare!(OTG_FS_WKUP);
116 declare!(TIM8_BRK_TIM12);
117 declare!(TIM8_UP_TIM13);
118 declare!(TIM8_TRG_COM_TIM14);
119 declare!(TIM8_CC);
120 declare!(DMA1_STREAM7);
121 // declare!(FMC);
122 declare!(SDIO);
123 declare!(TIM5);
124 declare!(SPI3);
125 declare!(UART4);
126 declare!(UART5);
127 declare!(TIM6_DAC);
128 declare!(TIM7);
129 declare!(DMA2_STREAM0);
130 declare!(DMA2_STREAM1);
131 declare!(DMA2_STREAM2);
132 declare!(DMA2_STREAM3);
133 declare!(DMA2_STREAM4);
134 declare!(ETH);
135 declare!(ETH_WKUP);
136 declare!(CAN2_TX);
137 declare!(CAN2_RX0);
138 declare!(CAN2_RX1);
139 declare!(CAN2_SCE);
140 declare!(OTG_FS);
141 declare!(DMA2_STREAM5);
142 declare!(DMA2_STREAM6);
143 declare!(DMA2_STREAM7);
144 declare!(USART6);
145 declare!(I2C3_EV);
146 declare!(I2C3_ER);
147 declare!(OTG_HS_EP1_OUT);
148 declare!(OTG_HS_EP1_IN);
149 declare!(OTG_HS_WKUP);
150 declare!(OTG_HS);
151 declare!(DCMI);
152 declare!(CRYP);
153 declare!(HASH_RNG);
154 declare!(FPU);
155 // declare!(UART7);
156 // declare!(UART8);
157 // declare!(SPI4);
158 // declare!(SPI5);
159 // declare!(SPI6);
160 // declare!(SAI1);
161 // declare!(LCD_TFT);
162 // declare!(LCD_TFT_1);
163 // declare!(DMA2D);
164}
165
166#[cfg(feature = "stm32f407")]
167mod irqs {
168 use super::*;
169
170 declare!(WWDG);
171 declare!(PVD);
172 declare!(TAMP_STAMP);
173 declare!(RTC_WKUP);
174 declare!(RCC);
175 declare!(EXTI0);
176 declare!(EXTI1);
177 declare!(EXTI2);
178 declare!(EXTI3);
179 declare!(EXTI4);
180 declare!(DMA1_STREAM0);
181 declare!(DMA1_STREAM1);
182 declare!(DMA1_STREAM2);
183 declare!(DMA1_STREAM3);
184 declare!(DMA1_STREAM4);
185 declare!(DMA1_STREAM5);
186 declare!(DMA1_STREAM6);
187 declare!(ADC);
188 declare!(CAN1_TX);
189 declare!(CAN1_RX0);
190 declare!(CAN1_RX1);
191 declare!(CAN1_SCE);
192 declare!(EXTI9_5);
193 declare!(TIM1_BRK_TIM9);
194 declare!(TIM1_UP_TIM10);
195 declare!(TIM1_TRG_COM_TIM11);
196 declare!(TIM1_CC);
197 declare!(TIM2);
198 declare!(TIM3);
199 declare!(TIM4);
200 declare!(I2C1_EV);
201 declare!(I2C1_ER);
202 declare!(I2C2_EV);
203 declare!(I2C2_ER);
204 declare!(SPI1);
205 declare!(SPI2);
206 declare!(USART1);
207 declare!(USART2);
208 declare!(USART3);
209 declare!(EXTI15_10);
210 declare!(RTC_ALARM);
211 declare!(OTG_FS_WKUP);
212 declare!(TIM8_BRK_TIM12);
213 declare!(TIM8_UP_TIM13);
214 declare!(TIM8_TRG_COM_TIM14);
215 declare!(TIM8_CC);
216 declare!(DMA1_STREAM7);
217 declare!(FSMC);
218 declare!(SDIO);
219 declare!(TIM5);
220 declare!(SPI3);
221 declare!(UART4);
222 declare!(UART5);
223 declare!(TIM6_DAC);
224 declare!(TIM7);
225 declare!(DMA2_STREAM0);
226 declare!(DMA2_STREAM1);
227 declare!(DMA2_STREAM2);
228 declare!(DMA2_STREAM3);
229 declare!(DMA2_STREAM4);
230 declare!(ETH);
231 declare!(ETH_WKUP);
232 declare!(CAN2_TX);
233 declare!(CAN2_RX0);
234 declare!(CAN2_RX1);
235 declare!(CAN2_SCE);
236 declare!(OTG_FS);
237 declare!(DMA2_STREAM5);
238 declare!(DMA2_STREAM6);
239 declare!(DMA2_STREAM7);
240 declare!(USART6);
241 declare!(I2C3_EV);
242 declare!(I2C3_ER);
243 declare!(OTG_HS_EP1_OUT);
244 declare!(OTG_HS_EP1_IN);
245 declare!(OTG_HS_WKUP);
246 declare!(OTG_HS);
247 declare!(DCMI);
248 declare!(CRYP);
249 declare!(HASH_RNG);
250 declare!(FPU);
251 declare!(LCD_TFT);
252 declare!(LCD_TFT_1);
253}
254
255#[cfg(feature = "stm32f410")]
256mod irqs {
257 use super::*;
258
259 declare!(WWDG);
260 declare!(PVD);
261 declare!(TAMP_STAMP);
262 declare!(RTC_WKUP);
263 declare!(FLASH);
264 declare!(RCC);
265 declare!(EXTI0);
266 declare!(EXTI1);
267 declare!(EXTI2);
268 declare!(EXTI3);
269 declare!(EXTI4);
270 declare!(DMA1_STREAM0);
271 declare!(DMA1_STREAM1);
272 declare!(DMA1_STREAM2);
273 declare!(DMA1_STREAM3);
274 declare!(DMA1_STREAM4);
275 declare!(DMA1_STREAM5);
276 declare!(DMA1_STREAM6);
277 declare!(ADC);
278 declare!(EXTI9_5);
279 declare!(TIM1_BRK_TIM9);
280 declare!(PWM1_UP);
281 declare!(TIM1_TRG_COM_TIM11);
282 declare!(TIM1_CC);
283 declare!(I2C1_EV);
284 declare!(I2C1_ER);
285 declare!(I2C2_EV);
286 declare!(I2C2_ER);
287 declare!(SPI1);
288 declare!(SPI2);
289 declare!(USART1);
290 declare!(USART2);
291 declare!(EXTI15_10);
292 declare!(RTC_ALARM);
293 declare!(DMA1_STREAM7);
294 declare!(TIM5);
295 declare!(TIM6_DAC1);
296 declare!(DMA2_STREAM0);
297 declare!(DMA2_STREAM1);
298 declare!(DMA2_STREAM2);
299 declare!(DMA2_STREAM3);
300 declare!(DMA2_STREAM4);
301 declare!(EXTI19);
302 declare!(DMA2_STREAM5);
303 declare!(DMA2_STREAM6);
304 declare!(DMA2_STREAM7);
305 declare!(USART6);
306 declare!(EXTI20);
307 declare!(RNG);
308 declare!(FPU);
309 declare!(SPI5);
310 declare!(I2C4_EV);
311 declare!(I2C4_ER);
312 declare!(LPTIM1);
313}
314
315#[cfg(feature = "stm32f411")]
316mod irqs {
317 use super::*;
318
319 declare!(WWDG);
320 declare!(PVD);
321 declare!(TAMP_STAMP);
322 declare!(RTC_WKUP);
323 declare!(FLASH);
324 declare!(RCC);
325 declare!(EXTI0);
326 declare!(EXTI1);
327 declare!(EXTI2);
328 declare!(EXTI3);
329 declare!(EXTI4);
330 declare!(DMA1_STREAM0);
331 declare!(DMA1_STREAM1);
332 declare!(DMA1_STREAM2);
333 declare!(DMA1_STREAM3);
334 declare!(DMA1_STREAM4);
335 declare!(DMA1_STREAM5);
336 declare!(DMA1_STREAM6);
337 declare!(ADC);
338 declare!(EXTI9_5);
339 declare!(TIM1_BRK_TIM9);
340 declare!(TIM1_UP_TIM10);
341 declare!(TIM1_TRG_COM_TIM11);
342 declare!(TIM1_CC);
343 declare!(TIM2);
344 declare!(TIM3);
345 declare!(TIM4);
346 declare!(I2C1_EV);
347 declare!(I2C1_ER);
348 declare!(I2C2_EV);
349 declare!(I2C2_ER);
350 declare!(SPI1);
351 declare!(SPI2);
352 declare!(USART1);
353 declare!(USART2);
354 declare!(EXTI15_10);
355 declare!(RTC_ALARM);
356 declare!(OTG_FS_WKUP);
357 declare!(DMA1_STREAM7);
358 declare!(SDIO);
359 declare!(TIM5);
360 declare!(SPI3);
361 declare!(DMA2_STREAM0);
362 declare!(DMA2_STREAM1);
363 declare!(DMA2_STREAM2);
364 declare!(DMA2_STREAM3);
365 declare!(DMA2_STREAM4);
366 declare!(OTG_FS);
367 declare!(DMA2_STREAM5);
368 declare!(DMA2_STREAM6);
369 declare!(DMA2_STREAM7);
370 declare!(USART6);
371 declare!(I2C3_EV);
372 declare!(I2C3_ER);
373 declare!(FPU);
374 declare!(SPI4);
375 declare!(SPI5);
376}
377
378#[cfg(feature = "stm32f412")]
379mod irqs {
380 use super::*;
381
382 declare!(WWDG);
383 declare!(PVD);
384 declare!(TAMP_STAMP);
385 declare!(RTC_WKUP);
386 declare!(FLASH);
387 declare!(RCC);
388 declare!(EXTI0);
389 declare!(EXTI1);
390 declare!(EXTI2);
391 declare!(EXTI3);
392 declare!(EXTI4);
393 declare!(DMA1_STREAM0);
394 declare!(DMA1_STREAM1);
395 declare!(DMA1_STREAM2);
396 declare!(DMA1_STREAM3);
397 declare!(DMA1_STREAM4);
398 declare!(DMA1_STREAM5);
399 declare!(DMA1_STREAM6);
400 declare!(ADC);
401 declare!(CAN1_TX);
402 declare!(CAN1_RX0);
403 declare!(CAN1_RX1);
404 declare!(CAN1_SCE);
405 declare!(EXTI9_5);
406 declare!(TIM1_BRK_TIM9);
407 declare!(TIM1_UP_TIM10);
408 declare!(TIM1_TRG_COM_TIM11);
409 declare!(TIM1_CC);
410 declare!(TIM2);
411 declare!(TIM3);
412 declare!(TIM4);
413 declare!(I2C1_EV);
414 declare!(I2C1_ER);
415 declare!(I2C2_EV);
416 declare!(I2C2_ER);
417 declare!(SPI1);
418 declare!(SPI2);
419 declare!(USART1);
420 declare!(USART2);
421 declare!(USART3);
422 declare!(EXTI15_10);
423 declare!(RTC_ALARM);
424 declare!(OTG_FS_WKUP);
425 declare!(TIM12);
426 declare!(TIM13);
427 declare!(TIM14);
428 declare!(TIM8_CC);
429 declare!(DMA1_STREAM7);
430 declare!(FSMC);
431 declare!(SDIO);
432 declare!(TIM5);
433 declare!(SPI3);
434 declare!(TIM6_DACUNDER);
435 declare!(TIM7);
436 declare!(DMA2_STREAM0);
437 declare!(DMA2_STREAM1);
438 declare!(DMA2_STREAM2);
439 declare!(DMA2_STREAM3);
440 declare!(DMA2_STREAM4);
441 declare!(DFSDM1_FLT0);
442 declare!(DFSDM1_FLT1);
443 declare!(CAN2_TX);
444 declare!(CAN2_RX0);
445 declare!(CAN2_RX1);
446 declare!(CAN2_SCE);
447 declare!(OTG_FS);
448 declare!(DMA2_STREAM5);
449 declare!(DMA2_STREAM6);
450 declare!(DMA2_STREAM7);
451 declare!(USART6);
452 declare!(I2C3_EV);
453 declare!(I2C3_ER);
454 declare!(HASH_RNG);
455 declare!(FPU);
456 declare!(SPI4);
457 declare!(SPI5);
458 declare!(QUAD_SPI);
459 declare!(I2CFMP1_EVENT);
460 declare!(I2CFMP1_ERROR);
461}
462
463#[cfg(feature = "stm32f413")]
464mod irqs {
465 use super::*;
466
467 declare!(PVD);
468 declare!(TAMP_STAMP);
469 declare!(RTC_WKUP);
470 declare!(FLASH);
471 declare!(RCC);
472 declare!(EXTI0);
473 declare!(EXTI1);
474 declare!(EXTI2);
475 declare!(EXTI3);
476 declare!(EXTI4);
477 declare!(DMA1_STREAM0);
478 declare!(DMA1_STREAM1);
479 declare!(DMA1_STREAM2);
480 declare!(DMA1_STREAM3);
481 declare!(DMA1_STREAM4);
482 declare!(DMA1_STREAM5);
483 declare!(DMA1_STREAM6);
484 declare!(ADC);
485 declare!(CAN1_TX);
486 declare!(CAN1_RX0);
487 declare!(CAN1_RX1);
488 declare!(CAN1_SCE);
489 declare!(EXTI9_5);
490 declare!(TIM1_BRK_TIM9);
491 declare!(TIM1_UP_TIM10);
492 declare!(TIM1_TRG_COM_TIM11);
493 declare!(TIM1_CC);
494 declare!(TIM2);
495 declare!(TIM3);
496 declare!(TIM4);
497 declare!(I2C1_EVT);
498 declare!(I2C1_ERR);
499 declare!(I2C2_EVT);
500 declare!(I2C2_ERR);
501 declare!(SPI1);
502 declare!(SPI2);
503 declare!(USART1);
504 declare!(USART2);
505 declare!(USART3);
506 declare!(EXTI15_10);
507 declare!(EXTI17_RTC_ALARM);
508 declare!(TIM8_BRK_TIM12);
509 declare!(TIM8_UP_TIM13);
510 declare!(TIM8_TRG_COM_TIM14);
511 declare!(TIM8_CC);
512 declare!(DMA1_STREAM7);
513 declare!(FSMC);
514 declare!(SDIO);
515 declare!(TIM5);
516 declare!(SPI3);
517 declare!(USART4);
518 declare!(UART5);
519 declare!(TIM6_GLB_IT_DAC1_DAC2);
520 declare!(TIM7);
521 declare!(DMA2_STREAM0);
522 declare!(DMA2_STREAM1);
523 declare!(DMA2_STREAM2);
524 declare!(DMA2_STREAM3);
525 declare!(DMA2_STREAM4);
526 declare!(DFSDM1_FLT0);
527 declare!(DFSDM1_FLT1);
528 declare!(CAN2_TX);
529 declare!(CAN2_RX0);
530 declare!(CAN2_RX1);
531 declare!(CAN2_SCE);
532 declare!(OTG_FS);
533 declare!(DMA2_STREAM5);
534 declare!(DMA2_STREAM6);
535 declare!(DMA2_STREAM7);
536 declare!(USART6);
537 declare!(I2C3_EV);
538 declare!(I2C3_ER);
539 declare!(CAN3_TX);
540 declare!(CAN3_RX0);
541 declare!(CAN3_RX1);
542 declare!(CAN3_SCE);
543 declare!(CRYPTO);
544 declare!(RNG);
545 declare!(FPU);
546 declare!(USART7);
547 declare!(USART8);
548 declare!(SPI4);
549 declare!(SPI5);
550 declare!(SAI1);
551 declare!(UART9);
552 declare!(UART10);
553 declare!(QUADSPI);
554 declare!(I2CFMP1EVENT);
555 declare!(I2CFMP1ERROR);
556 declare!(LPTIM1_OR_IT_EIT_23);
557 declare!(DFSDM2_FILTER1);
558 declare!(DFSDM2_FILTER2);
559 declare!(DFSDM2_FILTER3);
560 declare!(DFSDM2_FILTER4);
561}
562
563#[cfg(feature = "stm32f427")]
564mod irqs {
565 use super::*;
566
567 declare!(WWDG);
568 declare!(PVD);
569 declare!(TAMP_STAMP);
570 declare!(RTC_WKUP);
571 declare!(FLASH);
572 declare!(RCC);
573 declare!(EXTI0);
574 declare!(EXTI1);
575 declare!(EXTI2);
576 declare!(EXTI3);
577 declare!(EXTI4);
578 declare!(DMA1_STREAM0);
579 declare!(DMA1_STREAM1);
580 declare!(DMA1_STREAM2);
581 declare!(DMA1_STREAM3);
582 declare!(DMA1_STREAM4);
583 declare!(DMA1_STREAM5);
584 declare!(DMA1_STREAM6);
585 declare!(ADC);
586 declare!(CAN1_TX);
587 declare!(CAN1_RX0);
588 declare!(CAN1_RX1);
589 declare!(CAN1_SCE);
590 declare!(EXTI9_5);
591 declare!(TIM1_BRK_TIM9);
592 declare!(TIM1_UP_TIM10);
593 declare!(TIM1_TRG_COM_TIM11);
594 declare!(TIM1_CC);
595 declare!(TIM2);
596 declare!(TIM3);
597 declare!(TIM4);
598 declare!(I2C1_EV);
599 declare!(I2C1_ER);
600 declare!(I2C2_EV);
601 declare!(I2C2_ER);
602 declare!(SPI1);
603 declare!(SPI2);
604 declare!(USART1);
605 declare!(USART2);
606 declare!(USART3);
607 declare!(EXTI15_10);
608 declare!(RTC_ALARM);
609 declare!(OTG_FS_WKUP);
610 declare!(TIM8_BRK_TIM12);
611 declare!(TIM8_UP_TIM13);
612 declare!(TIM8_TRG_COM_TIM14);
613 declare!(TIM8_CC);
614 declare!(DMA1_STREAM7);
615 declare!(FMC);
616 declare!(SDIO);
617 declare!(TIM5);
618 declare!(SPI3);
619 declare!(UART4);
620 declare!(UART5);
621 declare!(TIM6_DAC);
622 declare!(TIM7);
623 declare!(DMA2_STREAM0);
624 declare!(DMA2_STREAM1);
625 declare!(DMA2_STREAM2);
626 declare!(DMA2_STREAM3);
627 declare!(DMA2_STREAM4);
628 declare!(ETH);
629 declare!(ETH_WKUP);
630 declare!(CAN2_TX);
631 declare!(CAN2_RX0);
632 declare!(CAN2_RX1);
633 declare!(CAN2_SCE);
634 declare!(OTG_FS);
635 declare!(DMA2_STREAM5);
636 declare!(DMA2_STREAM6);
637 declare!(DMA2_STREAM7);
638 declare!(USART6);
639 declare!(I2C3_EV);
640 declare!(I2C3_ER);
641 declare!(OTG_HS_EP1_OUT);
642 declare!(OTG_HS_EP1_IN);
643 declare!(OTG_HS_WKUP);
644 declare!(OTG_HS);
645 declare!(DCMI);
646 declare!(CRYP);
647 declare!(HASH_RNG);
648 declare!(FPU);
649 declare!(UART7);
650 declare!(UART8);
651 declare!(SPI4);
652 declare!(SPI5);
653 declare!(SPI6);
654 declare!(LCD_TFT);
655 declare!(LCD_TFT_1);
656}
657
658#[cfg(feature = "stm32f429")]
659mod irqs {
660 use super::*;
661
662 declare!(WWDG);
663 declare!(PVD);
664 declare!(TAMP_STAMP);
665 declare!(RTC_WKUP);
666 declare!(FLASH);
667 declare!(RCC);
668 declare!(EXTI0);
669 declare!(EXTI1);
670 declare!(EXTI2);
671 declare!(EXTI3);
672 declare!(EXTI4);
673 declare!(DMA1_STREAM0);
674 declare!(DMA1_STREAM1);
675 declare!(DMA1_STREAM2);
676 declare!(DMA1_STREAM3);
677 declare!(DMA1_STREAM4);
678 declare!(DMA1_STREAM5);
679 declare!(DMA1_STREAM6);
680 declare!(ADC);
681 declare!(CAN1_TX);
682 declare!(CAN1_RX0);
683 declare!(CAN1_RX1);
684 declare!(CAN1_SCE);
685 declare!(EXTI9_5);
686 declare!(TIM1_BRK_TIM9);
687 declare!(TIM1_UP_TIM10);
688 declare!(TIM1_TRG_COM_TIM11);
689 declare!(TIM1_CC);
690 declare!(TIM2);
691 declare!(TIM3);
692 declare!(TIM4);
693 declare!(I2C1_EV);
694 declare!(I2C1_ER);
695 declare!(I2C2_EV);
696 declare!(I2C2_ER);
697 declare!(SPI1);
698 declare!(SPI2);
699 declare!(USART1);
700 declare!(USART2);
701 declare!(USART3);
702 declare!(EXTI15_10);
703 declare!(RTC_ALARM);
704 declare!(OTG_FS_WKUP);
705 declare!(TIM8_BRK_TIM12);
706 declare!(TIM8_UP_TIM13);
707 declare!(TIM8_TRG_COM_TIM14);
708 declare!(TIM8_CC);
709 declare!(DMA1_STREAM7);
710 declare!(FMC);
711 declare!(SDIO);
712 declare!(TIM5);
713 declare!(SPI3);
714 declare!(UART4);
715 declare!(UART5);
716 declare!(TIM6_DAC);
717 declare!(TIM7);
718 declare!(DMA2_STREAM0);
719 declare!(DMA2_STREAM1);
720 declare!(DMA2_STREAM2);
721 declare!(DMA2_STREAM3);
722 declare!(DMA2_STREAM4);
723 declare!(ETH);
724 declare!(ETH_WKUP);
725 declare!(CAN2_TX);
726 declare!(CAN2_RX0);
727 declare!(CAN2_RX1);
728 declare!(CAN2_SCE);
729 declare!(OTG_FS);
730 declare!(DMA2_STREAM5);
731 declare!(DMA2_STREAM6);
732 declare!(DMA2_STREAM7);
733 declare!(USART6);
734 declare!(I2C3_EV);
735 declare!(I2C3_ER);
736 declare!(OTG_HS_EP1_OUT);
737 declare!(OTG_HS_EP1_IN);
738 declare!(OTG_HS_WKUP);
739 declare!(OTG_HS);
740 declare!(DCMI);
741 declare!(CRYP);
742 declare!(HASH_RNG);
743 declare!(FPU);
744 declare!(UART7);
745 declare!(UART8);
746 declare!(SPI4);
747 declare!(SPI5);
748 declare!(SPI6);
749 declare!(SAI1);
750 declare!(LCD_TFT);
751 declare!(LCD_TFT_1);
752 declare!(DMA2D);
753}
754
755#[cfg(feature = "stm32f446")]
756mod irqs {
757 use super::*;
758
759 declare!(WWDG);
760 declare!(TAMP_STAMP);
761 declare!(RTC_WKUP);
762 declare!(FLASH);
763 declare!(RCC);
764 declare!(EXTI0);
765 declare!(EXTI1);
766 declare!(EXTI2);
767 declare!(EXTI3);
768 declare!(EXTI4);
769 declare!(DMA1_STREAM0);
770 declare!(DMA1_STREAM1);
771 declare!(DMA1_STREAM2);
772 declare!(DMA1_STREAM3);
773 declare!(DMA1_STREAM4);
774 declare!(DMA1_STREAM5);
775 declare!(DMA1_STREAM6);
776 declare!(ADC);
777 declare!(CAN1_TX);
778 declare!(CAN1_RX0);
779 declare!(CAN1_RX1);
780 declare!(CAN1_SCE);
781 declare!(EXTI9_5);
782 declare!(TIM1_BRK_TIM9);
783 declare!(TIM1_UP_TIM10);
784 declare!(TIM1_TRG_COM_TIM11);
785 declare!(TIM1_CC);
786 declare!(TIM2);
787 declare!(TIM3);
788 declare!(TIM4);
789 declare!(I2C1_EV);
790 declare!(I2C1_ER);
791 declare!(I2C2_EV);
792 declare!(I2C2_ER);
793 declare!(SPI1);
794 declare!(SPI2);
795 declare!(USART1);
796 declare!(USART2);
797 declare!(USART3);
798 declare!(EXTI15_10);
799 declare!(RTC_ALARM);
800 declare!(OTG_FS_WKUP);
801 declare!(TIM8_BRK_TIM12);
802 declare!(TIM8_UP_TIM13);
803 declare!(TIM8_TRG_COM_TIM14);
804 declare!(TIM8_CC);
805 declare!(DMA1_STREAM7);
806 declare!(FMC);
807 // declare!(SDIO);
808 declare!(TIM5);
809 declare!(SPI3);
810 declare!(UART4);
811 declare!(UART5);
812 declare!(TIM6_DAC);
813 declare!(TIM7);
814 declare!(DMA2_STREAM0);
815 declare!(DMA2_STREAM1);
816 declare!(DMA2_STREAM2);
817 declare!(DMA2_STREAM3);
818 declare!(DMA2_STREAM4);
819 declare!(ETH);
820 declare!(ETH_WKUP);
821 declare!(CAN2_TX);
822 declare!(CAN2_RX0);
823 declare!(CAN2_RX1);
824 declare!(CAN2_SCE);
825 declare!(OTG_FS);
826 declare!(DMA2_STREAM5);
827 declare!(DMA2_STREAM6);
828 declare!(DMA2_STREAM7);
829 declare!(USART6);
830 declare!(I2C3_EV);
831 declare!(I2C3_ER);
832 declare!(DCMI);
833 declare!(FPU);
834 declare!(UART7);
835 declare!(UART8);
836 declare!(SPI4);
837 declare!(LCD_TFT);
838 declare!(LCD_TFT_1);
839}
840
841#[cfg(feature = "stm32f469")]
842mod irqs {
843 use super::*;
844
845 declare!(WWDG);
846 declare!(PVD);
847 declare!(TAMP_STAMP);
848 declare!(RTC_WKUP);
849 declare!(FLASH);
850 declare!(RCC);
851 declare!(EXTI0);
852 declare!(EXTI1);
853 declare!(EXTI2);
854 declare!(EXTI3);
855 declare!(EXTI4);
856 declare!(DMA1_STREAM0);
857 declare!(DMA1_STREAM1);
858 declare!(DMA1_STREAM2);
859 declare!(DMA1_STREAM3);
860 declare!(DMA1_STREAM4);
861 declare!(DMA1_STREAM5);
862 declare!(DMA1_STREAM6);
863 declare!(ADC);
864 declare!(CAN1_TX);
865 declare!(CAN1_RX0);
866 declare!(CAN1_RX1);
867 declare!(CAN1_SCE);
868 declare!(EXTI9_5);
869 declare!(TIM1_BRK_TIM9);
870 declare!(TIM1_UP_TIM10);
871 declare!(TIM1_TRG_COM_TIM11);
872 declare!(TIM1_CC);
873 declare!(TIM2);
874 declare!(TIM3);
875 declare!(TIM4);
876 declare!(I2C1_EV);
877 declare!(I2C1_ER);
878 declare!(I2C2_EV);
879 declare!(I2C2_ER);
880 declare!(SPI1);
881 declare!(SPI2);
882 declare!(USART1);
883 declare!(USART2);
884 declare!(USART3);
885 declare!(EXTI15_10);
886 declare!(RTC_ALARM);
887 declare!(OTG_FS_WKUP);
888 declare!(TIM8_BRK_TIM12);
889 declare!(TIM8_UP_TIM13);
890 declare!(TIM8_TRG_COM_TIM14);
891 declare!(TIM8_CC);
892 declare!(DMA1_STREAM7);
893 declare!(FMC);
894 declare!(SDIO);
895 declare!(TIM5);
896 declare!(SPI3);
897 declare!(UART4);
898 declare!(UART5);
899 declare!(TIM6_DAC);
900 declare!(TIM7);
901 declare!(DMA2_STREAM0);
902 declare!(DMA2_STREAM1);
903 declare!(DMA2_STREAM2);
904 declare!(DMA2_STREAM3);
905 declare!(DMA2_STREAM4);
906 declare!(ETH);
907 declare!(ETH_WKUP);
908 declare!(CAN2_TX);
909 declare!(CAN2_RX0);
910 declare!(CAN2_RX1);
911 declare!(CAN2_SCE);
912 declare!(OTG_FS);
913 declare!(DMA2_STREAM5);
914 declare!(DMA2_STREAM6);
915 declare!(DMA2_STREAM7);
916 declare!(USART6);
917 declare!(I2C3_EV);
918 declare!(I2C3_ER);
919 declare!(OTG_HS_EP1_OUT);
920 declare!(OTG_HS_EP1_IN);
921 declare!(OTG_HS_WKUP);
922 declare!(OTG_HS);
923 declare!(DCMI);
924 declare!(CRYP);
925 declare!(HASH_RNG);
926 declare!(FPU);
927 declare!(UART7);
928 declare!(UART8);
929 declare!(SPI4);
930 declare!(SPI5);
931 declare!(SPI6);
932 declare!(SAI1);
933 declare!(LCD_TFT);
934 declare!(LCD_TFT_1);
935 declare!(DMA2D);
936 declare!(QUADSPI);
937 declare!(DSIHOST);
938}
939
940#[cfg(feature = "stm32l0x1")]
941mod irqs {
942 use super::*;
943 declare!(WWDG);
944 declare!(PVD);
945 declare!(RTC);
946 declare!(FLASH);
947 declare!(RCC);
948 declare!(EXTI0_1);
949 declare!(EXTI2_3);
950 declare!(EXTI4_15);
951 declare!(DMA1_CHANNEL1);
952 declare!(DMA1_CHANNEL2_3);
953 declare!(DMA1_CHANNEL4_7);
954 declare!(ADC_COMP);
955 declare!(LPTIM1);
956 declare!(USART4_USART5);
957 declare!(TIM2);
958 declare!(TIM3);
959 declare!(TIM6);
960 declare!(TIM7);
961 declare!(TIM21);
962 declare!(I2C3);
963 declare!(TIM22);
964 declare!(I2C1);
965 declare!(I2C2);
966 declare!(SPI1);
967 declare!(SPI2);
968 declare!(USART1);
969 declare!(USART2);
970 declare!(AES_RNG_LPUART1);
971}
972
973#[cfg(feature = "stm32l0x2")]
974mod irqs {
975 use super::*;
976 declare!(WWDG);
977 declare!(PVD);
978 declare!(RTC);
979 declare!(RCC);
980 declare!(EXTI0_1);
981 declare!(EXTI2_3);
982 declare!(EXTI4_15);
983 declare!(TSC);
984 declare!(DMA1_CHANNEL1);
985 declare!(DMA1_CHANNEL2_3);
986 declare!(DMA1_CHANNEL4_7);
987 declare!(ADC_COMP);
988 declare!(LPTIM1);
989 declare!(USART4_USART5);
990 declare!(TIM2);
991 declare!(TIM3);
992 declare!(TIM6_DAC);
993 declare!(TIM7);
994 declare!(TIM21);
995 declare!(I2C3);
996 declare!(TIM22);
997 declare!(I2C1);
998 declare!(I2C2);
999 declare!(SPI1);
1000 declare!(SPI2);
1001 declare!(USART1);
1002 declare!(USART2);
1003 declare!(AES_RNG_LPUART1);
1004 declare!(USB);
1005}
1006
1007#[cfg(feature = "stm32l0x3")]
1008mod irqs {
1009 use super::*;
1010 declare!(WWDG);
1011 declare!(PVD);
1012 declare!(RTC);
1013 declare!(RCC);
1014 declare!(EXTI0_1);
1015 declare!(EXTI2_3);
1016 declare!(EXTI4_15);
1017 declare!(TSC);
1018 declare!(DMA1_CHANNEL1);
1019 declare!(DMA1_CHANNEL2_3);
1020 declare!(DMA1_CHANNEL4_7);
1021 declare!(ADC_COMP);
1022 declare!(LPTIM1);
1023 declare!(USART4_USART5);
1024 declare!(TIM2);
1025 declare!(TIM3);
1026 declare!(TIM6_DAC);
1027 declare!(TIM7);
1028 declare!(TIM21);
1029 declare!(I2C3);
1030 declare!(TIM22);
1031 declare!(I2C1);
1032 declare!(I2C2);
1033 declare!(SPI1);
1034 declare!(SPI2);
1035 declare!(USART1);
1036 declare!(USART2);
1037 declare!(AES_RNG_LPUART1);
1038 declare!(LCD);
1039 declare!(USB);
1040}
1041
1042pub use irqs::*;
diff --git a/embassy-stm32/src/l0/mod.rs b/embassy-stm32/src/l0/mod.rs
deleted file mode 100644
index 53b44fe2d..000000000
--- a/embassy-stm32/src/l0/mod.rs
+++ /dev/null
@@ -1,2 +0,0 @@
1pub mod rtc;
2pub mod system;
diff --git a/embassy-stm32/src/l0/rtc.rs b/embassy-stm32/src/l0/rtc.rs
deleted file mode 100644
index fa5011d3a..000000000
--- a/embassy-stm32/src/l0/rtc.rs
+++ /dev/null
@@ -1,372 +0,0 @@
1use crate::hal::rcc::Clocks;
2use atomic_polyfill::{compiler_fence, AtomicU32, Ordering};
3use core::cell::Cell;
4use core::convert::TryInto;
5use critical_section::CriticalSection;
6use embassy::interrupt::InterruptExt;
7use embassy::time::{Clock, TICKS_PER_SECOND};
8use embassy::util::CriticalSectionMutex as Mutex;
9
10use crate::interrupt;
11use crate::interrupt::Interrupt;
12
13// RTC timekeeping works with something we call "periods", which are time intervals
14// of 2^15 ticks. The RTC counter value is 16 bits, so one "overflow cycle" is 2 periods.
15//
16// A `period` count is maintained in parallel to the RTC hardware `counter`, like this:
17// - `period` and `counter` start at 0
18// - `period` is incremented on overflow (at counter value 0)
19// - `period` is incremented "midway" between overflows (at counter value 0x8000)
20//
21// Therefore, when `period` is even, counter is in 0..0x7FFF. When odd, counter is in 0x8000..0xFFFF
22// This allows for now() to return the correct value even if it races an overflow.
23//
24// To get `now()`, `period` is read first, then `counter` is read. If the counter value matches
25// the expected range for the `period` parity, we're done. If it doesn't, this means that
26// a new period start has raced us between reading `period` and `counter`, so we assume the `counter` value
27// corresponds to the next period.
28//
29// `period` is a 32bit integer, so It overflows on 2^32 * 2^15 / 32768 seconds of uptime, which is 136 years.
30fn calc_now(period: u32, counter: u16) -> u64 {
31 ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64)
32}
33
34struct AlarmState {
35 timestamp: Cell<u64>,
36 callback: Cell<Option<(fn(*mut ()), *mut ())>>,
37}
38
39impl AlarmState {
40 fn new() -> Self {
41 Self {
42 timestamp: Cell::new(u64::MAX),
43 callback: Cell::new(None),
44 }
45 }
46}
47
48// TODO: This is sometimes wasteful, try to find a better way
49const ALARM_COUNT: usize = 3;
50
51/// RTC timer that can be used by the executor and to set alarms.
52///
53/// It can work with Timers 2 and 3.
54
55/// This timer works internally with a unit of 2^15 ticks, which means that if a call to
56/// [`embassy::time::Clock::now`] is blocked for that amount of ticks the returned value will be
57/// wrong (an old value). The current default tick rate is 32768 ticks per second.
58pub struct RTC<T: Instance> {
59 rtc: T,
60 irq: T::Interrupt,
61
62 /// Number of 2^23 periods elapsed since boot.
63 period: AtomicU32,
64
65 /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled.
66 alarms: Mutex<[AlarmState; ALARM_COUNT]>,
67
68 clocks: Clocks,
69}
70
71impl<T: Instance> RTC<T> {
72 pub fn new(rtc: T, irq: T::Interrupt, clocks: Clocks) -> Self {
73 Self {
74 rtc,
75 irq,
76 period: AtomicU32::new(0),
77 alarms: Mutex::new([AlarmState::new(), AlarmState::new(), AlarmState::new()]),
78 clocks,
79 }
80 }
81
82 pub fn start(&'static self) {
83 self.rtc.enable_clock();
84 self.rtc.stop_and_reset();
85
86 let freq = T::pclk(&self.clocks);
87 let psc = freq / TICKS_PER_SECOND as u32 - 1;
88 let psc: u16 = psc.try_into().unwrap();
89
90 self.rtc.set_psc_arr(psc, u16::MAX);
91 // Mid-way point
92 self.rtc.set_compare(0, 0x8000);
93 self.rtc.set_compare_interrupt(0, true);
94
95 self.irq.set_handler(|ptr| unsafe {
96 let this = &*(ptr as *const () as *const Self);
97 this.on_interrupt();
98 });
99 self.irq.set_handler_context(self as *const _ as *mut _);
100 self.irq.unpend();
101 self.irq.enable();
102
103 self.rtc.start();
104 }
105
106 fn on_interrupt(&self) {
107 if self.rtc.overflow_interrupt_status() {
108 self.rtc.overflow_clear_flag();
109 self.next_period();
110 }
111
112 // Half overflow
113 if self.rtc.compare_interrupt_status(0) {
114 self.rtc.compare_clear_flag(0);
115 self.next_period();
116 }
117
118 for n in 1..=ALARM_COUNT {
119 if self.rtc.compare_interrupt_status(n) {
120 self.rtc.compare_clear_flag(n);
121 critical_section::with(|cs| self.trigger_alarm(n, cs));
122 }
123 }
124 }
125
126 fn next_period(&self) {
127 critical_section::with(|cs| {
128 let period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
129 let t = (period as u64) << 15;
130
131 for n in 1..=ALARM_COUNT {
132 let alarm = &self.alarms.borrow(cs)[n - 1];
133 let at = alarm.timestamp.get();
134
135 let diff = at - t;
136 if diff < 0xc000 {
137 self.rtc.set_compare(n, at as u16);
138 self.rtc.set_compare_interrupt(n, true);
139 }
140 }
141 })
142 }
143
144 fn trigger_alarm(&self, n: usize, cs: CriticalSection) {
145 self.rtc.set_compare_interrupt(n, false);
146
147 let alarm = &self.alarms.borrow(cs)[n - 1];
148 alarm.timestamp.set(u64::MAX);
149
150 // Call after clearing alarm, so the callback can set another alarm.
151 if let Some((f, ctx)) = alarm.callback.get() {
152 f(ctx);
153 }
154 }
155
156 fn set_alarm_callback(&self, n: usize, callback: fn(*mut ()), ctx: *mut ()) {
157 critical_section::with(|cs| {
158 let alarm = &self.alarms.borrow(cs)[n - 1];
159 alarm.callback.set(Some((callback, ctx)));
160 })
161 }
162
163 fn set_alarm(&self, n: usize, timestamp: u64) {
164 critical_section::with(|cs| {
165 let alarm = &self.alarms.borrow(cs)[n - 1];
166 alarm.timestamp.set(timestamp);
167
168 let t = self.now();
169 if timestamp <= t {
170 self.trigger_alarm(n, cs);
171 return;
172 }
173
174 let diff = timestamp - t;
175 if diff < 0xc000 {
176 let safe_timestamp = timestamp.max(t + 3);
177 self.rtc.set_compare(n, safe_timestamp as u16);
178 self.rtc.set_compare_interrupt(n, true);
179 } else {
180 self.rtc.set_compare_interrupt(n, false);
181 }
182 });
183 }
184
185 pub fn alarm1(&'static self) -> Alarm<T> {
186 Alarm { n: 1, rtc: self }
187 }
188 pub fn alarm2(&'static self) -> Option<Alarm<T>> {
189 if T::REAL_ALARM_COUNT >= 2 {
190 Some(Alarm { n: 2, rtc: self })
191 } else {
192 None
193 }
194 }
195 pub fn alarm3(&'static self) -> Option<Alarm<T>> {
196 if T::REAL_ALARM_COUNT >= 3 {
197 Some(Alarm { n: 3, rtc: self })
198 } else {
199 None
200 }
201 }
202}
203
204impl<T: Instance> embassy::time::Clock for RTC<T> {
205 fn now(&self) -> u64 {
206 let period = self.period.load(Ordering::Relaxed);
207 compiler_fence(Ordering::Acquire);
208 let counter = self.rtc.counter();
209 calc_now(period, counter)
210 }
211}
212
213pub struct Alarm<T: Instance> {
214 n: usize,
215 rtc: &'static RTC<T>,
216}
217
218impl<T: Instance> embassy::time::Alarm for Alarm<T> {
219 fn set_callback(&self, callback: fn(*mut ()), ctx: *mut ()) {
220 self.rtc.set_alarm_callback(self.n, callback, ctx);
221 }
222
223 fn set(&self, timestamp: u64) {
224 self.rtc.set_alarm(self.n, timestamp);
225 }
226
227 fn clear(&self) {
228 self.rtc.set_alarm(self.n, u64::MAX);
229 }
230}
231
232mod sealed {
233 pub trait Sealed {}
234}
235
236pub trait Instance: sealed::Sealed + Sized + 'static {
237 type Interrupt: Interrupt;
238 const REAL_ALARM_COUNT: usize;
239
240 fn enable_clock(&self);
241 fn set_compare(&self, n: usize, value: u16);
242 fn set_compare_interrupt(&self, n: usize, enable: bool);
243 fn compare_interrupt_status(&self, n: usize) -> bool;
244 fn compare_clear_flag(&self, n: usize);
245 fn overflow_interrupt_status(&self) -> bool;
246 fn overflow_clear_flag(&self);
247 // This method should ensure that the values are really updated before returning
248 fn set_psc_arr(&self, psc: u16, arr: u16);
249 fn stop_and_reset(&self);
250 fn start(&self);
251 fn counter(&self) -> u16;
252 fn pclk(clocks: &Clocks) -> u32;
253}
254
255#[allow(unused_macros)]
256macro_rules! impl_timer {
257 ($module:ident: ($TYPE:ident, $INT:ident, $timXen:ident, $timXrst:ident, $apbenr:ident, $apbrstr:ident, $pclk: ident)) => {
258 mod $module {
259 use super::*;
260 use crate::hal::pac::{$TYPE, RCC};
261
262 impl sealed::Sealed for $TYPE {}
263
264 impl Instance for $TYPE {
265 type Interrupt = interrupt::$INT;
266 const REAL_ALARM_COUNT: usize = 3;
267
268 fn enable_clock(&self) {
269 // NOTE(unsafe) It will only be used for atomic operations
270 unsafe {
271 let rcc = &*RCC::ptr();
272
273 rcc.$apbenr.modify(|_, w| w.$timXen().set_bit());
274 rcc.$apbrstr.modify(|_, w| w.$timXrst().set_bit());
275 rcc.$apbrstr.modify(|_, w| w.$timXrst().clear_bit());
276 }
277 }
278
279 fn set_compare(&self, n: usize, value: u16) {
280 // NOTE(unsafe) these registers accept all the range of u16 values
281 match n {
282 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
283 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
284 2 => self.ccr3.write(|w| unsafe { w.bits(value.into()) }),
285 3 => self.ccr4.write(|w| unsafe { w.bits(value.into()) }),
286 _ => {}
287 }
288 }
289
290 fn set_compare_interrupt(&self, n: usize, enable: bool) {
291 if n > 3 {
292 return;
293 }
294 let bit = n as u8 + 1;
295 unsafe {
296 if enable {
297 self.dier.modify(|r, w| w.bits(r.bits() | (1 << bit)));
298 } else {
299 self.dier.modify(|r, w| w.bits(r.bits() & !(1 << bit)));
300 }
301 }
302 }
303
304 fn compare_interrupt_status(&self, n: usize) -> bool {
305 let status = self.sr.read();
306 match n {
307 0 => status.cc1if().bit_is_set(),
308 1 => status.cc2if().bit_is_set(),
309 2 => status.cc3if().bit_is_set(),
310 3 => status.cc4if().bit_is_set(),
311 _ => false,
312 }
313 }
314
315 fn compare_clear_flag(&self, n: usize) {
316 if n > 3 {
317 return;
318 }
319 let bit = n as u8 + 1;
320 unsafe {
321 self.sr.modify(|r, w| w.bits(r.bits() & !(1 << bit)));
322 }
323 }
324
325 fn overflow_interrupt_status(&self) -> bool {
326 self.sr.read().uif().bit_is_set()
327 }
328
329 fn overflow_clear_flag(&self) {
330 unsafe {
331 self.sr.modify(|_, w| w.uif().clear_bit());
332 }
333 }
334
335 fn set_psc_arr(&self, psc: u16, arr: u16) {
336 // NOTE(unsafe) All u16 values are valid
337 self.psc.write(|w| unsafe { w.bits(psc.into()) });
338 self.arr.write(|w| unsafe { w.bits(arr.into()) });
339
340 unsafe {
341 // Set URS, generate update, clear URS
342 self.cr1.modify(|_, w| w.urs().set_bit());
343 self.egr.write(|w| w.ug().set_bit());
344 self.cr1.modify(|_, w| w.urs().clear_bit());
345 }
346 }
347
348 fn stop_and_reset(&self) {
349 unsafe {
350 self.cr1.modify(|_, w| w.cen().clear_bit());
351 }
352 self.cnt.reset();
353 }
354
355 fn start(&self) {
356 self.cr1.modify(|_, w| w.cen().set_bit());
357 }
358
359 fn counter(&self) -> u16 {
360 self.cnt.read().bits() as u16
361 }
362
363 fn pclk(clocks: &Clocks) -> u32 {
364 clocks.$pclk().0
365 }
366 }
367 }
368 };
369}
370
371impl_timer!(tim2: (TIM2, TIM2, tim2en, tim2rst, apb1enr, apb1rstr, apb1_tim_clk));
372impl_timer!(tim3: (TIM3, TIM3, tim3en, tim3rst, apb1enr, apb1rstr, apb1_tim_clk));
diff --git a/embassy-stm32/src/l0/system.rs b/embassy-stm32/src/l0/system.rs
deleted file mode 100644
index 00e417d4b..000000000
--- a/embassy-stm32/src/l0/system.rs
+++ /dev/null
@@ -1,17 +0,0 @@
1use crate::{hal, pac, Peripherals};
2
3pub use hal::{
4 prelude::*,
5 rcc::{Clocks, Config},
6};
7
8/// safety: must only call once.
9pub unsafe fn configure(config: Config) {
10 let dp = pac::Peripherals::take().unwrap();
11
12 let rcc = dp.RCC.freeze(config);
13
14 let clocks = rcc.clocks;
15
16 unsafe { Peripherals::set_peripherals(clocks) };
17}
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
deleted file mode 100644
index 2fd9f1d3d..000000000
--- a/embassy-stm32/src/lib.rs
+++ /dev/null
@@ -1,478 +0,0 @@
1#![no_std]
2#![feature(generic_associated_types)]
3#![feature(asm)]
4#![feature(min_type_alias_impl_trait)]
5#![feature(impl_trait_in_bindings)]
6#![feature(type_alias_impl_trait)]
7#![allow(incomplete_features)]
8
9#[cfg(any(
10 feature = "stm32f401",
11 feature = "stm32f405",
12 feature = "stm32f407",
13 feature = "stm32f410",
14 feature = "stm32f411",
15 feature = "stm32f412",
16 feature = "stm32f413",
17 feature = "stm32f415",
18 feature = "stm32f417",
19 feature = "stm32f423",
20 feature = "stm32f427",
21 feature = "stm32f429",
22 feature = "stm32f437",
23 feature = "stm32f439",
24 feature = "stm32f446",
25 feature = "stm32f469",
26 feature = "stm32f479",
27))]
28mod f4;
29
30#[cfg(any(
31 feature = "stm32f401",
32 feature = "stm32f405",
33 feature = "stm32f407",
34 feature = "stm32f412",
35 feature = "stm32f413",
36 feature = "stm32f415",
37 feature = "stm32f417",
38 feature = "stm32f423",
39 feature = "stm32f427",
40 feature = "stm32f429",
41 feature = "stm32f437",
42 feature = "stm32f439",
43 feature = "stm32f446",
44 feature = "stm32f469",
45 feature = "stm32f479",
46))]
47pub use {stm32f4xx_hal as hal, stm32f4xx_hal::stm32 as pac};
48
49#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
50pub use {stm32l0xx_hal as hal, stm32l0xx_hal::pac};
51
52#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
53mod l0;
54
55#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
56pub use l0::{rtc, system};
57
58pub mod fmt;
59
60pub mod exti;
61pub mod interrupt;
62
63#[cfg(any(
64 feature = "stm32f405",
65 feature = "stm32f407",
66 feature = "stm32f412",
67 feature = "stm32f413",
68 feature = "stm32f415",
69 feature = "stm32f417",
70 feature = "stm32f423",
71 feature = "stm32f427",
72 feature = "stm32f429",
73 feature = "stm32f437",
74 feature = "stm32f439",
75 feature = "stm32f446",
76 feature = "stm32f469",
77 feature = "stm32f479",
78))]
79pub mod can;
80
81#[cfg(any(
82 feature = "stm32f401",
83 feature = "stm32f405",
84 feature = "stm32f407",
85 feature = "stm32f412",
86 feature = "stm32f413",
87 feature = "stm32f415",
88 feature = "stm32f417",
89 feature = "stm32f423",
90 feature = "stm32f427",
91 feature = "stm32f429",
92 feature = "stm32f437",
93 feature = "stm32f439",
94 feature = "stm32f446",
95 feature = "stm32f469",
96 feature = "stm32f479",
97))]
98pub use f4::{rtc, serial, spi, system};
99
100#[cfg(any(
101 feature = "stm32f401",
102 feature = "stm32f405",
103 feature = "stm32f407",
104 feature = "stm32f410",
105 feature = "stm32f411",
106 feature = "stm32f412",
107 feature = "stm32f413",
108 feature = "stm32f415",
109 feature = "stm32f417",
110 feature = "stm32f423",
111 feature = "stm32f427",
112 feature = "stm32f429",
113 feature = "stm32f437",
114 feature = "stm32f439",
115 feature = "stm32f446",
116 feature = "stm32f469",
117 feature = "stm32f479",
118))]
119unsafe impl embassy_extras::usb::USBInterrupt for interrupt::OTG_FS {}
120
121use core::option::Option;
122use hal::prelude::*;
123use hal::rcc::Clocks;
124
125#[cfg(feature = "stm32f401")]
126embassy_extras::std_peripherals! {
127 ADC_COMMON,
128 ADC1,
129 CRC,
130 DBGMCU,
131 EXTI,
132 FLASH,
133 IWDG,
134 OTG_FS_DEVICE,
135 OTG_FS_GLOBAL,
136 OTG_FS_HOST,
137 OTG_FS_PWRCLK,
138 PWR,
139 //RCC,
140 RTC,
141 SDIO,
142 SYSCFG,
143 TIM1,
144 TIM8,
145 TIM10,
146 TIM11,
147 TIM2,
148 //TIM3,
149 TIM4,
150 TIM5,
151 TIM9,
152 USART1,
153 USART2,
154 USART6,
155 WWDG,
156 DMA2,
157 DMA1,
158 GPIOH,
159 GPIOE,
160 GPIOD,
161 GPIOC,
162 GPIOB,
163 GPIOA,
164 I2C3,
165 I2C2,
166 I2C1,
167 I2S2EXT,
168 I2S3EXT,
169 SPI1,
170 SPI2,
171 SPI3,
172 SPI4,
173 FPU,
174 STK,
175 NVIC_STIR,
176 FPU_CPACR,
177 SCB_ACTRL,
178}
179
180#[cfg(feature = "stm32f446")]
181embassy_extras::std_peripherals! {
182 DCMI,
183 FMC,
184 DBGMCU,
185 DMA2,
186 DMA1,
187// RCC,
188 GPIOH,
189 GPIOG,
190 GPIOF,
191 GPIOE,
192 GPIOD,
193 GPIOC,
194 GPIOB,
195 GPIOA,
196 SYSCFG,
197 SPI1,
198 SPI2,
199 SPI3,
200 SPI4,
201 ADC1,
202 ADC2,
203 ADC3,
204 USART6,
205 USART1,
206 USART2,
207 USART3,
208 DAC,
209 I2C3,
210 I2C2,
211 I2C1,
212 IWDG,
213 WWDG,
214 RTC,
215 UART4,
216 UART5,
217 ADC_COMMON,
218 TIM1,
219 TIM2,
220 TIM8,
221// TIM3,
222 TIM4,
223 TIM5,
224 TIM9,
225 TIM12,
226 TIM10,
227 TIM13,
228 TIM14,
229 TIM11,
230 TIM6,
231 TIM7,
232 CRC,
233 OTG_FS_GLOBAL,
234 OTG_FS_HOST,
235 OTG_FS_DEVICE,
236 OTG_FS_PWRCLK,
237 CAN1,
238 CAN2,
239 FLASH,
240 EXTI,
241 OTG_HS_GLOBAL,
242 OTG_HS_HOST,
243 OTG_HS_DEVICE,
244 OTG_HS_PWRCLK,
245 SAI1,
246 SAI2,
247 PWR,
248 QUADSPI,
249 SPDIFRX,
250// SDMMC,
251 HDMI_CEC,
252 FPU,
253 STK,
254 NVIC_STIR,
255 FPU_CPACR,
256 SCB_ACTRL,
257}
258
259#[cfg(feature = "stm32f405")]
260embassy_extras::std_peripherals! {
261 RNG,
262 DCMI,
263 FSMC,
264 DBGMCU,
265 DMA2,
266 DMA1,
267// RCC,
268 GPIOI,
269 GPIOH,
270 GPIOG,
271 GPIOF,
272 GPIOE,
273 GPIOD,
274 GPIOC,
275 GPIOJ,
276 GPIOK,
277 GPIOB,
278 GPIOA,
279 SYSCFG,
280 SPI1,
281 SPI2,
282 SPI3,
283 I2S2EXT,
284 I2S3EXT,
285 SPI4,
286 SPI5,
287 SPI6,
288 SDIO,
289 ADC1,
290 ADC2,
291 ADC3,
292 USART6,
293 USART1,
294 USART2,
295 USART3,
296 DAC,
297 PWR,
298 I2C3,
299 I2C2,
300 I2C1,
301 IWDG,
302 WWDG,
303 RTC,
304 UART4,
305 UART5,
306 UART7,
307 UART8,
308 ADC_COMMON,
309 TIM1,
310 TIM8,
311 TIM2,
312// TIM3,
313 TIM4,
314 TIM5,
315 TIM9,
316 TIM12,
317 TIM10,
318 TIM13,
319 TIM14,
320 TIM11,
321 TIM6,
322 TIM7,
323 ETHERNET_MAC,
324 ETHERNET_MMC,
325 ETHERNET_PTP,
326 ETHERNET_DMA,
327 CRC,
328 OTG_FS_GLOBAL,
329 OTG_FS_HOST,
330 OTG_FS_DEVICE,
331 OTG_FS_PWRCLK,
332 CAN1,
333 CAN2,
334 FLASH,
335 EXTI,
336 OTG_HS_GLOBAL,
337 OTG_HS_HOST,
338 OTG_HS_DEVICE,
339 OTG_HS_PWRCLK,
340 SAI1,
341 LTDC,
342 HASH,
343 CRYP,
344 FPU,
345 STK,
346 NVIC_STIR,
347 FPU_CPACR,
348 SCB_ACTRL,
349}
350
351#[cfg(feature = "stm32f407")]
352embassy_extras::std_peripherals! {
353 RNG,
354 DCMI,
355 FSMC,
356 DBGMCU,
357 DMA2,
358 DMA1,
359// RCC,
360 GPIOI,
361 GPIOH,
362 GPIOG,
363 GPIOF,
364 GPIOE,
365 GPIOD,
366 GPIOC,
367 GPIOJ,
368 GPIOK,
369 GPIOB,
370 GPIOA,
371 SYSCFG,
372 SPI1,
373 SPI2,
374 SPI3,
375 I2S2EXT,
376 I2S3EXT,
377 SPI4,
378 SPI5,
379 SPI6,
380 SDIO,
381 ADC1,
382 ADC2,
383 ADC3,
384 USART6,
385 USART1,
386 USART2,
387 USART3,
388 DAC,
389 PWR,
390 I2C3,
391 I2C2,
392 I2C1,
393 IWDG,
394 WWDG,
395 RTC,
396 UART4,
397 UART5,
398 UART7,
399 UART8,
400 ADC_COMMON,
401 TIM1,
402 TIM8,
403 TIM2,
404// TIM3,
405 TIM4,
406 TIM5,
407 TIM9,
408 TIM12,
409 TIM10,
410 TIM13,
411 TIM14,
412 TIM11,
413 TIM6,
414 TIM7,
415 ETHERNET_MAC,
416 ETHERNET_MMC,
417 ETHERNET_PTP,
418 ETHERNET_DMA,
419 CRC,
420 OTG_FS_GLOBAL,
421 OTG_FS_HOST,
422 OTG_FS_DEVICE,
423 OTG_FS_PWRCLK,
424 CAN1,
425 CAN2,
426 FLASH,
427 EXTI,
428 OTG_HS_GLOBAL,
429 OTG_HS_HOST,
430 OTG_HS_DEVICE,
431 OTG_HS_PWRCLK,
432 SAI1,
433 LTDC,
434 HASH,
435 CRYP,
436 FPU,
437 STK,
438 NVIC_STIR,
439 FPU_CPACR,
440 SCB_ACTRL,
441}
442
443#[cfg(feature = "stm32l0x2")]
444embassy_extras::std_peripherals! {
445 SPI1,
446 SPI2,
447 USART1,
448 USART2,
449 USART4,
450 USART5,
451 I2C1,
452 I2C2,
453 I2C3,
454 RNG,
455 TIM2,
456 TIM3,
457 TIM6,
458 TIM7,
459 TIM21,
460 TIM22,
461 DAC,
462 RTC,
463 PWR,
464 CRC,
465 GPIOA,
466 GPIOB,
467 GPIOC,
468 GPIOD,
469 GPIOE,
470 GPIOH,
471 SYSCFG,
472 DMA1,
473 EXTI,
474 ADC,
475 IWDG,
476 WWDG,
477 DBG,
478}