diff options
73 files changed, 2825 insertions, 5896 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8613f7e0d..97c668aca 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml | |||
| @@ -30,40 +30,31 @@ jobs: | |||
| 30 | target: thumbv7em-none-eabi | 30 | target: thumbv7em-none-eabi |
| 31 | - package: embassy-nrf | 31 | - package: embassy-nrf |
| 32 | target: thumbv7em-none-eabi | 32 | target: thumbv7em-none-eabi |
| 33 | features: 52810 | 33 | features: nrf52805 |
| 34 | - package: embassy-nrf | 34 | - package: embassy-nrf |
| 35 | target: thumbv7em-none-eabi | 35 | target: thumbv7em-none-eabi |
| 36 | features: 52832 | 36 | features: nrf52810 |
| 37 | - package: embassy-nrf | 37 | - package: embassy-nrf |
| 38 | target: thumbv7em-none-eabi | 38 | target: thumbv7em-none-eabi |
| 39 | features: 52833 | 39 | features: nrf52811 |
| 40 | - package: embassy-nrf | 40 | - package: embassy-nrf |
| 41 | target: thumbv7em-none-eabi | 41 | target: thumbv7em-none-eabi |
| 42 | features: 52840 | 42 | features: nrf52820 |
| 43 | - package: embassy-nrf | 43 | - package: embassy-nrf |
| 44 | target: thumbv7em-none-eabi | 44 | target: thumbv7em-none-eabi |
| 45 | features: 52840,log | 45 | features: nrf52832 |
| 46 | - package: embassy-nrf | 46 | - package: embassy-nrf |
| 47 | target: thumbv7em-none-eabi | 47 | target: thumbv7em-none-eabi |
| 48 | features: 52840,defmt | 48 | features: nrf52833 |
| 49 | - package: embassy-stm32-examples | 49 | - package: embassy-nrf |
| 50 | target: thumbv7em-none-eabi | ||
| 51 | features: stm32f405 | ||
| 52 | - package: embassy-stm32 | ||
| 53 | target: thumbv7em-none-eabi | 50 | target: thumbv7em-none-eabi |
| 54 | features: stm32f405 | 51 | features: nrf52840 |
| 55 | - package: embassy-stm32 | 52 | - package: embassy-nrf |
| 56 | target: thumbv7em-none-eabi | 53 | target: thumbv7em-none-eabi |
| 57 | features: stm32f446 | 54 | features: nrf52840,log |
| 58 | - package: embassy-stm32 | 55 | - package: embassy-nrf |
| 59 | target: thumbv7em-none-eabi | 56 | target: thumbv7em-none-eabi |
| 60 | features: stm32f405,defmt | 57 | features: nrf52840,defmt |
| 61 | - package: embassy-stm32 | ||
| 62 | target: thumbv6m-none-eabi | ||
| 63 | features: stm32l0x2 | ||
| 64 | - package: embassy-stm32 | ||
| 65 | target: thumbv6m-none-eabi | ||
| 66 | features: stm32l0x2,defmt | ||
| 67 | - package: embassy-rp-examples | 58 | - package: embassy-rp-examples |
| 68 | target: thumbv6m-none-eabi | 59 | target: thumbv6m-none-eabi |
| 69 | 60 | ||
diff --git a/embassy-extras/src/macros.rs b/embassy-extras/src/macros.rs index 860c0795a..fba752619 100644 --- a/embassy-extras/src/macros.rs +++ b/embassy-extras/src/macros.rs | |||
| @@ -46,18 +46,17 @@ macro_rules! peripherals { | |||
| 46 | impl Peripherals { | 46 | impl Peripherals { |
| 47 | ///Returns all the peripherals *once* | 47 | ///Returns all the peripherals *once* |
| 48 | #[inline] | 48 | #[inline] |
| 49 | pub fn take() -> Option<Self> { | 49 | pub(crate) fn take() -> Self { |
| 50 | 50 | ||
| 51 | #[no_mangle] | 51 | #[no_mangle] |
| 52 | static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false; | 52 | static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false; |
| 53 | 53 | ||
| 54 | critical_section::with(|_| { | 54 | critical_section::with(|_| unsafe { |
| 55 | if unsafe { _EMBASSY_DEVICE_PERIPHERALS } { | 55 | if _EMBASSY_DEVICE_PERIPHERALS { |
| 56 | None | 56 | panic!("init called more than once!") |
| 57 | } else { | ||
| 58 | unsafe { _EMBASSY_DEVICE_PERIPHERALS = true }; | ||
| 59 | Some(unsafe { <Self as embassy::util::Steal>::steal() }) | ||
| 60 | } | 57 | } |
| 58 | _EMBASSY_DEVICE_PERIPHERALS = true; | ||
| 59 | <Self as embassy::util::Steal>::steal() | ||
| 61 | }) | 60 | }) |
| 62 | } | 61 | } |
| 63 | } | 62 | } |
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/nrf.rs b/embassy-macros/src/chip/nrf.rs index aba4c004f..503a8ba5a 100644 --- a/embassy-macros/src/chip/nrf.rs +++ b/embassy-macros/src/chip/nrf.rs | |||
| @@ -9,7 +9,7 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream | |||
| 9 | quote!( | 9 | quote!( |
| 10 | use #embassy_nrf_path::{interrupt, peripherals, rtc}; | 10 | use #embassy_nrf_path::{interrupt, peripherals, rtc}; |
| 11 | 11 | ||
| 12 | unsafe { #embassy_nrf_path::system::configure(#config) }; | 12 | let p = #embassy_nrf_path::init(#config); |
| 13 | 13 | ||
| 14 | let mut rtc = rtc::RTC::new(unsafe { <peripherals::RTC1 as #embassy_path::util::Steal>::steal() }, interrupt::take!(RTC1)); | 14 | let mut rtc = rtc::RTC::new(unsafe { <peripherals::RTC1 as #embassy_path::util::Steal>::steal() }, interrupt::take!(RTC1)); |
| 15 | let rtc = unsafe { make_static(&mut rtc) }; | 15 | let rtc = unsafe { make_static(&mut rtc) }; |
diff --git a/embassy-macros/src/chip/rp.rs b/embassy-macros/src/chip/rp.rs index 33863de86..04211f8f3 100644 --- a/embassy-macros/src/chip/rp.rs +++ b/embassy-macros/src/chip/rp.rs | |||
| @@ -7,6 +7,6 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream | |||
| 7 | quote!( | 7 | quote!( |
| 8 | use #embassy_rp_path::{interrupt, peripherals}; | 8 | use #embassy_rp_path::{interrupt, peripherals}; |
| 9 | 9 | ||
| 10 | unsafe { #embassy_rp_path::system::configure(#config) }; | 10 | let p = #embassy_rp_path::init(#config); |
| 11 | ) | 11 | ) |
| 12 | } | 12 | } |
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 64411f5b4..dc234cd6d 100644 --- a/embassy-macros/src/lib.rs +++ b/embassy-macros/src/lib.rs | |||
| @@ -3,9 +3,13 @@ | |||
| 3 | extern crate proc_macro; | 3 | extern crate proc_macro; |
| 4 | 4 | ||
| 5 | use darling::FromMeta; | 5 | use darling::FromMeta; |
| 6 | use proc_macro::{Span, TokenStream}; | 6 | use proc_macro::TokenStream; |
| 7 | use proc_macro2::Span; | ||
| 7 | use quote::{format_ident, quote}; | 8 | use quote::{format_ident, quote}; |
| 9 | use std::iter; | ||
| 8 | use syn::spanned::Spanned; | 10 | use syn::spanned::Spanned; |
| 11 | use syn::{parse, Type, Visibility}; | ||
| 12 | use syn::{ItemFn, ReturnType}; | ||
| 9 | 13 | ||
| 10 | mod path; | 14 | mod path; |
| 11 | 15 | ||
| @@ -58,10 +62,9 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 58 | fail = true; | 62 | fail = true; |
| 59 | } | 63 | } |
| 60 | if pool_size < 1 { | 64 | if pool_size < 1 { |
| 61 | Span::call_site() | 65 | return parse::Error::new(Span::call_site(), "pool_size must be 1 or greater") |
| 62 | .error("pool_size must be 1 or greater") | 66 | .to_compile_error() |
| 63 | .emit(); | 67 | .into(); |
| 64 | fail = true | ||
| 65 | } | 68 | } |
| 66 | 69 | ||
| 67 | let mut arg_names: syn::punctuated::Punctuated<syn::Ident, syn::Token![,]> = | 70 | let mut arg_names: syn::punctuated::Punctuated<syn::Ident, syn::Token![,]> = |
| @@ -120,6 +123,66 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 120 | result.into() | 123 | result.into() |
| 121 | } | 124 | } |
| 122 | 125 | ||
| 126 | #[proc_macro_attribute] | ||
| 127 | pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream { | ||
| 128 | let mut f: ItemFn = syn::parse(input).expect("`#[interrupt]` must be applied to a function"); | ||
| 129 | |||
| 130 | if !args.is_empty() { | ||
| 131 | return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") | ||
| 132 | .to_compile_error() | ||
| 133 | .into(); | ||
| 134 | } | ||
| 135 | |||
| 136 | let fspan = f.span(); | ||
| 137 | let ident = f.sig.ident.clone(); | ||
| 138 | let ident_s = ident.to_string(); | ||
| 139 | |||
| 140 | // XXX should we blacklist other attributes? | ||
| 141 | |||
| 142 | let valid_signature = f.sig.constness.is_none() | ||
| 143 | && f.vis == Visibility::Inherited | ||
| 144 | && f.sig.abi.is_none() | ||
| 145 | && f.sig.inputs.is_empty() | ||
| 146 | && f.sig.generics.params.is_empty() | ||
| 147 | && f.sig.generics.where_clause.is_none() | ||
| 148 | && f.sig.variadic.is_none() | ||
| 149 | && match f.sig.output { | ||
| 150 | ReturnType::Default => true, | ||
| 151 | ReturnType::Type(_, ref ty) => match **ty { | ||
| 152 | Type::Tuple(ref tuple) => tuple.elems.is_empty(), | ||
| 153 | Type::Never(..) => true, | ||
| 154 | _ => false, | ||
| 155 | }, | ||
| 156 | }; | ||
| 157 | |||
| 158 | if !valid_signature { | ||
| 159 | return parse::Error::new( | ||
| 160 | fspan, | ||
| 161 | "`#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`", | ||
| 162 | ) | ||
| 163 | .to_compile_error() | ||
| 164 | .into(); | ||
| 165 | } | ||
| 166 | |||
| 167 | f.block.stmts = iter::once( | ||
| 168 | syn::parse2(quote! {{ | ||
| 169 | // Check that this interrupt actually exists | ||
| 170 | let __irq_exists_check: interrupt::#ident; | ||
| 171 | }}) | ||
| 172 | .unwrap(), | ||
| 173 | ) | ||
| 174 | .chain(f.block.stmts) | ||
| 175 | .collect(); | ||
| 176 | |||
| 177 | quote!( | ||
| 178 | #[doc(hidden)] | ||
| 179 | #[export_name = #ident_s] | ||
| 180 | #[allow(non_snake_case)] | ||
| 181 | #f | ||
| 182 | ) | ||
| 183 | .into() | ||
| 184 | } | ||
| 185 | |||
| 123 | #[proc_macro] | 186 | #[proc_macro] |
| 124 | pub fn interrupt_declare(item: TokenStream) -> TokenStream { | 187 | pub fn interrupt_declare(item: TokenStream) -> TokenStream { |
| 125 | let name = syn::parse_macro_input!(item as syn::Ident); | 188 | let name = syn::parse_macro_input!(item as syn::Ident); |
| @@ -130,7 +193,7 @@ pub fn interrupt_declare(item: TokenStream) -> TokenStream { | |||
| 130 | let result = quote! { | 193 | let result = quote! { |
| 131 | #[allow(non_camel_case_types)] | 194 | #[allow(non_camel_case_types)] |
| 132 | pub struct #name_interrupt(()); | 195 | pub struct #name_interrupt(()); |
| 133 | unsafe impl Interrupt for #name_interrupt { | 196 | unsafe impl ::embassy::interrupt::Interrupt for #name_interrupt { |
| 134 | type Priority = crate::interrupt::Priority; | 197 | type Priority = crate::interrupt::Priority; |
| 135 | fn number(&self) -> u16 { | 198 | fn number(&self) -> u16 { |
| 136 | use cortex_m::interrupt::InterruptNumber; | 199 | use cortex_m::interrupt::InterruptNumber; |
| @@ -204,10 +267,6 @@ pub fn interrupt_take(item: TokenStream) -> TokenStream { | |||
| 204 | #[path = "chip/nrf.rs"] | 267 | #[path = "chip/nrf.rs"] |
| 205 | mod chip; | 268 | mod chip; |
| 206 | 269 | ||
| 207 | #[cfg(feature = "stm32")] | ||
| 208 | #[path = "chip/stm32.rs"] | ||
| 209 | mod chip; | ||
| 210 | |||
| 211 | #[cfg(feature = "rp")] | 270 | #[cfg(feature = "rp")] |
| 212 | #[path = "chip/rp.rs"] | 271 | #[path = "chip/rp.rs"] |
| 213 | mod chip; | 272 | mod chip; |
| @@ -221,7 +280,7 @@ struct MainArgs { | |||
| 221 | config: Option<syn::LitStr>, | 280 | config: Option<syn::LitStr>, |
| 222 | } | 281 | } |
| 223 | 282 | ||
| 224 | #[cfg(any(feature = "nrf", feature = "stm32", feature = "rp"))] | 283 | #[cfg(any(feature = "nrf", feature = "rp"))] |
| 225 | #[proc_macro_attribute] | 284 | #[proc_macro_attribute] |
| 226 | pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { | 285 | pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { |
| 227 | let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs); | 286 | let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs); |
| @@ -256,12 +315,12 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 256 | 315 | ||
| 257 | let args = task_fn.sig.inputs.clone(); | 316 | let args = task_fn.sig.inputs.clone(); |
| 258 | 317 | ||
| 259 | if args.len() != 1 { | 318 | if args.len() != 2 { |
| 260 | task_fn | 319 | task_fn |
| 261 | .sig | 320 | .sig |
| 262 | .span() | 321 | .span() |
| 263 | .unwrap() | 322 | .unwrap() |
| 264 | .error("main function must have one argument") | 323 | .error("main function must have 2 arguments") |
| 265 | .emit(); | 324 | .emit(); |
| 266 | fail = true; | 325 | fail = true; |
| 267 | } | 326 | } |
| @@ -305,7 +364,7 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 305 | #chip_setup | 364 | #chip_setup |
| 306 | 365 | ||
| 307 | executor.run(|spawner| { | 366 | executor.run(|spawner| { |
| 308 | spawner.spawn(__embassy_main(spawner)).unwrap(); | 367 | spawner.spawn(__embassy_main(spawner, p)).unwrap(); |
| 309 | }) | 368 | }) |
| 310 | 369 | ||
| 311 | } | 370 | } |
diff --git a/embassy-nrf-examples/Cargo.toml b/embassy-nrf-examples/Cargo.toml index 29614f133..4cec37522 100644 --- a/embassy-nrf-examples/Cargo.toml +++ b/embassy-nrf-examples/Cargo.toml | |||
| @@ -19,7 +19,7 @@ defmt-error = [] | |||
| 19 | [dependencies] | 19 | [dependencies] |
| 20 | embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } | 20 | embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] } |
| 21 | embassy-traits = { version = "0.1.0", path = "../embassy-traits", features = ["defmt"] } | 21 | embassy-traits = { version = "0.1.0", path = "../embassy-traits", features = ["defmt"] } |
| 22 | embassy-nrf = { version = "0.1.0", path = "../embassy-nrf", features = ["defmt", "defmt-trace", "52840"] } | 22 | embassy-nrf = { version = "0.1.0", path = "../embassy-nrf", features = ["defmt", "defmt-trace", "nrf52840"] } |
| 23 | 23 | ||
| 24 | defmt = "0.2.0" | 24 | defmt = "0.2.0" |
| 25 | defmt-rtt = "0.2.0" | 25 | defmt-rtt = "0.2.0" |
diff --git a/embassy-nrf-examples/src/bin/blinky.rs b/embassy-nrf-examples/src/bin/blinky.rs index 4cb09bee7..e6fc854b5 100644 --- a/embassy-nrf-examples/src/bin/blinky.rs +++ b/embassy-nrf-examples/src/bin/blinky.rs | |||
| @@ -17,8 +17,7 @@ use embassy_nrf::Peripherals; | |||
| 17 | use embedded_hal::digital::v2::OutputPin; | 17 | use embedded_hal::digital::v2::OutputPin; |
| 18 | 18 | ||
| 19 | #[embassy::main] | 19 | #[embassy::main] |
| 20 | async fn main(spawner: Spawner) { | 20 | async fn main(spawner: Spawner, p: Peripherals) { |
| 21 | let p = Peripherals::take().unwrap(); | ||
| 22 | let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); | 21 | let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); |
| 23 | 22 | ||
| 24 | loop { | 23 | loop { |
diff --git a/embassy-nrf-examples/src/bin/buffered_uart.rs b/embassy-nrf-examples/src/bin/buffered_uart.rs index 8f5d9fb2e..b3a621c6b 100644 --- a/embassy-nrf-examples/src/bin/buffered_uart.rs +++ b/embassy-nrf-examples/src/bin/buffered_uart.rs | |||
| @@ -17,9 +17,7 @@ use example_common::*; | |||
| 17 | use futures::pin_mut; | 17 | use futures::pin_mut; |
| 18 | 18 | ||
| 19 | #[embassy::main] | 19 | #[embassy::main] |
| 20 | async fn main(spawner: Spawner) { | 20 | async fn main(spawner: Spawner, p: Peripherals) { |
| 21 | let p = Peripherals::take().unwrap(); | ||
| 22 | |||
| 23 | let mut config = uarte::Config::default(); | 21 | let mut config = uarte::Config::default(); |
| 24 | config.parity = uarte::Parity::EXCLUDED; | 22 | config.parity = uarte::Parity::EXCLUDED; |
| 25 | config.baudrate = uarte::Baudrate::BAUD115200; | 23 | config.baudrate = uarte::Baudrate::BAUD115200; |
diff --git a/embassy-nrf-examples/src/bin/executor_fairness_test.rs b/embassy-nrf-examples/src/bin/executor_fairness_test.rs index 3ea74316e..ca9bcc1e6 100644 --- a/embassy-nrf-examples/src/bin/executor_fairness_test.rs +++ b/embassy-nrf-examples/src/bin/executor_fairness_test.rs | |||
| @@ -13,7 +13,7 @@ use core::task::Poll; | |||
| 13 | use defmt::panic; | 13 | use defmt::panic; |
| 14 | use embassy::executor::Spawner; | 14 | use embassy::executor::Spawner; |
| 15 | use embassy::time::{Duration, Instant, Timer}; | 15 | use embassy::time::{Duration, Instant, Timer}; |
| 16 | use embassy_nrf::interrupt; | 16 | use embassy_nrf::{interrupt, Peripherals}; |
| 17 | 17 | ||
| 18 | #[embassy::task] | 18 | #[embassy::task] |
| 19 | async fn run1() { | 19 | async fn run1() { |
| @@ -40,7 +40,7 @@ async fn run3() { | |||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | #[embassy::main] | 42 | #[embassy::main] |
| 43 | async fn main(spawner: Spawner) { | 43 | async fn main(spawner: Spawner, p: Peripherals) { |
| 44 | unwrap!(spawner.spawn(run1())); | 44 | unwrap!(spawner.spawn(run1())); |
| 45 | unwrap!(spawner.spawn(run2())); | 45 | unwrap!(spawner.spawn(run2())); |
| 46 | unwrap!(spawner.spawn(run3())); | 46 | unwrap!(spawner.spawn(run3())); |
diff --git a/embassy-nrf-examples/src/bin/gpiote_channel.rs b/embassy-nrf-examples/src/bin/gpiote_channel.rs index 9e653192b..d52ed7767 100644 --- a/embassy-nrf-examples/src/bin/gpiote_channel.rs +++ b/embassy-nrf-examples/src/bin/gpiote_channel.rs | |||
| @@ -12,36 +12,29 @@ use example_common::*; | |||
| 12 | use defmt::panic; | 12 | use defmt::panic; |
| 13 | use embassy::executor::Spawner; | 13 | use embassy::executor::Spawner; |
| 14 | use embassy_nrf::gpio::{Input, Pull}; | 14 | use embassy_nrf::gpio::{Input, Pull}; |
| 15 | use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; | 15 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; |
| 16 | use embassy_nrf::{interrupt, Peripherals}; | 16 | use embassy_nrf::{interrupt, Peripherals}; |
| 17 | 17 | ||
| 18 | #[embassy::main] | 18 | #[embassy::main] |
| 19 | async fn main(spawner: Spawner) { | 19 | async fn main(spawner: Spawner, p: Peripherals) { |
| 20 | let p = Peripherals::take().unwrap(); | ||
| 21 | let g = gpiote::initialize(p.GPIOTE, interrupt::take!(GPIOTE)); | ||
| 22 | |||
| 23 | info!("Starting!"); | 20 | info!("Starting!"); |
| 24 | 21 | ||
| 25 | let ch1 = InputChannel::new( | 22 | let ch1 = InputChannel::new( |
| 26 | g, | ||
| 27 | p.GPIOTE_CH0, | 23 | p.GPIOTE_CH0, |
| 28 | Input::new(p.P0_11, Pull::Up), | 24 | Input::new(p.P0_11, Pull::Up), |
| 29 | InputChannelPolarity::HiToLo, | 25 | InputChannelPolarity::HiToLo, |
| 30 | ); | 26 | ); |
| 31 | let ch2 = InputChannel::new( | 27 | let ch2 = InputChannel::new( |
| 32 | g, | ||
| 33 | p.GPIOTE_CH1, | 28 | p.GPIOTE_CH1, |
| 34 | Input::new(p.P0_12, Pull::Up), | 29 | Input::new(p.P0_12, Pull::Up), |
| 35 | InputChannelPolarity::LoToHi, | 30 | InputChannelPolarity::LoToHi, |
| 36 | ); | 31 | ); |
| 37 | let ch3 = InputChannel::new( | 32 | let ch3 = InputChannel::new( |
| 38 | g, | ||
| 39 | p.GPIOTE_CH2, | 33 | p.GPIOTE_CH2, |
| 40 | Input::new(p.P0_24, Pull::Up), | 34 | Input::new(p.P0_24, Pull::Up), |
| 41 | InputChannelPolarity::Toggle, | 35 | InputChannelPolarity::Toggle, |
| 42 | ); | 36 | ); |
| 43 | let ch4 = InputChannel::new( | 37 | let ch4 = InputChannel::new( |
| 44 | g, | ||
| 45 | p.GPIOTE_CH3, | 38 | p.GPIOTE_CH3, |
| 46 | Input::new(p.P0_25, Pull::Up), | 39 | Input::new(p.P0_25, Pull::Up), |
| 47 | InputChannelPolarity::Toggle, | 40 | InputChannelPolarity::Toggle, |
diff --git a/embassy-nrf-examples/src/bin/gpiote_port.rs b/embassy-nrf-examples/src/bin/gpiote_port.rs index 386806dfc..4a7951cd3 100644 --- a/embassy-nrf-examples/src/bin/gpiote_port.rs +++ b/embassy-nrf-examples/src/bin/gpiote_port.rs | |||
| @@ -8,12 +8,11 @@ | |||
| 8 | #[path = "../example_common.rs"] | 8 | #[path = "../example_common.rs"] |
| 9 | mod example_common; | 9 | mod example_common; |
| 10 | 10 | ||
| 11 | use core::pin::Pin; | ||
| 12 | use defmt::panic; | 11 | use defmt::panic; |
| 13 | use embassy::executor::Spawner; | 12 | use embassy::executor::Spawner; |
| 14 | use embassy::traits::gpio::{WaitForHigh, WaitForLow}; | 13 | use embassy::traits::gpio::{WaitForHigh, WaitForLow}; |
| 15 | use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull}; | 14 | use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull}; |
| 16 | use embassy_nrf::gpiote::{self, PortInput}; | 15 | use embassy_nrf::gpiote::PortInput; |
| 17 | use embassy_nrf::interrupt; | 16 | use embassy_nrf::interrupt; |
| 18 | use embassy_nrf::Peripherals; | 17 | use embassy_nrf::Peripherals; |
| 19 | use example_common::*; | 18 | use example_common::*; |
| @@ -29,15 +28,13 @@ async fn button_task(n: usize, mut pin: PortInput<'static, AnyPin>) { | |||
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | #[embassy::main] | 30 | #[embassy::main] |
| 32 | async fn main(spawner: Spawner) { | 31 | async fn main(spawner: Spawner, p: Peripherals) { |
| 33 | let p = Peripherals::take().unwrap(); | 32 | info!("Starting!"); |
| 34 | 33 | ||
| 35 | let g = gpiote::initialize(p.GPIOTE, interrupt::take!(GPIOTE)); | 34 | let btn1 = PortInput::new(Input::new(p.P0_11.degrade(), Pull::Up)); |
| 36 | 35 | let btn2 = PortInput::new(Input::new(p.P0_12.degrade(), Pull::Up)); | |
| 37 | let btn1 = PortInput::new(g, Input::new(p.P0_11.degrade(), Pull::Up)); | 36 | let btn3 = PortInput::new(Input::new(p.P0_24.degrade(), Pull::Up)); |
| 38 | let btn2 = PortInput::new(g, Input::new(p.P0_12.degrade(), Pull::Up)); | 37 | let btn4 = PortInput::new(Input::new(p.P0_25.degrade(), Pull::Up)); |
| 39 | let btn3 = PortInput::new(g, Input::new(p.P0_24.degrade(), Pull::Up)); | ||
| 40 | let btn4 = PortInput::new(g, Input::new(p.P0_25.degrade(), Pull::Up)); | ||
| 41 | 38 | ||
| 42 | spawner.spawn(button_task(1, btn1)).unwrap(); | 39 | spawner.spawn(button_task(1, btn1)).unwrap(); |
| 43 | spawner.spawn(button_task(2, btn2)).unwrap(); | 40 | spawner.spawn(button_task(2, btn2)).unwrap(); |
diff --git a/embassy-nrf-examples/src/bin/multiprio.rs b/embassy-nrf-examples/src/bin/multiprio.rs index 9ed5c1368..79fa029b3 100644 --- a/embassy-nrf-examples/src/bin/multiprio.rs +++ b/embassy-nrf-examples/src/bin/multiprio.rs | |||
| @@ -126,9 +126,8 @@ static EXECUTOR_LOW: Forever<Executor> = Forever::new(); | |||
| 126 | fn main() -> ! { | 126 | fn main() -> ! { |
| 127 | info!("Hello World!"); | 127 | info!("Hello World!"); |
| 128 | 128 | ||
| 129 | let p = unwrap!(embassy_nrf::Peripherals::take()); | 129 | let p = embassy_nrf::init(Default::default()); |
| 130 | 130 | ||
| 131 | unsafe { embassy_nrf::system::configure(Default::default()) }; | ||
| 132 | let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); | 131 | let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); |
| 133 | rtc.start(); | 132 | rtc.start(); |
| 134 | unsafe { embassy::time::set_clock(rtc) }; | 133 | unsafe { embassy::time::set_clock(rtc) }; |
diff --git a/embassy-nrf-examples/src/bin/ppi.rs b/embassy-nrf-examples/src/bin/ppi.rs index aeda76f21..47782ed29 100644 --- a/embassy-nrf-examples/src/bin/ppi.rs +++ b/embassy-nrf-examples/src/bin/ppi.rs | |||
| @@ -19,46 +19,37 @@ use embassy_nrf::{interrupt, Peripherals}; | |||
| 19 | use gpiote::{OutputChannel, OutputChannelPolarity}; | 19 | use gpiote::{OutputChannel, OutputChannelPolarity}; |
| 20 | 20 | ||
| 21 | #[embassy::main] | 21 | #[embassy::main] |
| 22 | async fn main(spawner: Spawner) { | 22 | async fn main(spawner: Spawner, p: Peripherals) { |
| 23 | let p = Peripherals::take().unwrap(); | ||
| 24 | let g = gpiote::initialize(p.GPIOTE, interrupt::take!(GPIOTE)); | ||
| 25 | |||
| 26 | info!("Starting!"); | 23 | info!("Starting!"); |
| 27 | 24 | ||
| 28 | let button1 = InputChannel::new( | 25 | let button1 = InputChannel::new( |
| 29 | g, | ||
| 30 | p.GPIOTE_CH0, | 26 | p.GPIOTE_CH0, |
| 31 | Input::new(p.P0_11, Pull::Up), | 27 | Input::new(p.P0_11, Pull::Up), |
| 32 | InputChannelPolarity::HiToLo, | 28 | InputChannelPolarity::HiToLo, |
| 33 | ); | 29 | ); |
| 34 | let button2 = InputChannel::new( | 30 | let button2 = InputChannel::new( |
| 35 | g, | ||
| 36 | p.GPIOTE_CH1, | 31 | p.GPIOTE_CH1, |
| 37 | Input::new(p.P0_12, Pull::Up), | 32 | Input::new(p.P0_12, Pull::Up), |
| 38 | InputChannelPolarity::HiToLo, | 33 | InputChannelPolarity::HiToLo, |
| 39 | ); | 34 | ); |
| 40 | let button3 = InputChannel::new( | 35 | let button3 = InputChannel::new( |
| 41 | g, | ||
| 42 | p.GPIOTE_CH2, | 36 | p.GPIOTE_CH2, |
| 43 | Input::new(p.P0_24, Pull::Up), | 37 | Input::new(p.P0_24, Pull::Up), |
| 44 | InputChannelPolarity::HiToLo, | 38 | InputChannelPolarity::HiToLo, |
| 45 | ); | 39 | ); |
| 46 | let button4 = InputChannel::new( | 40 | let button4 = InputChannel::new( |
| 47 | g, | ||
| 48 | p.GPIOTE_CH3, | 41 | p.GPIOTE_CH3, |
| 49 | Input::new(p.P0_25, Pull::Up), | 42 | Input::new(p.P0_25, Pull::Up), |
| 50 | InputChannelPolarity::HiToLo, | 43 | InputChannelPolarity::HiToLo, |
| 51 | ); | 44 | ); |
| 52 | 45 | ||
| 53 | let led1 = OutputChannel::new( | 46 | let led1 = OutputChannel::new( |
| 54 | g, | ||
| 55 | p.GPIOTE_CH4, | 47 | p.GPIOTE_CH4, |
| 56 | Output::new(p.P0_13, Level::Low, OutputDrive::Standard), | 48 | Output::new(p.P0_13, Level::Low, OutputDrive::Standard), |
| 57 | OutputChannelPolarity::Toggle, | 49 | OutputChannelPolarity::Toggle, |
| 58 | ); | 50 | ); |
| 59 | 51 | ||
| 60 | let led2 = OutputChannel::new( | 52 | let led2 = OutputChannel::new( |
| 61 | g, | ||
| 62 | p.GPIOTE_CH5, | 53 | p.GPIOTE_CH5, |
| 63 | Output::new(p.P0_14, Level::Low, OutputDrive::Standard), | 54 | Output::new(p.P0_14, Level::Low, OutputDrive::Standard), |
| 64 | OutputChannelPolarity::Toggle, | 55 | OutputChannelPolarity::Toggle, |
diff --git a/embassy-nrf-examples/src/bin/pwm.rs b/embassy-nrf-examples/src/bin/pwm.rs new file mode 100644 index 000000000..6efcf22d2 --- /dev/null +++ b/embassy-nrf-examples/src/bin/pwm.rs | |||
| @@ -0,0 +1,104 @@ | |||
| 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 | #![allow(incomplete_features)] | ||
| 7 | |||
| 8 | #[path = "../example_common.rs"] | ||
| 9 | mod example_common; | ||
| 10 | use defmt::{panic, *}; | ||
| 11 | use embassy::executor::Spawner; | ||
| 12 | use embassy::time::{Duration, Timer}; | ||
| 13 | use embassy_nrf::pwm::{Prescaler, Pwm}; | ||
| 14 | use embassy_nrf::{interrupt, Peripherals}; | ||
| 15 | |||
| 16 | // for i in range(1024): print(int((math.sin(i/512*math.pi)*0.4+0.5)**2*32767), ', ', end='') | ||
| 17 | static DUTY: [u16; 1024] = [ | ||
| 18 | 8191, 8272, 8353, 8434, 8516, 8598, 8681, 8764, 8847, 8931, 9015, 9099, 9184, 9269, 9354, 9440, | ||
| 19 | 9526, 9613, 9700, 9787, 9874, 9962, 10050, 10139, 10227, 10316, 10406, 10495, 10585, 10675, | ||
| 20 | 10766, 10857, 10948, 11039, 11131, 11223, 11315, 11407, 11500, 11592, 11685, 11779, 11872, | ||
| 21 | 11966, 12060, 12154, 12248, 12343, 12438, 12533, 12628, 12723, 12818, 12914, 13010, 13106, | ||
| 22 | 13202, 13298, 13394, 13491, 13587, 13684, 13781, 13878, 13975, 14072, 14169, 14266, 14364, | ||
| 23 | 14461, 14558, 14656, 14754, 14851, 14949, 15046, 15144, 15242, 15339, 15437, 15535, 15632, | ||
| 24 | 15730, 15828, 15925, 16023, 16120, 16218, 16315, 16412, 16510, 16607, 16704, 16801, 16898, | ||
| 25 | 16995, 17091, 17188, 17284, 17380, 17477, 17572, 17668, 17764, 17859, 17955, 18050, 18145, | ||
| 26 | 18239, 18334, 18428, 18522, 18616, 18710, 18803, 18896, 18989, 19082, 19174, 19266, 19358, | ||
| 27 | 19449, 19540, 19631, 19722, 19812, 19902, 19991, 20081, 20169, 20258, 20346, 20434, 20521, | ||
| 28 | 20608, 20695, 20781, 20867, 20952, 21037, 21122, 21206, 21290, 21373, 21456, 21538, 21620, | ||
| 29 | 21701, 21782, 21863, 21943, 22022, 22101, 22179, 22257, 22335, 22412, 22488, 22564, 22639, | ||
| 30 | 22714, 22788, 22861, 22934, 23007, 23079, 23150, 23220, 23290, 23360, 23429, 23497, 23564, | ||
| 31 | 23631, 23698, 23763, 23828, 23892, 23956, 24019, 24081, 24143, 24204, 24264, 24324, 24383, | ||
| 32 | 24441, 24499, 24555, 24611, 24667, 24721, 24775, 24828, 24881, 24933, 24983, 25034, 25083, | ||
| 33 | 25132, 25180, 25227, 25273, 25319, 25363, 25407, 25451, 25493, 25535, 25575, 25615, 25655, | ||
| 34 | 25693, 25731, 25767, 25803, 25838, 25873, 25906, 25939, 25971, 26002, 26032, 26061, 26089, | ||
| 35 | 26117, 26144, 26170, 26195, 26219, 26242, 26264, 26286, 26307, 26327, 26346, 26364, 26381, | ||
| 36 | 26397, 26413, 26427, 26441, 26454, 26466, 26477, 26487, 26496, 26505, 26512, 26519, 26525, | ||
| 37 | 26530, 26534, 26537, 26539, 26540, 26541, 26540, 26539, 26537, 26534, 26530, 26525, 26519, | ||
| 38 | 26512, 26505, 26496, 26487, 26477, 26466, 26454, 26441, 26427, 26413, 26397, 26381, 26364, | ||
| 39 | 26346, 26327, 26307, 26286, 26264, 26242, 26219, 26195, 26170, 26144, 26117, 26089, 26061, | ||
| 40 | 26032, 26002, 25971, 25939, 25906, 25873, 25838, 25803, 25767, 25731, 25693, 25655, 25615, | ||
| 41 | 25575, 25535, 25493, 25451, 25407, 25363, 25319, 25273, 25227, 25180, 25132, 25083, 25034, | ||
| 42 | 24983, 24933, 24881, 24828, 24775, 24721, 24667, 24611, 24555, 24499, 24441, 24383, 24324, | ||
| 43 | 24264, 24204, 24143, 24081, 24019, 23956, 23892, 23828, 23763, 23698, 23631, 23564, 23497, | ||
| 44 | 23429, 23360, 23290, 23220, 23150, 23079, 23007, 22934, 22861, 22788, 22714, 22639, 22564, | ||
| 45 | 22488, 22412, 22335, 22257, 22179, 22101, 22022, 21943, 21863, 21782, 21701, 21620, 21538, | ||
| 46 | 21456, 21373, 21290, 21206, 21122, 21037, 20952, 20867, 20781, 20695, 20608, 20521, 20434, | ||
| 47 | 20346, 20258, 20169, 20081, 19991, 19902, 19812, 19722, 19631, 19540, 19449, 19358, 19266, | ||
| 48 | 19174, 19082, 18989, 18896, 18803, 18710, 18616, 18522, 18428, 18334, 18239, 18145, 18050, | ||
| 49 | 17955, 17859, 17764, 17668, 17572, 17477, 17380, 17284, 17188, 17091, 16995, 16898, 16801, | ||
| 50 | 16704, 16607, 16510, 16412, 16315, 16218, 16120, 16023, 15925, 15828, 15730, 15632, 15535, | ||
| 51 | 15437, 15339, 15242, 15144, 15046, 14949, 14851, 14754, 14656, 14558, 14461, 14364, 14266, | ||
| 52 | 14169, 14072, 13975, 13878, 13781, 13684, 13587, 13491, 13394, 13298, 13202, 13106, 13010, | ||
| 53 | 12914, 12818, 12723, 12628, 12533, 12438, 12343, 12248, 12154, 12060, 11966, 11872, 11779, | ||
| 54 | 11685, 11592, 11500, 11407, 11315, 11223, 11131, 11039, 10948, 10857, 10766, 10675, 10585, | ||
| 55 | 10495, 10406, 10316, 10227, 10139, 10050, 9962, 9874, 9787, 9700, 9613, 9526, 9440, 9354, 9269, | ||
| 56 | 9184, 9099, 9015, 8931, 8847, 8764, 8681, 8598, 8516, 8434, 8353, 8272, 8191, 8111, 8031, 7952, | ||
| 57 | 7873, 7794, 7716, 7638, 7561, 7484, 7407, 7331, 7255, 7180, 7105, 7031, 6957, 6883, 6810, 6738, | ||
| 58 | 6665, 6594, 6522, 6451, 6381, 6311, 6241, 6172, 6104, 6036, 5968, 5901, 5834, 5767, 5702, 5636, | ||
| 59 | 5571, 5507, 5443, 5379, 5316, 5253, 5191, 5130, 5068, 5008, 4947, 4888, 4828, 4769, 4711, 4653, | ||
| 60 | 4596, 4539, 4482, 4426, 4371, 4316, 4261, 4207, 4153, 4100, 4047, 3995, 3943, 3892, 3841, 3791, | ||
| 61 | 3741, 3691, 3642, 3594, 3546, 3498, 3451, 3404, 3358, 3312, 3267, 3222, 3178, 3134, 3090, 3047, | ||
| 62 | 3005, 2962, 2921, 2879, 2839, 2798, 2758, 2719, 2680, 2641, 2603, 2565, 2528, 2491, 2454, 2418, | ||
| 63 | 2382, 2347, 2312, 2278, 2244, 2210, 2177, 2144, 2112, 2080, 2048, 2017, 1986, 1956, 1926, 1896, | ||
| 64 | 1867, 1838, 1810, 1781, 1754, 1726, 1699, 1673, 1646, 1620, 1595, 1570, 1545, 1520, 1496, 1472, | ||
| 65 | 1449, 1426, 1403, 1380, 1358, 1336, 1315, 1294, 1273, 1252, 1232, 1212, 1192, 1173, 1154, 1135, | ||
| 66 | 1117, 1099, 1081, 1063, 1046, 1029, 1012, 996, 980, 964, 948, 933, 918, 903, 888, 874, 860, | ||
| 67 | 846, 833, 819, 806, 793, 781, 768, 756, 744, 733, 721, 710, 699, 688, 677, 667, 657, 647, 637, | ||
| 68 | 627, 618, 609, 599, 591, 582, 574, 565, 557, 549, 541, 534, 526, 519, 512, 505, 498, 492, 485, | ||
| 69 | 479, 473, 467, 461, 455, 450, 444, 439, 434, 429, 424, 419, 415, 410, 406, 402, 398, 394, 390, | ||
| 70 | 386, 383, 379, 376, 373, 370, 367, 364, 361, 359, 356, 354, 351, 349, 347, 345, 343, 342, 340, | ||
| 71 | 338, 337, 336, 334, 333, 332, 331, 330, 330, 329, 328, 328, 328, 327, 327, 327, 327, 327, 328, | ||
| 72 | 328, 328, 329, 330, 330, 331, 332, 333, 334, 336, 337, 338, 340, 342, 343, 345, 347, 349, 351, | ||
| 73 | 354, 356, 359, 361, 364, 367, 370, 373, 376, 379, 383, 386, 390, 394, 398, 402, 406, 410, 415, | ||
| 74 | 419, 424, 429, 434, 439, 444, 450, 455, 461, 467, 473, 479, 485, 492, 498, 505, 512, 519, 526, | ||
| 75 | 534, 541, 549, 557, 565, 574, 582, 591, 599, 609, 618, 627, 637, 647, 657, 667, 677, 688, 699, | ||
| 76 | 710, 721, 733, 744, 756, 768, 781, 793, 806, 819, 833, 846, 860, 874, 888, 903, 918, 933, 948, | ||
| 77 | 964, 980, 996, 1012, 1029, 1046, 1063, 1081, 1099, 1117, 1135, 1154, 1173, 1192, 1212, 1232, | ||
| 78 | 1252, 1273, 1294, 1315, 1336, 1358, 1380, 1403, 1426, 1449, 1472, 1496, 1520, 1545, 1570, 1595, | ||
| 79 | 1620, 1646, 1673, 1699, 1726, 1754, 1781, 1810, 1838, 1867, 1896, 1926, 1956, 1986, 2017, 2048, | ||
| 80 | 2080, 2112, 2144, 2177, 2210, 2244, 2278, 2312, 2347, 2382, 2418, 2454, 2491, 2528, 2565, 2603, | ||
| 81 | 2641, 2680, 2719, 2758, 2798, 2839, 2879, 2921, 2962, 3005, 3047, 3090, 3134, 3178, 3222, 3267, | ||
| 82 | 3312, 3358, 3404, 3451, 3498, 3546, 3594, 3642, 3691, 3741, 3791, 3841, 3892, 3943, 3995, 4047, | ||
| 83 | 4100, 4153, 4207, 4261, 4316, 4371, 4426, 4482, 4539, 4596, 4653, 4711, 4769, 4828, 4888, 4947, | ||
| 84 | 5008, 5068, 5130, 5191, 5253, 5316, 5379, 5443, 5507, 5571, 5636, 5702, 5767, 5834, 5901, 5968, | ||
| 85 | 6036, 6104, 6172, 6241, 6311, 6381, 6451, 6522, 6594, 6665, 6738, 6810, 6883, 6957, 7031, 7105, | ||
| 86 | 7180, 7255, 7331, 7407, 7484, 7561, 7638, 7716, 7794, 7873, 7952, 8031, 8111, | ||
| 87 | ]; | ||
| 88 | |||
| 89 | #[embassy::main] | ||
| 90 | async fn main(spawner: Spawner, p: Peripherals) { | ||
| 91 | let pwm = Pwm::new(p.PWM0, p.P0_13, p.P0_14, p.P0_16, p.P0_15); | ||
| 92 | pwm.set_prescaler(Prescaler::Div1); | ||
| 93 | info!("pwm initialized!"); | ||
| 94 | |||
| 95 | let mut i = 0; | ||
| 96 | loop { | ||
| 97 | i += 1; | ||
| 98 | pwm.set_duty(0, DUTY[i % 1024]); | ||
| 99 | pwm.set_duty(1, DUTY[(i + 256) % 1024]); | ||
| 100 | pwm.set_duty(2, DUTY[(i + 512) % 1024]); | ||
| 101 | pwm.set_duty(3, DUTY[(i + 768) % 1024]); | ||
| 102 | Timer::after(Duration::from_millis(3)).await; | ||
| 103 | } | ||
| 104 | } | ||
diff --git a/embassy-nrf-examples/src/bin/qspi.rs b/embassy-nrf-examples/src/bin/qspi.rs index 28cde6e51..3dc027f6f 100644 --- a/embassy-nrf-examples/src/bin/qspi.rs +++ b/embassy-nrf-examples/src/bin/qspi.rs | |||
| @@ -23,9 +23,7 @@ const PAGE_SIZE: usize = 4096; | |||
| 23 | struct AlignedBuf([u8; 4096]); | 23 | struct AlignedBuf([u8; 4096]); |
| 24 | 24 | ||
| 25 | #[embassy::main] | 25 | #[embassy::main] |
| 26 | async fn main(spawner: Spawner) { | 26 | async fn main(spawner: Spawner, p: Peripherals) { |
| 27 | let p = Peripherals::take().unwrap(); | ||
| 28 | |||
| 29 | let csn = p.P0_17; | 27 | let csn = p.P0_17; |
| 30 | let sck = p.P0_19; | 28 | let sck = p.P0_19; |
| 31 | let io0 = p.P0_20; | 29 | let io0 = p.P0_20; |
diff --git a/embassy-nrf-examples/src/bin/raw_spawn.rs b/embassy-nrf-examples/src/bin/raw_spawn.rs index f8e021d9b..78de7b100 100644 --- a/embassy-nrf-examples/src/bin/raw_spawn.rs +++ b/embassy-nrf-examples/src/bin/raw_spawn.rs | |||
| @@ -37,9 +37,8 @@ static EXECUTOR: Forever<Executor> = Forever::new(); | |||
| 37 | fn main() -> ! { | 37 | fn main() -> ! { |
| 38 | info!("Hello World!"); | 38 | info!("Hello World!"); |
| 39 | 39 | ||
| 40 | let p = unwrap!(embassy_nrf::Peripherals::take()); | 40 | let p = embassy_nrf::init(Default::default()); |
| 41 | 41 | ||
| 42 | unsafe { embassy_nrf::system::configure(Default::default()) }; | ||
| 43 | let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); | 42 | let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); |
| 44 | rtc.start(); | 43 | rtc.start(); |
| 45 | unsafe { embassy::time::set_clock(rtc) }; | 44 | unsafe { embassy::time::set_clock(rtc) }; |
diff --git a/embassy-nrf-examples/src/bin/spim.rs b/embassy-nrf-examples/src/bin/spim.rs index 27486374f..df921fc86 100644 --- a/embassy-nrf-examples/src/bin/spim.rs +++ b/embassy-nrf-examples/src/bin/spim.rs | |||
| @@ -19,19 +19,14 @@ use embedded_hal::digital::v2::*; | |||
| 19 | use example_common::*; | 19 | use example_common::*; |
| 20 | 20 | ||
| 21 | #[embassy::main] | 21 | #[embassy::main] |
| 22 | async fn main(spawner: Spawner) { | 22 | async fn main(spawner: Spawner, p: Peripherals) { |
| 23 | info!("running!"); | 23 | info!("running!"); |
| 24 | 24 | ||
| 25 | let p = unsafe { Peripherals::steal() }; | 25 | let mut config = spim::Config::default(); |
| 26 | 26 | config.frequency = spim::Frequency::M16; | |
| 27 | let config = spim::Config { | ||
| 28 | frequency: spim::Frequency::M16, | ||
| 29 | mode: spim::MODE_0, | ||
| 30 | orc: 0x00, | ||
| 31 | }; | ||
| 32 | 27 | ||
| 33 | let irq = interrupt::take!(SPIM3); | 28 | let irq = interrupt::take!(SPIM3); |
| 34 | let mut spim = spim::Spim::new(p.SPIM3, irq, p.P0_29, p.P0_28, p.P0_30, config); | 29 | let mut spim = spim::Spim::new(p.SPI3, irq, p.P0_29, p.P0_28, p.P0_30, config); |
| 35 | 30 | ||
| 36 | let mut ncs = Output::new(p.P0_31, Level::High, OutputDrive::Standard); | 31 | let mut ncs = Output::new(p.P0_31, Level::High, OutputDrive::Standard); |
| 37 | 32 | ||
diff --git a/embassy-nrf-examples/src/bin/timer.rs b/embassy-nrf-examples/src/bin/timer.rs index a2b717bc1..ffbbb7841 100644 --- a/embassy-nrf-examples/src/bin/timer.rs +++ b/embassy-nrf-examples/src/bin/timer.rs | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #[path = "../example_common.rs"] | 8 | #[path = "../example_common.rs"] |
| 9 | mod example_common; | 9 | mod example_common; |
| 10 | use embassy_nrf::Peripherals; | ||
| 10 | use example_common::*; | 11 | use example_common::*; |
| 11 | 12 | ||
| 12 | use defmt::panic; | 13 | use defmt::panic; |
| @@ -30,7 +31,7 @@ async fn run2() { | |||
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | #[embassy::main] | 33 | #[embassy::main] |
| 33 | async fn main(spawner: Spawner) { | 34 | async fn main(spawner: Spawner, p: Peripherals) { |
| 34 | unwrap!(spawner.spawn(run1())); | 35 | unwrap!(spawner.spawn(run1())); |
| 35 | unwrap!(spawner.spawn(run2())); | 36 | unwrap!(spawner.spawn(run2())); |
| 36 | } | 37 | } |
diff --git a/embassy-nrf-examples/src/bin/uart.rs b/embassy-nrf-examples/src/bin/uart.rs index 23fc89312..9a0e65d3e 100644 --- a/embassy-nrf-examples/src/bin/uart.rs +++ b/embassy-nrf-examples/src/bin/uart.rs | |||
| @@ -17,9 +17,7 @@ use embassy_nrf::gpio::NoPin; | |||
| 17 | use embassy_nrf::{interrupt, uarte, Peripherals}; | 17 | use embassy_nrf::{interrupt, uarte, Peripherals}; |
| 18 | 18 | ||
| 19 | #[embassy::main] | 19 | #[embassy::main] |
| 20 | async fn main(spawner: Spawner) { | 20 | async fn main(spawner: Spawner, p: Peripherals) { |
| 21 | let p = unsafe { Peripherals::steal() }; | ||
| 22 | |||
| 23 | let mut config = uarte::Config::default(); | 21 | let mut config = uarte::Config::default(); |
| 24 | config.parity = uarte::Parity::EXCLUDED; | 22 | config.parity = uarte::Parity::EXCLUDED; |
| 25 | config.baudrate = uarte::Baudrate::BAUD115200; | 23 | config.baudrate = uarte::Baudrate::BAUD115200; |
| @@ -42,33 +40,5 @@ async fn main(spawner: Spawner) { | |||
| 42 | unwrap!(uart.read(&mut buf).await); | 40 | unwrap!(uart.read(&mut buf).await); |
| 43 | info!("writing..."); | 41 | info!("writing..."); |
| 44 | unwrap!(uart.write(&buf).await); | 42 | unwrap!(uart.write(&buf).await); |
| 45 | |||
| 46 | /* | ||
| 47 | // `receive()` doesn't return until the buffer has been completely filled with | ||
| 48 | // incoming data, which in this case is 8 bytes. | ||
| 49 | // | ||
| 50 | // This example shows how to use `select` to run an uart receive concurrently with a | ||
| 51 | // 1 second timer, effectively adding a timeout to the receive operation. | ||
| 52 | let recv_fut = uart.read(&mut buf); | ||
| 53 | let timer_fut = Timer::after(Duration::from_millis(1000)); | ||
| 54 | let received_len = match select(recv_fut, timer_fut).await { | ||
| 55 | // recv_fut completed first, so we've received `buf_len` bytes. | ||
| 56 | Either::Left(_) => buf_len, | ||
| 57 | // timer_fut completed first. `select` gives us back the future that didn't complete, which | ||
| 58 | // is `recv_fut` in this case, so we can do further stuff with it. | ||
| 59 | // | ||
| 60 | // The recv_fut would stop the uart read automatically when dropped. However, we want to know how | ||
| 61 | // many bytes have been received, so we have to "gracefully stop" it with `.stop()`. | ||
| 62 | Either::Right((_, recv_fut)) => recv_fut.stop().await, | ||
| 63 | }; | ||
| 64 | let received = &mut buf[..received_len]; | ||
| 65 | |||
| 66 | if !received.is_empty() { | ||
| 67 | info!("read done, got {}", received); | ||
| 68 | |||
| 69 | // Echo back received data | ||
| 70 | unwrap!(uart.write(received).await); | ||
| 71 | } | ||
| 72 | */ | ||
| 73 | } | 43 | } |
| 74 | } | 44 | } |
diff --git a/embassy-nrf-examples/src/bin/uart_idle.rs b/embassy-nrf-examples/src/bin/uart_idle.rs index 54d524ae5..a97c65933 100644 --- a/embassy-nrf-examples/src/bin/uart_idle.rs +++ b/embassy-nrf-examples/src/bin/uart_idle.rs | |||
| @@ -18,9 +18,7 @@ use embassy_nrf::gpio::NoPin; | |||
| 18 | use embassy_nrf::{interrupt, uarte, Peripherals}; | 18 | use embassy_nrf::{interrupt, uarte, Peripherals}; |
| 19 | 19 | ||
| 20 | #[embassy::main] | 20 | #[embassy::main] |
| 21 | async fn main(spawner: Spawner) { | 21 | async fn main(spawner: Spawner, p: Peripherals) { |
| 22 | let p = unsafe { Peripherals::steal() }; | ||
| 23 | |||
| 24 | let mut config = uarte::Config::default(); | 22 | let mut config = uarte::Config::default(); |
| 25 | config.parity = uarte::Parity::EXCLUDED; | 23 | config.parity = uarte::Parity::EXCLUDED; |
| 26 | config.baudrate = uarte::Baudrate::BAUD115200; | 24 | config.baudrate = uarte::Baudrate::BAUD115200; |
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index f482f0493..07524fa2d 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -11,11 +11,13 @@ defmt-info = [ ] | |||
| 11 | defmt-warn = [ ] | 11 | defmt-warn = [ ] |
| 12 | defmt-error = [ ] | 12 | defmt-error = [ ] |
| 13 | 13 | ||
| 14 | 52810 = ["nrf52810-pac"] | 14 | nrf52805 = ["nrf52805-pac"] |
| 15 | 52811 = ["nrf52811-pac"] | 15 | nrf52810 = ["nrf52810-pac"] |
| 16 | 52832 = ["nrf52832-pac"] | 16 | nrf52811 = ["nrf52811-pac"] |
| 17 | 52833 = ["nrf52833-pac"] | 17 | nrf52820 = ["nrf52820-pac"] |
| 18 | 52840 = ["nrf52840-pac"] | 18 | nrf52832 = ["nrf52832-pac"] |
| 19 | nrf52833 = ["nrf52833-pac"] | ||
| 20 | nrf52840 = ["nrf52840-pac"] | ||
| 19 | 21 | ||
| 20 | 22 | ||
| 21 | [dependencies] | 23 | [dependencies] |
| @@ -30,10 +32,12 @@ cortex-m = "0.7.1" | |||
| 30 | embedded-hal = { version = "0.2.4" } | 32 | embedded-hal = { version = "0.2.4" } |
| 31 | embedded-dma = { version = "0.1.2" } | 33 | embedded-dma = { version = "0.1.2" } |
| 32 | futures = { version = "0.3.5", default-features = false } | 34 | futures = { version = "0.3.5", default-features = false } |
| 35 | critical-section = "0.2.1" | ||
| 33 | 36 | ||
| 37 | nrf52805-pac = { version = "0.1.0", optional = true, features = [ "rt" ], git = "https://github.com/Dirbaio/nrf52805-pac"} | ||
| 34 | nrf52810-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} | 38 | nrf52810-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} |
| 35 | nrf52811-pac = { version = "0.9.1", optional = true, features = [ "rt" ]} | 39 | nrf52811-pac = { version = "0.9.1", optional = true, features = [ "rt" ]} |
| 40 | nrf52820-pac = { version = "0.1.0", optional = true, features = [ "rt" ], git = "https://github.com/Dirbaio/nrf52820-pac"} | ||
| 36 | nrf52832-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} | 41 | nrf52832-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} |
| 37 | nrf52833-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} | 42 | nrf52833-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} |
| 38 | nrf52840-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} | 43 | nrf52840-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} |
| 39 | critical-section = "0.2.1" | ||
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs new file mode 100644 index 000000000..272cabc06 --- /dev/null +++ b/embassy-nrf/src/chips/nrf52805.rs | |||
| @@ -0,0 +1,181 @@ | |||
| 1 | pub use nrf52805_pac as pac; | ||
| 2 | |||
| 3 | pub const EASY_DMA_SIZE: usize = (1 << 14) - 1; | ||
| 4 | pub const FORCE_COPY_BUFFER_SIZE: usize = 256; | ||
| 5 | |||
| 6 | embassy_extras::peripherals! { | ||
| 7 | // RTC | ||
| 8 | RTC0, | ||
| 9 | RTC1, | ||
| 10 | |||
| 11 | // UARTE | ||
| 12 | UARTE0, | ||
| 13 | |||
| 14 | // SPI/TWI | ||
| 15 | TWI0, | ||
| 16 | SPI0, | ||
| 17 | |||
| 18 | // SAADC | ||
| 19 | SAADC, | ||
| 20 | |||
| 21 | // TIMER | ||
| 22 | TIMER0, | ||
| 23 | TIMER1, | ||
| 24 | TIMER2, | ||
| 25 | |||
| 26 | // GPIOTE | ||
| 27 | GPIOTE_CH0, | ||
| 28 | GPIOTE_CH1, | ||
| 29 | GPIOTE_CH2, | ||
| 30 | GPIOTE_CH3, | ||
| 31 | GPIOTE_CH4, | ||
| 32 | GPIOTE_CH5, | ||
| 33 | GPIOTE_CH6, | ||
| 34 | GPIOTE_CH7, | ||
| 35 | |||
| 36 | // PPI | ||
| 37 | PPI_CH0, | ||
| 38 | PPI_CH1, | ||
| 39 | PPI_CH2, | ||
| 40 | PPI_CH3, | ||
| 41 | PPI_CH4, | ||
| 42 | PPI_CH5, | ||
| 43 | PPI_CH6, | ||
| 44 | PPI_CH7, | ||
| 45 | PPI_CH8, | ||
| 46 | PPI_CH9, | ||
| 47 | PPI_CH10, | ||
| 48 | PPI_CH11, | ||
| 49 | PPI_CH12, | ||
| 50 | PPI_CH13, | ||
| 51 | PPI_CH14, | ||
| 52 | PPI_CH15, | ||
| 53 | PPI_CH16, | ||
| 54 | PPI_CH17, | ||
| 55 | PPI_CH18, | ||
| 56 | PPI_CH19, | ||
| 57 | PPI_CH20, | ||
| 58 | PPI_CH21, | ||
| 59 | PPI_CH22, | ||
| 60 | PPI_CH23, | ||
| 61 | PPI_CH24, | ||
| 62 | PPI_CH25, | ||
| 63 | PPI_CH26, | ||
| 64 | PPI_CH27, | ||
| 65 | PPI_CH28, | ||
| 66 | PPI_CH29, | ||
| 67 | PPI_CH30, | ||
| 68 | PPI_CH31, | ||
| 69 | |||
| 70 | PPI_GROUP0, | ||
| 71 | PPI_GROUP1, | ||
| 72 | PPI_GROUP2, | ||
| 73 | PPI_GROUP3, | ||
| 74 | PPI_GROUP4, | ||
| 75 | PPI_GROUP5, | ||
| 76 | |||
| 77 | // GPIO port 0 | ||
| 78 | P0_00, | ||
| 79 | P0_01, | ||
| 80 | P0_02, | ||
| 81 | P0_03, | ||
| 82 | P0_04, | ||
| 83 | P0_05, | ||
| 84 | P0_06, | ||
| 85 | P0_07, | ||
| 86 | P0_08, | ||
| 87 | P0_09, | ||
| 88 | P0_10, | ||
| 89 | P0_11, | ||
| 90 | P0_12, | ||
| 91 | P0_13, | ||
| 92 | P0_14, | ||
| 93 | P0_15, | ||
| 94 | P0_16, | ||
| 95 | P0_17, | ||
| 96 | P0_18, | ||
| 97 | P0_19, | ||
| 98 | P0_20, | ||
| 99 | P0_21, | ||
| 100 | P0_22, | ||
| 101 | P0_23, | ||
| 102 | P0_24, | ||
| 103 | P0_25, | ||
| 104 | P0_26, | ||
| 105 | P0_27, | ||
| 106 | P0_28, | ||
| 107 | P0_29, | ||
| 108 | P0_30, | ||
| 109 | P0_31, | ||
| 110 | } | ||
| 111 | |||
| 112 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | ||
| 113 | |||
| 114 | impl_spim!(SPI0, SPIM0, SPIM0_SPIS0_SPI0); | ||
| 115 | |||
| 116 | impl_twim!(TWI0, TWIM0, TWIM0_TWIS0_TWI0); | ||
| 117 | |||
| 118 | impl_timer!(TIMER0, TIMER0, TIMER0); | ||
| 119 | impl_timer!(TIMER1, TIMER1, TIMER1); | ||
| 120 | impl_timer!(TIMER2, TIMER2, TIMER2); | ||
| 121 | |||
| 122 | impl_pin!(P0_00, 0, 0); | ||
| 123 | impl_pin!(P0_01, 0, 1); | ||
| 124 | impl_pin!(P0_02, 0, 2); | ||
| 125 | impl_pin!(P0_03, 0, 3); | ||
| 126 | impl_pin!(P0_04, 0, 4); | ||
| 127 | impl_pin!(P0_05, 0, 5); | ||
| 128 | impl_pin!(P0_06, 0, 6); | ||
| 129 | impl_pin!(P0_07, 0, 7); | ||
| 130 | impl_pin!(P0_08, 0, 8); | ||
| 131 | impl_pin!(P0_09, 0, 9); | ||
| 132 | impl_pin!(P0_10, 0, 10); | ||
| 133 | impl_pin!(P0_11, 0, 11); | ||
| 134 | impl_pin!(P0_12, 0, 12); | ||
| 135 | impl_pin!(P0_13, 0, 13); | ||
| 136 | impl_pin!(P0_14, 0, 14); | ||
| 137 | impl_pin!(P0_15, 0, 15); | ||
| 138 | impl_pin!(P0_16, 0, 16); | ||
| 139 | impl_pin!(P0_17, 0, 17); | ||
| 140 | impl_pin!(P0_18, 0, 18); | ||
| 141 | impl_pin!(P0_19, 0, 19); | ||
| 142 | impl_pin!(P0_20, 0, 20); | ||
| 143 | impl_pin!(P0_21, 0, 21); | ||
| 144 | impl_pin!(P0_22, 0, 22); | ||
| 145 | impl_pin!(P0_23, 0, 23); | ||
| 146 | impl_pin!(P0_24, 0, 24); | ||
| 147 | impl_pin!(P0_25, 0, 25); | ||
| 148 | impl_pin!(P0_26, 0, 26); | ||
| 149 | impl_pin!(P0_27, 0, 27); | ||
| 150 | impl_pin!(P0_28, 0, 28); | ||
| 151 | impl_pin!(P0_29, 0, 29); | ||
| 152 | impl_pin!(P0_30, 0, 30); | ||
| 153 | impl_pin!(P0_31, 0, 31); | ||
| 154 | |||
| 155 | pub mod irqs { | ||
| 156 | use embassy_macros::interrupt_declare as declare; | ||
| 157 | declare!(POWER_CLOCK); | ||
| 158 | declare!(RADIO); | ||
| 159 | declare!(UARTE0_UART0); | ||
| 160 | declare!(TWIM0_TWIS0_TWI0); | ||
| 161 | declare!(SPIM0_SPIS0_SPI0); | ||
| 162 | declare!(GPIOTE); | ||
| 163 | declare!(SAADC); | ||
| 164 | declare!(TIMER0); | ||
| 165 | declare!(TIMER1); | ||
| 166 | declare!(TIMER2); | ||
| 167 | declare!(RTC0); | ||
| 168 | declare!(TEMP); | ||
| 169 | declare!(RNG); | ||
| 170 | declare!(ECB); | ||
| 171 | declare!(CCM_AAR); | ||
| 172 | declare!(WDT); | ||
| 173 | declare!(RTC1); | ||
| 174 | declare!(QDEC); | ||
| 175 | declare!(SWI0_EGU0); | ||
| 176 | declare!(SWI1_EGU1); | ||
| 177 | declare!(SWI2); | ||
| 178 | declare!(SWI3); | ||
| 179 | declare!(SWI4); | ||
| 180 | declare!(SWI5); | ||
| 181 | } | ||
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs new file mode 100644 index 000000000..9e9f80090 --- /dev/null +++ b/embassy-nrf/src/chips/nrf52810.rs | |||
| @@ -0,0 +1,189 @@ | |||
| 1 | pub use nrf52810_pac as pac; | ||
| 2 | |||
| 3 | pub const EASY_DMA_SIZE: usize = (1 << 10) - 1; | ||
| 4 | pub const FORCE_COPY_BUFFER_SIZE: usize = 256; | ||
| 5 | |||
| 6 | embassy_extras::peripherals! { | ||
| 7 | // RTC | ||
| 8 | RTC0, | ||
| 9 | RTC1, | ||
| 10 | |||
| 11 | // UARTE | ||
| 12 | UARTE0, | ||
| 13 | |||
| 14 | // SPI/TWI | ||
| 15 | TWI0, | ||
| 16 | SPI0, | ||
| 17 | |||
| 18 | // SAADC | ||
| 19 | SAADC, | ||
| 20 | |||
| 21 | // PWM | ||
| 22 | PWM0, | ||
| 23 | |||
| 24 | // TIMER | ||
| 25 | TIMER0, | ||
| 26 | TIMER1, | ||
| 27 | TIMER2, | ||
| 28 | |||
| 29 | // GPIOTE | ||
| 30 | GPIOTE_CH0, | ||
| 31 | GPIOTE_CH1, | ||
| 32 | GPIOTE_CH2, | ||
| 33 | GPIOTE_CH3, | ||
| 34 | GPIOTE_CH4, | ||
| 35 | GPIOTE_CH5, | ||
| 36 | GPIOTE_CH6, | ||
| 37 | GPIOTE_CH7, | ||
| 38 | |||
| 39 | // PPI | ||
| 40 | PPI_CH0, | ||
| 41 | PPI_CH1, | ||
| 42 | PPI_CH2, | ||
| 43 | PPI_CH3, | ||
| 44 | PPI_CH4, | ||
| 45 | PPI_CH5, | ||
| 46 | PPI_CH6, | ||
| 47 | PPI_CH7, | ||
| 48 | PPI_CH8, | ||
| 49 | PPI_CH9, | ||
| 50 | PPI_CH10, | ||
| 51 | PPI_CH11, | ||
| 52 | PPI_CH12, | ||
| 53 | PPI_CH13, | ||
| 54 | PPI_CH14, | ||
| 55 | PPI_CH15, | ||
| 56 | PPI_CH16, | ||
| 57 | PPI_CH17, | ||
| 58 | PPI_CH18, | ||
| 59 | PPI_CH19, | ||
| 60 | PPI_CH20, | ||
| 61 | PPI_CH21, | ||
| 62 | PPI_CH22, | ||
| 63 | PPI_CH23, | ||
| 64 | PPI_CH24, | ||
| 65 | PPI_CH25, | ||
| 66 | PPI_CH26, | ||
| 67 | PPI_CH27, | ||
| 68 | PPI_CH28, | ||
| 69 | PPI_CH29, | ||
| 70 | PPI_CH30, | ||
| 71 | PPI_CH31, | ||
| 72 | |||
| 73 | PPI_GROUP0, | ||
| 74 | PPI_GROUP1, | ||
| 75 | PPI_GROUP2, | ||
| 76 | PPI_GROUP3, | ||
| 77 | PPI_GROUP4, | ||
| 78 | PPI_GROUP5, | ||
| 79 | |||
| 80 | // GPIO port 0 | ||
| 81 | P0_00, | ||
| 82 | P0_01, | ||
| 83 | P0_02, | ||
| 84 | P0_03, | ||
| 85 | P0_04, | ||
| 86 | P0_05, | ||
| 87 | P0_06, | ||
| 88 | P0_07, | ||
| 89 | P0_08, | ||
| 90 | P0_09, | ||
| 91 | P0_10, | ||
| 92 | P0_11, | ||
| 93 | P0_12, | ||
| 94 | P0_13, | ||
| 95 | P0_14, | ||
| 96 | P0_15, | ||
| 97 | P0_16, | ||
| 98 | P0_17, | ||
| 99 | P0_18, | ||
| 100 | P0_19, | ||
| 101 | P0_20, | ||
| 102 | P0_21, | ||
| 103 | P0_22, | ||
| 104 | P0_23, | ||
| 105 | P0_24, | ||
| 106 | P0_25, | ||
| 107 | P0_26, | ||
| 108 | P0_27, | ||
| 109 | P0_28, | ||
| 110 | P0_29, | ||
| 111 | P0_30, | ||
| 112 | P0_31, | ||
| 113 | } | ||
| 114 | |||
| 115 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | ||
| 116 | |||
| 117 | impl_spim!(SPI0, SPIM0, SPIM0_SPIS0_SPI0); | ||
| 118 | |||
| 119 | impl_twim!(TWI0, TWIM0, TWIM0_TWIS0_TWI0); | ||
| 120 | |||
| 121 | impl_pwm!(PWM0, PWM0, PWM0); | ||
| 122 | |||
| 123 | impl_timer!(TIMER0, TIMER0, TIMER0); | ||
| 124 | impl_timer!(TIMER1, TIMER1, TIMER1); | ||
| 125 | impl_timer!(TIMER2, TIMER2, TIMER2); | ||
| 126 | |||
| 127 | impl_pin!(P0_00, 0, 0); | ||
| 128 | impl_pin!(P0_01, 0, 1); | ||
| 129 | impl_pin!(P0_02, 0, 2); | ||
| 130 | impl_pin!(P0_03, 0, 3); | ||
| 131 | impl_pin!(P0_04, 0, 4); | ||
| 132 | impl_pin!(P0_05, 0, 5); | ||
| 133 | impl_pin!(P0_06, 0, 6); | ||
| 134 | impl_pin!(P0_07, 0, 7); | ||
| 135 | impl_pin!(P0_08, 0, 8); | ||
| 136 | impl_pin!(P0_09, 0, 9); | ||
| 137 | impl_pin!(P0_10, 0, 10); | ||
| 138 | impl_pin!(P0_11, 0, 11); | ||
| 139 | impl_pin!(P0_12, 0, 12); | ||
| 140 | impl_pin!(P0_13, 0, 13); | ||
| 141 | impl_pin!(P0_14, 0, 14); | ||
| 142 | impl_pin!(P0_15, 0, 15); | ||
| 143 | impl_pin!(P0_16, 0, 16); | ||
| 144 | impl_pin!(P0_17, 0, 17); | ||
| 145 | impl_pin!(P0_18, 0, 18); | ||
| 146 | impl_pin!(P0_19, 0, 19); | ||
| 147 | impl_pin!(P0_20, 0, 20); | ||
| 148 | impl_pin!(P0_21, 0, 21); | ||
| 149 | impl_pin!(P0_22, 0, 22); | ||
| 150 | impl_pin!(P0_23, 0, 23); | ||
| 151 | impl_pin!(P0_24, 0, 24); | ||
| 152 | impl_pin!(P0_25, 0, 25); | ||
| 153 | impl_pin!(P0_26, 0, 26); | ||
| 154 | impl_pin!(P0_27, 0, 27); | ||
| 155 | impl_pin!(P0_28, 0, 28); | ||
| 156 | impl_pin!(P0_29, 0, 29); | ||
| 157 | impl_pin!(P0_30, 0, 30); | ||
| 158 | impl_pin!(P0_31, 0, 31); | ||
| 159 | |||
| 160 | pub mod irqs { | ||
| 161 | use embassy_macros::interrupt_declare as declare; | ||
| 162 | declare!(POWER_CLOCK); | ||
| 163 | declare!(RADIO); | ||
| 164 | declare!(UARTE0_UART0); | ||
| 165 | declare!(TWIM0_TWIS0_TWI0); | ||
| 166 | declare!(SPIM0_SPIS0_SPI0); | ||
| 167 | declare!(GPIOTE); | ||
| 168 | declare!(SAADC); | ||
| 169 | declare!(TIMER0); | ||
| 170 | declare!(TIMER1); | ||
| 171 | declare!(TIMER2); | ||
| 172 | declare!(RTC0); | ||
| 173 | declare!(TEMP); | ||
| 174 | declare!(RNG); | ||
| 175 | declare!(ECB); | ||
| 176 | declare!(CCM_AAR); | ||
| 177 | declare!(WDT); | ||
| 178 | declare!(RTC1); | ||
| 179 | declare!(QDEC); | ||
| 180 | declare!(COMP); | ||
| 181 | declare!(SWI0_EGU0); | ||
| 182 | declare!(SWI1_EGU1); | ||
| 183 | declare!(SWI2); | ||
| 184 | declare!(SWI3); | ||
| 185 | declare!(SWI4); | ||
| 186 | declare!(SWI5); | ||
| 187 | declare!(PWM0); | ||
| 188 | declare!(PDM); | ||
| 189 | } | ||
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs new file mode 100644 index 000000000..a9ef0ed19 --- /dev/null +++ b/embassy-nrf/src/chips/nrf52811.rs | |||
| @@ -0,0 +1,190 @@ | |||
| 1 | pub use nrf52811_pac as pac; | ||
| 2 | |||
| 3 | pub const EASY_DMA_SIZE: usize = (1 << 14) - 1; | ||
| 4 | pub const FORCE_COPY_BUFFER_SIZE: usize = 256; | ||
| 5 | |||
| 6 | embassy_extras::peripherals! { | ||
| 7 | // RTC | ||
| 8 | RTC0, | ||
| 9 | RTC1, | ||
| 10 | |||
| 11 | // UARTE | ||
| 12 | UARTE0, | ||
| 13 | |||
| 14 | // SPI/TWI | ||
| 15 | TWISPI0, | ||
| 16 | SPI1, | ||
| 17 | |||
| 18 | // SAADC | ||
| 19 | SAADC, | ||
| 20 | |||
| 21 | // PWM | ||
| 22 | PWM0, | ||
| 23 | |||
| 24 | // TIMER | ||
| 25 | TIMER0, | ||
| 26 | TIMER1, | ||
| 27 | TIMER2, | ||
| 28 | |||
| 29 | // GPIOTE | ||
| 30 | GPIOTE_CH0, | ||
| 31 | GPIOTE_CH1, | ||
| 32 | GPIOTE_CH2, | ||
| 33 | GPIOTE_CH3, | ||
| 34 | GPIOTE_CH4, | ||
| 35 | GPIOTE_CH5, | ||
| 36 | GPIOTE_CH6, | ||
| 37 | GPIOTE_CH7, | ||
| 38 | |||
| 39 | // PPI | ||
| 40 | PPI_CH0, | ||
| 41 | PPI_CH1, | ||
| 42 | PPI_CH2, | ||
| 43 | PPI_CH3, | ||
| 44 | PPI_CH4, | ||
| 45 | PPI_CH5, | ||
| 46 | PPI_CH6, | ||
| 47 | PPI_CH7, | ||
| 48 | PPI_CH8, | ||
| 49 | PPI_CH9, | ||
| 50 | PPI_CH10, | ||
| 51 | PPI_CH11, | ||
| 52 | PPI_CH12, | ||
| 53 | PPI_CH13, | ||
| 54 | PPI_CH14, | ||
| 55 | PPI_CH15, | ||
| 56 | PPI_CH16, | ||
| 57 | PPI_CH17, | ||
| 58 | PPI_CH18, | ||
| 59 | PPI_CH19, | ||
| 60 | PPI_CH20, | ||
| 61 | PPI_CH21, | ||
| 62 | PPI_CH22, | ||
| 63 | PPI_CH23, | ||
| 64 | PPI_CH24, | ||
| 65 | PPI_CH25, | ||
| 66 | PPI_CH26, | ||
| 67 | PPI_CH27, | ||
| 68 | PPI_CH28, | ||
| 69 | PPI_CH29, | ||
| 70 | PPI_CH30, | ||
| 71 | PPI_CH31, | ||
| 72 | |||
| 73 | PPI_GROUP0, | ||
| 74 | PPI_GROUP1, | ||
| 75 | PPI_GROUP2, | ||
| 76 | PPI_GROUP3, | ||
| 77 | PPI_GROUP4, | ||
| 78 | PPI_GROUP5, | ||
| 79 | |||
| 80 | // GPIO port 0 | ||
| 81 | P0_00, | ||
| 82 | P0_01, | ||
| 83 | P0_02, | ||
| 84 | P0_03, | ||
| 85 | P0_04, | ||
| 86 | P0_05, | ||
| 87 | P0_06, | ||
| 88 | P0_07, | ||
| 89 | P0_08, | ||
| 90 | P0_09, | ||
| 91 | P0_10, | ||
| 92 | P0_11, | ||
| 93 | P0_12, | ||
| 94 | P0_13, | ||
| 95 | P0_14, | ||
| 96 | P0_15, | ||
| 97 | P0_16, | ||
| 98 | P0_17, | ||
| 99 | P0_18, | ||
| 100 | P0_19, | ||
| 101 | P0_20, | ||
| 102 | P0_21, | ||
| 103 | P0_22, | ||
| 104 | P0_23, | ||
| 105 | P0_24, | ||
| 106 | P0_25, | ||
| 107 | P0_26, | ||
| 108 | P0_27, | ||
| 109 | P0_28, | ||
| 110 | P0_29, | ||
| 111 | P0_30, | ||
| 112 | P0_31, | ||
| 113 | } | ||
| 114 | |||
| 115 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | ||
| 116 | |||
| 117 | impl_spim!(TWISPI0, SPIM0, TWIM0_TWIS0_TWI0_SPIM0_SPIS0_SPI0); | ||
| 118 | impl_spim!(SPI1, SPIM1, SPIM1_SPIS1_SPI1); | ||
| 119 | |||
| 120 | impl_twim!(TWISPI0, TWIM0, TWIM0_TWIS0_TWI0_SPIM0_SPIS0_SPI0); | ||
| 121 | |||
| 122 | impl_pwm!(PWM0, PWM0, PWM0); | ||
| 123 | |||
| 124 | impl_timer!(TIMER0, TIMER0, TIMER0); | ||
| 125 | impl_timer!(TIMER1, TIMER1, TIMER1); | ||
| 126 | impl_timer!(TIMER2, TIMER2, TIMER2); | ||
| 127 | |||
| 128 | impl_pin!(P0_00, 0, 0); | ||
| 129 | impl_pin!(P0_01, 0, 1); | ||
| 130 | impl_pin!(P0_02, 0, 2); | ||
| 131 | impl_pin!(P0_03, 0, 3); | ||
| 132 | impl_pin!(P0_04, 0, 4); | ||
| 133 | impl_pin!(P0_05, 0, 5); | ||
| 134 | impl_pin!(P0_06, 0, 6); | ||
| 135 | impl_pin!(P0_07, 0, 7); | ||
| 136 | impl_pin!(P0_08, 0, 8); | ||
| 137 | impl_pin!(P0_09, 0, 9); | ||
| 138 | impl_pin!(P0_10, 0, 10); | ||
| 139 | impl_pin!(P0_11, 0, 11); | ||
| 140 | impl_pin!(P0_12, 0, 12); | ||
| 141 | impl_pin!(P0_13, 0, 13); | ||
| 142 | impl_pin!(P0_14, 0, 14); | ||
| 143 | impl_pin!(P0_15, 0, 15); | ||
| 144 | impl_pin!(P0_16, 0, 16); | ||
| 145 | impl_pin!(P0_17, 0, 17); | ||
| 146 | impl_pin!(P0_18, 0, 18); | ||
| 147 | impl_pin!(P0_19, 0, 19); | ||
| 148 | impl_pin!(P0_20, 0, 20); | ||
| 149 | impl_pin!(P0_21, 0, 21); | ||
| 150 | impl_pin!(P0_22, 0, 22); | ||
| 151 | impl_pin!(P0_23, 0, 23); | ||
| 152 | impl_pin!(P0_24, 0, 24); | ||
| 153 | impl_pin!(P0_25, 0, 25); | ||
| 154 | impl_pin!(P0_26, 0, 26); | ||
| 155 | impl_pin!(P0_27, 0, 27); | ||
| 156 | impl_pin!(P0_28, 0, 28); | ||
| 157 | impl_pin!(P0_29, 0, 29); | ||
| 158 | impl_pin!(P0_30, 0, 30); | ||
| 159 | impl_pin!(P0_31, 0, 31); | ||
| 160 | |||
| 161 | pub mod irqs { | ||
| 162 | use embassy_macros::interrupt_declare as declare; | ||
| 163 | declare!(POWER_CLOCK); | ||
| 164 | declare!(RADIO); | ||
| 165 | declare!(UARTE0_UART0); | ||
| 166 | declare!(TWIM0_TWIS0_TWI0_SPIM0_SPIS0_SPI0); | ||
| 167 | declare!(SPIM1_SPIS1_SPI1); | ||
| 168 | declare!(GPIOTE); | ||
| 169 | declare!(SAADC); | ||
| 170 | declare!(TIMER0); | ||
| 171 | declare!(TIMER1); | ||
| 172 | declare!(TIMER2); | ||
| 173 | declare!(RTC0); | ||
| 174 | declare!(TEMP); | ||
| 175 | declare!(RNG); | ||
| 176 | declare!(ECB); | ||
| 177 | declare!(CCM_AAR); | ||
| 178 | declare!(WDT); | ||
| 179 | declare!(RTC1); | ||
| 180 | declare!(QDEC); | ||
| 181 | declare!(COMP); | ||
| 182 | declare!(SWI0_EGU0); | ||
| 183 | declare!(SWI1_EGU1); | ||
| 184 | declare!(SWI2); | ||
| 185 | declare!(SWI3); | ||
| 186 | declare!(SWI4); | ||
| 187 | declare!(SWI5); | ||
| 188 | declare!(PWM0); | ||
| 189 | declare!(PDM); | ||
| 190 | } | ||
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs new file mode 100644 index 000000000..d0a8b9e9a --- /dev/null +++ b/embassy-nrf/src/chips/nrf52820.rs | |||
| @@ -0,0 +1,187 @@ | |||
| 1 | pub use nrf52820_pac as pac; | ||
| 2 | |||
| 3 | pub const EASY_DMA_SIZE: usize = (1 << 15) - 1; | ||
| 4 | pub const FORCE_COPY_BUFFER_SIZE: usize = 512; | ||
| 5 | |||
| 6 | embassy_extras::peripherals! { | ||
| 7 | // RTC | ||
| 8 | RTC0, | ||
| 9 | RTC1, | ||
| 10 | |||
| 11 | // UARTE | ||
| 12 | UARTE0, | ||
| 13 | |||
| 14 | // SPI/TWI | ||
| 15 | TWISPI0, | ||
| 16 | TWISPI1, | ||
| 17 | |||
| 18 | // SAADC | ||
| 19 | SAADC, | ||
| 20 | |||
| 21 | // TIMER | ||
| 22 | TIMER0, | ||
| 23 | TIMER1, | ||
| 24 | TIMER2, | ||
| 25 | TIMER3, | ||
| 26 | |||
| 27 | // GPIOTE | ||
| 28 | GPIOTE_CH0, | ||
| 29 | GPIOTE_CH1, | ||
| 30 | GPIOTE_CH2, | ||
| 31 | GPIOTE_CH3, | ||
| 32 | GPIOTE_CH4, | ||
| 33 | GPIOTE_CH5, | ||
| 34 | GPIOTE_CH6, | ||
| 35 | GPIOTE_CH7, | ||
| 36 | |||
| 37 | // PPI | ||
| 38 | PPI_CH0, | ||
| 39 | PPI_CH1, | ||
| 40 | PPI_CH2, | ||
| 41 | PPI_CH3, | ||
| 42 | PPI_CH4, | ||
| 43 | PPI_CH5, | ||
| 44 | PPI_CH6, | ||
| 45 | PPI_CH7, | ||
| 46 | PPI_CH8, | ||
| 47 | PPI_CH9, | ||
| 48 | PPI_CH10, | ||
| 49 | PPI_CH11, | ||
| 50 | PPI_CH12, | ||
| 51 | PPI_CH13, | ||
| 52 | PPI_CH14, | ||
| 53 | PPI_CH15, | ||
| 54 | PPI_CH16, | ||
| 55 | PPI_CH17, | ||
| 56 | PPI_CH18, | ||
| 57 | PPI_CH19, | ||
| 58 | PPI_CH20, | ||
| 59 | PPI_CH21, | ||
| 60 | PPI_CH22, | ||
| 61 | PPI_CH23, | ||
| 62 | PPI_CH24, | ||
| 63 | PPI_CH25, | ||
| 64 | PPI_CH26, | ||
| 65 | PPI_CH27, | ||
| 66 | PPI_CH28, | ||
| 67 | PPI_CH29, | ||
| 68 | PPI_CH30, | ||
| 69 | PPI_CH31, | ||
| 70 | |||
| 71 | PPI_GROUP0, | ||
| 72 | PPI_GROUP1, | ||
| 73 | PPI_GROUP2, | ||
| 74 | PPI_GROUP3, | ||
| 75 | PPI_GROUP4, | ||
| 76 | PPI_GROUP5, | ||
| 77 | |||
| 78 | // GPIO port 0 | ||
| 79 | P0_00, | ||
| 80 | P0_01, | ||
| 81 | P0_02, | ||
| 82 | P0_03, | ||
| 83 | P0_04, | ||
| 84 | P0_05, | ||
| 85 | P0_06, | ||
| 86 | P0_07, | ||
| 87 | P0_08, | ||
| 88 | P0_09, | ||
| 89 | P0_10, | ||
| 90 | P0_11, | ||
| 91 | P0_12, | ||
| 92 | P0_13, | ||
| 93 | P0_14, | ||
| 94 | P0_15, | ||
| 95 | P0_16, | ||
| 96 | P0_17, | ||
| 97 | P0_18, | ||
| 98 | P0_19, | ||
| 99 | P0_20, | ||
| 100 | P0_21, | ||
| 101 | P0_22, | ||
| 102 | P0_23, | ||
| 103 | P0_24, | ||
| 104 | P0_25, | ||
| 105 | P0_26, | ||
| 106 | P0_27, | ||
| 107 | P0_28, | ||
| 108 | P0_29, | ||
| 109 | P0_30, | ||
| 110 | P0_31, | ||
| 111 | } | ||
| 112 | |||
| 113 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | ||
| 114 | |||
| 115 | impl_spim!(TWISPI0, SPIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 116 | impl_spim!(TWISPI1, SPIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 117 | |||
| 118 | impl_twim!(TWISPI0, TWIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 119 | impl_twim!(TWISPI1, TWIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 120 | |||
| 121 | impl_timer!(TIMER0, TIMER0, TIMER0); | ||
| 122 | impl_timer!(TIMER1, TIMER1, TIMER1); | ||
| 123 | impl_timer!(TIMER2, TIMER2, TIMER2); | ||
| 124 | impl_timer!(TIMER3, TIMER3, TIMER3, extended); | ||
| 125 | |||
| 126 | impl_pin!(P0_00, 0, 0); | ||
| 127 | impl_pin!(P0_01, 0, 1); | ||
| 128 | impl_pin!(P0_02, 0, 2); | ||
| 129 | impl_pin!(P0_03, 0, 3); | ||
| 130 | impl_pin!(P0_04, 0, 4); | ||
| 131 | impl_pin!(P0_05, 0, 5); | ||
| 132 | impl_pin!(P0_06, 0, 6); | ||
| 133 | impl_pin!(P0_07, 0, 7); | ||
| 134 | impl_pin!(P0_08, 0, 8); | ||
| 135 | impl_pin!(P0_09, 0, 9); | ||
| 136 | impl_pin!(P0_10, 0, 10); | ||
| 137 | impl_pin!(P0_11, 0, 11); | ||
| 138 | impl_pin!(P0_12, 0, 12); | ||
| 139 | impl_pin!(P0_13, 0, 13); | ||
| 140 | impl_pin!(P0_14, 0, 14); | ||
| 141 | impl_pin!(P0_15, 0, 15); | ||
| 142 | impl_pin!(P0_16, 0, 16); | ||
| 143 | impl_pin!(P0_17, 0, 17); | ||
| 144 | impl_pin!(P0_18, 0, 18); | ||
| 145 | impl_pin!(P0_19, 0, 19); | ||
| 146 | impl_pin!(P0_20, 0, 20); | ||
| 147 | impl_pin!(P0_21, 0, 21); | ||
| 148 | impl_pin!(P0_22, 0, 22); | ||
| 149 | impl_pin!(P0_23, 0, 23); | ||
| 150 | impl_pin!(P0_24, 0, 24); | ||
| 151 | impl_pin!(P0_25, 0, 25); | ||
| 152 | impl_pin!(P0_26, 0, 26); | ||
| 153 | impl_pin!(P0_27, 0, 27); | ||
| 154 | impl_pin!(P0_28, 0, 28); | ||
| 155 | impl_pin!(P0_29, 0, 29); | ||
| 156 | impl_pin!(P0_30, 0, 30); | ||
| 157 | impl_pin!(P0_31, 0, 31); | ||
| 158 | |||
| 159 | pub mod irqs { | ||
| 160 | use embassy_macros::interrupt_declare as declare; | ||
| 161 | declare!(POWER_CLOCK); | ||
| 162 | declare!(RADIO); | ||
| 163 | declare!(UARTE0_UART0); | ||
| 164 | declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 165 | declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 166 | declare!(GPIOTE); | ||
| 167 | declare!(TIMER0); | ||
| 168 | declare!(TIMER1); | ||
| 169 | declare!(TIMER2); | ||
| 170 | declare!(RTC0); | ||
| 171 | declare!(TEMP); | ||
| 172 | declare!(RNG); | ||
| 173 | declare!(ECB); | ||
| 174 | declare!(CCM_AAR); | ||
| 175 | declare!(WDT); | ||
| 176 | declare!(RTC1); | ||
| 177 | declare!(QDEC); | ||
| 178 | declare!(COMP); | ||
| 179 | declare!(SWI0_EGU0); | ||
| 180 | declare!(SWI1_EGU1); | ||
| 181 | declare!(SWI2_EGU2); | ||
| 182 | declare!(SWI3_EGU3); | ||
| 183 | declare!(SWI4_EGU4); | ||
| 184 | declare!(SWI5_EGU5); | ||
| 185 | declare!(TIMER3); | ||
| 186 | declare!(USBD); | ||
| 187 | } | ||
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs new file mode 100644 index 000000000..4e57f2fa4 --- /dev/null +++ b/embassy-nrf/src/chips/nrf52832.rs | |||
| @@ -0,0 +1,213 @@ | |||
| 1 | pub use nrf52832_pac as pac; | ||
| 2 | |||
| 3 | pub const EASY_DMA_SIZE: usize = (1 << 8) - 1; | ||
| 4 | pub const FORCE_COPY_BUFFER_SIZE: usize = 255; | ||
| 5 | |||
| 6 | embassy_extras::peripherals! { | ||
| 7 | // RTC | ||
| 8 | RTC0, | ||
| 9 | RTC1, | ||
| 10 | RTC2, | ||
| 11 | |||
| 12 | // UARTE | ||
| 13 | UARTE0, | ||
| 14 | |||
| 15 | // SPI/TWI | ||
| 16 | TWISPI0, | ||
| 17 | TWISPI1, | ||
| 18 | SPI2, | ||
| 19 | SPI3, | ||
| 20 | |||
| 21 | // SAADC | ||
| 22 | SAADC, | ||
| 23 | |||
| 24 | // PWM | ||
| 25 | PWM0, | ||
| 26 | PWM1, | ||
| 27 | PWM2, | ||
| 28 | |||
| 29 | // TIMER | ||
| 30 | TIMER0, | ||
| 31 | TIMER1, | ||
| 32 | TIMER2, | ||
| 33 | TIMER3, | ||
| 34 | TIMER4, | ||
| 35 | |||
| 36 | // GPIOTE | ||
| 37 | GPIOTE_CH0, | ||
| 38 | GPIOTE_CH1, | ||
| 39 | GPIOTE_CH2, | ||
| 40 | GPIOTE_CH3, | ||
| 41 | GPIOTE_CH4, | ||
| 42 | GPIOTE_CH5, | ||
| 43 | GPIOTE_CH6, | ||
| 44 | GPIOTE_CH7, | ||
| 45 | |||
| 46 | // PPI | ||
| 47 | PPI_CH0, | ||
| 48 | PPI_CH1, | ||
| 49 | PPI_CH2, | ||
| 50 | PPI_CH3, | ||
| 51 | PPI_CH4, | ||
| 52 | PPI_CH5, | ||
| 53 | PPI_CH6, | ||
| 54 | PPI_CH7, | ||
| 55 | PPI_CH8, | ||
| 56 | PPI_CH9, | ||
| 57 | PPI_CH10, | ||
| 58 | PPI_CH11, | ||
| 59 | PPI_CH12, | ||
| 60 | PPI_CH13, | ||
| 61 | PPI_CH14, | ||
| 62 | PPI_CH15, | ||
| 63 | PPI_CH16, | ||
| 64 | PPI_CH17, | ||
| 65 | PPI_CH18, | ||
| 66 | PPI_CH19, | ||
| 67 | PPI_CH20, | ||
| 68 | PPI_CH21, | ||
| 69 | PPI_CH22, | ||
| 70 | PPI_CH23, | ||
| 71 | PPI_CH24, | ||
| 72 | PPI_CH25, | ||
| 73 | PPI_CH26, | ||
| 74 | PPI_CH27, | ||
| 75 | PPI_CH28, | ||
| 76 | PPI_CH29, | ||
| 77 | PPI_CH30, | ||
| 78 | PPI_CH31, | ||
| 79 | |||
| 80 | PPI_GROUP0, | ||
| 81 | PPI_GROUP1, | ||
| 82 | PPI_GROUP2, | ||
| 83 | PPI_GROUP3, | ||
| 84 | PPI_GROUP4, | ||
| 85 | PPI_GROUP5, | ||
| 86 | |||
| 87 | // GPIO port 0 | ||
| 88 | P0_00, | ||
| 89 | P0_01, | ||
| 90 | P0_02, | ||
| 91 | P0_03, | ||
| 92 | P0_04, | ||
| 93 | P0_05, | ||
| 94 | P0_06, | ||
| 95 | P0_07, | ||
| 96 | P0_08, | ||
| 97 | P0_09, | ||
| 98 | P0_10, | ||
| 99 | P0_11, | ||
| 100 | P0_12, | ||
| 101 | P0_13, | ||
| 102 | P0_14, | ||
| 103 | P0_15, | ||
| 104 | P0_16, | ||
| 105 | P0_17, | ||
| 106 | P0_18, | ||
| 107 | P0_19, | ||
| 108 | P0_20, | ||
| 109 | P0_21, | ||
| 110 | P0_22, | ||
| 111 | P0_23, | ||
| 112 | P0_24, | ||
| 113 | P0_25, | ||
| 114 | P0_26, | ||
| 115 | P0_27, | ||
| 116 | P0_28, | ||
| 117 | P0_29, | ||
| 118 | P0_30, | ||
| 119 | P0_31, | ||
| 120 | } | ||
| 121 | |||
| 122 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | ||
| 123 | |||
| 124 | impl_spim!(TWISPI0, SPIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 125 | impl_spim!(TWISPI1, SPIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 126 | impl_spim!(SPI2, SPIM2, SPIM2_SPIS2_SPI2); | ||
| 127 | |||
| 128 | impl_twim!(TWISPI0, TWIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 129 | impl_twim!(TWISPI1, TWIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 130 | |||
| 131 | impl_pwm!(PWM0, PWM0, PWM0); | ||
| 132 | impl_pwm!(PWM1, PWM1, PWM1); | ||
| 133 | impl_pwm!(PWM2, PWM2, PWM2); | ||
| 134 | |||
| 135 | impl_timer!(TIMER0, TIMER0, TIMER0); | ||
| 136 | impl_timer!(TIMER1, TIMER1, TIMER1); | ||
| 137 | impl_timer!(TIMER2, TIMER2, TIMER2); | ||
| 138 | impl_timer!(TIMER3, TIMER3, TIMER3, extended); | ||
| 139 | impl_timer!(TIMER4, TIMER4, TIMER4, extended); | ||
| 140 | |||
| 141 | impl_pin!(P0_00, 0, 0); | ||
| 142 | impl_pin!(P0_01, 0, 1); | ||
| 143 | impl_pin!(P0_02, 0, 2); | ||
| 144 | impl_pin!(P0_03, 0, 3); | ||
| 145 | impl_pin!(P0_04, 0, 4); | ||
| 146 | impl_pin!(P0_05, 0, 5); | ||
| 147 | impl_pin!(P0_06, 0, 6); | ||
| 148 | impl_pin!(P0_07, 0, 7); | ||
| 149 | impl_pin!(P0_08, 0, 8); | ||
| 150 | impl_pin!(P0_09, 0, 9); | ||
| 151 | impl_pin!(P0_10, 0, 10); | ||
| 152 | impl_pin!(P0_11, 0, 11); | ||
| 153 | impl_pin!(P0_12, 0, 12); | ||
| 154 | impl_pin!(P0_13, 0, 13); | ||
| 155 | impl_pin!(P0_14, 0, 14); | ||
| 156 | impl_pin!(P0_15, 0, 15); | ||
| 157 | impl_pin!(P0_16, 0, 16); | ||
| 158 | impl_pin!(P0_17, 0, 17); | ||
| 159 | impl_pin!(P0_18, 0, 18); | ||
| 160 | impl_pin!(P0_19, 0, 19); | ||
| 161 | impl_pin!(P0_20, 0, 20); | ||
| 162 | impl_pin!(P0_21, 0, 21); | ||
| 163 | impl_pin!(P0_22, 0, 22); | ||
| 164 | impl_pin!(P0_23, 0, 23); | ||
| 165 | impl_pin!(P0_24, 0, 24); | ||
| 166 | impl_pin!(P0_25, 0, 25); | ||
| 167 | impl_pin!(P0_26, 0, 26); | ||
| 168 | impl_pin!(P0_27, 0, 27); | ||
| 169 | impl_pin!(P0_28, 0, 28); | ||
| 170 | impl_pin!(P0_29, 0, 29); | ||
| 171 | impl_pin!(P0_30, 0, 30); | ||
| 172 | impl_pin!(P0_31, 0, 31); | ||
| 173 | |||
| 174 | pub mod irqs { | ||
| 175 | use embassy_macros::interrupt_declare as declare; | ||
| 176 | declare!(POWER_CLOCK); | ||
| 177 | declare!(RADIO); | ||
| 178 | declare!(UARTE0_UART0); | ||
| 179 | declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 180 | declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 181 | declare!(NFCT); | ||
| 182 | declare!(GPIOTE); | ||
| 183 | declare!(SAADC); | ||
| 184 | declare!(TIMER0); | ||
| 185 | declare!(TIMER1); | ||
| 186 | declare!(TIMER2); | ||
| 187 | declare!(RTC0); | ||
| 188 | declare!(TEMP); | ||
| 189 | declare!(RNG); | ||
| 190 | declare!(ECB); | ||
| 191 | declare!(CCM_AAR); | ||
| 192 | declare!(WDT); | ||
| 193 | declare!(RTC1); | ||
| 194 | declare!(QDEC); | ||
| 195 | declare!(COMP_LPCOMP); | ||
| 196 | declare!(SWI0_EGU0); | ||
| 197 | declare!(SWI1_EGU1); | ||
| 198 | declare!(SWI2_EGU2); | ||
| 199 | declare!(SWI3_EGU3); | ||
| 200 | declare!(SWI4_EGU4); | ||
| 201 | declare!(SWI5_EGU5); | ||
| 202 | declare!(TIMER3); | ||
| 203 | declare!(TIMER4); | ||
| 204 | declare!(PWM0); | ||
| 205 | declare!(PDM); | ||
| 206 | declare!(MWU); | ||
| 207 | declare!(PWM1); | ||
| 208 | declare!(PWM2); | ||
| 209 | declare!(SPIM2_SPIS2_SPI2); | ||
| 210 | declare!(RTC2); | ||
| 211 | declare!(I2S); | ||
| 212 | declare!(FPU); | ||
| 213 | } | ||
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs new file mode 100644 index 000000000..30b0ab007 --- /dev/null +++ b/embassy-nrf/src/chips/nrf52833.rs | |||
| @@ -0,0 +1,257 @@ | |||
| 1 | pub use nrf52833_pac as pac; | ||
| 2 | |||
| 3 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; | ||
| 4 | pub const FORCE_COPY_BUFFER_SIZE: usize = 512; | ||
| 5 | |||
| 6 | embassy_extras::peripherals! { | ||
| 7 | // RTC | ||
| 8 | RTC0, | ||
| 9 | RTC1, | ||
| 10 | RTC2, | ||
| 11 | |||
| 12 | // UARTE | ||
| 13 | UARTE0, | ||
| 14 | UARTE1, | ||
| 15 | |||
| 16 | // SPI/TWI | ||
| 17 | TWISPI0, | ||
| 18 | TWISPI1, | ||
| 19 | SPI2, | ||
| 20 | SPI3, | ||
| 21 | |||
| 22 | // SAADC | ||
| 23 | SAADC, | ||
| 24 | |||
| 25 | // PWM | ||
| 26 | PWM0, | ||
| 27 | PWM1, | ||
| 28 | PWM2, | ||
| 29 | PWM3, | ||
| 30 | |||
| 31 | // TIMER | ||
| 32 | TIMER0, | ||
| 33 | TIMER1, | ||
| 34 | TIMER2, | ||
| 35 | TIMER3, | ||
| 36 | TIMER4, | ||
| 37 | |||
| 38 | // GPIOTE | ||
| 39 | GPIOTE_CH0, | ||
| 40 | GPIOTE_CH1, | ||
| 41 | GPIOTE_CH2, | ||
| 42 | GPIOTE_CH3, | ||
| 43 | GPIOTE_CH4, | ||
| 44 | GPIOTE_CH5, | ||
| 45 | GPIOTE_CH6, | ||
| 46 | GPIOTE_CH7, | ||
| 47 | |||
| 48 | // PPI | ||
| 49 | PPI_CH0, | ||
| 50 | PPI_CH1, | ||
| 51 | PPI_CH2, | ||
| 52 | PPI_CH3, | ||
| 53 | PPI_CH4, | ||
| 54 | PPI_CH5, | ||
| 55 | PPI_CH6, | ||
| 56 | PPI_CH7, | ||
| 57 | PPI_CH8, | ||
| 58 | PPI_CH9, | ||
| 59 | PPI_CH10, | ||
| 60 | PPI_CH11, | ||
| 61 | PPI_CH12, | ||
| 62 | PPI_CH13, | ||
| 63 | PPI_CH14, | ||
| 64 | PPI_CH15, | ||
| 65 | PPI_CH16, | ||
| 66 | PPI_CH17, | ||
| 67 | PPI_CH18, | ||
| 68 | PPI_CH19, | ||
| 69 | PPI_CH20, | ||
| 70 | PPI_CH21, | ||
| 71 | PPI_CH22, | ||
| 72 | PPI_CH23, | ||
| 73 | PPI_CH24, | ||
| 74 | PPI_CH25, | ||
| 75 | PPI_CH26, | ||
| 76 | PPI_CH27, | ||
| 77 | PPI_CH28, | ||
| 78 | PPI_CH29, | ||
| 79 | PPI_CH30, | ||
| 80 | PPI_CH31, | ||
| 81 | |||
| 82 | PPI_GROUP0, | ||
| 83 | PPI_GROUP1, | ||
| 84 | PPI_GROUP2, | ||
| 85 | PPI_GROUP3, | ||
| 86 | PPI_GROUP4, | ||
| 87 | PPI_GROUP5, | ||
| 88 | |||
| 89 | // GPIO port 0 | ||
| 90 | P0_00, | ||
| 91 | P0_01, | ||
| 92 | P0_02, | ||
| 93 | P0_03, | ||
| 94 | P0_04, | ||
| 95 | P0_05, | ||
| 96 | P0_06, | ||
| 97 | P0_07, | ||
| 98 | P0_08, | ||
| 99 | P0_09, | ||
| 100 | P0_10, | ||
| 101 | P0_11, | ||
| 102 | P0_12, | ||
| 103 | P0_13, | ||
| 104 | P0_14, | ||
| 105 | P0_15, | ||
| 106 | P0_16, | ||
| 107 | P0_17, | ||
| 108 | P0_18, | ||
| 109 | P0_19, | ||
| 110 | P0_20, | ||
| 111 | P0_21, | ||
| 112 | P0_22, | ||
| 113 | P0_23, | ||
| 114 | P0_24, | ||
| 115 | P0_25, | ||
| 116 | P0_26, | ||
| 117 | P0_27, | ||
| 118 | P0_28, | ||
| 119 | P0_29, | ||
| 120 | P0_30, | ||
| 121 | P0_31, | ||
| 122 | |||
| 123 | // GPIO port 1 | ||
| 124 | P1_00, | ||
| 125 | P1_01, | ||
| 126 | P1_02, | ||
| 127 | P1_03, | ||
| 128 | P1_04, | ||
| 129 | P1_05, | ||
| 130 | P1_06, | ||
| 131 | P1_07, | ||
| 132 | P1_08, | ||
| 133 | P1_09, | ||
| 134 | P1_10, | ||
| 135 | P1_11, | ||
| 136 | P1_12, | ||
| 137 | P1_13, | ||
| 138 | P1_14, | ||
| 139 | P1_15, | ||
| 140 | } | ||
| 141 | |||
| 142 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | ||
| 143 | impl_uarte!(UARTE1, UARTE1, UARTE1); | ||
| 144 | |||
| 145 | impl_spim!(TWISPI0, SPIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 146 | impl_spim!(TWISPI1, SPIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 147 | impl_spim!(SPI2, SPIM2, SPIM2_SPIS2_SPI2); | ||
| 148 | impl_spim!(SPI3, SPIM3, SPIM3); | ||
| 149 | |||
| 150 | impl_twim!(TWISPI0, TWIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 151 | impl_twim!(TWISPI1, TWIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 152 | |||
| 153 | impl_pwm!(PWM0, PWM0, PWM0); | ||
| 154 | impl_pwm!(PWM1, PWM1, PWM1); | ||
| 155 | impl_pwm!(PWM2, PWM2, PWM2); | ||
| 156 | impl_pwm!(PWM3, PWM3, PWM3); | ||
| 157 | |||
| 158 | impl_timer!(TIMER0, TIMER0, TIMER0); | ||
| 159 | impl_timer!(TIMER1, TIMER1, TIMER1); | ||
| 160 | impl_timer!(TIMER2, TIMER2, TIMER2); | ||
| 161 | impl_timer!(TIMER3, TIMER3, TIMER3, extended); | ||
| 162 | impl_timer!(TIMER4, TIMER4, TIMER4, extended); | ||
| 163 | |||
| 164 | impl_pin!(P0_00, 0, 0); | ||
| 165 | impl_pin!(P0_01, 0, 1); | ||
| 166 | impl_pin!(P0_02, 0, 2); | ||
| 167 | impl_pin!(P0_03, 0, 3); | ||
| 168 | impl_pin!(P0_04, 0, 4); | ||
| 169 | impl_pin!(P0_05, 0, 5); | ||
| 170 | impl_pin!(P0_06, 0, 6); | ||
| 171 | impl_pin!(P0_07, 0, 7); | ||
| 172 | impl_pin!(P0_08, 0, 8); | ||
| 173 | impl_pin!(P0_09, 0, 9); | ||
| 174 | impl_pin!(P0_10, 0, 10); | ||
| 175 | impl_pin!(P0_11, 0, 11); | ||
| 176 | impl_pin!(P0_12, 0, 12); | ||
| 177 | impl_pin!(P0_13, 0, 13); | ||
| 178 | impl_pin!(P0_14, 0, 14); | ||
| 179 | impl_pin!(P0_15, 0, 15); | ||
| 180 | impl_pin!(P0_16, 0, 16); | ||
| 181 | impl_pin!(P0_17, 0, 17); | ||
| 182 | impl_pin!(P0_18, 0, 18); | ||
| 183 | impl_pin!(P0_19, 0, 19); | ||
| 184 | impl_pin!(P0_20, 0, 20); | ||
| 185 | impl_pin!(P0_21, 0, 21); | ||
| 186 | impl_pin!(P0_22, 0, 22); | ||
| 187 | impl_pin!(P0_23, 0, 23); | ||
| 188 | impl_pin!(P0_24, 0, 24); | ||
| 189 | impl_pin!(P0_25, 0, 25); | ||
| 190 | impl_pin!(P0_26, 0, 26); | ||
| 191 | impl_pin!(P0_27, 0, 27); | ||
| 192 | impl_pin!(P0_28, 0, 28); | ||
| 193 | impl_pin!(P0_29, 0, 29); | ||
| 194 | impl_pin!(P0_30, 0, 30); | ||
| 195 | impl_pin!(P0_31, 0, 31); | ||
| 196 | |||
| 197 | impl_pin!(P1_00, 1, 0); | ||
| 198 | impl_pin!(P1_01, 1, 1); | ||
| 199 | impl_pin!(P1_02, 1, 2); | ||
| 200 | impl_pin!(P1_03, 1, 3); | ||
| 201 | impl_pin!(P1_04, 1, 4); | ||
| 202 | impl_pin!(P1_05, 1, 5); | ||
| 203 | impl_pin!(P1_06, 1, 6); | ||
| 204 | impl_pin!(P1_07, 1, 7); | ||
| 205 | impl_pin!(P1_08, 1, 8); | ||
| 206 | impl_pin!(P1_09, 1, 9); | ||
| 207 | impl_pin!(P1_10, 1, 10); | ||
| 208 | impl_pin!(P1_11, 1, 11); | ||
| 209 | impl_pin!(P1_12, 1, 12); | ||
| 210 | impl_pin!(P1_13, 1, 13); | ||
| 211 | impl_pin!(P1_14, 1, 14); | ||
| 212 | impl_pin!(P1_15, 1, 15); | ||
| 213 | |||
| 214 | pub mod irqs { | ||
| 215 | use embassy_macros::interrupt_declare as declare; | ||
| 216 | declare!(POWER_CLOCK); | ||
| 217 | declare!(RADIO); | ||
| 218 | declare!(UARTE0_UART0); | ||
| 219 | declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 220 | declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 221 | declare!(NFCT); | ||
| 222 | declare!(GPIOTE); | ||
| 223 | declare!(SAADC); | ||
| 224 | declare!(TIMER0); | ||
| 225 | declare!(TIMER1); | ||
| 226 | declare!(TIMER2); | ||
| 227 | declare!(RTC0); | ||
| 228 | declare!(TEMP); | ||
| 229 | declare!(RNG); | ||
| 230 | declare!(ECB); | ||
| 231 | declare!(CCM_AAR); | ||
| 232 | declare!(WDT); | ||
| 233 | declare!(RTC1); | ||
| 234 | declare!(QDEC); | ||
| 235 | declare!(COMP_LPCOMP); | ||
| 236 | declare!(SWI0_EGU0); | ||
| 237 | declare!(SWI1_EGU1); | ||
| 238 | declare!(SWI2_EGU2); | ||
| 239 | declare!(SWI3_EGU3); | ||
| 240 | declare!(SWI4_EGU4); | ||
| 241 | declare!(SWI5_EGU5); | ||
| 242 | declare!(TIMER3); | ||
| 243 | declare!(TIMER4); | ||
| 244 | declare!(PWM0); | ||
| 245 | declare!(PDM); | ||
| 246 | declare!(MWU); | ||
| 247 | declare!(PWM1); | ||
| 248 | declare!(PWM2); | ||
| 249 | declare!(SPIM2_SPIS2_SPI2); | ||
| 250 | declare!(RTC2); | ||
| 251 | declare!(I2S); | ||
| 252 | declare!(FPU); | ||
| 253 | declare!(USBD); | ||
| 254 | declare!(UARTE1); | ||
| 255 | declare!(PWM3); | ||
| 256 | declare!(SPIM3); | ||
| 257 | } | ||
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs new file mode 100644 index 000000000..0b6c3f68e --- /dev/null +++ b/embassy-nrf/src/chips/nrf52840.rs | |||
| @@ -0,0 +1,264 @@ | |||
| 1 | pub use nrf52840_pac as pac; | ||
| 2 | |||
| 3 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; | ||
| 4 | pub const FORCE_COPY_BUFFER_SIZE: usize = 512; | ||
| 5 | |||
| 6 | embassy_extras::peripherals! { | ||
| 7 | // RTC | ||
| 8 | RTC0, | ||
| 9 | RTC1, | ||
| 10 | RTC2, | ||
| 11 | |||
| 12 | // QSPI | ||
| 13 | QSPI, | ||
| 14 | |||
| 15 | // UARTE | ||
| 16 | UARTE0, | ||
| 17 | UARTE1, | ||
| 18 | |||
| 19 | // SPI/TWI | ||
| 20 | TWISPI0, | ||
| 21 | TWISPI1, | ||
| 22 | SPI2, | ||
| 23 | SPI3, | ||
| 24 | |||
| 25 | // SAADC | ||
| 26 | SAADC, | ||
| 27 | |||
| 28 | // PWM | ||
| 29 | PWM0, | ||
| 30 | PWM1, | ||
| 31 | PWM2, | ||
| 32 | PWM3, | ||
| 33 | |||
| 34 | // TIMER | ||
| 35 | TIMER0, | ||
| 36 | TIMER1, | ||
| 37 | TIMER2, | ||
| 38 | TIMER3, | ||
| 39 | TIMER4, | ||
| 40 | |||
| 41 | // GPIOTE | ||
| 42 | GPIOTE_CH0, | ||
| 43 | GPIOTE_CH1, | ||
| 44 | GPIOTE_CH2, | ||
| 45 | GPIOTE_CH3, | ||
| 46 | GPIOTE_CH4, | ||
| 47 | GPIOTE_CH5, | ||
| 48 | GPIOTE_CH6, | ||
| 49 | GPIOTE_CH7, | ||
| 50 | |||
| 51 | // PPI | ||
| 52 | PPI_CH0, | ||
| 53 | PPI_CH1, | ||
| 54 | PPI_CH2, | ||
| 55 | PPI_CH3, | ||
| 56 | PPI_CH4, | ||
| 57 | PPI_CH5, | ||
| 58 | PPI_CH6, | ||
| 59 | PPI_CH7, | ||
| 60 | PPI_CH8, | ||
| 61 | PPI_CH9, | ||
| 62 | PPI_CH10, | ||
| 63 | PPI_CH11, | ||
| 64 | PPI_CH12, | ||
| 65 | PPI_CH13, | ||
| 66 | PPI_CH14, | ||
| 67 | PPI_CH15, | ||
| 68 | PPI_CH16, | ||
| 69 | PPI_CH17, | ||
| 70 | PPI_CH18, | ||
| 71 | PPI_CH19, | ||
| 72 | PPI_CH20, | ||
| 73 | PPI_CH21, | ||
| 74 | PPI_CH22, | ||
| 75 | PPI_CH23, | ||
| 76 | PPI_CH24, | ||
| 77 | PPI_CH25, | ||
| 78 | PPI_CH26, | ||
| 79 | PPI_CH27, | ||
| 80 | PPI_CH28, | ||
| 81 | PPI_CH29, | ||
| 82 | PPI_CH30, | ||
| 83 | PPI_CH31, | ||
| 84 | |||
| 85 | PPI_GROUP0, | ||
| 86 | PPI_GROUP1, | ||
| 87 | PPI_GROUP2, | ||
| 88 | PPI_GROUP3, | ||
| 89 | PPI_GROUP4, | ||
| 90 | PPI_GROUP5, | ||
| 91 | |||
| 92 | // GPIO port 0 | ||
| 93 | P0_00, | ||
| 94 | P0_01, | ||
| 95 | P0_02, | ||
| 96 | P0_03, | ||
| 97 | P0_04, | ||
| 98 | P0_05, | ||
| 99 | P0_06, | ||
| 100 | P0_07, | ||
| 101 | P0_08, | ||
| 102 | P0_09, | ||
| 103 | P0_10, | ||
| 104 | P0_11, | ||
| 105 | P0_12, | ||
| 106 | P0_13, | ||
| 107 | P0_14, | ||
| 108 | P0_15, | ||
| 109 | P0_16, | ||
| 110 | P0_17, | ||
| 111 | P0_18, | ||
| 112 | P0_19, | ||
| 113 | P0_20, | ||
| 114 | P0_21, | ||
| 115 | P0_22, | ||
| 116 | P0_23, | ||
| 117 | P0_24, | ||
| 118 | P0_25, | ||
| 119 | P0_26, | ||
| 120 | P0_27, | ||
| 121 | P0_28, | ||
| 122 | P0_29, | ||
| 123 | P0_30, | ||
| 124 | P0_31, | ||
| 125 | |||
| 126 | // GPIO port 1 | ||
| 127 | P1_00, | ||
| 128 | P1_01, | ||
| 129 | P1_02, | ||
| 130 | P1_03, | ||
| 131 | P1_04, | ||
| 132 | P1_05, | ||
| 133 | P1_06, | ||
| 134 | P1_07, | ||
| 135 | P1_08, | ||
| 136 | P1_09, | ||
| 137 | P1_10, | ||
| 138 | P1_11, | ||
| 139 | P1_12, | ||
| 140 | P1_13, | ||
| 141 | P1_14, | ||
| 142 | P1_15, | ||
| 143 | } | ||
| 144 | |||
| 145 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | ||
| 146 | impl_uarte!(UARTE1, UARTE1, UARTE1); | ||
| 147 | |||
| 148 | impl_spim!(TWISPI0, SPIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 149 | impl_spim!(TWISPI1, SPIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 150 | impl_spim!(SPI2, SPIM2, SPIM2_SPIS2_SPI2); | ||
| 151 | impl_spim!(SPI3, SPIM3, SPIM3); | ||
| 152 | |||
| 153 | impl_twim!(TWISPI0, TWIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 154 | impl_twim!(TWISPI1, TWIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 155 | |||
| 156 | impl_pwm!(PWM0, PWM0, PWM0); | ||
| 157 | impl_pwm!(PWM1, PWM1, PWM1); | ||
| 158 | impl_pwm!(PWM2, PWM2, PWM2); | ||
| 159 | impl_pwm!(PWM3, PWM3, PWM3); | ||
| 160 | |||
| 161 | impl_timer!(TIMER0, TIMER0, TIMER0); | ||
| 162 | impl_timer!(TIMER1, TIMER1, TIMER1); | ||
| 163 | impl_timer!(TIMER2, TIMER2, TIMER2); | ||
| 164 | impl_timer!(TIMER3, TIMER3, TIMER3, extended); | ||
| 165 | impl_timer!(TIMER4, TIMER4, TIMER4, extended); | ||
| 166 | |||
| 167 | impl_qspi!(QSPI, QSPI, QSPI); | ||
| 168 | |||
| 169 | impl_pin!(P0_00, 0, 0); | ||
| 170 | impl_pin!(P0_01, 0, 1); | ||
| 171 | impl_pin!(P0_02, 0, 2); | ||
| 172 | impl_pin!(P0_03, 0, 3); | ||
| 173 | impl_pin!(P0_04, 0, 4); | ||
| 174 | impl_pin!(P0_05, 0, 5); | ||
| 175 | impl_pin!(P0_06, 0, 6); | ||
| 176 | impl_pin!(P0_07, 0, 7); | ||
| 177 | impl_pin!(P0_08, 0, 8); | ||
| 178 | impl_pin!(P0_09, 0, 9); | ||
| 179 | impl_pin!(P0_10, 0, 10); | ||
| 180 | impl_pin!(P0_11, 0, 11); | ||
| 181 | impl_pin!(P0_12, 0, 12); | ||
| 182 | impl_pin!(P0_13, 0, 13); | ||
| 183 | impl_pin!(P0_14, 0, 14); | ||
| 184 | impl_pin!(P0_15, 0, 15); | ||
| 185 | impl_pin!(P0_16, 0, 16); | ||
| 186 | impl_pin!(P0_17, 0, 17); | ||
| 187 | impl_pin!(P0_18, 0, 18); | ||
| 188 | impl_pin!(P0_19, 0, 19); | ||
| 189 | impl_pin!(P0_20, 0, 20); | ||
| 190 | impl_pin!(P0_21, 0, 21); | ||
| 191 | impl_pin!(P0_22, 0, 22); | ||
| 192 | impl_pin!(P0_23, 0, 23); | ||
| 193 | impl_pin!(P0_24, 0, 24); | ||
| 194 | impl_pin!(P0_25, 0, 25); | ||
| 195 | impl_pin!(P0_26, 0, 26); | ||
| 196 | impl_pin!(P0_27, 0, 27); | ||
| 197 | impl_pin!(P0_28, 0, 28); | ||
| 198 | impl_pin!(P0_29, 0, 29); | ||
| 199 | impl_pin!(P0_30, 0, 30); | ||
| 200 | impl_pin!(P0_31, 0, 31); | ||
| 201 | |||
| 202 | impl_pin!(P1_00, 1, 0); | ||
| 203 | impl_pin!(P1_01, 1, 1); | ||
| 204 | impl_pin!(P1_02, 1, 2); | ||
| 205 | impl_pin!(P1_03, 1, 3); | ||
| 206 | impl_pin!(P1_04, 1, 4); | ||
| 207 | impl_pin!(P1_05, 1, 5); | ||
| 208 | impl_pin!(P1_06, 1, 6); | ||
| 209 | impl_pin!(P1_07, 1, 7); | ||
| 210 | impl_pin!(P1_08, 1, 8); | ||
| 211 | impl_pin!(P1_09, 1, 9); | ||
| 212 | impl_pin!(P1_10, 1, 10); | ||
| 213 | impl_pin!(P1_11, 1, 11); | ||
| 214 | impl_pin!(P1_12, 1, 12); | ||
| 215 | impl_pin!(P1_13, 1, 13); | ||
| 216 | impl_pin!(P1_14, 1, 14); | ||
| 217 | impl_pin!(P1_15, 1, 15); | ||
| 218 | |||
| 219 | pub mod irqs { | ||
| 220 | use embassy_macros::interrupt_declare as declare; | ||
| 221 | declare!(POWER_CLOCK); | ||
| 222 | declare!(RADIO); | ||
| 223 | declare!(UARTE0_UART0); | ||
| 224 | declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 225 | declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 226 | declare!(NFCT); | ||
| 227 | declare!(GPIOTE); | ||
| 228 | declare!(SAADC); | ||
| 229 | declare!(TIMER0); | ||
| 230 | declare!(TIMER1); | ||
| 231 | declare!(TIMER2); | ||
| 232 | declare!(RTC0); | ||
| 233 | declare!(TEMP); | ||
| 234 | declare!(RNG); | ||
| 235 | declare!(ECB); | ||
| 236 | declare!(CCM_AAR); | ||
| 237 | declare!(WDT); | ||
| 238 | declare!(RTC1); | ||
| 239 | declare!(QDEC); | ||
| 240 | declare!(COMP_LPCOMP); | ||
| 241 | declare!(SWI0_EGU0); | ||
| 242 | declare!(SWI1_EGU1); | ||
| 243 | declare!(SWI2_EGU2); | ||
| 244 | declare!(SWI3_EGU3); | ||
| 245 | declare!(SWI4_EGU4); | ||
| 246 | declare!(SWI5_EGU5); | ||
| 247 | declare!(TIMER3); | ||
| 248 | declare!(TIMER4); | ||
| 249 | declare!(PWM0); | ||
| 250 | declare!(PDM); | ||
| 251 | declare!(MWU); | ||
| 252 | declare!(PWM1); | ||
| 253 | declare!(PWM2); | ||
| 254 | declare!(SPIM2_SPIS2_SPI2); | ||
| 255 | declare!(RTC2); | ||
| 256 | declare!(I2S); | ||
| 257 | declare!(FPU); | ||
| 258 | declare!(USBD); | ||
| 259 | declare!(UARTE1); | ||
| 260 | declare!(QSPI); | ||
| 261 | declare!(CRYPTOCELL); | ||
| 262 | declare!(PWM3); | ||
| 263 | declare!(SPIM3); | ||
| 264 | } | ||
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index 14ac61822..fed1ae049 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | use core::convert::Infallible; | 3 | use core::convert::Infallible; |
| 2 | use core::hint::unreachable_unchecked; | 4 | use core::hint::unreachable_unchecked; |
| 3 | use core::marker::PhantomData; | 5 | use core::marker::PhantomData; |
| @@ -18,7 +20,7 @@ pub enum Port { | |||
| 18 | Port0, | 20 | Port0, |
| 19 | 21 | ||
| 20 | /// Port 1, only available on some nRF52 MCUs. | 22 | /// Port 1, only available on some nRF52 MCUs. |
| 21 | #[cfg(any(feature = "52833", feature = "52840"))] | 23 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 22 | Port1, | 24 | Port1, |
| 23 | } | 25 | } |
| 24 | 26 | ||
| @@ -281,12 +283,12 @@ pub(crate) mod sealed { | |||
| 281 | 283 | ||
| 282 | #[inline] | 284 | #[inline] |
| 283 | fn _pin(&self) -> u8 { | 285 | fn _pin(&self) -> u8 { |
| 284 | #[cfg(any(feature = "52833", feature = "52840"))] | 286 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 285 | { | 287 | { |
| 286 | self.pin_port() % 32 | 288 | self.pin_port() % 32 |
| 287 | } | 289 | } |
| 288 | 290 | ||
| 289 | #[cfg(not(any(feature = "52833", feature = "52840")))] | 291 | #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] |
| 290 | { | 292 | { |
| 291 | self.pin_port() | 293 | self.pin_port() |
| 292 | } | 294 | } |
| @@ -297,7 +299,7 @@ pub(crate) mod sealed { | |||
| 297 | unsafe { | 299 | unsafe { |
| 298 | match self.pin_port() / 32 { | 300 | match self.pin_port() / 32 { |
| 299 | 0 => &*pac::P0::ptr(), | 301 | 0 => &*pac::P0::ptr(), |
| 300 | #[cfg(any(feature = "52833", feature = "52840"))] | 302 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 301 | 1 => &*pac::P1::ptr(), | 303 | 1 => &*pac::P1::ptr(), |
| 302 | _ => unreachable_unchecked(), | 304 | _ => unreachable_unchecked(), |
| 303 | } | 305 | } |
| @@ -329,7 +331,7 @@ pub(crate) mod sealed { | |||
| 329 | pub trait OptionalPin {} | 331 | pub trait OptionalPin {} |
| 330 | } | 332 | } |
| 331 | 333 | ||
| 332 | pub trait Pin: sealed::Pin + Sized { | 334 | pub trait Pin: Unborrow<Target = Self> + sealed::Pin + Sized { |
| 333 | /// Number of the pin within the port (0..31) | 335 | /// Number of the pin within the port (0..31) |
| 334 | #[inline] | 336 | #[inline] |
| 335 | fn pin(&self) -> u8 { | 337 | fn pin(&self) -> u8 { |
| @@ -341,7 +343,7 @@ pub trait Pin: sealed::Pin + Sized { | |||
| 341 | fn port(&self) -> Port { | 343 | fn port(&self) -> Port { |
| 342 | match self.pin_port() / 32 { | 344 | match self.pin_port() / 32 { |
| 343 | 0 => Port::Port0, | 345 | 0 => Port::Port0, |
| 344 | #[cfg(any(feature = "52833", feature = "52840"))] | 346 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 345 | 1 => Port::Port1, | 347 | 1 => Port::Port1, |
| 346 | _ => unsafe { unreachable_unchecked() }, | 348 | _ => unsafe { unreachable_unchecked() }, |
| 347 | } | 349 | } |
| @@ -433,7 +435,7 @@ fn init_output<T: Pin>(pin: &T, drive: OutputDrive) { | |||
| 433 | 435 | ||
| 434 | // ==================== | 436 | // ==================== |
| 435 | 437 | ||
| 436 | pub trait OptionalPin: sealed::OptionalPin + Sized { | 438 | pub trait OptionalPin: Unborrow<Target = Self> + sealed::OptionalPin + Sized { |
| 437 | type Pin: Pin; | 439 | type Pin: Pin; |
| 438 | fn pin(&self) -> Option<&Self::Pin>; | 440 | fn pin(&self) -> Option<&Self::Pin>; |
| 439 | fn pin_mut(&mut self) -> Option<&mut Self::Pin>; | 441 | fn pin_mut(&mut self) -> Option<&mut Self::Pin>; |
| @@ -488,8 +490,8 @@ impl OptionalPin for NoPin { | |||
| 488 | 490 | ||
| 489 | macro_rules! impl_pin { | 491 | macro_rules! impl_pin { |
| 490 | ($type:ident, $port_num:expr, $pin_num:expr) => { | 492 | ($type:ident, $port_num:expr, $pin_num:expr) => { |
| 491 | impl Pin for peripherals::$type {} | 493 | impl crate::gpio::Pin for peripherals::$type {} |
| 492 | impl sealed::Pin for peripherals::$type { | 494 | impl crate::gpio::sealed::Pin for peripherals::$type { |
| 493 | #[inline] | 495 | #[inline] |
| 494 | fn pin_port(&self) -> u8 { | 496 | fn pin_port(&self) -> u8 { |
| 495 | $port_num * 32 + $pin_num | 497 | $port_num * 32 + $pin_num |
| @@ -497,57 +499,3 @@ macro_rules! impl_pin { | |||
| 497 | } | 499 | } |
| 498 | }; | 500 | }; |
| 499 | } | 501 | } |
| 500 | |||
| 501 | impl_pin!(P0_00, 0, 0); | ||
| 502 | impl_pin!(P0_01, 0, 1); | ||
| 503 | impl_pin!(P0_02, 0, 2); | ||
| 504 | impl_pin!(P0_03, 0, 3); | ||
| 505 | impl_pin!(P0_04, 0, 4); | ||
| 506 | impl_pin!(P0_05, 0, 5); | ||
| 507 | impl_pin!(P0_06, 0, 6); | ||
| 508 | impl_pin!(P0_07, 0, 7); | ||
| 509 | impl_pin!(P0_08, 0, 8); | ||
| 510 | impl_pin!(P0_09, 0, 9); | ||
| 511 | impl_pin!(P0_10, 0, 10); | ||
| 512 | impl_pin!(P0_11, 0, 11); | ||
| 513 | impl_pin!(P0_12, 0, 12); | ||
| 514 | impl_pin!(P0_13, 0, 13); | ||
| 515 | impl_pin!(P0_14, 0, 14); | ||
| 516 | impl_pin!(P0_15, 0, 15); | ||
| 517 | impl_pin!(P0_16, 0, 16); | ||
| 518 | impl_pin!(P0_17, 0, 17); | ||
| 519 | impl_pin!(P0_18, 0, 18); | ||
| 520 | impl_pin!(P0_19, 0, 19); | ||
| 521 | impl_pin!(P0_20, 0, 20); | ||
| 522 | impl_pin!(P0_21, 0, 21); | ||
| 523 | impl_pin!(P0_22, 0, 22); | ||
| 524 | impl_pin!(P0_23, 0, 23); | ||
| 525 | impl_pin!(P0_24, 0, 24); | ||
| 526 | impl_pin!(P0_25, 0, 25); | ||
| 527 | impl_pin!(P0_26, 0, 26); | ||
| 528 | impl_pin!(P0_27, 0, 27); | ||
| 529 | impl_pin!(P0_28, 0, 28); | ||
| 530 | impl_pin!(P0_29, 0, 29); | ||
| 531 | impl_pin!(P0_30, 0, 30); | ||
| 532 | impl_pin!(P0_31, 0, 31); | ||
| 533 | |||
| 534 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 535 | mod _p1 { | ||
| 536 | use super::*; | ||
| 537 | impl_pin!(P1_00, 1, 0); | ||
| 538 | impl_pin!(P1_01, 1, 1); | ||
| 539 | impl_pin!(P1_02, 1, 2); | ||
| 540 | impl_pin!(P1_03, 1, 3); | ||
| 541 | impl_pin!(P1_04, 1, 4); | ||
| 542 | impl_pin!(P1_05, 1, 5); | ||
| 543 | impl_pin!(P1_06, 1, 6); | ||
| 544 | impl_pin!(P1_07, 1, 7); | ||
| 545 | impl_pin!(P1_08, 1, 8); | ||
| 546 | impl_pin!(P1_09, 1, 9); | ||
| 547 | impl_pin!(P1_10, 1, 10); | ||
| 548 | impl_pin!(P1_11, 1, 11); | ||
| 549 | impl_pin!(P1_12, 1, 12); | ||
| 550 | impl_pin!(P1_13, 1, 13); | ||
| 551 | impl_pin!(P1_14, 1, 14); | ||
| 552 | impl_pin!(P1_15, 1, 15); | ||
| 553 | } | ||
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index fbd8c093c..f322c1694 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -2,7 +2,7 @@ use core::convert::Infallible; | |||
| 2 | use core::future::Future; | 2 | use core::future::Future; |
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use core::task::{Context, Poll}; | 4 | use core::task::{Context, Poll}; |
| 5 | use embassy::interrupt::InterruptExt; | 5 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 6 | use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow}; | 6 | use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow}; |
| 7 | use embassy::util::AtomicWaker; | 7 | use embassy::util::AtomicWaker; |
| 8 | use embassy_extras::impl_unborrow; | 8 | use embassy_extras::impl_unborrow; |
| @@ -17,9 +17,9 @@ use crate::{interrupt, peripherals}; | |||
| 17 | 17 | ||
| 18 | pub const CHANNEL_COUNT: usize = 8; | 18 | pub const CHANNEL_COUNT: usize = 8; |
| 19 | 19 | ||
| 20 | #[cfg(any(feature = "52833", feature = "52840"))] | 20 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 21 | pub const PIN_COUNT: usize = 48; | 21 | pub const PIN_COUNT: usize = 48; |
| 22 | #[cfg(not(any(feature = "52833", feature = "52840")))] | 22 | #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] |
| 23 | pub const PIN_COUNT: usize = 32; | 23 | pub const PIN_COUNT: usize = 32; |
| 24 | 24 | ||
| 25 | const NEW_AW: AtomicWaker = AtomicWaker::new(); | 25 | const NEW_AW: AtomicWaker = AtomicWaker::new(); |
| @@ -40,18 +40,10 @@ pub enum OutputChannelPolarity { | |||
| 40 | Toggle, | 40 | Toggle, |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | /// Token indicating GPIOTE has been correctly initialized. | 43 | pub(crate) fn init() { |
| 44 | /// | 44 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 45 | /// This is not an owned singleton, it is Copy. Drivers that make use of GPIOTE require it. | ||
| 46 | #[derive(Clone, Copy)] | ||
| 47 | pub struct Initialized { | ||
| 48 | _private: (), | ||
| 49 | } | ||
| 50 | |||
| 51 | pub fn initialize(_gpiote: peripherals::GPIOTE, irq: interrupt::GPIOTE) -> Initialized { | ||
| 52 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 53 | let ports = unsafe { &[&*pac::P0::ptr(), &*pac::P1::ptr()] }; | 45 | let ports = unsafe { &[&*pac::P0::ptr(), &*pac::P1::ptr()] }; |
| 54 | #[cfg(not(any(feature = "52833", feature = "52840")))] | 46 | #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] |
| 55 | let ports = unsafe { &[&*pac::P0::ptr()] }; | 47 | let ports = unsafe { &[&*pac::P0::ptr()] }; |
| 56 | 48 | ||
| 57 | for &p in ports { | 49 | for &p in ports { |
| @@ -62,17 +54,18 @@ pub fn initialize(_gpiote: peripherals::GPIOTE, irq: interrupt::GPIOTE) -> Initi | |||
| 62 | } | 54 | } |
| 63 | 55 | ||
| 64 | // Enable interrupts | 56 | // Enable interrupts |
| 65 | let g = unsafe { &*pac::GPIOTE::ptr() }; | 57 | |
| 66 | g.events_port.write(|w| w); | 58 | let irq = unsafe { interrupt::GPIOTE::steal() }; |
| 67 | g.intenset.write(|w| w.port().set()); | ||
| 68 | irq.set_handler(on_irq); | ||
| 69 | irq.unpend(); | 59 | irq.unpend(); |
| 70 | irq.enable(); | 60 | irq.enable(); |
| 71 | 61 | ||
| 72 | Initialized { _private: () } | 62 | let g = unsafe { &*pac::GPIOTE::ptr() }; |
| 63 | g.events_port.write(|w| w); | ||
| 64 | g.intenset.write(|w| w.port().set()); | ||
| 73 | } | 65 | } |
| 74 | 66 | ||
| 75 | unsafe fn on_irq(_ctx: *mut ()) { | 67 | #[interrupt] |
| 68 | unsafe fn GPIOTE() { | ||
| 76 | let g = &*pac::GPIOTE::ptr(); | 69 | let g = &*pac::GPIOTE::ptr(); |
| 77 | 70 | ||
| 78 | for i in 0..CHANNEL_COUNT { | 71 | for i in 0..CHANNEL_COUNT { |
| @@ -85,9 +78,9 @@ unsafe fn on_irq(_ctx: *mut ()) { | |||
| 85 | if g.events_port.read().bits() != 0 { | 78 | if g.events_port.read().bits() != 0 { |
| 86 | g.events_port.write(|w| w); | 79 | g.events_port.write(|w| w); |
| 87 | 80 | ||
| 88 | #[cfg(any(feature = "52833", feature = "52840"))] | 81 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 89 | let ports = &[&*pac::P0::ptr(), &*pac::P1::ptr()]; | 82 | let ports = &[&*pac::P0::ptr(), &*pac::P1::ptr()]; |
| 90 | #[cfg(not(any(feature = "52833", feature = "52840")))] | 83 | #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] |
| 91 | let ports = &[&*pac::P0::ptr()]; | 84 | let ports = &[&*pac::P0::ptr()]; |
| 92 | 85 | ||
| 93 | for (port, &p) in ports.iter().enumerate() { | 86 | for (port, &p) in ports.iter().enumerate() { |
| @@ -133,12 +126,7 @@ impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> { | |||
| 133 | } | 126 | } |
| 134 | 127 | ||
| 135 | impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { | 128 | impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { |
| 136 | pub fn new( | 129 | pub fn new(ch: C, pin: Input<'d, T>, polarity: InputChannelPolarity) -> Self { |
| 137 | _init: Initialized, | ||
| 138 | ch: C, | ||
| 139 | pin: Input<'d, T>, | ||
| 140 | polarity: InputChannelPolarity, | ||
| 141 | ) -> Self { | ||
| 142 | let g = unsafe { &*pac::GPIOTE::ptr() }; | 130 | let g = unsafe { &*pac::GPIOTE::ptr() }; |
| 143 | let num = ch.number(); | 131 | let num = ch.number(); |
| 144 | 132 | ||
| @@ -149,7 +137,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { | |||
| 149 | InputChannelPolarity::None => w.mode().event().polarity().none(), | 137 | InputChannelPolarity::None => w.mode().event().polarity().none(), |
| 150 | InputChannelPolarity::Toggle => w.mode().event().polarity().toggle(), | 138 | InputChannelPolarity::Toggle => w.mode().event().polarity().toggle(), |
| 151 | }; | 139 | }; |
| 152 | #[cfg(any(feature = "52833", feature = "52840"))] | 140 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 153 | w.port().bit(match pin.pin.port() { | 141 | w.port().bit(match pin.pin.port() { |
| 154 | Port::Port0 => false, | 142 | Port::Port0 => false, |
| 155 | Port::Port1 => true, | 143 | Port::Port1 => true, |
| @@ -217,12 +205,7 @@ impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> { | |||
| 217 | } | 205 | } |
| 218 | 206 | ||
| 219 | impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { | 207 | impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { |
| 220 | pub fn new( | 208 | pub fn new(ch: C, pin: Output<'d, T>, polarity: OutputChannelPolarity) -> Self { |
| 221 | _init: Initialized, | ||
| 222 | ch: C, | ||
| 223 | pin: Output<'d, T>, | ||
| 224 | polarity: OutputChannelPolarity, | ||
| 225 | ) -> Self { | ||
| 226 | let g = unsafe { &*pac::GPIOTE::ptr() }; | 209 | let g = unsafe { &*pac::GPIOTE::ptr() }; |
| 227 | let num = ch.number(); | 210 | let num = ch.number(); |
| 228 | 211 | ||
| @@ -237,7 +220,7 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { | |||
| 237 | OutputChannelPolarity::Clear => w.polarity().hi_to_lo(), | 220 | OutputChannelPolarity::Clear => w.polarity().hi_to_lo(), |
| 238 | OutputChannelPolarity::Toggle => w.polarity().toggle(), | 221 | OutputChannelPolarity::Toggle => w.polarity().toggle(), |
| 239 | }; | 222 | }; |
| 240 | #[cfg(any(feature = "52833", feature = "52840"))] | 223 | #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] |
| 241 | w.port().bit(match pin.pin.port() { | 224 | w.port().bit(match pin.pin.port() { |
| 242 | Port::Port0 => false, | 225 | Port::Port0 => false, |
| 243 | Port::Port1 => true, | 226 | Port::Port1 => true, |
| @@ -297,7 +280,7 @@ pub struct PortInput<'d, T: GpioPin> { | |||
| 297 | impl<'d, T: GpioPin> Unpin for PortInput<'d, T> {} | 280 | impl<'d, T: GpioPin> Unpin for PortInput<'d, T> {} |
| 298 | 281 | ||
| 299 | impl<'d, T: GpioPin> PortInput<'d, T> { | 282 | impl<'d, T: GpioPin> PortInput<'d, T> { |
| 300 | pub fn new(_init: Initialized, pin: Input<'d, T>) -> Self { | 283 | pub fn new(pin: Input<'d, T>) -> Self { |
| 301 | Self { pin } | 284 | Self { pin } |
| 302 | } | 285 | } |
| 303 | } | 286 | } |
diff --git a/embassy-nrf/src/interrupt.rs b/embassy-nrf/src/interrupt.rs deleted file mode 100644 index a29861977..000000000 --- a/embassy-nrf/src/interrupt.rs +++ /dev/null | |||
| @@ -1,210 +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::Priority3 as Priority; | ||
| 9 | |||
| 10 | #[cfg(feature = "52810")] | ||
| 11 | mod irqs { | ||
| 12 | use super::*; | ||
| 13 | declare!(POWER_CLOCK); | ||
| 14 | declare!(RADIO); | ||
| 15 | declare!(UARTE0_UART0); | ||
| 16 | declare!(TWIM0_TWIS0_TWI0); | ||
| 17 | declare!(SPIM0_SPIS0_SPI0); | ||
| 18 | declare!(GPIOTE); | ||
| 19 | declare!(SAADC); | ||
| 20 | declare!(TIMER0); | ||
| 21 | declare!(TIMER1); | ||
| 22 | declare!(TIMER2); | ||
| 23 | declare!(RTC0); | ||
| 24 | declare!(TEMP); | ||
| 25 | declare!(RNG); | ||
| 26 | declare!(ECB); | ||
| 27 | declare!(CCM_AAR); | ||
| 28 | declare!(WDT); | ||
| 29 | declare!(RTC1); | ||
| 30 | declare!(QDEC); | ||
| 31 | declare!(COMP); | ||
| 32 | declare!(SWI0_EGU0); | ||
| 33 | declare!(SWI1_EGU1); | ||
| 34 | declare!(SWI2); | ||
| 35 | declare!(SWI3); | ||
| 36 | declare!(SWI4); | ||
| 37 | declare!(SWI5); | ||
| 38 | declare!(PWM0); | ||
| 39 | declare!(PDM); | ||
| 40 | } | ||
| 41 | |||
| 42 | #[cfg(feature = "52811")] | ||
| 43 | mod irqs { | ||
| 44 | use super::*; | ||
| 45 | declare!(POWER_CLOCK); | ||
| 46 | declare!(RADIO); | ||
| 47 | declare!(UARTE0_UART0); | ||
| 48 | declare!(TWIM0_TWIS0_TWI0_SPIM1_SPIS1_SPI1); | ||
| 49 | declare!(SPIM0_SPIS0_SPI0); | ||
| 50 | declare!(GPIOTE); | ||
| 51 | declare!(SAADC); | ||
| 52 | declare!(TIMER0); | ||
| 53 | declare!(TIMER1); | ||
| 54 | declare!(TIMER2); | ||
| 55 | declare!(RTC0); | ||
| 56 | declare!(TEMP); | ||
| 57 | declare!(RNG); | ||
| 58 | declare!(ECB); | ||
| 59 | declare!(CCM_AAR); | ||
| 60 | declare!(WDT); | ||
| 61 | declare!(RTC1); | ||
| 62 | declare!(QDEC); | ||
| 63 | declare!(COMP); | ||
| 64 | declare!(SWI0_EGU0); | ||
| 65 | declare!(SWI1_EGU1); | ||
| 66 | declare!(SWI2); | ||
| 67 | declare!(SWI3); | ||
| 68 | declare!(SWI4); | ||
| 69 | declare!(SWI5); | ||
| 70 | declare!(PWM0); | ||
| 71 | declare!(PDM); | ||
| 72 | } | ||
| 73 | |||
| 74 | #[cfg(feature = "52832")] | ||
| 75 | mod irqs { | ||
| 76 | use super::*; | ||
| 77 | declare!(POWER_CLOCK); | ||
| 78 | declare!(RADIO); | ||
| 79 | declare!(UARTE0_UART0); | ||
| 80 | declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 81 | declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 82 | declare!(NFCT); | ||
| 83 | declare!(GPIOTE); | ||
| 84 | declare!(SAADC); | ||
| 85 | declare!(TIMER0); | ||
| 86 | declare!(TIMER1); | ||
| 87 | declare!(TIMER2); | ||
| 88 | declare!(RTC0); | ||
| 89 | declare!(TEMP); | ||
| 90 | declare!(RNG); | ||
| 91 | declare!(ECB); | ||
| 92 | declare!(CCM_AAR); | ||
| 93 | declare!(WDT); | ||
| 94 | declare!(RTC1); | ||
| 95 | declare!(QDEC); | ||
| 96 | declare!(COMP_LPCOMP); | ||
| 97 | declare!(SWI0_EGU0); | ||
| 98 | declare!(SWI1_EGU1); | ||
| 99 | declare!(SWI2_EGU2); | ||
| 100 | declare!(SWI3_EGU3); | ||
| 101 | declare!(SWI4_EGU4); | ||
| 102 | declare!(SWI5_EGU5); | ||
| 103 | declare!(TIMER3); | ||
| 104 | declare!(TIMER4); | ||
| 105 | declare!(PWM0); | ||
| 106 | declare!(PDM); | ||
| 107 | declare!(MWU); | ||
| 108 | declare!(PWM1); | ||
| 109 | declare!(PWM2); | ||
| 110 | declare!(SPIM2_SPIS2_SPI2); | ||
| 111 | declare!(RTC2); | ||
| 112 | declare!(I2S); | ||
| 113 | declare!(FPU); | ||
| 114 | } | ||
| 115 | |||
| 116 | #[cfg(feature = "52833")] | ||
| 117 | mod irqs { | ||
| 118 | use super::*; | ||
| 119 | declare!(POWER_CLOCK); | ||
| 120 | declare!(RADIO); | ||
| 121 | declare!(UARTE0_UART0); | ||
| 122 | declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 123 | declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 124 | declare!(NFCT); | ||
| 125 | declare!(GPIOTE); | ||
| 126 | declare!(SAADC); | ||
| 127 | declare!(TIMER0); | ||
| 128 | declare!(TIMER1); | ||
| 129 | declare!(TIMER2); | ||
| 130 | declare!(RTC0); | ||
| 131 | declare!(TEMP); | ||
| 132 | declare!(RNG); | ||
| 133 | declare!(ECB); | ||
| 134 | declare!(CCM_AAR); | ||
| 135 | declare!(WDT); | ||
| 136 | declare!(RTC1); | ||
| 137 | declare!(QDEC); | ||
| 138 | declare!(COMP_LPCOMP); | ||
| 139 | declare!(SWI0_EGU0); | ||
| 140 | declare!(SWI1_EGU1); | ||
| 141 | declare!(SWI2_EGU2); | ||
| 142 | declare!(SWI3_EGU3); | ||
| 143 | declare!(SWI4_EGU4); | ||
| 144 | declare!(SWI5_EGU5); | ||
| 145 | declare!(TIMER3); | ||
| 146 | declare!(TIMER4); | ||
| 147 | declare!(PWM0); | ||
| 148 | declare!(PDM); | ||
| 149 | declare!(MWU); | ||
| 150 | declare!(PWM1); | ||
| 151 | declare!(PWM2); | ||
| 152 | declare!(SPIM2_SPIS2_SPI2); | ||
| 153 | declare!(RTC2); | ||
| 154 | declare!(I2S); | ||
| 155 | declare!(FPU); | ||
| 156 | declare!(USBD); | ||
| 157 | declare!(UARTE1); | ||
| 158 | declare!(PWM3); | ||
| 159 | declare!(SPIM3); | ||
| 160 | } | ||
| 161 | |||
| 162 | #[cfg(feature = "52840")] | ||
| 163 | mod irqs { | ||
| 164 | use super::*; | ||
| 165 | declare!(POWER_CLOCK); | ||
| 166 | declare!(RADIO); | ||
| 167 | declare!(UARTE0_UART0); | ||
| 168 | declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 169 | declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 170 | declare!(NFCT); | ||
| 171 | declare!(GPIOTE); | ||
| 172 | declare!(SAADC); | ||
| 173 | declare!(TIMER0); | ||
| 174 | declare!(TIMER1); | ||
| 175 | declare!(TIMER2); | ||
| 176 | declare!(RTC0); | ||
| 177 | declare!(TEMP); | ||
| 178 | declare!(RNG); | ||
| 179 | declare!(ECB); | ||
| 180 | declare!(CCM_AAR); | ||
| 181 | declare!(WDT); | ||
| 182 | declare!(RTC1); | ||
| 183 | declare!(QDEC); | ||
| 184 | declare!(COMP_LPCOMP); | ||
| 185 | declare!(SWI0_EGU0); | ||
| 186 | declare!(SWI1_EGU1); | ||
| 187 | declare!(SWI2_EGU2); | ||
| 188 | declare!(SWI3_EGU3); | ||
| 189 | declare!(SWI4_EGU4); | ||
| 190 | declare!(SWI5_EGU5); | ||
| 191 | declare!(TIMER3); | ||
| 192 | declare!(TIMER4); | ||
| 193 | declare!(PWM0); | ||
| 194 | declare!(PDM); | ||
| 195 | declare!(MWU); | ||
| 196 | declare!(PWM1); | ||
| 197 | declare!(PWM2); | ||
| 198 | declare!(SPIM2_SPIS2_SPI2); | ||
| 199 | declare!(RTC2); | ||
| 200 | declare!(I2S); | ||
| 201 | declare!(FPU); | ||
| 202 | declare!(USBD); | ||
| 203 | declare!(UARTE1); | ||
| 204 | declare!(QSPI); | ||
| 205 | declare!(CRYPTOCELL); | ||
| 206 | declare!(PWM3); | ||
| 207 | declare!(SPIM3); | ||
| 208 | } | ||
| 209 | |||
| 210 | pub use irqs::*; | ||
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 33d764fba..1c496be19 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -7,257 +7,155 @@ | |||
| 7 | #![allow(incomplete_features)] | 7 | #![allow(incomplete_features)] |
| 8 | 8 | ||
| 9 | #[cfg(not(any( | 9 | #[cfg(not(any( |
| 10 | feature = "52810", | 10 | feature = "nrf51", |
| 11 | feature = "52811", | 11 | feature = "nrf52805", |
| 12 | feature = "52832", | 12 | feature = "nrf52810", |
| 13 | feature = "52833", | 13 | feature = "nrf52811", |
| 14 | feature = "52840", | 14 | feature = "nrf52820", |
| 15 | feature = "nrf52832", | ||
| 16 | feature = "nrf52833", | ||
| 17 | feature = "nrf52840", | ||
| 18 | feature = "nrf5340-app", | ||
| 19 | feature = "nrf5340-net", | ||
| 20 | feature = "nrf9160", | ||
| 15 | )))] | 21 | )))] |
| 16 | compile_error!("No chip feature activated. You must activate exactly one of the following features: 52810, 52811, 52832, 52833, 52840"); | 22 | compile_error!("No chip feature activated. You must activate exactly one of the following features: nrf52810, nrf52811, nrf52832, nrf52833, nrf52840"); |
| 17 | |||
| 18 | #[cfg(any( | ||
| 19 | all(feature = "52810", feature = "52811"), | ||
| 20 | all(feature = "52810", feature = "52832"), | ||
| 21 | all(feature = "52810", feature = "52833"), | ||
| 22 | all(feature = "52810", feature = "52840"), | ||
| 23 | all(feature = "52811", feature = "52832"), | ||
| 24 | all(feature = "52811", feature = "52833"), | ||
| 25 | all(feature = "52811", feature = "52840"), | ||
| 26 | all(feature = "52832", feature = "52833"), | ||
| 27 | all(feature = "52832", feature = "52840"), | ||
| 28 | all(feature = "52833", feature = "52840"), | ||
| 29 | ))] | ||
| 30 | compile_error!("Multile chip features activated. You must activate exactly one of the following features: 52810, 52811, 52832, 52833, 52840"); | ||
| 31 | |||
| 32 | #[cfg(feature = "52810")] | ||
| 33 | pub use nrf52810_pac as pac; | ||
| 34 | #[cfg(feature = "52811")] | ||
| 35 | pub use nrf52811_pac as pac; | ||
| 36 | #[cfg(feature = "52832")] | ||
| 37 | pub use nrf52832_pac as pac; | ||
| 38 | #[cfg(feature = "52833")] | ||
| 39 | pub use nrf52833_pac as pac; | ||
| 40 | #[cfg(feature = "52840")] | ||
| 41 | pub use nrf52840_pac as pac; | ||
| 42 | |||
| 43 | /// Length of Nordic EasyDMA differs for MCUs | ||
| 44 | #[cfg(any( | ||
| 45 | feature = "52810", | ||
| 46 | feature = "52811", | ||
| 47 | feature = "52832", | ||
| 48 | feature = "51" | ||
| 49 | ))] | ||
| 50 | pub mod target_constants { | ||
| 51 | // NRF52832 8 bits1..0xFF | ||
| 52 | pub const EASY_DMA_SIZE: usize = 255; | ||
| 53 | // Easy DMA can only read from data ram | ||
| 54 | pub const SRAM_LOWER: usize = 0x2000_0000; | ||
| 55 | pub const SRAM_UPPER: usize = 0x3000_0000; | ||
| 56 | } | ||
| 57 | #[cfg(any(feature = "52840", feature = "52833", feature = "9160"))] | ||
| 58 | pub mod target_constants { | ||
| 59 | // NRF52840 and NRF9160 16 bits 1..0xFFFF | ||
| 60 | pub const EASY_DMA_SIZE: usize = 65535; | ||
| 61 | // Limits for Easy DMA - it can only read from data ram | ||
| 62 | pub const SRAM_LOWER: usize = 0x2000_0000; | ||
| 63 | pub const SRAM_UPPER: usize = 0x3000_0000; | ||
| 64 | } | ||
| 65 | |||
| 66 | /// Does this slice reside entirely within RAM? | ||
| 67 | pub(crate) fn slice_in_ram(slice: &[u8]) -> bool { | ||
| 68 | let ptr = slice.as_ptr() as usize; | ||
| 69 | ptr >= target_constants::SRAM_LOWER && (ptr + slice.len()) < target_constants::SRAM_UPPER | ||
| 70 | } | ||
| 71 | |||
| 72 | /// Return an error if slice is not in RAM. | ||
| 73 | #[cfg(not(feature = "51"))] | ||
| 74 | pub(crate) fn slice_in_ram_or<T>(slice: &[u8], err: T) -> Result<(), T> { | ||
| 75 | if slice.len() == 0 || slice_in_ram(slice) { | ||
| 76 | Ok(()) | ||
| 77 | } else { | ||
| 78 | Err(err) | ||
| 79 | } | ||
| 80 | } | ||
| 81 | 23 | ||
| 82 | // This mod MUST go first, so that the others see its macros. | 24 | // This mod MUST go first, so that the others see its macros. |
| 83 | pub(crate) mod fmt; | 25 | pub(crate) mod fmt; |
| 26 | pub(crate) mod util; | ||
| 84 | 27 | ||
| 85 | pub mod buffered_uarte; | 28 | pub mod buffered_uarte; |
| 86 | pub mod gpio; | 29 | pub mod gpio; |
| 87 | pub mod gpiote; | 30 | pub mod gpiote; |
| 88 | pub mod interrupt; | ||
| 89 | pub mod ppi; | 31 | pub mod ppi; |
| 90 | #[cfg(feature = "52840")] | 32 | #[cfg(not(any(feature = "nrf52805", feature = "nrf52820")))] |
| 33 | pub mod pwm; | ||
| 34 | #[cfg(feature = "nrf52840")] | ||
| 91 | pub mod qspi; | 35 | pub mod qspi; |
| 92 | pub mod rtc; | 36 | pub mod rtc; |
| 37 | #[cfg(not(feature = "nrf52820"))] | ||
| 93 | pub mod saadc; | 38 | pub mod saadc; |
| 94 | pub mod spim; | 39 | pub mod spim; |
| 95 | pub mod system; | ||
| 96 | pub mod timer; | 40 | pub mod timer; |
| 41 | pub mod twim; | ||
| 97 | pub mod uarte; | 42 | pub mod uarte; |
| 98 | 43 | ||
| 99 | embassy_extras::peripherals! { | 44 | // This mod MUST go last, so that it sees all the `impl_foo!` macros |
| 100 | // RTC | 45 | #[cfg(feature = "nrf52805")] |
| 101 | RTC0, | 46 | #[path = "chips/nrf52805.rs"] |
| 102 | RTC1, | 47 | mod chip; |
| 103 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | 48 | #[cfg(feature = "nrf52810")] |
| 104 | RTC2, | 49 | #[path = "chips/nrf52810.rs"] |
| 105 | 50 | mod chip; | |
| 106 | // QSPI | 51 | #[cfg(feature = "nrf52811")] |
| 107 | #[cfg(feature = "52840")] | 52 | #[path = "chips/nrf52811.rs"] |
| 108 | QSPI, | 53 | mod chip; |
| 54 | #[cfg(feature = "nrf52820")] | ||
| 55 | #[path = "chips/nrf52820.rs"] | ||
| 56 | mod chip; | ||
| 57 | #[cfg(feature = "nrf52832")] | ||
| 58 | #[path = "chips/nrf52832.rs"] | ||
| 59 | mod chip; | ||
| 60 | #[cfg(feature = "nrf52833")] | ||
| 61 | #[path = "chips/nrf52833.rs"] | ||
| 62 | mod chip; | ||
| 63 | #[cfg(feature = "nrf52840")] | ||
| 64 | #[path = "chips/nrf52840.rs"] | ||
| 65 | mod chip; | ||
| 66 | |||
| 67 | pub(crate) use chip::pac; | ||
| 68 | pub use chip::{peripherals, Peripherals}; | ||
| 69 | |||
| 70 | pub mod interrupt { | ||
| 71 | pub use crate::chip::irqs::*; | ||
| 72 | pub use cortex_m::interrupt::{CriticalSection, Mutex}; | ||
| 73 | pub use embassy::interrupt::{declare, take, Interrupt}; | ||
| 74 | pub use embassy_extras::interrupt::Priority3 as Priority; | ||
| 75 | } | ||
| 76 | pub use embassy_macros::interrupt; | ||
| 109 | 77 | ||
| 110 | // UARTE | 78 | pub mod config { |
| 111 | UARTE0, | 79 | pub enum HfclkSource { |
| 112 | #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] | 80 | Internal, |
| 113 | UARTE1, | 81 | ExternalXtal, |
| 82 | } | ||
| 114 | 83 | ||
| 115 | // SPIM | 84 | pub enum LfclkSource { |
| 116 | // TODO this is actually shared with SPI, SPIM, SPIS, TWI, TWIS, TWIS. | 85 | InternalRC, |
| 117 | // When they're all implemented, they should be only one peripheral here. | 86 | Synthesized, |
| 118 | SPIM0, | 87 | ExternalXtal, |
| 119 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | 88 | ExternalLowSwing, |
| 120 | SPIM1, | 89 | ExternalFullSwing, |
| 121 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | 90 | } |
| 122 | SPIM2, | ||
| 123 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 124 | SPIM3, | ||
| 125 | 91 | ||
| 126 | // SAADC | 92 | #[non_exhaustive] |
| 127 | SAADC, | 93 | pub struct Config { |
| 94 | pub hfclk_source: HfclkSource, | ||
| 95 | pub lfclk_source: LfclkSource, | ||
| 96 | } | ||
| 128 | 97 | ||
| 129 | // TIMER | 98 | impl Default for Config { |
| 130 | TIMER0, | 99 | fn default() -> Self { |
| 131 | TIMER1, | 100 | Self { |
| 132 | TIMER2, | 101 | // There are hobby nrf52 boards out there without external XTALs... |
| 133 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | 102 | // Default everything to internal so it Just Works. User can enable external |
| 134 | TIMER3, | 103 | // xtals if they know they have them. |
| 135 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | 104 | hfclk_source: HfclkSource::Internal, |
| 136 | TIMER4, | 105 | lfclk_source: LfclkSource::InternalRC, |
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | } | ||
| 137 | 110 | ||
| 138 | // GPIOTE | 111 | pub fn init(config: config::Config) -> Peripherals { |
| 139 | GPIOTE, | 112 | // Do this first, so that it panics if user is calling `init` a second time |
| 140 | GPIOTE_CH0, | 113 | // before doing anything important. |
| 141 | GPIOTE_CH1, | 114 | let peripherals = Peripherals::take(); |
| 142 | GPIOTE_CH2, | 115 | |
| 143 | GPIOTE_CH3, | 116 | let r = unsafe { &*pac::CLOCK::ptr() }; |
| 144 | GPIOTE_CH4, | 117 | |
| 145 | GPIOTE_CH5, | 118 | // Start HFCLK. |
| 146 | GPIOTE_CH6, | 119 | match config.hfclk_source { |
| 147 | GPIOTE_CH7, | 120 | config::HfclkSource::Internal => {} |
| 121 | config::HfclkSource::ExternalXtal => { | ||
| 122 | // Datasheet says this is likely to take 0.36ms | ||
| 123 | r.events_hfclkstarted.write(|w| unsafe { w.bits(0) }); | ||
| 124 | r.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | ||
| 125 | while r.events_hfclkstarted.read().bits() == 0 {} | ||
| 126 | } | ||
| 127 | } | ||
| 148 | 128 | ||
| 149 | // PPI | 129 | // Configure LFCLK. |
| 150 | PPI_CH0, | 130 | match config.lfclk_source { |
| 151 | PPI_CH1, | 131 | config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()), |
| 152 | PPI_CH2, | 132 | config::LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()), |
| 153 | PPI_CH3, | 133 | |
| 154 | PPI_CH4, | 134 | config::LfclkSource::ExternalXtal => r.lfclksrc.write(|w| w.src().xtal()), |
| 155 | PPI_CH5, | 135 | |
| 156 | PPI_CH6, | 136 | config::LfclkSource::ExternalLowSwing => r.lfclksrc.write(|w| { |
| 157 | PPI_CH7, | 137 | w.src().xtal(); |
| 158 | PPI_CH8, | 138 | w.external().enabled(); |
| 159 | PPI_CH9, | 139 | w.bypass().disabled(); |
| 160 | PPI_CH10, | 140 | w |
| 161 | PPI_CH11, | 141 | }), |
| 162 | PPI_CH12, | 142 | config::LfclkSource::ExternalFullSwing => r.lfclksrc.write(|w| { |
| 163 | PPI_CH13, | 143 | w.src().xtal(); |
| 164 | PPI_CH14, | 144 | w.external().enabled(); |
| 165 | PPI_CH15, | 145 | w.bypass().enabled(); |
| 166 | #[cfg(not(feature = "51"))] | 146 | w |
| 167 | PPI_CH16, | 147 | }), |
| 168 | #[cfg(not(feature = "51"))] | 148 | } |
| 169 | PPI_CH17, | ||
| 170 | #[cfg(not(feature = "51"))] | ||
| 171 | PPI_CH18, | ||
| 172 | #[cfg(not(feature = "51"))] | ||
| 173 | PPI_CH19, | ||
| 174 | PPI_CH20, | ||
| 175 | PPI_CH21, | ||
| 176 | PPI_CH22, | ||
| 177 | PPI_CH23, | ||
| 178 | PPI_CH24, | ||
| 179 | PPI_CH25, | ||
| 180 | PPI_CH26, | ||
| 181 | PPI_CH27, | ||
| 182 | PPI_CH28, | ||
| 183 | PPI_CH29, | ||
| 184 | PPI_CH30, | ||
| 185 | PPI_CH31, | ||
| 186 | 149 | ||
| 187 | PPI_GROUP0, | 150 | // Start LFCLK. |
| 188 | PPI_GROUP1, | 151 | // Datasheet says this could take 100us from synth source |
| 189 | PPI_GROUP2, | 152 | // 600us from rc source, 0.25s from an external source. |
| 190 | PPI_GROUP3, | 153 | r.events_lfclkstarted.write(|w| unsafe { w.bits(0) }); |
| 191 | #[cfg(not(feature = "51"))] | 154 | r.tasks_lfclkstart.write(|w| unsafe { w.bits(1) }); |
| 192 | PPI_GROUP4, | 155 | while r.events_lfclkstarted.read().bits() == 0 {} |
| 193 | #[cfg(not(feature = "51"))] | ||
| 194 | PPI_GROUP5, | ||
| 195 | 156 | ||
| 196 | // GPIO port 0 | 157 | // Init GPIOTE |
| 197 | P0_00, | 158 | crate::gpiote::init(); |
| 198 | P0_01, | ||
| 199 | P0_02, | ||
| 200 | P0_03, | ||
| 201 | P0_04, | ||
| 202 | P0_05, | ||
| 203 | P0_06, | ||
| 204 | P0_07, | ||
| 205 | P0_08, | ||
| 206 | P0_09, | ||
| 207 | P0_10, | ||
| 208 | P0_11, | ||
| 209 | P0_12, | ||
| 210 | P0_13, | ||
| 211 | P0_14, | ||
| 212 | P0_15, | ||
| 213 | P0_16, | ||
| 214 | P0_17, | ||
| 215 | P0_18, | ||
| 216 | P0_19, | ||
| 217 | P0_20, | ||
| 218 | P0_21, | ||
| 219 | P0_22, | ||
| 220 | P0_23, | ||
| 221 | P0_24, | ||
| 222 | P0_25, | ||
| 223 | P0_26, | ||
| 224 | P0_27, | ||
| 225 | P0_28, | ||
| 226 | P0_29, | ||
| 227 | P0_30, | ||
| 228 | P0_31, | ||
| 229 | 159 | ||
| 230 | // GPIO port 1 | 160 | peripherals |
| 231 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 232 | P1_00, | ||
| 233 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 234 | P1_01, | ||
| 235 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 236 | P1_02, | ||
| 237 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 238 | P1_03, | ||
| 239 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 240 | P1_04, | ||
| 241 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 242 | P1_05, | ||
| 243 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 244 | P1_06, | ||
| 245 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 246 | P1_07, | ||
| 247 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 248 | P1_08, | ||
| 249 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 250 | P1_09, | ||
| 251 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 252 | P1_10, | ||
| 253 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 254 | P1_11, | ||
| 255 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 256 | P1_12, | ||
| 257 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 258 | P1_13, | ||
| 259 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 260 | P1_14, | ||
| 261 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 262 | P1_15, | ||
| 263 | } | 161 | } |
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs new file mode 100644 index 000000000..34c31e3bb --- /dev/null +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -0,0 +1,233 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | use core::cell::UnsafeCell; | ||
| 4 | use core::marker::PhantomData; | ||
| 5 | use core::sync::atomic::{compiler_fence, Ordering}; | ||
| 6 | use embassy::util::Unborrow; | ||
| 7 | use embassy_extras::unborrow; | ||
| 8 | |||
| 9 | use crate::fmt::{assert, panic, unreachable, *}; | ||
| 10 | use crate::gpio::sealed::Pin as _; | ||
| 11 | use crate::gpio::OptionalPin as GpioOptionalPin; | ||
| 12 | use crate::interrupt::Interrupt; | ||
| 13 | use crate::pac; | ||
| 14 | |||
| 15 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 16 | pub enum Prescaler { | ||
| 17 | Div1, | ||
| 18 | Div2, | ||
| 19 | Div4, | ||
| 20 | Div8, | ||
| 21 | Div16, | ||
| 22 | Div32, | ||
| 23 | Div64, | ||
| 24 | Div128, | ||
| 25 | } | ||
| 26 | |||
| 27 | /// Interface to the UARTE peripheral | ||
| 28 | pub struct Pwm<'d, T: Instance> { | ||
| 29 | peri: T, | ||
| 30 | phantom: PhantomData<&'d mut T>, | ||
| 31 | } | ||
| 32 | |||
| 33 | impl<'d, T: Instance> Pwm<'d, T> { | ||
| 34 | /// Creates the interface to a UARTE instance. | ||
| 35 | /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. | ||
| 36 | /// | ||
| 37 | /// # Safety | ||
| 38 | /// | ||
| 39 | /// The returned API is safe unless you use `mem::forget` (or similar safe mechanisms) | ||
| 40 | /// on stack allocated buffers which which have been passed to [`send()`](Pwm::send) | ||
| 41 | /// or [`receive`](Pwm::receive). | ||
| 42 | #[allow(unused_unsafe)] | ||
| 43 | pub fn new( | ||
| 44 | pwm: impl Unborrow<Target = T> + 'd, | ||
| 45 | ch0: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | ||
| 46 | ch1: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | ||
| 47 | ch2: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | ||
| 48 | ch3: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | ||
| 49 | ) -> Self { | ||
| 50 | unborrow!(pwm, ch0, ch1, ch2, ch3); | ||
| 51 | |||
| 52 | let r = T::regs(); | ||
| 53 | let s = T::state(); | ||
| 54 | |||
| 55 | if let Some(pin) = ch0.pin_mut() { | ||
| 56 | pin.set_low(); | ||
| 57 | pin.conf().write(|w| w.dir().output()); | ||
| 58 | } | ||
| 59 | if let Some(pin) = ch1.pin_mut() { | ||
| 60 | pin.set_low(); | ||
| 61 | pin.conf().write(|w| w.dir().output()); | ||
| 62 | } | ||
| 63 | if let Some(pin) = ch2.pin_mut() { | ||
| 64 | pin.set_low(); | ||
| 65 | pin.conf().write(|w| w.dir().output()); | ||
| 66 | } | ||
| 67 | if let Some(pin) = ch3.pin_mut() { | ||
| 68 | pin.set_low(); | ||
| 69 | pin.conf().write(|w| w.dir().output()); | ||
| 70 | } | ||
| 71 | r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) }); | ||
| 72 | r.psel.out[1].write(|w| unsafe { w.bits(ch1.psel_bits()) }); | ||
| 73 | r.psel.out[2].write(|w| unsafe { w.bits(ch2.psel_bits()) }); | ||
| 74 | r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) }); | ||
| 75 | |||
| 76 | // Disable all interrupts | ||
| 77 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | ||
| 78 | |||
| 79 | // Enable | ||
| 80 | r.enable.write(|w| w.enable().enabled()); | ||
| 81 | |||
| 82 | r.seq0 | ||
| 83 | .ptr | ||
| 84 | .write(|w| unsafe { w.bits(&s.duty as *const _ as u32) }); | ||
| 85 | r.seq0.cnt.write(|w| unsafe { w.bits(4) }); | ||
| 86 | r.seq0.refresh.write(|w| unsafe { w.bits(32) }); | ||
| 87 | r.seq0.enddelay.write(|w| unsafe { w.bits(0) }); | ||
| 88 | |||
| 89 | r.decoder.write(|w| { | ||
| 90 | w.load().individual(); | ||
| 91 | w.mode().refresh_count() | ||
| 92 | }); | ||
| 93 | r.mode.write(|w| w.updown().up()); | ||
| 94 | r.prescaler.write(|w| w.prescaler().div_1()); | ||
| 95 | r.countertop | ||
| 96 | .write(|w| unsafe { w.countertop().bits(32767) }); | ||
| 97 | r.loop_.write(|w| w.cnt().disabled()); | ||
| 98 | |||
| 99 | Self { | ||
| 100 | peri: pwm, | ||
| 101 | phantom: PhantomData, | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | /// Enables the PWM generator. | ||
| 106 | #[inline(always)] | ||
| 107 | pub fn enable(&self) { | ||
| 108 | let r = T::regs(); | ||
| 109 | r.enable.write(|w| w.enable().enabled()); | ||
| 110 | } | ||
| 111 | |||
| 112 | /// Disables the PWM generator. | ||
| 113 | #[inline(always)] | ||
| 114 | pub fn disable(&self) { | ||
| 115 | let r = T::regs(); | ||
| 116 | r.enable.write(|w| w.enable().disabled()); | ||
| 117 | } | ||
| 118 | |||
| 119 | /// Sets duty cycle (15 bit) for a PWM channel. | ||
| 120 | pub fn set_duty(&self, channel: usize, duty: u16) { | ||
| 121 | let s = T::state(); | ||
| 122 | unsafe { (*s.duty.get())[channel] = duty & 0x7FFF }; | ||
| 123 | |||
| 124 | compiler_fence(Ordering::SeqCst); | ||
| 125 | T::regs().tasks_seqstart[0].write(|w| unsafe { w.bits(1) }); | ||
| 126 | } | ||
| 127 | |||
| 128 | /// Sets the PWM clock prescaler. | ||
| 129 | #[inline(always)] | ||
| 130 | pub fn set_prescaler(&self, div: Prescaler) { | ||
| 131 | T::regs().prescaler.write(|w| w.prescaler().bits(div as u8)); | ||
| 132 | } | ||
| 133 | |||
| 134 | /// Sets the PWM clock prescaler. | ||
| 135 | #[inline(always)] | ||
| 136 | pub fn prescaler(&self) -> Prescaler { | ||
| 137 | match T::regs().prescaler.read().prescaler().bits() { | ||
| 138 | 0 => Prescaler::Div1, | ||
| 139 | 1 => Prescaler::Div2, | ||
| 140 | 2 => Prescaler::Div4, | ||
| 141 | 3 => Prescaler::Div8, | ||
| 142 | 4 => Prescaler::Div16, | ||
| 143 | 5 => Prescaler::Div32, | ||
| 144 | 6 => Prescaler::Div64, | ||
| 145 | 7 => Prescaler::Div128, | ||
| 146 | _ => unreachable!(), | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | /// Sets the maximum duty cycle value. | ||
| 151 | #[inline(always)] | ||
| 152 | pub fn set_max_duty(&self, duty: u16) { | ||
| 153 | T::regs() | ||
| 154 | .countertop | ||
| 155 | .write(|w| unsafe { w.countertop().bits(duty.min(32767u16)) }); | ||
| 156 | } | ||
| 157 | |||
| 158 | /// Returns the maximum duty cycle value. | ||
| 159 | #[inline(always)] | ||
| 160 | pub fn max_duty(&self) -> u16 { | ||
| 161 | T::regs().countertop.read().countertop().bits() | ||
| 162 | } | ||
| 163 | |||
| 164 | /// Sets the PWM output frequency. | ||
| 165 | #[inline(always)] | ||
| 166 | pub fn set_period(&self, freq: u32) { | ||
| 167 | let clk = 16_000_000u32 >> (self.prescaler() as u8); | ||
| 168 | let duty = clk / freq; | ||
| 169 | self.set_max_duty(duty.min(32767) as u16); | ||
| 170 | } | ||
| 171 | |||
| 172 | /// Returns the PWM output frequency. | ||
| 173 | #[inline(always)] | ||
| 174 | pub fn period(&self) -> u32 { | ||
| 175 | let clk = 16_000_000u32 >> (self.prescaler() as u8); | ||
| 176 | let max_duty = self.max_duty() as u32; | ||
| 177 | clk / max_duty | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 181 | impl<'a, T: Instance> Drop for Pwm<'a, T> { | ||
| 182 | fn drop(&mut self) { | ||
| 183 | let r = T::regs(); | ||
| 184 | r.enable.write(|w| w.enable().disabled()); | ||
| 185 | |||
| 186 | info!("pwm drop: done"); | ||
| 187 | |||
| 188 | // TODO: disable pins | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | pub(crate) mod sealed { | ||
| 193 | use super::*; | ||
| 194 | |||
| 195 | pub struct State { | ||
| 196 | pub duty: UnsafeCell<[u16; 4]>, | ||
| 197 | } | ||
| 198 | unsafe impl Sync for State {} | ||
| 199 | |||
| 200 | impl State { | ||
| 201 | pub const fn new() -> Self { | ||
| 202 | Self { | ||
| 203 | duty: UnsafeCell::new([0; 4]), | ||
| 204 | } | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | pub trait Instance { | ||
| 209 | fn regs() -> &'static pac::pwm0::RegisterBlock; | ||
| 210 | fn state() -> &'static State; | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { | ||
| 215 | type Interrupt: Interrupt; | ||
| 216 | } | ||
| 217 | |||
| 218 | macro_rules! impl_pwm { | ||
| 219 | ($type:ident, $pac_type:ident, $irq:ident) => { | ||
| 220 | impl crate::pwm::sealed::Instance for peripherals::$type { | ||
| 221 | fn regs() -> &'static pac::pwm0::RegisterBlock { | ||
| 222 | unsafe { &*pac::$pac_type::ptr() } | ||
| 223 | } | ||
| 224 | fn state() -> &'static crate::pwm::sealed::State { | ||
| 225 | static STATE: crate::pwm::sealed::State = crate::pwm::sealed::State::new(); | ||
| 226 | &STATE | ||
| 227 | } | ||
| 228 | } | ||
| 229 | impl crate::pwm::Instance for peripherals::$type { | ||
| 230 | type Interrupt = crate::interrupt::$irq; | ||
| 231 | } | ||
| 232 | }; | ||
| 233 | } | ||
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs index f683138d6..db6b653e7 100644 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | use core::future::Future; | 3 | use core::future::Future; |
| 2 | use core::marker::PhantomData; | 4 | use core::marker::PhantomData; |
| 3 | use core::task::Poll; | 5 | use core::task::Poll; |
| @@ -361,7 +363,7 @@ impl<'d, T: Instance> Flash for Qspi<'d, T> { | |||
| 361 | } | 363 | } |
| 362 | } | 364 | } |
| 363 | 365 | ||
| 364 | mod sealed { | 366 | pub(crate) mod sealed { |
| 365 | use super::*; | 367 | use super::*; |
| 366 | 368 | ||
| 367 | pub struct State { | 369 | pub struct State { |
| @@ -381,25 +383,23 @@ mod sealed { | |||
| 381 | } | 383 | } |
| 382 | } | 384 | } |
| 383 | 385 | ||
| 384 | pub trait Instance: sealed::Instance + 'static { | 386 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { |
| 385 | type Interrupt: Interrupt; | 387 | type Interrupt: Interrupt; |
| 386 | } | 388 | } |
| 387 | 389 | ||
| 388 | macro_rules! impl_instance { | 390 | macro_rules! impl_qspi { |
| 389 | ($type:ident, $irq:ident) => { | 391 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 390 | impl sealed::Instance for peripherals::$type { | 392 | impl crate::qspi::sealed::Instance for peripherals::$type { |
| 391 | fn regs() -> &'static pac::qspi::RegisterBlock { | 393 | fn regs() -> &'static pac::qspi::RegisterBlock { |
| 392 | unsafe { &*pac::$type::ptr() } | 394 | unsafe { &*pac::$pac_type::ptr() } |
| 393 | } | 395 | } |
| 394 | fn state() -> &'static sealed::State { | 396 | fn state() -> &'static crate::qspi::sealed::State { |
| 395 | static STATE: sealed::State = sealed::State::new(); | 397 | static STATE: crate::qspi::sealed::State = crate::qspi::sealed::State::new(); |
| 396 | &STATE | 398 | &STATE |
| 397 | } | 399 | } |
| 398 | } | 400 | } |
| 399 | impl Instance for peripherals::$type { | 401 | impl crate::qspi::Instance for peripherals::$type { |
| 400 | type Interrupt = interrupt::$irq; | 402 | type Interrupt = crate::interrupt::$irq; |
| 401 | } | 403 | } |
| 402 | }; | 404 | }; |
| 403 | } | 405 | } |
| 404 | |||
| 405 | impl_instance!(QSPI, QSPI); | ||
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs index dc0e3ceb6..99b6c099d 100644 --- a/embassy-nrf/src/rtc.rs +++ b/embassy-nrf/src/rtc.rs | |||
| @@ -3,7 +3,7 @@ use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; | |||
| 3 | use critical_section::CriticalSection; | 3 | use critical_section::CriticalSection; |
| 4 | use embassy::interrupt::InterruptExt; | 4 | use embassy::interrupt::InterruptExt; |
| 5 | use embassy::time::Clock; | 5 | use embassy::time::Clock; |
| 6 | use embassy::util::CriticalSectionMutex as Mutex; | 6 | use embassy::util::{CriticalSectionMutex as Mutex, Unborrow}; |
| 7 | 7 | ||
| 8 | use crate::interrupt::Interrupt; | 8 | use crate::interrupt::Interrupt; |
| 9 | use crate::pac; | 9 | use crate::pac; |
| @@ -283,7 +283,7 @@ macro_rules! impl_instance { | |||
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | /// Implemented by all RTC instances. | 285 | /// Implemented by all RTC instances. |
| 286 | pub trait Instance: sealed::Instance + 'static { | 286 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { |
| 287 | /// The interrupt associated with this RTC instance. | 287 | /// The interrupt associated with this RTC instance. |
| 288 | type Interrupt: Interrupt; | 288 | type Interrupt: Interrupt; |
| 289 | } | 289 | } |
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 3370e1243..0703836b9 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | use core::future::Future; | 3 | use core::future::Future; |
| 2 | use core::marker::PhantomData; | 4 | use core::marker::PhantomData; |
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 5 | use core::sync::atomic::{compiler_fence, Ordering}; |
| @@ -12,7 +14,7 @@ use traits::spi::FullDuplex; | |||
| 12 | use crate::gpio::sealed::Pin as _; | 14 | use crate::gpio::sealed::Pin as _; |
| 13 | use crate::gpio::{OptionalPin, Pin as GpioPin}; | 15 | use crate::gpio::{OptionalPin, Pin as GpioPin}; |
| 14 | use crate::interrupt::{self, Interrupt}; | 16 | use crate::interrupt::{self, Interrupt}; |
| 15 | use crate::{pac, peripherals, slice_in_ram_or}; | 17 | use crate::{pac, peripherals, util::slice_in_ram_or}; |
| 16 | 18 | ||
| 17 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 19 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 18 | pub use pac::spim0::frequency::FREQUENCY_A as Frequency; | 20 | pub use pac::spim0::frequency::FREQUENCY_A as Frequency; |
| @@ -33,12 +35,23 @@ pub struct Spim<'d, T: Instance> { | |||
| 33 | phantom: PhantomData<&'d mut T>, | 35 | phantom: PhantomData<&'d mut T>, |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 38 | #[non_exhaustive] | ||
| 36 | pub struct Config { | 39 | pub struct Config { |
| 37 | pub frequency: Frequency, | 40 | pub frequency: Frequency, |
| 38 | pub mode: Mode, | 41 | pub mode: Mode, |
| 39 | pub orc: u8, | 42 | pub orc: u8, |
| 40 | } | 43 | } |
| 41 | 44 | ||
| 45 | impl Default for Config { | ||
| 46 | fn default() -> Self { | ||
| 47 | Self { | ||
| 48 | frequency: Frequency::M1, | ||
| 49 | mode: MODE_0, | ||
| 50 | orc: 0x00, | ||
| 51 | } | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 42 | impl<'d, T: Instance> Spim<'d, T> { | 55 | impl<'d, T: Instance> Spim<'d, T> { |
| 43 | pub fn new( | 56 | pub fn new( |
| 44 | spim: impl Unborrow<Target = T> + 'd, | 57 | spim: impl Unborrow<Target = T> + 'd, |
| @@ -315,7 +328,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spim<'d, T> { | |||
| 315 | } | 328 | } |
| 316 | } | 329 | } |
| 317 | 330 | ||
| 318 | mod sealed { | 331 | pub(crate) mod sealed { |
| 319 | use super::*; | 332 | use super::*; |
| 320 | 333 | ||
| 321 | pub struct State { | 334 | pub struct State { |
| @@ -336,37 +349,23 @@ mod sealed { | |||
| 336 | } | 349 | } |
| 337 | } | 350 | } |
| 338 | 351 | ||
| 339 | pub trait Instance: sealed::Instance + 'static { | 352 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { |
| 340 | type Interrupt: Interrupt; | 353 | type Interrupt: Interrupt; |
| 341 | } | 354 | } |
| 342 | 355 | ||
| 343 | macro_rules! impl_instance { | 356 | macro_rules! impl_spim { |
| 344 | ($type:ident, $irq:ident) => { | 357 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 345 | impl sealed::Instance for peripherals::$type { | 358 | impl crate::spim::sealed::Instance for peripherals::$type { |
| 346 | fn regs() -> &'static pac::spim0::RegisterBlock { | 359 | fn regs() -> &'static pac::spim0::RegisterBlock { |
| 347 | unsafe { &*pac::$type::ptr() } | 360 | unsafe { &*pac::$pac_type::ptr() } |
| 348 | } | 361 | } |
| 349 | fn state() -> &'static sealed::State { | 362 | fn state() -> &'static crate::spim::sealed::State { |
| 350 | static STATE: sealed::State = sealed::State::new(); | 363 | static STATE: crate::spim::sealed::State = crate::spim::sealed::State::new(); |
| 351 | &STATE | 364 | &STATE |
| 352 | } | 365 | } |
| 353 | } | 366 | } |
| 354 | impl Instance for peripherals::$type { | 367 | impl crate::spim::Instance for peripherals::$type { |
| 355 | type Interrupt = interrupt::$irq; | 368 | type Interrupt = crate::interrupt::$irq; |
| 356 | } | 369 | } |
| 357 | }; | 370 | }; |
| 358 | } | 371 | } |
| 359 | |||
| 360 | #[cfg(feature = "52810")] | ||
| 361 | impl_instance!(SPIM0, SPIM0_SPIS0_SPI0); | ||
| 362 | #[cfg(not(feature = "52810"))] | ||
| 363 | impl_instance!(SPIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 364 | |||
| 365 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | ||
| 366 | impl_instance!(SPIM1, SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); | ||
| 367 | |||
| 368 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | ||
| 369 | impl_instance!(SPIM2, SPIM2_SPIS2_SPI2); | ||
| 370 | |||
| 371 | #[cfg(any(feature = "52833", feature = "52840"))] | ||
| 372 | impl_instance!(SPIM3, SPIM3); | ||
diff --git a/embassy-nrf/src/system.rs b/embassy-nrf/src/system.rs deleted file mode 100644 index 5d36e66fa..000000000 --- a/embassy-nrf/src/system.rs +++ /dev/null | |||
| @@ -1,76 +0,0 @@ | |||
| 1 | use crate::pac; | ||
| 2 | |||
| 3 | pub enum HfclkSource { | ||
| 4 | Internal, | ||
| 5 | ExternalXtal, | ||
| 6 | } | ||
| 7 | |||
| 8 | pub enum LfclkSource { | ||
| 9 | InternalRC, | ||
| 10 | Synthesized, | ||
| 11 | ExternalXtal, | ||
| 12 | ExternalLowSwing, | ||
| 13 | ExternalFullSwing, | ||
| 14 | } | ||
| 15 | |||
| 16 | #[non_exhaustive] | ||
| 17 | pub struct Config { | ||
| 18 | pub hfclk_source: HfclkSource, | ||
| 19 | pub lfclk_source: LfclkSource, | ||
| 20 | } | ||
| 21 | |||
| 22 | impl Default for Config { | ||
| 23 | fn default() -> Self { | ||
| 24 | Self { | ||
| 25 | // There are hobby nrf52 boards out there without external XTALs... | ||
| 26 | // Default everything to internal so it Just Works. User can enable external | ||
| 27 | // xtals if they know they have them. | ||
| 28 | hfclk_source: HfclkSource::Internal, | ||
| 29 | lfclk_source: LfclkSource::InternalRC, | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | /// safety: must only call once. | ||
| 35 | pub unsafe fn configure(config: Config) { | ||
| 36 | let r = &*pac::CLOCK::ptr(); | ||
| 37 | |||
| 38 | // Start HFCLK. | ||
| 39 | match config.hfclk_source { | ||
| 40 | HfclkSource::Internal => {} | ||
| 41 | HfclkSource::ExternalXtal => { | ||
| 42 | // Datasheet says this is likely to take 0.36ms | ||
| 43 | r.events_hfclkstarted.write(|w| unsafe { w.bits(0) }); | ||
| 44 | r.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | ||
| 45 | while r.events_hfclkstarted.read().bits() == 0 {} | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | // Configure LFCLK. | ||
| 50 | match config.lfclk_source { | ||
| 51 | LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()), | ||
| 52 | LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()), | ||
| 53 | |||
| 54 | LfclkSource::ExternalXtal => r.lfclksrc.write(move |w| w.src().xtal()), | ||
| 55 | |||
| 56 | LfclkSource::ExternalLowSwing => r.lfclksrc.write(move |w| { | ||
| 57 | w.src().xtal(); | ||
| 58 | w.external().enabled(); | ||
| 59 | w.bypass().disabled(); | ||
| 60 | w | ||
| 61 | }), | ||
| 62 | LfclkSource::ExternalFullSwing => r.lfclksrc.write(move |w| { | ||
| 63 | w.src().xtal(); | ||
| 64 | w.external().enabled(); | ||
| 65 | w.bypass().enabled(); | ||
| 66 | w | ||
| 67 | }), | ||
| 68 | } | ||
| 69 | |||
| 70 | // Start LFCLK. | ||
| 71 | // Datasheet says this could take 100us from synth source | ||
| 72 | // 600us from rc source, 0.25s from an external source. | ||
| 73 | r.events_lfclkstarted.write(|w| unsafe { w.bits(0) }); | ||
| 74 | r.tasks_lfclkstart.write(|w| unsafe { w.bits(1) }); | ||
| 75 | while r.events_lfclkstarted.read().bits() == 0 {} | ||
| 76 | } | ||
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index d74e3cfad..2490bfd93 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -1,8 +1,11 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | use embassy::interrupt::Interrupt; | 3 | use embassy::interrupt::Interrupt; |
| 4 | use embassy::util::Unborrow; | ||
| 2 | 5 | ||
| 3 | use crate::{interrupt, pac, peripherals}; | 6 | use crate::pac; |
| 4 | 7 | ||
| 5 | mod sealed { | 8 | pub(crate) mod sealed { |
| 6 | use super::*; | 9 | use super::*; |
| 7 | 10 | ||
| 8 | pub trait Instance { | 11 | pub trait Instance { |
| @@ -11,33 +14,25 @@ mod sealed { | |||
| 11 | pub trait ExtendedInstance {} | 14 | pub trait ExtendedInstance {} |
| 12 | } | 15 | } |
| 13 | 16 | ||
| 14 | pub trait Instance: sealed::Instance + 'static { | 17 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { |
| 15 | type Interrupt: Interrupt; | 18 | type Interrupt: Interrupt; |
| 16 | } | 19 | } |
| 17 | pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {} | 20 | pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {} |
| 18 | 21 | ||
| 19 | macro_rules! impl_instance { | 22 | macro_rules! impl_timer { |
| 20 | ($type:ident, $irq:ident) => { | 23 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 21 | impl sealed::Instance for peripherals::$type { | 24 | impl crate::timer::sealed::Instance for peripherals::$type { |
| 22 | fn regs(&self) -> &pac::timer0::RegisterBlock { | 25 | fn regs(&self) -> &pac::timer0::RegisterBlock { |
| 23 | unsafe { &*(pac::$type::ptr() as *const pac::timer0::RegisterBlock) } | 26 | unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) } |
| 24 | } | 27 | } |
| 25 | } | 28 | } |
| 26 | impl Instance for peripherals::$type { | 29 | impl crate::timer::Instance for peripherals::$type { |
| 27 | type Interrupt = interrupt::$irq; | 30 | type Interrupt = crate::interrupt::$irq; |
| 28 | } | 31 | } |
| 29 | }; | 32 | }; |
| 30 | ($type:ident, $irq:ident, extended) => { | 33 | ($type:ident, $pac_type:ident, $irq:ident, extended) => { |
| 31 | impl_instance!($type, $irq); | 34 | impl_timer!($type, $pac_type, $irq); |
| 32 | impl sealed::ExtendedInstance for peripherals::$type {} | 35 | impl crate::timer::sealed::ExtendedInstance for peripherals::$type {} |
| 33 | impl ExtendedInstance for peripherals::$type {} | 36 | impl crate::timer::ExtendedInstance for peripherals::$type {} |
| 34 | }; | 37 | }; |
| 35 | } | 38 | } |
| 36 | |||
| 37 | impl_instance!(TIMER0, TIMER0); | ||
| 38 | impl_instance!(TIMER1, TIMER1); | ||
| 39 | impl_instance!(TIMER2, TIMER2); | ||
| 40 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | ||
| 41 | impl_instance!(TIMER3, TIMER3, extended); | ||
| 42 | #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] | ||
| 43 | impl_instance!(TIMER4, TIMER4, extended); | ||
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs new file mode 100644 index 000000000..3e0fbc3d0 --- /dev/null +++ b/embassy-nrf/src/twim.rs | |||
| @@ -0,0 +1,531 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | //! HAL interface to the TWIM peripheral. | ||
| 4 | //! | ||
| 5 | //! See product specification: | ||
| 6 | //! | ||
| 7 | //! - nRF52832: Section 33 | ||
| 8 | //! - nRF52840: Section 6.31 | ||
| 9 | use core::marker::PhantomData; | ||
| 10 | use core::sync::atomic::{compiler_fence, Ordering::SeqCst}; | ||
| 11 | use embassy::interrupt::{Interrupt, InterruptExt}; | ||
| 12 | use embassy::util::{AtomicWaker, Unborrow}; | ||
| 13 | use embassy_extras::unborrow; | ||
| 14 | |||
| 15 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | ||
| 16 | use crate::fmt::*; | ||
| 17 | use crate::gpio::Pin as GpioPin; | ||
| 18 | use crate::pac; | ||
| 19 | use crate::util::{slice_in_ram, slice_in_ram_or}; | ||
| 20 | |||
| 21 | pub enum Frequency { | ||
| 22 | #[doc = "26738688: 100 kbps"] | ||
| 23 | K100 = 26738688, | ||
| 24 | #[doc = "67108864: 250 kbps"] | ||
| 25 | K250 = 67108864, | ||
| 26 | #[doc = "104857600: 400 kbps"] | ||
| 27 | K400 = 104857600, | ||
| 28 | } | ||
| 29 | |||
| 30 | #[non_exhaustive] | ||
| 31 | pub struct Config { | ||
| 32 | pub frequency: Frequency, | ||
| 33 | } | ||
| 34 | |||
| 35 | impl Default for Config { | ||
| 36 | fn default() -> Self { | ||
| 37 | Self { | ||
| 38 | frequency: Frequency::K100, | ||
| 39 | } | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | /// Interface to a TWIM instance. | ||
| 44 | pub struct Twim<'d, T: Instance> { | ||
| 45 | peri: T, | ||
| 46 | irq: T::Interrupt, | ||
| 47 | phantom: PhantomData<&'d mut T>, | ||
| 48 | } | ||
| 49 | |||
| 50 | impl<'d, T: Instance> Twim<'d, T> { | ||
| 51 | pub fn new( | ||
| 52 | twim: impl Unborrow<Target = T> + 'd, | ||
| 53 | irq: impl Unborrow<Target = T::Interrupt> + 'd, | ||
| 54 | sda: impl Unborrow<Target = impl GpioPin> + 'd, | ||
| 55 | scl: impl Unborrow<Target = impl GpioPin> + 'd, | ||
| 56 | config: Config, | ||
| 57 | ) -> Self { | ||
| 58 | unborrow!(twim, irq, sda, scl); | ||
| 59 | |||
| 60 | let r = T::regs(); | ||
| 61 | |||
| 62 | // Configure pins | ||
| 63 | sda.conf().write(|w| { | ||
| 64 | w.dir().input(); | ||
| 65 | w.input().connect(); | ||
| 66 | w.pull().pullup(); | ||
| 67 | w.drive().s0d1(); | ||
| 68 | w | ||
| 69 | }); | ||
| 70 | scl.conf().write(|w| { | ||
| 71 | w.dir().input(); | ||
| 72 | w.input().connect(); | ||
| 73 | w.pull().pullup(); | ||
| 74 | w.drive().s0d1(); | ||
| 75 | w | ||
| 76 | }); | ||
| 77 | |||
| 78 | // Select pins. | ||
| 79 | r.psel.sda.write(|w| unsafe { w.bits(sda.psel_bits()) }); | ||
| 80 | r.psel.scl.write(|w| unsafe { w.bits(scl.psel_bits()) }); | ||
| 81 | |||
| 82 | // Enable TWIM instance. | ||
| 83 | r.enable.write(|w| w.enable().enabled()); | ||
| 84 | |||
| 85 | // Configure frequency. | ||
| 86 | r.frequency | ||
| 87 | .write(|w| unsafe { w.frequency().bits(config.frequency as u32) }); | ||
| 88 | |||
| 89 | // Disable all events interrupts | ||
| 90 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | ||
| 91 | |||
| 92 | irq.set_handler(Self::on_interrupt); | ||
| 93 | irq.unpend(); | ||
| 94 | irq.enable(); | ||
| 95 | |||
| 96 | Self { | ||
| 97 | peri: twim, | ||
| 98 | irq, | ||
| 99 | phantom: PhantomData, | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | fn on_interrupt(_: *mut ()) { | ||
| 104 | let r = T::regs(); | ||
| 105 | let s = T::state(); | ||
| 106 | |||
| 107 | if r.events_stopped.read().bits() != 0 { | ||
| 108 | s.end_waker.wake(); | ||
| 109 | r.intenclr.write(|w| w.stopped().clear()); | ||
| 110 | } | ||
| 111 | if r.events_error.read().bits() != 0 { | ||
| 112 | s.end_waker.wake(); | ||
| 113 | r.intenclr.write(|w| w.error().clear()); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | /// Set TX buffer, checking that it is in RAM and has suitable length. | ||
| 118 | unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { | ||
| 119 | slice_in_ram_or(buffer, Error::DMABufferNotInDataMemory)?; | ||
| 120 | |||
| 121 | if buffer.len() == 0 { | ||
| 122 | return Err(Error::TxBufferZeroLength); | ||
| 123 | } | ||
| 124 | if buffer.len() > EASY_DMA_SIZE { | ||
| 125 | return Err(Error::TxBufferTooLong); | ||
| 126 | } | ||
| 127 | |||
| 128 | let r = T::regs(); | ||
| 129 | |||
| 130 | r.txd.ptr.write(|w| | ||
| 131 | // We're giving the register a pointer to the stack. Since we're | ||
| 132 | // waiting for the I2C transaction to end before this stack pointer | ||
| 133 | // becomes invalid, there's nothing wrong here. | ||
| 134 | // | ||
| 135 | // The PTR field is a full 32 bits wide and accepts the full range | ||
| 136 | // of values. | ||
| 137 | w.ptr().bits(buffer.as_ptr() as u32)); | ||
| 138 | r.txd.maxcnt.write(|w| | ||
| 139 | // We're giving it the length of the buffer, so no danger of | ||
| 140 | // accessing invalid memory. We have verified that the length of the | ||
| 141 | // buffer fits in an `u8`, so the cast to `u8` is also fine. | ||
| 142 | // | ||
| 143 | // The MAXCNT field is 8 bits wide and accepts the full range of | ||
| 144 | // values. | ||
| 145 | w.maxcnt().bits(buffer.len() as _)); | ||
| 146 | |||
| 147 | Ok(()) | ||
| 148 | } | ||
| 149 | |||
| 150 | /// Set RX buffer, checking that it has suitable length. | ||
| 151 | unsafe fn set_rx_buffer(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | ||
| 152 | // NOTE: RAM slice check is not necessary, as a mutable | ||
| 153 | // slice can only be built from data located in RAM. | ||
| 154 | |||
| 155 | if buffer.len() == 0 { | ||
| 156 | return Err(Error::RxBufferZeroLength); | ||
| 157 | } | ||
| 158 | if buffer.len() > EASY_DMA_SIZE { | ||
| 159 | return Err(Error::RxBufferTooLong); | ||
| 160 | } | ||
| 161 | |||
| 162 | let r = T::regs(); | ||
| 163 | |||
| 164 | r.rxd.ptr.write(|w| | ||
| 165 | // We're giving the register a pointer to the stack. Since we're | ||
| 166 | // waiting for the I2C transaction to end before this stack pointer | ||
| 167 | // becomes invalid, there's nothing wrong here. | ||
| 168 | // | ||
| 169 | // The PTR field is a full 32 bits wide and accepts the full range | ||
| 170 | // of values. | ||
| 171 | w.ptr().bits(buffer.as_mut_ptr() as u32)); | ||
| 172 | r.rxd.maxcnt.write(|w| | ||
| 173 | // We're giving it the length of the buffer, so no danger of | ||
| 174 | // accessing invalid memory. We have verified that the length of the | ||
| 175 | // buffer fits in an `u8`, so the cast to the type of maxcnt | ||
| 176 | // is also fine. | ||
| 177 | // | ||
| 178 | // Note that that nrf52840 maxcnt is a wider | ||
| 179 | // type than a u8, so we use a `_` cast rather than a `u8` cast. | ||
| 180 | // The MAXCNT field is thus at least 8 bits wide and accepts the | ||
| 181 | // full range of values that fit in a `u8`. | ||
| 182 | w.maxcnt().bits(buffer.len() as _)); | ||
| 183 | |||
| 184 | Ok(()) | ||
| 185 | } | ||
| 186 | |||
| 187 | fn clear_errorsrc(&mut self) { | ||
| 188 | let r = T::regs(); | ||
| 189 | r.errorsrc | ||
| 190 | .write(|w| w.anack().bit(true).dnack().bit(true).overrun().bit(true)); | ||
| 191 | } | ||
| 192 | |||
| 193 | /// Get Error instance, if any occurred. | ||
| 194 | fn read_errorsrc(&self) -> Result<(), Error> { | ||
| 195 | let r = T::regs(); | ||
| 196 | |||
| 197 | let err = r.errorsrc.read(); | ||
| 198 | if err.anack().is_received() { | ||
| 199 | return Err(Error::AddressNack); | ||
| 200 | } | ||
| 201 | if err.dnack().is_received() { | ||
| 202 | return Err(Error::DataNack); | ||
| 203 | } | ||
| 204 | if err.overrun().is_received() { | ||
| 205 | return Err(Error::DataNack); | ||
| 206 | } | ||
| 207 | Ok(()) | ||
| 208 | } | ||
| 209 | |||
| 210 | /// Wait for stop or error | ||
| 211 | fn wait(&mut self) { | ||
| 212 | let r = T::regs(); | ||
| 213 | loop { | ||
| 214 | if r.events_stopped.read().bits() != 0 { | ||
| 215 | r.events_stopped.reset(); | ||
| 216 | break; | ||
| 217 | } | ||
| 218 | if r.events_error.read().bits() != 0 { | ||
| 219 | r.events_error.reset(); | ||
| 220 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | /// Write to an I2C slave. | ||
| 226 | /// | ||
| 227 | /// The buffer must have a length of at most 255 bytes on the nRF52832 | ||
| 228 | /// and at most 65535 bytes on the nRF52840. | ||
| 229 | pub fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { | ||
| 230 | let r = T::regs(); | ||
| 231 | |||
| 232 | // Conservative compiler fence to prevent optimizations that do not | ||
| 233 | // take in to account actions by DMA. The fence has been placed here, | ||
| 234 | // before any DMA action has started. | ||
| 235 | compiler_fence(SeqCst); | ||
| 236 | |||
| 237 | r.address.write(|w| unsafe { w.address().bits(address) }); | ||
| 238 | |||
| 239 | // Set up the DMA write. | ||
| 240 | unsafe { self.set_tx_buffer(buffer)? }; | ||
| 241 | |||
| 242 | // Clear events | ||
| 243 | r.events_stopped.reset(); | ||
| 244 | r.events_error.reset(); | ||
| 245 | r.events_lasttx.reset(); | ||
| 246 | self.clear_errorsrc(); | ||
| 247 | |||
| 248 | // Start write operation. | ||
| 249 | r.shorts.write(|w| w.lasttx_stop().enabled()); | ||
| 250 | r.tasks_starttx.write(|w| | ||
| 251 | // `1` is a valid value to write to task registers. | ||
| 252 | unsafe { w.bits(1) }); | ||
| 253 | |||
| 254 | self.wait(); | ||
| 255 | |||
| 256 | // Conservative compiler fence to prevent optimizations that do not | ||
| 257 | // take in to account actions by DMA. The fence has been placed here, | ||
| 258 | // after all possible DMA actions have completed. | ||
| 259 | compiler_fence(SeqCst); | ||
| 260 | |||
| 261 | self.read_errorsrc()?; | ||
| 262 | |||
| 263 | if r.txd.amount.read().bits() != buffer.len() as u32 { | ||
| 264 | return Err(Error::Transmit); | ||
| 265 | } | ||
| 266 | |||
| 267 | Ok(()) | ||
| 268 | } | ||
| 269 | |||
| 270 | /// Read from an I2C slave. | ||
| 271 | /// | ||
| 272 | /// The buffer must have a length of at most 255 bytes on the nRF52832 | ||
| 273 | /// and at most 65535 bytes on the nRF52840. | ||
| 274 | pub fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { | ||
| 275 | let r = T::regs(); | ||
| 276 | |||
| 277 | // Conservative compiler fence to prevent optimizations that do not | ||
| 278 | // take in to account actions by DMA. The fence has been placed here, | ||
| 279 | // before any DMA action has started. | ||
| 280 | compiler_fence(SeqCst); | ||
| 281 | |||
| 282 | r.address.write(|w| unsafe { w.address().bits(address) }); | ||
| 283 | |||
| 284 | // Set up the DMA read. | ||
| 285 | unsafe { self.set_rx_buffer(buffer)? }; | ||
| 286 | |||
| 287 | // Clear events | ||
| 288 | r.events_stopped.reset(); | ||
| 289 | r.events_error.reset(); | ||
| 290 | self.clear_errorsrc(); | ||
| 291 | |||
| 292 | // Start read operation. | ||
| 293 | r.shorts.write(|w| w.lastrx_stop().enabled()); | ||
| 294 | r.tasks_startrx.write(|w| | ||
| 295 | // `1` is a valid value to write to task registers. | ||
| 296 | unsafe { w.bits(1) }); | ||
| 297 | |||
| 298 | self.wait(); | ||
| 299 | |||
| 300 | // Conservative compiler fence to prevent optimizations that do not | ||
| 301 | // take in to account actions by DMA. The fence has been placed here, | ||
| 302 | // after all possible DMA actions have completed. | ||
| 303 | compiler_fence(SeqCst); | ||
| 304 | |||
| 305 | self.read_errorsrc()?; | ||
| 306 | |||
| 307 | if r.rxd.amount.read().bits() != buffer.len() as u32 { | ||
| 308 | return Err(Error::Receive); | ||
| 309 | } | ||
| 310 | |||
| 311 | Ok(()) | ||
| 312 | } | ||
| 313 | |||
| 314 | /// Write data to an I2C slave, then read data from the slave without | ||
| 315 | /// triggering a stop condition between the two. | ||
| 316 | /// | ||
| 317 | /// The buffers must have a length of at most 255 bytes on the nRF52832 | ||
| 318 | /// and at most 65535 bytes on the nRF52840. | ||
| 319 | pub fn write_then_read( | ||
| 320 | &mut self, | ||
| 321 | address: u8, | ||
| 322 | wr_buffer: &[u8], | ||
| 323 | rd_buffer: &mut [u8], | ||
| 324 | ) -> Result<(), Error> { | ||
| 325 | let r = T::regs(); | ||
| 326 | |||
| 327 | // Conservative compiler fence to prevent optimizations that do not | ||
| 328 | // take in to account actions by DMA. The fence has been placed here, | ||
| 329 | // before any DMA action has started. | ||
| 330 | compiler_fence(SeqCst); | ||
| 331 | |||
| 332 | r.address.write(|w| unsafe { w.address().bits(address) }); | ||
| 333 | |||
| 334 | // Set up DMA buffers. | ||
| 335 | unsafe { | ||
| 336 | self.set_tx_buffer(wr_buffer)?; | ||
| 337 | self.set_rx_buffer(rd_buffer)?; | ||
| 338 | } | ||
| 339 | |||
| 340 | // Clear events | ||
| 341 | r.events_stopped.reset(); | ||
| 342 | r.events_error.reset(); | ||
| 343 | self.clear_errorsrc(); | ||
| 344 | |||
| 345 | // Start write+read operation. | ||
| 346 | r.shorts.write(|w| { | ||
| 347 | w.lasttx_startrx().enabled(); | ||
| 348 | w.lastrx_stop().enabled(); | ||
| 349 | w | ||
| 350 | }); | ||
| 351 | // `1` is a valid value to write to task registers. | ||
| 352 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | ||
| 353 | |||
| 354 | self.wait(); | ||
| 355 | |||
| 356 | // Conservative compiler fence to prevent optimizations that do not | ||
| 357 | // take in to account actions by DMA. The fence has been placed here, | ||
| 358 | // after all possible DMA actions have completed. | ||
| 359 | compiler_fence(SeqCst); | ||
| 360 | |||
| 361 | self.read_errorsrc()?; | ||
| 362 | |||
| 363 | let bad_write = r.txd.amount.read().bits() != wr_buffer.len() as u32; | ||
| 364 | let bad_read = r.rxd.amount.read().bits() != rd_buffer.len() as u32; | ||
| 365 | |||
| 366 | if bad_write { | ||
| 367 | return Err(Error::Transmit); | ||
| 368 | } | ||
| 369 | |||
| 370 | if bad_read { | ||
| 371 | return Err(Error::Receive); | ||
| 372 | } | ||
| 373 | |||
| 374 | Ok(()) | ||
| 375 | } | ||
| 376 | |||
| 377 | /// Copy data into RAM and write to an I2C slave. | ||
| 378 | /// | ||
| 379 | /// The write buffer must have a length of at most 255 bytes on the nRF52832 | ||
| 380 | /// and at most 1024 bytes on the nRF52840. | ||
| 381 | pub fn copy_write(&mut self, address: u8, wr_buffer: &[u8]) -> Result<(), Error> { | ||
| 382 | if wr_buffer.len() > FORCE_COPY_BUFFER_SIZE { | ||
| 383 | return Err(Error::TxBufferTooLong); | ||
| 384 | } | ||
| 385 | |||
| 386 | // Copy to RAM | ||
| 387 | let wr_ram_buffer = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; | ||
| 388 | wr_ram_buffer.copy_from_slice(wr_buffer); | ||
| 389 | |||
| 390 | self.write(address, wr_ram_buffer) | ||
| 391 | } | ||
| 392 | |||
| 393 | /// Copy data into RAM and write to an I2C slave, then read data from the slave without | ||
| 394 | /// triggering a stop condition between the two. | ||
| 395 | /// | ||
| 396 | /// The write buffer must have a length of at most 255 bytes on the nRF52832 | ||
| 397 | /// and at most 1024 bytes on the nRF52840. | ||
| 398 | /// | ||
| 399 | /// The read buffer must have a length of at most 255 bytes on the nRF52832 | ||
| 400 | /// and at most 65535 bytes on the nRF52840. | ||
| 401 | pub fn copy_write_then_read( | ||
| 402 | &mut self, | ||
| 403 | address: u8, | ||
| 404 | wr_buffer: &[u8], | ||
| 405 | rd_buffer: &mut [u8], | ||
| 406 | ) -> Result<(), Error> { | ||
| 407 | if wr_buffer.len() > FORCE_COPY_BUFFER_SIZE { | ||
| 408 | return Err(Error::TxBufferTooLong); | ||
| 409 | } | ||
| 410 | |||
| 411 | // Copy to RAM | ||
| 412 | let wr_ram_buffer = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; | ||
| 413 | wr_ram_buffer.copy_from_slice(wr_buffer); | ||
| 414 | |||
| 415 | self.write_then_read(address, wr_ram_buffer, rd_buffer) | ||
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | impl<'a, T: Instance> Drop for Twim<'a, T> { | ||
| 420 | fn drop(&mut self) { | ||
| 421 | info!("twim drop"); | ||
| 422 | |||
| 423 | // TODO when implementing async here, check for abort | ||
| 424 | |||
| 425 | // disable! | ||
| 426 | let r = T::regs(); | ||
| 427 | r.enable.write(|w| w.enable().disabled()); | ||
| 428 | |||
| 429 | info!("uarte drop: done"); | ||
| 430 | |||
| 431 | // TODO: disable pins | ||
| 432 | } | ||
| 433 | } | ||
| 434 | |||
| 435 | impl<'a, T: Instance> embedded_hal::blocking::i2c::Write for Twim<'a, T> { | ||
| 436 | type Error = Error; | ||
| 437 | |||
| 438 | fn write<'w>(&mut self, addr: u8, bytes: &'w [u8]) -> Result<(), Error> { | ||
| 439 | if slice_in_ram(bytes) { | ||
| 440 | self.write(addr, bytes) | ||
| 441 | } else { | ||
| 442 | let buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..]; | ||
| 443 | for chunk in bytes.chunks(FORCE_COPY_BUFFER_SIZE) { | ||
| 444 | buf[..chunk.len()].copy_from_slice(chunk); | ||
| 445 | self.write(addr, &buf[..chunk.len()])?; | ||
| 446 | } | ||
| 447 | Ok(()) | ||
| 448 | } | ||
| 449 | } | ||
| 450 | } | ||
| 451 | |||
| 452 | impl<'a, T: Instance> embedded_hal::blocking::i2c::Read for Twim<'a, T> { | ||
| 453 | type Error = Error; | ||
| 454 | |||
| 455 | fn read<'w>(&mut self, addr: u8, bytes: &'w mut [u8]) -> Result<(), Error> { | ||
| 456 | self.read(addr, bytes) | ||
| 457 | } | ||
| 458 | } | ||
| 459 | |||
| 460 | impl<'a, T: Instance> embedded_hal::blocking::i2c::WriteRead for Twim<'a, T> { | ||
| 461 | type Error = Error; | ||
| 462 | |||
| 463 | fn write_read<'w>( | ||
| 464 | &mut self, | ||
| 465 | addr: u8, | ||
| 466 | bytes: &'w [u8], | ||
| 467 | buffer: &'w mut [u8], | ||
| 468 | ) -> Result<(), Error> { | ||
| 469 | if slice_in_ram(bytes) { | ||
| 470 | self.write_then_read(addr, bytes, buffer) | ||
| 471 | } else { | ||
| 472 | self.copy_write_then_read(addr, bytes, buffer) | ||
| 473 | } | ||
| 474 | } | ||
| 475 | } | ||
| 476 | |||
| 477 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | ||
| 478 | pub enum Error { | ||
| 479 | TxBufferTooLong, | ||
| 480 | RxBufferTooLong, | ||
| 481 | TxBufferZeroLength, | ||
| 482 | RxBufferZeroLength, | ||
| 483 | Transmit, | ||
| 484 | Receive, | ||
| 485 | DMABufferNotInDataMemory, | ||
| 486 | AddressNack, | ||
| 487 | DataNack, | ||
| 488 | Overrun, | ||
| 489 | } | ||
| 490 | |||
| 491 | pub(crate) mod sealed { | ||
| 492 | use super::*; | ||
| 493 | |||
| 494 | pub struct State { | ||
| 495 | pub end_waker: AtomicWaker, | ||
| 496 | } | ||
| 497 | |||
| 498 | impl State { | ||
| 499 | pub const fn new() -> Self { | ||
| 500 | Self { | ||
| 501 | end_waker: AtomicWaker::new(), | ||
| 502 | } | ||
| 503 | } | ||
| 504 | } | ||
| 505 | |||
| 506 | pub trait Instance { | ||
| 507 | fn regs() -> &'static pac::twim0::RegisterBlock; | ||
| 508 | fn state() -> &'static State; | ||
| 509 | } | ||
| 510 | } | ||
| 511 | |||
| 512 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { | ||
| 513 | type Interrupt: Interrupt; | ||
| 514 | } | ||
| 515 | |||
| 516 | macro_rules! impl_twim { | ||
| 517 | ($type:ident, $pac_type:ident, $irq:ident) => { | ||
| 518 | impl crate::twim::sealed::Instance for peripherals::$type { | ||
| 519 | fn regs() -> &'static pac::twim0::RegisterBlock { | ||
| 520 | unsafe { &*pac::$pac_type::ptr() } | ||
| 521 | } | ||
| 522 | fn state() -> &'static crate::twim::sealed::State { | ||
| 523 | static STATE: crate::twim::sealed::State = crate::twim::sealed::State::new(); | ||
| 524 | &STATE | ||
| 525 | } | ||
| 526 | } | ||
| 527 | impl crate::twim::Instance for peripherals::$type { | ||
| 528 | type Interrupt = crate::interrupt::$irq; | ||
| 529 | } | ||
| 530 | }; | ||
| 531 | } | ||
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 04907fb56..494110bee 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | //! Async UART | 3 | //! Async UART |
| 2 | 4 | ||
| 3 | use core::future::Future; | 5 | use core::future::Future; |
| @@ -10,6 +12,7 @@ use embassy::util::{AtomicWaker, OnDrop, Unborrow}; | |||
| 10 | use embassy_extras::unborrow; | 12 | use embassy_extras::unborrow; |
| 11 | use futures::future::poll_fn; | 13 | use futures::future::poll_fn; |
| 12 | 14 | ||
| 15 | use crate::chip::EASY_DMA_SIZE; | ||
| 13 | use crate::fmt::{assert, panic, *}; | 16 | use crate::fmt::{assert, panic, *}; |
| 14 | use crate::gpio::sealed::Pin as _; | 17 | use crate::gpio::sealed::Pin as _; |
| 15 | use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; | 18 | use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; |
| @@ -18,7 +21,6 @@ use crate::interrupt::Interrupt; | |||
| 18 | use crate::pac; | 21 | use crate::pac; |
| 19 | use crate::peripherals; | 22 | use crate::peripherals; |
| 20 | use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; | 23 | use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; |
| 21 | use crate::target_constants::EASY_DMA_SIZE; | ||
| 22 | use crate::timer::Instance as TimerInstance; | 24 | use crate::timer::Instance as TimerInstance; |
| 23 | 25 | ||
| 24 | // Re-export SVD variants to allow user to directly set values. | 26 | // Re-export SVD variants to allow user to directly set values. |
| @@ -445,7 +447,7 @@ impl<'d, U: Instance, T: TimerInstance> Write for UarteWithIdle<'d, U, T> { | |||
| 445 | } | 447 | } |
| 446 | } | 448 | } |
| 447 | 449 | ||
| 448 | mod sealed { | 450 | pub(crate) mod sealed { |
| 449 | use super::*; | 451 | use super::*; |
| 450 | 452 | ||
| 451 | pub struct State { | 453 | pub struct State { |
| @@ -467,27 +469,23 @@ mod sealed { | |||
| 467 | } | 469 | } |
| 468 | } | 470 | } |
| 469 | 471 | ||
| 470 | pub trait Instance: sealed::Instance + 'static { | 472 | pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { |
| 471 | type Interrupt: Interrupt; | 473 | type Interrupt: Interrupt; |
| 472 | } | 474 | } |
| 473 | 475 | ||
| 474 | macro_rules! impl_instance { | 476 | macro_rules! impl_uarte { |
| 475 | ($type:ident, $irq:ident) => { | 477 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 476 | impl sealed::Instance for peripherals::$type { | 478 | impl crate::uarte::sealed::Instance for peripherals::$type { |
| 477 | fn regs() -> &'static pac::uarte0::RegisterBlock { | 479 | fn regs() -> &'static pac::uarte0::RegisterBlock { |
| 478 | unsafe { &*pac::$type::ptr() } | 480 | unsafe { &*pac::$pac_type::ptr() } |
| 479 | } | 481 | } |
| 480 | fn state() -> &'static sealed::State { | 482 | fn state() -> &'static crate::uarte::sealed::State { |
| 481 | static STATE: sealed::State = sealed::State::new(); | 483 | static STATE: crate::uarte::sealed::State = crate::uarte::sealed::State::new(); |
| 482 | &STATE | 484 | &STATE |
| 483 | } | 485 | } |
| 484 | } | 486 | } |
| 485 | impl Instance for peripherals::$type { | 487 | impl crate::uarte::Instance for peripherals::$type { |
| 486 | type Interrupt = interrupt::$irq; | 488 | type Interrupt = crate::interrupt::$irq; |
| 487 | } | 489 | } |
| 488 | }; | 490 | }; |
| 489 | } | 491 | } |
| 490 | |||
| 491 | impl_instance!(UARTE0, UARTE0_UART0); | ||
| 492 | #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] | ||
| 493 | impl_instance!(UARTE1, UARTE1); | ||
diff --git a/embassy-nrf/src/util.rs b/embassy-nrf/src/util.rs new file mode 100644 index 000000000..7c3974eeb --- /dev/null +++ b/embassy-nrf/src/util.rs | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | const SRAM_LOWER: usize = 0x2000_0000; | ||
| 2 | const SRAM_UPPER: usize = 0x3000_0000; | ||
| 3 | |||
| 4 | /// Does this slice reside entirely within RAM? | ||
| 5 | pub(crate) fn slice_in_ram(slice: &[u8]) -> bool { | ||
| 6 | let ptr = slice.as_ptr() as usize; | ||
| 7 | ptr >= SRAM_LOWER && (ptr + slice.len()) < SRAM_UPPER | ||
| 8 | } | ||
| 9 | |||
| 10 | /// Return an error if slice is not in RAM. | ||
| 11 | #[cfg(not(feature = "51"))] | ||
| 12 | pub(crate) fn slice_in_ram_or<T>(slice: &[u8], err: T) -> Result<(), T> { | ||
| 13 | if slice.len() == 0 || slice_in_ram(slice) { | ||
| 14 | Ok(()) | ||
| 15 | } else { | ||
| 16 | Err(err) | ||
| 17 | } | ||
| 18 | } | ||
diff --git a/embassy-rp-examples/src/bin/blinky.rs b/embassy-rp-examples/src/bin/blinky.rs index 34e3cafc3..e42999912 100644 --- a/embassy-rp-examples/src/bin/blinky.rs +++ b/embassy-rp-examples/src/bin/blinky.rs | |||
| @@ -16,9 +16,7 @@ use embedded_hal::digital::v2::OutputPin; | |||
| 16 | use gpio::{Level, Output}; | 16 | use gpio::{Level, Output}; |
| 17 | 17 | ||
| 18 | #[embassy::main] | 18 | #[embassy::main] |
| 19 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 20 | let p = unwrap!(Peripherals::take()); | ||
| 21 | |||
| 22 | let mut led = Output::new(p.PIN_25, Level::Low); | 20 | let mut led = Output::new(p.PIN_25, Level::Low); |
| 23 | 21 | ||
| 24 | loop { | 22 | loop { |
diff --git a/embassy-rp-examples/src/bin/button.rs b/embassy-rp-examples/src/bin/button.rs index 77d4c57a9..007d07a36 100644 --- a/embassy-rp-examples/src/bin/button.rs +++ b/embassy-rp-examples/src/bin/button.rs | |||
| @@ -16,9 +16,7 @@ use embassy_rp::Peripherals; | |||
| 16 | use embedded_hal::digital::v2::{InputPin, OutputPin}; | 16 | use embedded_hal::digital::v2::{InputPin, OutputPin}; |
| 17 | 17 | ||
| 18 | #[embassy::main] | 18 | #[embassy::main] |
| 19 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 20 | let p = unwrap!(Peripherals::take()); | ||
| 21 | |||
| 22 | let button = Input::new(p.PIN_28, Pull::Up); | 20 | let button = Input::new(p.PIN_28, Pull::Up); |
| 23 | let mut led = Output::new(p.PIN_25, Level::Low); | 21 | let mut led = Output::new(p.PIN_25, Level::Low); |
| 24 | 22 | ||
diff --git a/embassy-rp-examples/src/bin/uart.rs b/embassy-rp-examples/src/bin/uart.rs index cd72d5312..82bd4cb6a 100644 --- a/embassy-rp-examples/src/bin/uart.rs +++ b/embassy-rp-examples/src/bin/uart.rs | |||
| @@ -14,9 +14,7 @@ use embassy::executor::Spawner; | |||
| 14 | use embassy_rp::{uart, Peripherals}; | 14 | use embassy_rp::{uart, Peripherals}; |
| 15 | 15 | ||
| 16 | #[embassy::main] | 16 | #[embassy::main] |
| 17 | async fn main(_spanwer: Spawner) { | 17 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 18 | let p = unwrap!(Peripherals::take()); | ||
| 19 | |||
| 20 | let config = uart::Config::default(); | 18 | let config = uart::Config::default(); |
| 21 | let mut uart = uart::Uart::new(p.UART0, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, config); | 19 | let mut uart = uart::Uart::new(p.UART0, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, config); |
| 22 | uart.send("Hello World!\r\n".as_bytes()); | 20 | uart.send("Hello World!\r\n".as_bytes()); |
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index f64464d13..f1a045987 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs | |||
| @@ -15,7 +15,6 @@ pub mod dma; | |||
| 15 | pub mod gpio; | 15 | pub mod gpio; |
| 16 | pub mod pll; | 16 | pub mod pll; |
| 17 | pub mod resets; | 17 | pub mod resets; |
| 18 | pub mod system; | ||
| 19 | pub mod uart; | 18 | pub mod uart; |
| 20 | 19 | ||
| 21 | embassy_extras::peripherals! { | 20 | embassy_extras::peripherals! { |
| @@ -72,3 +71,105 @@ embassy_extras::peripherals! { | |||
| 72 | DMA_CH10, | 71 | DMA_CH10, |
| 73 | DMA_CH11, | 72 | DMA_CH11, |
| 74 | } | 73 | } |
| 74 | |||
| 75 | #[link_section = ".boot2"] | ||
| 76 | #[used] | ||
| 77 | static BOOT2: [u8; 256] = *include_bytes!("boot2.bin"); | ||
| 78 | |||
| 79 | pub mod config { | ||
| 80 | #[non_exhaustive] | ||
| 81 | pub struct Config {} | ||
| 82 | |||
| 83 | impl Default for Config { | ||
| 84 | fn default() -> Self { | ||
| 85 | Self {} | ||
| 86 | } | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | pub fn init(config: config::Config) -> Peripherals { | ||
| 91 | // Do this first, so that it panics if user is calling `init` a second time | ||
| 92 | // before doing anything important. | ||
| 93 | let peripherals = Peripherals::take(); | ||
| 94 | |||
| 95 | // Now reset all the peripherals, except QSPI and XIP (we're using those | ||
| 96 | // to execute from external flash!) | ||
| 97 | |||
| 98 | let resets = resets::Resets::new(); | ||
| 99 | |||
| 100 | // Reset everything except: | ||
| 101 | // - QSPI (we're using it to run this code!) | ||
| 102 | // - PLLs (it may be suicide if that's what's clocking us) | ||
| 103 | let mut peris = resets::ALL_PERIPHERALS; | ||
| 104 | peris.set_io_qspi(false); | ||
| 105 | peris.set_pads_qspi(false); | ||
| 106 | peris.set_pll_sys(false); | ||
| 107 | peris.set_pll_usb(false); | ||
| 108 | resets.reset(peris); | ||
| 109 | |||
| 110 | let mut peris = resets::ALL_PERIPHERALS; | ||
| 111 | peris.set_adc(false); | ||
| 112 | peris.set_rtc(false); | ||
| 113 | peris.set_spi0(false); | ||
| 114 | peris.set_spi1(false); | ||
| 115 | peris.set_uart0(false); | ||
| 116 | peris.set_uart1(false); | ||
| 117 | peris.set_usbctrl(false); | ||
| 118 | resets.unreset_wait(peris); | ||
| 119 | |||
| 120 | unsafe { | ||
| 121 | // xosc 12 mhz | ||
| 122 | pac::WATCHDOG.tick().write(|w| { | ||
| 123 | w.set_cycles(XOSC_MHZ as u16); | ||
| 124 | w.set_enable(true); | ||
| 125 | }); | ||
| 126 | |||
| 127 | pac::CLOCKS | ||
| 128 | .clk_sys_resus_ctrl() | ||
| 129 | .write_value(pac::clocks::regs::ClkSysResusCtrl(0)); | ||
| 130 | |||
| 131 | // Enable XOSC | ||
| 132 | // TODO extract to HAL module | ||
| 133 | const XOSC_MHZ: u32 = 12; | ||
| 134 | pac::XOSC | ||
| 135 | .ctrl() | ||
| 136 | .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ)); | ||
| 137 | |||
| 138 | let startup_delay = (((XOSC_MHZ * 1_000_000) / 1000) + 128) / 256; | ||
| 139 | pac::XOSC | ||
| 140 | .startup() | ||
| 141 | .write(|w| w.set_delay(startup_delay as u16)); | ||
| 142 | pac::XOSC.ctrl().write(|w| { | ||
| 143 | w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ); | ||
| 144 | w.set_enable(pac::xosc::vals::CtrlEnable::ENABLE); | ||
| 145 | }); | ||
| 146 | while !pac::XOSC.status().read().stable() {} | ||
| 147 | |||
| 148 | // Before we touch PLLs, switch sys and ref cleanly away from their aux sources. | ||
| 149 | pac::CLOCKS | ||
| 150 | .clk_sys_ctrl() | ||
| 151 | .modify(|w| w.set_src(pac::clocks::vals::ClkSysCtrlSrc::CLK_REF)); | ||
| 152 | while pac::CLOCKS.clk_sys_selected().read() != 1 {} | ||
| 153 | pac::CLOCKS | ||
| 154 | .clk_ref_ctrl() | ||
| 155 | .modify(|w| w.set_src(pac::clocks::vals::ClkRefCtrlSrc::ROSC_CLKSRC_PH)); | ||
| 156 | while pac::CLOCKS.clk_ref_selected().read() != 1 {} | ||
| 157 | |||
| 158 | let mut peris = resets::Peripherals(0); | ||
| 159 | peris.set_pll_sys(true); | ||
| 160 | peris.set_pll_usb(true); | ||
| 161 | resets.reset(peris); | ||
| 162 | resets.unreset_wait(peris); | ||
| 163 | |||
| 164 | pll::PLL::new(pll::PllSys).configure(1, 1500_000_000, 6, 2); | ||
| 165 | pll::PLL::new(pll::PllUsb).configure(1, 480_000_000, 5, 2); | ||
| 166 | |||
| 167 | // Activate peripheral clock and take external oscillator as input | ||
| 168 | pac::CLOCKS.clk_peri_ctrl().write(|w| { | ||
| 169 | w.set_enable(true); | ||
| 170 | w.set_auxsrc(pac::clocks::vals::ClkPeriCtrlAuxsrc::XOSC_CLKSRC); | ||
| 171 | }); | ||
| 172 | } | ||
| 173 | |||
| 174 | peripherals | ||
| 175 | } | ||
diff --git a/embassy-rp/src/system.rs b/embassy-rp/src/system.rs deleted file mode 100644 index ba1396433..000000000 --- a/embassy-rp/src/system.rs +++ /dev/null | |||
| @@ -1,94 +0,0 @@ | |||
| 1 | use crate::{pac, pll, resets}; | ||
| 2 | |||
| 3 | #[link_section = ".boot2"] | ||
| 4 | #[used] | ||
| 5 | pub static BOOT2: [u8; 256] = *include_bytes!("boot2.bin"); | ||
| 6 | |||
| 7 | #[non_exhaustive] | ||
| 8 | pub struct Config {} | ||
| 9 | |||
| 10 | impl Default for Config { | ||
| 11 | fn default() -> Self { | ||
| 12 | Self {} | ||
| 13 | } | ||
| 14 | } | ||
| 15 | |||
| 16 | /// safety: must only call once. | ||
| 17 | pub unsafe fn configure(_config: Config) { | ||
| 18 | // Now reset all the peripherals, except QSPI and XIP (we're using those | ||
| 19 | // to execute from external flash!) | ||
| 20 | |||
| 21 | let resets = resets::Resets::new(); | ||
| 22 | |||
| 23 | // Reset everything except: | ||
| 24 | // - QSPI (we're using it to run this code!) | ||
| 25 | // - PLLs (it may be suicide if that's what's clocking us) | ||
| 26 | let mut peris = resets::ALL_PERIPHERALS; | ||
| 27 | peris.set_io_qspi(false); | ||
| 28 | peris.set_pads_qspi(false); | ||
| 29 | peris.set_pll_sys(false); | ||
| 30 | peris.set_pll_usb(false); | ||
| 31 | resets.reset(peris); | ||
| 32 | |||
| 33 | let mut peris = resets::ALL_PERIPHERALS; | ||
| 34 | peris.set_adc(false); | ||
| 35 | peris.set_rtc(false); | ||
| 36 | peris.set_spi0(false); | ||
| 37 | peris.set_spi1(false); | ||
| 38 | peris.set_uart0(false); | ||
| 39 | peris.set_uart1(false); | ||
| 40 | peris.set_usbctrl(false); | ||
| 41 | resets.unreset_wait(peris); | ||
| 42 | |||
| 43 | // xosc 12 mhz | ||
| 44 | pac::WATCHDOG.tick().write(|w| { | ||
| 45 | w.set_cycles(XOSC_MHZ as u16); | ||
| 46 | w.set_enable(true); | ||
| 47 | }); | ||
| 48 | |||
| 49 | pac::CLOCKS | ||
| 50 | .clk_sys_resus_ctrl() | ||
| 51 | .write_value(pac::clocks::regs::ClkSysResusCtrl(0)); | ||
| 52 | |||
| 53 | // Enable XOSC | ||
| 54 | // TODO extract to HAL module | ||
| 55 | const XOSC_MHZ: u32 = 12; | ||
| 56 | pac::XOSC | ||
| 57 | .ctrl() | ||
| 58 | .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ)); | ||
| 59 | |||
| 60 | let startup_delay = (((XOSC_MHZ * 1_000_000) / 1000) + 128) / 256; | ||
| 61 | pac::XOSC | ||
| 62 | .startup() | ||
| 63 | .write(|w| w.set_delay(startup_delay as u16)); | ||
| 64 | pac::XOSC.ctrl().write(|w| { | ||
| 65 | w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ); | ||
| 66 | w.set_enable(pac::xosc::vals::CtrlEnable::ENABLE); | ||
| 67 | }); | ||
| 68 | while !pac::XOSC.status().read().stable() {} | ||
| 69 | |||
| 70 | // Before we touch PLLs, switch sys and ref cleanly away from their aux sources. | ||
| 71 | pac::CLOCKS | ||
| 72 | .clk_sys_ctrl() | ||
| 73 | .modify(|w| w.set_src(pac::clocks::vals::ClkSysCtrlSrc::CLK_REF)); | ||
| 74 | while pac::CLOCKS.clk_sys_selected().read() != 1 {} | ||
| 75 | pac::CLOCKS | ||
| 76 | .clk_ref_ctrl() | ||
| 77 | .modify(|w| w.set_src(pac::clocks::vals::ClkRefCtrlSrc::ROSC_CLKSRC_PH)); | ||
| 78 | while pac::CLOCKS.clk_ref_selected().read() != 1 {} | ||
| 79 | |||
| 80 | let mut peris = resets::Peripherals(0); | ||
| 81 | peris.set_pll_sys(true); | ||
| 82 | peris.set_pll_usb(true); | ||
| 83 | resets.reset(peris); | ||
| 84 | resets.unreset_wait(peris); | ||
| 85 | |||
| 86 | pll::PLL::new(pll::PllSys).configure(1, 1500_000_000, 6, 2); | ||
| 87 | pll::PLL::new(pll::PllUsb).configure(1, 480_000_000, 5, 2); | ||
| 88 | |||
| 89 | // Activate peripheral clock and take external oscillator as input | ||
| 90 | pac::CLOCKS.clk_peri_ctrl().write(|w| { | ||
| 91 | w.set_enable(true); | ||
| 92 | w.set_auxsrc(pac::clocks::vals::ClkPeriCtrlAuxsrc::XOSC_CLKSRC); | ||
| 93 | }); | ||
| 94 | } | ||
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 | } | ||
