diff options
| author | Diego Barrios Romero <eldruin@gmail.com> | 2021-07-29 23:14:25 +0200 | 
|---|---|---|
| committer | Diego Barrios Romero <eldruin@gmail.com> | 2021-07-29 23:14:25 +0200 | 
| commit | 28126fee8ce253e67ab737927ff0d89ebc24e419 (patch) | |
| tree | 503e6056682296c3ac3ead637cad7f5c2e6da8a3 | |
| parent | deb65c3a794bdc4e5c534983c8753072cec10adf (diff) | |
| download | ads1x1x-async-28126fee8ce253e67ab737927ff0d89ebc24e419.tar.gz ads1x1x-async-28126fee8ce253e67ab737927ff0d89ebc24e419.tar.xz ads1x1x-async-28126fee8ce253e67ab737927ff0d89ebc24e419.zip | |
Add value-based one-shot trait to ease driver usage in functions
| -rw-r--r-- | CHANGELOG.md | 3 | ||||
| -rw-r--r-- | examples/trait.rs | 24 | ||||
| -rw-r--r-- | src/channels.rs | 9 | ||||
| -rw-r--r-- | src/devices/mode/oneshot.rs | 20 | ||||
| -rw-r--r-- | src/lib.rs | 8 | ||||
| -rw-r--r-- | src/types.rs | 11 | 
6 files changed, 68 insertions, 7 deletions
| diff --git a/CHANGELOG.md b/CHANGELOG.md index cd5f06e..be9b2fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.  ## [Unreleased] +### Added +- `DynamicOneShot` trait to ease usage of driver in functions. See `trait` example. +  ### Changed  - Updated `nb` dependency to version `1`. diff --git a/examples/trait.rs b/examples/trait.rs new file mode 100644 index 0000000..eda1f37 --- /dev/null +++ b/examples/trait.rs @@ -0,0 +1,24 @@ +// This example demonstrates the use of a type alias for the `Ads1x1x` struct +// to ease usage in signatures. + +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 value = read(&mut adc); +    println!("Measurement: {}", value); +    // get I2C device back +    let _dev = adc.destroy_ads1115(); +} diff --git a/src/channels.rs b/src/channels.rs index c0f0ff9..a4c806c 100644 --- a/src/channels.rs +++ b/src/channels.rs @@ -23,15 +23,24 @@ pub mod channel {      pub struct DifferentialA2A3;  } +/// ADC input channel selection  #[derive(Debug, Clone, Copy)]  pub enum ChannelSelection { +    /// Measure single-ended signal on input channel 0      SingleA0, +    /// Measure single-ended signal on input channel 1      SingleA1, +    /// Measure single-ended signal on input channel 2      SingleA2, +    /// Measure single-ended signal on input channel 3      SingleA3, +    /// Measure signal on input channel 0 differentially to signal on input channel 1      DifferentialA0A1, +    /// Measure signal on input channel 0 differentially to signal on input channel 3      DifferentialA0A3, +    /// Measure signal on input channel 1 differentially to signal on input channel 3      DifferentialA1A3, +    /// Measure signal on input channel 2 differentially to signal on input channel 3      DifferentialA2A3,  } diff --git a/src/devices/mode/oneshot.rs b/src/devices/mode/oneshot.rs index 665ce33..fa4d3b8 100644 --- a/src/devices/mode/oneshot.rs +++ b/src/devices/mode/oneshot.rs @@ -1,7 +1,7 @@  //! Common functions  use crate::{ -    channels::ChannelSelection, conversion, devices::OperatingMode, interface, mode, Ads1x1x, -    BitFlags, Config, Error, ModeChangeError, Register, +    conversion, devices::OperatingMode, interface, mode, Ads1x1x, BitFlags, ChannelSelection, +    Config, DynamicOneShot, Error, ModeChangeError, Register,  };  use core::marker::PhantomData;  use embedded_hal::adc; @@ -58,13 +58,25 @@ where      /// measurement on a different channel is requested, a new measurement on      /// using the new channel selection is triggered.      fn read(&mut self, _channel: &mut CH) -> nb::Result<i16, Self::Error> { +        <Self as DynamicOneShot>::read(self, CH::channel()) +    } +} + +impl<DI, IC, CONV, E> DynamicOneShot for Ads1x1x<DI, IC, CONV, mode::OneShot> +where +    DI: interface::ReadData<Error = E> + interface::WriteData<Error = E>, +    CONV: conversion::ConvertMeasurement, +{ +    type Error = Error<E>; + +    fn read(&mut self, channel: ChannelSelection) -> nb::Result<i16, Self::Error> {          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(CH::channel()); +        let same_channel = self.config == self.config.with_mux_bits(channel);          if self.a_conversion_was_started && same_channel {              // result is ready              let value = self @@ -74,7 +86,7 @@ where              self.a_conversion_was_started = false;              return Ok(CONV::convert_measurement(value));          } -        let config = self.config.with_mux_bits(CH::channel()); +        let config = self.config.with_mux_bits(channel);          self.trigger_measurement(&config)              .map_err(nb::Error::Other)?;          self.config = config; @@ -237,7 +237,7 @@ impl BitFlags {  }  mod channels; -pub use crate::channels::channel; +pub use crate::channels::{channel, ChannelSelection};  mod construction;  mod conversion;  pub use crate::conversion::{ConvertMeasurement, ConvertThreshold}; @@ -250,14 +250,16 @@ mod types;  use crate::types::Config;  pub use crate::types::{      mode, Ads1x1x, ComparatorLatching, ComparatorMode, ComparatorPolarity, ComparatorQueue, -    DataRate12Bit, DataRate16Bit, Error, FullScaleRange, ModeChangeError, SlaveAddr, +    DataRate12Bit, DataRate16Bit, DynamicOneShot, Error, FullScaleRange, ModeChangeError, +    SlaveAddr,  };  mod private { -    use super::{ic, interface}; +    use super::{ic, interface, Ads1x1x};      pub trait Sealed {}      impl<I2C> Sealed for interface::I2cInterface<I2C> {} +    impl<DI, IC, CONV, MODE> Sealed for Ads1x1x<DI, IC, CONV, MODE> {}      impl Sealed for ic::Resolution12Bit {}      impl Sealed for ic::Resolution16Bit {} diff --git a/src/types.rs b/src/types.rs index 2b9fc02..957825e 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,5 +1,6 @@  //! Type definitions. +use crate::{channels::ChannelSelection, private};  use core::marker::PhantomData;  /// Errors in this crate @@ -70,6 +71,7 @@ pub enum DataRate16Bit {      /// 860 SPS      Sps860,  } +  /// Comparator mode (only for ADS1x14, ADS1x15)  #[derive(Debug, Clone, Copy, PartialEq)]  pub enum ComparatorMode { @@ -257,6 +259,15 @@ pub struct Ads1x1x<DI, IC, CONV, MODE> {      pub(crate) _mode: PhantomData<MODE>,  } +/// Multi channel One-shot ADC +pub trait DynamicOneShot: private::Sealed { +    /// Error type +    type Error; + +    /// Read a measurement +    fn read(&mut self, channel: ChannelSelection) -> nb::Result<i16, Self::Error>; +} +  #[cfg(test)]  mod tests {      use crate::DEVICE_BASE_ADDRESS as ADDR; | 
