diff --git a/examples/ads1256/src/bin/multiplex.rs b/examples/ads1256/src/bin/multiplex.rs index 229aa35..4460cc2 100644 --- a/examples/ads1256/src/bin/multiplex.rs +++ b/examples/ads1256/src/bin/multiplex.rs @@ -101,15 +101,15 @@ async fn main(spawner: Spawner) { let inputs = &*ANALOG_INPUTS.init(Inputs { ai1: StatefulPublisher::new( - Cell::new(f32::ElectricPotential::new::(-1000.0)).into(), + Cell::new(f32::ElectricPotential::new::(f32::NAN)).into(), PubSubChannel::new().into(), ), ai2: StatefulPublisher::new( - Cell::new(f32::ElectricPotential::new::(-1000.0)).into(), + Cell::new(f32::ElectricPotential::new::(f32::NAN)).into(), PubSubChannel::new().into(), ), ai3: StatefulPublisher::new( - Cell::new(f32::ElectricPotential::new::(-1000.0)).into(), + Cell::new(f32::ElectricPotential::new::(f32::NAN)).into(), PubSubChannel::new().into(), ), }); diff --git a/examples/ads1256/src/bin/poll.rs b/examples/ads1256/src/bin/poll.rs index 229aa35..6e5e225 100644 --- a/examples/ads1256/src/bin/poll.rs +++ b/examples/ads1256/src/bin/poll.rs @@ -10,12 +10,12 @@ use {defmt_rtt as _, panic_probe as _}; use {embassy_executor as executor, embassy_stm32 as stm32}; +use ads1256::standard::input::SingleEnded; use ads1256::{ AdControl, Ads1256, AutoCal, BitOrder, BlockingDelay, Buffer, ClockOut, Config, DState, DataRate, DigitalIo, DigitalIoDirection, DigitalIoState, DioDirection, Gain, Multiplexer, MuxInput, OutputPin, Sdcs, SpiBus, Status, Wait, }; -use ads1256::standard::input::SingleEnded; use embassy_time::{Delay, Duration, Timer}; use executor::Spawner; use stm32::dma::NoDma; @@ -32,8 +32,12 @@ use defmt::{debug, error, info, trace, unwrap}; use embassy_executor::_export::StaticCell; use embassy_stm32::peripherals::{EXTI6, PF6, PF7, SPI3}; use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; use embassy_sync::pubsub::PubSubChannel; -use physical_node::transducer::{Publish, StatefulPublisher}; +use physical_ads1256::standard::multiplexer::poll::{ + AutocalPoll, AutocalPollStatePub, ModInputOnly, +}; +use physical_node::transducer::{Publish, Publisher, StatefulPublisher}; const AUTOCAL_CONF: Config = Config { status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst), @@ -56,16 +60,31 @@ impl ads1256::BlockingDelay for Ads1256Delay { fn t11_2_delay(&mut self) {} } +type ExampleInput = AutocalPollStatePub< + 'static, + NoopRawMutex, + NoopRawMutex, + ModInputOnly, + Ads1256Delay, + Output<'static, PF7>, + ExtiInput<'static, PF6>, + Spi<'static, SPI3, NoDma, NoDma>, + 10, + 1, +>; + struct Inputs { - ai1: StatefulPublisher, - ai2: StatefulPublisher, - ai3: StatefulPublisher, + ai1: ExampleInput, + ai2: ExampleInput, + ai3: ExampleInput, } // Inputs static ANALOG_INPUTS: StaticCell = StaticCell::new(); -static ADS_1256: StaticCell, ExtiInput>> = StaticCell::new(); -static SPI: StaticCell> = StaticCell::new(); +static ADS_1256: StaticCell< + Mutex, ExtiInput>>, +> = StaticCell::new(); +static SPI: StaticCell>> = StaticCell::new(); #[embassy_executor::main] async fn main(spawner: Spawner) { @@ -86,7 +105,7 @@ async fn main(spawner: Spawner) { let ads1256_data_ready = ExtiInput::new(Input::new(p.PF6, Pull::Up), p.EXTI6); let select_ads1256 = Output::new(p.PF7, Level::High, Speed::VeryHigh); - let spi = SPI.init(Spi::new( + let spi = &*SPI.init(Mutex::new(Spi::new( p.SPI3, p.PC10, p.PC12, @@ -95,86 +114,48 @@ async fn main(spawner: Spawner) { NoDma, Hertz(ads1256::defaults::SPI_CLK_HZ), spi_conf, - )); + ))); - let ads_1256 = ADS_1256.init(Ads1256::new(Ads1256Delay, select_ads1256, ads1256_data_ready)); + let ads_1256 = + &*ADS_1256.init(Mutex::new(Ads1256::new(Ads1256Delay, select_ads1256, ads1256_data_ready))); let inputs = &*ANALOG_INPUTS.init(Inputs { - ai1: StatefulPublisher::new( - Cell::new(f32::ElectricPotential::new::(-1000.0)).into(), - PubSubChannel::new().into(), - ), - ai2: StatefulPublisher::new( - Cell::new(f32::ElectricPotential::new::(-1000.0)).into(), - PubSubChannel::new().into(), - ), - ai3: StatefulPublisher::new( - Cell::new(f32::ElectricPotential::new::(-1000.0)).into(), - PubSubChannel::new().into(), - ), + ai1: AutocalPollStatePub { + poll: AutocalPoll::new( + ModInputOnly { + gain: Gain::X2, + multiplexer: SingleEnded::AIn1.into(), + }, + ads_1256, + spi, + ), + publisher: PubSubChannel::new().into(), + state: Cell::new(f32::ElectricPotential::new::(f32::NAN)).into(), + }, + ai2: AutocalPollStatePub { + poll: AutocalPoll::new( + ModInputOnly { + gain: Gain::X2, + multiplexer: SingleEnded::AIn2.into(), + }, + ads_1256, + spi, + ), + publisher: PubSubChannel::new().into(), + state: Cell::new(f32::ElectricPotential::new::(f32::NAN)).into(), + }, + ai3: AutocalPollStatePub { + poll: AutocalPoll::new( + ModInputOnly { + gain: Gain::X2, + multiplexer: SingleEnded::AIn3.into(), + }, + ads_1256, + spi, + ), + publisher: PubSubChannel::new().into(), + state: Cell::new(f32::ElectricPotential::new::(f32::NAN)).into(), + }, }); - spawner.spawn(log_task(inputs)).unwrap(); - spawner - .spawn(drive_inputs_task(ads_1256, spi, inputs)) - .unwrap(); -} - -#[embassy_executor::task] -async fn drive_inputs_task( - ads_1256: &'static mut Ads1256, ExtiInput<'static, PF6>>, - spi: &'static mut Spi<'static, SPI3, NoDma, NoDma>, - inputs: &'static Inputs, -) { - let Inputs { ai1, ai2, ai3 } = inputs; - - loop { - let mut accumulator = f32::ElectricPotential::new::(0.0); - - let voltage = ads_1256 - .autocal_convert(spi, SingleEnded::AIn0.into(), None, None, None, false) - .await - .unwrap() - .to_voltage(AUTOCAL_CONF.ad_control.gain()); - ai1.update(voltage); - accumulator += voltage; - - let voltage = ads_1256 - .autocal_convert(spi, SingleEnded::AIn1.into(), None, None, None, false) - .await - .unwrap() - .to_voltage(AUTOCAL_CONF.ad_control.gain()); - ai2.update(voltage); - accumulator += voltage; - - let voltage = ads_1256 - .autocal_convert(spi, SingleEnded::AIn2.into(), None, None, None, false) - .await - .unwrap() - .to_voltage(AUTOCAL_CONF.ad_control.gain()); - ai3.update(voltage); - accumulator += voltage; - - let accum_volts = accumulator.get::(); - info!("Immediate loop iteration result, combined volts: {}", accum_volts); - } -} - -#[embassy_executor::task] -async fn log_task(inputs: &'static Inputs) { - let Inputs { ai1, ai2, ai3 } = inputs; - let mut ai1_sub = ai1.subscribe().unwrap(); - let mut ai2_sub = ai2.subscribe().unwrap(); - let mut ai3_sub = ai3.subscribe().unwrap(); - - loop { - let msg = ai1_sub.next_message_pure().await.get::(); - info!("Log task ai1: {}", msg); - - let msg = ai2_sub.next_message_pure().await.get::(); - info!("Log task ai2: {}", msg); - - let msg = ai3_sub.next_message_pure().await.get::(); - info!("Log task ai3: {}", msg); - } } diff --git a/peripheral-components/ads1256/node/src/standard/mod.rs b/peripheral-components/ads1256/node/src/standard/mod.rs index 8c85608..490e4c6 100644 --- a/peripheral-components/ads1256/node/src/standard/mod.rs +++ b/peripheral-components/ads1256/node/src/standard/mod.rs @@ -1,2 +1,2 @@ -#[cfg(feature = "standard-input")] +#[cfg(feature = "standard-multiplexer")] pub mod multiplexer; \ No newline at end of file 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 4a5d8ae..1038272 100644 --- a/peripheral-components/ads1256/node/src/standard/multiplexer/sync/poll.rs +++ b/peripheral-components/ads1256/node/src/standard/multiplexer/sync/poll.rs @@ -25,6 +25,30 @@ where spi: &'a Mutex, } +impl<'a, DeviceMutexT, ModInT, DelayerT, SST, DrdyT, SpiT> + AutocalPoll<'a, DeviceMutexT, ModInT, DelayerT, SST, DrdyT, SpiT> +where + DeviceMutexT: RawMutex, + ModInT: ModInput, + DelayerT: BlockingDelay, + SST: OutputPin, + DrdyT: Wait, + SpiT: SpiBus, +{ + #[inline(always)] + pub fn new( + input_mod: ModInT, + ads1256: &'a Mutex>, + spi: &'a Mutex, + ) -> Self { + Self { + input_mod, + ads1256, + spi, + } + } +} + impl<'a, DeviceMutexT, ModInT, DelayerT, SST, DrdyT, SpiT> Poll for AutocalPoll<'a, DeviceMutexT, ModInT, DelayerT, SST, DrdyT, SpiT> where @@ -40,6 +64,7 @@ where async fn poll(&self) -> Result { let mut ads1256_guard = self.ads1256.lock().await; let ads1256 = ads1256_guard.deref_mut(); + ads1256.data_ready.wait_for_low().await; let result = ads1256 .autocal_convert_m( @@ -71,6 +96,36 @@ pub trait ModInput: Copy { fn data_rate(self) -> Option; } +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct ModInputOnly { + pub multiplexer: Multiplexer, + /// Only used for converting to voltage, this value must match what is set on the ADS1256, it + /// will not *be* set unlike the other fields. + pub gain: Gain, +} + +impl ModInput for ModInputOnly { + fn multiplexer(self) -> Multiplexer { + self.multiplexer + } + + fn gain(self) -> Gain { + self.gain + } + + fn status(self) -> Option { + None + } + + fn ad_control(self) -> Option { + None + } + + fn data_rate(self) -> Option { + None + } +} + /// buffer #[derive(Copy, Clone, Eq, PartialEq)] pub struct ModInStatus {