i2c_bus

[中文]

How to Use i2c_bus

  1. Create a bus: create a bus object using i2c_bus_create(). During the process, you need to specify the I2C port number and the bus configuration option i2c_config_t, which includes SDA and SCL pin numbers, pull-up and pull-down modes, as these are determined when the system is designed and normally will not be changed at runtime. The bus configuration option also includes the default clock frequency of the bus, which is used when the device does not specify a frequency.

  2. Create a device: use i2c_bus_device_create() to create a device on the bus object created in the first step. During the process, you need to specify bus handle, the I2C address of the device, and the clock frequency when the device is running. The frequency will be dynamically changed during I2C transmission based on device configuration options. The device clock frequency can be configured as 0, indicating the current bus frequency is used by default.

  3. Data reading: use i2c_bus_read_byte() or i2c_bus_read_bytes() to read Byte data; use i2c_bus_read_bit() or i2c_bus_read_bits() to read bit data. During the process, you only need to pass in the device handle, the device register address, a buffer to hold the read data, the read length, etc. The register address can be configured as NULL_I2C_MEM_ADDR for devices without internal registers.

  4. Data writing: use i2c_bus_write_byte() or i2c_bus_write_bytes() to write Byte data; use i2c_bus_write_bit() or i2c_bus_write_bits() to write bit data. During the process, you only need to pass in the device handle, the device register address, the data location to be written, the write length, etc. The register address can be configured as NULL_I2C_MEM_ADDR for devices without internal registers.

  5. Delete device and bus: if all i2c_bus communication has been completed, you can free your system resources by deleting devices and bus objects. Use i2c_bus_device_delete() to delete created devices respectively, then use i2c_bus_delete() to delete bus resources. If the bus is deleted with the device not being deleted yet, this operation will not take effect.

Example:

i2c_config_t conf = {
    .mode = I2C_MODE_MASTER,
    .sda_io_num = I2C_MASTER_SDA_IO,
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_io_num = I2C_MASTER_SCL_IO,
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .master.clk_speed = 100000,
}; // i2c_bus configurations

uint8_t data_rd[2] = {0};
uint8_t data_wr[2] = {0x01, 0x21};

i2c_bus_handle_t i2c0_bus = i2c_bus_create(I2C_NUM_0, &conf); // create i2c_bus
i2c_bus_device_handle_t i2c_device1 = i2c_bus_device_create(i2c0_bus, 0x28, 400000); // create device1, address: 0x28 , clk_speed: 400000
i2c_bus_device_handle_t i2c_device2 = i2c_bus_device_create(i2c0_bus, 0x32, 0); // create device2, address: 0x32 , clk_speed: no-specified

i2c_bus_read_bytes(i2c_device1, NULL_I2C_MEM_ADDR, 2, data_rd); // read bytes from device1 with no register address
i2c_bus_write_bytes(i2c_device2, 0x10, 2, data_wr); // write bytes to device2 register 0x10

i2c_bus_device_delete(&i2c_device1); //delete device1
i2c_bus_device_delete(&i2c_device2); //delete device2
i2c_bus_delete(&i2c0_bus);  //delete i2c_bus

Note

For some special application scenarios:

  1. When the address of a register is 16-bit, you can use i2c_bus_read_reg16() or i2c_bus_write_reg16() to read or write its data;

  2. For devices that need to skip the address phase or need to add a command phase, you can operate using i2c_bus_cmd_begin() combined with I2C command link.

Adapted IDF Versions

  • ESP-IDF v4.0 and later versions.

API Reference

Header File

Functions

i2c_bus_handle_t i2c_bus_create(i2c_port_t port, const i2c_config_t *conf)

Create an I2C bus instance then return a handle if created successfully. Each I2C bus works in a singleton mode, which means for an i2c port only one group parameter works. When i2c_bus_create is called more than one time for the same i2c port, following parameter will override the previous one.

Parameters
  • port – I2C port number

  • conf – Pointer to I2C bus configuration

Returns

i2c_bus_handle_t Return the I2C bus handle if created successfully, return NULL if failed.

esp_err_t i2c_bus_delete(i2c_bus_handle_t *p_bus_handle)

