Initial node implementation #4

Merged
zack merged 51 commits from develop into master 2023-07-19 18:09:13 +00:00
42 changed files with 1473 additions and 44 deletions
Showing only changes of commit 07cb49bee5 - Show all commits

View File

@ -5,12 +5,11 @@ use syn::__private::Span;
use syn::punctuated::Punctuated; use syn::punctuated::Punctuated;
use syn::token::{Colon, Comma, PathSep, Plus}; use syn::token::{Colon, Comma, PathSep, Plus};
use syn::{ use syn::{
parse_macro_input, parse_quote, parse_quote_spanned, Data, DeriveInput, Expr, GenericParam, parse_macro_input, parse_quote, parse_quote_spanned, parse_str, Data, DeriveInput, Expr,
Generics, Ident, Lit, Meta, Path, PathSegment, Token, TraitBound, TraitBoundModifier, GenericParam, Generics, Ident, Lit, Meta, Path, PathSegment, Token, TraitBound,
TypeParam, TypeParamBound, TraitBoundModifier, TypeParam, TypeParamBound,
}; };
// Struct name: Ads1256PollStateful, Ads1256PollPublish, Ads1256PollStatePub
#[proc_macro_derive(PollVariants, attributes(value_type))] #[proc_macro_derive(PollVariants, attributes(value_type))]
pub fn poll_variant_macro(input: TokenStream) -> TokenStream { pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
// ----- Parse input ---------------------------------- // ----- Parse input ----------------------------------
@ -31,7 +30,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
// ----- Extract value type attribute ---------------------------------- // ----- Extract value type attribute ----------------------------------
const VALUE_T_NAME: &str = "value_type"; const VALUE_T_NAME: &str = "value_type";
let mut value_type_ident: Option<Ident> = None; let mut value_type_path: Option<Path> = None;
for attribute in attrs.iter() { for attribute in attrs.iter() {
// if the attribute is a named value // if the attribute is a named value
if let Meta::NameValue(meta) = &attribute.meta { 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 let Expr::Lit(lit) = &meta.value {
// if the literal is a string // if the literal is a string
if let Lit::Str(lit) = &lit.lit { 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<PathSegment, PathSep> = 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 { } else {
panic!("{VALUE_T_NAME} must be set with a string literal.") panic!("{VALUE_T_NAME} must be set with a string literal.")
} }
} else { } else {
panic!("{VALUE_T_NAME} must be set with a literal.") 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 { let value_type_path = value_type_path
val .expect(format!("Need attribute {VALUE_T_NAME}: #[{VALUE_T_NAME} = \"type\"]").deref());
} else {
panic!("Need attribute {VALUE_T_NAME}: #[{VALUE_T_NAME} = \"type\"]")
};
// ----- Add publisher generics ---------------------------------- // ----- Add publisher generics ----------------------------------
// MutexT // MutexT
@ -144,12 +146,12 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
// ----- Stateful struct ---------------------------------- // ----- Stateful struct ----------------------------------
#vis struct #stateful_variant_ident #og_generics #og_where_clause { #vis struct #stateful_variant_ident #og_generics #og_where_clause {
pub poll: #ident #og_type_generics, pub poll: #ident #og_type_generics,
pub state: #state_path<#value_type_ident>, pub state: #state_path<#value_type_path>,
} }
// ----- Stateful impls ---------------------------------- // ----- Stateful impls ----------------------------------
impl #og_impl_generics #poll_path for #stateful_variant_ident #og_type_generics #og_where_clause { 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)] #[inline(always)]
async fn poll(&self) -> Self::Value { 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 { 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)] #[inline(always)]
fn state_cell(&self) -> #cellview_path<Self::Value> { fn state_cell(&self) -> #cellview_path<Self::Value> {
@ -177,13 +179,13 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
#[cfg(feature = "embassy-sync")] #[cfg(feature = "embassy-sync")]
#vis struct #publish_variant_ident #publish_generics #publ_where_clause { #vis struct #publish_variant_ident #publish_generics #publ_where_clause {
pub poll: #ident #og_type_generics, 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 ---------------------------------- // ----- Publish impl ----------------------------------
#[cfg(feature = "embassy-sync")] #[cfg(feature = "embassy-sync")]
impl #publ_impl_generics #poll_path for #publish_variant_ident #publ_type_generics #publ_where_clause { 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)] #[inline(always)]
async fn poll(&self) -> Self::Value { async fn poll(&self) -> Self::Value {
@ -195,7 +197,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
#[cfg(feature = "embassy-sync")] #[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 { 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; type Mutex = #mutex_t_ident;
#[inline(always)] #[inline(always)]
@ -210,13 +212,13 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
#[cfg(feature = "embassy-sync")] #[cfg(feature = "embassy-sync")]
#vis struct #state_pub_variant_ident #publish_generics #publ_where_clause { #vis struct #state_pub_variant_ident #publish_generics #publ_where_clause {
pub poll: #ident #og_type_generics, pub poll: #ident #og_type_generics,
pub state: #state_path<#value_type_ident>, pub state: #state_path<#value_type_path>,
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>,
} }
#[cfg(feature = "embassy-sync")] #[cfg(feature = "embassy-sync")]
impl #publ_impl_generics #poll_path for #state_pub_variant_ident #publ_type_generics #publ_where_clause { 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] #[inline]
async fn poll(&self) -> Self::Value { async fn poll(&self) -> Self::Value {
@ -229,7 +231,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
#[cfg(feature = "embassy-sync")] #[cfg(feature = "embassy-sync")]
impl #publ_impl_generics #stateful_path for #state_pub_variant_ident #publ_type_generics #publ_where_clause { 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)] #[inline(always)]
fn state_cell(&self) -> #cellview_path<Self::Value> { fn state_cell(&self) -> #cellview_path<Self::Value> {
@ -244,7 +246,7 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
#[cfg(feature = "embassy-sync")] #[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 { 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; type Mutex = #mutex_t_ident;
#[inline(always)] #[inline(always)]

View File

@ -8,7 +8,7 @@ readme.workspace = true
license.workspace = true license.workspace = true
[features] [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"] poll = ["standard-multiplexer", "embassy-sync"]
config = ["physical-ads1256-types/config"] config = ["physical-ads1256-types/config"]
standard-input = ["physical-ads1256-types/standard-input"] standard-input = ["physical-ads1256-types/standard-input"]

View File

@ -1,11 +1,15 @@
use core::ops::DerefMut;
use ads1256::{ use ads1256::{
AdControl, Ads1256, BlockingDelay, DataRate, Multiplexer, OutputPin, SpiBus, Status, Wait, AdControl, Ads1256, BlockingDelay, DataRate, Multiplexer, OutputPin, SpiBus, Status, Wait,
}; };
use core::ops::DerefMut;
use embassy_sync::blocking_mutex::raw::RawMutex; use embassy_sync::blocking_mutex::raw::RawMutex;
use embassy_sync::mutex::Mutex; use embassy_sync::mutex::Mutex;
use node_poll_variants::PollVariants;
use physical_node::transducer::input::Poll; 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> pub struct AutocalPoll<'a, DeviceMutexT, ModInT, DelayerT, SST, DrdyT, SpiT>
where where
DeviceMutexT: RawMutex, DeviceMutexT: RawMutex,
@ -30,10 +34,22 @@ where
DrdyT: Wait, DrdyT: Wait,
SpiT: SpiBus, SpiT: SpiBus,
{ {
type Value = (); type Value = f32::ElectricPotential;
async fn poll(&self) -> Self::Value { 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
} }
} }

12
src/error.rs Normal file
View File

@ -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,
}

View File

@ -3,3 +3,6 @@
pub mod transducer; pub mod transducer;
pub mod cell; pub mod cell;
mod error;
pub use error::*;