From 4cb7514150c0cedb7f74510d14921989459cfb92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 3 Sep 2024 17:00:35 +0200 Subject: [PATCH] Remove gpio dispatch proc macro --- esp-hal-procmacros/src/enum_dispatch.rs | 77 ------------------------- esp-hal-procmacros/src/lib.rs | 33 ----------- esp-hal/src/gpio/mod.rs | 63 ++++++++++++++------ 3 files changed, 46 insertions(+), 127 deletions(-) delete mode 100644 esp-hal-procmacros/src/enum_dispatch.rs diff --git a/esp-hal-procmacros/src/enum_dispatch.rs b/esp-hal-procmacros/src/enum_dispatch.rs deleted file mode 100644 index 3a010bd9849..00000000000 --- a/esp-hal-procmacros/src/enum_dispatch.rs +++ /dev/null @@ -1,77 +0,0 @@ -use proc_macro2::{Group, TokenStream, TokenTree}; -use quote::{format_ident, quote}; -use syn::{ - parse::{Parse, ParseStream, Result}, - Ident, -}; - -#[derive(Debug)] -pub(crate) struct MakeGpioEnumDispatchMacro { - pub name: String, - pub filter: Vec, - pub elements: Vec<(String, usize)>, -} - -impl Parse for MakeGpioEnumDispatchMacro { - fn parse(input: ParseStream) -> Result { - let name = input.parse::()?.to_string(); - let filter = input - .parse::()? - .stream() - .into_iter() - .map(|v| match v { - TokenTree::Group(_) => String::new(), - TokenTree::Ident(ident) => ident.to_string(), - TokenTree::Punct(_) => String::new(), - TokenTree::Literal(_) => String::new(), - }) - .filter(|p| !p.is_empty()) - .collect(); - - let mut elements = vec![]; - - let stream = input.parse::()?.stream().into_iter(); - let mut element_name = String::new(); - for v in stream { - match v { - TokenTree::Ident(ident) => { - element_name = ident.to_string(); - } - TokenTree::Literal(lit) => { - let index = lit.to_string().parse().unwrap(); - elements.push((element_name.clone(), index)); - } - _ => (), - } - } - - Ok(MakeGpioEnumDispatchMacro { - name, - filter, - elements, - }) - } -} - -pub(crate) fn build_match_arms(input: MakeGpioEnumDispatchMacro) -> Vec { - let mut arms = Vec::new(); - for (gpio_type, num) in input.elements { - let enum_name = format_ident!("ErasedPin"); - let variant_name = format_ident!("Gpio{}", num); - - if input.filter.contains(&gpio_type) { - arms.push({ - quote! { #enum_name::#variant_name($target) => $body } - }); - } else { - arms.push({ - quote! { - #[allow(unused)] - #enum_name::#variant_name($target) => { panic!("Unsupported") } - } - }); - } - } - - arms -} diff --git a/esp-hal-procmacros/src/lib.rs b/esp-hal-procmacros/src/lib.rs index 0a1106e4b87..5f423b6ce5e 100644 --- a/esp-hal-procmacros/src/lib.rs +++ b/esp-hal-procmacros/src/lib.rs @@ -52,8 +52,6 @@ use proc_macro::TokenStream; #[cfg(feature = "embassy")] mod embassy; -#[cfg(feature = "enum-dispatch")] -mod enum_dispatch; #[cfg(feature = "interrupt")] mod interrupt; #[cfg(any( @@ -339,37 +337,6 @@ pub fn handler(args: TokenStream, input: TokenStream) -> TokenStream { .into() } -/// Create an enum for erased GPIO pins, using the enum-dispatch pattern -/// -/// Only used internally -#[cfg(feature = "enum-dispatch")] -#[proc_macro] -pub fn make_gpio_enum_dispatch_macro(input: TokenStream) -> TokenStream { - use quote::{format_ident, quote}; - - use self::enum_dispatch::{build_match_arms, MakeGpioEnumDispatchMacro}; - - let input = syn::parse_macro_input!(input as MakeGpioEnumDispatchMacro); - - let macro_name = format_ident!("{}", input.name); - let arms = build_match_arms(input); - - quote! { - #[doc(hidden)] - #[macro_export] - macro_rules! #macro_name { - ($m:ident, $target:ident, $body:block) => { - match $m { - #(#arms)* - } - } - } - - pub(crate) use #macro_name; - } - .into() -} - /// Load code to be run on the LP/ULP core. /// /// ## Example diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index a167cbed0df..8a96daf127a 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -670,6 +670,10 @@ pub trait PinType { type IsOutput: BooleanType; type IsAnalog: BooleanType; type IsTouch: BooleanType; + + fn is_output() -> bool { + ::VALUE + } } #[doc(hidden)] @@ -1328,6 +1332,17 @@ pub trait GpioProperties { type PinType: PinType; } + +#[doc(hidden)] +#[macro_export] +macro_rules! if_output_pin { + (InputOnlyAnalog, { $($then:tt)* } else { $($else:tt)* } ) => { $($else)* }; + (InputOutputAnalog, { $($then:tt)* } else { $($else:tt)* } ) => { $($then)* }; + (InputOutputAnalogTouch, { $($then:tt)* } else { $($else:tt)* } ) => { $($then)* }; + (InputOutput, { $($then:tt)* } else { $($else:tt)* } ) => { $($then)* }; +} +pub use if_output_pin; + #[doc(hidden)] #[macro_export] macro_rules! gpio { @@ -1431,25 +1446,39 @@ macro_rules! gpio { } } - procmacros::make_gpio_enum_dispatch_macro!( - handle_gpio_output - { InputOutputAnalogTouch, InputOutputAnalog, InputOutput, } - { - $( - $type,$gpionum - )+ + // These macros call the code block on the actually contained GPIO pin. + + #[doc(hidden)] + #[macro_export] + macro_rules! handle_gpio_output { + ($this:ident, $inner:ident, $code:tt) => { + match $this { + $( + ErasedPin::[]($inner) => if_output_pin!($type, { + $code + } else {{ + let _ = $inner; + panic!("Unsupported") + }}), + )+ + } } - ); - - procmacros::make_gpio_enum_dispatch_macro!( - handle_gpio_input - { InputOutputAnalogTouch, InputOutputAnalog, InputOutput, InputOnlyAnalog } - { - $( - $type,$gpionum - )+ + } + + #[doc(hidden)] + #[macro_export] + macro_rules! handle_gpio_input { + ($this:ident, $inner:ident, $code:tt) => { + match $this { + $( + ErasedPin::[]($inner) => $code + )+ + } } - ); + } + + pub(crate) use handle_gpio_output; + pub(crate) use handle_gpio_input; } }; }