Removed a bunch of over abstracted bullshit.

This commit is contained in:
Zachary Sunforge
2024-06-22 09:45:12 -07:00
parent 02ddde0c5d
commit a95cb64941
35 changed files with 26 additions and 1600 deletions

View File

@ -1,177 +0,0 @@
#![no_std]
#![no_main]
use core::cell::Cell;
use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs;
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, Buffer, ClockOut, Config, DataRate, DigitalIo,
DigitalIoDirection, DigitalIoState, Gain, Multiplexer, MuxInput, Sdcs, Status,
};
use embassy_time::Delay;
use executor::Spawner;
use stm32::dma::NoDma;
use stm32::exti::ExtiInput;
use stm32::gpio::{Input, Level, Output, Pull, Speed};
use stm32::spi::Spi;
use stm32::time::Hertz;
use stm32::{pac, spi};
use uom::si::electric_potential::volt;
use uom::si::f32;
use defmt::{debug, error, info, trace, unwrap};
use static_cell::StaticCell;
use embassy_stm32::peripherals::{PA1, PA3, SPI1};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_sync::pubsub::PubSubChannel;
use physical_node::transducer::{Publish, StatefulPublisher};
const AUTOCAL_CONF: Config = Config {
status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst),
multiplexer: Multiplexer::setting(MuxInput::AIn0, MuxInput::Common),
ad_control: AdControl::setting(Gain::X2, Sdcs::Off, ClockOut::Off),
data_rate: DataRate::Sps2_5,
digital_io: DigitalIo::setting(DigitalIoState::default(), DigitalIoDirection::default()),
};
struct Ads1256Delay;
impl ads1256::BlockingDelay for Ads1256Delay {
#[inline]
fn t6_delay(&mut self) {
Delay.delay_us(1u32);
}
fn t11_1_delay(&mut self) {}
fn t11_2_delay(&mut self) {}
}
struct Inputs {
ai0: StatefulPublisher<f32::ElectricPotential, NoopRawMutex, 10, 1>,
ai1: StatefulPublisher<f32::ElectricPotential, NoopRawMutex, 10, 1>,
ai2: StatefulPublisher<f32::ElectricPotential, NoopRawMutex, 10, 1>,
}
// Inputs
static ANALOG_INPUTS: StaticCell<Inputs> = StaticCell::new();
static ADS_1256: StaticCell<Ads1256<Ads1256Delay, Output<PA1>, ExtiInput<PA3>>> = StaticCell::new();
static SPI: StaticCell<Spi<SPI1, NoDma, NoDma>> = StaticCell::new();
#[embassy_executor::main]
async fn main(spawner: Spawner) {
unsafe {
pac::FLASH.acr().modify(|v| {
v.set_prften(true);
v.set_icen(true);
v.set_dcen(true);
});
}
let p = embassy_stm32::init(Default::default());
let mut spi_conf = spi::Config::default();
spi_conf.mode = spi::MODE_1;
spi_conf.bit_order = spi::BitOrder::MsbFirst;
spi_conf.frequency = Hertz(ads1256::defaults::SPI_CLK_HZ);
let ads1256_data_ready = ExtiInput::new(Input::new(p.PA3, Pull::Up), p.EXTI3);
let select_ads1256 = Output::new(p.PA1, Level::High, Speed::VeryHigh);
let spi = SPI.init(Spi::new(
p.SPI1,
p.PA5,
p.PA7,
p.PA6,
NoDma,
NoDma,
spi_conf,
));
let ads_1256 = ADS_1256.init(Ads1256::new(Ads1256Delay, select_ads1256, ads1256_data_ready));
ads_1256.write_config(spi, AUTOCAL_CONF).unwrap();
let inputs = &*ANALOG_INPUTS.init(Inputs {
ai0: StatefulPublisher::new(
Cell::new(f32::ElectricPotential::new::<volt>(f32::NAN)).into(),
PubSubChannel::new().into(),
),
ai1: StatefulPublisher::new(
Cell::new(f32::ElectricPotential::new::<volt>(f32::NAN)).into(),
PubSubChannel::new().into(),
),
ai2: StatefulPublisher::new(
Cell::new(f32::ElectricPotential::new::<volt>(f32::NAN)).into(),
PubSubChannel::new().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<Ads1256Delay, Output<'static, PA1>, ExtiInput<'static, PA3>>,
spi: &'static mut Spi<'static, SPI1, NoDma, NoDma>,
inputs: &'static Inputs,
) {
let Inputs { ai0, ai1, ai2 } = inputs;
loop {
let mut accumulator = f32::ElectricPotential::new::<volt>(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());
ai0.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());
ai1.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());
ai2.update(voltage);
accumulator += voltage;
let accum_volts = accumulator.get::<volt>();
info!("Immediate loop iteration result, combined volts: {}", accum_volts);
}
}
#[embassy_executor::task]
async fn log_task(inputs: &'static Inputs) {
let Inputs { ai0, ai1, ai2 } = inputs;
let mut ai0_sub = ai0.subscribe().unwrap();
let mut ai1_sub = ai1.subscribe().unwrap();
let mut ai2_sub = ai2.subscribe().unwrap();
loop {
let msg = ai0_sub.next_message_pure().await.get::<volt>();
info!("Log task ai0: {}", msg);
let msg = ai1_sub.next_message_pure().await.get::<volt>();
info!("Log task ai1: {}", msg);
let msg = ai2_sub.next_message_pure().await.get::<volt>();
info!("Log task ai2: {}", msg);
}
}

View File

@ -1,195 +0,0 @@
#![no_std]
#![no_main]
use core::cell::Cell;
use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs;
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, Buffer, ClockOut, Config, DState, DataRate, DigitalIo,
DigitalIoDirection, DigitalIoState, Gain, Multiplexer, MuxInput, Sdcs, Status,
};
use embassy_time::{Delay, Duration, Timer};
use executor::Spawner;
use stm32::dma::NoDma;
use stm32::exti::ExtiInput;
use stm32::gpio::{Input, Level, Output, Pull, Speed};
use stm32::spi::Spi;
use stm32::time::Hertz;
use stm32::{pac, spi};
use uom::si::electric_potential::volt;
use uom::si::f32;
use defmt::info;
use static_cell::StaticCell;
use embassy_stm32::peripherals::{PA1, PA3, SPI1};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_sync::mutex::Mutex;
use embassy_sync::pubsub::PubSubChannel;
use physical_ads1256::standard::multiplexer::poll::{
AutocalPoll, AutocalPollStatePub, ModInputOnly,
};
use physical_node::transducer::input::Poll;
use physical_node::transducer::{Publish, Publisher, StatefulPublisher};
const AUTOCAL_CONF: Config = Config {
status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst),
multiplexer: Multiplexer::setting(MuxInput::AIn0, MuxInput::Common),
ad_control: AdControl::setting(Gain::X2, Sdcs::Off, ClockOut::Off),
data_rate: DataRate::Sps2_5,
digital_io: DigitalIo::setting(DigitalIoState::default(), DigitalIoDirection::default()),
};
struct Ads1256Delay;
impl ads1256::BlockingDelay for Ads1256Delay {
#[inline]
fn t6_delay(&mut self) {
Delay.delay_us(1u32);
}
fn t11_1_delay(&mut self) {}
fn t11_2_delay(&mut self) {}
}
type ExampleInput = AutocalPollStatePub<
'static,
NoopRawMutex,
NoopRawMutex,
ModInputOnly,
Ads1256Delay,
Output<'static, PA1>,
ExtiInput<'static, PA3>,
Spi<'static, SPI1, NoDma, NoDma>,
10,
1,
>;
struct Inputs {
ai1: ExampleInput,
ai2: ExampleInput,
ai3: ExampleInput,
}
// Inputs
static ANALOG_INPUTS: StaticCell<Inputs> = StaticCell::new();
static ADS_1256: StaticCell<
Mutex<NoopRawMutex, Ads1256<Ads1256Delay, Output<PA1>, ExtiInput<PA3>>>,
> = StaticCell::new();
static SPI: StaticCell<Mutex<NoopRawMutex, Spi<SPI1, NoDma, NoDma>>> = StaticCell::new();
#[embassy_executor::main]
async fn main(spawner: Spawner) {
unsafe {
pac::FLASH.acr().modify(|v| {
v.set_prften(true);
v.set_icen(true);
v.set_dcen(true);
});
}
let p = embassy_stm32::init(Default::default());
let mut spi_conf = spi::Config::default();
spi_conf.mode = spi::MODE_1;
spi_conf.bit_order = spi::BitOrder::MsbFirst;
spi_conf.frequency = Hertz(ads1256::defaults::SPI_CLK_HZ);
let ads1256_data_ready = ExtiInput::new(Input::new(p.PA3, Pull::Up), p.EXTI3);
let select_ads1256 = Output::new(p.PA1, Level::High, Speed::VeryHigh);
let spi = SPI.init(Mutex::new(
Spi::new(
p.SPI1,
p.PA5,
p.PA7,
p.PA6,
NoDma,
NoDma,
spi_conf,
)
));
let ads_1256 =
ADS_1256.init(Mutex::new(Ads1256::new(Ads1256Delay, select_ads1256, ads1256_data_ready)));
ads_1256
.get_mut()
.write_config(spi.get_mut(), AUTOCAL_CONF)
.unwrap();
let inputs = &*ANALOG_INPUTS.init(Inputs {
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::<volt>(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::<volt>(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::<volt>(f32::NAN)).into(),
},
});
spawner.spawn(log_task(&inputs.ai1, 1)).unwrap();
spawner.spawn(log_task(&inputs.ai2, 2)).unwrap();
spawner.spawn(log_task(&inputs.ai3, 3)).unwrap();
spawner
.spawn(poll_task(&inputs.ai1, 1, Duration::from_secs(5)))
.unwrap();
spawner
.spawn(poll_task(&inputs.ai2, 2, Duration::from_secs(10)))
.unwrap();
spawner
.spawn(poll_task(&inputs.ai3, 3, Duration::from_secs(20)))
.unwrap();
}
#[embassy_executor::task(pool_size = 3)]
async fn poll_task(input: &'static ExampleInput, input_num: u8, every: Duration) {
loop {
Timer::after(every).await;
let result = input.poll().await.unwrap().get::<volt>();
info!("ai{} poll result: {} volts", input_num, result);
}
}
#[embassy_executor::task(pool_size = 3)]
async fn log_task(input: &'static ExampleInput, input_num: u8) {
let mut subscriber = input.subscribe().unwrap();
loop {
let msg = subscriber.next_message_pure().await.get::<volt>();
info!("Log task ai{}: {}", input_num, msg);
}
}

