Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split API into one distinct type per device variant. #17

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
When changing into continuous mode the measurements are started and to stop one
can simply change into one-shot mode. (This is how the hardware does it anyway).
The one-shot mode is not affected.
When changing the mode an I2C communication error can occur but the unchanged device
When changing the mode an I²C communication error can occur but the unchanged device
can now be retrieved.

## [0.1.0] - 2018-11-21
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ include = [
edition = "2021"

[dependencies]
nb = "1"
bitflags = "2"
embedded-hal = "1"
nb = "1"

[dev-dependencies]
embedded-hal-mock = { version = "0.10", default-features = false, features = ["eh1"] }
Expand Down
47 changes: 24 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ analog-to-digital converters (ADC), based on the [`embedded-hal`] traits.
[Introductory blog post]

This driver allows you to:
- Set the operating mode to one-shot or continuous. See: `into_continuous()`.
- Make a measurement in one-shot mode. See: `read()`.
- Start continuous conversion mode. See: `start()`.
- Read the last measurement made in continuous conversion mode. See: `read()`.
- Set the data rate. See: `set_data_rate()`.
- Set the full-scale range (gain amplifier). See `set_full_scale_range()`.
- Read whether a measurement is in progress. See: `is_measurement_in_progress()`.
- Set the ALERT/RDY pin to be used as conversion-ready pin. See: `use_alert_rdy_pin_as_ready()`.
- Set the operating mode to one-shot or continuous. See `Ads1115::into_continuous`.
- Make a measurement in one-shot mode. See `Ads1115::read`.
- Start continuous conversion mode. See `Ads1115::start`.
- Read the last measurement made in continuous conversion mode. See `Ads1115::read`.
- Set the data rate. See `Ads1115::set_data_rate`.
- Set the full-scale range (gain amplifier). Se `Ads1115::set_full_scale_range`.
- Read whether a measurement is in progress. See `Ads1115::is_measurement_in_progress`.
- Set the ALERT/RDY pin to be used as conversion-ready pin. See `Ads1115::use_alert_rdy_pin_as_ready`.
- Comparator:
- Set the low and high thresholds. See: `set_high_threshold_raw()`.
- Set the comparator mode. See: `set_comparator_mode()`.
- Set the comparator polarity. See: `set_comparator_polarity()`.
- Set the comparator latching. See: `set_comparator_latching()`.
- Set the comparator queue. See: `set_comparator_queue()`.
- Disable the comparator. See: `disable_comparator()`.
- Set the low and high thresholds. See `Ads1115::set_high_threshold_raw`.
- Set the comparator mode. See `Ads1115::set_comparator_mode`.
- Set the comparator polarity. See `Ads1115::set_comparator_polarity`.
- Set the comparator latching. See `Ads1115::set_comparator_latching`.
- Set the comparator queue. See `Ads1115::set_comparator_queue`.
- Disable the comparator. See `Ads1115::disable_comparator`.

## The devices

Expand All @@ -48,7 +48,7 @@ thermocouples.
The devices operate either in continuous-conversion mode, or in a
single-shot mode that automatically powers down after a conversion.
Single-shot mode significantly reduces current consumption during idle
periods. Data is transferred through I2C.
periods. Data is transferred through I²C.

Here is a comparison of the caracteristics of the devices:

Expand All @@ -70,26 +70,27 @@ Datasheets:
To use this driver, import this crate and an `embedded_hal` implementation,
then instantiate the appropriate device.
In the following examples an instance of the device ADS1013 will be created
as an example. Other devices can be created with similar methods like:
`Ads1x1x::new_ads1114(...)`.
as an example.

Please find additional examples using hardware in this repository: [driver-examples]

[driver-examples]: https://github.com/eldruin/driver-examples

```rust
use ads1x1x::{channel, Ads1013, TargetAddr};
use linux_embedded_hal::I2cdev;
use nb::block;

use ads1x1x::{channel, Ads1x1x, TargetAddr};

fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut adc = Ads1x1x::new_ads1013(dev, TargetAddr::default());
let i2c = I2cdev::new("/dev/i2c-1").unwrap();
let mut adc = Ads1013::new(i2c, TargetAddr::default());

let value = block!(adc.read(channel::DifferentialA0A1)).unwrap();
println!("Measurement: {}", value);
// get I2C device back
let _dev = adc.destroy_ads1013();

// Get the I²C peripheral back.
let i2c = adc.release();
drop(i2c);
}
```

Expand Down
9 changes: 4 additions & 5 deletions examples/all_channels.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use linux_embedded_hal::I2cdev;
use nb::block;

use ads1x1x::{channel, Ads1x1x, TargetAddr};
use ads1x1x::{channel, Ads1015, TargetAddr};

fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut adc = Ads1x1x::new_ads1015(dev, TargetAddr::default());
let i2c = I2cdev::new("/dev/i2c-1").unwrap();
let mut adc = Ads1015::new(i2c, TargetAddr::default());

let values = [
block!(adc.read(channel::SingleA0)).unwrap(),
block!(adc.read(channel::SingleA1)).unwrap(),
Expand All @@ -15,6 +16,4 @@ fn main() {
for (channel, value) in values.iter().enumerate() {
println!("Channel {}: {}", channel, value);
}
// get I2C device back
let _dev = adc.destroy_ads1015();
}
9 changes: 4 additions & 5 deletions examples/linux.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use linux_embedded_hal::I2cdev;
use nb::block;

use ads1x1x::{channel, Ads1x1x, TargetAddr};
use ads1x1x::{channel, Ads1013, TargetAddr};

fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut adc = Ads1x1x::new_ads1013(dev, TargetAddr::default());
let i2c = I2cdev::new("/dev/i2c-1").unwrap();
let mut adc = Ads1013::new(i2c, TargetAddr::default());

let value = block!(adc.read(channel::DifferentialA0A1)).unwrap();
println!("Measurement: {}", value);
// get I2C device back
let _dev = adc.destroy_ads1013();
}
14 changes: 4 additions & 10 deletions examples/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,10 @@
use linux_embedded_hal::I2cdev;
use nb::block;

use ads1x1x::{
channel,
ic::{Ads1115, Resolution16Bit},
Ads1x1x, TargetAddr,
};
use ads1x1x::{channel, mode, Ads1115, TargetAddr};

/// Type alias
type Adc = Ads1x1x<I2cdev, Ads1115, Resolution16Bit, ads1x1x::mode::OneShot>;
type Adc = Ads1115<I2cdev, mode::OneShot>;

/// Read a single value from channel A.
/// Returns 0 on Error.
Expand All @@ -20,11 +16,9 @@ pub fn read(adc: &mut Adc) -> i16 {
}

fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut adc = Ads1x1x::new_ads1115(dev, TargetAddr::default());
let i2c = I2cdev::new("/dev/i2c-1").unwrap();
let mut adc = Ads1115::new(i2c, TargetAddr::default());

let value = read(&mut adc);
println!("Measurement: {}", value);
// get I2C device back
let _dev = adc.destroy_ads1115();
}
63 changes: 33 additions & 30 deletions src/channel.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
//! ADC input channels
use crate::{ic, Ads1x1x, BitFlags as BF, Config};
//! ADC input channels.
use crate::{Ads1013, Ads1014, Ads1015, Ads1113, Ads1114, Ads1115, Config};

