2024-09-08 22:17:01 -04:00
|
|
|
# DeviceAddDemo for SSD1306
|
|
|
|
|
|
|
|
I received a question about using an SSD1306 and other i2c/spi devices at the same time.
|
|
|
|
A new i2c driver is now available in ESP-IDF V5.2.
|
2024-09-08 22:24:24 -04:00
|
|
|
This complicated the use of other i2c devices at the same time as the i2c's SSD1306.
|
2024-09-08 22:17:01 -04:00
|
|
|
|
2024-09-09 04:28:19 -04:00
|
|
|
I will record the results of my investigation and publish sample code.
|
2024-09-08 22:17:01 -04:00
|
|
|
If you want to use SSD1306 and other i2c/spi devices at the same time, please follow the guide below.
|
|
|
|
|
|
|
|
# Using i2c interface
|
|
|
|
|
2024-09-08 22:21:26 -04:00
|
|
|
### Use multiple i2c devices on one i2c bus.
|
2024-09-08 22:17:01 -04:00
|
|
|
SCL and SDA are shared by all devices.
|
|
|
|
```
|
|
|
|
I2C_NUM_0 --+-- I2C SSD1306
|
|
|
|
+---Any I2C Device
|
|
|
|
```
|
|
|
|
|
|
|
|
In the XTENSA series, you can use I2C_NUM_1 bus instead of I2C_NUM_0 bus.
|
|
|
|
```
|
|
|
|
I2C_NUM_1 --+-- I2C SSD1306
|
|
|
|
+---Any I2C Device
|
|
|
|
```
|
|
|
|
|
2024-09-09 08:07:23 -04:00
|
|
|
SSD1306 and other device use the same frequency.
|
|
|
|
__Please note that the maximum i2c clock frequency of SSD1306 is 400KHz.__
|
|
|
|
```
|
|
|
|
I2C_NUM_1 --+-- I2C SSD1306 using 400KHz
|
|
|
|
+---Any I2C Device using 400KHz
|
|
|
|
```
|
|
|
|
|
|
|
|
|
2024-09-08 22:17:01 -04:00
|
|
|
- Legacy driver
|
|
|
|
|
|
|
|
We only need to run this code once.
|
|
|
|
Under ESP-IDF V5.2 or later, this project uses the new I2C driver, but there is an option to force the use of the legacy I2C driver.
|
|
|
|
|
|
|
|
```
|
|
|
|
i2c_config_t i2c_config = {
|
|
|
|
.mode = I2C_MODE_MASTER,
|
|
|
|
.sda_io_num = CONFIG_SDA_GPIO,
|
|
|
|
.scl_io_num = CONFIG_SCL_GPIO,
|
|
|
|
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
|
|
|
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
|
|
|
.master.clk_speed = I2C_MASTER_FREQ_HZ
|
|
|
|
};
|
|
|
|
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &i2c_config));
|
|
|
|
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0));
|
|
|
|
```
|
|
|
|
|
|
|
|
This project uses the following functions to install the i2c driver.
|
|
|
|
```
|
|
|
|
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
|
|
|
This project allows you to use an initialization function that does not install the i2c driver.
|
|
|
|
```
|
|
|
|
i2c_device_add(&dev, i2c_num, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
|
|
|
The i2c driver must be installed before using this initialization function.
|
|
|
|
```
|
|
|
|
// install i2c master driver
|
|
|
|
i2c_config_t i2c_config = {
|
|
|
|
.mode = I2C_MODE_MASTER,
|
|
|
|
.sda_io_num = CONFIG_SDA_GPIO,
|
|
|
|
.scl_io_num = CONFIG_SCL_GPIO,
|
|
|
|
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
|
|
|
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
|
|
|
.master.clk_speed = 400000
|
|
|
|
};
|
|
|
|
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &i2c_config));
|
|
|
|
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0));
|
|
|
|
|
|
|
|
// add new device to i2c bus
|
|
|
|
i2c_device_add(&dev, I2C_NUM_0, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
|
|
|
- New i2c driver
|
|
|
|
|
|
|
|
We need to run this code on the first i2c device.
|
|
|
|
```
|
|
|
|
i2c_master_bus_config_t i2c_mst_config = {
|
|
|
|
.clk_source = I2C_CLK_SRC_DEFAULT,
|
|
|
|
.glitch_ignore_cnt = 7,
|
|
|
|
.i2c_port = I2C_NUM_0,
|
|
|
|
.scl_io_num = scl,
|
|
|
|
.sda_io_num = sda,
|
|
|
|
.flags.enable_internal_pullup = true,
|
|
|
|
};
|
|
|
|
i2c_master_bus_handle_t bus_handle;
|
|
|
|
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
|
|
|
|
|
|
|
i2c_device_config_t dev_cfg = {
|
|
|
|
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
|
|
|
.device_address = I2C_ADDRESS1,
|
|
|
|
.scl_speed_hz = I2C_MASTER_FREQ_HZ1,
|
|
|
|
};
|
|
|
|
i2c_master_dev_handle_t dev_handle;
|
|
|
|
ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
|
|
|
```
|
|
|
|
|
|
|
|
We need to run this code on the second device.
|
|
|
|
SSD1306 and other device can use different frequencies.
|
|
|
|
|
|
|
|
```
|
|
|
|
i2c_device_config_t dev_cfg = {
|
|
|
|
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
|
|
|
.device_address = I2C_ADDRESS2,
|
|
|
|
.scl_speed_hz = I2C_MASTER_FREQ_HZ2,
|
|
|
|
};
|
|
|
|
i2c_master_dev_handle_t dev_handle;
|
|
|
|
ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
|
|
|
```
|
|
|
|
|
|
|
|
This project uses the following functions to install the i2c driver.
|
|
|
|
```
|
|
|
|
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
|
|
|
This project allows you to use an initialization function that does not install the i2c driver.
|
|
|
|
```
|
|
|
|
i2c_bus_add(&dev, bus_handle, i2c_num, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
|
|
|
The i2c driver must be installed before using this initialization function.
|
|
|
|
```
|
|
|
|
// install i2c master driver
|
|
|
|
i2c_master_bus_config_t i2c_mst_config = {
|
|
|
|
.clk_source = I2C_CLK_SRC_DEFAULT,
|
|
|
|
.glitch_ignore_cnt = 7,
|
|
|
|
.i2c_port = I2C_NUM_0,
|
|
|
|
.scl_io_num = CONFIG_SCL_GPIO,
|
|
|
|
.sda_io_num = CONFIG_SDA_GPIO,
|
|
|
|
.flags.enable_internal_pullup = true,
|
|
|
|
};
|
|
|
|
i2c_master_bus_handle_t bus_handle;
|
|
|
|
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
|
|
|
|
|
|
|
// add new device to i2c bus
|
|
|
|
i2c_bus_add(&dev, bus_handle, I2C_NUM_0, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
2024-09-08 22:21:26 -04:00
|
|
|
### Use multiple i2c devices on two i2c bus.
|
2024-09-08 22:17:01 -04:00
|
|
|
SCL and SDA each use separate GPIOs.
|
|
|
|
Install the i2c master driver for each of I2C_NUM_0 and I2C_NUM_1.
|
|
|
|
The frequencies of I2C_NUM_0 and I2C_NUM_1 can be set completely independently.
|
|
|
|
```
|
|
|
|
I2C_NUM_0 ----- I2C SSD1306
|
|
|
|
I2C_NUM_1 ----- Any I2C Device
|
|
|
|
```
|
|
|
|
|
|
|
|
This is possible with both the new i2c driver or the legacy i2c driver, but **both buses must use the same driver.**
|
|
|
|
This is not acceptable.
|
|
|
|
```
|
|
|
|
I2C_NUM_0 ----- I2C SSD1306 using new i2c driver
|
|
|
|
I2C_NUM_1 ----- Any I2C Device using legacy i2c driver
|
|
|
|
```
|
|
|
|
|
|
|
|
If other i2c devices use legacy i2c drivers, SSD1306 must also use legacy i2c drivers.
|
|
|
|
Under ESP-IDF V5.2 or later, this project uses the new I2C driver, but there is an option to force the use of the legacy I2C driver.
|
|
|
|
```
|
|
|
|
I2C_NUM_0 ----- I2C SSD1306 using legacy i2c driver
|
|
|
|
I2C_NUM_1 ----- Any I2C Device using legacy i2c driver
|
|
|
|
```
|
|
|
|
|
|
|
|
If SSD1306 use new i2c drivers, other i2c devices must also use new i2c drivers.
|
|
|
|
```
|
|
|
|
I2C_NUM_0 ----- I2C SSD1306 using new i2c driver
|
|
|
|
I2C_NUM_1 ----- Any I2C Device using new i2c driver
|
|
|
|
```
|
|
|
|
|
|
|
|
ESP32C series has only one i2c bus.
|
|
|
|
This is not available on the ESP32C series.
|
|
|
|
Can only be used with XTENSA series.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
# Using spi interface
|
|
|
|
|
2024-09-08 22:21:26 -04:00
|
|
|
### Use multiple spi devices on one spi bus.
|
2024-09-08 22:17:01 -04:00
|
|
|
MOSI and SCLK are shared by all devices.
|
|
|
|
```
|
|
|
|
SPI2_HOST --+-- SPI SSD1306
|
|
|
|
+---Any SPI Device
|
|
|
|
```
|
|
|
|
|
|
|
|
In the XTENSA series, you can use SPI2_HOST bus instead of SPI3_HOST bus.
|
|
|
|
```
|
|
|
|
SPI3_HOST --+-- SPI SSD1306
|
|
|
|
+---Any SPI Device
|
|
|
|
```
|
|
|
|
|
2024-09-09 08:07:23 -04:00
|
|
|
SSD1306 and other devices use different frequencies.
|
|
|
|
```
|
|
|
|
SPI2_HOST --+-- SPI SSD1306 using 1MHz
|
|
|
|
+---Any I2C Device using 2MHz
|
|
|
|
```
|
|
|
|
|
2024-09-08 22:17:01 -04:00
|
|
|
We only need to run this code once.
|
|
|
|
|
|
|
|
```
|
|
|
|
spi_bus_config_t spi_bus_config = {
|
|
|
|
.mosi_io_num = CONFIG_MOSI_GPIO,
|
|
|
|
.miso_io_num = -1,
|
|
|
|
.sclk_io_num = CONFIG_SCLK_GPIO,
|
|
|
|
.quadwp_io_num = -1,
|
|
|
|
.quadhd_io_num = -1,
|
|
|
|
.max_transfer_sz = 0,
|
|
|
|
.flags = 0
|
|
|
|
};
|
|
|
|
|
|
|
|
ESP_LOGI(tag, "SPI HOST_ID=%d", host_id);
|
|
|
|
esp_err_t ret = spi_bus_initialize( host_id, &spi_bus_config, SPI_DMA_CH_AUTO );
|
|
|
|
ESP_LOGI(tag, "spi_bus_initialize=%d",ret);
|
|
|
|
```
|
|
|
|
|
|
|
|
This project uses the following functions to install the spi driver.
|
|
|
|
```
|
|
|
|
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
|
|
|
This project allows you to use an initialization function that does not install the spi driver.
|
|
|
|
```
|
|
|
|
spi_device_add(&dev, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
|
|
|
The spi driver must be installed before using this initialization function.
|
|
|
|
```
|
|
|
|
// install spi master driver
|
|
|
|
spi_bus_config_t spi_bus_config = {
|
|
|
|
.mosi_io_num = CONFIG_MOSI_GPIO,
|
|
|
|
.miso_io_num = -1,
|
|
|
|
.sclk_io_num = CONFIG_SCLK_GPIO,
|
|
|
|
.quadwp_io_num = -1,
|
|
|
|
.quadhd_io_num = -1,
|
|
|
|
.max_transfer_sz = 0,
|
|
|
|
.flags = 0
|
|
|
|
};
|
|
|
|
|
|
|
|
esp_err_t ret = spi_bus_initialize( SPI2_HOST, &spi_bus_config, SPI_DMA_CH_AUTO );
|
|
|
|
ESP_LOGI(tag, "spi_bus_initialize=%d",ret);
|
|
|
|
assert(ret==ESP_OK);
|
|
|
|
|
|
|
|
// add new device to spi bus
|
|
|
|
spi_device_add(&dev, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
|
|
|
|
```
|
|
|
|
|
2024-09-08 22:21:26 -04:00
|
|
|
### Use multiple spi devices on two spi bus.
|
2024-09-08 22:17:01 -04:00
|
|
|
MOSI and SCLK each use separate GPIOs.
|
|
|
|
Install the spi master driver for each of SPI2_HOST and SPI3_HOST.
|
|
|
|
```
|
|
|
|
SPI2_HOST ----- SPI SSD1306
|
|
|
|
SPI3_HOST ----- Any SPI Device
|
|
|
|
```
|
2024-09-08 22:36:25 -04:00
|
|
|
|
2024-09-08 22:37:23 -04:00
|
|
|
ESP32C series has only one spi bus.
|
|
|
|
This is not available on the ESP32C series.
|
|
|
|
Can only be used with XTENSA series.
|
2024-09-08 22:36:25 -04:00
|
|
|
|