Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

broken usage example for i2c sharing #904

Open
pdgilbert opened this issue Mar 16, 2024 · 2 comments
Open

broken usage example for i2c sharing #904

pdgilbert opened this issue Mar 16, 2024 · 2 comments

Comments

@pdgilbert
Copy link

I have been trying to compile the Arbiter i2c usage example in rtic-rs/rtic/rtic-sync/src/arbiter.rs. It has some typos which suggest it has never been tested. With some fixes and adjustments for different hals I have made progress but have a problem with an unsatisfied trait bounds for &mut Ens160<ArbiterDevice<'static, I2c<I2C1>>>. I have tried with both release and git versions of rtic-sync and also tried with both stm32f4xx_hal and a version of stm32g4xx_hal that uses embedded-hal-1.0.0. I think the problem is possibly a bug in rtic-sync or elsewhere, but maybe that I am just not bringing the proper trait into scope. Below are results for the git versions using stm32f4xx_hal.

Click to expand code
// I2C bus sharing using [`Arbiter`]
//
// An Example how to use it in RTIC application:

#![deny(unsafe_code)]
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]

#[cfg(debug_assertions)]
use panic_semihosting as _;

#[cfg(not(debug_assertions))]
use panic_halt as _;

use rtic::app;

#[cfg_attr(feature = "stm32f4xx", app(device = stm32f4xx_hal::pac,   dispatchers = [TIM2, TIM3]))]

mod app {
    use core::mem::MaybeUninit;
    use rtic_sync::arbiter::{i2c::ArbiterDevice, Arbiter};

    // Instantiate an Arbiter with a static lifetime.
    static ARBITER: Arbiter<u32> = Arbiter::new(32);

    use ens160::{Ens160, AirQualityIndex, ECo2};

    pub use stm32f4xx_hal::{
       pac::{I2C1, TIM2, TIM5},
       i2c::I2c,
       gpio::GpioExt,
       rcc::{Clocks, RccExt},
       timer::TimerExt,
       prelude::*,
    };

    pub type I2c1Type = I2c<I2C1>;

    #[shared]
    struct Shared {}

    #[local]
    struct Local {
        ens160: Ens160<ArbiterDevice<'static, I2c1Type>>,
    }

    #[init(local = [
        i2c_arbiter: MaybeUninit<Arbiter<I2c1Type>> = MaybeUninit::uninit(),
    ])]
    fn init(cx: init::Context) -> (Shared, Local) {

        let rcc = cx.device.RCC.constrain();
        let clocks = rcc.cfgr.freeze();

        let gpiob = cx.device.GPIOB.split();
        let scl = gpiob.pb8.into_alternate_open_drain(); 
        let sda = gpiob.pb9.into_alternate_open_drain(); 

        let i2c = I2c::new(cx.device.I2C1, (scl, sda), 400.kHz(), &clocks);

        let i2c_arbiter = cx.local.i2c_arbiter.write(Arbiter::new(i2c));
        let ens160 = Ens160::new(ArbiterDevice::new(i2c_arbiter), 0x52);

        i2c_sensors::spawn(i2c_arbiter).ok();

        (Shared {}, Local { ens160 })
    }

    #[task(local = [ens160])]
    async fn i2c_sensors(cx: i2c_sensors::Context, i2c: &'static Arbiter<I2c1Type>) {
    //async fn i2c_sensors(cx: i2c_sensors::Context, i2c: &'static Arbiter<I2c<'static, I2c1Type>>) {
        loop {
            // Read ENS160 sensor.
            let eco2 = cx.local.ens160.eco2().await;
        }
    }
}
Click to expand compiling error
$ cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32f411,stm32f4xx --example ens160_f4
   Compiling rust-integration-testing-of-examples v0.3.0 (dev-testing)
warning: unused imports: `AirQualityIndex`, `ECo2`
  --> examples/ens160_f4.rs:27:26
   |
27 |     use ens160::{Ens160, AirQualityIndex, ECo2};
   |                          ^^^^^^^^^^^^^^^  ^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

error[E0599]: the method `eco2` exists for mutable reference `&mut Ens160<ArbiterDevice<'static, I2c<I2C1>>>`, but its trait bounds were not satisfied
   --> examples/ens160_f4.rs:75:40
    |
75  |             let eco2 = cx.local.ens160.eco2().await;
    |                                        ^^^^ method cannot be called on `&mut Ens160<ArbiterDevice<'static, I2c<I2C1>>>` due to unsatisfied trait bounds
    |
   ::: /home/paul/.cargo/git/checkouts/rtic-98d87eafbe677b11/22ac33a/rtic-sync/src/arbiter.rs:330:5
    |
330 |     pub struct ArbiterDevice<'a, BUS> {
    |     --------------------------------- doesn't satisfy `_: I2c`
    |
    = note: the full type name has been written to 'dev-testing/target/thumbv7em-none-eabihf/debug/examples/ens160_f4-64d1daf9f661405a.long-type-16809872599107602039.txt'
    = note: the following trait bounds were not satisfied:
            `rtic_sync::arbiter::i2c::ArbiterDevice<'static, stm32f4xx_hal::i2c::I2c<I2C1>>: stm32f4xx_hal::embedded_hal::i2c::I2c`

For more information about this error, try `rustc --explain E0599`.
warning: `rust-integration-testing-of-examples` (example "ens160_f4") generated 1 warning
error: could not compile `rust-integration-testing-of-examples` (example "ens160_f4") due to 1 previous error; 1 warning emitted

Is this a bug or am I missing something simple?

(This issue is somewhat related to #886 where @perlindgren and @korken89 suggested this example.)

@korken89
Copy link
Collaborator

Hi,

The error you are getting is because the trait I2c is the async trait.
You seem to be providing a sync implementation. Hope that helps!

@pdgilbert
Copy link
Author

Thanks @korken89. I'm new to many pieces of this, so pretty confused. I think you are suggesting I should

use embedded_hal_async::i2c::I2c;

rather than

use stm32f4xx_hal::i2c::I2c;

If so, that gets me back to all the errors that had me looking for a working example of arbiter with embedded-hal 1.0 and rtic. Is the example in rtic-sync (https://github.com/rtic-rs/rtic/blob/master/rtic-sync/src/arbiter.rs#L276) supposed to use an async I2c trait?

A pointer to a working stm32*-hal arbiter example would be helpful, for me and in documentation. Actually, any working example of embedded-hal 1.0, rtic v2 ,stm32*-hal with shared I2C bus would help me. (I have lots of rtic shared I2C bus examples that do not work after shifting to embedded-hal 1.0.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants