Skip to main content

I2C Peripheral Guide

The TKL I2C interface drives the I2C bus in master mode for sensors, OLED displays, IO expanders, and other peripherals. You assign the SCL/SDA pins, initialize the bus at a chosen speed, then send and receive bytes against each device address.

Prerequisitesโ€‹

  • Completed Environment Setup
  • Board with I2C-capable pins and ENABLE_I2C=y in Kconfig

I2C in TuyaOpenโ€‹

TuyaOpen provides I2C master mode through the TKL layer. The API is the same across all platforms (T5AI, ESP32, Linux, etc.).

Initializationโ€‹

1. Assign pins via pinmuxโ€‹

I2C pins default to GPIO 0/1 (I2C0) and GPIO 2/3 (I2C1). Override for your board:

#include "tkl_pinmux.h"
#include "tkl_i2c.h"

tkl_io_pinmux_config(TUYA_GPIO_NUM_9, TUYA_IIC0_SCL);
tkl_io_pinmux_config(TUYA_GPIO_NUM_10, TUYA_IIC0_SDA);

2. Initialize the busโ€‹

TUYA_IIC_BASE_CFG_T i2c_cfg = {
.role = TUYA_IIC_MODE_MASTER,
.speed = TUYA_IIC_BUS_SPEED_400K,
.addr_width = TUYA_IIC_ADDRESS_7BIT,
};
OPERATE_RET rt = tkl_i2c_init(TUYA_I2C_NUM_0, &i2c_cfg);

Speed options: TUYA_IIC_BUS_SPEED_100K, TUYA_IIC_BUS_SPEED_400K, TUYA_IIC_BUS_SPEED_1M (if hardware supports it).

Read and Writeโ€‹

Write a registerโ€‹

UINT8_T buf[2] = { reg_addr, value };
tkl_i2c_master_send(TUYA_I2C_NUM_0, device_addr, buf, 2, TRUE);

The last parameter (TRUE) generates a STOP condition after the transfer.

Read a registerโ€‹

UINT8_T reg = 0x00;
UINT8_T data[2];
tkl_i2c_master_send(TUYA_I2C_NUM_0, device_addr, &reg, 1, FALSE);
tkl_i2c_master_receive(TUYA_I2C_NUM_0, device_addr, data, 2, TRUE);

Use FALSE for the STOP on the write to generate a repeated START for the subsequent read.

I2C Bus Scanโ€‹

Scan for connected devices by attempting to read from each address:

for (UINT8_T addr = 0x08; addr < 0x78; addr++) {
UINT8_T dummy;
OPERATE_RET rt = tkl_i2c_master_receive(TUYA_I2C_NUM_0, addr, &dummy, 1, TRUE);
if (rt == OPRT_OK) {
TAL_PR_INFO("found device at 0x%02X", addr);
}
}

See the I2C scan example in the SDK.

Multiple Devices on One Busโ€‹

I2C is a multi-device bus. Multiple sensors with different addresses share the same SCL/SDA:

#define OLED_ADDR 0x3C
#define SENSOR_ADDR 0x44
#define EXPANDER_ADDR 0x20

tkl_i2c_master_send(TUYA_I2C_NUM_0, OLED_ADDR, oled_cmd, sizeof(oled_cmd), TRUE);
tkl_i2c_master_send(TUYA_I2C_NUM_0, SENSOR_ADDR, sensor_cmd, 2, TRUE);
tkl_i2c_master_send(TUYA_I2C_NUM_0, EXPANDER_ADDR, exp_cmd, 2, TRUE);

:::warning Address Conflicts If two devices share the same I2C address, you need separate buses (I2C0 and I2C1) or an I2C multiplexer. :::

Limitationsโ€‹

FeatureStatus
Master modeSupported
Slave modeNot supported (OPRT_NOT_SUPPORTED)
10-bit addressingSupported (set addr_width = TUYA_IIC_ADDRESS_10BIT)
Bus reset / ioctlNot supported
DMA transfersPlatform-dependent (transparent to TKL API)

Common I2C Devices in TuyaOpen Projectsโ€‹

DeviceAddressTypeUsed By
SHT3x (temp/humidity)0x44 / 0x45SensorI2C sensor example
SSD1306 (OLED)0x3CDisplayESP32 Bread Compact, XingZhi Cube
ES8311 (audio codec)0x18AudioDNESP32S3-BOX, Waveshare AMOLED
ES8388 (audio codec)0x20AudioESP32 Bread Board, DNESP32S3
FT5x06 (touch)0x38TouchWaveshare AMOLED
XL9555 (IO expander)0x20GPIO expanderDNESP32S3, DNESP32S3-BOX
TCA9554 (IO expander)0x20GPIO expanderWaveshare AMOLED
BMI270 (IMU)0x68 / 0x69Motion sensorIMU example

Referencesโ€‹