feat: 重构项目结构以支持新的用户界面和功能
- 更新 CMakeLists.txt,添加新的源文件和依赖项以支持应用程序结构 - 移除旧的 main.c 和 lvgl_demo_ui.c 文件,整合应用逻辑至 app_main.c - 新增 app/ui_handlers.c 和 app/ui_handlers.h,准备处理 UI 事件 - 引入 bsp/display.c 和 bsp/touch.c,配置显示和触摸功能 - 添加 services/wifi_manager.c,管理 Wi-Fi 连接 - 组织 UI 组件和资源,提升代码可维护性与可读性 - 更新相关头文件和配置,确保项目兼容性与功能完整性
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "driver/i2c.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
/* LCD SPI (ST7789) */
|
||||
#define BOARD_LCD_HOST SPI2_HOST
|
||||
#define BOARD_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000)
|
||||
#define BOARD_LCD_H_RES 240
|
||||
#define BOARD_LCD_V_RES 320
|
||||
#define BOARD_LCD_CMD_BITS 8
|
||||
#define BOARD_LCD_PARAM_BITS 8
|
||||
|
||||
#define BOARD_PIN_LCD_SCLK 10
|
||||
#define BOARD_PIN_LCD_MOSI 13
|
||||
#define BOARD_PIN_LCD_MISO (-1)
|
||||
#define BOARD_PIN_LCD_DC 11
|
||||
#define BOARD_PIN_LCD_RST 9
|
||||
#define BOARD_PIN_LCD_CS 12
|
||||
#define BOARD_PIN_BK_LIGHT 14
|
||||
|
||||
/* Backlight PWM */
|
||||
#define BOARD_LCD_BK_LIGHT_CH LEDC_CHANNEL_0
|
||||
#define BOARD_LCD_BK_LIGHT_TIMER LEDC_TIMER_0
|
||||
#define BOARD_LCD_BK_LIGHT_FREQ 5000
|
||||
#define BOARD_LCD_BK_LIGHT_ON_LEVEL 1
|
||||
#define BOARD_LCD_BK_LIGHT_OFF_LEVEL (!BOARD_LCD_BK_LIGHT_ON_LEVEL)
|
||||
|
||||
/* Touch I2C (CST816) */
|
||||
#define BOARD_PIN_TOUCH_SDA 47
|
||||
#define BOARD_PIN_TOUCH_SCL 48
|
||||
#define BOARD_PIN_TOUCH_RST 17
|
||||
#define BOARD_PIN_TOUCH_INT 21
|
||||
|
||||
#define BOARD_TOUCH_I2C_NUM I2C_NUM_0
|
||||
#define BOARD_TOUCH_I2C_FREQ_HZ 400000
|
||||
#define BOARD_TOUCH_ENABLED 0
|
||||
|
||||
/* User IO */
|
||||
#define BOARD_PIN_KEY 4
|
||||
#define BOARD_PIN_LED 16
|
||||
|
||||
/* LVGL port */
|
||||
#define BOARD_LVGL_DRAW_BUF_LINES 20
|
||||
#define BOARD_LVGL_TICK_PERIOD_MS 2
|
||||
#define BOARD_LVGL_TASK_MAX_DELAY_MS 500
|
||||
#define BOARD_LVGL_TASK_MIN_DELAY_MS (1000 / CONFIG_FREERTOS_HZ)
|
||||
#define BOARD_LVGL_TASK_STACK_SIZE (8 * 1024)
|
||||
#define BOARD_LVGL_TASK_PRIORITY 2
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "display.h"
|
||||
|
||||
#include "board_config.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lcd_panel_st7789.h"
|
||||
#include "esp_lcd_panel_vendor.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "display";
|
||||
|
||||
void display_backlight_set_brightness(uint16_t brightness)
|
||||
{
|
||||
if (brightness > 1023) {
|
||||
brightness = 1023;
|
||||
}
|
||||
ESP_ERROR_CHECK(
|
||||
ledc_set_duty(LEDC_LOW_SPEED_MODE, BOARD_LCD_BK_LIGHT_CH, brightness));
|
||||
ESP_ERROR_CHECK(
|
||||
ledc_update_duty(LEDC_LOW_SPEED_MODE, BOARD_LCD_BK_LIGHT_CH));
|
||||
}
|
||||
|
||||
void display_backlight_on(void)
|
||||
{
|
||||
display_backlight_set_brightness(1023);
|
||||
}
|
||||
|
||||
esp_err_t display_init(esp_lcd_panel_io_handle_t *io_handle_out,
|
||||
esp_lcd_panel_handle_t *panel_handle_out)
|
||||
{
|
||||
ESP_LOGI(TAG, "Configure LCD backlight PWM");
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.timer_num = BOARD_LCD_BK_LIGHT_TIMER,
|
||||
.duty_resolution = LEDC_TIMER_10_BIT,
|
||||
.freq_hz = BOARD_LCD_BK_LIGHT_FREQ,
|
||||
.clk_cfg = LEDC_AUTO_CLK,
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
||||
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.channel = BOARD_LCD_BK_LIGHT_CH,
|
||||
.timer_sel = BOARD_LCD_BK_LIGHT_TIMER,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = BOARD_PIN_BK_LIGHT,
|
||||
.duty = 0,
|
||||
.hpoint = 0,
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
||||
|
||||
ESP_LOGI(TAG, "Initialize SPI bus");
|
||||
spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = BOARD_PIN_LCD_SCLK,
|
||||
.mosi_io_num = BOARD_PIN_LCD_MOSI,
|
||||
.miso_io_num = BOARD_PIN_LCD_MISO,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = BOARD_LCD_H_RES * 80 * sizeof(uint16_t),
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(BOARD_LCD_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
ESP_LOGI(TAG, "Install panel IO");
|
||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||
esp_lcd_panel_io_spi_config_t io_config = {
|
||||
.dc_gpio_num = BOARD_PIN_LCD_DC,
|
||||
.cs_gpio_num = BOARD_PIN_LCD_CS,
|
||||
.pclk_hz = BOARD_LCD_PIXEL_CLOCK_HZ,
|
||||
.lcd_cmd_bits = BOARD_LCD_CMD_BITS,
|
||||
.lcd_param_bits = BOARD_LCD_PARAM_BITS,
|
||||
.spi_mode = 0,
|
||||
.trans_queue_depth = 10,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(BOARD_LCD_HOST, &io_config, &io_handle));
|
||||
|
||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||
esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = BOARD_PIN_LCD_RST,
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
|
||||
.bits_per_pixel = 16,
|
||||
};
|
||||
ESP_LOGI(TAG, "Install ST7789 panel driver");
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, false, false));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
|
||||
|
||||
ESP_LOGI(TAG, "Turn on LCD backlight");
|
||||
gpio_set_level(BOARD_PIN_BK_LIGHT, BOARD_LCD_BK_LIGHT_ON_LEVEL);
|
||||
|
||||
*io_handle_out = io_handle;
|
||||
*panel_handle_out = panel_handle;
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_lcd_panel_io.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
|
||||
esp_err_t display_init(esp_lcd_panel_io_handle_t *io_handle_out,
|
||||
esp_lcd_panel_handle_t *panel_handle_out);
|
||||
void display_backlight_set_brightness(uint16_t brightness);
|
||||
void display_backlight_on(void);
|
||||
@@ -0,0 +1,119 @@
|
||||
#include "lvgl_port.h"
|
||||
|
||||
#include "board_config.h"
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "sys/lock.h"
|
||||
#include "sys/param.h"
|
||||
#include "unistd.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static const char *TAG = "lvgl_port";
|
||||
static _lock_t s_lvgl_api_lock;
|
||||
|
||||
static bool notify_flush_ready(esp_lcd_panel_io_handle_t panel_io,
|
||||
esp_lcd_panel_io_event_data_t *edata,
|
||||
void *user_ctx)
|
||||
{
|
||||
(void)panel_io;
|
||||
(void)edata;
|
||||
lv_display_t *disp = (lv_display_t *)user_ctx;
|
||||
lv_display_flush_ready(disp);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
|
||||
{
|
||||
esp_lcd_panel_handle_t panel_handle = lv_display_get_user_data(disp);
|
||||
int offsetx1 = area->x1;
|
||||
int offsetx2 = area->x2;
|
||||
int offsety1 = area->y1;
|
||||
int offsety2 = area->y2;
|
||||
lv_draw_sw_rgb565_swap(px_map,
|
||||
(offsetx2 + 1 - offsetx1) * (offsety2 + 1 - offsety1));
|
||||
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1,
|
||||
offsety2 + 1, px_map);
|
||||
}
|
||||
|
||||
static void increase_lvgl_tick(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
lv_tick_inc(BOARD_LVGL_TICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
static void lvgl_port_task(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
ESP_LOGI(TAG, "Starting LVGL task");
|
||||
uint32_t time_till_next_ms = 0;
|
||||
while (1) {
|
||||
_lock_acquire(&s_lvgl_api_lock);
|
||||
time_till_next_ms = lv_timer_handler();
|
||||
_lock_release(&s_lvgl_api_lock);
|
||||
time_till_next_ms = MAX(time_till_next_ms, BOARD_LVGL_TASK_MIN_DELAY_MS);
|
||||
time_till_next_ms = MIN(time_till_next_ms, BOARD_LVGL_TASK_MAX_DELAY_MS);
|
||||
usleep(1000 * time_till_next_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void lvgl_port_lock(void)
|
||||
{
|
||||
_lock_acquire(&s_lvgl_api_lock);
|
||||
}
|
||||
|
||||
void lvgl_port_unlock(void)
|
||||
{
|
||||
_lock_release(&s_lvgl_api_lock);
|
||||
}
|
||||
|
||||
lv_display_t *lvgl_port_init(esp_lcd_panel_io_handle_t io_handle,
|
||||
esp_lcd_panel_handle_t panel_handle)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initialize LVGL library");
|
||||
lv_init();
|
||||
|
||||
lv_display_t *display =
|
||||
lv_display_create(BOARD_LCD_H_RES, BOARD_LCD_V_RES);
|
||||
|
||||
size_t draw_buffer_sz = BOARD_LCD_H_RES * BOARD_LVGL_DRAW_BUF_LINES *
|
||||
sizeof(lv_color16_t);
|
||||
void *buf1 = spi_bus_dma_memory_alloc(BOARD_LCD_HOST, draw_buffer_sz, 0);
|
||||
assert(buf1);
|
||||
void *buf2 = spi_bus_dma_memory_alloc(BOARD_LCD_HOST, draw_buffer_sz, 0);
|
||||
assert(buf2);
|
||||
|
||||
lv_display_set_buffers(display, buf1, buf2, draw_buffer_sz,
|
||||
LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
lv_display_set_user_data(display, panel_handle);
|
||||
lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB565);
|
||||
lv_display_set_flush_cb(display, flush_cb);
|
||||
|
||||
ESP_LOGI(TAG, "Install LVGL tick timer");
|
||||
const esp_timer_create_args_t lvgl_tick_timer_args = {
|
||||
.callback = &increase_lvgl_tick,
|
||||
.name = "lvgl_tick",
|
||||
};
|
||||
esp_timer_handle_t lvgl_tick_timer = NULL;
|
||||
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
|
||||
ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer,
|
||||
BOARD_LVGL_TICK_PERIOD_MS * 1000));
|
||||
|
||||
ESP_LOGI(TAG, "Register flush ready callback");
|
||||
const esp_lcd_panel_io_callbacks_t cbs = {
|
||||
.on_color_trans_done = notify_flush_ready,
|
||||
};
|
||||
ESP_ERROR_CHECK(
|
||||
esp_lcd_panel_io_register_event_callbacks(io_handle, &cbs, display));
|
||||
|
||||
ESP_LOGI(TAG, "Create LVGL task");
|
||||
xTaskCreate(lvgl_port_task, "LVGL", BOARD_LVGL_TASK_STACK_SIZE, NULL,
|
||||
BOARD_LVGL_TASK_PRIORITY, NULL);
|
||||
|
||||
return display;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_lcd_panel_io.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
lv_display_t *lvgl_port_init(esp_lcd_panel_io_handle_t io_handle,
|
||||
esp_lcd_panel_handle_t panel_handle);
|
||||
void lvgl_port_lock(void);
|
||||
void lvgl_port_unlock(void);
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "touch.h"
|
||||
|
||||
#include "board_config.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_lcd_touch.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "touch";
|
||||
|
||||
#if BOARD_TOUCH_ENABLED
|
||||
|
||||
#include "esp_lcd_touch_cst816.h"
|
||||
|
||||
static void lvgl_touch_read_cb(lv_indev_t *indev, lv_indev_data_t *data)
|
||||
{
|
||||
uint16_t touchpad_x[1] = {0};
|
||||
uint16_t touchpad_y[1] = {0};
|
||||
uint8_t touchpad_cnt = 0;
|
||||
|
||||
esp_lcd_touch_handle_t touch_pad = lv_indev_get_user_data(indev);
|
||||
esp_lcd_touch_read_data(touch_pad);
|
||||
bool touchpad_pressed = esp_lcd_touch_get_coordinates(
|
||||
touch_pad, touchpad_x, touchpad_y, NULL, &touchpad_cnt, 1);
|
||||
|
||||
if (touchpad_pressed && touchpad_cnt > 0) {
|
||||
data->point.x = touchpad_x[0];
|
||||
data->point.y = touchpad_y[0];
|
||||
data->state = LV_INDEV_STATE_PRESSED;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t touch_init(lv_display_t *display)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initialize I2C for touch");
|
||||
i2c_config_t i2c_conf = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_io_num = BOARD_PIN_TOUCH_SDA,
|
||||
.scl_io_num = BOARD_PIN_TOUCH_SCL,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = BOARD_TOUCH_I2C_FREQ_HZ,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_param_config(BOARD_TOUCH_I2C_NUM, &i2c_conf));
|
||||
ESP_ERROR_CHECK(i2c_driver_install(BOARD_TOUCH_I2C_NUM, I2C_MODE_MASTER, 0, 0, 0));
|
||||
|
||||
ESP_LOGI(TAG, "Initialize touch controller CST816");
|
||||
esp_lcd_touch_handle_t tp = NULL;
|
||||
esp_lcd_touch_config_t tp_cfg = {
|
||||
.x_max = BOARD_LCD_H_RES,
|
||||
.y_max = BOARD_LCD_V_RES,
|
||||
.rst_gpio_num = BOARD_PIN_TOUCH_RST,
|
||||
.int_gpio_num = BOARD_PIN_TOUCH_INT,
|
||||
.flags = {
|
||||
.swap_xy = 0,
|
||||
.mirror_x = 0,
|
||||
.mirror_y = 0,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_cst816(BOARD_TOUCH_I2C_NUM, &tp_cfg, &tp));
|
||||
|
||||
lv_indev_t *indev = lv_indev_create();
|
||||
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
|
||||
lv_indev_set_display(indev, display);
|
||||
lv_indev_set_user_data(indev, tp);
|
||||
lv_indev_set_read_cb(indev, lvgl_touch_read_cb);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
esp_err_t touch_init(lv_display_t *display)
|
||||
{
|
||||
(void)display;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
esp_err_t touch_init(lv_display_t *display);
|
||||
Reference in New Issue
Block a user