Revert "Add support for LCD Wiki ES3C35P board configuration and files (#2112)"

This reverts commit ac3212d781.
This commit is contained in:
Xiaoxia
2026-07-23 03:55:23 +08:00
committed by GitHub
parent 324c8098a9
commit 0d0ea8c1c2
8 changed files with 2 additions and 577 deletions
-5
View File
@@ -868,11 +868,6 @@ elseif(CONFIG_BOARD_TYPE_AI_VOX3)
set(BUILTIN_TEXT_FONT font_noto_sans_basic_20_4)
set(BUILTIN_ICON_FONT font_material_symbols_20_4)
set(DEFAULT_EMOJI_COLLECTION noto-color-emoji_64)
elseif(CONFIG_BOARD_TYPE_LCDWIKI_ES3C35P)
set(BOARD_TYPE "lcdwiki-es3c35p")
set(BUILTIN_TEXT_FONT font_noto_sans_basic_20_4)
set(BUILTIN_ICON_FONT font_material_symbols_20_4)
set(DEFAULT_EMOJI_COLLECTION noto-color-emoji_128)
endif()
if(MANUFACTURER)
-3
View File
@@ -585,9 +585,6 @@ choice BOARD_TYPE
config BOARD_TYPE_AI_VOX3
bool "NULLLAB-AI-VOX3"
depends on IDF_TARGET_ESP32S3
config BOARD_TYPE_LCDWIKI_ES3C35P
bool "LCD Wiki ES3C35P (3.5寸 ESP32-S3)"
depends on IDF_TARGET_ESP32S3
endchoice
choice XIAOZHI_NETWORK_TYPE
-160
View File
@@ -1,160 +0,0 @@
# LCD Wiki ES3C35P
3.5 寸 ESP32-S3 智能显示模块
资料文档: [https://www.lcdwiki.com/zh/3.5inch_ESP32-S3_Display](https://www.lcdwiki.com/zh/3.5inch_ESP32-S3_Display)
## 产品规格
| 项目 | 参数 |
|------|------|
| SKU | ES3C35P (带喇叭) / ES3C35P-NS (无喇叭) |
| 主控芯片 | ESP32-S3 Xtensa LX7 双核 240MHz |
| 存储 | 16MB QSPI Flash + 8MB OPI PSRAM (N16R8) |
| 无线 | Wi-Fi 2.4GHz 802.11b/g/n, 蓝牙 5.0 BLE |
| 工作电压 | 5V (USB Type-C 供电) |
| 电池 | 支持 3.7V 锂电池, TP4054 充电管理 |
### 显示屏
| 项目 | 参数 |
|------|------|
| 屏幕类型 | 3.5" IPS TFT |
| 分辨率 | 320×480 像素 |
| 色彩 | 65K RGB565 |
| 驱动 IC | ST77922 TDDI (触显一体) |
| 显示接口 | QSPI (接 ESP32-S3) |
| 触摸屏 | 电容触摸 (全贴合), I2C 0x55 |
| 背光 | PWM 控制, 亮度 300 cd/m² |
### 音频
| 项目 | 参数 |
|------|------|
| 编解码芯片 | ES8311 |
| 功放 | FM8002E |
| 麦克风 | MEMS 麦克风 (LMA2718B381) |
| 音频接口 | I2S (双工: 输入+输出) |
| 采样率 | 输入/输出 24000Hz |
### 外设
| 项目 | 型号/接口 |
|------|-----------|
| RGB LED | WS2812B ×1 (IO40) |
| MicroSD | SDIO 4-bit |
| 充电管理 | TP4054, 电池 ADC (IO8) |
| 按键 | BOOT (IO0), RESET (EN) |
## 完整引脚分配
| GPIO | 功能 | 说明 |
|------|------|------|
| IO0 | BOOT 按键 | 开机按下=下载模式, 运行中=切换对话 |
| IO1 | PA 使能 | 低电平使能功放 |
| IO2 | SD D2 | SDIO DATA2 |
| IO3 | SD D3 | SDIO DATA3 |
| IO4 | SD CMD | SDIO 命令 |
| IO5 | SD CLK | SDIO 时钟 |
| IO6 | SD D0 | SDIO DATA0 |
| IO7 | SD D1 | SDIO DATA1 |
| IO8 | 电池 ADC | 电压检测 |
| IO9 | LCD D3 | QSPI 数据 D3 |
| IO10 | LCD CS | QSPI 片选 (低有效) |
| IO11 | LCD D0 | QSPI 数据 D0 |
| IO12 | LCD CLK | QSPI 时钟 |
| IO13 | LCD D1 | QSPI 数据 D1 |
| IO14 | LCD D2 | QSPI 数据 D2 |
| IO15 | I2S DOUT | 音频输出 |
| IO16 | I2S DIN | 音频输入 (MEMS 麦克风) |
| IO17 | I2S MCLK | I2S 主时钟 |
| IO18 | I2S BCLK | I2S 位时钟 |
| IO21 | I2S WS | I2S 左右声道 |
| IO38 | I2C SDA | 音频+触摸共用 |
| IO39 | I2C SCL | 音频+触摸共用 |
| IO40 | RGB LED | WS2812B 单线 |
| IO41 | 背光 | PWM 高电平点亮 |
| IO43 | UART RXD0 | 串口/普通 IO |
| IO44 | UART TXD0 | 串口/普通 IO |
| IO45 | GPIO45 | 扩展 IO |
| IO46 | GPIO46 | 扩展 IO |
| IO47 | 触摸 INT | 触摸中断 (低有效) |
| IO48 | 触摸 RST | 触摸复位 (低复位) |
| EN | LCD RST | 与 ESP32-S3 共用 |
### 显示 QSPI 引脚组
```
CS = IO10 D0 = IO11
CLK = IO12 D1 = IO13
D2 = IO14
D3 = IO9
```
### I2C 设备地址
| 设备 | 地址 | 总线 |
|------|------|------|
| ES8311 音频 | ES8311_CODEC_DEFAULT_ADDR | I2C0 |
| ST77922 触摸 | 0x55 | I2C0 (共享) |
## 编译
```bash
# 一键编译打包 (推荐)
python scripts/release.py lcdwiki-es3c35p
# 或手动编译
idf.py set-target esp32s3
idf.py menuconfig
# Xiaozhi Assistant -> Board Type -> LCD Wiki ES3C35P (3.5寸 ESP32-S3)
idf.py build flash monitor
```
## 关键配置说明
### 显示 ST77922 QSPI
| 配置项 | 值 | 原因 |
|--------|-----|------|
| `DISPLAY_WIDTH/HEIGHT` | 320×480 | 原生竖屏分辨率 |
| `DISPLAY_RGB_ORDER` | BGR | 面板实际色彩顺序 |
| `SPI_DMA_CH_AUTO` + `max_transfer_sz` | 51KB | SPI 总线 DMA,缓冲在 SRAM 避免 PSRAM 中转 |
| `buff_dma=1, buff_spiram=0` | SRAM DMA | SRAM 可直接 DMA 访问,无需中转缓冲 |
| `buffer_size` | width×80 (51KB) | 部分刷新缓冲 |
| `st77922_rounder_cb` | x 坐标 4 对齐 | ST77922 硬件要求,否则花屏 |
### 触摸 ST77922 内置
| 配置项 | 值 |
|--------|-----|
| I2C 地址 | 0x55 |
| 寄存器位宽 | 16 位 |
| 单点数据 | 7 字节 |
| 读取方式 | 必须一次性读 `7 × max_points` 字节清空缓冲 |
### 音频 ES8311
| 配置项 | 值 |
|--------|-----|
| PA 引脚 | IO1 |
| PA 极性 | 低电平使能 (`pa_inverted=true`) |
| I2C 总线 | I2C0 (与触摸共享 IO38/39) |
| 采样率 | 24000Hz 输入/输出 |
## 已知限制
1. **ST77922 不支持 `swap_xy`** — 只能使用原生 320×480 竖屏
2. **ST77922 要求 x 坐标 4 对齐** — 已通过 rounder_cb 自动处理
3. **触摸无 DMA/中断** — 使用轮询方式读取,约 30fps
4. **LVGL 缓冲在 SRAM** — 占用约 51KB,剩余 ~180KB 给其他模块
## 文件结构
```
main/boards/lcdwiki-es3c35p/
config.h — 引脚/硬件配置宏
config.json — 构建目标 (esp32s3, 16MB Flash)
lcdwiki-es3c35p.cc — 板级初始化 (QSPI 显示 + I2C 触摸 + ES8311 音频 + LED)
README.md — 本文档
```
-54
View File
@@ -1,54 +0,0 @@
#ifndef _BOARD_CONFIG_H_
#define _BOARD_CONFIG_H_
#include <driver/gpio.h>
#include <driver/spi_master.h>
#define AUDIO_INPUT_SAMPLE_RATE 24000
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_17
#define AUDIO_I2S_GPIO_WS GPIO_NUM_21
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_18
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_16
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_15
#define AUDIO_CODEC_PA_PIN GPIO_NUM_1
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_38
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_39
#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR
#define BUILTIN_LED_GPIO GPIO_NUM_40
#define BOOT_BUTTON_GPIO GPIO_NUM_0
#define VOLUME_UP_BUTTON_GPIO GPIO_NUM_NC
#define VOLUME_DOWN_BUTTON_GPIO GPIO_NUM_NC
#define DISPLAY_CS_PIN GPIO_NUM_10
#define DISPLAY_CLK_PIN GPIO_NUM_12
#define DISPLAY_DATA0_PIN GPIO_NUM_11
#define DISPLAY_DATA1_PIN GPIO_NUM_13
#define DISPLAY_DATA2_PIN GPIO_NUM_14
#define DISPLAY_DATA3_PIN GPIO_NUM_9
#define DISPLAY_RST_PIN GPIO_NUM_NC
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_41
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT false
#define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 480
#define DISPLAY_MIRROR_X false
#define DISPLAY_MIRROR_Y false
#define DISPLAY_SWAP_XY false
#define DISPLAY_RGB_ORDER LCD_RGB_ELEMENT_ORDER_BGR
#define DISPLAY_INVERT_COLOR false
#define DISPLAY_OFFSET_X 0
#define DISPLAY_OFFSET_Y 0
#define DISPLAY_BUFFER_LINES 80
#define DISPLAY_BUFFER_SIZE (DISPLAY_WIDTH * DISPLAY_BUFFER_LINES)
#define TOUCH_RST_PIN GPIO_NUM_48
#define TOUCH_INT_PIN GPIO_NUM_47
#endif // _BOARD_CONFIG_H_
-12
View File
@@ -1,12 +0,0 @@
{
"target": "esp32s3",
"builds": [
{
"name": "lcdwiki-es3c35p",
"sdkconfig_append": [
"CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y",
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/16m.csv\""
]
}
]
}
@@ -1,340 +0,0 @@
#include "wifi_board.h"
#include "codecs/es8311_audio_codec.h"
#include "display/lcd_display.h"
#include "application.h"
#include "button.h"
#include "config.h"
#include "mcp_server.h"
#include "led/single_led.h"
#include <esp_log.h>
#include <driver/i2c_master.h>
#include <driver/spi_common.h>
#include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h>
#include <esp_lcd_st77922.h>
#include <esp_lvgl_port.h>
#include <lvgl.h>
#define TAG "LCDWikiES3C35P"
// ---- ST77922 touch controller (I2C addr 0x55, FT6336G-compatible) ----
#define TOUCH_I2C_ADDR 0x55
#define TOUCH_REG_INFO 0x0010
#define TOUCH_REG_MAX_TOUCHES 0x0009
#define TOUCH_REG_POINT0 0x0014
static i2c_master_dev_handle_t touch_dev_handle = NULL;
static uint8_t touch_max_points = 1;
static esp_err_t touch_i2c_read(uint16_t reg, uint8_t *data, size_t len) {
if (touch_dev_handle == NULL) return ESP_FAIL;
uint8_t wbuf[2] = { (uint8_t)(reg >> 8), (uint8_t)(reg & 0xFF) };
return i2c_master_transmit_receive(touch_dev_handle, wbuf, 2, data, len, pdMS_TO_TICKS(100));
}
static void touchpad_read(lv_indev_t *, lv_indev_data_t *data) {
static int16_t last_x = 0, last_y = 0;
data->point.x = last_x;
data->point.y = last_y;
data->state = LV_INDEV_STATE_RELEASED;
if (touch_dev_handle == NULL) return;
uint8_t info;
if (touch_i2c_read(TOUCH_REG_INFO, &info, 1) != ESP_OK) return;
if (info & 0x08) {
uint8_t buf[7 * 5];
if (touch_i2c_read(TOUCH_REG_POINT0, buf, 7 * touch_max_points) == ESP_OK) {
for (int i = 0; i < touch_max_points; i++) {
if (buf[i * 7] & 0x80) {
int16_t x = ((buf[i * 7] & 0x3F) << 8) | buf[i * 7 + 1];
int16_t y = ((buf[i * 7 + 2] & 0x3F) << 8) | buf[i * 7 + 3];
// Ignore jitter < 4px to reduce unwanted scroll on tap
int16_t dx = x - last_x, dy = y - last_y;
if (dx > 3 || dx < -3 || dy > 3 || dy < -3) {
last_x = x;
last_y = y;
}
data->state = LV_INDEV_STATE_PRESSED;
break;
}
}
}
}
}
// ---- ST77922 init commands ----
static const st77922_lcd_init_cmd_t lcd_init_cmds[] = {
{0xF1, (uint8_t []){0x00}, 1, 0},
{0x60, (uint8_t []){0x00, 0x00, 0x00}, 3, 0},
{0x65, (uint8_t []){0x80}, 1, 0},
{0x79, (uint8_t []){0x06}, 1, 0},
{0x7B, (uint8_t []){0x00, 0x08, 0x08}, 3, 0},
{0x80, (uint8_t []){0x55, 0x62, 0x2F, 0x17, 0xF0, 0x52, 0x70, 0xD2, 0x52, 0x62, 0xEA}, 11, 0},
{0x81, (uint8_t []){0x26, 0x52, 0x72, 0x27}, 4, 0},
{0x84, (uint8_t []){0x92, 0x25}, 2, 0},
{0x87, (uint8_t []){0x10, 0x10, 0x58, 0x00, 0x02, 0x3A}, 6, 0},
{0x88, (uint8_t []){0x00, 0x00, 0x2C, 0x10, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x06}, 15, 0},
{0x89, (uint8_t []){0x00, 0x00, 0x00}, 3, 0},
{0x8A, (uint8_t []){0x13, 0x00, 0x2C, 0x00, 0x00, 0x2C, 0x10, 0x10, 0x00, 0x3E, 0x19}, 11, 0},
{0x8B, (uint8_t []){0x15, 0xB1, 0xB1, 0x44, 0x96, 0x2C, 0x10, 0x97, 0x8E}, 9, 0},
{0x8C, (uint8_t []){0x1D, 0xB1, 0xB1, 0x44, 0x96, 0x2C, 0x10, 0x50, 0x0F, 0x01, 0xC5, 0x12, 0x09}, 13, 0},
{0x8D, (uint8_t []){0x0C}, 1, 0},
{0x8E, (uint8_t []){0x33, 0x01, 0x0C, 0x13, 0x01, 0x01}, 6, 0},
{0xB3, (uint8_t []){0x00, 0x30}, 2, 0},
{0xF1, (uint8_t []){0x00}, 1, 0},
{0x71, (uint8_t []){0xD0}, 1, 0},
{0x66, (uint8_t []){0x02, 0x3F}, 2, 0},
{0xBE, (uint8_t []){0x26, 0x00, 0x9D}, 3, 0},
{0x70, (uint8_t []){0x01, 0xA0, 0x11, 0x40, 0xE0, 0x00, 0x11, 0x69, 0x11, 0x00, 0x00, 0x1A}, 12, 0},
{0x90, (uint8_t []){0x04, 0x04, 0x55, 0x74, 0x00, 0x40, 0x43, 0x27, 0x27}, 9, 0},
{0x91, (uint8_t []){0x04, 0x04, 0x55, 0x75, 0x00, 0x40, 0x42, 0x27, 0x27}, 9, 0},
{0x92, (uint8_t []){0x04, 0x44, 0x55, 0xC0, 0x06, 0x00, 0x07, 0x05, 0x90, 0x27}, 10, 0},
{0x93, (uint8_t []){0x04, 0x43, 0x11, 0x00, 0x00, 0x00, 0x00, 0x05, 0x90, 0x27}, 10, 0},
{0x94, (uint8_t []){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 6, 0},
{0x95, (uint8_t []){0x96, 0x16, 0x00, 0x00, 0xFF}, 5, 0},
{0x96, (uint8_t []){0x44, 0x53, 0x03, 0x12, 0x23, 0x24, 0x06, 0x05, 0x94, 0x27, 0x00, 0x44}, 12, 0},
{0x97, (uint8_t []){0x44, 0x53, 0x47, 0x56, 0x20, 0x20, 0x02, 0x01, 0x94, 0x27, 0x00, 0x44}, 12, 0},
{0xBA, (uint8_t []){0x55, 0x94, 0x2D, 0x94, 0x27}, 5, 0},
{0x9A, (uint8_t []){0x40, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00}, 7, 0},
{0x9B, (uint8_t []){0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00}, 7, 0},
{0x9C, (uint8_t []){0x5C, 0x12, 0x00, 0x00, 0x10, 0x12, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00}, 13, 0},
{0x9D, (uint8_t []){0x8A, 0x51, 0x00, 0x00, 0x00, 0x80, 0x1E, 0x01}, 8, 0},
{0x9E, (uint8_t []){0x51, 0x00, 0x00, 0x00, 0x80, 0x1E, 0x01}, 7, 0},
{0xB4, (uint8_t []){0x1D, 0x1C, 0x1E, 0x0B, 0x14, 0x02, 0x13, 0x09, 0x1E, 0x00, 0x1E, 0x10}, 12, 0},
{0xB5, (uint8_t []){0x1D, 0x1C, 0x1E, 0x0A, 0x15, 0x03, 0x11, 0x08, 0x1E, 0x01, 0x1E, 0x12}, 12, 0},
{0xB6, (uint8_t []){0x77, 0x77, 0x00, 0x0A, 0xFF, 0x0A, 0xFF}, 7, 0},
{0x86, (uint8_t []){0xCD, 0x04, 0xB1, 0x02, 0x58, 0x12, 0x58, 0x0C, 0x13, 0x01, 0xA5, 0x00, 0xA5, 0xA5}, 14, 0},
{0xB7, (uint8_t []){0x07, 0x0A, 0x0E, 0x06, 0x05, 0x03, 0x2B, 0x03, 0x03, 0x42, 0x07, 0x10, 0x10, 0x2E, 0x3F, 0x0D}, 16, 0},
{0xB8, (uint8_t []){0x07, 0x0A, 0x0D, 0x05, 0x05, 0x02, 0x2B, 0x02, 0x03, 0x42, 0x06, 0x10, 0x0F, 0x2E, 0x3F, 0x0D}, 16, 0},
{0xB9, (uint8_t []){0x23, 0x23}, 2, 0},
{0xBF, (uint8_t []){0x10, 0x14, 0x14, 0x0B, 0x0B, 0x0B}, 6, 0},
{0xF2, (uint8_t []){0x00}, 1, 0},
{0x73, (uint8_t []){0x04, 0xDA, 0x12, 0x54, 0x47}, 5, 0},
{0x77, (uint8_t []){0x6B, 0x5B, 0xFD, 0xC3, 0xC5}, 5, 0},
{0x7A, (uint8_t []){0x15, 0x27}, 2, 0},
{0x7B, (uint8_t []){0x04, 0x57}, 2, 0},
{0x7E, (uint8_t []){0x01, 0x0E}, 2, 0},
{0xBF, (uint8_t []){0x36}, 1, 0},
{0xE3, (uint8_t []){0x40, 0x40}, 2, 0},
{0xF0, (uint8_t []){0x00}, 1, 0},
{0xD0, (uint8_t []){0x00}, 1, 0},
{0x2A, (uint8_t []){0x00, 0x00, 0x01, 0x3F}, 4, 0},
{0x2B, (uint8_t []){0x00, 0x00, 0x01, 0xDF}, 4, 0},
{0x21, (uint8_t []){0x00}, 0, 0},
{0x11, (uint8_t []){0x00}, 0, 120},
{0x29, (uint8_t []){0x00}, 0, 0},
{0x2C, (uint8_t []){0x00}, 0, 0},
{0x3A, (uint8_t []){0x01}, 1, 0},
{0x36, (uint8_t []){0x00}, 1, 0},
{0x35, (uint8_t []){0x01}, 1, 20},
};
// ---- Display class with ST77922 4-pixel alignment ----
static void st77922_rounder_cb(lv_event_t *e)
{
lv_area_t *area = (lv_area_t *)lv_event_get_param(e);
area->x1 = (area->x1 >> 2) << 2;
area->x2 = ((area->x2 >> 2) << 2) + 3;
}
class ST77922_Display : public LcdDisplay {
private:
void LvglInit() {
lv_init();
lvgl_port_cfg_t port_cfg = ESP_LVGL_PORT_INIT_CONFIG();
port_cfg.task_priority = 1;
port_cfg.task_affinity = 1;
lvgl_port_init(&port_cfg);
const lvgl_port_display_cfg_t display_cfg = {
.io_handle = panel_io_,
.panel_handle = panel_,
.control_handle = nullptr,
.buffer_size = static_cast<uint32_t>(DISPLAY_BUFFER_SIZE),
.double_buffer = false,
.trans_size = 0,
.hres = static_cast<uint32_t>(DISPLAY_WIDTH),
.vres = static_cast<uint32_t>(DISPLAY_HEIGHT),
.monochrome = false,
.rotation = {
.swap_xy = false,
.mirror_x = false,
.mirror_y = false,
},
.color_format = LV_COLOR_FORMAT_RGB565,
.flags = {
.buff_dma = 1,
.buff_spiram = 0,
.sw_rotate = 0,
.swap_bytes = 1,
.full_refresh = 0,
.direct_mode = 0,
},
};
display_ = lvgl_port_add_disp(&display_cfg);
if (display_ != nullptr) {
lv_display_add_event_cb(display_, st77922_rounder_cb, LV_EVENT_INVALIDATE_AREA, nullptr);
}
}
public:
ST77922_Display(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_t panel,
int width, int height, int offset_x, int offset_y,
bool mirror_x, bool mirror_y, bool swap_xy)
: LcdDisplay(panel_io, panel, width, height) {
LvglInit();
if (offset_x != 0 || offset_y != 0) {
lv_display_set_offset(display_, offset_x, offset_y);
}
}
};
class LCDWikiES3C35P_Board : public WifiBoard {
private:
Button boot_button_;
i2c_master_bus_handle_t i2c_bus_;
ST77922_Display* display_;
void InitializeI2c() {
i2c_master_bus_config_t i2c_bus_cfg = {
.i2c_port = I2C_NUM_0,
.sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,
.scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.intr_priority = 0,
.trans_queue_depth = 0,
.flags = { .enable_internal_pullup = 1 },
};
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &i2c_bus_));
}
void InitializeQspiBus() {
ESP_LOGI(TAG, "Initialize QSPI bus");
spi_bus_config_t buscfg = {};
buscfg.sclk_io_num = DISPLAY_CLK_PIN;
buscfg.data0_io_num = DISPLAY_DATA0_PIN;
buscfg.data1_io_num = DISPLAY_DATA1_PIN;
buscfg.data2_io_num = DISPLAY_DATA2_PIN;
buscfg.data3_io_num = DISPLAY_DATA3_PIN;
buscfg.max_transfer_sz = DISPLAY_BUFFER_SIZE * sizeof(uint16_t);
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
}
void InitializeLcdDisplay() {
esp_lcd_panel_io_handle_t panel_io = nullptr;
esp_lcd_panel_handle_t panel = nullptr;
ESP_LOGI(TAG, "Install QSPI panel IO");
esp_lcd_panel_io_spi_config_t io_config = ST77922_PANEL_IO_QSPI_CONFIG(DISPLAY_CS_PIN, NULL, NULL);
io_config.pclk_hz = 80 * 1000 * 1000;
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &panel_io));
ESP_LOGI(TAG, "Install ST77922 LCD driver");
st77922_vendor_config_t vendor_config = {
.init_cmds = lcd_init_cmds,
.init_cmds_size = sizeof(lcd_init_cmds) / sizeof(st77922_lcd_init_cmd_t),
.flags = { .use_qspi_interface = 1 },
};
esp_lcd_panel_dev_config_t panel_config = {};
panel_config.reset_gpio_num = DISPLAY_RST_PIN;
panel_config.rgb_ele_order = DISPLAY_RGB_ORDER;
panel_config.bits_per_pixel = 16;
panel_config.vendor_config = (void *)&vendor_config;
ESP_ERROR_CHECK(esp_lcd_new_panel_st77922(panel_io, &panel_config, &panel));
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel));
ESP_ERROR_CHECK(esp_lcd_panel_init(panel));
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel, true));
display_ = new ST77922_Display(panel_io, panel,
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y,
DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}
void InitializeTouch() {
i2c_device_config_t dev_cfg = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = TOUCH_I2C_ADDR,
.scl_speed_hz = 400000,
};
ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c_bus_, &dev_cfg, &touch_dev_handle));
gpio_config_t rst_cfg = { .pin_bit_mask = (1ULL << TOUCH_RST_PIN), .mode = GPIO_MODE_OUTPUT };
gpio_config(&rst_cfg);
gpio_set_level(TOUCH_RST_PIN, 0);
vTaskDelay(pdMS_TO_TICKS(10));
gpio_set_level(TOUCH_RST_PIN, 1);
vTaskDelay(pdMS_TO_TICKS(100));
// Read max supported touch points
uint8_t max_pts;
if (touch_i2c_read(TOUCH_REG_MAX_TOUCHES, &max_pts, 1) == ESP_OK && max_pts > 0 && max_pts <= 5) {
touch_max_points = max_pts;
}
ESP_LOGI(TAG, "Touch max points: %d", touch_max_points);
lv_indev_t *indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, touchpad_read);
lv_indev_set_disp(indev, lv_display_get_default());
ESP_LOGI(TAG, "Touch initialized successfully");
}
void InitializeButtons() {
boot_button_.OnClick([this]() {
auto& app = Application::GetInstance();
if (app.GetDeviceState() == kDeviceStateStarting) {
EnterWifiConfigMode();
return;
}
app.ToggleChatState();
});
}
void InitializeTools() {
auto &mcp_server = McpServer::GetInstance();
mcp_server.AddTool("self.system.reconfigure_wifi",
"End this conversation and enter WiFi configuration mode.\n"
"**CAUTION** You must ask the user to confirm this action.",
PropertyList(), [this](const PropertyList& properties) {
EnterWifiConfigMode();
return true;
});
}
public:
LCDWikiES3C35P_Board() : boot_button_(BOOT_BUTTON_GPIO) {
InitializeI2c();
InitializeQspiBus();
InitializeLcdDisplay();
InitializeTouch();
InitializeButtons();
InitializeTools();
GetBacklight()->RestoreBrightness();
}
virtual AudioCodec* GetAudioCodec() override {
static Es8311AudioCodec audio_codec(i2c_bus_, I2C_NUM_0,
AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_GPIO_MCLK, AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS,
AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN,
AUDIO_CODEC_PA_PIN, AUDIO_CODEC_ES8311_ADDR, true, true);
return &audio_codec;
}
virtual Display* GetDisplay() override { return display_; }
virtual Backlight* GetBacklight() override {
static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
return &backlight;
}
virtual Led* GetLed() override {
static SingleLed led(BUILTIN_LED_GPIO);
return &led;
}
};
DECLARE_BOARD(LCDWikiES3C35P_Board);
-1
View File
@@ -53,7 +53,6 @@ dependencies:
version: ^1.0.1
rules:
- if: target not in [esp32]
espressif/esp_lcd_st77922: ^2.0.2
espressif/esp_lcd_touch_ft5x06: ~1
espressif/esp_lcd_touch_gt911: ^1
espressif/esp_lcd_touch_gt1151: ^1
+2 -2
View File
@@ -24,8 +24,8 @@ class VersionTests(unittest.TestCase):
def test_current_matrix_counts_and_uniqueness(self):
idf5 = release._collect_variants(idf_version=(5, 5, 4))
idf6 = release._collect_variants(idf_version=(6, 0, 1))
self.assertEqual(len(idf5), 172)
self.assertEqual(len(idf6), 158)
self.assertEqual(len(idf5), 171)
self.assertEqual(len(idf6), 157)
for variants in (idf5, idf6):
names = [variant["full_name"] for variant in variants]
self.assertEqual(len(names), len(set(names)))