Files
P4-USB-transfer/main/SCREEN/screen_init.c
T
zhengxinandCursor 851e347cf5 初始提交卡包 USB 工程
纳入固件源码、屏幕组件、nand_xfer 工具和文档。忽略本机构建产物、sdkconfig,以及含本机路径的依赖锁。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 21:54:50 +08:00

238 lines
8.4 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.
#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);
}