Files
HeavenlyHeroStar/main/main.c
T
rsgltzyd b0ba814625 feat: 增强用户界面组件与功能
- 在 CMakeLists.txt 中添加新的源文件和依赖项以支持 UI 组件
- 新增 ui.c、ui_helpers.c、ui_events.h、ui.h、screens/ui_Screen1.c 和相关头文件,构建用户界面
- 更新 main.c 以初始化 UI 组件并调整 LVGL 任务栈大小
- 引入新的屏幕和控件,提升用户交互体验
- 添加 project.info 文件以记录项目元数据
2026-06-30 18:07:17 +08:00

577 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* WiFi station Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "driver/ledc.h"
#include "driver/spi_master.h"
#include "esp_err.h"
#include "esp_event.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_st7789.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_timer.h"
#include "esp_wifi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"
#include "lvgl.h"
#include "nvs_flash.h"
#include <stdio.h>
#include <string.h>
#include <sys/lock.h>
#include <sys/param.h>
#include <unistd.h>
#include "lwip/err.h"
#include "lwip/sys.h"
#include "ui.h"
/* The examples use WiFi configuration that you can set via project
configuration menu
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY
// 在文件顶部定义 PWM 参数
#define EXAMPLE_LCD_BK_LIGHT_CH LEDC_CHANNEL_0
#define EXAMPLE_LCD_BK_LIGHT_TIMER LEDC_TIMER_0
#define EXAMPLE_LCD_BK_LIGHT_FREQ (5000) // 5KHz PWM 频率
#if CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_HUNT_AND_PECK
#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_HUNT_AND_PECK
#define EXAMPLE_H2E_IDENTIFIER ""
#elif CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_HASH_TO_ELEMENT
#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_HASH_TO_ELEMENT
#define EXAMPLE_H2E_IDENTIFIER CONFIG_ESP_WIFI_PW_ID
#elif CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_BOTH
#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_BOTH
#define EXAMPLE_H2E_IDENTIFIER CONFIG_ESP_WIFI_PW_ID
#endif
#if CONFIG_ESP_WIFI_AUTH_OPEN
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
#elif CONFIG_ESP_WIFI_AUTH_WEP
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
#endif
#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_STMPE610
#include "esp_lcd_touch_stmpe610.h"
#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_XPT2046
#include "esp_lcd_touch_xpt2046.h"
#endif
// Using SPI2 in the example
#define LCD_HOST SPI2_HOST
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// Please update the following configuration according to your
/// LCD spec //////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000)
#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL 1
#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL
// LCD SPI 管脚(根据实际开发板)
#define EXAMPLE_PIN_NUM_SCLK 10
#define EXAMPLE_PIN_NUM_MOSI 13
#define EXAMPLE_PIN_NUM_MISO -1 // LCD 不需要 MISO
#define EXAMPLE_PIN_NUM_LCD_DC 11
#define EXAMPLE_PIN_NUM_LCD_RST 9
#define EXAMPLE_PIN_NUM_LCD_CS 12
#define EXAMPLE_PIN_NUM_BK_LIGHT 14 // 背光 PWM
#define EXAMPLE_PIN_NUM_TOUCH_CS 15
// 触摸屏 - 改为 I2C 接口
#define EXAMPLE_PIN_NUM_TOUCH_SDA 47
#define EXAMPLE_PIN_NUM_TOUCH_SCL 48
#define EXAMPLE_PIN_NUM_TOUCH_RST 17
#define EXAMPLE_PIN_NUM_TOUCH_INT 21
// 用户按键和 LED
#define EXAMPLE_PIN_NUM_KEY 4
#define EXAMPLE_PIN_NUM_LED 16
#define TOUCH_I2C_MASTER_NUM I2C_NUM_0
#define TOUCH_I2C_MASTER_FREQ_HZ 400000
// The pixel number in horizontal and vertical
#define EXAMPLE_LCD_H_RES 240
#define EXAMPLE_LCD_V_RES 320
// Bit number used to represent command and parameter
#define EXAMPLE_LCD_CMD_BITS 8
#define EXAMPLE_LCD_PARAM_BITS 8
#define EXAMPLE_LVGL_DRAW_BUF_LINES \
20 // number of display lines in each draw buffer
#define EXAMPLE_LVGL_TICK_PERIOD_MS 2
#define EXAMPLE_LVGL_TASK_MAX_DELAY_MS 500
#define EXAMPLE_LVGL_TASK_MIN_DELAY_MS 1000 / CONFIG_FREERTOS_HZ
// 8KB stack size for LVGL task
#define EXAMPLE_LVGL_TASK_STACK_SIZE (8 * 1024)
#define EXAMPLE_LVGL_TASK_PRIORITY 2
// 开启触摸屏支持
#define CONFIG_EXAMPLE_LCD_TOUCH_ENABLED 0
// 添加 CST816 驱动代码
#define CST816_I2C_ADDR 0x15
typedef struct {
uint16_t x;
uint16_t y;
uint8_t touched;
} cst816_data_t;
static bool cst816_read_touch(cst816_data_t *data) {
uint8_t reg = 0x02; // 触摸点数寄存器
uint8_t buffer[5];
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (CST816_I2C_ADDR << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (CST816_I2C_ADDR << 1) | I2C_MASTER_READ, true);
i2c_master_read_byte(cmd, buffer, I2C_MASTER_ACK);
i2c_master_read_byte(cmd, buffer + 1, I2C_MASTER_ACK);
i2c_master_read_byte(cmd, buffer + 2, I2C_MASTER_ACK);
i2c_master_read_byte(cmd, buffer + 3, I2C_MASTER_ACK);
i2c_master_read_byte(cmd, buffer + 4, I2C_MASTER_NACK);
i2c_master_stop(cmd);
esp_err_t ret =
i2c_master_cmd_begin(TOUCH_I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100));
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
return false;
}
data->touched = buffer[0] > 0;
if (data->touched) {
data->x = ((buffer[1] & 0x0F) << 8) | buffer[2];
data->y = ((buffer[3] & 0x0F) << 8) | buffer[4];
return true;
}
return false;
}
// LVGL library is not thread-safe, this example will call LVGL APIs from
// different tasks, so use a mutex to protect it
static _lock_t lvgl_api_lock;
/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event, but we only care about
* two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static const char *TAG = "example";
// static const char *TAG = "wifi station";
static int s_retry_num = 0;
// extern void example_lvgl_demo_ui(lv_disp_t *disp);
/**
* @brief 设置 LCD 背光亮度
* @param brightness 亮度值 0-10230=灭, 1023=最亮)
*/
void lcd_backlight_set_brightness(uint16_t brightness) {
if (brightness > 1023)
brightness = 1023;
ESP_ERROR_CHECK(
ledc_set_duty(LEDC_LOW_SPEED_MODE, EXAMPLE_LCD_BK_LIGHT_CH, brightness));
ESP_ERROR_CHECK(
ledc_update_duty(LEDC_LOW_SPEED_MODE, EXAMPLE_LCD_BK_LIGHT_CH));
}
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) {
lv_display_t *disp = (lv_display_t *)user_ctx;
lv_display_flush_ready(disp);
return false;
}
/* Rotate display and touch, when rotated screen in LVGL. Called when driver
* parameters are updated. */
static void example_lvgl_port_update_callback(lv_display_t *disp) {
esp_lcd_panel_handle_t panel_handle = lv_display_get_user_data(disp);
lv_display_rotation_t rotation = lv_display_get_rotation(disp);
switch (rotation) {
case LV_DISPLAY_ROTATION_0:
// Rotate LCD display
esp_lcd_panel_swap_xy(panel_handle, false);
esp_lcd_panel_mirror(panel_handle, true, false);
break;
case LV_DISPLAY_ROTATION_90:
// Rotate LCD display
esp_lcd_panel_swap_xy(panel_handle, true);
esp_lcd_panel_mirror(panel_handle, true, true);
break;
case LV_DISPLAY_ROTATION_180:
// Rotate LCD display
esp_lcd_panel_swap_xy(panel_handle, false);
esp_lcd_panel_mirror(panel_handle, false, true);
break;
case LV_DISPLAY_ROTATION_270:
// Rotate LCD display
esp_lcd_panel_swap_xy(panel_handle, true);
esp_lcd_panel_mirror(panel_handle, false, false);
break;
}
}
static void example_lvgl_flush_cb(lv_display_t *disp, const lv_area_t *area,
uint8_t *px_map) {
// example_lvgl_port_update_callback(disp);
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;
// because SPI LCD is big-endian, we need to swap the RGB bytes order
lv_draw_sw_rgb565_swap(px_map,
(offsetx2 + 1 - offsetx1) * (offsety2 + 1 - offsety1));
// copy a buffer's content to a specific area of the display
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1,
offsety2 + 1, px_map);
}
#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED
static void example_lvgl_touch_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);
/* Get coordinates */
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;
}
}
#endif
static void example_increase_lvgl_tick(void *arg) {
/* Tell LVGL how many milliseconds has elapsed */
lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS);
}
static void example_lvgl_port_task(void *arg) {
ESP_LOGI(TAG, "Starting LVGL task");
uint32_t time_till_next_ms = 0;
while (1) {
_lock_acquire(&lvgl_api_lock);
time_till_next_ms = lv_timer_handler();
_lock_release(&lvgl_api_lock);
// in case of triggering a task watch dog time out
time_till_next_ms = MAX(time_till_next_ms, EXAMPLE_LVGL_TASK_MIN_DELAY_MS);
// in case of lvgl display not ready yet
time_till_next_ms = MIN(time_till_next_ms, EXAMPLE_LVGL_TASK_MAX_DELAY_MS);
usleep(1000 * time_till_next_ms);
}
}
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT &&
event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
} else {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
ESP_LOGI(TAG, "connect to the AP fail");
}
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifi_init_sta(void) {
s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(
WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(
IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
wifi_config_t wifi_config = {
.sta =
{
.ssid = EXAMPLE_ESP_WIFI_SSID,
.password = EXAMPLE_ESP_WIFI_PASS,
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = ESP_WIFI_SAE_MODE,
.sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished. Connecting to AP in background...");
}
void app_main(void) {
esp_log_level_set("*", ESP_LOG_INFO);
// ESP_LOGI(TAG, "Turn off LCD backlight");
// gpio_config_t bk_gpio_config = {
// .mode = GPIO_MODE_OUTPUT,
// .pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_BK_LIGHT};
// ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
ESP_LOGI(TAG, "Configure LCD backlight PWM");
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.timer_num = EXAMPLE_LCD_BK_LIGHT_TIMER,
.duty_resolution = LEDC_TIMER_10_BIT, // 10位分辨率 (0-1023)
.freq_hz = EXAMPLE_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 = EXAMPLE_LCD_BK_LIGHT_CH,
.timer_sel = EXAMPLE_LCD_BK_LIGHT_TIMER,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = EXAMPLE_PIN_NUM_BK_LIGHT,
.duty = 0, // 初始为 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 = EXAMPLE_PIN_NUM_SCLK,
.mosi_io_num = EXAMPLE_PIN_NUM_MOSI,
.miso_io_num = EXAMPLE_PIN_NUM_MISO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = EXAMPLE_LCD_H_RES * 80 * sizeof(uint16_t),
};
ESP_ERROR_CHECK(spi_bus_initialize(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 = EXAMPLE_PIN_NUM_LCD_DC,
.cs_gpio_num = EXAMPLE_PIN_NUM_LCD_CS,
.pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
.spi_mode = 0,
.trans_queue_depth = 10,
};
// Attach the LCD to the SPI bus
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(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 = EXAMPLE_PIN_NUM_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));
// user can flush pre-defined pattern to the screen before we turn on the
// screen or backlight
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
ESP_LOGI(TAG, "Turn on LCD backlight");
gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_ON_LEVEL);
// 设置背光亮度为 100%(占空比 1023/1023
// lcd_backlight_set_brightness(1023);
// lcd_backlight_set_brightness(1023);
// while(1) {
// vTaskDelay(pdMS_TO_TICKS(1000));
// }
// ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, EXAMPLE_LCD_BK_LIGHT_CH,
// 1023)); ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE,
// EXAMPLE_LCD_BK_LIGHT_CH));
ESP_LOGI(TAG, "Initialize LVGL library");
lv_init();
// create a lvgl display
lv_display_t *display =
lv_display_create(EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES);
// alloc draw buffers used by LVGL
// it's recommended to choose the size of the draw buffer(s) to be at least
// 1/10 screen sized
size_t draw_buffer_sz =
EXAMPLE_LCD_H_RES * EXAMPLE_LVGL_DRAW_BUF_LINES * sizeof(lv_color16_t);
void *buf1 = spi_bus_dma_memory_alloc(LCD_HOST, draw_buffer_sz, 0);
assert(buf1);
void *buf2 = spi_bus_dma_memory_alloc(LCD_HOST, draw_buffer_sz, 0);
assert(buf2);
// initialize LVGL draw buffers
lv_display_set_buffers(display, buf1, buf2, draw_buffer_sz,
LV_DISPLAY_RENDER_MODE_PARTIAL);
// associate the mipi panel handle to the display
lv_display_set_user_data(display, panel_handle);
// set color depth
lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB565);
// set the callback which can copy the rendered image to an area of the
// display
lv_display_set_flush_cb(display, example_lvgl_flush_cb);
ESP_LOGI(TAG, "Install LVGL tick timer");
// Tick interface for LVGL (using esp_timer to generate 2ms periodic event)
const esp_timer_create_args_t lvgl_tick_timer_args = {
.callback = &example_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,
EXAMPLE_LVGL_TICK_PERIOD_MS * 1000));
ESP_LOGI(
TAG,
"Register io panel event callback for LVGL flush ready notification");
const esp_lcd_panel_io_callbacks_t cbs = {
.on_color_trans_done = example_notify_lvgl_flush_ready,
};
/* Register done callback */
ESP_ERROR_CHECK(
esp_lcd_panel_io_register_event_callbacks(io_handle, &cbs, display));
#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED
// 仅在触摸启用时初始化 I2C
ESP_LOGI(TAG, "Initialize I2C for touch");
i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = EXAMPLE_PIN_NUM_TOUCH_SDA,
.scl_io_num = EXAMPLE_PIN_NUM_TOUCH_SCL,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = TOUCH_I2C_MASTER_FREQ_HZ,
};
ESP_ERROR_CHECK(i2c_param_config(TOUCH_I2C_MASTER_NUM, &i2c_conf));
ESP_ERROR_CHECK(
i2c_driver_install(TOUCH_I2C_MASTER_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 = EXAMPLE_LCD_H_RES,
.y_max = EXAMPLE_LCD_V_RES,
.rst_gpio_num = EXAMPLE_PIN_NUM_TOUCH_RST,
.int_gpio_num = EXAMPLE_PIN_NUM_TOUCH_INT,
.flags =
{
.swap_xy = 0,
.mirror_x = 0,
.mirror_y = 0,
},
};
// CST816 使用 I2C 接口
ESP_ERROR_CHECK(
esp_lcd_touch_new_i2c_cst816(TOUCH_I2C_MASTER_NUM, &tp_cfg, &tp));
static lv_indev_t *indev;
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, example_lvgl_touch_cb);
#endif
ESP_LOGI(TAG, "Create LVGL task");
xTaskCreate(example_lvgl_port_task, "LVGL", EXAMPLE_LVGL_TASK_STACK_SIZE,
NULL, EXAMPLE_LVGL_TASK_PRIORITY, NULL);
ESP_LOGI(TAG, "Lock the mutex due to the LVGL APIs are not thread-safe");
// Lock the mutex due to the LVGL APIs are not thread-safe
_lock_acquire(&lvgl_api_lock);
// example_lvgl_demo_ui(display);
ui_init();
_lock_release(&lvgl_api_lock);
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
if (CONFIG_LOG_MAXIMUM_LEVEL > CONFIG_LOG_DEFAULT_LEVEL) {
/* If you only want to open more logs in the wifi module, you need to make
* the max level greater than the default level, and call
* esp_log_level_set() before esp_wifi_init() to improve the log level of
* the wifi module. */
esp_log_level_set("wifi", CONFIG_LOG_MAXIMUM_LEVEL);
}
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
wifi_init_sta();
}