I am quite new to Rust and are diving into the relatively complicated embedded programming, perhaps thats my problem, please bear with me...
I use the RPi Pico, with an SH11106 display over i2c, using https://github.com/jamwaffles/sh1106. I have another i2c peripheral (MCP3421) connected to the same bus. I am using Embassy.
My problem is, that after passing the i2c interface to the SH1106 driver, it isn't accessible anymore. I cannot read data from with i2c.read() and display it. The i2c instance is moved, I understand that. But WHY is it moved? IMHO this contradicts the whole purpose a bus with multiple devices attached to it. So...
- I am too stupid/fresh and miss an obvious Rust way to re-use the i2c?
- Is there a serious reason that display drivers take the whole bus?
- (nearly impossible) Is there a design problem with the mentioned display driver and any others I inspected?
Any comments?
Here is a (hopefully sufficient) snippet of my code. The problem certainly isn't tied to Embassy, I just mentioned that I use it.
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let used_i2c = p.I2C0;
let sda = p.PIN_12;
let scl = p.PIN_13;
let mut data = [0u8; 4];
info!("set up i2c ");
let mut i2c = i2c::I2c::new_async(used_i2c, scl, sda, Irqs, Config::default());
let mut display: GraphicsMode<_> = Builder::new().connect_i2c(i2c).into();
i2c.read_async(ADDRESS_16, &mut data).await.unwrap(); <--- Here the compiler protests.
...
As i found out, it seems that my question has been answered a while ago, but it gave the developers of the "embedded-hal" some headache, too. This discussion should give the answers:
https://github.com/rust-embedded/embedded-hal/issues/35
Now i just have to learn enough rust to understand it...
Edit: Here a blog post related to that issue
https://blog.rahix.de/001-shared-bus/
And the mentioned library.
https://docs.rs/shared-bus/latest/shared_bus/