rust-embedded / embedded-hal

A Hardware Abstraction Layer (HAL) for embedded systems
Apache License 2.0
1.95k stars 197 forks source link

embedded-hal-bus shared i2c usage #571

Closed pdgilbert closed 8 months ago

pdgilbert commented 8 months ago

Using embedded-hal_1.0.0 I have been trying to replace shared_bus in several examples. @rursprung pointed out the this can be done with embedded-hal-bus. I am finding it is not a simple replacement.

I have been using RefCellDevice. The code below compiles with stm32f4xx_hal and with stm32h7xx-hal branch eh-v1.0 as updated by @richardeoin. It uses crates

all of which use embedded-hal_1.0.0.

I have not tried to run on hardware. I am fairly sure it will not work, based on my confusion and the implication of the GIGO principle. (And also the fact that it does not pass the bus address to ssd1306.)

My coding effort has been guided by

but I am still confused. That is probably because I am missing some basic point everyone thinks is so obvious that there is no need to mention it.

I would very much appreciate any explanations/comments/advice. My main confusion is over what parts of the implementation should be done in device crates and what needs to be done in user code. I have a poor understand of what trait implementation coherence and the orphan rule imply for where things must be done in the hals, device crates, and user code.

The code compiles with a section that does more of the implementation than I think is needed in user code. Comments in the code indicate that section as well as something closer to what I think the user should need. Some other questions are also indicated in comments.