View File

@ -1,125 +0,0 @@
#![no_std]
#![no_main]
use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs;
// Necessary unused import.
use {defmt_rtt as _, panic_probe as _};
use {embassy_executor as executor, embassy_stm32 as stm32};
use ads1256::standard::input::{Differential, SingleEnded};
use ads1256::{
AdControl, Ads1256, AutoCal, BitOrder, Buffer, ClockOut, Config, DataRate, DigitalIo,
DigitalIoDirection, DigitalIoState, Gain, Multiplexer, MuxInput, Sdcs, Status,
};
use embassy_time::Delay;
use executor::Spawner;
use stm32::dma::NoDma;
use stm32::exti::ExtiInput;
use stm32::gpio::{Input, Level, Output, Pull, Speed};
use stm32::spi::Spi;
use stm32::time::Hertz;
use stm32::{pac, spi};
use uom::si::electric_potential::{millivolt, volt};
use defmt::info;
use physical::transducer::{lm35, thermocouple_k};
use uom::si::thermodynamic_temperature::degree_celsius;
const AUTOCAL_CONF: Config = Config {
status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst),
multiplexer: Multiplexer::setting(MuxInput::AIn0, MuxInput::AIn1),
ad_control: AdControl::setting(Gain::X64, Sdcs::Off, ClockOut::Off),
data_rate: DataRate::Sps2_5,
digital_io: DigitalIo::setting(DigitalIoState::default(), DigitalIoDirection::default()),
};
struct Ads1256Delay;
impl ads1256::BlockingDelay for Ads1256Delay {
#[inline]
fn t6_delay(&mut self) {
Delay.delay_us(1u32);
}
fn t11_1_delay(&mut self) {}
fn t11_2_delay(&mut self) {}
}
#[embassy_executor::main]
async fn main(spawner: Spawner) {
unsafe {
pac::FLASH.acr().modify(|v| {
v.set_prften(true);
v.set_icen(true);
v.set_dcen(true);
});
}
let p = embassy_stm32::init(Default::default());
let mut spi_conf = spi::Config::default();
spi_conf.mode = spi::MODE_1;
spi_conf.bit_order = spi::BitOrder::MsbFirst;
spi_conf.frequency = Hertz(ads1256::defaults::SPI_CLK_HZ);
let ads1256_data_ready = ExtiInput::new(Input::new(p.PA3, Pull::Up), p.EXTI3);
let select_ads1256 = Output::new(p.PA1, Level::High, Speed::VeryHigh);
let mut spi = Spi::new(
p.SPI1,
p.PA5,
p.PA7,
p.PA6,
NoDma,
NoDma,
spi_conf,
);
let mut ads_1256 = Ads1256::new(Ads1256Delay, select_ads1256, ads1256_data_ready);
ads_1256.write_config(&mut spi, AUTOCAL_CONF).unwrap();
ads_1256.self_calibrate(&mut spi).await.unwrap();
loop {
let gain = Gain::X2;
let reference = ads_1256
.autocal_convert(
&mut spi,
SingleEnded::AIn2.into(),
None,
Some(AUTOCAL_CONF.ad_control.with_gain(gain)),
None,
false,
)
.await
.unwrap()
.to_voltage(gain);
let reference_volts = reference.get::<volt>();
let reference = lm35::convert(reference).unwrap();
let reference_celsius = reference.get::<degree_celsius>();
info!(
"Reference junction temperature: {}°C, from voltage reading: {}V",
reference_celsius, reference_volts
);
let gain = Gain::X64;
let voltage = ads_1256
.autocal_convert(
&mut spi,
Differential::AIn0.into(),
None,
Some(AUTOCAL_CONF.ad_control.with_gain(gain)),
None,
false,
)
.await
.unwrap()
.to_voltage(AUTOCAL_CONF.ad_control.gain());
let mv = voltage.get::<millivolt>();
let temperature = thermocouple_k::convert_direct(voltage, reference).unwrap();
let celsius = temperature.get::<degree_celsius>();
info!("Thermocouple temperature: {}°C, from reading: {}mV", celsius, mv);
}
}