diff options
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" | |||
| 14 | proc-macro = true | 14 | proc-macro = true |
| 15 | 15 | ||
| 16 | [features] | 16 | [features] |
| 17 | stm32 = [] | ||
| 18 | nrf = [] | 17 | nrf = [] |
| 19 | rp = [] | 18 | rp = [] |
| 20 | std = [] | 19 | std = [] |
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 @@ | |||
| 1 | use crate::path::ModulePrefix; | ||
| 2 | use proc_macro2::TokenStream; | ||
| 3 | use quote::quote; | ||
| 4 | |||
| 5 | pub 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"] |
| 268 | mod chip; | 268 | mod chip; |
| 269 | 269 | ||
| 270 | #[cfg(feature = "stm32")] | ||
| 271 | #[path = "chip/stm32.rs"] | ||
| 272 | mod chip; | ||
| 273 | |||
| 274 | #[cfg(feature = "rp")] | 270 | #[cfg(feature = "rp")] |
| 275 | #[path = "chip/rp.rs"] | 271 | #[path = "chip/rp.rs"] |
| 276 | mod chip; | 272 | mod 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] |
| 289 | pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { | 285 | pub 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"))'] | ||
| 2 | runner = "probe-run --chip STM32F401CCUx" | ||
| 3 | |||
| 4 | rustflags = [ | ||
| 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] | ||
| 28 | target = "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] | ||
| 2 | authors = ["Dario Nieuwenhuis <[email protected]>"] | ||
| 3 | edition = "2018" | ||
| 4 | name = "embassy-stm32f4-examples" | ||
| 5 | version = "0.1.0" | ||
| 6 | |||
| 7 | [features] | ||
| 8 | default = [ | ||
| 9 | "defmt-default", | ||
| 10 | ] | ||
| 11 | defmt-default = [] | ||
| 12 | defmt-trace = [] | ||
| 13 | defmt-debug = [] | ||
| 14 | defmt-info = [] | ||
| 15 | defmt-warn = [] | ||
| 16 | defmt-error = [] | ||
| 17 | |||
| 18 | stm32f401 = ["embassy-stm32/stm32f401"] | ||
| 19 | stm32f405 = ["embassy-stm32/stm32f405"] | ||
| 20 | stm32f407 = ["embassy-stm32/stm32f407"] | ||
| 21 | stm32f410 = ["embassy-stm32/stm32f410"] | ||
| 22 | stm32f411 = ["embassy-stm32/stm32f411"] | ||
| 23 | stm32f412 = ["embassy-stm32/stm32f412"] | ||
| 24 | stm32f413 = ["embassy-stm32/stm32f413"] | ||
| 25 | stm32f415 = ["embassy-stm32/stm32f405"] | ||
| 26 | stm32f417 = ["embassy-stm32/stm32f407"] | ||
| 27 | stm32f423 = ["embassy-stm32/stm32f413"] | ||
| 28 | stm32f427 = ["embassy-stm32/stm32f427"] | ||
| 29 | stm32f429 = ["embassy-stm32/stm32f429"] | ||
| 30 | stm32f437 = ["embassy-stm32/stm32f427"] | ||
| 31 | stm32f439 = ["embassy-stm32/stm32f429"] | ||
| 32 | stm32f446 = ["embassy-stm32/stm32f446"] | ||
| 33 | stm32f469 = ["embassy-stm32/stm32f469"] | ||
| 34 | stm32f479 = ["embassy-stm32/stm32f469"] | ||
| 35 | |||
| 36 | |||
| 37 | [dependencies] | ||
| 38 | embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } | ||
| 39 | embassy-traits = { version = "0.1.0", path = "../embassy-traits", features = ["defmt"] } | ||
| 40 | embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } | ||
| 41 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } | ||
| 42 | |||
| 43 | defmt = "0.2.0" | ||
| 44 | defmt-rtt = "0.2.0" | ||
| 45 | |||
| 46 | cortex-m = "0.7.1" | ||
| 47 | cortex-m-rt = "0.6.13" | ||
| 48 | embedded-hal = { version = "0.2.4" } | ||
| 49 | panic-probe = { version = "0.2.0", features = ["print-defmt"] } | ||
| 50 | futures = { version = "0.3.8", default-features = false, features = ["async-await"] } | ||
| 51 | rtt-target = { version = "0.3", features = ["cortex-m"] } | ||
| 52 | bxcan = "0.5.0" | ||
| 53 | usb-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 | |||
| 11 | use std::env; | ||
| 12 | use std::fs::File; | ||
| 13 | use std::io::Write; | ||
| 14 | use std::path::PathBuf; | ||
| 15 | |||
| 16 | fn 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 @@ | |||
| 1 | MEMORY | ||
| 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"] | ||
| 9 | mod example_common; | ||
| 10 | use example_common::{panic, *}; | ||
| 11 | |||
| 12 | use bxcan::filter::Mask32; | ||
| 13 | use cortex_m_rt::entry; | ||
| 14 | use embassy::executor::Executor; | ||
| 15 | use embassy::util::Forever; | ||
| 16 | use embassy_stm32::hal::prelude::*; | ||
| 17 | use embassy_stm32::hal::{can::Can, stm32}; | ||
| 18 | use embassy_stm32::{can, interrupt}; | ||
| 19 | |||
| 20 | #[embassy::task] | ||
| 21 | async 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 | |||
| 39 | static EXECUTOR: Forever<Executor> = Forever::new(); | ||
| 40 | |||
| 41 | #[entry] | ||
| 42 | fn 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"] | ||
| 9 | mod example_common; | ||
| 10 | use example_common::{panic, *}; | ||
| 11 | |||
| 12 | use cortex_m_rt::entry; | ||
| 13 | use embassy::executor::Executor; | ||
| 14 | use embassy::traits::gpio::*; | ||
| 15 | use embassy::util::Forever; | ||
| 16 | use embassy_stm32::exti::ExtiPin; | ||
| 17 | use embassy_stm32::hal::prelude::*; | ||
| 18 | use embassy_stm32::interrupt; | ||
| 19 | use embassy_stm32::pac as stm32; | ||
| 20 | use futures::pin_mut; | ||
| 21 | |||
| 22 | #[embassy::task] | ||
| 23 | async 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 | |||
| 39 | static EXECUTOR: Forever<Executor> = Forever::new(); | ||
| 40 | |||
| 41 | #[entry] | ||
| 42 | fn 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"] | ||
| 9 | mod example_common; | ||
| 10 | use example_common::*; | ||
| 11 | |||
| 12 | use cortex_m_rt::entry; | ||
| 13 | use embassy_stm32::hal::prelude::*; | ||
| 14 | |||
| 15 | #[entry] | ||
| 16 | fn 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"] | ||
| 8 | mod example_common; | ||
| 9 | use example_common::*; | ||
| 10 | |||
| 11 | use defmt::panic; | ||
| 12 | use embassy; | ||
| 13 | |||
| 14 | use embassy::executor::Spawner; | ||
| 15 | use embassy::time::{Duration, Timer}; | ||
| 16 | use embassy_stm32; | ||
| 17 | use embassy_stm32::hal; | ||
| 18 | |||
| 19 | #[embassy::task] | ||
| 20 | async 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] | ||
| 28 | async 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)")] | ||
| 36 | async 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"] | ||
| 9 | mod example_common; | ||
| 10 | use example_common::{panic, *}; | ||
| 11 | |||
| 12 | use cortex_m::singleton; | ||
| 13 | use cortex_m_rt::entry; | ||
| 14 | use embassy::executor::{Executor, Spawner}; | ||
| 15 | use embassy::traits::uart::{Read, ReadUntilIdle, Write}; | ||
| 16 | use embassy::util::Forever; | ||
| 17 | use embassy_stm32::hal::dma::StreamsTuple; | ||
| 18 | use embassy_stm32::hal::prelude::*; | ||
| 19 | use embassy_stm32::hal::serial::config::Config; | ||
| 20 | use embassy_stm32::interrupt; | ||
| 21 | use embassy_stm32::pac as stm32; | ||
| 22 | use embassy_stm32::serial; | ||
| 23 | use futures::pin_mut; | ||
| 24 | |||
| 25 | #[embassy::main(config = "embassy_stm32::system::Config::new().use_hse(16).sysclk(48).pclk1(24)")] | ||
| 26 | async 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"] | ||
| 8 | mod example_common; | ||
| 9 | use example_common::*; | ||
| 10 | |||
| 11 | use cortex_m_rt::entry; | ||
| 12 | use defmt::panic; | ||
| 13 | use embassy::executor::{Executor, Spawner}; | ||
| 14 | use embassy::interrupt::InterruptExt; | ||
| 15 | use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; | ||
| 16 | use embassy::time::{Duration, Timer}; | ||
| 17 | use embassy::util::Forever; | ||
| 18 | use embassy_extras::usb::usb_serial::UsbSerial; | ||
| 19 | use embassy_extras::usb::Usb; | ||
| 20 | use embassy_stm32::hal::otg_fs::{UsbBus, USB}; | ||
| 21 | use embassy_stm32::hal::prelude::*; | ||
| 22 | use embassy_stm32::{interrupt, pac, rtc}; | ||
| 23 | use futures::future::{select, Either}; | ||
| 24 | use futures::pin_mut; | ||
| 25 | use usb_device::bus::UsbBusAllocator; | ||
| 26 | use usb_device::prelude::*; | ||
| 27 | |||
| 28 | #[embassy::task] | ||
| 29 | async 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 | |||
| 93 | static 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 | )] | ||
| 98 | async 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 | |||
| 3 | use defmt_rtt as _; // global logger | ||
| 4 | use panic_probe as _; | ||
| 5 | |||
| 6 | pub use defmt::*; | ||
| 7 | |||
| 8 | use core::sync::atomic::{AtomicUsize, Ordering}; | ||
| 9 | |||
| 10 | defmt::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] | ||
| 2 | name = "embassy-stm32" | ||
| 3 | version = "0.1.0" | ||
| 4 | authors = ["Dario Nieuwenhuis <[email protected]>"] | ||
| 5 | edition = "2018" | ||
| 6 | |||
| 7 | [features] | ||
| 8 | defmt-trace = [ ] | ||
| 9 | defmt-debug = [ ] | ||
| 10 | defmt-info = [ ] | ||
| 11 | defmt-warn = [ ] | ||
| 12 | defmt-error = [ ] | ||
| 13 | |||
| 14 | stm32f401 = ["stm32f4xx-hal/stm32f401"] | ||
| 15 | stm32f405 = ["stm32f4xx-hal/stm32f405"] | ||
| 16 | stm32f407 = ["stm32f4xx-hal/stm32f407"] | ||
| 17 | stm32f410 = ["stm32f4xx-hal/stm32f410"] | ||
| 18 | stm32f411 = ["stm32f4xx-hal/stm32f411"] | ||
| 19 | stm32f412 = ["stm32f4xx-hal/stm32f412"] | ||
| 20 | stm32f413 = ["stm32f4xx-hal/stm32f413"] | ||
| 21 | stm32f415 = ["stm32f4xx-hal/stm32f405"] | ||
| 22 | stm32f417 = ["stm32f4xx-hal/stm32f407"] | ||
| 23 | stm32f423 = ["stm32f4xx-hal/stm32f413"] | ||
| 24 | stm32f427 = ["stm32f4xx-hal/stm32f427"] | ||
| 25 | stm32f429 = ["stm32f4xx-hal/stm32f429"] | ||
| 26 | stm32f437 = ["stm32f4xx-hal/stm32f427"] | ||
| 27 | stm32f439 = ["stm32f4xx-hal/stm32f429"] | ||
| 28 | stm32f446 = ["stm32f4xx-hal/stm32f446"] | ||
| 29 | stm32f469 = ["stm32f4xx-hal/stm32f469"] | ||
| 30 | stm32f479 = ["stm32f4xx-hal/stm32f469"] | ||
| 31 | |||
| 32 | stm32l0x1 = ["stm32l0xx-hal/stm32l0x1"] | ||
| 33 | stm32l0x2 = ["stm32l0xx-hal/stm32l0x2"] | ||
| 34 | stm32l0x3 = ["stm32l0xx-hal/stm32l0x3"] | ||
| 35 | |||
| 36 | [dependencies] | ||
| 37 | embassy = { version = "0.1.0", path = "../embassy" } | ||
| 38 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"]} | ||
| 39 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } | ||
| 40 | |||
| 41 | atomic-polyfill = "0.1.1" | ||
| 42 | critical-section = "0.2.1" | ||
| 43 | defmt = { version = "0.2.0", optional = true } | ||
| 44 | log = { version = "0.4.11", optional = true } | ||
| 45 | cortex-m-rt = "0.6.13" | ||
| 46 | cortex-m = "0.7.1" | ||
| 47 | embedded-hal = { version = "0.2.4" } | ||
| 48 | embedded-dma = { version = "0.1.2" } | ||
| 49 | bxcan = "0.5.0" | ||
| 50 | nb = "*" | ||
| 51 | stm32f4xx-hal = { version = "0.9.0", features = ["rt", "can", "usb_fs"], optional = true } | ||
| 52 | stm32l0xx-hal = { version = "0.7.0", features = ["rt"], optional = true } | ||
| 53 | futures = { 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 | |||
| 7 | use bxcan; | ||
| 8 | use bxcan::Interrupts; | ||
| 9 | use core::future::Future; | ||
| 10 | use embassy::interrupt::Interrupt; | ||
| 11 | use embassy::util::InterruptFuture; | ||
| 12 | use nb; | ||
| 13 | use nb::block; | ||
| 14 | |||
| 15 | use crate::interrupt; | ||
| 16 | |||
| 17 | /// Interface to the Serial peripheral | ||
| 18 | pub struct Can<T: Instance> { | ||
| 19 | can: bxcan::Can<T>, | ||
| 20 | tx_int: T::TInterrupt, | ||
| 21 | rx_int: T::RInterrupt, | ||
| 22 | } | ||
| 23 | |||
| 24 | impl<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 | |||
| 77 | mod private { | ||
| 78 | pub trait Sealed {} | ||
| 79 | } | ||
| 80 | |||
| 81 | pub trait Instance: bxcan::Instance + private::Sealed { | ||
| 82 | type TInterrupt: Interrupt; | ||
| 83 | type RInterrupt: Interrupt; | ||
| 84 | } | ||
| 85 | |||
| 86 | macro_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 | ))] | ||
| 117 | can! { | ||
| 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 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | use core::mem; | ||
| 3 | use cortex_m; | ||
| 4 | |||
| 5 | use 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 | ))] | ||
| 26 | use crate::hal::syscfg::SysCfg; | ||
| 27 | |||
| 28 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 29 | use crate::hal::syscfg::SYSCFG as SysCfg; | ||
| 30 | |||
| 31 | use embassy::traits::gpio::{ | ||
| 32 | WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge, | ||
| 33 | }; | ||
| 34 | use embassy::util::InterruptFuture; | ||
| 35 | |||
| 36 | use embedded_hal::digital::v2 as digital; | ||
| 37 | |||
| 38 | use crate::interrupt; | ||
| 39 | |||
| 40 | pub struct ExtiPin<T: Instance> { | ||
| 41 | pin: T, | ||
| 42 | interrupt: T::Interrupt, | ||
| 43 | } | ||
| 44 | |||
| 45 | impl<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 | |||
| 55 | impl<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 | |||
| 67 | impl<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 | |||
| 77 | impl<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 | |||
| 85 | impl<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 | |||
| 97 | impl<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 | |||
| 123 | impl<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 | |||
| 140 | impl<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 | |||
| 148 | impl<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 | |||
| 167 | impl<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 | |||
| 175 | impl<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 | |||
| 183 | impl<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 | |||
| 191 | mod private { | ||
| 192 | pub trait Sealed {} | ||
| 193 | } | ||
| 194 | |||
| 195 | #[derive(Copy, Clone)] | ||
| 196 | pub enum EdgeOption { | ||
| 197 | Rising, | ||
| 198 | Falling, | ||
| 199 | RisingFalling, | ||
| 200 | } | ||
| 201 | |||
| 202 | pub trait WithInterrupt: private::Sealed { | ||
| 203 | type Interrupt: interrupt::Interrupt; | ||
| 204 | } | ||
| 205 | |||
| 206 | pub 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 | |||
| 212 | macro_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 | ))] | ||
| 325 | exti!(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 | ))] | ||
| 363 | exti!(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 | ))] | ||
| 401 | exti!(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 | ))] | ||
| 438 | exti!(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 | ))] | ||
| 475 | exti!(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 | ))] | ||
| 510 | exti!(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 | ))] | ||
| 545 | exti!(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 | ))] | ||
| 582 | exti!(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"))] | ||
| 602 | exti!(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 | ))] | ||
| 619 | exti!(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 | ))] | ||
| 646 | exti!(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 | ))] | ||
| 673 | exti!(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",))] | ||
| 685 | exti!(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",))] | ||
| 705 | exti!(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",))] | ||
| 725 | exti!(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",))] | ||
| 745 | exti!(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",))] | ||
| 765 | exti!(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",))] | ||
| 785 | exti!(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 @@ | |||
| 1 | pub mod rtc; | ||
| 2 | pub mod serial; | ||
| 3 | pub mod spi; | ||
| 4 | pub 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 @@ | |||
| 1 | use crate::hal::bb; | ||
| 2 | use crate::hal::rcc::Clocks; | ||
| 3 | use core::cell::Cell; | ||
| 4 | use core::convert::TryInto; | ||
| 5 | use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; | ||
| 6 | use critical_section::CriticalSection; | ||
| 7 | use embassy::interrupt::InterruptExt; | ||
| 8 | use embassy::time::{Clock, TICKS_PER_SECOND}; | ||
| 9 | use embassy::util::CriticalSectionMutex as Mutex; | ||
| 10 | |||
| 11 | use crate::interrupt; | ||
| 12 | use 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. | ||
| 31 | fn calc_now(period: u32, counter: u16) -> u64 { | ||
| 32 | ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) | ||
| 33 | } | ||
| 34 | |||
| 35 | struct AlarmState { | ||
| 36 | timestamp: Cell<u64>, | ||
| 37 | callback: Cell<Option<(fn(*mut ()), *mut ())>>, | ||
| 38 | } | ||
| 39 | |||
| 40 | impl 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 | ||
| 50 | const 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. | ||
| 59 | pub 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 | |||
| 72 | impl<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 | |||
| 206 | impl<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 | |||
| 215 | pub struct Alarm<T: Instance> { | ||
| 216 | n: usize, | ||
| 217 | rtc: &'static RTC<T>, | ||
| 218 | } | ||
| 219 | |||
| 220 | impl<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 | |||
| 234 | mod sealed { | ||
| 235 | pub trait Sealed {} | ||
| 236 | } | ||
| 237 | |||
| 238 | pub 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)] | ||
| 259 | macro_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"))] | ||
| 492 | impl_timer!(tim2: (TIM2, TIM2, apb1enr, 0, apb1rstr, 0, ppre1, pclk1), 3); | ||
| 493 | |||
| 494 | #[cfg(not(feature = "stm32f410"))] | ||
| 495 | impl_timer!(tim3: (TIM3, TIM3, apb1enr, 1, apb1rstr, 1, ppre1, pclk1), 3); | ||
| 496 | |||
| 497 | #[cfg(not(feature = "stm32f410"))] | ||
| 498 | impl_timer!(tim4: (TIM4, TIM4, apb1enr, 2, apb1rstr, 2, ppre1, pclk1), 3); | ||
| 499 | |||
| 500 | impl_timer!(tim5: (TIM5, TIM5, apb1enr, 3, apb1rstr, 3, ppre1, pclk1), 3); | ||
| 501 | |||
| 502 | impl_timer!(tim9: (TIM9, TIM1_BRK_TIM9, apb2enr, 16, apb2rstr, 16, ppre2, pclk2), 1); | ||
| 503 | |||
| 504 | #[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411")))] | ||
| 505 | impl_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 | |||
| 3 | use core::future::Future; | ||
| 4 | use core::marker::PhantomData; | ||
| 5 | use embassy::interrupt::Interrupt; | ||
| 6 | use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write}; | ||
| 7 | use embassy::util::InterruptFuture; | ||
| 8 | use futures::{select_biased, FutureExt}; | ||
| 9 | |||
| 10 | use 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 | }; | ||
| 20 | use crate::interrupt; | ||
| 21 | use crate::pac; | ||
| 22 | |||
| 23 | /// Interface to the Serial peripheral | ||
| 24 | pub 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 | |||
| 41 | impl<USART, TSTREAM, RSTREAM, CHANNEL> Serial<USART, TSTREAM, RSTREAM, CHANNEL> | ||
| 42 | where | ||
| 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 | |||
| 86 | impl<USART, TSTREAM, RSTREAM, CHANNEL> Read for Serial<USART, TSTREAM, RSTREAM, CHANNEL> | ||
| 87 | where | ||
| 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 | |||
| 134 | impl<USART, TSTREAM, RSTREAM, CHANNEL> Write for Serial<USART, TSTREAM, RSTREAM, CHANNEL> | ||
| 135 | where | ||
| 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 | |||
| 183 | impl<USART, TSTREAM, RSTREAM, CHANNEL> ReadUntilIdle for Serial<USART, TSTREAM, RSTREAM, CHANNEL> | ||
| 184 | where | ||
| 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 | |||
| 253 | mod private { | ||
| 254 | pub trait Sealed {} | ||
| 255 | } | ||
| 256 | |||
| 257 | pub trait WithInterrupt: private::Sealed { | ||
| 258 | type Interrupt: Interrupt; | ||
| 259 | } | ||
| 260 | |||
| 261 | macro_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 | |||
| 272 | macro_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 | |||
| 283 | dma! { | ||
| 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",))] | ||
| 302 | usart! { | ||
| 303 | USART1 => (USART1), | ||
| 304 | USART2 => (USART2), | ||
| 305 | USART6 => (USART6), | ||
| 306 | } | ||
| 307 | |||
| 308 | #[cfg(any(feature = "stm32f405", feature = "stm32f407"))] | ||
| 309 | usart! { | ||
| 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")] | ||
| 320 | usart! { | ||
| 321 | USART1 => (USART1), | ||
| 322 | USART2 => (USART2), | ||
| 323 | USART3 => (USART3), | ||
| 324 | USART6 => (USART6), | ||
| 325 | } | ||
| 326 | |||
| 327 | #[cfg(feature = "stm32f413")] | ||
| 328 | usart! { | ||
| 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 | ))] | ||
| 347 | usart! { | ||
| 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 | |||
| 3 | use embassy::time; | ||
| 4 | |||
| 5 | use core::{future::Future, marker::PhantomData, mem, ops::Deref, pin::Pin, ptr}; | ||
| 6 | use embassy::{interrupt::Interrupt, traits::spi::FullDuplex, util::InterruptFuture}; | ||
| 7 | use nb; | ||
| 8 | |||
| 9 | pub use crate::hal::spi::{Mode, Phase, Polarity}; | ||
| 10 | use 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 | }; | ||
| 19 | use crate::interrupt; | ||
| 20 | use crate::pac; | ||
| 21 | use futures::future; | ||
| 22 | |||
| 23 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| 24 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 25 | #[non_exhaustive] | ||
| 26 | pub enum Error { | ||
| 27 | TxBufferTooLong, | ||
| 28 | RxBufferTooLong, | ||
| 29 | Overrun, | ||
| 30 | ModeFault, | ||
| 31 | Crc, | ||
| 32 | } | ||
| 33 | |||
| 34 | fn 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 | |||
| 51 | fn 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 | ||
| 78 | pub 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 | |||
| 93 | impl<SPI, TSTREAM, RSTREAM, CHANNEL> Spi<SPI, TSTREAM, RSTREAM, CHANNEL> | ||
| 94 | where | ||
| 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 | |||
| 199 | impl<SPI, TSTREAM, RSTREAM, CHANNEL> FullDuplex<u8> for Spi<SPI, TSTREAM, RSTREAM, CHANNEL> | ||
| 200 | where | ||
| 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 | |||
| 406 | mod private { | ||
| 407 | pub trait Sealed {} | ||
| 408 | } | ||
| 409 | |||
| 410 | pub trait WithInterrupt: private::Sealed { | ||
| 411 | type Interrupt: Interrupt; | ||
| 412 | } | ||
| 413 | |||
| 414 | pub trait Instance: Deref<Target = pac::spi1::RegisterBlock> + private::Sealed { | ||
| 415 | unsafe fn enable_clock(); | ||
| 416 | fn clock_speed(clocks: Clocks) -> Hertz; | ||
| 417 | } | ||
| 418 | |||
| 419 | macro_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 | |||
| 430 | macro_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 | |||
| 456 | dma! { | ||
| 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 | ))] | ||
| 480 | spi! { | ||
| 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"))] | ||
| 489 | spi! { | ||
| 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 @@ | |||
| 1 | use crate::{hal::prelude::*, pac, Peripherals}; | ||
| 2 | |||
| 3 | #[derive(Default)] | ||
| 4 | pub 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 | |||
| 11 | impl 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. | ||
| 38 | pub 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"))] | ||
| 6 | compile_error!("You may not enable both `defmt` and `log` features."); | ||
| 7 | |||
| 8 | pub use fmt::*; | ||
| 9 | |||
| 10 | #[cfg(feature = "defmt")] | ||
| 11 | mod 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")] | ||
| 19 | mod 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")))] | ||
| 28 | mod 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"))] | ||
| 68 | macro_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)] | ||
| 88 | pub struct NoneError; | ||
| 89 | |||
| 90 | pub trait Try { | ||
| 91 | type Ok; | ||
| 92 | type Error; | ||
| 93 | fn into_result(self) -> Result<Self::Ok, Self::Error>; | ||
| 94 | } | ||
| 95 | |||
| 96 | impl<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 | |||
| 106 | impl<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 | ||
| 7 | pub use embassy::interrupt::{declare, take, Interrupt}; | ||
| 8 | pub use embassy_extras::interrupt::Priority4 as Priority; | ||
| 9 | |||
| 10 | #[cfg(feature = "stm32f401")] | ||
| 11 | mod 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")] | ||
| 71 | mod 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")] | ||
| 167 | mod 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")] | ||
| 256 | mod 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")] | ||
| 316 | mod 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")] | ||
| 379 | mod 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")] | ||
| 464 | mod 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")] | ||
| 564 | mod 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")] | ||
| 659 | mod 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")] | ||
| 756 | mod 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")] | ||
| 842 | mod 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")] | ||
| 941 | mod 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")] | ||
| 974 | mod 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")] | ||
| 1008 | mod 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 | |||
| 1042 | pub 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 @@ | |||
| 1 | pub mod rtc; | ||
| 2 | pub 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 @@ | |||
| 1 | use crate::hal::rcc::Clocks; | ||
| 2 | use atomic_polyfill::{compiler_fence, AtomicU32, Ordering}; | ||
| 3 | use core::cell::Cell; | ||
| 4 | use core::convert::TryInto; | ||
| 5 | use critical_section::CriticalSection; | ||
| 6 | use embassy::interrupt::InterruptExt; | ||
| 7 | use embassy::time::{Clock, TICKS_PER_SECOND}; | ||
| 8 | use embassy::util::CriticalSectionMutex as Mutex; | ||
| 9 | |||
| 10 | use crate::interrupt; | ||
| 11 | use 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. | ||
| 30 | fn calc_now(period: u32, counter: u16) -> u64 { | ||
| 31 | ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) | ||
| 32 | } | ||
| 33 | |||
| 34 | struct AlarmState { | ||
| 35 | timestamp: Cell<u64>, | ||
| 36 | callback: Cell<Option<(fn(*mut ()), *mut ())>>, | ||
| 37 | } | ||
| 38 | |||
| 39 | impl 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 | ||
| 49 | const 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. | ||
| 58 | pub 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 | |||
| 71 | impl<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 | |||
| 204 | impl<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 | |||
| 213 | pub struct Alarm<T: Instance> { | ||
| 214 | n: usize, | ||
| 215 | rtc: &'static RTC<T>, | ||
| 216 | } | ||
| 217 | |||
| 218 | impl<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 | |||
| 232 | mod sealed { | ||
| 233 | pub trait Sealed {} | ||
| 234 | } | ||
| 235 | |||
| 236 | pub 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)] | ||
| 256 | macro_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 | |||
| 371 | impl_timer!(tim2: (TIM2, TIM2, tim2en, tim2rst, apb1enr, apb1rstr, apb1_tim_clk)); | ||
| 372 | impl_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 @@ | |||
| 1 | use crate::{hal, pac, Peripherals}; | ||
| 2 | |||
| 3 | pub use hal::{ | ||
| 4 | prelude::*, | ||
| 5 | rcc::{Clocks, Config}, | ||
| 6 | }; | ||
| 7 | |||
| 8 | /// safety: must only call once. | ||
| 9 | pub 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 | ))] | ||
| 28 | mod 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 | ))] | ||
| 47 | pub use {stm32f4xx_hal as hal, stm32f4xx_hal::stm32 as pac}; | ||
| 48 | |||
| 49 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 50 | pub use {stm32l0xx_hal as hal, stm32l0xx_hal::pac}; | ||
| 51 | |||
| 52 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 53 | mod l0; | ||
| 54 | |||
| 55 | #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))] | ||
| 56 | pub use l0::{rtc, system}; | ||
| 57 | |||
| 58 | pub mod fmt; | ||
| 59 | |||
| 60 | pub mod exti; | ||
| 61 | pub 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 | ))] | ||
| 79 | pub 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 | ))] | ||
| 98 | pub 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 | ))] | ||
| 119 | unsafe impl embassy_extras::usb::USBInterrupt for interrupt::OTG_FS {} | ||
| 120 | |||
| 121 | use core::option::Option; | ||
| 122 | use hal::prelude::*; | ||
| 123 | use hal::rcc::Clocks; | ||
| 124 | |||
| 125 | #[cfg(feature = "stm32f401")] | ||
| 126 | embassy_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")] | ||
| 181 | embassy_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")] | ||
| 260 | embassy_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")] | ||
| 352 | embassy_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")] | ||
| 444 | embassy_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 | } | ||
