forked from xiaozhi/xiaozhi-esp32
New Waveshare ESP32-S3-Touch-LCD-4B third party board, 86 box form. (#1199)
Co-authored-by: Xiaoxia <terrence@tenclass.com>
This commit is contained in:
@@ -229,6 +229,11 @@ elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_AMOLED_2_06)
|
||||
set(BUILTIN_TEXT_FONT font_puhui_basic_30_4)
|
||||
set(BUILTIN_ICON_FONT font_awesome_30_4)
|
||||
set(DEFAULT_EMOJI_COLLECTION twemoji_64)
|
||||
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_4B)
|
||||
set(BOARD_TYPE "waveshare-s3-touch-lcd-4b")
|
||||
set(BUILTIN_TEXT_FONT font_puhui_basic_30_4)
|
||||
set(BUILTIN_ICON_FONT font_awesome_30_4)
|
||||
set(DEFAULT_EMOJI_COLLECTION twemoji_64)
|
||||
elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_AMOLED_1_75)
|
||||
set(BOARD_TYPE "waveshare-s3-touch-amoled-1.75")
|
||||
set(BUILTIN_TEXT_FONT font_puhui_basic_30_4)
|
||||
|
||||
@@ -215,6 +215,8 @@ choice BOARD_TYPE
|
||||
bool "Waveshare ESP32-S3-Touch-AMOLED-2.06"
|
||||
config BOARD_TYPE_ESP32S3_Touch_AMOLED_1_75
|
||||
bool "Waveshare ESP32-S3-Touch-AMOLED-1.75"
|
||||
config BOARD_TYPE_ESP32S3_Touch_LCD_4B
|
||||
bool "Waveshare ESP32-S3-Touch-LCD-4B"
|
||||
depends on IDF_TARGET_ESP32S3
|
||||
config BOARD_TYPE_ESP32S3_Touch_LCD_1_85C
|
||||
bool "Waveshare ESP32-S3-Touch-LCD-1.85C"
|
||||
@@ -545,7 +547,7 @@ config USE_DEVICE_AEC
|
||||
default n
|
||||
depends on USE_AUDIO_PROCESSOR && (BOARD_TYPE_ESP_BOX_3 || BOARD_TYPE_ESP_BOX || BOARD_TYPE_ESP_BOX_LITE \
|
||||
|| BOARD_TYPE_LICHUANG_DEV || BOARD_TYPE_ESP32S3_KORVO2_V3 || BOARD_TYPE_ESP32S3_Touch_AMOLED_1_75 \
|
||||
|| BOARD_TYPE_ESP32S3_Touch_AMOLED_2_06 || BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_4B \
|
||||
|| BOARD_TYPE_ESP32S3_Touch_AMOLED_2_06 || BOARD_TYPE_ESP32S3_Touch_LCD_4B || BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_4B \
|
||||
|| BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_XC || BOARD_TYPE_ESP_S3_LCD_EV_Board_2 || BOARD_TYPE_YUNLIAO_S3 \
|
||||
|| BOARD_TYPE_ECHOEAR)
|
||||
help
|
||||
|
||||
12
main/boards/waveshare-s3-touch-lcd-4b/README.md
Normal file
12
main/boards/waveshare-s3-touch-lcd-4b/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Waveshare ESP32-S3-Touch-LCD-4B
|
||||
|
||||
|
||||
[ESP32-S3-Touch-LCD-4B](https://www.waveshare.com/esp32-s3-touch-lcd-4b.htm) is waveshare electronics designed an intelligent 86 box based on ESP32-S3 module equipped with a 480*480 IPS capacitive touch screen
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration in `menuconfig`.
|
||||
|
||||
Selection Board Type `Xiaozhi Assistant --> Board Type`
|
||||
- Waveshare ESP32-S3-Touch-LCD-4B
|
||||
65
main/boards/waveshare-s3-touch-lcd-4b/config.h
Normal file
65
main/boards/waveshare-s3-touch-lcd-4b/config.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef _BOARD_CONFIG_H_
|
||||
#define _BOARD_CONFIG_H_
|
||||
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#define AUDIO_INPUT_SAMPLE_RATE 24000
|
||||
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
|
||||
|
||||
#define AUDIO_INPUT_REFERENCE true
|
||||
|
||||
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_5
|
||||
#define AUDIO_I2S_GPIO_WS GPIO_NUM_7
|
||||
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_16
|
||||
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_15
|
||||
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_6
|
||||
|
||||
#define AUDIO_CODEC_PA_PIN GPIO_NUM_NC
|
||||
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_47
|
||||
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_48
|
||||
#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR
|
||||
#define AUDIO_CODEC_ES7210_ADDR ES7210_CODEC_DEFAULT_ADDR
|
||||
|
||||
#define I2C_ADDRESS ESP_IO_EXPANDER_I2C_TCA9554_ADDRESS_000
|
||||
#define BOOT_BUTTON_GPIO GPIO_NUM_0
|
||||
|
||||
#define BSP_LCD_VSYNC (GPIO_NUM_3)
|
||||
#define BSP_LCD_HSYNC (GPIO_NUM_46)
|
||||
#define BSP_LCD_DE (GPIO_NUM_17)
|
||||
#define BSP_LCD_PCLK (GPIO_NUM_9)
|
||||
#define BSP_LCD_DISP (GPIO_NUM_NC)
|
||||
#define BSP_LCD_DATA0 (GPIO_NUM_40)
|
||||
#define BSP_LCD_DATA1 (GPIO_NUM_41)
|
||||
#define BSP_LCD_DATA2 (GPIO_NUM_42)
|
||||
#define BSP_LCD_DATA3 (GPIO_NUM_2)
|
||||
#define BSP_LCD_DATA4 (GPIO_NUM_1)
|
||||
#define BSP_LCD_DATA5 (GPIO_NUM_21)
|
||||
#define BSP_LCD_DATA6 (GPIO_NUM_8)
|
||||
#define BSP_LCD_DATA7 (GPIO_NUM_18)
|
||||
#define BSP_LCD_DATA8 (GPIO_NUM_45)
|
||||
#define BSP_LCD_DATA9 (GPIO_NUM_38)
|
||||
#define BSP_LCD_DATA10 (GPIO_NUM_39)
|
||||
#define BSP_LCD_DATA11 (GPIO_NUM_10)
|
||||
#define BSP_LCD_DATA12 (GPIO_NUM_11)
|
||||
#define BSP_LCD_DATA13 (GPIO_NUM_12)
|
||||
#define BSP_LCD_DATA14 (GPIO_NUM_13)
|
||||
#define BSP_LCD_DATA15 (GPIO_NUM_14)
|
||||
|
||||
#define BSP_LCD_IO_SPI_CS (IO_EXPANDER_PIN_NUM_0)
|
||||
#define BSP_LCD_IO_SPI_SCL (IO_EXPANDER_PIN_NUM_2)
|
||||
#define BSP_LCD_IO_SPI_SDA (IO_EXPANDER_PIN_NUM_1)
|
||||
|
||||
#define DISPLAY_WIDTH 480
|
||||
#define DISPLAY_HEIGHT 480
|
||||
|
||||
#define DISPLAY_SWAP_XY false
|
||||
#define DISPLAY_MIRROR_X false
|
||||
#define DISPLAY_MIRROR_Y false
|
||||
|
||||
#define DISPLAY_OFFSET_X 0
|
||||
#define DISPLAY_OFFSET_Y 0
|
||||
|
||||
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_4
|
||||
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT true
|
||||
|
||||
#endif // _BOARD_CONFIG_H_
|
||||
12
main/boards/waveshare-s3-touch-lcd-4b/config.json
Normal file
12
main/boards/waveshare-s3-touch-lcd-4b/config.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"target": "esp32s3",
|
||||
"builds": [
|
||||
{
|
||||
"name": "waveshare-s3-touch-lcd-4b",
|
||||
"sdkconfig_append": [
|
||||
"CONFIG_USE_WECHAT_MESSAGE_STYLE=n",
|
||||
"CONFIG_USE_DEVICE_AEC=y"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
432
main/boards/waveshare-s3-touch-lcd-4b/esp32-s3-touch-lcd-4b.cc
Normal file
432
main/boards/waveshare-s3-touch-lcd-4b/esp32-s3-touch-lcd-4b.cc
Normal file
@@ -0,0 +1,432 @@
|
||||
#include "wifi_board.h"
|
||||
#include "display/lcd_display.h"
|
||||
#include "esp_lcd_st7701.h"
|
||||
|
||||
#include "codecs/box_audio_codec.h"
|
||||
#include "application.h"
|
||||
#include "button.h"
|
||||
#include "led/single_led.h"
|
||||
#include "mcp_server.h"
|
||||
#include "config.h"
|
||||
#include "power_save_timer.h"
|
||||
#include "axp2101.h"
|
||||
#include "i2c_device.h"
|
||||
#include <wifi_station.h>
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <esp_lcd_panel_vendor.h>
|
||||
#include <driver/i2c_master.h>
|
||||
#include <driver/spi_master.h>
|
||||
#include "esp_io_expander_tca9554.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <esp_lcd_touch_gt911.h>
|
||||
#include <esp_lvgl_port.h>
|
||||
#include <lvgl.h>
|
||||
|
||||
#include <esp_lcd_panel_io.h>
|
||||
#include <esp_lcd_panel_ops.h>
|
||||
#include <esp_lcd_panel_io_additions.h>
|
||||
#include <esp_ota_ops.h>
|
||||
|
||||
#define TAG "WaveshareEsp32s3TouchLCD4b"
|
||||
|
||||
class Pmic : public Axp2101 {
|
||||
public:
|
||||
Pmic(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : Axp2101(i2c_bus, addr) {
|
||||
WriteReg(0x22, 0b110); // PWRON > OFFLEVEL as POWEROFF Source enable
|
||||
WriteReg(0x27, 0x10); // hold 4s to power off
|
||||
|
||||
// Disable All DCs but DC1
|
||||
WriteReg(0x80, 0x01);
|
||||
// Disable All LDOs
|
||||
WriteReg(0x90, 0x00);
|
||||
WriteReg(0x91, 0x00);
|
||||
|
||||
// Set DC1 to 3.3V
|
||||
WriteReg(0x82, (3300 - 1500) / 100);
|
||||
|
||||
// Set ALDO1 to 3.3V
|
||||
WriteReg(0x92, (3300 - 500) / 100);
|
||||
|
||||
// Enable ALDO1(MIC)
|
||||
WriteReg(0x90, 0x01);
|
||||
|
||||
WriteReg(0x64, 0x02); // CV charger voltage setting to 4.1V
|
||||
|
||||
WriteReg(0x61, 0x02); // set Main battery precharge current to 50mA
|
||||
WriteReg(0x62, 0x08); // set Main battery charger current to 400mA ( 0x08-200mA, 0x09-300mA, 0x0A-400mA )
|
||||
WriteReg(0x63, 0x01); // set Main battery term charge current to 25mA
|
||||
}
|
||||
};
|
||||
|
||||
#define LCD_OPCODE_WRITE_CMD (0x02ULL)
|
||||
#define LCD_OPCODE_READ_CMD (0x03ULL)
|
||||
#define LCD_OPCODE_WRITE_COLOR (0x32ULL)
|
||||
|
||||
static const st7701_lcd_init_cmd_t lcd_init_cmds[] = {
|
||||
// {cmd, { data }, data_size, delay_ms}
|
||||
{0x11, (uint8_t[]){0x00}, 0, 120},
|
||||
{0xFF, (uint8_t[]){0x77, 0x01, 0x00, 0x00, 0x10}, 5, 0},
|
||||
{0xC0, (uint8_t[]){0x3B, 0x00}, 2, 0},
|
||||
{0xC1, (uint8_t[]){0x0D, 0x02}, 2, 0},
|
||||
{0xC2, (uint8_t[]){0x21, 0x08}, 2, 0},
|
||||
{0xCD, (uint8_t[]){0x08}, 1, 0},
|
||||
{0xB0, (uint8_t[]){0x00, 0x11, 0x18, 0x0E, 0x11, 0x06, 0x07, 0x08, 0x07, 0x22, 0x04, 0x12, 0x0F, 0xAA, 0x31, 0x18}, 16, 0},
|
||||
{0xB1, (uint8_t[]){0x00, 0x11, 0x19, 0x0E, 0x12, 0x07, 0x08, 0x08, 0x08, 0x22, 0x04, 0x11, 0x11, 0xA9, 0x32, 0x18}, 16, 0},
|
||||
{0xFF, (uint8_t[]){0x77, 0x01, 0x00, 0x00, 0x11}, 5, 0},
|
||||
{0xB0, (uint8_t[]){0x60}, 1, 0},
|
||||
{0xB1, (uint8_t[]){0x30}, 1, 0},
|
||||
{0xB2, (uint8_t[]){0x87}, 1, 0},
|
||||
{0xB3, (uint8_t[]){0x80}, 1, 0},
|
||||
{0xB5, (uint8_t[]){0x49}, 1, 0},
|
||||
{0xB7, (uint8_t[]){0x85}, 1, 0},
|
||||
{0xB8, (uint8_t[]){0x21}, 1, 0},
|
||||
{0xC1, (uint8_t[]){0x78}, 1, 0},
|
||||
{0xC2, (uint8_t[]){0x78}, 1, 20},
|
||||
{0xE0, (uint8_t[]){0x00, 0x1B, 0x02}, 3, 0},
|
||||
{0xE1, (uint8_t[]){0x08, 0xA0, 0x00, 0x00, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x44, 0x44}, 11, 0},
|
||||
{0xE2, (uint8_t[]){0x11, 0x11, 0x44, 0x44, 0xED, 0xA0, 0x00, 0x00, 0xEC, 0xA0, 0x00, 0x00}, 12, 0},
|
||||
{0xE3, (uint8_t[]){0x00, 0x00, 0x11, 0x11}, 4, 0},
|
||||
{0xE4, (uint8_t[]){0x44, 0x44}, 2, 0},
|
||||
{0xE5, (uint8_t[]){0x0A, 0xE9, 0xD8, 0xA0, 0x0C, 0xEB, 0xD8, 0xA0, 0x0E, 0xED, 0xD8, 0xA0, 0x10, 0xEF, 0xD8, 0xA0}, 16, 0},
|
||||
{0xE6, (uint8_t[]){0x00, 0x00, 0x11, 0x11}, 4, 0},
|
||||
{0xE7, (uint8_t[]){0x44, 0x44}, 2, 0},
|
||||
{0xE8, (uint8_t[]){0x09, 0xE8, 0xD8, 0xA0, 0x0B, 0xEA, 0xD8, 0xA0, 0x0D, 0xEC, 0xD8, 0xA0, 0x0F, 0xEE, 0xD8, 0xA0}, 16, 0},
|
||||
{0xEB, (uint8_t[]){0x02, 0x00, 0xE4, 0xE4, 0x88, 0x00, 0x40}, 7, 0},
|
||||
{0xEC, (uint8_t[]){0x3C, 0x00}, 2, 0},
|
||||
{0xED, (uint8_t[]){0xAB, 0x89, 0x76, 0x54, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x45, 0x67, 0x98, 0xBA}, 16, 0},
|
||||
{0xFF, (uint8_t[]){0x77, 0x01, 0x00, 0x00, 0x00}, 5, 0},
|
||||
{0x36, (uint8_t[]){0x00}, 1, 0},
|
||||
{0x3A, (uint8_t[]){0x66}, 1, 0},
|
||||
{0x21, (uint8_t[]){0x00}, 0, 120},
|
||||
{0x29, (uint8_t[]){0x00}, 0, 0},
|
||||
};
|
||||
|
||||
class WaveshareEsp32s3TouchLCD4b : public WifiBoard {
|
||||
private:
|
||||
i2c_master_bus_handle_t i2c_bus_;
|
||||
Pmic* pmic_ = nullptr;
|
||||
Button boot_button_;
|
||||
LcdDisplay* display_;
|
||||
esp_io_expander_handle_t io_expander = NULL;
|
||||
PowerSaveTimer* power_save_timer_;
|
||||
|
||||
uint32_t key_press_start;
|
||||
bool key_pressed;
|
||||
bool key_handled;
|
||||
|
||||
void InitializePowerSaveTimer() {
|
||||
power_save_timer_ = new PowerSaveTimer(-1, 60, 300);
|
||||
power_save_timer_->OnEnterSleepMode([this]() {
|
||||
GetDisplay()->SetPowerSaveMode(true);
|
||||
GetBacklight()->SetBrightness(70); });
|
||||
power_save_timer_->OnExitSleepMode([this]() {
|
||||
GetDisplay()->SetPowerSaveMode(false);
|
||||
GetBacklight()->RestoreBrightness(); });
|
||||
power_save_timer_->OnShutdownRequest([this](){
|
||||
pmic_->PowerOff(); });
|
||||
power_save_timer_->SetEnabled(true);
|
||||
}
|
||||
|
||||
void InitializeCodecI2c() {
|
||||
// Initialize I2C peripheral
|
||||
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,
|
||||
.trans_queue_depth = 0,
|
||||
.flags = {
|
||||
.enable_internal_pullup = 1,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &i2c_bus_));
|
||||
}
|
||||
|
||||
void InitializeTca9554(void) {
|
||||
esp_io_expander_new_i2c_tca9554(i2c_bus_, I2C_ADDRESS, &io_expander);
|
||||
esp_io_expander_set_dir(io_expander, IO_EXPANDER_PIN_NUM_3|IO_EXPANDER_PIN_NUM_5 | IO_EXPANDER_PIN_NUM_6 , IO_EXPANDER_OUTPUT);
|
||||
esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_3, 1);
|
||||
esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_6, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_5, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_5, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
esp_io_expander_set_dir(io_expander, IO_EXPANDER_PIN_NUM_4|IO_EXPANDER_PIN_NUM_6, IO_EXPANDER_INPUT);
|
||||
}
|
||||
void InitializeAxp2101() {
|
||||
ESP_LOGI(TAG, "Init AXP2101");
|
||||
pmic_ = new Pmic(i2c_bus_, 0x34);
|
||||
}
|
||||
|
||||
void InitializeRGB() {
|
||||
esp_lcd_panel_io_handle_t panel_io = nullptr;
|
||||
|
||||
spi_line_config_t line_config = {
|
||||
.cs_io_type = IO_TYPE_EXPANDER,
|
||||
.cs_expander_pin = BSP_LCD_IO_SPI_CS,
|
||||
.scl_io_type = IO_TYPE_EXPANDER,
|
||||
.scl_expander_pin = BSP_LCD_IO_SPI_SCL,
|
||||
.sda_io_type = IO_TYPE_EXPANDER,
|
||||
.sda_expander_pin = BSP_LCD_IO_SPI_SDA,
|
||||
.io_expander = io_expander,
|
||||
};
|
||||
esp_lcd_panel_io_3wire_spi_config_t io_config = ST7701_PANEL_IO_3WIRE_SPI_CONFIG(line_config, 0);
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_3wire_spi(&io_config, &panel_io));
|
||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||
esp_lcd_rgb_panel_config_t rgb_config = {
|
||||
.clk_src = LCD_CLK_SRC_DEFAULT,
|
||||
.timings = {
|
||||
.pclk_hz = 16 * 1000 * 1000,
|
||||
.h_res = DISPLAY_WIDTH,
|
||||
.v_res = DISPLAY_HEIGHT,
|
||||
.hsync_pulse_width = 10,
|
||||
.hsync_back_porch = 10,
|
||||
.hsync_front_porch = 20,
|
||||
.vsync_pulse_width = 10,
|
||||
.vsync_back_porch = 10,
|
||||
.vsync_front_porch = 10,
|
||||
.flags = {
|
||||
.pclk_active_neg = false
|
||||
}
|
||||
},
|
||||
.data_width = 16,
|
||||
.bits_per_pixel = 16,
|
||||
.num_fbs = 2,
|
||||
.bounce_buffer_size_px = 480 * 20,
|
||||
.psram_trans_align = 64,
|
||||
.hsync_gpio_num = BSP_LCD_HSYNC,
|
||||
.vsync_gpio_num = BSP_LCD_VSYNC,
|
||||
.de_gpio_num = BSP_LCD_DE,
|
||||
.pclk_gpio_num = BSP_LCD_PCLK,
|
||||
.disp_gpio_num = BSP_LCD_DISP,
|
||||
.data_gpio_nums = {
|
||||
BSP_LCD_DATA0, BSP_LCD_DATA1, BSP_LCD_DATA2, BSP_LCD_DATA3,
|
||||
BSP_LCD_DATA4, BSP_LCD_DATA5, BSP_LCD_DATA6, BSP_LCD_DATA7,
|
||||
BSP_LCD_DATA8, BSP_LCD_DATA9, BSP_LCD_DATA10, BSP_LCD_DATA11,
|
||||
BSP_LCD_DATA12, BSP_LCD_DATA13, BSP_LCD_DATA14, BSP_LCD_DATA15
|
||||
},
|
||||
.flags = {
|
||||
.fb_in_psram = 1,
|
||||
},
|
||||
};
|
||||
|
||||
rgb_config.timings.h_res = DISPLAY_WIDTH;
|
||||
rgb_config.timings.v_res = DISPLAY_HEIGHT;
|
||||
st7701_vendor_config_t vendor_config = {
|
||||
.init_cmds = lcd_init_cmds,
|
||||
.init_cmds_size = sizeof(lcd_init_cmds) / sizeof(lcd_init_cmds[0]),
|
||||
.rgb_config = &rgb_config,
|
||||
.flags = {
|
||||
.mirror_by_cmd = 0,
|
||||
.auto_del_panel_io = 1,
|
||||
}
|
||||
};
|
||||
const esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = GPIO_NUM_NC,
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
||||
.bits_per_pixel = 18,
|
||||
.vendor_config = &vendor_config,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_st7701(panel_io, &panel_config, &panel_handle));
|
||||
esp_lcd_panel_init(panel_handle);
|
||||
|
||||
display_ = new RgbLcdDisplay(panel_io, panel_handle,
|
||||
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X,
|
||||
DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
|
||||
}
|
||||
|
||||
void InitializeButtons() {
|
||||
boot_button_.OnClick([this]() {
|
||||
auto& app = Application::GetInstance();
|
||||
if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
|
||||
ResetWifiConfiguration();
|
||||
}
|
||||
app.ToggleChatState();
|
||||
});
|
||||
|
||||
#if CONFIG_USE_DEVICE_AEC
|
||||
boot_button_.OnDoubleClick([this]() {
|
||||
auto& app = Application::GetInstance();
|
||||
if (app.GetDeviceState() == kDeviceStateIdle) {
|
||||
app.SetAecMode(app.GetAecMode() == kAecOff ? kAecOnDeviceSide : kAecOff);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void InitializeTouch() {
|
||||
esp_lcd_touch_handle_t tp;
|
||||
esp_lcd_touch_config_t tp_cfg = {
|
||||
.x_max = DISPLAY_WIDTH - 1,
|
||||
.y_max = DISPLAY_HEIGHT - 1,
|
||||
.rst_gpio_num = GPIO_NUM_NC,
|
||||
.int_gpio_num = GPIO_NUM_NC,
|
||||
.levels = {
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags = {
|
||||
.swap_xy = 0,
|
||||
.mirror_x = 0,
|
||||
.mirror_y = 0,
|
||||
},
|
||||
};
|
||||
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
|
||||
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
|
||||
tp_io_config.scl_speed_hz = 400* 1000;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(i2c_bus_, &tp_io_config, &tp_io_handle));
|
||||
ESP_LOGI(TAG, "Initialize touch controller");
|
||||
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp));
|
||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||
.disp = lv_display_get_default(),
|
||||
.handle = tp,
|
||||
};
|
||||
lvgl_port_add_touch(&touch_cfg);
|
||||
ESP_LOGI(TAG, "Touch panel initialized successfully");
|
||||
}
|
||||
|
||||
void InitializeTools() {
|
||||
auto &mcp_server = McpServer::GetInstance();
|
||||
mcp_server.AddTool("self.system.reconfigure_wifi",
|
||||
"Reboot the device and enter WiFi configuration mode.\n"
|
||||
"**CAUTION** You must ask the user to confirm this action.",
|
||||
PropertyList(), [this](const PropertyList& properties) {
|
||||
ResetWifiConfiguration();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
void CheckKeyState() {
|
||||
if (!io_expander) return;
|
||||
|
||||
uint32_t current_level;
|
||||
esp_err_t ret = esp_io_expander_get_level(io_expander, IO_EXPANDER_PIN_NUM_4, ¤t_level);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read IO_EXPANDER_PIN_NUM_4 level");
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t last_level = 0;
|
||||
static uint64_t press_start_time_ms = 0;
|
||||
|
||||
if (current_level != last_level) {
|
||||
last_level = current_level;
|
||||
|
||||
if (current_level > 0) {
|
||||
press_start_time_ms = esp_timer_get_time() / 1000;
|
||||
ESP_LOGD(TAG, "Button pressed, start time recorded");
|
||||
} else {
|
||||
uint64_t press_duration = (esp_timer_get_time() / 1000) - press_start_time_ms;
|
||||
ESP_LOGI(TAG, "Button released after %llums", press_duration);
|
||||
|
||||
if (press_duration < 1000) {
|
||||
ESP_LOGI(TAG, "Short press detected, switching to factory partition");
|
||||
|
||||
const esp_partition_t* factory_partition = esp_partition_find_first(
|
||||
ESP_PARTITION_TYPE_APP,
|
||||
ESP_PARTITION_SUBTYPE_APP_FACTORY,
|
||||
nullptr
|
||||
);
|
||||
if (factory_partition) {
|
||||
ESP_LOGI(TAG, "Found factory partition: %s", factory_partition->label);
|
||||
ESP_ERROR_CHECK(esp_ota_set_boot_partition(factory_partition));
|
||||
esp_restart();
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Factory partition not found");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Long press detected (>1000ms), no action");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeKeyMonitor() {
|
||||
key_press_start = 0;
|
||||
key_pressed = false;
|
||||
key_handled = false;
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
[](void* arg) {
|
||||
auto* board = static_cast<WaveshareEsp32s3TouchLCD4b*>(arg);
|
||||
while (true) {
|
||||
board->CheckKeyState();
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
},
|
||||
"key_monitor_task",
|
||||
4096,
|
||||
this,
|
||||
5,
|
||||
nullptr,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
WaveshareEsp32s3TouchLCD4b() : boot_button_(BOOT_BUTTON_GPIO) {
|
||||
InitializePowerSaveTimer();
|
||||
InitializeCodecI2c();
|
||||
InitializeTca9554();
|
||||
InitializeAxp2101();
|
||||
InitializeRGB();
|
||||
InitializeTouch();
|
||||
InitializeButtons();
|
||||
InitializeTools();
|
||||
InitializeKeyMonitor(); // 启动按键监听
|
||||
GetBacklight()->SetBrightness(100);
|
||||
}
|
||||
|
||||
virtual AudioCodec* GetAudioCodec() override {
|
||||
static BoxAudioCodec audio_codec(
|
||||
i2c_bus_,
|
||||
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,
|
||||
AUDIO_CODEC_ES7210_ADDR,
|
||||
AUDIO_INPUT_REFERENCE);
|
||||
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 bool GetBatteryLevel(int &level, bool &charging, bool &discharging) override {
|
||||
static bool last_discharging = false;
|
||||
charging = pmic_->IsCharging();
|
||||
discharging = pmic_->IsDischarging();
|
||||
if (discharging != last_discharging)
|
||||
{
|
||||
power_save_timer_->SetEnabled(discharging);
|
||||
last_discharging = discharging;
|
||||
}
|
||||
|
||||
level = pmic_->GetBatteryLevel();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void SetPowerSaveMode(bool enabled) override {
|
||||
if (!enabled)
|
||||
{
|
||||
power_save_timer_->WakeUp();
|
||||
}
|
||||
WifiBoard::SetPowerSaveMode(enabled);
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_BOARD(WaveshareEsp32s3TouchLCD4b);
|
||||
@@ -4,6 +4,7 @@ dependencies:
|
||||
espressif/esp_lcd_ili9341: ==1.2.0
|
||||
espressif/esp_lcd_gc9a01: ==2.0.1
|
||||
espressif/esp_lcd_st77916: ^1.0.1
|
||||
espressif/esp_lcd_st7701: "^1.1.*"
|
||||
espressif/esp_lcd_axs15231b: ^1.0.0
|
||||
espressif/esp_lcd_st7796:
|
||||
version: 1.3.4
|
||||
|
||||
Reference in New Issue
Block a user