Delete and release the I2C bus resource.

Parameters

p_bus_handle – Point to the I2C bus handle, if delete succeed handle will set to NULL.

Returns

  • ESP_OK Success

  • ESP_FAIL Fail

uint8_t i2c_bus_scan(i2c_bus_handle_t bus_handle, uint8_t *buf, uint8_t num)

Scan i2c devices attached on i2c bus.

Parameters
  • bus_handle – I2C bus handle

  • buf – Pointer to a buffer to save devices’ address, if NULL no address will be saved.

  • num – Maximum number of addresses to save, invalid if buf set to NULL, higher addresses will be discarded if num less-than the total number found on the I2C bus.

Returns

uint8_t Total number of devices found on the I2C bus

uint32_t i2c_bus_get_current_clk_speed(i2c_bus_handle_t bus_handle)

Get current active clock speed.

Parameters

bus_handle – I2C bus handle

Returns

uint32_t current clock speed

uint8_t i2c_bus_get_created_device_num(i2c_bus_handle_t bus_handle)

Get created device number of the bus.

Parameters

bus_handle – I2C bus handle

Returns

uint8_t created device number of the bus

i2c_bus_device_handle_t i2c_bus_device_create(i2c_bus_handle_t bus_handle, uint8_t dev_addr, uint32_t clk_speed)

Create an I2C device on specific bus. Dynamic configuration must be enable to achieve multiple devices with different configs on a single bus. menuconfig:Bus Options->I2C Bus Options->enable dynamic configuration.

Parameters
  • bus_handle – Point to the I2C bus handle

  • dev_addr – i2c device address

  • clk_speed – device specified clock frequency the i2c_bus will switch to during each transfer. 0 if use current bus speed.

Returns

i2c_bus_device_handle_t return a device handle if created successfully, return NULL if failed.

esp_err_t i2c_bus_device_delete(i2c_bus_device_handle_t *p_dev_handle)

Delete and release the I2C device resource, i2c_bus_device_delete should be used in pairs with i2c_bus_device_create.

Parameters

p_dev_handle – Point to the I2C device handle, if delete succeed handle will set to NULL.

Returns

  • ESP_OK Success

  • ESP_FAIL Fail

uint8_t i2c_bus_device_get_address(i2c_bus_device_handle_t dev_handle)

Get device’s I2C address.

Parameters

dev_handle – I2C device handle

Returns

uint8_t I2C address, return NULL_I2C_DEV_ADDR if dev_handle is invalid.

esp_err_t i2c_bus_read_byte(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t *data)

Read single byte from i2c device with 8-bit internal register/memory address.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal reg/mem address to read from, set to NULL_I2C_MEM_ADDR if no internal address.

  • data – Pointer to a buffer to save the data that was read

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_read_bytes(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, size_t data_len, uint8_t *data)

Read multiple bytes from i2c device with 8-bit internal register/memory address. If internal reg/mem address is 16-bit, please refer i2c_bus_read_reg16.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal reg/mem address to read from, set to NULL_I2C_MEM_ADDR if no internal address.

  • data_len – Number of bytes to read

  • data – Pointer to a buffer to save the data that was read

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_read_bit(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t bit_num, uint8_t *data)

Read single bit of a byte from i2c device with 8-bit internal register/memory address.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal reg/mem address to read from, set to NULL_I2C_MEM_ADDR if no internal address.

  • bit_num – The bit number 0 - 7 to read

  • data – Pointer to a buffer to save the data that was read. *data == 0 -> bit = 0, *data !=0 -> bit = 1.

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_read_bits(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t bit_start, uint8_t length, uint8_t *data)

Read multiple bits of a byte from i2c device with 8-bit internal register/memory address.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal reg/mem address to read from, set to NULL_I2C_MEM_ADDR if no internal address.

  • bit_start – The bit to start from, 0 - 7, MSB at 0

  • length – The number of bits to read, 1 - 8

  • data – Pointer to a buffer to save the data that was read

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_write_byte(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t data)

Write single byte to i2c device with 8-bit internal register/memory address.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal reg/mem address to write to, set to NULL_I2C_MEM_ADDR if no internal address.

  • data – The byte to write.

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_write_bytes(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, size_t data_len, const uint8_t *data)

