Skip to content

Commit

Permalink
Merge branch 'feat/oled_example_use_new_i2c_master_driver_v5.2' into …
Browse files Browse the repository at this point in the history
…'release/v5.2'

feat(i2c_lcd): use new i2c master driver in oled example (v5.2)

See merge request espressif/esp-idf!29178
  • Loading branch information
suda-morris committed Feb 22, 2024
2 parents 3f730f2 + aa7d73c commit 383a1e8
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 50 deletions.
18 changes: 10 additions & 8 deletions docs/en/api-reference/peripherals/lcd.rst
Expand Up @@ -90,33 +90,35 @@ I2C Interfaced LCD

.. code-block:: c
i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER, // I2C LCD is a master node
i2c_master_bus_handle_t i2c_bus = NULL;
i2c_master_bus_config_t bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.i2c_port = I2C_BUS_PORT,
.sda_io_num = EXAMPLE_PIN_NUM_SDA,
.scl_io_num = EXAMPLE_PIN_NUM_SCL,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
.flags.enable_internal_pullup = true,
};
ESP_ERROR_CHECK(i2c_param_config(I2C_HOST, &i2c_conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_HOST, I2C_MODE_MASTER, 0, 0, 0));
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &i2c_bus));
#. Allocate an LCD IO device handle from the I2C bus. In this step, you need to provide the following information:

- :cpp:member:`esp_lcd_panel_io_i2c_config_t::dev_addr` sets the I2C device address of the LCD controller chip. The LCD driver uses this address to communicate with the LCD controller chip.
- :cpp:member:`esp_lcd_panel_io_i2c_config_t::scl_speed_hz` sets the I2C clock frequency in Hz. The value should not exceed the range recommended in the LCD spec.
- :cpp:member:`esp_lcd_panel_io_i2c_config_t::lcd_cmd_bits` and :cpp:member:`esp_lcd_panel_io_i2c_config_t::lcd_param_bits` set the bit width of the command and parameter that recognized by the LCD controller chip. This is chip specific, you should refer to your LCD spec in advance.

.. code-block:: c
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_io_i2c_config_t io_config = {
.dev_addr = EXAMPLE_I2C_HW_ADDR,
.scl_speed_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
.control_phase_bytes = 1, // refer to LCD spec
.dc_bit_offset = 6, // refer to LCD spec
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
.lcd_param_bits = EXAMPLE_LCD_CMD_BITS,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_HOST, &io_config, &io_handle));
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(i2c_bus, &io_config, &io_handle));
#. Install the LCD controller driver. The LCD controller driver is responsible for sending the commands and parameters to the LCD controller chip. In this step, you need to specify the I2C IO device handle that allocated in the last step, and some panel specific configurations:

Expand Down
3 changes: 1 addition & 2 deletions examples/peripherals/.build-test-rules.yml
Expand Up @@ -105,8 +105,7 @@ examples/peripherals/lcd/i2c_oled:
- if: SOC_I2C_SUPPORTED != 1
depends_components:
- esp_lcd
depends_filepatterns:
- components/driver/i2c/**/*
- esp_driver_i2c

examples/peripherals/lcd/i80_controller:
disable:
Expand Down
23 changes: 13 additions & 10 deletions examples/peripherals/lcd/i2c_oled/README.md
Expand Up @@ -19,7 +19,7 @@ This example shows how to make use of the SSD1306 panel driver from `esp_lcd` co

The connection between ESP Board and the LCD is as follows:

```
```text
ESP Board OLED LCD (I2C)
+------------------+ +-------------------+
| GND+--------------+GND |
Expand Down Expand Up @@ -48,17 +48,20 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l

```bash
...
I (0) cpu_start: Starting scheduler on APP CPU.
I (345) example: Initialize I2C bus
I (345) example: Install panel IO
I (345) example: Install SSD1306 panel driver
I (455) example: Initialize LVGL library
I (455) example: Register display driver to LVGL
I (455) example: Install LVGL tick timer
I (455) example: Display LVGL Scroll Text
I (308) main_task: Started on CPU0
I (318) main_task: Calling app_main()
I (318) example: Initialize I2C bus
I (318) gpio: GPIO[3]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
I (328) gpio: GPIO[4]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
I (338) example: Install panel IO
I (338) example: Install SSD1306 panel driver
I (448) example: Initialize LVGL
I (448) LVGL: Starting LVGL task
I (448) example: Display LVGL Scroll Text
I (448) main_task: Returned from app_main()
...
```

