mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-18 19:03:16 +00:00
* Revert "Update ESP LCD Touch dependencies (#63)" This reverts commit cbd0355cec25e9d0f83f328ac2cae78e0e3b83e3. * Revert "Updated board configs for LVGL changes (#62)" This reverts commit 52d769854f6805407f7ee08adaa78b3a406fa13e. * Revert "Various updates (#60)" This reverts commit a8a664703b131963222d2035a3a85ecede29e633.
266 lines
8.6 KiB
C
266 lines
8.6 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#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_3)
|
|
|
|
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_display_t *lvgl_disp = NULL;
|
|
static lv_indev_t *lvgl_touch_indev = NULL;
|
|
|
|
static esp_err_t app_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 app_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,
|
|
.swap_bytes = 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_rotation_t rotation = lv_disp_get_rotation(lvgl_disp);
|
|
rotation++;
|
|
if (rotation > LV_DISPLAY_ROTATION_270) {
|
|
rotation = LV_DISPLAY_ROTATION_0;
|
|
}
|
|
|
|
/* LCD HW rotation */
|
|
lv_disp_set_rotation(lvgl_disp, rotation);
|
|
}
|
|
|
|
static void app_main_display(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_obj_set_width(label, EXAMPLE_LCD_H_RES);
|
|
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
|
|
#if LVGL_VERSION_MAJOR == 8
|
|
lv_label_set_recolor(label, true);
|
|
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" #");
|
|
#else
|
|
lv_label_set_text(label, LV_SYMBOL_BELL" Hello world Espressif and LVGL "LV_SYMBOL_BELL"\n "LV_SYMBOL_WARNING" For simplier initialization, use BSP "LV_SYMBOL_WARNING);
|
|
#endif
|
|
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 app_main(void)
|
|
{
|
|
/* LCD HW initialization */
|
|
ESP_ERROR_CHECK(app_lcd_init());
|
|
|
|
/* Touch initialization */
|
|
ESP_ERROR_CHECK(app_touch_init());
|
|
|
|
/* LVGL initialization */
|
|
ESP_ERROR_CHECK(app_lvgl_init());
|
|
|
|
/* Show LVGL objects */
|
|
app_main_display();
|
|
}
|