Changeset - 36aad00d10b4
[Not reviewed]
default
0 3 2
Ethan Zonca - 17 months ago 2024-01-06 11:40:00
ez@ethanzonca.com
Add example code for display and LVGL
5 files changed with 278 insertions and 1 deletions:
0 comments (0 inline, 0 general)
main/CMakeLists.txt
Show inline comments
 
idf_component_register(SRCS "main.c" "wifi.c" "usb_cdc.c" "can.c"
 
idf_component_register(SRCS "main.c" "wifi.c" "usb_cdc.c" "can.c" "display.c"
 
                       INCLUDE_DIRS .)
main/display.c
Show inline comments
 
new file 100644
 
//
 
// display
 
//
 

	
 
#include "display.h"
 
#include "esp_err.h"
 
#include "esp_log.h"
 
#include "esp_check.h"
 
#include "driver/i2c.h"
 
#include "driver/gpio.h"
 
#include "driver/spi_master.h"
 
#include "esp_lcd_panel_io.h"
 
#include "esp_lcd_panel_vendor.h"
 
#include "esp_lcd_panel_ops.h"
 
#include "esp_lvgl_port.h"
 

	
 

	
 

	
 

	
 
#include "esp_lcd_touch_tt21100.h"
 

	
 
/* LCD size */
 
#define EXAMPLE_LCD_H_RES   (320)
 
#define EXAMPLE_LCD_V_RES   (240)
 

	
 
/* LCD settings */
 
#define EXAMPLE_LCD_SPI_NUM         (SPI3_HOST)
 
#define EXAMPLE_LCD_PIXEL_CLK_HZ    (40 * 1000 * 1000)
 
#define EXAMPLE_LCD_CMD_BITS        (8)
 
#define EXAMPLE_LCD_PARAM_BITS      (8)
 
#define EXAMPLE_LCD_COLOR_SPACE     (ESP_LCD_COLOR_SPACE_BGR)
 
#define EXAMPLE_LCD_BITS_PER_PIXEL  (16)
 
#define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (1)
 
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (50)
 
#define EXAMPLE_LCD_BL_ON_LEVEL     (1)
 

	
 
/* LCD pins */
 
#define EXAMPLE_LCD_GPIO_SCLK       (GPIO_NUM_7)
 
#define EXAMPLE_LCD_GPIO_MOSI       (GPIO_NUM_6)
 
#define EXAMPLE_LCD_GPIO_RST        (GPIO_NUM_48)
 
#define EXAMPLE_LCD_GPIO_DC         (GPIO_NUM_4)
 
#define EXAMPLE_LCD_GPIO_CS         (GPIO_NUM_5)
 
#define EXAMPLE_LCD_GPIO_BL         (GPIO_NUM_45)
 

	
 
/* Touch settings */
 
#define EXAMPLE_TOUCH_I2C_NUM       (0)
 
#define EXAMPLE_TOUCH_I2C_CLK_HZ    (400000)
 

	
 
/* LCD touch pins */
 
#define EXAMPLE_TOUCH_I2C_SCL       (GPIO_NUM_18)
 
#define EXAMPLE_TOUCH_I2C_SDA       (GPIO_NUM_8)
 
#define EXAMPLE_TOUCH_GPIO_INT      (GPIO_NUM_20)
 

	
 
static const char *TAG = "EXAMPLE";
 

	
 
/* LCD IO and panel */
 
static esp_lcd_panel_io_handle_t lcd_io = NULL;
 
static esp_lcd_panel_handle_t lcd_panel = NULL;
 
static esp_lcd_touch_handle_t touch_handle = NULL;
 

	
 
/* LVGL display and touch */
 
static lv_disp_t *lvgl_disp = NULL;
 
static lv_indev_t *lvgl_touch_indev = NULL;
 

	
 

	
 

	
 
static esp_err_t __lcd_init(void)
 
{
 
    esp_err_t ret = ESP_OK;
 

	
 
    /* LCD backlight */
 
    gpio_config_t bk_gpio_config = {
 
        .mode = GPIO_MODE_OUTPUT,
 
        .pin_bit_mask = 1ULL << EXAMPLE_LCD_GPIO_BL
 
    };
 
    ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
 

	
 
    /* LCD initialization */
 
    ESP_LOGD(TAG, "Initialize SPI bus");
 
    const spi_bus_config_t buscfg = {
 
        .sclk_io_num = EXAMPLE_LCD_GPIO_SCLK,
 
        .mosi_io_num = EXAMPLE_LCD_GPIO_MOSI,
 
        .miso_io_num = GPIO_NUM_NC,
 
        .quadwp_io_num = GPIO_NUM_NC,
 
        .quadhd_io_num = GPIO_NUM_NC,
 
        .max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t),
 
    };
 
    ESP_RETURN_ON_ERROR(spi_bus_initialize(EXAMPLE_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed");
 

	
 
    ESP_LOGD(TAG, "Install panel IO");
 
    const esp_lcd_panel_io_spi_config_t io_config = {
 
        .dc_gpio_num = EXAMPLE_LCD_GPIO_DC,
 
        .cs_gpio_num = EXAMPLE_LCD_GPIO_CS,
 
        .pclk_hz = EXAMPLE_LCD_PIXEL_CLK_HZ,
 
        .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
 
        .lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
 
        .spi_mode = 0,
 
        .trans_queue_depth = 10,
 
    };
 
    ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)EXAMPLE_LCD_SPI_NUM, &io_config, &lcd_io), err, TAG, "New panel IO failed");
 

	
 
    ESP_LOGD(TAG, "Install LCD driver");
 
    const esp_lcd_panel_dev_config_t panel_config = {
 
        .reset_gpio_num = EXAMPLE_LCD_GPIO_RST,
 
        .color_space = EXAMPLE_LCD_COLOR_SPACE,
 
        .bits_per_pixel = EXAMPLE_LCD_BITS_PER_PIXEL,
 
    };
 
    ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(lcd_io, &panel_config, &lcd_panel), err, TAG, "New panel failed");
 

	
 
    esp_lcd_panel_reset(lcd_panel);
 
    esp_lcd_panel_init(lcd_panel);
 
    esp_lcd_panel_mirror(lcd_panel, true, true);
 
    esp_lcd_panel_disp_on_off(lcd_panel, true);
 

	
 
    /* LCD backlight on */
 
    ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_LCD_GPIO_BL, EXAMPLE_LCD_BL_ON_LEVEL));
 

	
 
    return ret;
 

	
 