Click to expand code ``` #![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 cortex_m_rt::entry; use embedded_hal::delay::DelayNs; ///////////////////// ads use ads1x1x::{Ads1x1x, channel, ChannelSelection, DynamicOneShot, FullScaleRange, SlaveAddr}; ///////////////////// ina use ina219::{address::{Address, Pin}, measurements::BusVoltage, SyncIna219}; ///////////////////// ssd use ssd1306::{mode::BufferedGraphicsMode, prelude::*, I2CDisplayInterface, Ssd1306}; const DISPLAYSIZE:ssd1306::prelude::DisplaySize128x32 = DisplaySize128x32; const VPIX:i32 = 12; // vertical pixels for a line, including space use core::fmt::Write; use embedded_graphics::{ mono_font::{ascii::FONT_6X10 as FONT, MonoTextStyle, MonoTextStyleBuilder}, pixelcolor::BinaryColor, prelude::*, text::{Baseline, Text}, }; ///////////////////// hals #[cfg(feature = "stm32f4xx")] pub use stm32f4xx_hal::{ pac::{Peripherals, I2C1}, rcc::{Clocks, RccExt}, pac::{TIM2, TIM5}, timer::Delay, timer::TimerExt, gpio::GpioExt, prelude::*, block, }; #[cfg(feature = "stm32f4xx")] pub fn setup_from_dp(dp: Peripherals) -> ( impl I2c, impl DelayNs) { // NEEDS u8 NOT I2C1 Why? let rcc = dp.RCC.constrain(); let clocks = rcc.cfgr.freeze(); let gpiob = dp.GPIOB.split(); let scl = gpiob.pb8.into_alternate_open_drain(); let sda = gpiob.pb9.into_alternate_open_drain(); let i2c = dp.I2C1.i2c( (scl, sda), 400.kHz(), &clocks); // need ::<1000000_u32> for `FREQ` of the method `delay WHY? let delay = dp.TIM5.delay::<1000000_u32>(&clocks); (i2c, delay) } #[cfg(feature = "stm32h7xx")] use stm32h7xx_hal::{ pac::{Peripherals}, delay::DelayFromCountDownTimer, rcc::{RccExt}, pwr::PwrExt, prelude::*, block, }; #[cfg(feature = "stm32h7xx")] pub fn setup_from_dp(dp: Peripherals) -> ( impl I2c, impl DelayNs) { // NEEDS u8 NOT I2C1 Why? let rcc = dp.RCC.constrain(); let vos = dp.PWR.constrain().freeze(); let ccdr = rcc.sys_ck(100.MHz()).freeze(vos, &dp.SYSCFG); let clocks = ccdr.clocks; let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB); let scl = gpiob.pb8.into_alternate().set_open_drain(); let sda = gpiob.pb9.into_alternate().set_open_drain(); let i2c = dp.I2C1.i2c((scl, sda), 400.kHz(), ccdr.peripheral.I2C1, &clocks); // CountDownTimer not supported by embedded-hal 1.0.0 ?? let timer = dp.TIM5.timer(1.Hz(), ccdr.peripheral.TIM5, &clocks); let delay = DelayFromCountDownTimer::new(timer); (i2c, delay) } /////////////////////////////////////////////////////////////////////////////////////////// // HOW SHOULD THIS BE DOME? // SHOULD ANYTHING BE DEFINED IN DEVICE CRATES OR DOES EVERYTHING HAVE TO BE DONE IN THE USER CODE? //////////// I THINK IT SHOULD COMPILE (BUT DOES NOT) WITH SOMETHING LIKE THIS ////////////// // //use core::cell::RefCell; // //use embedded_hal::i2c::{I2c, SevenBitAddress, ErrorKind, ErrorType}; //Operation, //use embedded_hal_bus::i2c; //use embedded_hal_bus::i2c::RefCellDevice; // ////use embedded_hal::i2c::{Error}; ////////////////// IT DOES COMPILES USING THIS SECTION INSTEAD OF ABOVE //////////////////////////////////////// use core::cell::RefCell; use embedded_hal::i2c::{self as i2c, SevenBitAddress, I2c, ErrorKind, ErrorType}; // RefCellDevice cannot be imported because // "only traits defined in the current crate can be implemented for types defined outside of the crate" struct RefCellDevice<'a, T> { bus: &'a RefCell, } #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum Error { } impl i2c::Error for Error { fn kind(&self) -> i2c::ErrorKind { ErrorKind::Other } } impl<'a, T> RefCellDevice<'a, T> { /// Create a new `RefCellDevice`. #[inline] pub fn new(bus: &'a RefCell) -> Self { Self { bus } } } impl<'a, T> ErrorType for RefCellDevice<'a, T> where T: I2c, { type Error = T::Error; } impl<'a, T> I2c for RefCellDevice<'a, T> where T: I2c, { // DOES THIS TRAIT MEAN THAT ANYTHING SHARING THE BUS SHOULD USE ONLY THESE METHODS ? #[inline] fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { let bus = &mut *self.bus.borrow_mut(); bus.read(address, read) } #[inline] fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { let bus = &mut *self.bus.borrow_mut(); bus.write(address, write) } #[inline] fn write_read( &mut self, address: u8, write: &[u8], read: &mut [u8], ) -> Result<(), Self::Error> { let bus = &mut *self.bus.borrow_mut(); bus.write_read(address, write, read) } #[inline] fn transaction( //HOW IS THIS USED AND WHERE &mut self, address: u8, operations: &mut [embedded_hal::i2c::Operation<'_>], //WHAT DOES THIS DO? ) -> Result<(), Self::Error> { let bus = &mut *self.bus.borrow_mut(); bus.transaction(address, operations) } } /////////////////////////////////////////////////////////////////////////////////////////// fn display( voltage: BusVoltage, a_mv: i16, b_mv: [i16; 2], text_style: MonoTextStyle, display: &mut Ssd1306>, ) -> () where S: DisplaySize, { let mut lines: [heapless::String<32>; 3] = [ heapless::String::new(), heapless::String::new(), heapless::String::new(), ]; write!(lines[0], "ina V: {:?} mv? ", voltage).unwrap(); write!(lines[1], "ads_a V: {} mv ", a_mv).unwrap(); write!(lines[2], "ads_b A0: {} mv. ads_b A1: {} mv.", b_mv[0], b_mv[1]).unwrap(); display.clear_buffer(); for (i, line) in lines.iter().enumerate() { // start from 0 requires that the top is used for font baseline Text::with_baseline( line, Point::new(0, i as i32 * VPIX), text_style, Baseline::Top, ) .draw(&mut *display) .unwrap(); } display.flush().unwrap(); () } //////////////////////////////////////////////////////////////////////////////// #[entry] fn main() -> ! { let dp = Peripherals::take().unwrap(); let (i2cset, mut delay) = setup_from_dp(dp); let i2cset_ref_cell = RefCell::new(i2cset); let adc_a_rcd = RefCellDevice::new(&i2cset_ref_cell); let adc_b_rcd = RefCellDevice::new(&i2cset_ref_cell); let ina_rcd = RefCellDevice::new(&i2cset_ref_cell); let ssd_rcd = RefCellDevice::new(&i2cset_ref_cell); ///////////////////// ads let mut adc_a = Ads1x1x::new_ads1015(adc_a_rcd, SlaveAddr::Alternative(false, false)); //addr = GND let mut adc_b = Ads1x1x::new_ads1015(adc_b_rcd, SlaveAddr::Alternative(false, true)); //addr = V // set FullScaleRange to measure expected max voltage. adc_a.set_full_scale_range(FullScaleRange::Within4_096V).unwrap(); adc_b.set_full_scale_range(FullScaleRange::Within4_096V).unwrap(); ///////////////////// ina let mut ina = SyncIna219::new( ina_rcd, Address::from_pins(Pin::Gnd, Pin::Gnd)).unwrap(); ///////////////////// ssd //let interface = I2CDisplayInterface::new(ssd_rcd, 0x3C); // check address let interface = I2CDisplayInterface::new(ssd_rcd); // COMPILES BUT NOT USING ADDRESS ?? let mut disp = Ssd1306::new(interface, DISPLAYSIZE, DisplayRotation::Rotate0) .into_buffered_graphics_mode(); disp.init().unwrap(); let text_style = MonoTextStyleBuilder::new() .font(&FONT) .text_color(BinaryColor::On) .build(); Text::with_baseline( "Display initialized ...", Point::zero(), text_style, Baseline::Top, ) .draw(&mut disp) .unwrap(); ///////////////////// measure and display in loop loop { let voltage = ina.bus_voltage().unwrap(); let a_mv = block!(DynamicOneShot::read(&mut adc_a, ChannelSelection::SingleA0)).unwrap_or(8091); let values_b = [ block!(adc_b.read(channel::SingleA0)).unwrap_or(8091), block!(adc_b.read(channel::SingleA1)).unwrap_or(8091), ]; display(voltage, a_mv, values_b, text_style, &mut disp); delay.delay_ms(2000); // sleep for 2s } } ```
Click to expand Cargo.toml ``` [package] authors = ["pdGilbert"] categories = ["embedded", "no-std"] description = "ads, ina, ssd, embedded-hal-bus example" keywords = ["driver", "i2c", "embedded-hal-bus", "example"] license = "MIT OR Apache-2.0" name = "embedded-hal-bus_example" version = "0.0.1" edition = "2021" [dependencies] stm32f4xx-hal = { version = "0.20.0", optional = true } stm32h7xx-hal = { git = "https://github.com/stm32-rs/stm32h7xx-hal", optional = true , branch = "eh-v1.0"} ssd1306 = { git = "https://github.com/bugadani/ssd1306", branch = "ehal1" } ads1x1x = { git = "https://github.com/eldruin/ads1x1x-rs" } ina219 = { git = "https://github.com/tdittr/ina219", branch = "add-configuration-register" } # has eh1.0.0 embedded-hal = "1.0" embedded-hal-bus = { git = "https://github.com/rust-embedded/embedded-hal/" } embedded-graphics = ">=0.7" heapless = "0.7" cortex-m-rt = ">=0.7.0" panic-semihosting = { version = ">=0.5.2" } [features] stm32f4xx = ["stm32f4xx-hal", ] stm32h7xx = ["stm32h7xx-hal/rt", ] stm32f401 = ["stm32f4xx-hal/stm32f401" ] stm32f411 = ["stm32f4xx-hal/stm32f411" ] stm32h742 = ["stm32h7xx-hal/stm32h742" ] ```
Click to expand compile results with stm32f4xx_hal ``` $ cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32f401,stm32f4xx --example ads_ina_ssd Compiling proc-macro2 v1.0.78 Compiling nb v1.1.0 Compiling semver-parser v0.7.0 Compiling unicode-ident v1.0.12 Compiling cortex-m v0.7.7 Compiling embedded-hal v1.0.0 Compiling cortex-m-rt v0.7.3 Compiling critical-section v1.1.2 Compiling nb v0.1.3 Compiling syn v1.0.109 Compiling embedded-hal-async v1.0.0 Compiling void v1.0.2 Compiling semver v1.0.21 Compiling semver v0.9.0 Compiling rustc_version v0.2.3 Compiling vcell v0.1.3 Compiling volatile-register v0.2.2 Compiling embedded-hal v0.2.7 Compiling autocfg v1.1.0 Compiling az v1.2.1 Compiling byteorder v1.5.0 Compiling bitfield v0.13.2 Compiling bare-metal v0.2.5 Compiling stable_deref_trait v1.2.0 Compiling stm32f4 v0.15.1 Compiling gcd v2.3.0 Compiling rustc_version v0.4.0 Compiling display-interface v0.5.0 Compiling quote v1.0.35 Compiling powerfmt v0.2.0 Compiling cortex-m-semihosting v0.5.0 Compiling num-traits v0.2.17 Compiling syn v2.0.48 Compiling deranged v0.3.11 Compiling heapless v0.7.17 Compiling fugit v0.3.7 Compiling embedded-hal-bus v0.1.0 (https://github.com/rust-embedded/embedded-hal/#04b4f189) Compiling ssd1306 v0.8.4 (https://github.com/bugadani/ssd1306?branch=ehal1#0bae3a66) Compiling bare-metal v1.0.0 Compiling litrs v0.4.1 Compiling byte-slice-cast v1.2.2 Compiling ina219 v0.2.0 (https://github.com/tdittr/ina219?branch=add-configuration-register#0b13baf2) Compiling embedded-graphics-core v0.4.0 Compiling stm32f4xx-hal v0.20.0 Compiling time-core v0.1.2 Compiling time v0.3.31 Compiling float-cmp v0.9.0 Compiling display-interface-spi v0.5.0 Compiling fugit-timer v0.1.3 Compiling document-features v0.2.8 Compiling display-interface-i2c v0.5.0 Compiling embedded-dma v0.2.0 Compiling hash32 v0.2.1 Compiling embedded-hal-nb v1.0.0 Compiling embedded-hal v1.0.0 (https://github.com/rust-embedded/embedded-hal/#04b4f189) Compiling micromath v2.1.0 Compiling rand_core v0.6.4 Compiling embedded-storage v0.3.1 Compiling embedded-graphics v0.8.1 Compiling panic-semihosting v0.6.0 Compiling ads1x1x v0.2.2 (https://github.com/eldruin/ads1x1x-rs#5cd36134) Compiling enumflags2_derive v0.7.8 Compiling cortex-m-rt-macros v0.7.0 Compiling enumflags2 v0.7.8 Compiling embedded-hal-bus_example v0.0.1 (/ads_ina_ssd) Finished dev [unoptimized + debuginfo] target(s) in 19.69s ```
Click to expand compile results with stm32h7xx_hal ``` $ cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32h742,stm32h7xx --example ads_ina_ssd Compiling nb v0.1.3 Compiling paste v1.0.14 Compiling stm32h7 v0.15.1 Compiling cast v0.3.0 Compiling embedded-io v0.6.1 Compiling embedded-hal v0.2.7 Compiling cortex-m v0.7.7 Compiling cortex-m-semihosting v0.5.0 Compiling panic-semihosting v0.6.0 Compiling stm32h7xx-hal v0.15.1 (https://github.com/stm32-rs/stm32h7xx-hal?branch=eh-v1.0#b05811ce) Compiling embedded-hal-bus_example v0.0.1 (/ads_ina_ssd) Finished dev [unoptimized + debuginfo] target(s) in 22.18s ```
pdgilbert commented 8 months ago