Write multiple byte to i2c device with 8-bit internal register/memory address If internal reg/mem address is 16-bit, please refer i2c_bus_write_reg16.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal reg/mem address to write to, set to NULL_I2C_MEM_ADDR if no internal address.

  • data_len – Number of bytes to write

  • data – Pointer to the bytes to write.

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_write_bit(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t bit_num, uint8_t data)

Write single bit of a byte to an i2c device with 8-bit internal register/memory address.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal reg/mem address to write to, set to NULL_I2C_MEM_ADDR if no internal address.

  • bit_num – The bit number 0 - 7 to write

  • data – The bit to write, data == 0 means set bit = 0, data !=0 means set bit = 1.

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_write_bits(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t bit_start, uint8_t length, uint8_t data)

Write multiple bits of a byte to an i2c device with 8-bit internal register/memory address.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal reg/mem address to write to, set to NULL_I2C_MEM_ADDR if no internal address.

  • bit_start – The bit to start from, 0 - 7, MSB at 0

  • length – The number of bits to write, 1 - 8

  • data – The bits to write.

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_cmd_begin(i2c_bus_device_handle_t dev_handle, i2c_cmd_handle_t cmd)

I2C master send queued commands create by i2c_cmd_link_create . This function will trigger sending all queued commands. The task will be blocked until all the commands have been sent out. If I2C_BUS_DYNAMIC_CONFIG enable, i2c_bus will dynamically check configs and re-install i2c driver before each transfer, hence multiple devices with different configs on a single bus can be supported.

Note

Only call this function when i2c_bus_read/write_xx do not meet the requirements

Parameters
  • dev_handle – I2C device handle

  • cmd – I2C command handler

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_write_reg16(i2c_bus_device_handle_t dev_handle, uint16_t mem_address, size_t data_len, const uint8_t *data)

Write date to an i2c device with 16-bit internal reg/mem address.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal 16-bit reg/mem address to write to, set to NULL_I2C_MEM_ADDR if no internal address.

  • data_len – Number of bytes to write

  • data – Pointer to the bytes to write.

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

esp_err_t i2c_bus_read_reg16(i2c_bus_device_handle_t dev_handle, uint16_t mem_address, size_t data_len, uint8_t *data)

Read date from i2c device with 16-bit internal reg/mem address.

Parameters
  • dev_handle – I2C device handle

  • mem_address – The internal 16-bit reg/mem address to read from, set to NULL_I2C_MEM_ADDR if no internal address.

  • data_len – Number of bytes to read

  • data – Pointer to a buffer to save the data that was read

Returns

esp_err_t

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Sending command error, slave doesn’t ACK the transfer.

  • ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.

  • ESP_ERR_TIMEOUT Operation timeout because the bus is busy.

Structures

struct i2c_config_t

I2C initialization parameters.

Public Members

i2c_mode_t mode

I2C mode

int sda_io_num

GPIO number for I2C sda signal

int scl_io_num

GPIO number for I2C scl signal

bool sda_pullup_en

Internal GPIO pull mode for I2C sda signal

bool scl_pullup_en

Internal GPIO pull mode for I2C scl signal

uint32_t clk_speed

I2C clock frequency for master mode, (no higher than 1MHz for now)

struct i2c_config_t::[anonymous] master

I2C master config

uint32_t clk_flags

Bitwise of I2C_SCLK_SRC_FLAG_**FOR_DFS** for clk source choice

Macros

NULL_I2C_MEM_ADDR

set mem_address to NULL_I2C_MEM_ADDR if i2c device has no internal address during read/write

NULL_I2C_MEM_16BIT_ADDR

set 16bit mem_address to NULL_I2C_MEM_16BIT_ADDR if i2c device has no internal address during read/write

NULL_I2C_DEV_ADDR

invalid i2c device address

gpio_pad_select_gpio
portTICK_RATE_MS

Type Definitions

typedef void *i2c_bus_handle_t

i2c bus handle

typedef void *i2c_bus_device_handle_t

i2c device handle

typedef void *i2c_cmd_handle_t

I2C command handle