Module master

Source
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§

AnyI2c
Any I2C peripheral.
Config
I2C driver configuration
I2c
I2C driver

Enums§

AcknowledgeCheckFailedReason
I2C no acknowledge error reason.
BusTimeout
I2C SCL timeout period.
ConfigError
I2C-specific configuration errors
Error
I2C-specific transmission errors
Eventunstable
Stability
I2cAddress
Representation of I2C address.
Operation
I2C operation.
SoftwareTimeoutunstable
Software timeout for I2C operations.

Traits§

Instance
A peripheral singleton compatible with the I2C master driver.