From 7e661b3f7f6cf8346848fec9087c578f3878e9b1 Mon Sep 17 00:00:00 2001 From: Vilem Zavodny Date: Thu, 3 Nov 2022 10:26:05 +0100 Subject: [PATCH] lcd: Add SH1107 controller into I2C oled example. --- .../lcd/i2c_oled/main/Kconfig.projbuild | 16 ++++++ .../lcd/i2c_oled/main/i2c_oled_example_main.c | 56 ++++++++++++++----- .../lcd/i2c_oled/main/idf_component.yml | 2 + 3 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 examples/peripherals/lcd/i2c_oled/main/Kconfig.projbuild diff --git a/examples/peripherals/lcd/i2c_oled/main/Kconfig.projbuild b/examples/peripherals/lcd/i2c_oled/main/Kconfig.projbuild new file mode 100644 index 0000000000..64101e6c43 --- /dev/null +++ b/examples/peripherals/lcd/i2c_oled/main/Kconfig.projbuild @@ -0,0 +1,16 @@ +menu "Example Configuration" + + choice EXAMPLE_LCD_CONTROLLER + prompt "LCD controller model" + default EXAMPLE_LCD_CONTROLLER_SSD1306 + help + Select LCD controller model + + config EXAMPLE_LCD_CONTROLLER_SSD1306 + bool "SSD1306" + + config EXAMPLE_LCD_CONTROLLER_SH1107 + bool "SH1107" + endchoice + +endmenu diff --git a/examples/peripherals/lcd/i2c_oled/main/i2c_oled_example_main.c b/examples/peripherals/lcd/i2c_oled/main/i2c_oled_example_main.c index 6545ba2bd2..fa71893d5f 100644 --- a/examples/peripherals/lcd/i2c_oled/main/i2c_oled_example_main.c +++ b/examples/peripherals/lcd/i2c_oled/main/i2c_oled_example_main.c @@ -9,7 +9,6 @@ #include "freertos/task.h" #include "esp_timer.h" #include "esp_lcd_panel_io.h" -#include "esp_lcd_panel_vendor.h" #include "esp_lcd_panel_ops.h" #include "driver/i2c.h" #include "esp_err.h" @@ -17,6 +16,12 @@ #include "lvgl.h" #include "esp_lvgl_port.h" +#if CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107 +#include "esp_lcd_sh1107.h" +#else +#include "esp_lcd_panel_vendor.h" +#endif + static const char *TAG = "example"; #define I2C_HOST 0 @@ -31,22 +36,26 @@ static const char *TAG = "example"; #define EXAMPLE_I2C_HW_ADDR 0x3C // The pixel number in horizontal and vertical +#if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306 #define EXAMPLE_LCD_H_RES 128 #define EXAMPLE_LCD_V_RES 64 +#elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107 +#define EXAMPLE_LCD_H_RES 64 +#define EXAMPLE_LCD_V_RES 128 +#endif // Bit number used to represent command and parameter #define EXAMPLE_LCD_CMD_BITS 8 #define EXAMPLE_LCD_PARAM_BITS 8 -#define EXAMPLE_LVGL_TICK_PERIOD_MS 2 - extern void example_lvgl_demo_ui(lv_disp_t *disp); -static lv_disp_t * disp; - -static bool example_notify_lvgl_flush_ready(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx) +/* 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); + lv_disp_t * disp = (lv_disp_t *)user_ctx; + lvgl_port_flush_ready(disp); return false; } @@ -69,11 +78,17 @@ void app_main(void) esp_lcd_panel_io_i2c_config_t io_config = { .dev_addr = EXAMPLE_I2C_HW_ADDR, .control_phase_bytes = 1, // According to SSD1306 datasheet - .dc_bit_offset = 6, // 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 - .on_color_trans_done = example_notify_lvgl_flush_ready, - .user_ctx = &disp, +#if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306 + .dc_bit_offset = 6, // According to SSD1306 datasheet +#elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107 + .dc_bit_offset = 0, // According to SH1107 datasheet + .flags = + { + .disable_control_phase = 1, + } +#endif }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_HOST, &io_config, &io_handle)); @@ -83,18 +98,27 @@ void app_main(void) .bits_per_pixel = 1, .reset_gpio_num = EXAMPLE_PIN_NUM_RST, }; +#if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306 ESP_ERROR_CHECK(esp_lcd_new_panel_ssd1306(io_handle, &panel_config, &panel_handle)); +#elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107 + ESP_ERROR_CHECK(esp_lcd_new_panel_sh1107(io_handle, &panel_config, &panel_handle)); +#endif ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle)); ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); +#if CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107 + ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, true)); +#endif + ESP_LOGI(TAG, "Initialize LVGL"); const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG(); lvgl_port_init(&lvgl_cfg); const lvgl_port_display_cfg_t disp_cfg = { - .handle = panel_handle, + .io_handle = io_handle, + .panel_handle = panel_handle, .buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES, .double_buffer = true, .hres = EXAMPLE_LCD_H_RES, @@ -106,7 +130,13 @@ void app_main(void) .mirror_y = false, } }; - disp = lvgl_port_add_disp(&disp_cfg); + 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); + /* Rotation of the screen */ lv_disp_set_rotation(disp, LV_DISP_ROT_NONE); diff --git a/examples/peripherals/lcd/i2c_oled/main/idf_component.yml b/examples/peripherals/lcd/i2c_oled/main/idf_component.yml index 84e851db81..1a62a3f4e5 100644 --- a/examples/peripherals/lcd/i2c_oled/main/idf_component.yml +++ b/examples/peripherals/lcd/i2c_oled/main/idf_component.yml @@ -1,3 +1,5 @@ dependencies: idf: ">=4.4" lvgl/lvgl: "~8.2.0" + esp_lcd_sh1107: "^1" + esp_lvgl_port: "^1"