Skip to content

Commit

Permalink
Complete rewrite with separate struct for each version.
Browse files Browse the repository at this point in the history
  • Loading branch information
reitermarkus committed Jan 13, 2024
1 parent b24fe1c commit fa3ca00
Show file tree
Hide file tree
Showing 21 changed files with 741 additions and 804 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,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::{Ads1013, SlaveAddr, ChannelSelection};
use linux_embedded_hal::I2cdev;
use nb::block;

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

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

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

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

Expand Down
11 changes: 4 additions & 7 deletions examples/all_channels.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use ads1x1x::{Ads1015, ChannelSelection, SlaveAddr};
use linux_embedded_hal::I2cdev;
use nb::block;

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

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

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

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

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

let value = block!(adc.read(ChannelSelection::DifferentialA0A1)).unwrap();
println!("Measurement: {}", value);
// get I2C device back
let _dev = adc.destroy_ads1013();
}
12 changes: 4 additions & 8 deletions examples/trait.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
// This example demonstrates the use of the `DynamicOneSot` trait to ease the usage
// of the `Ads1x1x` struct in functions.
// of the `Ads1x1x` structs in functions.

use ads1x1x::{Ads1115, ChannelSelection, DynamicOneShot, SlaveAddr};
use linux_embedded_hal::I2cdev;
use nb::block;

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

/// Read a single value from channel A.
/// Returns 0 on Error.
pub fn read<E, A: DynamicOneShot<Error = E>>(adc: &mut A) -> i16 {
block!(adc.read(ChannelSelection::SingleA0)).unwrap_or(0)
}

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

let value = read(&mut adc);
println!("Measurement: {}", value);
// get I2C device back
let _dev = adc.destroy_ads1115();
}
18 changes: 5 additions & 13 deletions examples/typed.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
// This example demonstrates the use of a type alias for the `Ads1x1x` struct
// This example demonstrates the use of a type alias for the `Ads1115` struct
// to ease usage in signatures.

use ads1x1x::{Ads1115, ChannelSelection, SlaveAddr};
use linux_embedded_hal::I2cdev;
use nb::block;

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

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

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

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

let value = read(&mut adc);
println!("Measurement: {}", value);
// get I2C device back
let _dev = adc.destroy_ads1115();
}
42 changes: 0 additions & 42 deletions src/construction.rs

This file was deleted.

104 changes: 0 additions & 104 deletions src/conversion.rs

This file was deleted.

87 changes: 52 additions & 35 deletions src/devices/common.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,58 @@
//! Common functions
use crate::{devices::OperatingMode, interface, Ads1x1x, BitFlags, Config, Error, Register};
use crate::{
devices::OperatingMode, Ads1013, Ads1014, Ads1015, Ads1113, Ads1114, Ads1115, BitFlags, Config,
Error, Register,
};

impl<DI, IC, CONV, MODE, E> Ads1x1x<DI, IC, CONV, MODE>
where
DI: interface::ReadWriteRegister<Error = E>,
{
pub(super) fn set_operating_mode(&mut self, mode: OperatingMode) -> Result<(), Error<E>> {
let config = match mode {
OperatingMode::OneShot => self.config.with_high(BitFlags::OP_MODE),
OperatingMode::Continuous => self.config.with_low(BitFlags::OP_MODE),
};
self.iface.write_register(Register::CONFIG, config.bits)?;
self.config = config;
Ok(())
}
macro_rules! impl_common_features {
($Ads:ident) => {
impl<I2C, E, MODE> $Ads<I2C, MODE>
where
I2C: embedded_hal::i2c::I2c<Error = E>,
{
pub(super) fn set_operating_mode(
&mut self,
mode: OperatingMode,
) -> Result<(), Error<E>> {
let config = match mode {
OperatingMode::OneShot => self.config.with_high(BitFlags::OP_MODE),
OperatingMode::Continuous => self.config.with_low(BitFlags::OP_MODE),
};
self.iface.write_register(Register::CONFIG, config.bits)?;
self.config = config;
Ok(())
}

/// Read whether a measurement is currently in progress.
pub fn is_measurement_in_progress(&mut self) -> Result<bool, Error<E>> {
let config = Config {
bits: self.iface.read_register(Register::CONFIG)?,
};
Ok(!config.is_high(BitFlags::OS))
}
/// Read whether a measurement is currently in progress.
pub fn is_measurement_in_progress(&mut self) -> Result<bool, Error<E>> {
let config = Config {
bits: self.iface.read_register(Register::CONFIG)?,
};
Ok(!config.is_high(BitFlags::OS))
}

/// Reset the internal state of this driver to the default values.
///
/// *Note:* This does not alter the state or configuration of the device.
///
/// This resets the cached configuration register value in this driver to
/// the power-up (reset) configuration of the device.
///
/// This needs to be called after performing a reset on the device, for
/// example through an I2C general-call Reset command, which was not done
/// through this driver to ensure that the configurations in the device
/// and in the driver match.
pub fn reset_internal_driver_state(&mut self) {
self.config = Config::default();
}
/// Reset the internal state of this driver to the default values.
///
/// *Note:* This does not alter the state or configuration of the device.
///
/// This resets the cached configuration register value in this driver to
/// the power-up (reset) configuration of the device.
///
/// This needs to be called after performing a reset on the device, for
/// example through an I2C general-call Reset command, which was not done
/// through this driver to ensure that the configurations in the device
/// and in the driver match.
pub fn reset_internal_driver_state(&mut self) {
self.config = Config::default();
}
}
};
}

impl_common_features!(Ads1013);
impl_common_features!(Ads1113);
impl_common_features!(Ads1014);
impl_common_features!(Ads1114);
impl_common_features!(Ads1015);
impl_common_features!(Ads1115);
Loading

0 comments on commit fa3ca00

Please sign in to comment.