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; |