esp-idf-ssd1306/DeviceAddDemo/README.md

264 lines
8.0 KiB
Markdown
Raw Normal View History

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