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