use private::ChannelSelection;

/// Marker type for an ADC input channel.
pub trait ChannelId<T> {
pub trait ChannelId<T>: private::Sealed {
/// Get the channel.
fn channel_id() -> ChannelSelection;
}

macro_rules! impl_channels {
($(#[doc = $doc:expr] $CH:ident => [$($IC:ident),+]),+ $(,)?) => {
($(#[doc = $doc:expr] $CH:ident => [$($Ads:ident),+]),+ $(,)?) => {
mod private {
pub trait Sealed {}

#[derive(Debug, Clone, Copy)]
/// ADC input channel selection.
pub enum ChannelSelection {
Expand All @@ -26,8 +28,10 @@ macro_rules! impl_channels {
#[doc = $doc]
pub struct $CH;

impl private::Sealed for $CH {}

$(
impl<I2C, CONV, MODE> ChannelId<Ads1x1x<I2C, ic::$IC, CONV, MODE>> for $CH {
impl<I2C, MODE> ChannelId<$Ads<I2C, MODE>> for $CH {
fn channel_id() -> ChannelSelection {
ChannelSelection::$CH
}
Expand Down Expand Up @@ -60,37 +64,36 @@ 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),
.difference(Self::MUX2)
.difference(Self::MUX1)
.difference(Self::MUX0),
ChannelSelection::DifferentialA0A3 => self
.with_low(BF::MUX2)
.with_low(BF::MUX1)
.with_high(BF::MUX0),
.difference(Self::MUX2)
.difference(Self::MUX1)
.union(Self::MUX0),
ChannelSelection::DifferentialA1A3 => self
.with_low(BF::MUX2)
.with_high(BF::MUX1)
.with_low(BF::MUX0),
.difference(Self::MUX2)
.union(Self::MUX1)
.difference(Self::MUX0),
ChannelSelection::DifferentialA2A3 => self
.with_low(BF::MUX2)
.with_high(BF::MUX1)
.with_high(BF::MUX0),
.difference(Self::MUX2)
.union(Self::MUX1)
.union(Self::MUX0),
ChannelSelection::SingleA0 => self
.with_high(BF::MUX2)
.with_low(BF::MUX1)
.with_low(BF::MUX0),
.union(Self::MUX2)
.difference(Self::MUX1)
.difference(Self::MUX0),
ChannelSelection::SingleA1 => self
.with_high(BF::MUX2)
.with_low(BF::MUX1)
.with_high(BF::MUX0),
.union(Self::MUX2)
.difference(Self::MUX1)
.union(Self::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),
.union(Self::MUX2)
.union(Self::MUX1)
.difference(Self::MUX0),
ChannelSelection::SingleA3 => {
self.union(Self::MUX2).union(Self::MUX1).union(Self::MUX0)
}
}
}
}
40 changes: 0 additions & 40 deletions src/construction.rs

This file was deleted.

Loading
Loading