Initial node implementation #4
@ -33,8 +33,8 @@ use embassy_stm32::peripherals::{EXTI6, PF6, PF7, SPI3};
|
|||||||
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
||||||
use embassy_sync::pubsub::PubSubChannel;
|
use embassy_sync::pubsub::PubSubChannel;
|
||||||
use physical_ads1256::{standard_input, SingleEnded};
|
use physical_ads1256::{standard_input, SingleEnded};
|
||||||
use physical_node::transducer::input::RawStatePubInput;
|
use physical_node::transducer::input::StatefulPublisher;
|
||||||
use physical_node::transducer::Publisher;
|
use physical_node::transducer::Publish;
|
||||||
|
|
||||||
const AUTOCAL_CONF: Config = Config {
|
const AUTOCAL_CONF: Config = Config {
|
||||||
status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst),
|
status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst),
|
||||||
@ -58,9 +58,9 @@ impl ads1256::BlockingDelay for Ads1256Delay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Inputs {
|
struct Inputs {
|
||||||
ai1: RawStatePubInput<f32::ElectricPotential, NoopRawMutex, 10, 1>,
|
ai1: StatefulPublisher<f32::ElectricPotential, NoopRawMutex, 10, 1>,
|
||||||
ai2: RawStatePubInput<f32::ElectricPotential, NoopRawMutex, 10, 1>,
|
ai2: StatefulPublisher<f32::ElectricPotential, NoopRawMutex, 10, 1>,
|
||||||
ai3: RawStatePubInput<f32::ElectricPotential, NoopRawMutex, 10, 1>,
|
ai3: StatefulPublisher<f32::ElectricPotential, NoopRawMutex, 10, 1>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inputs
|
// Inputs
|
||||||
@ -101,17 +101,17 @@ async fn main(spawner: Spawner) {
|
|||||||
let ads_1256 = ADS_1256.init(Ads1256::new(Ads1256Delay, select_ads1256, ads1256_data_ready));
|
let ads_1256 = ADS_1256.init(Ads1256::new(Ads1256Delay, select_ads1256, ads1256_data_ready));
|
||||||
|
|
||||||
let inputs = &*ANALOG_INPUTS.init(Inputs {
|
let inputs = &*ANALOG_INPUTS.init(Inputs {
|
||||||
ai1: RawStatePubInput::new(
|
ai1: StatefulPublisher::new(
|
||||||
Cell::new(f32::ElectricPotential::new::<volt>(-1000.0)),
|
Cell::new(f32::ElectricPotential::new::<volt>(-1000.0)).into(),
|
||||||
PubSubChannel::new(),
|
PubSubChannel::new().into(),
|
||||||
),
|
),
|
||||||
ai2: RawStatePubInput::new(
|
ai2: StatefulPublisher::new(
|
||||||
Cell::new(f32::ElectricPotential::new::<volt>(-1000.0)),
|
Cell::new(f32::ElectricPotential::new::<volt>(-1000.0)).into(),
|
||||||
PubSubChannel::new(),
|
PubSubChannel::new().into(),
|
||||||
),
|
),
|
||||||
ai3: RawStatePubInput::new(
|
ai3: StatefulPublisher::new(
|
||||||
Cell::new(f32::ElectricPotential::new::<volt>(-1000.0)),
|
Cell::new(f32::ElectricPotential::new::<volt>(-1000.0)).into(),
|
||||||
PubSubChannel::new(),
|
PubSubChannel::new().into(),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,105 +1,68 @@
|
|||||||
use crate::cell::CellView;
|
use crate::cell::CellView;
|
||||||
use crate::transducer::Publisher;
|
use crate::transducer::{Publish, Publisher};
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
#[cfg(feature = "embassy-sync")]
|
#[cfg(feature = "embassy-sync")]
|
||||||
use embassy_sync::blocking_mutex::raw::RawMutex;
|
use embassy_sync::blocking_mutex::raw::RawMutex;
|
||||||
#[cfg(feature = "embassy-sync")]
|
#[cfg(feature = "embassy-sync")]
|
||||||
use embassy_sync::pubsub::PubSubChannel;
|
use embassy_sync::pubsub::{Error, PubSubChannel, Subscriber};
|
||||||
use embassy_sync::pubsub::{Error, PubSubBehavior, Subscriber};
|
|
||||||
pub use physical::transducer::input::*;
|
pub use physical::transducer::input::*;
|
||||||
use physical::transducer::Stateful;
|
use physical::transducer::{State, Stateful};
|
||||||
|
|
||||||
#[cfg(feature = "embassy-sync")]
|
#[cfg(feature = "embassy-sync")]
|
||||||
pub struct RawPublishInput<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
pub struct StatefulPublisher<
|
||||||
{
|
|
||||||
pub channel: PubSubChannel<MutexT, T, CAPACITY, NUM_SUBS, 0>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
|
||||||
RawPublishInput<T, MutexT, CAPACITY, NUM_SUBS>
|
|
||||||
{
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn new(channel: PubSubChannel<MutexT, T, CAPACITY, NUM_SUBS, 0>) -> Self {
|
|
||||||
Self { channel }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn update(&self, value: T) {
|
|
||||||
self.channel.publish_immediate(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
|
||||||
Publisher<CAPACITY, NUM_SUBS> for RawPublishInput<T, MutexT, CAPACITY, NUM_SUBS>
|
|
||||||
{
|
|
||||||
type Value = T;
|
|
||||||
type Mutex = MutexT;
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn subscribe(
|
|
||||||
&self,
|
|
||||||
) -> Result<Subscriber<Self::Mutex, Self::Value, CAPACITY, NUM_SUBS, 0>, Error> {
|
|
||||||
self.channel.subscriber()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embassy-sync")]
|
|
||||||
pub struct RawStatePubInput<
|
|
||||||
T: Copy,
|
T: Copy,
|
||||||
MutexT: RawMutex,
|
MutexT: RawMutex,
|
||||||
const CAPACITY: usize,
|
const CAPACITY: usize,
|
||||||
const NUM_SUBS: usize,
|
const NUM_SUBS: usize,
|
||||||
> {
|
> {
|
||||||
pub state_cell: Cell<T>,
|
pub state: State<T>,
|
||||||
pub channel: PubSubChannel<MutexT, T, CAPACITY, NUM_SUBS, 0>,
|
pub publisher: Publisher<T, MutexT, CAPACITY, NUM_SUBS>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
||||||
RawStatePubInput<T, MutexT, CAPACITY, NUM_SUBS>
|
StatefulPublisher<T, MutexT, CAPACITY, NUM_SUBS>
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
state_cell: Cell<T>,
|
state: State<T>,
|
||||||
channel: PubSubChannel<MutexT, T, CAPACITY, NUM_SUBS, 0>,
|
publisher: Publisher<T, MutexT, CAPACITY, NUM_SUBS>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self { state, publisher }
|
||||||
state_cell,
|
|
||||||
channel,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
pub fn update(&self, value: T) {
|
pub fn update(&self, value: T) {
|
||||||
self.state_cell.set(value);
|
self.state.update(value);
|
||||||
self.channel.publish_immediate(value);
|
self.publisher.update(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize> Stateful
|
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize> Stateful
|
||||||
for RawStatePubInput<T, MutexT, CAPACITY, NUM_SUBS>
|
for StatefulPublisher<T, MutexT, CAPACITY, NUM_SUBS>
|
||||||
{
|
{
|
||||||
type Value = T;
|
type Value = T;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn state_cell(&self) -> CellView<Self::Value> {
|
fn state_cell(&self) -> CellView<Self::Value> {
|
||||||
(&self.state_cell).into()
|
self.state.state_cell()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn state(&self) -> Self::Value {
|
fn state(&self) -> Self::Value {
|
||||||
self.state_cell.get()
|
self.state.state()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
||||||
Publisher<CAPACITY, NUM_SUBS> for RawStatePubInput<T, MutexT, CAPACITY, NUM_SUBS>
|
Publish<CAPACITY, NUM_SUBS> for StatefulPublisher<T, MutexT, CAPACITY, NUM_SUBS>
|
||||||
{
|
{
|
||||||
type Value = T;
|
type Value = T;
|
||||||
type Mutex = MutexT;
|
type Mutex = MutexT;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn subscribe(
|
fn subscribe(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Subscriber<Self::Mutex, Self::Value, CAPACITY, NUM_SUBS, 0>, Error> {
|
) -> Result<Subscriber<Self::Mutex, Self::Value, CAPACITY, NUM_SUBS, 0>, Error> {
|
||||||
self.channel.subscriber()
|
self.publisher.subscribe()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@ use embassy_sync::blocking_mutex::raw::RawMutex;
|
|||||||
#[cfg(feature = "embassy-sync")]
|
#[cfg(feature = "embassy-sync")]
|
||||||
use embassy_sync::pubsub;
|
use embassy_sync::pubsub;
|
||||||
#[cfg(feature = "embassy-sync")]
|
#[cfg(feature = "embassy-sync")]
|
||||||
use embassy_sync::pubsub::Subscriber;
|
use embassy_sync::pubsub::{PubSubBehavior, PubSubChannel, Subscriber};
|
||||||
|
|
||||||
#[cfg(feature = "embassy-sync")]
|
#[cfg(feature = "embassy-sync")]
|
||||||
pub trait Publisher<const CAPACITY: usize, const NUM_SUBS: usize> {
|
pub trait Publish<const CAPACITY: usize, const NUM_SUBS: usize> {
|
||||||
type Value: Copy;
|
type Value: Copy;
|
||||||
type Mutex: RawMutex;
|
type Mutex: RawMutex;
|
||||||
|
|
||||||
@ -19,3 +19,46 @@ pub trait Publisher<const CAPACITY: usize, const NUM_SUBS: usize> {
|
|||||||
&self,
|
&self,
|
||||||
) -> Result<Subscriber<Self::Mutex, Self::Value, CAPACITY, NUM_SUBS, 0>, pubsub::Error>;
|
) -> Result<Subscriber<Self::Mutex, Self::Value, CAPACITY, NUM_SUBS, 0>, pubsub::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "embassy-sync")]
|
||||||
|
pub struct Publisher<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize> {
|
||||||
|
channel: PubSubChannel<MutexT, T, CAPACITY, NUM_SUBS, 0>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
||||||
|
Publisher<T, MutexT, CAPACITY, NUM_SUBS>
|
||||||
|
{
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn new(channel: PubSubChannel<MutexT, T, CAPACITY, NUM_SUBS, 0>) -> Self {
|
||||||
|
Self { channel }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn update(&self, value: T) {
|
||||||
|
self.channel.publish_immediate(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
||||||
|
Publish<CAPACITY, NUM_SUBS> for Publisher<T, MutexT, CAPACITY, NUM_SUBS>
|
||||||
|
{
|
||||||
|
type Value = T;
|
||||||
|
type Mutex = MutexT;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn subscribe(
|
||||||
|
&self,
|
||||||
|
) -> Result<Subscriber<Self::Mutex, Self::Value, CAPACITY, NUM_SUBS, 0>, pubsub::Error> {
|
||||||
|
self.channel.subscriber()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy, MutexT: RawMutex, const CAPACITY: usize, const NUM_SUBS: usize>
|
||||||
|
From<PubSubChannel<MutexT, T, CAPACITY, NUM_SUBS, 0>>
|
||||||
|
for Publisher<T, MutexT, CAPACITY, NUM_SUBS>
|
||||||
|
{
|
||||||
|
#[inline(always)]
|
||||||
|
fn from(channel: PubSubChannel<MutexT, T, CAPACITY, NUM_SUBS, 0>) -> Self {
|
||||||
|
Publisher::new(channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,33 +5,3 @@ use crate::transducer::Stateful;
|
|||||||
pub trait Poll<T: Copy> {
|
pub trait Poll<T: Copy> {
|
||||||
async fn poll() -> T;
|
async fn poll() -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RawStatefulInput<T: Copy> {
|
|
||||||
pub state_cell: Cell<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy> RawStatefulInput<T> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn new(state_cell: Cell<T>) -> Self {
|
|
||||||
Self { state_cell }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn raw_update(&self, value: T) {
|
|
||||||
self.state_cell.set(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy> Stateful for RawStatefulInput<T> {
|
|
||||||
type Value = T;
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn state_cell(&self) -> CellView<Self::Value> {
|
|
||||||
(&self.state_cell).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn state(&self) -> Self::Value {
|
|
||||||
self.state_cell.get()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use core::cell::Cell;
|
||||||
use crate::cell::CellView;
|
use crate::cell::CellView;
|
||||||
|
|
||||||
pub mod input;
|
pub mod input;
|
||||||
@ -11,8 +12,42 @@ pub trait Stateful {
|
|||||||
|
|
||||||
fn state_cell(&self) -> CellView<Self::Value>;
|
fn state_cell(&self) -> CellView<Self::Value>;
|
||||||
|
|
||||||
|
fn state(&self) -> Self::Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct State<T: Copy> {
|
||||||
|
state_cell: Cell<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy> State<T> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn state(&self) -> Self::Value {
|
pub fn new(state_cell: Cell<T>) -> Self {
|
||||||
self.state_cell().get()
|
Self { state_cell }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn update(&self, value: T) {
|
||||||
|
self.state_cell.set(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy> Stateful for State<T> {
|
||||||
|
type Value = T;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn state_cell(&self) -> CellView<Self::Value> {
|
||||||
|
(&self.state_cell).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn state(&self) -> Self::Value {
|
||||||
|
self.state_cell.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy> From<Cell<T>> for State<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn from(state_cell: Cell<T>) -> Self {
|
||||||
|
State::new(state_cell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,5 @@ pub trait Output {
|
|||||||
|
|
||||||
//TODO: return result
|
//TODO: return result
|
||||||
//TODO: Make maybe async
|
//TODO: Make maybe async
|
||||||
fn set(&mut self, setting: Self::Value);
|
fn output(&mut self, setting: Self::Value);
|
||||||
}
|
}
|
Reference in New Issue
Block a user