err:
 
    if (lcd_panel) {
 
        esp_lcd_panel_del(lcd_panel);
 
    }
 
    if (lcd_io) {
 
        esp_lcd_panel_io_del(lcd_io);
 
    }
 
    spi_bus_free(EXAMPLE_LCD_SPI_NUM);
 
    return ret;
 
}
 

	
 

	
 
// static esp_err_t app_touch_init(void)
 
// {
 
//     /* Initilize I2C */
 
//     const i2c_config_t i2c_conf = {
 
//         .mode = I2C_MODE_MASTER,
 
//         .sda_io_num = EXAMPLE_TOUCH_I2C_SDA,
 
//         .sda_pullup_en = GPIO_PULLUP_DISABLE,
 
//         .scl_io_num = EXAMPLE_TOUCH_I2C_SCL,
 
//         .scl_pullup_en = GPIO_PULLUP_DISABLE,
 
//         .master.clk_speed = EXAMPLE_TOUCH_I2C_CLK_HZ
 
//     };
 
//     ESP_RETURN_ON_ERROR(i2c_param_config(EXAMPLE_TOUCH_I2C_NUM, &i2c_conf), TAG, "I2C configuration failed");
 
//     ESP_RETURN_ON_ERROR(i2c_driver_install(EXAMPLE_TOUCH_I2C_NUM, i2c_conf.mode, 0, 0, 0), TAG, "I2C initialization failed");
 

	
 
//     /* Initialize touch HW */
 
//     const esp_lcd_touch_config_t tp_cfg = {
 
//         .x_max = EXAMPLE_LCD_H_RES,
 
//         .y_max = EXAMPLE_LCD_V_RES,
 
//         .rst_gpio_num = GPIO_NUM_NC, // Shared with LCD reset
 
//         .int_gpio_num = EXAMPLE_TOUCH_GPIO_INT,
 
//         .levels = {
 
//             .reset = 0,
 
//             .interrupt = 0,
 
//         },
 
//         .flags = {
 
//             .swap_xy = 0,
 
//             .mirror_x = 1,
 
//             .mirror_y = 0,
 
//         },
 
//     };
 
//     esp_lcd_panel_io_handle_t tp_io_handle = NULL;
 
//     const esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_TT21100_CONFIG();
 
//     ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)EXAMPLE_TOUCH_I2C_NUM, &tp_io_config, &tp_io_handle), TAG, "");
 
//     return esp_lcd_touch_new_i2c_tt21100(tp_io_handle, &tp_cfg, &touch_handle);
 
// }
 

	
 
static esp_err_t __lvgl_init(void)
 
