use embedded_hal_bus::i2c::AtomicDevice; use embedded_hal_bus::util::AtomicCell; use esp_hal::gpio::interconnect::PeripheralInput; use esp_hal::i2c::master::Config; use esp_hal::{gpio::interconnect::PeripheralOutput, i2c::master::I2c}; type InnerI2cBus<'a> = esp_hal::i2c::master::I2c<'a, esp_hal::Blocking>; pub type I2cBus<'a> = &'a AtomicCell>; pub type I2cDevice<'a> = AtomicDevice<'a, esp_hal::i2c::master::I2c<'a, esp_hal::Blocking>>; pub struct I2cBusPinConfiguration { pub i2c_peripheral: I2C, pub scl: SCL, pub sda: SDA, } impl<'a, I2C, SCL, SDA> I2cBusPinConfiguration where I2C: esp_hal::i2c::master::Instance + 'a, SCL: PeripheralOutput<'a> + PeripheralInput<'a>, SDA: PeripheralOutput<'a> + PeripheralInput<'a>, { pub fn build(self) -> Result>, Self> { let config = Config::default().with_frequency(esp_hal::time::Rate::from_khz(400)); match I2c::new(self.i2c_peripheral, config) { Ok(bus) => { let i2c = bus.with_sda(self.sda).with_scl(self.scl); log::info!("Shared I2C bus ready on GPIO17 (SDA) and GPIO18 (SCL)"); Ok(AtomicCell::new(i2c)) } Err(e) => { log::error!("Shared I2C bus initialization failed for GPIO17/GPIO18: {e:?}"); unimplemented!("Partial move makes it impossible to retry."); // Err(self) } } } }