/ firmware / examples / esp32s3 / i2c.rs
i2c.rs
 1  #![no_std]
 2  #![no_main]
 3  
 4  use defmt::info;
 5  use embassy_executor::Spawner;
 6  use embassy_time::{Duration, Ticker, Timer};
 7  use esp_hal::{
 8      clock::CpuClock,
 9      gpio::{Level, Output, OutputConfig},
10      i2c::master::{Config as I2cConfig, I2c},
11      interrupt::software::SoftwareInterruptControl,
12      time::Rate,
13      timer::timg::TimerGroup,
14  };
15  use panic_rtt_target as _;
16  
17  extern crate alloc;
18  
19  const I2C_BUS_FREQUENCY_KHZ: u32 = 100;
20  
21  esp_bootloader_esp_idf::esp_app_desc!();
22  
23  #[esp_rtos::main]
24  async fn main(_spawner: Spawner) -> ! {
25      rtt_target::rtt_init_defmt!();
26  
27      let hal_configuration = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
28      let peripherals = esp_hal::init(hal_configuration);
29  
30      esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744);
31      esp_alloc::heap_allocator!(size: 64 * 1024);
32  
33      let timer_group0 = TimerGroup::new(peripherals.TIMG0);
34      let sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
35      esp_rtos::start(timer_group0.timer0, sw_ints.software_interrupt0);
36  
37      let _sensor_power_relay = Output::new(peripherals.GPIO5, Level::High, OutputConfig::default());
38      Timer::after(Duration::from_millis(1_000)).await;
39  
40      let mut i2c_bus = I2c::new(
41          peripherals.I2C0,
42          I2cConfig::default().with_frequency(Rate::from_khz(I2C_BUS_FREQUENCY_KHZ)),
43      )
44      .unwrap()
45      .with_sda(peripherals.GPIO15)
46      .with_scl(peripherals.GPIO16)
47      .into_async();
48  
49      info!(
50          "i2c scan started on I2C0 (SDA=GPIO{}, SCL=GPIO{}, {}kHz)",
51          15, 16, I2C_BUS_FREQUENCY_KHZ
52      );
53  
54      let mut scan_interval = Ticker::every(Duration::from_secs(2));
55  
56      loop {
57          scan_interval.next().await;
58          info!("scanning I2C addresses 0x03..=0x77");
59  
60          let mut found_device_count: usize = 0;
61  
62          for i2c_address in 0x03_u8..=0x77_u8 {
63              if i2c_bus.write_async(i2c_address, &[]).await.is_ok() {
64                  found_device_count += 1;
65                  info!("found i2c device at address {}", i2c_address);
66  
67                  if i2c_address == 0x70 {
68                      info!("address 0x70 often indicates a TCA9548A I2C multiplexer");
69                  }
70  
71                  if (0x44_u8..=0x47_u8).contains(&i2c_address) {
72                      info!("address {} matches a possible CHT832X sensor", i2c_address);
73                  }
74              }
75          }
76  
77          info!("i2c scan complete: {} device(s) found", found_device_count);
78      }
79  }