|
|
|
@@ -0,0 +1,382 @@
|
|
|
|
|
use ads1256::{
|
|
|
|
|
AdControl, Ads1256, BlockingDelay, DataRate, Gain, 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 physical_node::CriticalError;
|
|
|
|
|
use uom::si::f32;
|
|
|
|
|
|
|
|
|
|
#[derive(PollVariants)]
|
|
|
|
|
#[value_type = "f32::ElectricPotential"]
|
|
|
|
|
#[error_type = "CriticalError"]
|
|
|
|
|
pub struct AutocalPoll<'a, DeviceMutexT, ModInT, DelayerT, SST, DrdyT, SpiT>
|
|
|
|
|
where
|
|
|
|
|
DeviceMutexT: RawMutex,
|
|
|
|
|
ModInT: ModInput,
|
|
|
|
|
DelayerT: BlockingDelay,
|
|
|
|
|
SST: OutputPin,
|
|
|
|
|
DrdyT: Wait,
|
|
|
|
|
SpiT: SpiBus,
|
|
|
|
|
{
|
|
|
|
|
input_mod: ModInT,
|
|
|
|
|
ads1256: &'a Mutex<DeviceMutexT, Ads1256<DelayerT, SST, DrdyT>>,
|
|
|
|
|
spi: &'a Mutex<DeviceMutexT, SpiT>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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<DeviceMutexT, Ads1256<DelayerT, SST, DrdyT>>,
|
|
|
|
|
spi: &'a Mutex<DeviceMutexT, SpiT>,
|
|
|
|
|
) -> 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
|
|
|
|
|
DeviceMutexT: RawMutex,
|
|
|
|
|
ModInT: ModInput,
|
|
|
|
|
DelayerT: BlockingDelay,
|
|
|
|
|
SST: OutputPin,
|
|
|
|
|
DrdyT: Wait,
|
|
|
|
|
SpiT: SpiBus,
|
|
|
|
|
{
|
|
|
|
|
type Value = f32::ElectricPotential;
|
|
|
|
|
type Error = CriticalError;
|
|
|
|
|
|
|
|
|
|
async fn poll(&self) -> Result<Self::Value, CriticalError> {
|
|
|
|
|
let mut ads1256_guard = self.ads1256.lock().await;
|
|
|
|
|
let ads1256 = ads1256_guard.deref_mut();
|
|
|
|
|
//TODO: ADS1256 documentation seems to say we should be waiting for drdy low after
|
|
|
|
|
// issuing standby command but it never goes low.
|
|
|
|
|
|
|
|
|
|
let result = ads1256
|
|
|
|
|
.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;
|
|
|
|
|
|
|
|
|
|
match result {
|
|
|
|
|
Ok(conversion) => Ok(conversion.to_voltage(self.input_mod.gain())),
|
|
|
|
|
Err(_) => Err(CriticalError::Communication),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub trait ModInput: Copy {
|
|
|
|
|
fn multiplexer(self) -> Multiplexer;
|
|
|
|
|
|
|
|
|
|
fn gain(self) -> Gain;
|
|
|
|
|
|
|
|
|
|
fn status(self) -> Option<Status>;
|
|
|
|
|
|
|
|
|
|
fn ad_control(self) -> Option<AdControl>;
|
|
|
|
|
|
|
|
|
|
fn data_rate(self) -> Option<DataRate>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[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<Status> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn ad_control(self) -> Option<AdControl> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn data_rate(self) -> Option<DataRate> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// buffer
|
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
|
|
|
pub struct ModInStatus {
|
|
|
|
|
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,
|
|
|
|
|
pub status: Status,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ModInput for ModInStatus {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn multiplexer(self) -> Multiplexer {
|
|
|
|
|
self.multiplexer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn gain(self) -> Gain {
|
|
|
|
|
self.gain
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn status(self) -> Option<Status> {
|
|
|
|
|
Some(self.status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn ad_control(self) -> Option<AdControl> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn data_rate(self) -> Option<DataRate> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// gain
|
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
|
|
|
pub struct ModInAdControl {
|
|
|
|
|
pub multiplexer: Multiplexer,
|
|
|
|
|
pub ad_control: AdControl,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ModInput for ModInAdControl {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn multiplexer(self) -> Multiplexer {
|
|
|
|
|
self.multiplexer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn gain(self) -> Gain {
|
|
|
|
|
self.ad_control.gain()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn status(self) -> Option<Status> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn ad_control(self) -> Option<AdControl> {
|
|
|
|
|
Some(self.ad_control)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn data_rate(self) -> Option<DataRate> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// data rate
|
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
|
|
|
pub struct ModInDataRate {
|
|
|
|
|
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,
|
|
|
|
|
pub data_rate: DataRate,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ModInput for ModInDataRate {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn multiplexer(self) -> Multiplexer {
|
|
|
|
|
self.multiplexer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn gain(self) -> Gain {
|
|
|
|
|
self.gain
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn status(self) -> Option<Status> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn ad_control(self) -> Option<AdControl> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn data_rate(self) -> Option<DataRate> {
|
|
|
|
|
Some(self.data_rate)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// buffer, gain
|
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
|
|
|
pub struct ModInStatAdc {
|
|
|
|
|
pub multiplexer: Multiplexer,
|
|
|
|
|
pub status: Status,
|
|
|
|
|
pub ad_control: AdControl,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ModInput for ModInStatAdc {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn multiplexer(self) -> Multiplexer {
|
|
|
|
|
self.multiplexer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn gain(self) -> Gain {
|
|
|
|
|
self.ad_control.gain()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn status(self) -> Option<Status> {
|
|
|
|
|
Some(self.status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn ad_control(self) -> Option<AdControl> {
|
|
|
|
|
Some(self.ad_control)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn data_rate(self) -> Option<DataRate> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// buffer, data rate
|
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
|
|
|
pub struct ModInStatDrate {
|
|
|
|
|
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,
|
|
|
|
|
pub status: Status,
|
|
|
|
|
pub data_rate: DataRate,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ModInput for ModInStatDrate {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn multiplexer(self) -> Multiplexer {
|
|
|
|
|
self.multiplexer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn gain(self) -> Gain {
|
|
|
|
|
self.gain
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn status(self) -> Option<Status> {
|
|
|
|
|
Some(self.status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn ad_control(self) -> Option<AdControl> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn data_rate(self) -> Option<DataRate> {
|
|
|
|
|
Some(self.data_rate)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// gain, data rate
|
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
|
|
|
pub struct ModInAdcDrate {
|
|
|
|
|
pub multiplexer: Multiplexer,
|
|
|
|
|
pub ad_control: AdControl,
|
|
|
|
|
pub data_rate: DataRate,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ModInput for ModInAdcDrate {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn multiplexer(self) -> Multiplexer {
|
|
|
|
|
self.multiplexer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn gain(self) -> Gain {
|
|
|
|
|
self.ad_control.gain()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn status(self) -> Option<Status> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn ad_control(self) -> Option<AdControl> {
|
|
|
|
|
Some(self.ad_control)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn data_rate(self) -> Option<DataRate> {
|
|
|
|
|
Some(self.data_rate)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// buffer, gain, data rate
|
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
|
|
|
pub struct ModInAll {
|
|
|
|
|
pub multiplexer: Multiplexer,
|
|
|
|
|
pub status: Status,
|
|
|
|
|
pub ad_control: AdControl,
|
|
|
|
|
pub data_rate: DataRate,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ModInput for ModInAll {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn multiplexer(self) -> Multiplexer {
|
|
|
|
|
self.multiplexer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn gain(self) -> Gain {
|
|
|
|
|
self.ad_control.gain()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn status(self) -> Option<Status> {
|
|
|
|
|
Some(self.status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn ad_control(self) -> Option<AdControl> {
|
|
|
|
|
Some(self.ad_control)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn data_rate(self) -> Option<DataRate> {
|
|
|
|
|
Some(self.data_rate)
|
|
|
|
|
}
|
|
|
|
|
}
|