/* * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ #include #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 "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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////// Please update the following configuration according to your LCD spec ////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define EXAMPLE_LCD_PIXEL_CLOCK_HZ (400 * 1000) #define EXAMPLE_PIN_NUM_SDA 3 #define EXAMPLE_PIN_NUM_SCL 4 #define EXAMPLE_PIN_NUM_RST -1 #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 CONFIG_EXAMPLE_SSD1306_HEIGHT #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 extern void example_lvgl_demo_ui(lv_disp_t *disp); void app_main(void) { ESP_LOGI(TAG, "Initialize I2C bus"); i2c_config_t i2c_conf = { .mode = I2C_MODE_MASTER, .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, }; 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_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, .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 #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(I2C_HOST, &io_config, &io_handle)); ESP_LOGI(TAG, "Install SSD1306 panel driver"); esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_panel_dev_config_t panel_config = { .bits_per_pixel = 1, .reset_gpio_num = EXAMPLE_PIN_NUM_RST, }; #if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306 esp_lcd_panel_ssd1306_config_t ssd1306_config = { .height = EXAMPLE_LCD_V_RES, }; panel_config.vendor_config = &ssd1306_config; 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 = { .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, .vres = EXAMPLE_LCD_V_RES, .monochrome = true, .rotation = { .swap_xy = false, .mirror_x = false, .mirror_y = false, } }; lv_disp_t * disp = lvgl_port_add_disp(&disp_cfg); /* Rotation of the screen */ lv_disp_set_rotation(disp, LV_DISP_ROT_NONE); ESP_LOGI(TAG, "Display LVGL Scroll Text"); // Lock the mutex due to the LVGL APIs are not thread-safe if (lvgl_port_lock(0)) { example_lvgl_demo_ui(disp); // Release the mutex lvgl_port_unlock(); } }