#include "gpio.h" #include "esp_lvgl_port.h" #include "esp_lcd_st77916.h" #include "esp_err.h" #include "esp_log.h" #include "lcd.h" #include "esp_lcd_touch_cst816s.h" #include "unity.h" #include "unity_test_runner.h" static lv_disp_t * disp_handle = NULL; static esp_lcd_panel_handle_t panel_handle = NULL; static esp_lcd_panel_io_handle_t io_handle = NULL; static esp_lcd_touch_handle_t touch_handle; static esp_lcd_panel_io_handle_t tp_io_handle = NULL; void lcd_init(){ const spi_bus_config_t buscfg = ST77916_PANEL_BUS_QSPI_CONFIG(PIN_LCD_CLK, PIN_LCD_D0, PIN_LCD_D1, PIN_LCD_D2, PIN_LCD_D3, LCD_HIGH * 80 * sizeof(uint16_t)); spi_bus_initialize(SPI_LCD_HOST, &buscfg, SPI_DMA_CH_AUTO); const esp_lcd_panel_io_spi_config_t io_config = ST77916_PANEL_IO_QSPI_CONFIG(PIN_LCD_CS, NULL, NULL); ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)SPI_LCD_HOST, &io_config, &io_handle)); const st77916_vendor_config_t vendor_config = { .flags = { .use_qspi_interface = 1, }, }; const esp_lcd_panel_dev_config_t panel_config = { .reset_gpio_num = PIN_LCD_RST, .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, .bits_per_pixel = 16, .vendor_config = &vendor_config, }; ESP_ERROR_CHECK(esp_lcd_new_panel_st77916(io_handle, &panel_config, &panel_handle)); esp_lcd_panel_reset(panel_handle); esp_lcd_panel_init(panel_handle); esp_lcd_panel_disp_on_off(panel_handle, true); } // 初始化触摸控制器 void touch_init(){ const esp_lcd_touch_config_t tp_cfg = { .x_max = LCD_WID, .y_max = LCD_HIGH, .rst_gpio_num = PIN_TP_RST, .int_gpio_num = PIN_TP_INT, .levels = { .reset = 0,// 重置电平 .interrupt = 0,// 中断电平 }, .flags = { .swap_xy = false,// 交换XY轴 .mirror_x = false,// 水平镜像 .mirror_y = false,// 垂直镜像 }, }; const esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG(); esp_err_t err = esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_MASTER_NUM, &tp_io_config, &tp_io_handle); if (err != ESP_OK) { ESP_LOGE(LCD_TAG, "Failed to create I2C IO for touch: %s", esp_err_to_name(err)); return; } err = esp_lcd_touch_new_i2c_cst816s(tp_io_handle, &tp_cfg, &touch_handle); if (err != ESP_OK) { ESP_LOGE(LCD_TAG, "Failed to create touch handle: %s", esp_err_to_name(err)); return; } ESP_LOGI(LCD_TAG, "Touch controller initialized successfully"); } // 初始化LVGL显示和触摸 void lvgl_lcd_init(){ const lvgl_port_cfg_t lvgl_cfg = { .task_priority = 4, .task_stack = 8192, .task_affinity = -1, .task_max_sleep_ms = 500, .timer_period_ms = 5 }; lvgl_port_init(&lvgl_cfg); // 使用固定30行的缓冲区大小,参考QSPI LCD驱动版本 #define LVGL_DRAW_BUF_LINES 30 size_t buffer_size = LCD_WID * LVGL_DRAW_BUF_LINES; ESP_LOGI(LCD_TAG, "LVGL buffer size: %d bytes (W: %d, Lines: %d)", buffer_size * 2, LCD_WID, LVGL_DRAW_BUF_LINES); const lvgl_port_display_cfg_t disp_cfg = { .io_handle = io_handle, .panel_handle = panel_handle, .buffer_size = buffer_size, .double_buffer = true, .hres = LCD_WID, .vres = LCD_HIGH, .monochrome = false,// 单色显示 .rotation = { .swap_xy = false,// 交换XY轴 .mirror_x = false,// 水平镜像 .mirror_y = false,// 垂直镜像 }, .flags = { .buff_dma = true,// 使用DMA传输显示缓冲区 } }; disp_handle = lvgl_port_add_disp(&disp_cfg); if (touch_handle != NULL) { lvgl_port_touch_cfg_t touch_cgf = { .disp = disp_handle, .handle = touch_handle, }; lvgl_port_add_touch(&touch_cgf); ESP_LOGI(LCD_TAG, "Touch controller added to LVGL"); } else { ESP_LOGE(LCD_TAG, "Touch handle is NULL, skipping touch initialization"); } } void get_touch(uint16_t* touchx,uint16_t* touchy){ if (touch_handle == NULL) { ESP_LOGE(LCD_TAG, "Touch handle is NULL, cannot get touch data"); *touchx = 0; *touchy = 0; return; } uint8_t max = 1; max = touch_handle->data.points; *touchx = touch_handle->data.coords[0].x; *touchy = touch_handle->data.coords[0].y; printf("%x\n",max); }