Skip to content

Commit

Permalink
Re-add channel-specific types.
Browse files Browse the repository at this point in the history
  • Loading branch information
reitermarkus committed Jan 18, 2024
1 parent 5f797bc commit b58cc94
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 94 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ Please find additional examples using hardware in this repository: [driver-examp
use linux_embedded_hal::I2cdev;
use nb::block;

use ads1x1x::{Ads1x1x, SlaveAddr, ChannelSelection};
use ads1x1x::{channel, Ads1x1x, SlaveAddr};

fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let address = SlaveAddr::default();
let mut adc = Ads1x1x::new_ads1013(dev, address);
let value = block!(adc.read(ChannelSelection::DifferentialA0A1)).unwrap();
let value = block!(adc.read(channel::DifferentialA0A1)).unwrap();
println!("Measurement: {}", value);
// get I2C device back
let _dev = adc.destroy_ads1013();
Expand Down
10 changes: 5 additions & 5 deletions examples/all_channels.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use linux_embedded_hal::I2cdev;
use nb::block;

use ads1x1x::{Ads1x1x, ChannelSelection, SlaveAddr};
use ads1x1x::{channel, Ads1x1x, SlaveAddr};

fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let address = SlaveAddr::default();
let mut adc = Ads1x1x::new_ads1015(dev, address);
let values = [
block!(adc.read(ChannelSelection::SingleA0)).unwrap(),
block!(adc.read(ChannelSelection::SingleA1)).unwrap(),
block!(adc.read(ChannelSelection::SingleA2)).unwrap(),
block!(adc.read(ChannelSelection::SingleA3)).unwrap(),
block!(adc.read(channel::SingleA0)).unwrap(),
block!(adc.read(channel::SingleA1)).unwrap(),
block!(adc.read(channel::SingleA2)).unwrap(),
block!(adc.read(channel::SingleA3)).unwrap(),
];
for (channel, value) in values.iter().enumerate() {
println!("Channel {}: {}", channel, value);
Expand Down
4 changes: 2 additions & 2 deletions examples/linux.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use linux_embedded_hal::I2cdev;
use nb::block;

use ads1x1x::{Ads1x1x, ChannelSelection, SlaveAddr};
use ads1x1x::{channel, Ads1x1x, SlaveAddr};

fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let address = SlaveAddr::default();
let mut adc = Ads1x1x::new_ads1013(dev, address);
let value = block!(adc.read(ChannelSelection::DifferentialA0A1)).unwrap();
let value = block!(adc.read(channel::DifferentialA0A1)).unwrap();
println!("Measurement: {}", value);
// get I2C device back
let _dev = adc.destroy_ads1013();
Expand Down
5 changes: 3 additions & 2 deletions examples/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use linux_embedded_hal::I2cdev;
use nb::block;

use ads1x1x::{
channel,
ic::{Ads1115, Resolution16Bit},
interface::I2cInterface,
Ads1x1x, ChannelSelection, SlaveAddr,
Ads1x1x, SlaveAddr,
};

/// Type alias
Expand All @@ -16,7 +17,7 @@ type Adc = Ads1x1x<I2cInterface<I2cdev>, Ads1115, Resolution16Bit, ads1x1x::mode
/// Read a single value from channel A.
/// Returns 0 on Error.
pub fn read(adc: &mut Adc) -> i16 {
block!(adc.read(ChannelSelection::SingleA0)).unwrap_or(0)
block!(adc.read(channel::SingleA0)).unwrap_or(0)
}

fn main() {
Expand Down
96 changes: 96 additions & 0 deletions src/channel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//! ADC input channels
use crate::{ic, Ads1x1x, BitFlags as BF, Config};

use private::ChannelSelection;

/// Marker type for an ADC input channel.
pub trait Channel<T> {
/// Get the channel.
fn channel(self) -> ChannelSelection;
}

macro_rules! impl_channels {
($(#[doc = $doc:expr] $CH:ident => [$($IC:ident),+]),+ $(,)?) => {
mod private {
#[derive(Debug, Clone, Copy)]
/// ADC input channel selection.
pub enum ChannelSelection {
$(
#[doc = $doc]
$CH,
)+
}
}

$(
#[doc = $doc]
pub struct $CH;

$(
impl<DI, CONV, MODE> Channel<Ads1x1x<DI, ic::$IC, CONV, MODE>> for $CH {
fn channel(self) -> ChannelSelection {
ChannelSelection::$CH
}
}
)+
)+
};
}

impl_channels!(
/// Measure signal on input channel 0 differentially to signal on input channel 1.
DifferentialA0A1 => [Ads1013, Ads1014, Ads1015, Ads1113, Ads1114, Ads1115],
/// Measure signal on input channel 0 differentially to signal on input channel 3.
DifferentialA0A3 => [Ads1015, Ads1115],
/// Measure signal on input channel 1 differentially to signal on input channel 3.
DifferentialA1A3 => [Ads1015, Ads1115],
/// Measure signal on input channel 3 differentially to signal on input channel 3.
DifferentialA2A3 => [Ads1015, Ads1115],
/// Measure single-ended signal on input channel 0.
SingleA0 => [Ads1015, Ads1115],
/// Measure single-ended signal on input channel 1.
SingleA1 => [Ads1015, Ads1115],
/// Measure single-ended signal on input channel 2.
SingleA2 => [Ads1015, Ads1115],
/// Measure single-ended signal on input channel 3.
SingleA3 => [Ads1015, Ads1115]
);

impl Config {
pub(crate) fn with_mux_bits(&self, ch: ChannelSelection) -> Self {
match ch {
ChannelSelection::DifferentialA0A1 => self
.with_low(BF::MUX2)
.with_low(BF::MUX1)
.with_low(BF::MUX0),
ChannelSelection::DifferentialA0A3 => self
.with_low(BF::MUX2)
.with_low(BF::MUX1)
.with_high(BF::MUX0),
ChannelSelection::DifferentialA1A3 => self
.with_low(BF::MUX2)
.with_high(BF::MUX1)
.with_low(BF::MUX0),
ChannelSelection::DifferentialA2A3 => self
.with_low(BF::MUX2)
.with_high(BF::MUX1)
.with_high(BF::MUX0),
ChannelSelection::SingleA0 => self
.with_high(BF::MUX2)
.with_low(BF::MUX1)
.with_low(BF::MUX0),
ChannelSelection::SingleA1 => self
.with_high(BF::MUX2)
.with_low(BF::MUX1)
.with_high(BF::MUX0),
ChannelSelection::SingleA2 => self
.with_high(BF::MUX2)
.with_high(BF::MUX1)
.with_low(BF::MUX0),
ChannelSelection::SingleA3 => self
.with_high(BF::MUX2)
.with_high(BF::MUX1)
.with_high(BF::MUX0),
}
}
}
62 changes: 0 additions & 62 deletions src/channels.rs

This file was deleted.

8 changes: 4 additions & 4 deletions src/devices/mode/continuous.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Continuous measurement mode
use crate::{
channels::ChannelSelection, conversion, devices::OperatingMode, interface, mode, Ads1x1x,
Error, ModeChangeError, Register,
conversion, devices::OperatingMode, interface, mode, Ads1x1x, Channel, Error, ModeChangeError,
Register,
};
use core::marker::PhantomData;

Expand Down Expand Up @@ -40,8 +40,8 @@ where
/// Note that when changing the channel in continuous conversion mode, the
/// ongoing conversion will be completed.
/// The following conversions will use the new channel configuration.
pub fn select_channel(&mut self, channel: ChannelSelection) -> Result<(), Error<E>> {
let config = self.config.with_mux_bits(channel);
pub fn select_channel<CH: Channel<Self>>(&mut self, channel: CH) -> Result<(), Error<E>> {
let config = self.config.with_mux_bits(channel.channel());
self.iface.write_register(Register::CONFIG, config.bits)?;
self.config = config;
Ok(())
Expand Down
10 changes: 5 additions & 5 deletions src/devices/mode/oneshot.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Common functions
use crate::{
conversion, devices::OperatingMode, interface, mode, Ads1x1x, BitFlags, ChannelSelection,
Config, Error, ModeChangeError, Register,
conversion, devices::OperatingMode, interface, mode, Ads1x1x, BitFlags, Channel, Config, Error,
ModeChangeError, Register,
};
use core::marker::PhantomData;

Expand Down Expand Up @@ -52,14 +52,15 @@ where
/// In case a measurement was requested and after is it is finished a
/// measurement on a different channel is requested, a new measurement on
/// using the new channel selection is triggered.
pub fn read(&mut self, channel: ChannelSelection) -> nb::Result<i16, Error<E>> {
pub fn read<CH: Channel<Self>>(&mut self, channel: CH) -> nb::Result<i16, Error<E>> {
if self
.is_measurement_in_progress()
.map_err(nb::Error::Other)?
{
return Err(nb::Error::WouldBlock);
}
let same_channel = self.config == self.config.with_mux_bits(channel);
let config = self.config.with_mux_bits(channel.channel());
let same_channel = self.config == config;
if self.a_conversion_was_started && same_channel {
// result is ready
let value = self
Expand All @@ -69,7 +70,6 @@ where
self.a_conversion_was_started = false;
return Ok(CONV::convert_measurement(value));
}
let config = self.config.with_mux_bits(channel);
self.trigger_measurement(&config)
.map_err(nb::Error::Other)?;
self.config = config;
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@
//!
//! ### Make a one-shot measurement
//! ```no_run
//! use ads1x1x::{Ads1x1x, SlaveAddr, ChannelSelection};
//! use ads1x1x::{channel, Ads1x1x, SlaveAddr};
//! use linux_embedded_hal::I2cdev;
//! use nb::block;
//!
//! let dev = I2cdev::new("/dev/i2c-1").unwrap();
//! let mut adc = Ads1x1x::new_ads1013(dev, SlaveAddr::default());
//! let measurement = block!(adc.read(ChannelSelection::DifferentialA0A1)).unwrap();
//! let measurement = block!(adc.read(channel::DifferentialA0A1)).unwrap();
//! println!("Measurement: {}", measurement);
//! let _dev = adc.destroy_ads1013(); // get I2C device back
//! ```
Expand Down Expand Up @@ -234,8 +234,8 @@ impl BitFlags {
const COMP_QUE0: u16 = 0b0000_0000_0000_0001;
}

mod channels;
pub use crate::channels::ChannelSelection;
pub mod channel;
pub use channel::Channel;
mod construction;
mod conversion;
pub use crate::conversion::{ConvertMeasurement, ConvertThreshold};
Expand Down
10 changes: 5 additions & 5 deletions tests/mux.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ads1x1x::ChannelSelection;
use ads1x1x::channel;
use embedded_hal_mock::eh1::i2c::Transaction as I2cTrans;
use nb::block;

Expand Down Expand Up @@ -32,7 +32,7 @@ macro_rules! mux_test {
I2cTrans::write_read(DEV_ADDR, vec![Register::CONVERSION], vec![0x80, 0x00]),
];
let mut dev = new(&transactions);
let measurement = block!(dev.read(ChannelSelection::$CS)).unwrap();
let measurement = block!(dev.read(channel::$CS)).unwrap();
assert_eq!(-2048, measurement);
destroy(dev);
}
Expand Down Expand Up @@ -66,8 +66,8 @@ macro_rules! mux_test {
I2cTrans::write_read(DEV_ADDR, vec![Register::CONVERSION], vec![0x80, 0x00]),
];
let mut dev = new(&transactions);
assert_would_block!(dev.read(ChannelSelection::$CS));
let measurement = block!(dev.read(ChannelSelection::$other_CS)).unwrap();
assert_would_block!(dev.read(channel::$CS));
let measurement = block!(dev.read(channel::$other_CS)).unwrap();
assert_eq!(-2048, measurement);
destroy(dev);
}
Expand All @@ -88,7 +88,7 @@ macro_rules! mux_test {
];
let dev = new(&transactions);
let mut dev = dev.into_continuous().ok().unwrap();
dev.select_channel(ChannelSelection::$CS).unwrap();
dev.select_channel(channel::$CS).unwrap();
destroy(dev);
}
}
Expand Down
6 changes: 3 additions & 3 deletions tests/tier1.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ads1x1x::{ChannelSelection, DataRate12Bit, DataRate16Bit};
use ads1x1x::{channel, DataRate12Bit, DataRate16Bit};
use embedded_hal_mock::eh1::i2c::Transaction as I2cTrans;
use nb::block;

Expand All @@ -25,7 +25,7 @@ macro_rules! measure_tests {
vec![config.msb(), config.lsb()],
)];
let mut dev = $create(&transactions);
assert_would_block!(dev.read(ChannelSelection::DifferentialA0A1));
assert_would_block!(dev.read(channel::DifferentialA0A1));
$destroy(dev);
}
}
Expand All @@ -52,7 +52,7 @@ macro_rules! measure_tests {
I2cTrans::write_read(DEV_ADDR, vec![Register::CONVERSION], vec![0x80, 0x00]),
];
let mut dev = $create(&transactions);
let measurement = block!(dev.read(ChannelSelection::DifferentialA0A1)).unwrap();
let measurement = block!(dev.read(channel::DifferentialA0A1)).unwrap();
assert_eq!($expected, measurement);
$destroy(dev);
}
Expand Down

0 comments on commit b58cc94

Please sign in to comment.