diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-05-17 01:04:13 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-05-17 01:04:13 +0200 |
| commit | 35d05a4214e035bbb6da380c38c0a90b285887f2 (patch) | |
| tree | de9f18e1f858e62b03c0c465135bea3f57d926ac /embassy-macros/src | |
| parent | cd4111736c0384b1ef957df7f6aa51e3727c29b2 (diff) | |
| parent | a5ad79927ecaa9d6cd7bd96e015b66afa9201d84 (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.rs | 2 | ||||
| -rw-r--r-- | embassy-macros/src/chip/rp.rs | 2 | ||||
| -rw-r--r-- | embassy-macros/src/chip/stm32.rs | 28 | ||||
| -rw-r--r-- | embassy-macros/src/lib.rs | 87 |
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 @@ | |||
| 1 | use crate::path::ModulePrefix; | ||
| 2 | use proc_macro2::TokenStream; | ||
| 3 | use quote::quote; | ||
| 4 | |||
| 5 | pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream { | ||
| 6 | let embassy_path = embassy_prefix.append("embassy").path(); | ||
| 7 | let embassy_stm32_path = embassy_prefix.append("embassy_stm32").path(); | ||
| 8 | |||
| 9 | quote!( | ||
| 10 | use #embassy_stm32_path::{rtc, interrupt, Peripherals, pac, hal::rcc::RccExt, hal::time::U32Ext}; | ||
| 11 | |||
| 12 | unsafe { #embassy_stm32_path::system::configure(#config) }; | ||
| 13 | |||
| 14 | let (dp, clocks) = Peripherals::take().unwrap(); | ||
| 15 | |||
| 16 | let mut rtc = rtc::RTC::new(dp.TIM2, interrupt::take!(TIM2), clocks); | ||
| 17 | let rtc = unsafe { make_static(&mut rtc) }; | ||
| 18 | rtc.start(); | ||
| 19 | let mut alarm = rtc.alarm1(); | ||
| 20 | |||
| 21 | unsafe { #embassy_path::time::set_clock(rtc) }; | ||
| 22 | |||
| 23 | let alarm = unsafe { make_static(&mut alarm) }; | ||
| 24 | executor.set_alarm(alarm); | ||
| 25 | |||
| 26 | unsafe { Peripherals::set_peripherals(clocks) }; | ||
| 27 | ) | ||
| 28 | } | ||
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs index 64411f5b4..dc234cd6d 100644 --- a/embassy-macros/src/lib.rs +++ b/embassy-macros/src/lib.rs | |||
| @@ -3,9 +3,13 @@ | |||
| 3 | extern crate proc_macro; | 3 | extern crate proc_macro; |
| 4 | 4 | ||
| 5 | use darling::FromMeta; | 5 | use darling::FromMeta; |
| 6 | use proc_macro::{Span, TokenStream}; | 6 | use proc_macro::TokenStream; |
| 7 | use proc_macro2::Span; | ||
| 7 | use quote::{format_ident, quote}; | 8 | use quote::{format_ident, quote}; |
| 9 | use std::iter; | ||
| 8 | use syn::spanned::Spanned; | 10 | use syn::spanned::Spanned; |
| 11 | use syn::{parse, Type, Visibility}; | ||
| 12 | use syn::{ItemFn, ReturnType}; | ||
| 9 | 13 | ||
| 10 | mod path; | 14 | mod path; |
| 11 | 15 | ||
| @@ -58,10 +62,9 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 58 | fail = true; | 62 | fail = true; |
| 59 | } | 63 | } |
| 60 | if pool_size < 1 { | 64 | if pool_size < 1 { |
| 61 | Span::call_site() | 65 | return parse::Error::new(Span::call_site(), "pool_size must be 1 or greater") |
| 62 | .error("pool_size must be 1 or greater") | 66 | .to_compile_error() |
| 63 | .emit(); | 67 | .into(); |
| 64 | fail = true | ||
| 65 | } | 68 | } |
| 66 | 69 | ||
| 67 | let mut arg_names: syn::punctuated::Punctuated<syn::Ident, syn::Token![,]> = | 70 | let mut arg_names: syn::punctuated::Punctuated<syn::Ident, syn::Token![,]> = |
| @@ -120,6 +123,66 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 120 | result.into() | 123 | result.into() |
| 121 | } | 124 | } |
| 122 | 125 | ||
| 126 | #[proc_macro_attribute] | ||
| 127 | pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream { | ||
| 128 | let mut f: ItemFn = syn::parse(input).expect("`#[interrupt]` must be applied to a function"); | ||
| 129 | |||
| 130 | if !args.is_empty() { | ||
| 131 | return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") | ||
| 132 | .to_compile_error() | ||
| 133 | .into(); | ||
| 134 | } | ||
| 135 | |||
| 136 | let fspan = f.span(); | ||
| 137 | let ident = f.sig.ident.clone(); | ||
| 138 | let ident_s = ident.to_string(); | ||
| 139 | |||
| 140 | // XXX should we blacklist other attributes? | ||
| 141 | |||
| 142 | let valid_signature = f.sig.constness.is_none() | ||
| 143 | && f.vis == Visibility::Inherited | ||
| 144 | && f.sig.abi.is_none() | ||
| 145 | && f.sig.inputs.is_empty() | ||
| 146 | && f.sig.generics.params.is_empty() | ||
| 147 | && f.sig.generics.where_clause.is_none() | ||
| 148 | && f.sig.variadic.is_none() | ||
| 149 | && match f.sig.output { | ||
| 150 | ReturnType::Default => true, | ||
| 151 | ReturnType::Type(_, ref ty) => match **ty { | ||
| 152 | Type::Tuple(ref tuple) => tuple.elems.is_empty(), | ||
| 153 | Type::Never(..) => true, | ||
| 154 | _ => false, | ||
| 155 | }, | ||
| 156 | }; | ||
| 157 | |||
| 158 | if !valid_signature { | ||
| 159 | return parse::Error::new( | ||
| 160 | fspan, | ||
| 161 | "`#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`", | ||
| 162 | ) | ||
| 163 | .to_compile_error() | ||
| 164 | .into(); | ||
| 165 | } | ||
| 166 | |||
| 167 | f.block.stmts = iter::once( | ||
| 168 | syn::parse2(quote! {{ | ||
| 169 | // Check that this interrupt actually exists | ||
| 170 | let __irq_exists_check: interrupt::#ident; | ||
| 171 | }}) | ||
| 172 | .unwrap(), | ||
| 173 | ) | ||
| 174 | .chain(f.block.stmts) | ||
| 175 | .collect(); | ||
| 176 | |||
| 177 | quote!( | ||
| 178 | #[doc(hidden)] | ||
| 179 | #[export_name = #ident_s] | ||
| 180 | #[allow(non_snake_case)] | ||
| 181 | #f | ||
| 182 | ) | ||
| 183 | .into() | ||
| 184 | } | ||
| 185 | |||
| 123 | #[proc_macro] | 186 | #[proc_macro] |
| 124 | pub fn interrupt_declare(item: TokenStream) -> TokenStream { | 187 | pub fn interrupt_declare(item: TokenStream) -> TokenStream { |
| 125 | let name = syn::parse_macro_input!(item as syn::Ident); | 188 | let name = syn::parse_macro_input!(item as syn::Ident); |
| @@ -130,7 +193,7 @@ pub fn interrupt_declare(item: TokenStream) -> TokenStream { | |||
| 130 | let result = quote! { | 193 | let result = quote! { |
| 131 | #[allow(non_camel_case_types)] | 194 | #[allow(non_camel_case_types)] |
| 132 | pub struct #name_interrupt(()); | 195 | pub struct #name_interrupt(()); |
| 133 | unsafe impl Interrupt for #name_interrupt { | 196 | unsafe impl ::embassy::interrupt::Interrupt for #name_interrupt { |
| 134 | type Priority = crate::interrupt::Priority; | 197 | type Priority = crate::interrupt::Priority; |
| 135 | fn number(&self) -> u16 { | 198 | fn number(&self) -> u16 { |
| 136 | use cortex_m::interrupt::InterruptNumber; | 199 | use cortex_m::interrupt::InterruptNumber; |
| @@ -204,10 +267,6 @@ pub fn interrupt_take(item: TokenStream) -> TokenStream { | |||
| 204 | #[path = "chip/nrf.rs"] | 267 | #[path = "chip/nrf.rs"] |
| 205 | mod chip; | 268 | mod chip; |
| 206 | 269 | ||
| 207 | #[cfg(feature = "stm32")] | ||
| 208 | #[path = "chip/stm32.rs"] | ||
| 209 | mod chip; | ||
| 210 | |||
| 211 | #[cfg(feature = "rp")] | 270 | #[cfg(feature = "rp")] |
| 212 | #[path = "chip/rp.rs"] | 271 | #[path = "chip/rp.rs"] |
| 213 | mod chip; | 272 | mod chip; |
| @@ -221,7 +280,7 @@ struct MainArgs { | |||
| 221 | config: Option<syn::LitStr>, | 280 | config: Option<syn::LitStr>, |
| 222 | } | 281 | } |
| 223 | 282 | ||
| 224 | #[cfg(any(feature = "nrf", feature = "stm32", feature = "rp"))] | 283 | #[cfg(any(feature = "nrf", feature = "rp"))] |
| 225 | #[proc_macro_attribute] | 284 | #[proc_macro_attribute] |
| 226 | pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { | 285 | pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { |
| 227 | let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs); | 286 | let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs); |
| @@ -256,12 +315,12 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 256 | 315 | ||
| 257 | let args = task_fn.sig.inputs.clone(); | 316 | let args = task_fn.sig.inputs.clone(); |
| 258 | 317 | ||
| 259 | if args.len() != 1 { | 318 | if args.len() != 2 { |
| 260 | task_fn | 319 | task_fn |
| 261 | .sig | 320 | .sig |
| 262 | .span() | 321 | .span() |
| 263 | .unwrap() | 322 | .unwrap() |
| 264 | .error("main function must have one argument") | 323 | .error("main function must have 2 arguments") |
| 265 | .emit(); | 324 | .emit(); |
| 266 | fail = true; | 325 | fail = true; |
| 267 | } | 326 | } |
| @@ -305,7 +364,7 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 305 | #chip_setup | 364 | #chip_setup |
| 306 | 365 | ||
| 307 | executor.run(|spawner| { | 366 | executor.run(|spawner| { |
| 308 | spawner.spawn(__embassy_main(spawner)).unwrap(); | 367 | spawner.spawn(__embassy_main(spawner, p)).unwrap(); |
| 309 | }) | 368 | }) |
| 310 | 369 | ||
| 311 | } | 370 | } |