For completeness, here are error messages when compiling with the section I think should work:

Click to expand compile errors with section I think should work (stm32f4xx_hal)( ``` $ cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32f401,stm32f4xx --example ads_ina_ssd Compiling embedded-hal-bus_example v0.0.1 (/ads_ina_ssd) warning: unused imports: `ErrorKind`, `ErrorType`, `SevenBitAddress` --> examples/ads_ina_ssd.rs:109:30 | 109 | use embedded_hal::i2c::{I2c, SevenBitAddress, ErrorKind, ErrorType}; //... | ^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: unused import: `embedded_hal_bus::i2c` --> examples/ads_ina_ssd.rs:110:5 | 110 | use embedded_hal_bus::i2c; | ^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:244:42 | 244 | ...et mut adc_a = Ads1x1x::new_ads1015(adc_a_rcd, SlaveAddr::Alternativ... | -------------------- ^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> note: required by a bound in `ads1x1x::construction::>::new_ads1015` --> .cargo/git/checkouts/ads1x1x-rs-bbbb6dc8bfa9c063/5cd3613/src/construction.rs:39:1 | 39 | impl_new_destroy!(Ads1015, new_ads1015, destroy_ads1015, ic::Resolution12Bi... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | | | required by a bound in this associated function | required by this bound in `ads1x1x::construction::>::new_ads1015` = note: this error originates in the macro `impl_new_destroy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:245:42 | 245 | ...et mut adc_b = Ads1x1x::new_ads1015(adc_b_rcd, SlaveAddr::Alternativ... | -------------------- ^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> note: required by a bound in `ads1x1x::construction::>::new_ads1015` --> .cargo/git/checkouts/ads1x1x-rs-bbbb6dc8bfa9c063/5cd3613/src/construction.rs:39:1 | 39 | impl_new_destroy!(Ads1015, new_ads1015, destroy_ads1015, ic::Resolution12Bi... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | | | required by a bound in this associated function | required by this bound in `ads1x1x::construction::>::new_ads1015` = note: this error originates in the macro `impl_new_destroy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: the method `set_full_scale_range` exists for struct `Ads1x1x, ..., ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:248:11 | 248 | adc_a.set_full_scale_range(FullScaleRange::Within4_096V).unwrap(); | ^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Ads1x1x, ..., ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `<_ as ErrorType>::Error = _` | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-16586508009076085825.txt' = note: the following trait bounds were not satisfied: ` as embedded_hal::i2c::ErrorType>::Error = _` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` error[E0599]: the method `set_full_scale_range` exists for struct `Ads1x1x, ..., ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:249:11 | 249 | adc_b.set_full_scale_range(FullScaleRange::Within4_096V).unwrap(); | ^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Ads1x1x, ..., ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `<_ as ErrorType>::Error = _` | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-16515996984657643508.txt' = note: the following trait bounds were not satisfied: ` as embedded_hal::i2c::ErrorType>::Error = _` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:252:36 | 252 | let mut ina = SyncIna219::new( ina_rcd, Address::from_pins(Pin::Gnd... | --------------- ^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> note: required by a bound in `SyncIna219::::new` --> /ads_ina_ssd/target/thumbv7em-none-eabihf/debug/build/ina219-86a769b8c3dec220/out/de-asynced.rs:27:10 | 27 | I2C: I2c, | ^^^ required by this bound in `SyncIna219::::new` ... 36 | pub fn new( | --- required by a bound in this associated function error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` is not satisfied --> examples/ads_ina_ssd.rs:252:19 | 252 | ... = SyncIna219::new( ina_rcd, Address::from_pins(Pin::Gnd, Pin::Gnd)).un... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `embedded_hal::i2c::ErrorType` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:78:1 | 78 | / impl<'a, T> ErrorType for RefCellDevice<'a, T> 79 | | where 80 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::ErrorType`: I2cStub stm32f4xx_hal::i2c::I2c &mut T error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:256:46 | 256 | ...et interface = I2CDisplayInterface::new(ssd_rcd); // COMPIL... | ------------------------ ^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> note: required by a bound in `I2CDisplayInterface::new` --> .cargo/git/checkouts/ssd1306-407b1a92e31533f1/0bae3a6/src/i2c_interface.rs:15:12 | 13 | pub fn new(i2c: I) -> I2CInterface | --- required by a bound in this associated function 14 | where 15 | I: embedded_hal::i2c::I2c, | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `I2CDisplayInterface::new` error[E0599]: the method `init` exists for struct `Ssd1306, ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:261:10 | 261 | disp.init().unwrap(); | ^^^^ method cannot be called on `Ssd1306, ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/ssd1306-407b1a92e31533f1/0bae3a6/src/lib.rs:139:1 | 139 | pub struct Ssd1306 { | ---------------------------------- doesn't satisfy `_: DisplayConfig` | ::: .cargo/registry/src/index.crates.io-6f17d22bba15001f/display-interface-i2c-0.5.0/src/lib.rs:10:1 | 10 | pub struct I2CInterface { | ---------------------------- doesn't satisfy `_: WriteOnlyDataCommand` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-5903234030866805803.txt' = note: the following trait bounds were not satisfied: `I2CInterface>: ssd1306::prelude::WriteOnlyDataCommand` which is required by `Ssd1306>, ssd1306::prelude::DisplaySize128x32, BufferedGraphicsMode>: ssd1306::mode::DisplayConfig` error[E0599]: the method `bus_voltage` exists for struct `SyncIna219, ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:279:27 | 279 | let voltage = ina.bus_voltage().unwrap(); | ^^^^^^^^^^^ method cannot be called on `SyncIna219, ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-16620405065280132329.txt' = note: the following trait bounds were not satisfied: `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:281:48 | 281 | ... a_mv = block!(DynamicOneShot::read(&mut adc_a, ChannelSelection::Si... | -------------------- ^^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> = note: required for `Ads1x1x, ..., ..., ...>` to implement `DynamicOneShot` = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-16586508009076085825.txt' error[E0599]: the method `read` exists for struct `Ads1x1x, ..., ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:284:26 | 284 | block!(adc_b.read(channel::SingleA0)).unwrap_or(8091), | ^^^^ method cannot be called on `Ads1x1x, ..., ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/ads1x1x-rs-bbbb6dc8bfa9c063/5cd3613/src/types.rs:248:1 | 248 | pub struct Ads1x1x { | --------------------------------------- doesn't satisfy `_: DynamicOneShot` | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `<_ as ErrorType>::Error = _` | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-16515996984657643508.txt' = note: the following trait bounds were not satisfied: ` as embedded_hal::i2c::ErrorType>::Error = _` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` ` as embedded_hal::i2c::ErrorType>::Error = _` which is required by `Ads1x1x, Ads1015, Resolution12Bit, ads1x1x::mode::OneShot>: DynamicOneShot` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` which is required by `Ads1x1x, Ads1015, Resolution12Bit, ads1x1x::mode::OneShot>: DynamicOneShot` error[E0599]: the method `read` exists for struct `Ads1x1x, ..., ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:285:26 | 285 | block!(adc_b.read(channel::SingleA1)).unwrap_or(8091), | ^^^^ method cannot be called on `Ads1x1x, ..., ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/ads1x1x-rs-bbbb6dc8bfa9c063/5cd3613/src/types.rs:248:1 | 248 | pub struct Ads1x1x { | --------------------------------------- doesn't satisfy `_: DynamicOneShot` | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `<_ as ErrorType>::Error = _` | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-16515996984657643508.txt' = note: the following trait bounds were not satisfied: ` as embedded_hal::i2c::ErrorType>::Error = _` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` ` as embedded_hal::i2c::ErrorType>::Error = _` which is required by `Ads1x1x, Ads1015, Resolution12Bit, ads1x1x::mode::OneShot>: DynamicOneShot` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` which is required by `Ads1x1x, Ads1015, Resolution12Bit, ads1x1x::mode::OneShot>: DynamicOneShot` error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:288:54 | 288 | display(voltage, a_mv, values_b, text_style, &mut disp); | ------- ^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> = note: required for `I2CInterface>` to implement `ssd1306::prelude::WriteOnlyDataCommand` = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-15940486291940955331.txt' note: required by a bound in `display` --> examples/ads_ina_ssd.rs:199:32 | 194 | fn display( | ------- required by a bound in this function ... 199 | display: &mut Ssd1306: embedded_hal::i2c::ErrorType` is not satisfied --> examples/ads_ina_ssd.rs:252:19 | 252 | let mut ina = SyncIna219::new( ina_rcd, Address::from_pins(Pin::Gnd... | ^^^^^^^^^^^^^^^ the trait `embedded_hal::i2c::ErrorType` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:78:1 | 78 | / impl<'a, T> ErrorType for RefCellDevice<'a, T> 79 | | where 80 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::ErrorType`: I2cStub stm32f4xx_hal::i2c::I2c &mut T error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:281:27 | 281 | ...k!(DynamicOneShot::read(&mut adc_a, ChannelSelection::SingleA0)).unw... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> = note: required for `Ads1x1x, ..., ..., ...>` to implement `DynamicOneShot` = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-87889009d6170455.long-type-16586508009076085825.txt' Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`. warning: `embedded-hal-bus_example` (example "ads_ina_ssd") generated 2 warnings error: could not compile `embedded-hal-bus_example` (example "ads_ina_ssd") due to 15 previous errors; 2 warnings emitted ```
Click to expand compile errors with section I think should work (stm32h7xx_hal)( ``` $ cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32h742,stm32h7xx --example ads_ina_ssd Compiling embedded-hal-bus_example v0.0.1 (/ads_ina_ssd) warning: unused imports: `ErrorKind`, `ErrorType`, `SevenBitAddress` --> examples/ads_ina_ssd.rs:109:30 | 109 | use embedded_hal::i2c::{I2c, SevenBitAddress, ErrorKind, ErrorType}; //... | ^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: unused import: `embedded_hal_bus::i2c` --> examples/ads_ina_ssd.rs:110:5 | 110 | use embedded_hal_bus::i2c; | ^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:244:42 | 244 | ...et mut adc_a = Ads1x1x::new_ads1015(adc_a_rcd, SlaveAddr::Alternativ... | -------------------- ^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> note: required by a bound in `ads1x1x::construction::>::new_ads1015` --> .cargo/git/checkouts/ads1x1x-rs-bbbb6dc8bfa9c063/5cd3613/src/construction.rs:39:1 | 39 | impl_new_destroy!(Ads1015, new_ads1015, destroy_ads1015, ic::Resolution12Bi... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | | | required by a bound in this associated function | required by this bound in `ads1x1x::construction::>::new_ads1015` = note: this error originates in the macro `impl_new_destroy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:245:42 | 245 | ...et mut adc_b = Ads1x1x::new_ads1015(adc_b_rcd, SlaveAddr::Alternativ... | -------------------- ^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> note: required by a bound in `ads1x1x::construction::>::new_ads1015` --> .cargo/git/checkouts/ads1x1x-rs-bbbb6dc8bfa9c063/5cd3613/src/construction.rs:39:1 | 39 | impl_new_destroy!(Ads1015, new_ads1015, destroy_ads1015, ic::Resolution12Bi... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | | | required by a bound in this associated function | required by this bound in `ads1x1x::construction::>::new_ads1015` = note: this error originates in the macro `impl_new_destroy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: the method `set_full_scale_range` exists for struct `Ads1x1x, ..., ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:248:11 | 248 | adc_a.set_full_scale_range(FullScaleRange::Within4_096V).unwrap(); | ^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Ads1x1x, ..., ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `<_ as ErrorType>::Error = _` | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-16730457139217183598.txt' = note: the following trait bounds were not satisfied: ` as embedded_hal::i2c::ErrorType>::Error = _` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` error[E0599]: the method `set_full_scale_range` exists for struct `Ads1x1x, ..., ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:249:11 | 249 | adc_b.set_full_scale_range(FullScaleRange::Within4_096V).unwrap(); | ^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Ads1x1x, ..., ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `<_ as ErrorType>::Error = _` | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-8449901325409358039.txt' = note: the following trait bounds were not satisfied: ` as embedded_hal::i2c::ErrorType>::Error = _` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:252:36 | 252 | let mut ina = SyncIna219::new( ina_rcd, Address::from_pins(Pin::Gnd... | --------------- ^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> note: required by a bound in `SyncIna219::::new` --> /ads_ina_ssd/target/thumbv7em-none-eabihf/debug/build/ina219-86a769b8c3dec220/out/de-asynced.rs:27:10 | 27 | I2C: I2c, | ^^^ required by this bound in `SyncIna219::::new` ... 36 | pub fn new( | --- required by a bound in this associated function error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` is not satisfied --> examples/ads_ina_ssd.rs:252:19 | 252 | ... = SyncIna219::new( ina_rcd, Address::from_pins(Pin::Gnd, Pin::Gnd)).un... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `embedded_hal::i2c::ErrorType` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:78:1 | 78 | / impl<'a, T> ErrorType for RefCellDevice<'a, T> 79 | | where 80 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::ErrorType`: I2cStub stm32h7xx_hal::i2c::I2c stm32h7xx_hal::i2c::I2c stm32h7xx_hal::i2c::I2c stm32h7xx_hal::i2c::I2c &mut T error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:256:46 | 256 | ...et interface = I2CDisplayInterface::new(ssd_rcd); // COMPIL... | ------------------------ ^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> note: required by a bound in `I2CDisplayInterface::new` --> .cargo/git/checkouts/ssd1306-407b1a92e31533f1/0bae3a6/src/i2c_interface.rs:15:12 | 13 | pub fn new(i2c: I) -> I2CInterface | --- required by a bound in this associated function 14 | where 15 | I: embedded_hal::i2c::I2c, | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `I2CDisplayInterface::new` error[E0599]: the method `init` exists for struct `Ssd1306, ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:261:10 | 261 | disp.init().unwrap(); | ^^^^ method cannot be called on `Ssd1306, ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/ssd1306-407b1a92e31533f1/0bae3a6/src/lib.rs:139:1 | 139 | pub struct Ssd1306 { | ---------------------------------- doesn't satisfy `_: DisplayConfig` | ::: .cargo/registry/src/index.crates.io-6f17d22bba15001f/display-interface-i2c-0.5.0/src/lib.rs:10:1 | 10 | pub struct I2CInterface { | ---------------------------- doesn't satisfy `_: WriteOnlyDataCommand` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-5483017462222041460.txt' = note: the following trait bounds were not satisfied: `I2CInterface>: ssd1306::prelude::WriteOnlyDataCommand` which is required by `Ssd1306>, ssd1306::prelude::DisplaySize128x32, BufferedGraphicsMode>: ssd1306::mode::DisplayConfig` error[E0599]: the method `bus_voltage` exists for struct `SyncIna219, ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:279:27 | 279 | let voltage = ina.bus_voltage().unwrap(); | ^^^^^^^^^^^ method cannot be called on `SyncIna219, ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-11763277744911582059.txt' = note: the following trait bounds were not satisfied: `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:281:48 | 281 | ... a_mv = block!(DynamicOneShot::read(&mut adc_a, ChannelSelection::Si... | -------------------- ^^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> = note: required for `Ads1x1x, ..., ..., ...>` to implement `DynamicOneShot` = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-16730457139217183598.txt' error[E0599]: the method `read` exists for struct `Ads1x1x, ..., ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:284:26 | 284 | block!(adc_b.read(channel::SingleA0)).unwrap_or(8091), | ^^^^ method cannot be called on `Ads1x1x, ..., ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/ads1x1x-rs-bbbb6dc8bfa9c063/5cd3613/src/types.rs:248:1 | 248 | pub struct Ads1x1x { | --------------------------------------- doesn't satisfy `_: DynamicOneShot` | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `<_ as ErrorType>::Error = _` | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-8449901325409358039.txt' = note: the following trait bounds were not satisfied: ` as embedded_hal::i2c::ErrorType>::Error = _` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` ` as embedded_hal::i2c::ErrorType>::Error = _` which is required by `Ads1x1x, Ads1015, Resolution12Bit, ads1x1x::mode::OneShot>: DynamicOneShot` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` which is required by `Ads1x1x, Ads1015, Resolution12Bit, ads1x1x::mode::OneShot>: DynamicOneShot` error[E0599]: the method `read` exists for struct `Ads1x1x, ..., ..., ...>`, but its trait bounds were not satisfied --> examples/ads_ina_ssd.rs:285:26 | 285 | block!(adc_b.read(channel::SingleA1)).unwrap_or(8091), | ^^^^ method cannot be called on `Ads1x1x, ..., ..., ...>` due to unsatisfied trait bounds | ::: .cargo/git/checkouts/ads1x1x-rs-bbbb6dc8bfa9c063/5cd3613/src/types.rs:248:1 | 248 | pub struct Ads1x1x { | --------------------------------------- doesn't satisfy `_: DynamicOneShot` | ::: .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:66:1 | 66 | pub struct RefCellDevice<'a, T> { | ------------------------------- | | | doesn't satisfy `<_ as ErrorType>::Error = _` | doesn't satisfy `_: ErrorType` | doesn't satisfy `_: I2c` | = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-8449901325409358039.txt' = note: the following trait bounds were not satisfied: ` as embedded_hal::i2c::ErrorType>::Error = _` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::ErrorType` which is required by `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` ` as embedded_hal::i2c::ErrorType>::Error = _` which is required by `Ads1x1x, Ads1015, Resolution12Bit, ads1x1x::mode::OneShot>: DynamicOneShot` `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` which is required by `Ads1x1x, Ads1015, Resolution12Bit, ads1x1x::mode::OneShot>: DynamicOneShot` error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:288:54 | 288 | display(voltage, a_mv, values_b, text_style, &mut disp); | ------- ^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | | | required by a bound introduced by this call | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> = note: required for `I2CInterface>` to implement `ssd1306::prelude::WriteOnlyDataCommand` = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-16554978696879225790.txt' note: required by a bound in `display` --> examples/ads_ina_ssd.rs:199:32 | 194 | fn display( | ------- required by a bound in this function ... 199 | display: &mut Ssd1306: embedded_hal::i2c::ErrorType` is not satisfied --> examples/ads_ina_ssd.rs:252:19 | 252 | let mut ina = SyncIna219::new( ina_rcd, Address::from_pins(Pin::Gnd... | ^^^^^^^^^^^^^^^ the trait `embedded_hal::i2c::ErrorType` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:78:1 | 78 | / impl<'a, T> ErrorType for RefCellDevice<'a, T> 79 | | where 80 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::ErrorType`: I2cStub stm32h7xx_hal::i2c::I2c stm32h7xx_hal::i2c::I2c stm32h7xx_hal::i2c::I2c stm32h7xx_hal::i2c::I2c &mut T error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>: embedded_hal::i2c::I2c` is not satisfied --> examples/ads_ina_ssd.rs:281:27 | 281 | ...k!(DynamicOneShot::read(&mut adc_a, ChannelSelection::SingleA0)).unw... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `embedded_hal::i2c::I2c` is not implemented for `embedded_hal_bus::i2c::RefCellDevice<'_, impl embedded_hal::i2c::I2c>` | help: trait impl with same name found --> .cargo/git/checkouts/embedded-hal-2c6e880c6b254bb0/04b4f18/embedded-hal-bus/src/i2c/refcell.rs:85:1 | 85 | / impl<'a, T> I2c for RefCellDevice<'a, T> 86 | | where 87 | | T: I2c, | |___________^ = note: perhaps two different versions of crate `embedded_hal` are being used? = help: the following other types implement trait `embedded_hal::i2c::I2c`: as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> as embedded_hal::i2c::I2c> <&mut T as embedded_hal::i2c::I2c> = note: required for `Ads1x1x, ..., ..., ...>` to implement `DynamicOneShot` = note: the full type name has been written to '/ads_ina_ssd/target/thumbv7em-none-eabihf/debug/examples/ads_ina_ssd-5d0addd19a929217.long-type-16730457139217183598.txt' Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`. warning: `embedded-hal-bus_example` (example "ads_ina_ssd") generated 2 warnings error: could not compile `embedded-hal-bus_example` (example "ads_ina_ssd") due to 15 previous errors; 2 warnings emitted ```
bugadani commented 8 months ago

The problem is this line in your Cargo.toml:

embedded-hal-bus = { git = "https://github.com/rust-embedded/embedded-hal/" }

You can't mix and match dependencies from crates.io and git. This import causes a second embedded-hal to be imported, which defines a (from the compiler's viewpoint) different I2c trait than the STM32 crates implement, or the device crates expect.

The fix is as simple as replacing it with a version from crates.io:

embedded-hal-bus = "0.1"

pdgilbert commented 8 months ago

Thank you @bugadani . When I use

embedded-hal = "1.0"
embedded-hal-bus = "0.1"

the code compiles without error using the section I thought should work. I am still not passing the bus address to ssd1306. If I change from

    let interface = I2CDisplayInterface::new(ssd_rcd); 

to

    let interface = I2CDisplayInterface::new(ssd_rcd, 0x3C); 

I get

error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> examples/ads_ina_ssd.rs:256:21
    |
256 | ...nterface = I2CDisplayInterface::new(ssd_rcd, 0x3C);  // check address 
    |               ^^^^^^^^^^^^^^^^^^^^^^^^        ------
    |                                               | |
    |                                               | unexpected argument of type `{integer}`
    |                                               help: remove the extra argument
    |
note: associated function defined here
   --> /home/paul/.cargo/git/checkouts/ssd1306-407b1a92e31533f1/0bae3a6/src/i2c_interface.rs:13:12
    |
13  |     pub fn new<I>(i2c: I) -> I2CInterface<I>
    |            ^^^

Also, if I specify both hals from git:

embedded-hal = { git = "https://github.com/rust-embedded/embedded-hal/" }
embedded-hal-bus = { git = "https://github.com/rust-embedded/embedded-hal/" }

I get errors as before. I guess this is probably due to the git versions of ads1x1x, ina219, and ssd1306 all using the release version of embedded-hal. It seems mixing and matching traits is more sensitive to versions than mixing and matching types.

Does this mean that all dependencies in a project must use the same version of embedded-hal?

And, does it mean that update rules will become a problem? For example ads1x1x specifies embedded-hal = "1" while ssd1306 specifies embedded-hal = "1.0.0". Eventually some device crates will specify '1.0.1'. If I understand cargo update, which is questionable, this can result in a mix of versions.

If the last is true, perhaps there should be a preferred way to specify the dependency to help avoid mixing versions?

bugadani commented 8 months ago

Rust has no method overloading and new only takes one argument. Why do you expect it to work?

What you want is new_custom_address (although new already uses 0x3C as the address, so why do you want to set it to the same value?)

pdgilbert commented 8 months ago

Thanks @bugadani . The fog is beginning to clear, there were a few things I did not understand correctly.