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

Oneshot mut #8

Closed David-OConnor closed 3 years ago

David-OConnor commented 3 years ago

Re-branch of https://github.com/eldruin/ads1x1x-rs/pull/6 due to git merge issues.

I'm still unable to make my code work without this addition.

coveralls commented 3 years ago

Coverage Status

Coverage decreased (-2.8%) to 85.993% when pulling 5630ef2bcc12341fdbb6fb3c20fac3bcb8607102 on David-OConnor:oneshot-mut into a5eabb805bc585214d4d5bf716843044ea1241c1 on eldruin:master.

eldruin commented 3 years ago

Can you try adapting your code to look similar to the code below? 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

After considering your comment and further reflection, this is required when the Ads1x1x struct being wrapped in an option, ie called from &mut self.orp.adc.as_mut().unwrap().

After inserting these lines in your example in tier1.rs:

let mut dev = Some($create(&transactions));
read(&mut dev.as_mut().unwrap(), &mut channel::DifferentialA0A1);

I receive a similar error as before, unless I insert the patch from this PR.

This pattern is due to the ownership issue of peripherals. In this case, I'm using an Option to indicate if a struct owns the Adc struct, or if something else does.

eldruin commented 3 years ago

I see. I could reproduce your problem now. I could solve the reference type mismatch by doing this:

let mut dev = Some(new_ads1013(&transactions));
read(dev.as_mut().unwrap(), &mut channel::DifferentialA0A1); // notice I removed the `&mut` 
destroy_ads1013(dev.unwrap());
David-OConnor commented 3 years ago

Thank you! Fixed.