#![deny(
missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
trivial_numeric_casts, unused_import_braces, unused_qualifications
)]
#![feature(generators)]
extern crate bitfield_register;
extern crate bitfield_register_macro;
extern crate byteorder;
extern crate futures_await as futures;
extern crate i2cdev;
extern crate qutex;
extern crate tokio_timer;
use futures::prelude::async;
use futures::prelude::await;
use std::time;
pub mod error;
pub mod reg;
#[derive(Debug)]
pub struct Ads1x15<D> {
device: qutex::Qutex<D>,
gain: Gain,
model: Model,
}
#[derive(Clone, Copy, Debug)]
enum Model {
ADS1015,
ADS1115,
}
#[derive(Clone, Copy, Debug)]
pub enum Channel {
A0,
A1,
A2,
A3,
}
#[derive(Clone, Copy, Debug)]
#[allow(non_camel_case_types)]
pub enum Gain {
Within6_144V,
Within4_096V,
Within2_048V,
Within1_024V,
Within0_512V,
Within0_256V,
}
impl<D> Ads1x15<D> {
pub fn new_ads1015(device: D) -> Self {
let device = qutex::Qutex::new(device);
let gain = Gain::Within6_144V;
let model = Model::ADS1015;
Ads1x15 {
device,
gain,
model,
}
}
pub fn new_ads1115(device: D) -> Self {
let device = qutex::Qutex::new(device);
let gain = Gain::Within6_144V;
let model = Model::ADS1115;
Ads1x15 {
device,
gain,
model,
}
}
pub fn gain(&self) -> Gain {
self.gain
}
pub fn set_gain(&mut self, gain: Gain) {
self.gain = gain;
}
}
impl<D> Ads1x15<D>
where
D: i2cdev::core::I2CDevice + 'static,
{
#[async]
fn read_single_ended_impl(
device: qutex::Qutex<D>,
gain: Gain,
model: Model,
channel: Channel,
) -> Result<f32, error::Error<D>> {
use byteorder::ByteOrder;
let mut device = await!(device.lock()).map_err(error::Error::Canceled::<D>)?;
let mut config = reg::Config::default();
config.set_os(reg::ConfigOs::Single);
config.set_mux(channel.as_reg_config_mux_single());
config.set_pga(gain.as_reg_config_pga());
config.set_mode(reg::ConfigMode::Single);
config.set_dr(reg::ConfigDr::_3300SPS);
config.set_cmode(reg::ConfigCmode::Trad);
config.set_cpol(reg::ConfigCpol::Actvlow);
config.set_clat(reg::ConfigClat::Nonlat);
config.set_cque(reg::ConfigCque::None);
let mut write_buf = [reg::Register::Config as u8, 0u8, 0u8];
byteorder::LittleEndian::write_u16(&mut write_buf[1..], config.into());
device.write(&write_buf).map_err(error::Error::I2C)?;
await!(tokio_timer::sleep(model.conversion_delay())).map_err(error::Error::Timer::<D>)?;
let mut read_buf = [0u8, 0u8];
device
.smbus_write_byte(reg::Register::Convert as u8)
.map_err(error::Error::I2C)?;
device.read(&mut read_buf).map_err(error::Error::I2C)?;
let value = model.convert_raw_voltage(gain, byteorder::BigEndian::read_i16(&read_buf));
Ok(value)
}
pub fn read_single_ended(
&self,
channel: Channel,
) -> impl futures::Future<Item = f32, Error = error::Error<D>> {
Ads1x15::read_single_ended_impl(self.device.clone(), self.gain, self.model, channel)
}
}
impl Channel {
pub fn as_reg_config_mux_single(&self) -> reg::ConfigMux {
match *self {
Channel::A0 => reg::ConfigMux::Single0,
Channel::A1 => reg::ConfigMux::Single1,
Channel::A2 => reg::ConfigMux::Single2,
Channel::A3 => reg::ConfigMux::Single3,
}
}
}
impl Gain {
pub fn as_reg_config_pga(&self) -> reg::ConfigPga {
match *self {
Gain::Within6_144V => reg::ConfigPga::_6_144V,
Gain::Within4_096V => reg::ConfigPga::_4_096V,
Gain::Within2_048V => reg::ConfigPga::_2_048V,
Gain::Within1_024V => reg::ConfigPga::_1_024V,
Gain::Within0_512V => reg::ConfigPga::_0_512V,
Gain::Within0_256V => reg::ConfigPga::_0_256V,
}
}
}
impl Model {
fn conversion_delay(&self) -> time::Duration {
match *self {
Model::ADS1015 => time::Duration::from_millis(1),
Model::ADS1115 => time::Duration::from_millis(8),
}
}
fn convert_raw_voltage(&self, gain: Gain, value: i16) -> f32 {
match *self {
Model::ADS1015 => {
let value = (value >> 4) as f32;
match gain {
Gain::Within6_144V => value * 3.0000e-3,
Gain::Within4_096V => value * 2.0000e-3,
Gain::Within2_048V => value * 1.0000e-3,
Gain::Within1_024V => value * 5.0000e-4,
Gain::Within0_512V => value * 2.5000e-4,
Gain::Within0_256V => value * 1.2500e-4,
}
}
Model::ADS1115 => {
let value = value as f32;
match gain {
Gain::Within6_144V => value * 1.8750e-4,
Gain::Within4_096V => value * 1.2500e-4,
Gain::Within2_048V => value * 6.2500e-5,
Gain::Within1_024V => value * 3.1250e-5,
Gain::Within0_512V => value * 1.5625e-5,
Gain::Within0_256V => value * 7.8125e-6,
}
}
}
}
}