{
 
    /* Initialize LVGL */
 
    const lvgl_port_cfg_t lvgl_cfg = {
 
        .task_priority = 4,         /* LVGL task priority */
 
        .task_stack = 4096,         /* LVGL task stack size */
 
        .task_affinity = -1,        /* LVGL task pinned to core (-1 is no affinity) */
 
        .task_max_sleep_ms = 500,   /* Maximum sleep in LVGL task */
 
        .timer_period_ms = 5        /* LVGL timer tick period in ms */
 
    };
 
    ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL port initialization failed");
 

	
 
    /* Add LCD screen */
 
    ESP_LOGD(TAG, "Add LCD screen");
 
    const lvgl_port_display_cfg_t disp_cfg = {
 
        .io_handle = lcd_io,
 
        .panel_handle = lcd_panel,
 
        .buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t),
 
        .double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE,
 
        .hres = EXAMPLE_LCD_H_RES,
 
        .vres = EXAMPLE_LCD_V_RES,
 
        .monochrome = false,
 
        /* Rotation values must be same as used in esp_lcd for initial settings of the screen */
 
        .rotation = {
 
            .swap_xy = false,
 
            .mirror_x = true,
 
            .mirror_y = true,
 
        },
 
        .flags = {
 
            .buff_dma = true,
 
        }
 
    };
 
    lvgl_disp = lvgl_port_add_disp(&disp_cfg);
 

	
 
    /* Add touch input (for selected screen) */
 
    // const lvgl_port_touch_cfg_t touch_cfg = {
 
    //     .disp = lvgl_disp,
 
    //     .handle = touch_handle,
 
    // };
 
    // lvgl_touch_indev = lvgl_port_add_touch(&touch_cfg);
 

	
 
    return ESP_OK;
 
}
 

	
 
static void _app_button_cb(lv_event_t *e)
 
{
 
    lv_disp_rot_t rotation = lv_disp_get_rotation(lvgl_disp);
 
    rotation++;
 
    if (rotation > LV_DISP_ROT_270) {
 
        rotation = LV_DISP_ROT_NONE;
 
    }
 

	
 
    /* LCD HW rotation */
 
    lv_disp_set_rotation(lvgl_disp, rotation);
 
}
 

	
 
static void show_stuff(void)
 
{
 
    lv_obj_t *scr = lv_scr_act();
 

	
 
    /* Task lock */
 
    lvgl_port_lock(0);
 

	
 
    /* Your LVGL objects code here .... */
 

	
 
    /* Label */
 
    lv_obj_t *label = lv_label_create(scr);
 
    lv_label_set_recolor(label, true);
 
    lv_obj_set_width(label, EXAMPLE_LCD_H_RES);
 
    lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
 
    lv_label_set_text(label, "#FF0000 "LV_SYMBOL_BELL" Hello world Espressif and LVGL "LV_SYMBOL_BELL"#\n#FF9400 "LV_SYMBOL_WARNING" For simplier initialization, use BSP "LV_SYMBOL_WARNING" #");
 
    lv_obj_align(label, LV_ALIGN_CENTER, 0, -30);
 

	
 
    /* Button */
 
    lv_obj_t *btn = lv_btn_create(scr);
 
    label = lv_label_create(btn);
 
    lv_label_set_text_static(label, "Rotate screen");
 
    lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -30);
 
    lv_obj_add_event_cb(btn, _app_button_cb, LV_EVENT_CLICKED, NULL);
 

	
 
    /* Task unlock */
 
    lvgl_port_unlock();
 
}
 

	
 
void display_init(void)
 
{
 
    /* LCD HW initialization */
 
    ESP_ERROR_CHECK(__lcd_init());
 

	
 
    /* Touch initialization */
 
//    ESP_ERROR_CHECK(app_touch_init());
 

	
 
    /* LVGL initialization */
 
    ESP_ERROR_CHECK(__lvgl_init());
 

	
 
    /* Show LVGL objects */
 
    show_stuff();
 
}
 
\ No newline at end of file
main/display.h
Show inline comments
 
new file 100644
 
#ifndef _DISPLAY_H_
 
#define _DISPLAY_H_
 

	
 
void display_init(void);
 

	
 
#endif
 
\ No newline at end of file
main/idf_component.yml
Show inline comments
 
## IDF Component Manager Manifest File
 
dependencies:
 
  espressif/esp_lcd_touch_tt21100: "*"
 
  espressif/esp_lvgl_port: "*"
 
  espressif/esp_tinyusb: "^1"
 
  idf: "^5.0"
main/main.c
Show inline comments
 
@@ -15,6 +15,7 @@
 
#include "wifi.h"
 
#include "usb_cdc.h"
 
#include "can.h"
 
#include "display.h"
 

	
 

	
 
// Private variables
 
@@ -42,4 +43,7 @@ void app_main(void)
 
    // Initialize canbus
 
    can_init();
 

	
 
    // Initialize display
 
    display_init();
 

	
 
}
0 comments (0 inline, 0 general)