Files

238 lines
8.4 KiB
C
Raw Permalink Normal View History

2026-10-13 21:54:50 +08:00
#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);
}