From fc03cedf66a07522a34de0aff651dfea03d1f67d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=A8=E9=9C=96=E9=93=83?= Date: Mon, 29 Jun 2026 22:27:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=B8=8E=E4=BB=A3=E7=A0=81=E4=BB=A5=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=20ESP-IDF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 .editorconfig 以统一 C++ 代码格式 - 更新 c_cpp_properties.json 中的编译器路径,适配 Windows 环境 - 修改 settings.json 中的 IDF 设置路径,反映新的环境配置 - 将 dependencies.lock 中的 IDF 版本降级至 6.0.1 以保证稳定性 - 在 CMakeLists.txt 中补充缺失的 esp_driver_ledc 依赖 - 清理 idf_component.yml,移除已注释的依赖项 - 重新整理 main.c 中的头文件包含,提升可读性与结构清晰度 - 在 main.c 中实现 LCD 背光控制,加入 PWM 配置 - 增强 LVGL 集成,更新屏幕刷新与触摸回调函数 - 改进 main.c 中的 WiFi 初始化与事件处理逻辑 --- .editorconfig | 59 +++ .vscode/c_cpp_properties.json | 2 +- .vscode/settings.json | 9 +- dependencies.lock | 2 +- main/CMakeLists.txt | 2 +- main/idf_component.yml | 3 - main/main.c | 796 ++++++++++++++++++---------------- 7 files changed, 483 insertions(+), 390 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1639887 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,59 @@ +[*] +cpp_indent_braces=false +cpp_indent_multi_line_relative_to=innermost_parenthesis +cpp_indent_within_parentheses=indent +cpp_indent_preserve_within_parentheses=false +cpp_indent_case_labels=false +cpp_indent_case_contents=true +cpp_indent_case_contents_when_block=false +cpp_indent_lambda_braces_when_parameter=true +cpp_indent_goto_labels=one_left +cpp_indent_preprocessor=leftmost_column +cpp_indent_access_specifiers=false +cpp_indent_namespace_contents=true +cpp_indent_preserve_comments=false +cpp_new_line_before_open_brace_namespace=ignore +cpp_new_line_before_open_brace_type=ignore +cpp_new_line_before_open_brace_function=ignore +cpp_new_line_before_open_brace_block=ignore +cpp_new_line_before_open_brace_lambda=ignore +cpp_new_line_scope_braces_on_separate_lines=false +cpp_new_line_close_brace_same_line_empty_type=false +cpp_new_line_close_brace_same_line_empty_function=false +cpp_new_line_before_catch=true +cpp_new_line_before_else=true +cpp_new_line_before_while_in_do_while=false +cpp_space_before_function_open_parenthesis=remove +cpp_space_within_parameter_list_parentheses=false +cpp_space_between_empty_parameter_list_parentheses=false +cpp_space_after_keywords_in_control_flow_statements=true +cpp_space_within_control_flow_statement_parentheses=false +cpp_space_before_lambda_open_parenthesis=false +cpp_space_within_cast_parentheses=false +cpp_space_after_cast_close_parenthesis=false +cpp_space_within_expression_parentheses=false +cpp_space_before_block_open_brace=true +cpp_space_between_empty_braces=false +cpp_space_before_initializer_list_open_brace=false +cpp_space_within_initializer_list_braces=true +cpp_space_preserve_in_initializer_list=true +cpp_space_before_open_square_bracket=false +cpp_space_within_square_brackets=false +cpp_space_before_empty_square_brackets=false +cpp_space_between_empty_square_brackets=false +cpp_space_group_square_brackets=true +cpp_space_within_lambda_brackets=false +cpp_space_between_empty_lambda_brackets=false +cpp_space_before_comma=false +cpp_space_after_comma=true +cpp_space_remove_around_member_operators=true +cpp_space_before_inheritance_colon=true +cpp_space_before_constructor_colon=true +cpp_space_remove_before_semicolon=true +cpp_space_after_semicolon=false +cpp_space_remove_around_unary_operator=true +cpp_space_around_binary_operator=insert +cpp_space_around_assignment_operator=insert +cpp_space_pointer_reference_alignment=left +cpp_space_around_ternary_operator=insert +cpp_wrap_preserve_blocks=one_liners diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 03c6ac3..195091b 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,7 +2,7 @@ "configurations": [ { "name": "ESP-IDF", - "compilerPath": "/Users/yulinling/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20260121/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc", + "compilerPath": "C:\\Espressif\\tools\\xtensa-esp-elf\\esp-15.2.0_20251204\\xtensa-esp-elf\\bin\\xtensa-esp32-elf-gcc", "compileCommands": "${config:idf.buildPath}/compile_commands.json", "intelliSenseMode": "gcc-x86", "includePath": [ diff --git a/.vscode/settings.json b/.vscode/settings.json index 46771b6..bfcf6e9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,15 +5,16 @@ "board/esp32s3-builtin.cfg" ], "idf.port": "/dev/ttyACM0", - "idf.currentSetup": "/opt/esp/idf", + "idf.currentSetup": "C:\\esp\\v6.0.1\\esp-idf", "idf.customExtraVars": { "IDF_TARGET": "esp32s3" }, - "clangd.path": "/Users/yulinling/.espressif/tools/esp-clang/esp-19.1.2_20250312/esp-clang/bin/clangd", + "clangd.path": "C:\\Espressif\\tools\\xtensa-esp-elf\\esp-15.2.0_20251204\\esp-clang/bin/clangd", "clangd.arguments": [ "--background-index", "--query-driver=**", - "--compile-commands-dir=/Users/yulinling/work/work-hardware/HeavenlyHeroStar/build" + "--compile-commands-dir=C:\\Users\\yulinling\\work\\work-hardware\\HeavenlyHeroStar\\build" ], - "idf.flashType": "UART" + "idf.flashType": "UART", + "idf.portWin": "COM5" } diff --git a/dependencies.lock b/dependencies.lock index e9b52a7..e3ac29b 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -40,7 +40,7 @@ dependencies: idf: source: type: idf - version: 6.2.0 + version: 6.0.1 lvgl/lvgl: component_hash: b702d642e03e95928046d5c6726558e6444e112420c77efa5fdb6650b0a13c5d dependencies: [] diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 294df87..096eb78 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "main.c" "lvgl_demo_ui.c" - PRIV_REQUIRES esp_wifi nvs_flash + PRIV_REQUIRES esp_wifi nvs_flash esp_driver_ledc INCLUDE_DIRS ".") diff --git a/main/idf_component.yml b/main/idf_component.yml index 0251d87..aa0d884 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -2,9 +2,6 @@ dependencies: lvgl/lvgl: 9.3.0 esp_lcd_touch_stmpe610: ^1.0.0 atanisoft/esp_lcd_touch_xpt2046: 1.0.6 - # esp_lcd_touch_cst816: - # version: "^1.0.0" - # public: true espressif/esp_wifi_remote: version: ">=0.10,<2.0" rules: diff --git a/main/main.c b/main/main.c index d875c4f..dc5c4de 100644 --- a/main/main.c +++ b/main/main.c @@ -6,42 +6,48 @@ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#include -#include -#include -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_timer.h" +#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_vendor.h" #include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_st7789.h" -#include "driver/gpio.h" -#include "driver/spi_master.h" -#include "driver/i2c.h" -#include "esp_err.h" +#include "esp_lcd_panel_vendor.h" #include "esp_log.h" -#include "lvgl.h" #include "esp_system.h" +#include "esp_timer.h" #include "esp_wifi.h" -#include "esp_event.h" -#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "lvgl.h" #include "nvs_flash.h" +#include +#include +#include +#include +#include #include "lwip/err.h" #include "lwip/sys.h" -/* The examples use WiFi configuration that you can set via project configuration menu +/* 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 +#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 @@ -78,63 +84,67 @@ #endif // Using SPI2 in the example -#define LCD_HOST SPI2_HOST +#define LCD_HOST SPI2_HOST //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// Please update the following configuration according to your LCD spec ////////////////////////////// +//////////////////// 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_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 +#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 +#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 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 +#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 +#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_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_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 -#define EXAMPLE_LVGL_TASK_STACK_SIZE (4 * 1024) -#define EXAMPLE_LVGL_TASK_PRIORITY 2 +#define EXAMPLE_LVGL_TASK_STACK_SIZE (4 * 1024) +#define EXAMPLE_LVGL_TASK_PRIORITY 2 -// LVGL library is not thread-safe, this example will call LVGL APIs from different tasks, so use a mutex to protect it +// 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: +/* 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 +#define WIFI_FAIL_BIT BIT1 static const char *TAG = "example"; // static const char *TAG = "wifi station"; @@ -143,348 +153,374 @@ static int s_retry_num = 0; extern void example_lvgl_demo_ui(lv_disp_t *disp); -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; +/** + * @brief 设置 LCD 背光亮度 + * @param brightness 亮度值 0-1023(0=灭, 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)); } -/* 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 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; } -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); +/* 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; +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); + 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; - } + 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_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, - /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8). - * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value - * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to - * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards. - */ - .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."); - - /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum - * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ - EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, - WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, - pdFALSE, - pdFALSE, - portMAX_DELAY); - - /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually - * happened. */ - if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); - } else if (bits & WIFI_FAIL_BIT) { - ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); - } else { - ESP_LOGE(TAG, "UNEXPECTED EVENT"); - } -} - -void app_main(void) -{ - //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(); - - 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, "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, true, 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); - - 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, "Display LVGL Meter Widget"); - // Lock the mutex due to the LVGL APIs are not thread-safe +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); - example_lvgl_demo_ui(display); + 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, "Display LVGL Meter Widget"); + // Lock the mutex due to the LVGL APIs are not thread-safe + _lock_acquire(&lvgl_api_lock); + example_lvgl_demo_ui(display); + _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(); }