From 07cb49bee5d12bb9bb3221fbf4568e1a0faae98a Mon Sep 17 00:00:00 2001 From: Zachary Sunforge Date: Fri, 23 Jun 2023 14:15:43 -0700 Subject: [PATCH] Changes to Derive(PollVariants) to accept any path for the value type. --- macros/node-poll-variants/src/lib.rs | 54 ++++++++++--------- peripheral-components/ads1256/node/Cargo.toml | 2 +- .../src/standard_multiplexer/sync/poll.rs | 22 ++++++-- src/error.rs | 12 +++++ src/lib.rs | 3 ++ 5 files changed, 63 insertions(+), 30 deletions(-) create mode 100644 src/error.rs diff --git a/macros/node-poll-variants/src/lib.rs b/macros/node-poll-variants/src/lib.rs index 53f2597..2f3936e 100644 --- a/macros/node-poll-variants/src/lib.rs +++ b/macros/node-poll-variants/src/lib.rs @@ -5,12 +5,11 @@ use syn::__private::Span; use syn::punctuated::Punctuated; use syn::token::{Colon, Comma, PathSep, Plus}; use syn::{ - parse_macro_input, parse_quote, parse_quote_spanned, Data, DeriveInput, Expr, GenericParam, - Generics, Ident, Lit, Meta, Path, PathSegment, Token, TraitBound, TraitBoundModifier, - TypeParam, TypeParamBound, + parse_macro_input, parse_quote, parse_quote_spanned, parse_str, Data, DeriveInput, Expr, + GenericParam, Generics, Ident, Lit, Meta, Path, PathSegment, Token, TraitBound, + TraitBoundModifier, TypeParam, TypeParamBound, }; -// Struct name: Ads1256PollStateful, Ads1256PollPublish, Ads1256PollStatePub #[proc_macro_derive(PollVariants, attributes(value_type))] pub fn poll_variant_macro(input: TokenStream) -> TokenStream { // ----- Parse input ---------------------------------- @@ -31,7 +30,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { // ----- Extract value type attribute ---------------------------------- const VALUE_T_NAME: &str = "value_type"; - let mut value_type_ident: Option = None; + let mut value_type_path: Option = None; for attribute in attrs.iter() { // if the attribute is a named value if let Meta::NameValue(meta) = &attribute.meta { @@ -41,25 +40,28 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { if let Expr::Lit(lit) = &meta.value { // if the literal is a string if let Lit::Str(lit) = &lit.lit { - value_type_ident = Some(Ident::new(lit.value().deref(), Span::call_site())); + let span = lit.span(); + let string = lit.token().to_string(); + let mut segments: Punctuated = Punctuated::new(); + string + .trim_matches('"') + .split("::") + .map(|segment| Ident::new(segment, span)) + .for_each(|ident| segments.push(parse_quote_spanned!(span=> #ident))); + + let path: Path = parse_quote_spanned!(span=> #segments); + value_type_path = Some(path); } else { panic!("{VALUE_T_NAME} must be set with a string literal.") } } else { panic!("{VALUE_T_NAME} must be set with a literal.") } - } else { - continue; } - } else { - continue; } } - let value_type_ident = if let Some(val) = value_type_ident { - val - } else { - panic!("Need attribute {VALUE_T_NAME}: #[{VALUE_T_NAME} = \"type\"]") - }; + let value_type_path = value_type_path + .expect(format!("Need attribute {VALUE_T_NAME}: #[{VALUE_T_NAME} = \"type\"]").deref()); // ----- Add publisher generics ---------------------------------- // MutexT @@ -144,12 +146,12 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { // ----- Stateful struct ---------------------------------- #vis struct #stateful_variant_ident #og_generics #og_where_clause { pub poll: #ident #og_type_generics, - pub state: #state_path<#value_type_ident>, + pub state: #state_path<#value_type_path>, } // ----- Stateful impls ---------------------------------- impl #og_impl_generics #poll_path for #stateful_variant_ident #og_type_generics #og_where_clause { - type Value = #value_type_ident; + type Value = #value_type_path; #[inline(always)] async fn poll(&self) -> Self::Value { @@ -160,7 +162,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { } impl #og_impl_generics #stateful_path for #stateful_variant_ident #og_type_generics #og_where_clause { - type Value = #value_type_ident; + type Value = #value_type_path; #[inline(always)] fn state_cell(&self) -> #cellview_path { @@ -177,13 +179,13 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { #[cfg(feature = "embassy-sync")] #vis struct #publish_variant_ident #publish_generics #publ_where_clause { pub poll: #ident #og_type_generics, - pub publisher: #publisher_path<#value_type_ident, #mutex_t_ident, #capacity_ident, #num_subs_ident>, + pub publisher: #publisher_path<#value_type_path, #mutex_t_ident, #capacity_ident, #num_subs_ident>, } // ----- Publish impl ---------------------------------- #[cfg(feature = "embassy-sync")] impl #publ_impl_generics #poll_path for #publish_variant_ident #publ_type_generics #publ_where_clause { - type Value = #value_type_ident; + type Value = #value_type_path; #[inline(always)] async fn poll(&self) -> Self::Value { @@ -195,7 +197,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { #[cfg(feature = "embassy-sync")] impl #publ_impl_generics #publish_path<#capacity_ident, #num_subs_ident> for #publish_variant_ident #publ_type_generics #publ_where_clause { - type Value = #value_type_ident; + type Value = #value_type_path; type Mutex = #mutex_t_ident; #[inline(always)] @@ -210,13 +212,13 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { #[cfg(feature = "embassy-sync")] #vis struct #state_pub_variant_ident #publish_generics #publ_where_clause { pub poll: #ident #og_type_generics, - pub state: #state_path<#value_type_ident>, - pub publisher: #publisher_path<#value_type_ident, #mutex_t_ident, #capacity_ident, #num_subs_ident>, + pub state: #state_path<#value_type_path>, + pub publisher: #publisher_path<#value_type_path, #mutex_t_ident, #capacity_ident, #num_subs_ident>, } #[cfg(feature = "embassy-sync")] impl #publ_impl_generics #poll_path for #state_pub_variant_ident #publ_type_generics #publ_where_clause { - type Value = #value_type_ident; + type Value = #value_type_path; #[inline] async fn poll(&self) -> Self::Value { @@ -229,7 +231,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { #[cfg(feature = "embassy-sync")] impl #publ_impl_generics #stateful_path for #state_pub_variant_ident #publ_type_generics #publ_where_clause { - type Value = #value_type_ident; + type Value = #value_type_path; #[inline(always)] fn state_cell(&self) -> #cellview_path { @@ -244,7 +246,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream { #[cfg(feature = "embassy-sync")] impl #publ_impl_generics #publish_path<#capacity_ident, #num_subs_ident> for #state_pub_variant_ident #publ_type_generics #publ_where_clause { - type Value = #value_type_ident; + type Value = #value_type_path; type Mutex = #mutex_t_ident; #[inline(always)] diff --git a/peripheral-components/ads1256/node/Cargo.toml b/peripheral-components/ads1256/node/Cargo.toml index b4f8d3d..d5169ea 100644 --- a/peripheral-components/ads1256/node/Cargo.toml +++ b/peripheral-components/ads1256/node/Cargo.toml @@ -8,7 +8,7 @@ readme.workspace = true license.workspace = true [features] -embassy-sync = ["dep:embassy-sync", "ads1256/embassy-sync"] +embassy-sync = ["dep:embassy-sync", "ads1256/embassy-sync", "physical-node/embassy-sync"] poll = ["standard-multiplexer", "embassy-sync"] config = ["physical-ads1256-types/config"] standard-input = ["physical-ads1256-types/standard-input"] diff --git a/peripheral-components/ads1256/node/src/standard_multiplexer/sync/poll.rs b/peripheral-components/ads1256/node/src/standard_multiplexer/sync/poll.rs index 8eaddaa..62513eb 100644 --- a/peripheral-components/ads1256/node/src/standard_multiplexer/sync/poll.rs +++ b/peripheral-components/ads1256/node/src/standard_multiplexer/sync/poll.rs @@ -1,11 +1,15 @@ -use core::ops::DerefMut; use ads1256::{ AdControl, Ads1256, BlockingDelay, DataRate, Multiplexer, OutputPin, SpiBus, Status, Wait, }; +use core::ops::DerefMut; use embassy_sync::blocking_mutex::raw::RawMutex; use embassy_sync::mutex::Mutex; +use node_poll_variants::PollVariants; use physical_node::transducer::input::Poll; +use uom::si::f32; +#[derive(PollVariants)] +#[value_type = "f32::ElectricPotential"] pub struct AutocalPoll<'a, DeviceMutexT, ModInT, DelayerT, SST, DrdyT, SpiT> where DeviceMutexT: RawMutex, @@ -30,10 +34,22 @@ where DrdyT: Wait, SpiT: SpiBus, { - type Value = (); + type Value = f32::ElectricPotential; async fn poll(&self) -> Self::Value { - todo!() + self.ads1256 + .lock() + .await + .deref_mut() + .autocal_convert_m( + self.spi, + self.input_mod.multiplexer(), + self.input_mod.status(), + self.input_mod.ad_control(), + self.input_mod.data_rate(), + true, + ) + .await } } diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..99b3012 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,12 @@ +/// An error that it is likely impossible to recover. This error should only be created in +/// situations where attempts to recover have already been attempted and have failed. Error handling +/// should consist of attempting to alert another system for maintenance and attempting to shut down +/// any systems that depend on the correct functionality of the component having errors. +/// +/// In many systems there can be a single function for handling any critical error as a critical +/// error always means everything needs to be stopped. +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum CriticalError { + /// Critical communication failed and retries are either impossible or also failed. + Communication, +} diff --git a/src/lib.rs b/src/lib.rs index 9fe79e6..d700e0c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,6 @@ pub mod transducer; pub mod cell; +mod error; + +pub use error::*;