Skip to content

Commit

Permalink
Simplify SlaveAddr. (#21)
Browse files Browse the repository at this point in the history
* Simplify `SlaveAddr`.

* Update changelog.

* Update CHANGELOG.md

---------

Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
  • Loading branch information
reitermarkus and eldruin committed Feb 13, 2024
1 parent 3c2805f commit 0ff4c7b
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 99 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Add default for `ComparatorQueue`.

### Changed
- Updated `embedded-hal` to version `1`, `read` in one-shot mode is therefore only an inherent method.
- [breaking-change] Updated `embedded-hal` to version `1`, `read` in one-shot mode is therefore only an inherent method.
- [breaking-change] Simplified `SlaveAddr` enum.
- Raised MSRV to 1.62.0.

### Removed
Expand Down
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -85,8 +85,7 @@ 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 mut adc = Ads1x1x::new_ads1013(dev, SlaveAddr::default());
let value = block!(adc.read(channel::DifferentialA0A1)).unwrap();
println!("Measurement: {}", value);
// get I2C device back
Expand Down
3 changes: 1 addition & 2 deletions examples/all_channels.rs
Expand Up @@ -5,8 +5,7 @@ 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 mut adc = Ads1x1x::new_ads1015(dev, SlaveAddr::default());
let values = [
block!(adc.read(channel::SingleA0)).unwrap(),
block!(adc.read(channel::SingleA1)).unwrap(),
Expand Down
3 changes: 1 addition & 2 deletions examples/linux.rs
Expand Up @@ -5,8 +5,7 @@ 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 mut adc = Ads1x1x::new_ads1013(dev, SlaveAddr::default());
let value = block!(adc.read(channel::DifferentialA0A1)).unwrap();
println!("Measurement: {}", value);
// get I2C device back
Expand Down
3 changes: 1 addition & 2 deletions examples/trait.rs
Expand Up @@ -14,8 +14,7 @@ pub fn read<E, A: DynamicOneShot<Error = E>>(adc: &mut A) -> i16 {

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

let value = read(&mut adc);
println!("Measurement: {}", value);
Expand Down
3 changes: 1 addition & 2 deletions examples/typed.rs
Expand Up @@ -21,8 +21,7 @@ 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 mut adc = Ads1x1x::new_ads1115(dev, SlaveAddr::default());

let value = read(&mut adc);
println!("Measurement: {}", value);
Expand Down
4 changes: 2 additions & 2 deletions src/construction.rs
@@ -1,6 +1,6 @@
//! Constructor/destructor functions.

use crate::{ic, mode, Ads1x1x, Config, FullScaleRange, SlaveAddr, DEVICE_BASE_ADDRESS};
use crate::{ic, mode, Ads1x1x, Config, FullScaleRange, SlaveAddr};
use core::marker::PhantomData;

macro_rules! impl_new_destroy {
Expand All @@ -13,7 +13,7 @@ macro_rules! impl_new_destroy {
pub fn $create(i2c: I2C, address: SlaveAddr) -> Self {
Ads1x1x {
i2c,
address: address.addr(DEVICE_BASE_ADDRESS),
address: address.bits(),
config: Config::default(),
fsr: FullScaleRange::default(),
a_conversion_was_started: false,
Expand Down
34 changes: 6 additions & 28 deletions src/lib.rs
Expand Up @@ -84,46 +84,28 @@
//!
//! [driver-examples]: https://github.com/eldruin/driver-examples
//!
//! ### Create a driver instance for the ADS1013
//! ### Create a driver instance for an ADS1013 with the default address.
//!
//! ```no_run
//! use linux_embedded_hal::I2cdev;
//! use ads1x1x::{Ads1x1x, SlaveAddr};
//!
//! let dev = I2cdev::new("/dev/i2c-1").unwrap();
//! let address = SlaveAddr::default();
//! let adc = Ads1x1x::new_ads1013(dev, address);
//! let adc = Ads1x1x::new_ads1013(dev, SlaveAddr::default());
//! // do something...
//!
//! // get the I2C device back
//! let dev = adc.destroy_ads1013();
//! ```
//!
//! ### Create a driver instance for the ADS1013 with an alternative address (method 1)
//! ### Create a driver instance for an ADS1013 with the ADDR pin connected to SDA.
//!
//! ```no_run
//! use linux_embedded_hal::I2cdev;
//! use ads1x1x::{Ads1x1x, SlaveAddr};
//!
//! let dev = I2cdev::new("/dev/i2c-1").unwrap();
//! let (bit1, bit0) = (true, false); // last two bits of address
//! let address = SlaveAddr::Alternative(bit1, bit0);
//! let adc = Ads1x1x::new_ads1013(dev, address);
//! ```

//! ### Create a driver instance for the ADS1013 with an alternative address (method 2)
//!
//! Using helper `SlaveAddr` creation method depending on the connection of
//! the `ADDR` pin.
//!
//! ```no_run
//! use linux_embedded_hal::I2cdev;
//! use ads1x1x::{Ads1x1x, SlaveAddr};
//!
//! let dev = I2cdev::new("/dev/i2c-1").unwrap();
//! // `ADDR` pin connected to SDA results in the 0x4A effective address
//! let address = SlaveAddr::new_sda();
//! let adc = Ads1x1x::new_ads1013(dev, address);
//! let adc = Ads1x1x::new_ads1013(dev, SlaveAddr::Sda);
//! ```
//!
//! ### Make a one-shot measurement
Expand All @@ -149,8 +131,7 @@
//! use ads1x1x::{Ads1x1x, ModeChangeError, SlaveAddr};
//!
//! let dev = I2cdev::new("/dev/i2c-1").unwrap();
//! let address = SlaveAddr::default();
//! let adc = Ads1x1x::new_ads1013(dev, address);
//! let adc = Ads1x1x::new_ads1013(dev, SlaveAddr::default());
//! match adc.into_continuous() {
//! Err(ModeChangeError::I2C(e, adc)) => /* mode change failed handling */ panic!(),
//! Ok(mut adc) => {
Expand All @@ -170,8 +151,7 @@
//! use ads1x1x::{Ads1x1x, DataRate16Bit, SlaveAddr};
//!
//! let dev = I2cdev::new("/dev/i2c-1").unwrap();
//! let address = SlaveAddr::default();
//! let mut adc = Ads1x1x::new_ads1115(dev, address);
//! let mut adc = Ads1x1x::new_ads1115(dev, SlaveAddr::default());
//! adc.set_data_rate(DataRate16Bit::Sps860).unwrap();
//! ```
//!
Expand Down Expand Up @@ -204,8 +184,6 @@
#![deny(missing_docs)]
#![no_std]

const DEVICE_BASE_ADDRESS: u8 = 0b100_1000;

struct Register;
impl Register {
const CONVERSION: u8 = 0x00;
Expand Down
85 changes: 27 additions & 58 deletions src/types.rs
Expand Up @@ -162,56 +162,35 @@ pub enum FullScaleRange {
Within0_256V,
}

/// Possible slave addresses
/// A slave address.
///
/// See [Table 4 in the datasheet](https://www.ti.com/lit/ds/symlink/ads1115.pdf#%5B%7B%22num%22%3A716%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C602.2%2C0%5D).
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub enum SlaveAddr {
/// Address when the ADDR pin is connected to GND. (default)
#[default]
/// Default slave address
Default,
/// Alternative slave address using the provided values
/// for the last two bits (A1, A0)
Alternative(bool, bool),
Gnd,
/// Address when the ADDR pin is connected to VDD.
Vdd,
/// Address when the ADDR pin is connected to SDA.
///
/// If SDA is used as the device address, hold the SDA line low for at
/// least 100 ns after the SCL line goes low to make sure the device
/// decodes the address correctly during I²C communication.
Sda,
/// Address when the ADDR pin is connected to SCL.
Scl,
}

impl SlaveAddr {
pub(crate) fn addr(self, default: u8) -> u8 {
pub(crate) const fn bits(self) -> u8 {
match self {
SlaveAddr::Default => default,
SlaveAddr::Alternative(a1, a0) => default | ((a1 as u8) << 1) | a0 as u8,
Self::Gnd => 0b1001000,
Self::Vdd => 0b1001001,
Self::Sda => 0b1001010,
Self::Scl => 0b1001011,
}
}

/// Create `SlaveAddr` instance corresponding to the address
/// effective when connecting the pin `ADDR` to GND (0x48).
///
/// See [Table 4 in the datasheet](https://www.ti.com/lit/ds/symlink/ads1115.pdf#%5B%7B%22num%22%3A716%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C602.2%2C0%5D).
pub fn new_gnd() -> Self {
SlaveAddr::default()
}

/// Create `SlaveAddr` instance corresponding to the address
/// effective when connecting the pin `ADDR` to VDD (0x49).
///
/// See [Table 4 in the datasheet](https://www.ti.com/lit/ds/symlink/ads1115.pdf#%5B%7B%22num%22%3A716%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C602.2%2C0%5D).
pub fn new_vdd() -> Self {
SlaveAddr::Alternative(false, true)
}

/// Create `SlaveAddr` instance corresponding to the address
/// effective when connecting the pin `ADDR` to SDA (0x4A).
///
/// See [Table 4 in the datasheet](https://www.ti.com/lit/ds/symlink/ads1115.pdf#%5B%7B%22num%22%3A716%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C602.2%2C0%5D).
pub fn new_sda() -> Self {
SlaveAddr::Alternative(true, false)
}

/// Create `SlaveAddr` instance corresponding to the address
/// effective when connecting the pin `ADDR` to SCL (0x4B).
///
/// See [Table 4 in the datasheet](https://www.ti.com/lit/ds/symlink/ads1115.pdf#%5B%7B%22num%22%3A716%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C602.2%2C0%5D).
pub fn new_scl() -> Self {
SlaveAddr::Alternative(true, true)
}
}

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -267,29 +246,19 @@ pub trait DynamicOneShot: private::Sealed {

#[cfg(test)]
mod tests {
use crate::DEVICE_BASE_ADDRESS as ADDR;
use crate::{FullScaleRange, SlaveAddr};

#[test]
fn can_get_default_address() {
let addr = SlaveAddr::default();
assert_eq!(ADDR, addr.addr(ADDR));
}

#[test]
fn can_generate_alternative_addresses() {
assert_eq!(0b100_1000, SlaveAddr::Alternative(false, false).addr(ADDR));
assert_eq!(0b100_1001, SlaveAddr::Alternative(false, true).addr(ADDR));
assert_eq!(0b100_1010, SlaveAddr::Alternative(true, false).addr(ADDR));
assert_eq!(0b100_1011, SlaveAddr::Alternative(true, true).addr(ADDR));
fn slave_addr_default() {
assert_eq!(0b100_1000, SlaveAddr::default().bits());
}

#[test]
fn can_generate_alternative_addresses_using_helper_constructors() {
assert_eq!(0b100_1000, SlaveAddr::new_gnd().addr(ADDR));
assert_eq!(0b100_1001, SlaveAddr::new_vdd().addr(ADDR));
assert_eq!(0b100_1010, SlaveAddr::new_sda().addr(ADDR));
assert_eq!(0b100_1011, SlaveAddr::new_scl().addr(ADDR));
fn slave_addr_bits() {
assert_eq!(0b100_1000, SlaveAddr::Gnd.bits());
assert_eq!(0b100_1001, SlaveAddr::Vdd.bits());
assert_eq!(0b100_1010, SlaveAddr::Sda.bits());
assert_eq!(0b100_1011, SlaveAddr::Scl.bits());
}

#[test]
Expand Down

0 comments on commit 0ff4c7b

Please sign in to comment.