eldruin / ads1x1x-rs

Platform-agnostic Rust driver for the ADS1x1x ultra-small, low-power analog-to-digital converters (ADC). Compatible with ADS1013, ADS1014, ADS1015, ADS1113, ADS1114 and ADS1115
https://blog.eldruin.com/ads1x1x-analog-to-digital-converter-driver-in-rust/
Apache License 2.0
31 stars 9 forks source link

Added OneShot trait for &mut Ads1x1x #6

Closed David-OConnor closed 3 years ago

David-OConnor commented 3 years ago

This is useful if, for example, you're using a mutable reference instead of owning the ADS1x1x struct. For example, if you have multiple sensors connected to different channels. You could reduce DRY by using a macro instead of the copy+paste I did, but but it's not clear that with only 2 variants (owned, and &mut), this would be clearer.

eldruin commented 3 years ago

Thanks @David-OConnor. Can you provide an example function where this is necessary? This works fine, for example: (You can paste this code at the end of the tests/tier1.rs file to run it)

use embedded_hal::adc::OneShot;
use ads1x1x::{ic, interface, mode, Ads1x1x};
use embedded_hal_mock::i2c::{Mock as I2cMock};

fn read(dev: &mut Ads1x1x<interface::I2cInterface<I2cMock>, ic::Ads1013, ic::Resolution12Bit, mode::OneShot>) {
    assert_would_block!(dev.read(&mut channel::DifferentialA0A1));
}

#[test]
fn read_if_measurement_in_progress() {
    let config = Config::default().with_low(BF::OS);
    let transactions = [I2cTrans::write_read(
        DEV_ADDR,
        vec![Register::CONFIG],
        vec![config.msb(), config.lsb()],
    )];
    let mut dev = new_ads1013(&transactions);
    read(&mut dev);
    destroy_ads1013(dev);
}
David-OConnor commented 3 years ago

This is required if you're using the embedded-hal::adc::OneShot trait, vice specifying the type explicitly as in your example.

Eg, if read was something like this:

fn read<ADC, i16, C>(dev: &mut A) 
where
        A: OneShot<ADC, i16, C>,
        C: :Channel<ADC>,
{
    assert_would_block!(dev.read(&mut channel::DifferentialA0A1));
}
eldruin commented 3 years ago

I am afraid I still cannot reproduce the error. This code builds fine when putting it in tests/tier1.rs:

use embedded_hal::adc::{Channel, OneShot};
use ads1x1x::{ic, interface, mode, Ads1x1x};
use embedded_hal_mock::i2c::{Mock as I2cMock};

fn read<A, ADC, C>(dev: &mut A, c: &mut C)
where
        A: OneShot<ADC, i16, C>,
        C: Channel<ADC>,
{
    assert_would_block!(dev.read(c));
}

#[test]
fn read_if_measurement_in_progress() {
    let config = Config::default().with_low(BF::OS);
    let transactions = [I2cTrans::write_read(
        DEV_ADDR,
        vec![Register::CONFIG],
        vec![config.msb(), config.lsb()],
    )];
    let mut dev = new_ads1013(&transactions);
    read(&mut dev, &mut channel::DifferentialA0A1);
    destroy_ads1013(dev);
}
David-OConnor commented 3 years ago

Closing due to git issues.