aboutsummaryrefslogtreecommitdiff
path: root/embassy-macros/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-05-17 01:04:13 +0200
committerGitHub <[email protected]>2021-05-17 01:04:13 +0200
commit35d05a4214e035bbb6da380c38c0a90b285887f2 (patch)
treede9f18e1f858e62b03c0c465135bea3f57d926ac /embassy-macros/src
parentcd4111736c0384b1ef957df7f6aa51e3727c29b2 (diff)
parenta5ad79927ecaa9d6cd7bd96e015b66afa9201d84 (diff)
Merge pull request #174 from embassy-rs/nrf-neo
nRF-neo
Diffstat (limited to 'embassy-macros/src')
-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
4 files changed, 75 insertions, 44 deletions
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 }