#include "screen_init.h" #include "config.h" #include "LVGL/lvgl_init.h" #include "driver/i2c_master.h" const char *TAG_LVGL = "lvgl_init";//打印标签 #if EXAMPLE_USE_TOUCH esp_lcd_touch_handle_t tp = NULL; bool is_anim_paused = false; i2c_master_bus_handle_t touch_bus_handle_touch; // 定义触摸屏I2C总线句柄(全局,供BMI270共享) #endif static void read_lcd_id(esp_lcd_panel_io_handle_t read_io) { uint8_t id_buf[3] = {0}; esp_err_t ret = esp_lcd_panel_io_rx_param(read_io, 0x03000400, id_buf, 3); if (ret == ESP_OK) { ESP_LOGI(TAG_LVGL, "LCD ID: %02X %02X %02X", id_buf[0], id_buf[1], id_buf[2]); } else { ESP_LOGE(TAG_LVGL, "Read ID failed: %s", esp_err_to_name(ret)); } uint8_t id1 = 0; uint8_t id2 = 0; uint8_t id3 = 0; esp_err_t ret1 = esp_lcd_panel_io_rx_param(read_io, 0x0300DA00, &id1, 1); esp_err_t ret2 = esp_lcd_panel_io_rx_param(read_io, 0x0300DB00, &id2, 1); esp_err_t ret3 = esp_lcd_panel_io_rx_param(read_io, 0x0300DC00, &id3, 1); if (ret1 == ESP_OK && ret2 == ESP_OK && ret3 == ESP_OK) { ESP_LOGI(TAG_LVGL, "LCD RDID: %02X %02X %02X", id1, id2, id3); } else { ESP_LOGE(TAG_LVGL, "Read RDID failed: %s %s %s", esp_err_to_name(ret1), esp_err_to_name(ret2), esp_err_to_name(ret3)); } } /* const qspi_amoled_lcd_init_cmd_t lcd_init_cmds[13] = { {0xFE, (uint8_t[]){0x00}, 1, 0}, {0xC4, (uint8_t[]){0x80}, 1, 0}, {0x35, (uint8_t[]){0x00}, 1, 0}, {0x3A, (uint8_t[]){0x77}, 1, 0}, {0x53, (uint8_t[]){0x20}, 1, 0}, {0x51, (uint8_t[]){0x00}, 1, 0}, {0x63, (uint8_t[]){0xFF}, 1, 0}, {0x2A, (uint8_t[]){0x00, 0x16, 0x01, 0xAF}, 4, 0}, {0x2B, (uint8_t[]){0x00, 0x00, 0x01, 0xF5}, 4, 0}, {0x11, (uint8_t[]){0x00}, 0, 120}, {0x29, (uint8_t[]){0x00}, 0, 60}, {0x58, (uint8_t[]){0x07}, 1, 10}, {0x36, (uint8_t[]){0xA8}, 1, 0}, }; */ const qspi_amoled_lcd_init_cmd_t lcd_init_cmds[] = { // 0x11: 退出睡眠模式(Sleep Out),之后延时 60ms {0x11, (uint8_t[]){0x00}, 0, 60}, // 0x2A: 列地址范围 0~239(0x00 0x00 ~ 0x00 0xEF) {0x2A, (uint8_t[]){0x00, 0x00, 0x00, 0xEF}, 4, 0}, // 0x2B: 行地址范围 0~295(0x00 0x00 ~ 0x01 0x27) {0x2B, (uint8_t[]){0x00, 0x00, 0x01, 0x27}, 4, 0}, // 0x44: 撕裂效应行(TE Line)设为 295 {0x44, (uint8_t[]){0x01, 0x27}, 2, 0}, // 0x3A: 像素格式(Pixel Format)0x55(通常为 16bit/18bit) {0x3A, (uint8_t[]){0x55}, 1, 0}, // 0x35: TE 信号控制,0x00 = 关闭 {0x35, (uint8_t[]){0x00}, 1, 0}, // 0x53: 亮度控制寄存器,设为 0x20 {0x53, (uint8_t[]){0x20}, 1, 0}, // 0x51: 亮度值设为最高 0xFF,之后延时 60ms 再开启显示 {0x51, (uint8_t[]){0xFF}, 1, 60}, // 0x29: 开启显示(Display On),无需额外延时 {0x29, (uint8_t[]){0x00}, 0, 0}, }; // QSPI AMOLED供应商配置 qspi_amoled_vendor_config_t vendor_config = { .init_cmds = lcd_init_cmds, .init_cmds_size = sizeof(lcd_init_cmds) / sizeof(lcd_init_cmds[0]), .flags = { .use_qspi_interface = 1, }, }; // LCD面板配置 const esp_lcd_panel_dev_config_t panel_config = { .reset_gpio_num = EXAMPLE_PIN_NUM_LCD_RST, .rgb_ele_order = LCD_RGB_ELEMENT_ORDER, .bits_per_pixel = LCD_BIT_PER_PIXEL, .vendor_config = &vendor_config, }; extern esp_lcd_panel_io_handle_t io_handle; void read_co5300_response(void) { } esp_err_t app_lcd_init(void)//QSPI初始化 { esp_err_t ret = ESP_OK; ESP_LOGI(TAG_LVGL, "Initialize QSPI bus"); // 使用原始的SPI总线最大传输大小,确保稳定传输 const spi_bus_config_t buscfg = QSPI_AMOLED_PANEL_BUS_QSPI_CONFIG(EXAMPLE_PIN_NUM_LCD_PCLK, EXAMPLE_PIN_NUM_LCD_DATA0, EXAMPLE_PIN_NUM_LCD_DATA1, EXAMPLE_PIN_NUM_LCD_DATA2, EXAMPLE_PIN_NUM_LCD_DATA3, (EXAMPLE_LCD_H_RES * EXAMPLE_LVGL_BUF_HEIGHT * LCD_BIT_PER_PIXEL / 8) + 64); ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO)); ESP_LOGI(TAG_LVGL, "Install panel IO"); esp_lcd_panel_io_spi_config_t io_config = { .cs_gpio_num = EXAMPLE_PIN_NUM_LCD_CS, .dc_gpio_num = -1, .spi_mode = AMOLED_QSPI_MODE, .pclk_hz = AMOLED_QSPI_MAX_PCLK, .trans_queue_depth = 3, .on_color_trans_done = example_notify_lvgl_flush_ready, .user_ctx = NULL, .lcd_cmd_bits = 32, .lcd_param_bits = 8, .flags = { .quad_mode = true, }, }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io_handle)); ESP_LOGI(TAG_LVGL, "Install QSPI_AMOLED panel driver"); ESP_ERROR_CHECK(esp_lcd_new_panel_qspi_amoled(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_set_gap(panel_handle, EXAMPLE_LCD_X_GAP, EXAMPLE_LCD_Y_GAP)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); /* 初始化时设置亮度为0,避免白光闪烁,等待 UI 加载后渐变亮屏 */ esp_err_t br = panel_qspi_amoled_set_brightness(panel_handle,100); //uint8_t read_buf[3] = {0}; // RDDID 返回 3 个字节 /* // 发送读指令 0x04,读取 3 个字节的回应数据 esp_err_t ret2 = esp_lcd_panel_io_rx_param(io_handle, 0x04, read_buf, 3); if (ret2 == ESP_OK) { ESP_LOGI("TAG", "读取回应成功!ID1: 0x%02X, ID2: 0x%02X, ID3: 0x%02X", read_buf[0], read_buf[1], read_buf[2]); // 根据数据手册,正常回应通常为:33h, 10h, 00h 或 33h, 11h, 00h } else { ESP_LOGE("TAG", "读取回应失败:%s", esp_err_to_name(ret2)); }*/ //read_lcd_id(io_handle); //ESP_LOGI(TAG_LVGL,"br=%d",br); //uint8_t blue_color[] = {0x00, 0x00, 0xFF}; //esp_err_t brt =panel_qspi_amoled_draw_bitmap(panel_handle, 0, 0, EXAMPLE_LCD_H_RES - 1, EXAMPLE_LCD_V_RES - 1, blue_color); /* if (br != ESP_OK) { ESP_LOGE(TAG_LVGL, "panel_qspi_amoled_set_brightness failed: %s", esp_err_to_name(br)); } else { ESP_LOGI(TAG_LVGL, "Screen brightness set to 0 (等待 UI 加载后渐变亮屏)"); } */ /* Register done callback */ //ESP_ERROR_CHECK(esp_lcd_panel_io_register_event_callbacks(io_handle, &cbs, disp)); return ret; } esp_err_t app_touch_init(void) { ESP_LOGI(TAG_LVGL, "初始化 I2C 总线 (新驱动模式)"); // 1. 配置 I2C 总线 i2c_master_bus_config_t i2c_bus_config = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TOUCH_HOST, .scl_io_num = EXAMPLE_PIN_NUM_TOUCH_SCL, .sda_io_num = EXAMPLE_PIN_NUM_TOUCH_SDA, .glitch_ignore_cnt = 7, .flags.enable_internal_pullup = true, }; ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &touch_bus_handle_touch)); // 2. 配置触摸面板 IO(这里会自动适配新驱动) esp_lcd_panel_io_handle_t tp_io_handle = NULL; const esp_lcd_panel_io_i2c_config_t tp_io_config = { .dev_addr = 0x15, // CST816/CST820 的默认地址,根据实际修改 .on_color_trans_done = NULL, .user_ctx = NULL, .control_phase_bytes = 1, .dc_bit_offset = 0, .lcd_cmd_bits = 8, .lcd_param_bits = 8, .scl_speed_hz = 400 * 1000, .flags = { .disable_control_phase = 1, }}; // 使用新总线句柄创建 IO ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c_v2(touch_bus_handle_touch, &tp_io_config, &tp_io_handle)); // 3. 配置触摸芯片参数 const 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, .levels = { .reset = 0, .interrupt = 0, }, .flags = { .swap_xy = 1, .mirror_x = 0, .mirror_y = 1, }, }; ESP_LOGI(TAG_LVGL, "创建触摸控制器句柄"); return esp_lcd_touch_new_i2c(tp_io_handle, &tp_cfg, &tp); }