Closed empirephoenix closed 3 weeks ago
It would've been better to ask this question on the Matrix ESP-RS chat rather than opening an issue here, but anyway.
In any case, you should absolutely not play and hack around the I2cDriver
internals!
Currently I'm force creating a new driver based on the first ones port. But since these fields are private this is obviously no the correct way to do it.
let driver = I2cDriver{ i2c: port as u8, _p: std::marker::PhantomData, };
The "port" ^^^ simply means which of the (potentially multiple) I2c peripherals (or "bus"-es) should be used by this I2cDriver. esp32 as far as I remember has only one i2c peripheral/bus, but the c3 and others have two.
( Note that an i2c "peripheral" (or bus) is NOT the same as the slave device(s) you attach to this bus, like your temperature sensor, or CMOS clock or whatever. All of these can be attached to a single i2c bus (one I2cDriver) and thus use the same i2c pins, or - which is simple - each device can be attached to one of the 2 i2c bus-es supported by newer chips. )
Now, I assume you have TWO (or more) such devices, but just one I2cDriver
and so you are struggling because you cannot have your e.g. CMOS clock Rust driver and your e.g. temp sensor Rust driver "sharing" the single I2cDriver
.
To do this:
Ic2Driver
in a std::sync::Mutex
with e.g. let my_i2c_driver_mutex = std::sync::Mutex::new(my_i2c_driver)
MutexDevice::new(&my_i2c_driver_mutex)
and pass this one to e.g. your CMOS clockMutexDevice::new(&my_i2c_driver_mutex)
and pass this one to e.g. your temp sensorIf you want the mutex to be shared into the MutexDevice
instances with an Arc
instead of by &
just copy-paste the mutex.rs
file I referred to and replace the &
references to the mutex with an Arc
.
Ah sorry did not know there is a matrix channel at all. Joined it now and will ask similar stuff there in the future.
I currently try to wrap my head around, how I could share a I2CDriver between multiple I2CDevices.
Currently I'm force creating a new driver based on the first ones port. But since these fields are private this is obviously no the correct way to do it.
let driver = I2cDriver{ i2c: port as u8, _p: std::marker::PhantomData, };
I tried via unchecked_clone to clone all pins and then create a second driver via new(), but that one crashes since it tries to low lever init the i2c hardware a second time.
E (1035) i2c: i2c driver install error thread 'main' panicked at src/plant_hal.rs:1016:65: called Result::unwrap() on an Err value: ESP_FAIL (error code -1) note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
Is there any solution to this that I do not see?