Expand description
§Inter-Integrated Circuit (I2C) - Master mode
§Overview
This driver implements the I2C Master mode. In this mode, the MCU initiates and controls the I2C communication with one or more slave devices. Slave devices are identified by their unique I2C addresses.
§Configuration
The driver can be configured using the Config
struct. To create a
configuration, you can use the Config::default()
method, and then modify
the individual settings as needed, by calling with_*
methods on the
Config
struct.
use esp_hal::{i2c::master::Config, time::Rate};
let config = Config::default().with_frequency(Rate::from_khz(100));
You will then need to pass the configuration to I2c::new
, and you can
also change the configuration later by calling I2c::apply_config
.
You will also need to specify the SDA and SCL pins when you create the driver instance.
use esp_hal::i2c::master::I2c;
// You need to configure the driver during initialization:
let mut i2c = I2c::new(peripherals.I2C0, config)?
.with_sda(peripherals.GPIO2)
.with_scl(peripherals.GPIO3);
// You can change the configuration later:
let new_config = config.with_frequency(Rate::from_khz(400));
i2c.apply_config(&new_config)?;
§Usage
The master communicates with slave devices using I2C transactions. A
transaction can be a write, a read, or a combination of both. The
I2c
driver provides methods for performing these transactions:
// `u8` is automatically converted to `I2cAddress::SevenBit`. The device
// address does not contain the `R/W` bit!
const DEVICE_ADDR: u8 = 0x77;
let write_buffer = [0xAA];
let mut read_buffer = [0u8; 22];
i2c.write(DEVICE_ADDR, &write_buffer)?;
i2c.write_read(DEVICE_ADDR, &write_buffer, &mut read_buffer)?;
i2c.read(DEVICE_ADDR, &mut read_buffer)?;
i2c.transaction(
DEVICE_ADDR,
&mut [
Operation::Write(&write_buffer),
Operation::Read(&mut read_buffer),
],
)?;
If you configure the driver to async
mode, the driver also provides
asynchronous versions of these methods:
// Reconfigure the driver to use async mode.
let mut i2c = i2c.into_async();
i2c.write_async(DEVICE_ADDR, &write_buffer).await?;
i2c.write_read_async(DEVICE_ADDR, &write_buffer, &mut read_buffer)
.await?;
i2c.read_async(DEVICE_ADDR, &mut read_buffer).await?;
i2c.transaction_async(
DEVICE_ADDR,
&mut [
Operation::Write(&write_buffer),
Operation::Read(&mut read_buffer),
],
)
.await?;
// You should still be able to use the blocking methods, if you need to:
i2c.write(DEVICE_ADDR, &write_buffer)?;
The I2C driver also implements embedded-hal and embedded-hal-async traits, so you can use it with any crate that supports these traits.
Structs§
Enums§
- Acknowledge
Check Failed Reason - I2C no acknowledge error reason.
- BusTimeout
- I2C SCL timeout period.
- Config
Error - I2C-specific configuration errors
- Error
- I2C-specific transmission errors
- Event
unstable
- Stability
- I2cAddress
- Representation of I2C address.
- Operation
- I2C operation.
- Software
Timeout unstable
- Software timeout for I2C operations.
Traits§
- Instance
- A peripheral singleton compatible with the I2C master driver.