From 2e6910b549a17a55f1df2ded481640e457ff8ed5 Mon Sep 17 00:00:00 2001 From: nopnop2002 Date: Mon, 9 Sep 2024 11:01:19 +0900 Subject: [PATCH] added i2c_device_add/i2c_bus_add/spi_device_add function --- components/ssd1306/ssd1306.h | 17 ++--- components/ssd1306/ssd1306_i2c_legacy.c | 75 +++++++++++++------- components/ssd1306/ssd1306_i2c_new.c | 17 +++-- components/ssd1306/ssd1306_spi.c | 91 ++++++++++++++++++++----- 4 files changed, 146 insertions(+), 54 deletions(-) diff --git a/components/ssd1306/ssd1306.h b/components/ssd1306/ssd1306.h index d8ebc1d..e91e65c 100644 --- a/components/ssd1306/ssd1306.h +++ b/components/ssd1306/ssd1306.h @@ -4,6 +4,8 @@ #include "driver/spi_master.h" #if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)) #include "driver/i2c_master.h" +#else +#include "driver/i2c.h" #endif // Following definitions are bollowed from @@ -74,8 +76,6 @@ Usage: #define I2C_ADDRESS 0x3C #define SPI_ADDRESS 0xFF -#define I2C_DRIVER_NOT_INSTALL -1 - typedef enum { SCROLL_RIGHT = 1, SCROLL_LEFT = 2, @@ -96,13 +96,14 @@ typedef struct { int _height; int _pages; int _dc; - spi_device_handle_t _SPIHandle; bool _scEnable; int _scStart; int _scEnd; int _scDirection; PAGE_t _page[8]; bool _flip; + i2c_port_t _i2c_num; + spi_device_handle_t _SPIHandle; } SSD1306_t; #ifdef __cplusplus @@ -141,17 +142,17 @@ void ssd1306_fadeout(SSD1306_t * dev); void ssd1306_dump(SSD1306_t dev); void ssd1306_dump_page(SSD1306_t * dev, int page, int seg); -#if CONFIG_SPI_INTERFACE -void spi_clock_speed(int speed); -#endif void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset); -void i2c_device_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, int16_t reset); +void i2c_device_add(SSD1306_t * dev, i2c_port_t i2c_num, int16_t reset); +void i2c_bus_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, i2c_port_t i2c_num, int16_t reset); void i2c_init(SSD1306_t * dev, int width, int height); void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width); void i2c_contrast(SSD1306_t * dev, int contrast); void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll); -void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET); +void spi_clock_speed(int speed); +void spi_master_init(SSD1306_t * dev, int16_t mosi, int16_t sclk, int16_t cs, int16_t dc, int16_t reset); +void spi_device_add(SSD1306_t * dev, int16_t cs, int16_t dc, int16_t reset); bool spi_master_write_byte(spi_device_handle_t SPIHandle, const uint8_t* Data, size_t DataLength ); bool spi_master_write_command(SSD1306_t * dev, uint8_t Command ); bool spi_master_write_data(SSD1306_t * dev, const uint8_t* Data, size_t DataLength ); diff --git a/components/ssd1306/ssd1306_i2c_legacy.c b/components/ssd1306/ssd1306_i2c_legacy.c index c1844d1..1980aab 100644 --- a/components/ssd1306/ssd1306_i2c_legacy.c +++ b/components/ssd1306/ssd1306_i2c_legacy.c @@ -19,25 +19,21 @@ #endif #define I2C_MASTER_FREQ_HZ 400000 // I2C clock of SSD1306 can run at 400 kHz max. -#define I2C_TICKS_TO_WAIT 100 // Maximum ticks to wait before issuing a timeout. +#define I2C_TICKS_TO_WAIT 100 // Maximum ticks to wait before issuing a timeout. void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset) { ESP_LOGI(TAG, "Legacy i2c driver is used"); - if (sda != I2C_DRIVER_NOT_INSTALL && scl != I2C_DRIVER_NOT_INSTALL) { - i2c_config_t i2c_config = { - .mode = I2C_MODE_MASTER, - .sda_io_num = sda, - .scl_io_num = scl, - .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, &i2c_config)); - ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0)); - } else { - ESP_LOGW(TAG, "Will not install i2c master driver"); - } + i2c_config_t i2c_config = { + .mode = I2C_MODE_MASTER, + .sda_io_num = sda, + .scl_io_num = scl, + .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, &i2c_config)); + ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0)); if (reset >= 0) { //gpio_pad_select_gpio(reset); @@ -47,8 +43,41 @@ void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset) vTaskDelay(50 / portTICK_PERIOD_MS); gpio_set_level(reset, 1); } + dev->_address = I2C_ADDRESS; dev->_flip = false; + dev->_i2c_num = I2C_NUM; +} + +void i2c_device_add(SSD1306_t * dev, i2c_port_t i2c_num, int16_t reset) +{ + ESP_LOGI(TAG, "Legacy i2c driver is used"); + ESP_LOGW(TAG, "Will not install i2c master driver"); +#if 0 + i2c_config_t i2c_config = { + .mode = I2C_MODE_MASTER, + .sda_io_num = sda, + .scl_io_num = scl, + .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, &i2c_config)); + ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0)); +#endif + + if (reset >= 0) { + //gpio_pad_select_gpio(reset); + gpio_reset_pin(reset); + gpio_set_direction(reset, GPIO_MODE_OUTPUT); + gpio_set_level(reset, 0); + vTaskDelay(50 / portTICK_PERIOD_MS); + gpio_set_level(reset, 1); + } + + dev->_address = I2C_ADDRESS; + dev->_flip = false; + dev->_i2c_num = i2c_num; } void i2c_init(SSD1306_t * dev, int width, int height) { @@ -62,11 +91,11 @@ void i2c_init(SSD1306_t * dev, int width, int height) { i2c_master_start(cmd); i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); - i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); // AE - i2c_master_write_byte(cmd, OLED_CMD_SET_MUX_RATIO, true); // A8 + i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); // AE + i2c_master_write_byte(cmd, OLED_CMD_SET_MUX_RATIO, true); // A8 if (dev->_height == 64) i2c_master_write_byte(cmd, 0x3F, true); if (dev->_height == 32) i2c_master_write_byte(cmd, 0x1F, true); - i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); // D3 + i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); // D3 i2c_master_write_byte(cmd, 0x00, true); //i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); // 40 i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_START_LINE, true); // 40 @@ -102,7 +131,7 @@ void i2c_init(SSD1306_t * dev, int width, int height) { i2c_master_stop(cmd); - esp_err_t res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT); + esp_err_t res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT); if (res == ESP_OK) { ESP_LOGI(TAG, "OLED configured successfully"); } else { @@ -138,7 +167,7 @@ void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int i2c_master_write_byte(cmd, 0xB0 | _page, true); i2c_master_stop(cmd); - esp_err_t res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT); + esp_err_t res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT); if (res != ESP_OK) { ESP_LOGE(TAG, "Image command failed. code: 0x%.2X", res); } @@ -151,7 +180,7 @@ void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int i2c_master_write(cmd, images, width, true); i2c_master_stop(cmd); - res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT); + res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT); if (res != ESP_OK) { ESP_LOGE(TAG, "Image command failed. code: 0x%.2X", res); } @@ -171,7 +200,7 @@ void i2c_contrast(SSD1306_t * dev, int contrast) { i2c_master_write_byte(cmd, _contrast, true); i2c_master_stop(cmd); - esp_err_t res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT); + esp_err_t res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT); if (res != ESP_OK) { ESP_LOGE(TAG, "Contrast command failed. code: 0x%.2X", res); } @@ -252,7 +281,7 @@ void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll) { i2c_master_stop(cmd); - esp_err_t res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT); + esp_err_t res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT); if (res != ESP_OK) { ESP_LOGE(TAG, "Scroll command failed. code: 0x%.2X", res); } diff --git a/components/ssd1306/ssd1306_i2c_new.c b/components/ssd1306/ssd1306_i2c_new.c index 0304f9a..842ee4f 100644 --- a/components/ssd1306/ssd1306_i2c_new.c +++ b/components/ssd1306/ssd1306_i2c_new.c @@ -53,13 +53,16 @@ void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset) vTaskDelay(50 / portTICK_PERIOD_MS); gpio_set_level(reset, 1); } + dev->_address = I2C_ADDRESS; dev->_flip = false; + dev->_i2c_num = I2C_NUM; } -void i2c_device_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, int16_t reset) +void i2c_bus_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, i2c_port_t i2c_num, int16_t reset) { ESP_LOGI(TAG, "New i2c driver is used"); + ESP_LOGW(TAG, "Will not install i2c master driver"); #if 0 i2c_master_bus_config_t i2c_mst_config = { .clk_source = I2C_CLK_SRC_DEFAULT, @@ -89,8 +92,10 @@ void i2c_device_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, int16_t vTaskDelay(50 / portTICK_PERIOD_MS); gpio_set_level(reset, 1); } + dev->_address = I2C_ADDRESS; dev->_flip = false; + dev->_i2c_num = i2c_num; } void i2c_init(SSD1306_t * dev, int width, int height) { @@ -145,7 +150,7 @@ void i2c_init(SSD1306_t * dev, int width, int height) { if (res == ESP_OK) { ESP_LOGI(TAG, "OLED configured successfully"); } else { - ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res)); + ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res)); } } @@ -181,14 +186,14 @@ void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int esp_err_t res; res = i2c_master_transmit(dev_handle, out_buf, out_index, I2C_TICKS_TO_WAIT); if (res != ESP_OK) - ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res)); + ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res)); out_buf[0] = OLED_CONTROL_BYTE_DATA_STREAM; memcpy(&out_buf[1], images, width); res = i2c_master_transmit(dev_handle, out_buf, width + 1, I2C_TICKS_TO_WAIT); if (res != ESP_OK) - ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res)); + ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res)); free(out_buf); } @@ -205,7 +210,7 @@ void i2c_contrast(SSD1306_t * dev, int contrast) { esp_err_t res = i2c_master_transmit(dev_handle, out_buf, 3, I2C_TICKS_TO_WAIT); if (res != ESP_OK) - ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res)); + ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res)); } @@ -280,6 +285,6 @@ void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll) { esp_err_t res = i2c_master_transmit(dev_handle, out_buf, 3, I2C_TICKS_TO_WAIT); if (res != ESP_OK) - ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res)); + ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res)); } diff --git a/components/ssd1306/ssd1306_spi.c b/components/ssd1306/ssd1306_spi.c index 8207e0e..e5dab64 100644 --- a/components/ssd1306/ssd1306_spi.c +++ b/components/ssd1306/ssd1306_spi.c @@ -29,30 +29,30 @@ void spi_clock_speed(int speed) { clock_speed_hz = speed; } -void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET) +void spi_master_init(SSD1306_t * dev, int16_t mosi, int16_t sclk, int16_t cs, int16_t dc, int16_t reset) { esp_err_t ret; - gpio_reset_pin( GPIO_CS ); - gpio_set_direction( GPIO_CS, GPIO_MODE_OUTPUT ); - gpio_set_level( GPIO_CS, 0 ); + gpio_reset_pin( cs ); + gpio_set_direction( cs, GPIO_MODE_OUTPUT ); + gpio_set_level( cs, 0 ); - gpio_reset_pin( GPIO_DC ); - gpio_set_direction( GPIO_DC, GPIO_MODE_OUTPUT ); - gpio_set_level( GPIO_DC, 0 ); + gpio_reset_pin( dc ); + gpio_set_direction( dc, GPIO_MODE_OUTPUT ); + gpio_set_level( dc, 0 ); - if ( GPIO_RESET >= 0 ) { - gpio_reset_pin( GPIO_RESET ); - gpio_set_direction( GPIO_RESET, GPIO_MODE_OUTPUT ); - gpio_set_level( GPIO_RESET, 0 ); + if ( reset >= 0 ) { + gpio_reset_pin( reset ); + gpio_set_direction( reset, GPIO_MODE_OUTPUT ); + gpio_set_level( reset, 0 ); vTaskDelay( pdMS_TO_TICKS( 100 ) ); - gpio_set_level( GPIO_RESET, 1 ); + gpio_set_level( reset, 1 ); } spi_bus_config_t spi_bus_config = { - .mosi_io_num = GPIO_MOSI, + .mosi_io_num = mosi, .miso_io_num = -1, - .sclk_io_num = GPIO_SCLK, + .sclk_io_num = sclk, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = 0, @@ -68,17 +68,74 @@ void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int1 memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) ); //devcfg.clock_speed_hz = SPI_DEFAULT_FREQUENCY; devcfg.clock_speed_hz = clock_speed_hz; - devcfg.spics_io_num = GPIO_CS; + devcfg.spics_io_num = cs; devcfg.queue_size = 1; spi_device_handle_t handle; ret = spi_bus_add_device( HOST_ID, &devcfg, &handle); ESP_LOGI(TAG, "spi_bus_add_device=%d",ret); assert(ret==ESP_OK); - dev->_dc = GPIO_DC; - dev->_SPIHandle = handle; + + dev->_dc = dc; dev->_address = SPI_ADDRESS; dev->_flip = false; + dev->_SPIHandle = handle; +} + +void spi_device_add(SSD1306_t * dev, int16_t cs, int16_t dc, int16_t reset) +{ + ESP_LOGW(TAG, "Will not install spi master driver"); + esp_err_t ret; + + gpio_reset_pin( cs ); + gpio_set_direction( cs, GPIO_MODE_OUTPUT ); + gpio_set_level( cs, 0 ); + + gpio_reset_pin( dc ); + gpio_set_direction( dc, GPIO_MODE_OUTPUT ); + gpio_set_level( dc, 0 ); + + if ( reset >= 0 ) { + gpio_reset_pin( reset ); + gpio_set_direction( reset, GPIO_MODE_OUTPUT ); + gpio_set_level( reset, 0 ); + vTaskDelay( pdMS_TO_TICKS( 100 ) ); + gpio_set_level( reset, 1 ); + } + +#if 0 + spi_bus_config_t spi_bus_config = { + .mosi_io_num = mosi, + .miso_io_num = -1, + .sclk_io_num = sclk, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = 0, + .flags = 0 + }; + + ESP_LOGI(TAG, "SPI HOST_ID=%d", HOST_ID); + ret = spi_bus_initialize( HOST_ID, &spi_bus_config, SPI_DMA_CH_AUTO ); + ESP_LOGI(TAG, "spi_bus_initialize=%d",ret); + assert(ret==ESP_OK); +#endif + + spi_device_interface_config_t devcfg; + memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) ); + //devcfg.clock_speed_hz = SPI_DEFAULT_FREQUENCY; + devcfg.clock_speed_hz = clock_speed_hz; + devcfg.spics_io_num = cs; + devcfg.queue_size = 1; + + spi_device_handle_t handle; + ret = spi_bus_add_device( HOST_ID, &devcfg, &handle); + ESP_LOGI(TAG, "spi_bus_add_device=%d",ret); + assert(ret==ESP_OK); + + dev->_dc = dc; + dev->_address = SPI_ADDRESS; + dev->_flip = false; + dev->_SPIHandle = handle; }