summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDiego Barrios Romero <eldruin@gmail.com>2021-07-29 23:14:25 +0200
committerDiego Barrios Romero <eldruin@gmail.com>2021-07-29 23:14:25 +0200
commit28126fee8ce253e67ab737927ff0d89ebc24e419 (patch)
tree503e6056682296c3ac3ead637cad7f5c2e6da8a3
parentdeb65c3a794bdc4e5c534983c8753072cec10adf (diff)
downloadads1x1x-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.md3
-rw-r--r--examples/trait.rs24
-rw-r--r--src/channels.rs9
-rw-r--r--src/devices/mode/oneshot.rs20
-rw-r--r--src/lib.rs8
-rw-r--r--src/types.rs11
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;
diff --git a/src/lib.rs b/src/lib.rs
index 418fc46..90a0f62 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;