## Troubleshooting

For any technical queries, please open an [issue] (https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
43 changes: 14 additions & 29 deletions examples/peripherals/lcd/i2c_oled/main/i2c_oled_example_main.c
@@ -1,20 +1,19 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_timer.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_ops.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"
#include "lvgl.h"
#include "driver/i2c_master.h"
#include "esp_lvgl_port.h"
#include "lvgl.h"

#if CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
#include "esp_lcd_sh1107.h"
Expand All @@ -24,7 +23,7 @@

static const char *TAG = "example";

#define I2C_HOST 0
#define I2C_BUS_PORT 0

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// Please update the following configuration according to your LCD spec //////////////////////////////
Expand All @@ -49,34 +48,25 @@ static const char *TAG = "example";

extern void example_lvgl_demo_ui(lv_disp_t *disp);

/* The LVGL port component calls esp_lcd_panel_draw_bitmap API for send data to the screen. There must be called
lvgl_port_flush_ready(disp) after each transaction to display. The best way is to use on_color_trans_done
callback from esp_lcd IO config structure. In IDF 5.1 and higher, it is solved inside LVGL port component. */
static bool notify_lvgl_flush_ready(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx)
{
lv_disp_t * disp = (lv_disp_t *)user_ctx;
lvgl_port_flush_ready(disp);
return false;
}

void app_main(void)
{
ESP_LOGI(TAG, "Initialize I2C bus");
i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
i2c_master_bus_handle_t i2c_bus = NULL;
i2c_master_bus_config_t bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.i2c_port = I2C_BUS_PORT,
.sda_io_num = EXAMPLE_PIN_NUM_SDA,
.scl_io_num = EXAMPLE_PIN_NUM_SCL,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
.flags.enable_internal_pullup = true,
};
ESP_ERROR_CHECK(i2c_param_config(I2C_HOST, &i2c_conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_HOST, I2C_MODE_MASTER, 0, 0, 0));
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &i2c_bus));

ESP_LOGI(TAG, "Install panel IO");
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_io_i2c_config_t io_config = {
.dev_addr = EXAMPLE_I2C_HW_ADDR,
.scl_speed_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
.control_phase_bytes = 1, // According to SSD1306 datasheet
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS, // According to SSD1306 datasheet
.lcd_param_bits = EXAMPLE_LCD_CMD_BITS, // According to SSD1306 datasheet
Expand All @@ -90,7 +80,7 @@ void app_main(void)
}
#endif
};
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_HOST, &io_config, &io_handle));
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(i2c_bus, &io_config, &io_handle));

ESP_LOGI(TAG, "Install SSD1306 panel driver");
esp_lcd_panel_handle_t panel_handle = NULL;
Expand Down Expand Up @@ -130,12 +120,7 @@ void app_main(void)
.mirror_y = false,
}
};
lv_disp_t * disp = lvgl_port_add_disp(&disp_cfg);
/* Register done callback for IO */
const esp_lcd_panel_io_callbacks_t cbs = {
.on_color_trans_done = notify_lvgl_flush_ready,
};
esp_lcd_panel_io_register_event_callbacks(io_handle, &cbs, disp);
lv_disp_t *disp = lvgl_port_add_disp(&disp_cfg);

/* Rotation of the screen */
lv_disp_set_rotation(disp, LV_DISP_ROT_NONE);
Expand Down
1 change: 0 additions & 1 deletion examples/peripherals/lcd/i2c_oled/main/idf_component.yml
@@ -1,5 +1,4 @@
dependencies:
idf: ">=4.4"
lvgl/lvgl: "~8.3.0"
esp_lcd_sh1107: "^1"
esp_lvgl_port: "^1"

0 comments on commit 383a1e8

Please sign in to comment.