### ESP-Hi Example: Initialize MCP Tools Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Example of initializing MCP tools on an ESP32 device, including a tool with no arguments and a tool with RGB color arguments. ```cpp void InitializeTools() { auto& mcp_server = McpServer::GetInstance(); // Example 1: no arguments - move the robot forward mcp_server.AddTool("self.dog.forward", "Move the robot forward", PropertyList(), [this](const PropertyList&) -> ReturnValue { servo_dog_ctrl_send(DOG_STATE_FORWARD, NULL); return true; }); // Example 2: with arguments - set RGB light color mcp_server.AddTool("self.light.set_rgb", "Set the RGB color of the light", PropertyList({ Property("r", kPropertyTypeInteger, 0, 255), Property("g", kPropertyTypeInteger, 0, 255), Property("b", kPropertyTypeInteger, 0, 255) }), [this](const PropertyList& properties) -> ReturnValue { int r = properties["r"].value(); int g = properties["g"].value(); int b = properties["b"].value(); led_on_ = true; SetLedColor(r, g, b); return true; }); } ``` -------------------------------- ### Example: Registering Tools Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Demonstrates how to register tools with and without arguments using `McpServer::AddTool`. ```APIDOC ## Example: Registering Tools ### Description This example shows how to register two tools: one with no arguments for moving the robot forward, and another with RGB color arguments for setting an LED. ### Code ```cpp void InitializeTools() { auto& mcp_server = McpServer::GetInstance(); // Example 1: no arguments - move the robot forward mcp_server.AddTool("self.dog.forward", "Move the robot forward", PropertyList(), [this](const PropertyList&) -> ReturnValue { servo_dog_ctrl_send(DOG_STATE_FORWARD, NULL); return true; }); // Example 2: with arguments - set RGB light color mcp_server.AddTool("self.light.set_rgb", "Set the RGB color of the light", PropertyList({ Property("r", kPropertyTypeInteger, 0, 255), Property("g", kPropertyTypeInteger, 0, 255), Property("b", kPropertyTypeInteger, 0, 255) }), [this](const PropertyList& properties) -> ReturnValue { int r = properties["r"].value(); int g = properties["g"].value(); int b = properties["b"].value(); led_on_ = true; SetLedColor(r, g, b); return true; }); } ``` ``` -------------------------------- ### Install Dependencies Source: https://github.com/78/xiaozhi-esp32/blob/main/scripts/Image_Converter/README.md Install project dependencies using pip from a requirements.txt file. ```bash pip install -r requirements.txt ``` -------------------------------- ### Bread-compact-wifi Board Initialization Sequence Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/quandong-s3-dev/HARDWARE_DIFF.md This sequence details the initialization process for the bread-compact-wifi board, including display I2C setup, OLED display initialization, button setup, and tool registration. ```cpp InitializeDisplayI2c() // I2C0 for SSD1306 InitializeSsd1306Display() // OledDisplay InitializeButtons() // BOOT + Touch + Vol+ + Vol- InitializeTools() // 注册 LampController(MCP 外设) ``` -------------------------------- ### Get Tools List Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Example JSON-RPC request to list available tools. Set `withUserTools` to `true` to include user-specific tools. ```APIDOC ## Get the tools list ```json { "jsonrpc": "2.0", "method": "tools/list", "params": { "cursor": "", "withUserTools": false }, "id": 1 } ``` ``` -------------------------------- ### Quandong-s3-dev Board Initialization Sequence Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/quandong-s3-dev/HARDWARE_DIFF.md This sequence outlines the initialization steps for the quandong-s3-dev board, including I2C and SPI setup, audio power amplifier enablement, display initialization, and button setup. ```cpp InitializeI2c() // I2C0 for ES8311 InitializeSpi() // SPI2 for ILI9341 InitializeAudioPaEnable() // GPIO1 拉低使能功放 InitializeIli9341Display() // 自定义 init cmds + 实例化 SpiLcdDisplay InitializeButtons() // BOOT 单键 GetBacklight()->SetBrightness(100) ``` -------------------------------- ### Example: Registering a User-only Tool Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Illustrates how to register a user-only tool using `McpServer::AddUserOnlyTool`. ```APIDOC ## Example: Registering a User-only Tool ### Description This example demonstrates registering a user-only tool for clearing local cache. This tool will not be visible in a regular `tools/list` response and requires `withUserTools=true` to be discovered. ### Code ```cpp mcp_server.AddUserOnlyTool("self.display.clear_cache", "Clear locally cached images. User-only action.", PropertyList(), [](const PropertyList&) -> ReturnValue { ClearLocalCache(); return true; }); ``` ``` -------------------------------- ### Install Dependencies Source: https://github.com/78/xiaozhi-esp32/blob/main/scripts/ogg_converter/README.md Installs the necessary Python library for the OGG converter script. Ensure you are within an activated virtual environment. ```bash pip install ffmpeg-python ``` -------------------------------- ### Install clang-format on Windows Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/code_style.md Installs clang-format using package managers like winget or Chocolatey. ```powershell winget install LLVM # or with Chocolatey choco install llvm ``` -------------------------------- ### Install clang-format on Linux Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/code_style.md Installs clang-format using package managers for Ubuntu/Debian or Fedora. ```bash sudo apt install clang-format # Ubuntu/Debian sudo dnf install clang-tools-extra # Fedora ``` -------------------------------- ### Flash ESP32C6 Slave Example Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/lilygo-t-display-p4/README.md Flashes the slave example from the esp-hosted-mcu library to the ESP32-C6 target chip. Ensure the esp-hosted-mcu version matches the xiaozhi-esp32 library. ```bash Flash the slave example from the esp-hosted-mcu library for the target chip ESP32C6. The esp-hosted-mcu version must match the one used in the xiaozhi-esp32 library. ``` -------------------------------- ### Example: Registering a User-only Tool for Cache Clearing Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Demonstrates how to register a user-only tool using AddUserOnlyTool. This tool is hidden from regular tool listings and requires `withUserTools=true` to be discovered. ```cpp mcp_server.AddUserOnlyTool("self.display.clear_cache", "Clear locally cached images. User-only action.", PropertyList(), [](const PropertyList&) -> ReturnValue { ClearLocalCache(); return true; }); ``` -------------------------------- ### Install clang-format on macOS Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/code_style.md Installs clang-format using the Homebrew package manager. ```bash brew install clang-format ``` -------------------------------- ### Common SDK Configuration Options Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md Examples of common `sdkconfig_append` entries for configuring flash size, partition tables, language, and wake word detection. ```json // Flash size "CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y" "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y" "CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y" ``` ```json // Partition table "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/4m.csv\"" "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\"" "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/16m.csv\"" ``` ```json // Language "CONFIG_LANGUAGE_EN_US=y" "CONFIG_LANGUAGE_ZH_CN=y" ``` ```json // Wake word configuration "CONFIG_USE_DEVICE_AEC=y" // enable on-device AEC "CONFIG_WAKE_WORD_DISABLED=y" // disable wake word detection ``` -------------------------------- ### Configure Camera Sensor Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/lilygo-t-cameraplus-s3/README.md Select and configure the camera sensor. This example sets the sensor to OV2640 with YUV422 format at 240x240 resolution and 25fps. ```text Component config -> Espressif Camera Sensors Configurations -> Camera Sensor Configuration -> Select and Set Camera Sensor -> OV2640 -> Select default output format for DVP interface -> YUV422 240x240 25fps, DVP 8-bit, 20M input ``` -------------------------------- ### Call Tool: Switch Light Mode Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Example JSON-RPC request to call the `self.chassis.switch_light_mode` tool, specifying the desired `light_mode`. ```APIDOC ## Switch the light mode ```json { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "self.chassis.switch_light_mode", "arguments": { "light_mode": 3 } }, "id": 3 } ``` ``` -------------------------------- ### Custom Board Initialization - C++ Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board_zh.md Implement custom board initialization logic, including I2C, SPI, display, and button setup. This class inherits from WifiBoard and overrides virtual functions to provide hardware-specific implementations. ```cpp #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 #include #include #define TAG "MyCustomBoard" class MyCustomBoard : public WifiBoard { private: i2c_master_bus_handle_t codec_i2c_bus_; Button boot_button_; LcdDisplay* display_; // I2C初始化 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, &codec_i2c_bus_)); } // SPI初始化(用于显示屏) void InitializeSpi() { spi_bus_config_t buscfg = {}; buscfg.mosi_io_num = DISPLAY_SPI_MOSI_PIN; buscfg.miso_io_num = GPIO_NUM_NC; buscfg.sclk_io_num = DISPLAY_SPI_SCK_PIN; buscfg.quadwp_io_num = GPIO_NUM_NC; buscfg.quadhd_io_num = GPIO_NUM_NC; buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t); ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO)); } // 按钮初始化 void InitializeButtons() { boot_button_.OnClick([this]() { auto& app = Application::GetInstance(); if (app.GetDeviceState() == kDeviceStateStarting) { EnterWifiConfigMode(); return; } app.ToggleChatState(); }); } // 显示屏初始化(以ST7789为例) void InitializeDisplay() { esp_lcd_panel_io_handle_t panel_io = nullptr; esp_lcd_panel_handle_t panel = nullptr; esp_lcd_panel_io_spi_config_t io_config = {}; io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN; io_config.dc_gpio_num = DISPLAY_DC_PIN; io_config.spi_mode = 2; io_config.pclk_hz = 80 * 1000 * 1000; io_config.trans_queue_depth = 10; io_config.lcd_cmd_bits = 8; io_config.lcd_param_bits = 8; ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &panel_io)); esp_lcd_panel_dev_config_t panel_config = {}; panel_config.reset_gpio_num = GPIO_NUM_NC; panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB; panel_config.bits_per_pixel = 16; ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel)); esp_lcd_panel_reset(panel); esp_lcd_panel_init(panel); esp_lcd_panel_invert_color(panel, true); esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); // 创建显示屏对象 display_ = new SpiLcdDisplay(panel_io, panel, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY); } // MCP Tools 初始化 void InitializeTools() { // 参考 MCP 文档 } public: // 构造函数 MyCustomBoard() : boot_button_(BOOT_BUTTON_GPIO) { InitializeI2c(); InitializeSpi(); InitializeDisplay(); InitializeButtons(); InitializeTools(); GetBacklight()->SetBrightness(100); } // 获取音频编解码器 virtual AudioCodec* GetAudioCodec() override { static Es8311AudioCodec audio_codec( 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); 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; } }; // 注册开发板 DECLARE_BOARD(MyCustomBoard); ``` -------------------------------- ### Server to Device TTS Start Command Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/websocket.md Initiates Text-to-Speech playback on the device. The server sends this message followed by binary Opus frames for audio. ```json { "session_id": "xxx", "type": "tts", "state": "start" } ``` -------------------------------- ### Call Tool: Reboot Device (User-Only) Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Example JSON-RPC request to call the user-only `self.reboot` tool to restart the device. ```APIDOC ## Reboot the device (user-only) ```json { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "self.reboot", "arguments": {} }, "id": 4 } ``` ``` -------------------------------- ### Run the OGG Converter Script Source: https://github.com/78/xiaozhi-esp32/blob/main/scripts/ogg_converter/README.md Executes the main Python script for batch OGG conversion. Ensure FFmpeg is installed and accessible. ```bash python ogg_covertor.py ``` -------------------------------- ### Call Tool: Move Chassis Forward Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Example JSON-RPC request to call the `self.chassis.go_forward` tool. This is used to move the device's chassis forward. ```APIDOC ## Move the chassis forward ```json { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "self.chassis.go_forward", "arguments": {} }, "id": 2 } ``` ``` -------------------------------- ### WebSocket Message: List Tools Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/electron-bot/README.md Example JSON message to send to the WebSocket endpoint to list available tools. This uses the MCP format. ```json {"type":"mcp","payload":{"jsonrpc":"2.0","method":"tools/list","id":1}} ``` -------------------------------- ### WebSocket Message: Call Method Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/electron-bot/README.md Example JSON message to send to the WebSocket endpoint to call a specific method, such as getting the robot's status. This uses the JSON-RPC 2.0 format. ```json {"jsonrpc":"2.0","method":"tools/call","params":{"name":"self.electron.get_status","arguments":{}},"id":2} ``` -------------------------------- ### Manual Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/aipi-lite/README_en.md Open the project's configuration menu to customize settings. Ensure the correct board type is selected within the menu. ```bash idf.py menuconfig ``` -------------------------------- ### One-click Build for SenseCAP Watcher Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/sensecap-watcher/README_en.md Use this command for a simplified build process. Ensure you have the necessary configuration file. ```bash python scripts/release.py sensecap-watcher -c config_en.json ``` -------------------------------- ### Format the entire project with clang-format Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/code_style.md Formats all header and source files within the 'main' directory. ```bash # Run from the project root find main -iname '*.h' -o -iname '*.cc' | xargs clang-format -i ``` -------------------------------- ### Build and Flash Firmware Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/sensecap-watcher/README_en.md Compile the firmware and flash it to the SenseCAP Watcher board. This command specifies the board name and language. ```bash idf.py -DBOARD_NAME=sensecap-watcher-en build flash ``` -------------------------------- ### Run LVGL Image Conversion Tool Source: https://github.com/78/xiaozhi-esp32/blob/main/scripts/Image_Converter/README.md Instructions to activate the virtual environment and run the GUI image conversion tool. ```bash # 激活环境 source venv/bin/activate # Linux/Mac virtualenv\Scripts\activate # Windows # 运行 python lvgl_tools_gui.py ``` -------------------------------- ### Build and Package with release.py Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md Automate the build and packaging process for a custom board using `scripts/release.py`. This script reads configuration from `config.json` and applies SDK configurations. ```bash python scripts/release.py my-custom-board ``` -------------------------------- ### Build and Flash Custom Board Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md After configuring the board in `menuconfig`, use `idf.py build` to compile the project and `idf.py flash monitor` to deploy and observe the output. ```bash idf.py build idf.py flash monitor ``` -------------------------------- ### Server Alert Message (JSON) Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mqtt-udp.md An example of an alert message sent from the server to the device, used for UI notifications. ```json { "session_id": "xxx", "type": "alert", "status": "Warning", "message": "Battery low", "emotion": "sad" } ``` -------------------------------- ### One-click Build for AiPi-Lite Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/aipi-lite/README_en.md Use this script for a simplified build process. Ensure you are in the project root directory. ```bash python scripts/release.py aipi-lite -c config_en.json ``` -------------------------------- ### Build and Flash AiPi-Lite Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/aipi-lite/README_en.md Compile the firmware and flash it to the AiPi-Lite board. Be cautious if flashing over previous AiPi-Lite firmware to avoid data loss. ```bash idf.py -DBOARD_NAME=aipi-lite build flash ``` -------------------------------- ### Device Listen Message (JSON) Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mqtt-udp.md Sent by the device to start listening for audio input, specifying the session ID and mode. ```json { "session_id": "xxx", "type": "listen", "state": "start", "mode": "manual" } ``` -------------------------------- ### Device Initiates Connection Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/websocket.md When the device initiates a connection, it calls OpenAudioChannel(), sets up the WebSocket, and sends a 'hello' message. ```c // In main/device_state.c // ... case kDeviceStateIdle: // Triggered by wake word or button press. OpenAudioChannel(); // ... setup WebSocket and send "type":"hello" break; // ... ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/78/xiaozhi-esp32/blob/main/scripts/Image_Converter/README.md Steps to create a Python virtual environment and activate it on Linux/Mac or Windows. ```bash # 创建 venv python -m venv venv # 激活环境 source venv/bin/activate # Linux/Mac venv\Scripts\activate # Windows ``` -------------------------------- ### Build the Project Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/esp-box-3/README.md Compile the project code after configuration. This command generates the necessary firmware files for flashing onto the ESP-BOX-3. ```bash idf.py build ``` -------------------------------- ### IoT MCP Tool Call Command Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/websocket.md An example of a server-to-device IoT command using JSON-RPC 2.0 for calling a tool. Specifies the method and arguments. ```json { "session_id": "xxx", "type": "mcp", "payload": { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "self.light.set_rgb", "arguments": { "r": 255, "g": 0, "b": 0 } }, "id": 1 } } ``` -------------------------------- ### Registering MCP Tools on ESP32 Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Demonstrates how to register regular and user-only tools with the McpServer singleton. Use AddTool for AI-callable functions and AddUserOnlyTool for privileged actions. ```cpp void AddTool( const std::string& name, // unique tool name, e.g. self.dog.forward const std::string& description, // short description for the model const PropertyList& properties, // input parameters (may be empty); supported types: bool, int, string std::function callback // implementation ); void AddUserOnlyTool( const std::string& name, const std::string& description, const PropertyList& properties, std::function callback ); ``` -------------------------------- ### Device Transitions to Listening Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/websocket.md After establishing a connection, the device calls SendStartListening(...) and begins streaming microphone audio. ```c // In main/device_state.c // ... case kDeviceStateConnecting: // Once connected, SendStartListening(...) is called and microphone streaming begins. SendStartListening(...); // ... transition to kDeviceStateListening break; // ... ``` -------------------------------- ### Device Transitions to Speaking Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/websocket.md When the server sends a 'tts' start message, the device stops sending microphone audio and begins playing incoming TTS audio. ```c // In main/device_state.c // ... case kDeviceStateListening: // Server sends {"type":"tts","state":"start"}; // the device stops sending mic audio and plays incoming TTS. // ... transition to kDeviceStateSpeaking break; // ... ``` -------------------------------- ### Text-to-Speech (TTS) State Updates Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/websocket.md Manages the Text-to-Speech process. 'start' indicates the server is about to stream audio, 'stop' indicates completion, and 'sentence_start' can display current subtitles. ```json { "session_id": "xxx", "type": "tts", "state": "start" } ``` ```json { "session_id": "xxx", "type": "tts", "state": "stop" } ``` ```json { "session_id": "xxx", "type": "tts", "state": "sentence_start", "text": "..." } ``` -------------------------------- ### Get Tools List with MCP Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Send this JSON-RPC request to the tools/list endpoint to retrieve a list of available tools. Set withUserTools to true to include user-only tools. ```json { "jsonrpc": "2.0", "method": "tools/list", "params": { "cursor": "", "withUserTools": false }, "id": 1 } ``` -------------------------------- ### Spotpear-ESP32-S3-1.54-MUMA Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Sets default text, icon fonts, and emoji collection for the sp-esp32-s3-1.54-muma board. ```cmake set(BOARD_TYPE "sp-esp32-s3-1.54-muma") set(BUILTIN_TEXT_FONT font_puhui_basic_16_4) set(BUILTIN_ICON_FONT font_awesome_16_4) set(DEFAULT_EMOJI_COLLECTION twemoji_32) ``` -------------------------------- ### Configure ESP32-P4 Wi-Fi Buffers Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/wireless-tag-wtp4c5mp07s/README.md Adjust the maximum number of Wi-Fi RX and TX buffers in menuconfig for optimal performance. ```bash Component config -> Wi-Fi Remote -> Wi-Fi configuration -> Max number of WiFi static RX buffers -> 10 ``` ```bash Component config -> Wi-Fi Remote -> Wi-Fi configuration -> Max number of WiFi dynamic RX buffers -> 24 ``` ```bash Component config -> Wi-Fi Remote -> Wi-Fi configuration -> Max number of WiFi static TX buffers -> 10 ``` -------------------------------- ### Get Local Assets File Path (CMake Function) Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt This CMake function retrieves the local file path for assets, handling both direct file paths and URLs. It downloads remote assets if they don't exist locally. Use this when you need to ensure an asset file is available locally before proceeding. ```cmake function(get_assets_local_file assets_source assets_local_file_var) # Check if it's a URL (starts with http:// or https://) if(assets_source MATCHES "^https?://") # It's a URL, download it get_filename_component(ASSETS_FILENAME "${assets_source}" NAME) set(ASSETS_LOCAL_FILE "${CMAKE_BINARY_DIR}/${ASSETS_FILENAME}") set(ASSETS_TEMP_FILE "${CMAKE_BINARY_DIR}/${ASSETS_FILENAME}.tmp") # Check if local file exists if(EXISTS ${ASSETS_LOCAL_FILE}) message(STATUS "Assets file ${ASSETS_FILENAME} already exists, skipping download") else() message(STATUS "Downloading ${ASSETS_FILENAME}") # Clean up any existing temp file if(EXISTS ${ASSETS_TEMP_FILE}) file(REMOVE ${ASSETS_TEMP_FILE}) endif() # Download to temporary file first file(DOWNLOAD ${assets_source} ${ASSETS_TEMP_FILE} STATUS DOWNLOAD_STATUS) list(GET DOWNLOAD_STATUS 0 STATUS_CODE) if(NOT STATUS_CODE EQUAL 0) # Clean up temp file on failure if(EXISTS ${ASSETS_TEMP_FILE}) file(REMOVE ${ASSETS_TEMP_FILE}) endif() message(FATAL_ERROR "Failed to download ${ASSETS_FILENAME} from ${assets_source}") endif() # Move temp file to final location (atomic operation) file(RENAME ${ASSETS_TEMP_FILE} ${ASSETS_LOCAL_FILE}) message(STATUS "Successfully downloaded ${ASSETS_FILENAME}") endif() else() # It's a local file path if(IS_ABSOLUTE "${assets_source}") set(ASSETS_LOCAL_FILE "${assets_source}") else() set(ASSETS_LOCAL_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${assets_source}") endif() # Check if local file exists if(NOT EXISTS ${ASSETS_LOCAL_FILE}) message(FATAL_ERROR "Assets file not found: ${ASSETS_LOCAL_FILE}") endif() message(STATUS "Using assets file: ${ASSETS_LOCAL_FILE}") endif() set(${assets_local_file_var} ${ASSETS_LOCAL_FILE} PARENT_SCOPE) endfunction() ``` -------------------------------- ### Spotpear-ESP32-S3-1.28-BOX Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Sets default text, icon fonts, and emoji collection for the sp-esp32-s3-1.28-box board. ```cmake set(BOARD_TYPE "sp-esp32-s3-1.28-box") set(BUILTIN_TEXT_FONT font_puhui_basic_16_4) set(BUILTIN_ICON_FONT font_awesome_16_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) ``` -------------------------------- ### Bread-Compact-WIFI-CAM Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Sets default text, icon fonts, and emoji collection for the bread-compact-wifi-s3cam board. ```cmake set(BOARD_TYPE "bread-compact-wifi-s3cam") set(BUILTIN_TEXT_FONT font_puhui_basic_16_4) set(BUILTIN_ICON_FONT font_awesome_16_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) ``` -------------------------------- ### Implement Custom Board Class Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md This C++ code defines a custom board class `MyCustomBoard` that inherits from `WifiBoard`. It includes initialization for I2C, SPI, display, and buttons, and overrides methods to provide specific hardware implementations. Use this as a template for your custom board. ```cpp #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 #include #include #define TAG "MyCustomBoard" class MyCustomBoard : public WifiBoard { private: i2c_master_bus_handle_t codec_i2c_bus_; Button boot_button_; LcdDisplay* 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, &codec_i2c_bus_)); } void InitializeSpi() { spi_bus_config_t buscfg = {}; buscfg.mosi_io_num = DISPLAY_SPI_MOSI_PIN; buscfg.miso_io_num = GPIO_NUM_NC; buscfg.sclk_io_num = DISPLAY_SPI_SCK_PIN; buscfg.quadwp_io_num = GPIO_NUM_NC; buscfg.quadhd_io_num = GPIO_NUM_NC; buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t); ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO)); } void InitializeButtons() { boot_button_.OnClick([this]() { auto& app = Application::GetInstance(); if (app.GetDeviceState() == kDeviceStateStarting) { EnterWifiConfigMode(); return; } app.ToggleChatState(); }); } void InitializeDisplay() { esp_lcd_panel_io_handle_t panel_io = nullptr; esp_lcd_panel_handle_t panel = nullptr; esp_lcd_panel_io_spi_config_t io_config = {}; io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN; io_config.dc_gpio_num = DISPLAY_DC_PIN; io_config.spi_mode = 2; io_config.pclk_hz = 80 * 1000 * 1000; io_config.trans_queue_depth = 10; io_config.lcd_cmd_bits = 8; io_config.lcd_param_bits = 8; ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &panel_io)); esp_lcd_panel_dev_config_t panel_config = {}; panel_config.reset_gpio_num = GPIO_NUM_NC; panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB; panel_config.bits_per_pixel = 16; ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel)); esp_lcd_panel_reset(panel); esp_lcd_panel_init(panel); esp_lcd_panel_invert_color(panel, true); esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); display_ = new SpiLcdDisplay(panel_io, panel, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY); } void InitializeTools() { // Register MCP tools here; see docs/mcp-usage.md. } public: MyCustomBoard() : boot_button_(BOOT_BUTTON_GPIO) { InitializeI2c(); InitializeSpi(); InitializeDisplay(); InitializeButtons(); InitializeTools(); GetBacklight()->SetBrightness(100); } virtual AudioCodec* GetAudioCodec() override { static Es8311AudioCodec audio_codec( 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); 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; } }; DECLARE_BOARD(MyCustomBoard); ``` -------------------------------- ### Server Hello Response (JSON) Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mqtt-udp.md The server responds with UDP endpoint details, encryption keys, and audio parameters for establishing the real-time audio channel. ```json { "type": "hello", "transport": "udp", "session_id": "xxx", "audio_params": { "format": "opus", "sample_rate": 24000, "channels": 1, "frame_duration": 60 }, "udp": { "server": "192.168.1.100", "port": 8888, "key": "0123456789ABCDEF0123456789ABCDEF", "nonce": "0123456789ABCDEF0123456789ABCDEF" } } ``` -------------------------------- ### Create Custom Board Directory Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md Use this bash command to create a new directory for your custom board following the `[vendor]-[model]` naming convention. ```bash mkdir main/boards/my-custom-board ``` -------------------------------- ### Clean Project Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md Run `idf.py fullclean` to remove stale build artifacts and configuration files, ensuring a clean build environment. ```bash idf.py fullclean ``` -------------------------------- ### Configure Custom Board in CMakeLists.txt Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md Extend the board-type chain in `main/CMakeLists.txt` to set board-specific variables like directory name, fonts, and emoji collections. ```cmake elseif(CONFIG_BOARD_TYPE_MY_CUSTOM_BOARD) set(BOARD_TYPE "my-custom-board") # must match the directory name set(BUILTIN_TEXT_FONT font_puhui_basic_20_4) # pick a font for the display set(BUILTIN_ICON_FONT font_awesome_20_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) // optional, for emoji display ``` -------------------------------- ### Define Board Hardware Configuration (config.h) Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md Define all hardware-specific settings, including audio parameters, I2S pin mapping, codec details, button and LED pins, and display configurations in this C header file. ```c #ifndef _BOARD_CONFIG_H_ #define _BOARD_CONFIG_H_ #include // Audio #define AUDIO_INPUT_SAMPLE_RATE 24000 #define AUDIO_OUTPUT_SAMPLE_RATE 24000 #define AUDIO_I2S_GPIO_MCLK GPIO_NUM_10 #define AUDIO_I2S_GPIO_WS GPIO_NUM_12 #define AUDIO_I2S_GPIO_BCLK GPIO_NUM_8 #define AUDIO_I2S_GPIO_DIN GPIO_NUM_7 #define AUDIO_I2S_GPIO_DOUT GPIO_NUM_11 #define AUDIO_CODEC_PA_PIN GPIO_NUM_13 #define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_0 #define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_1 #define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR // Buttons #define BOOT_BUTTON_GPIO GPIO_NUM_9 // Display #define DISPLAY_SPI_SCK_PIN GPIO_NUM_3 #define DISPLAY_SPI_MOSI_PIN GPIO_NUM_5 #define DISPLAY_DC_PIN GPIO_NUM_6 #define DISPLAY_SPI_CS_PIN GPIO_NUM_4 #define DISPLAY_WIDTH 320 #define DISPLAY_HEIGHT 240 #define DISPLAY_MIRROR_X true #define DISPLAY_MIRROR_Y false #define DISPLAY_SWAP_XY true #define DISPLAY_OFFSET_X 0 #define DISPLAY_OFFSET_Y 0 #define DISPLAY_BACKLIGHT_PIN GPIO_NUM_2 #define DISPLAY_BACKLIGHT_OUTPUT_INVERT true #endif // _BOARD_CONFIG_H_ ``` -------------------------------- ### Define Build Configuration (config.json) Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/custom-board.md Configure build settings for your custom board, including the target chip, firmware package name, and additional SDK configurations. This JSON file is used by the `scripts/release.py` script. ```json { "target": "esp32s3", "builds": [ { "name": "my-custom-board", "sdkconfig_append": [ "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y", "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\"" ] } ] } ``` -------------------------------- ### Select Audio Processor Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Appends the appropriate audio processor source file based on the CONFIG_USE_AUDIO_PROCESSOR Kconfig option. ```cmake if(CONFIG_USE_AUDIO_PROCESSOR) list(APPEND SOURCES "audio/processors/afe_audio_processor.cc") else() list(APPEND SOURCES "audio/processors/no_audio_processor.cc") endif() ``` -------------------------------- ### Electron-Bot Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Sets default text, icon fonts, and emoji collection for the electron-bot board. ```cmake set(BOARD_TYPE "electron-bot") set(BUILTIN_TEXT_FONT font_puhui_20_4) set(BUILTIN_ICON_FONT font_awesome_20_4) set(DEFAULT_EMOJI_COLLECTION otto-gif) ``` -------------------------------- ### Minsi-K08-Dual Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Sets default text, icon fonts, and emoji collection for the minsi-k08-dual board. ```cmake set(BOARD_TYPE "minsi-k08-dual") set(BUILTIN_TEXT_FONT font_puhui_basic_20_4) set(BUILTIN_ICON_FONT font_awesome_20_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) ``` -------------------------------- ### Set ESP-IDF Build Target Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/movecall-moji2-esp32c5/README.md Initialize the project to target the ESP32-C5 chip. This command must be run before building. ```bash idf.py set-target esp32c5 ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/78/xiaozhi-esp32/blob/main/scripts/ogg_converter/README.md Commands to create a Python virtual environment and activate it on different operating systems. This isolates project dependencies. ```bash # 创建虚拟环境 python -m venv venv # 激活虚拟环境 source venv/bin/activate # Mac/Linux venv\Scripts\activate # Windows ``` -------------------------------- ### XMINI_C3_4G Board Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Configures the XMINI_C3_4G board with specific text and icon fonts. ```cmake set(BOARD_TYPE "xmini-c3-4g") set(BUILTIN_TEXT_FONT font_puhui_basic_14_1) set(BUILTIN_ICON_FONT font_awesome_14_1) ``` -------------------------------- ### Tool Registration APIs Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md APIs for registering tools on the McpServer singleton. `AddTool` is for regular tools, while `AddUserOnlyTool` is for privileged actions. ```APIDOC ## McpServer::AddTool ### Description Registers a regular tool that is visible in the default `tools/list` response and callable by the AI model. ### Signature ```cpp void AddTool( const std::string& name, // unique tool name, e.g. self.dog.forward const std::string& description, // short description for the model const PropertyList& properties, // input parameters (may be empty); supported types: bool, int, string std::function callback // implementation ); ``` ## McpServer::AddUserOnlyTool ### Description Registers a hidden tool, only returned when the backend lists tools with `withUserTools=true`. Use this for privileged or user-initiated actions. ### Signature ```cpp void AddUserOnlyTool( const std::string& name, const std::string& description, const PropertyList& properties, std::function callback ); ``` ### Parameters - `name` (string) - Required - Unique identifier for the tool. A `module.action` naming style is recommended. - `description` (string) - Required - Natural-language description used by the AI to decide when to call the tool. - `properties` (PropertyList) - Optional - Input parameters for the tool. Supported property types are boolean, integer, and string, with optional min/max and default values. - `callback` (std::function) - Required - The implementation of the tool. Return values can be `bool`, `int`, or `std::string`. ``` -------------------------------- ### Configure Screen Pixel Format Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/lilygo-t-display-p4/README.md In menuconfig, under 'Xiaozhi Assistant -> Select the color format of the screen', select the desired pixel format for the display. ```bash Xiaozhi Assistant -> Select the color format of the screen -> (Select the screen pixel format you need to configure) ``` -------------------------------- ### Format a single file with clang-format Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/code_style.md Applies formatting to a specific file in place. ```bash clang-format -i path/to/your/file.cpp ``` -------------------------------- ### Select LILYGO T-Display-P4 Board Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/lilygo-t-display-p4/README.md Within menuconfig, navigate to 'Xiaozhi Assistant -> Board Type' and select 'LILYGO T-Display-P4' to configure the board. ```bash Xiaozhi Assistant -> Board Type -> LILYGO T-Display-P4 ``` -------------------------------- ### Discover Tools Response Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-protocol.md The device's response listing available tools, their descriptions, and input schemas. Includes a `nextCursor` for pagination. ```json { "jsonrpc": "2.0", "id": 2, "result": { "tools": [ { "name": "self.get_device_status", "description": "...", "inputSchema": { ... } }, { "name": "self.audio_speaker.set_volume", "description": "...", "inputSchema": { ... } } ], "nextCursor": "..." } } ``` -------------------------------- ### WAVESHARE_ESP32_S3_AUDIO_BOARD Board Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Configures the WAVESHARE_ESP32_S3_AUDIO_BOARD with manufacturer, board type, and default text and icon fonts. ```cmake set(MANUFACTURER "waveshare") set(BOARD_TYPE "esp32-s3-audio-board") set(BUILTIN_TEXT_FONT font_puhui_basic_16_4) ``` -------------------------------- ### Zhengchen-1.54tft-wifi Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Sets default text, icon fonts, and emoji collection for the zhengchen-1.54tft-wifi board. ```cmake set(BOARD_TYPE "zhengchen-1.54tft-wifi") set(BUILTIN_TEXT_FONT font_puhui_basic_20_4) set(BUILTIN_ICON_FONT font_awesome_20_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) ``` -------------------------------- ### M5STACK_ATOM_S3R_ECHO_PYRAMID Board Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Configures the M5STACK_ATOM_S3R_ECHO_PYRAMID board with specific text and icon fonts, and a default emoji collection. ```cmake set(BOARD_TYPE "atoms3r-echo-pyramid") set(BUILTIN_TEXT_FONT font_puhui_basic_16_4) set(BUILTIN_ICON_FONT font_awesome_16_4) set(DEFAULT_EMOJI_COLLECTION twemoji_32) ``` -------------------------------- ### Configure ESP32-P4 Wi-Fi Slave Target Source: https://github.com/78/xiaozhi-esp32/blob/main/main/boards/wireless-tag-wtp4c5mp07s/README.md Set the Wi-Fi slave target in menuconfig to esp32c5. ```bash Component config -> Wi-Fi Remote -> choose slave target -> esp32c5 ``` -------------------------------- ### Call Chassis Go Forward Tool with MCP Source: https://github.com/78/xiaozhi-esp32/blob/main/docs/mcp-usage.md Use this JSON-RPC call to instruct the device's chassis to move forward. Ensure the tool name and arguments match the registered tool. ```json { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "self.chassis.go_forward", "arguments": {} }, "id": 2 } ``` -------------------------------- ### Set URL and Create Emoji Directory for ESP-HI Board Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Conditionally sets a URL and creates an 'emoji' directory in the binary directory if the CONFIG_BOARD_TYPE_ESP_HI is defined. ```cmake if(CONFIG_BOARD_TYPE_ESP_HI) set(URL "https://github.com/espressif2022/image_player/raw/main/test_apps/test_8bit") set(EMOJI_DIR "${CMAKE_BINARY_DIR}/emoji") file(MAKE_DIRECTORY ${EMOJI_DIR}) endif() ``` -------------------------------- ### Flash Assets to ESP32 Partition Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt This section of the CMakeLists.txt handles flashing assets to the ESP32's 'assets' partition based on different build configurations. It supports flashing default, custom, or expression-generated assets. ```cmake partition_table_get_partition_info(size "--partition-name assets" "size") partition_table_get_partition_info(offset "--partition-name assets" "offset") if ("${size}" AND "${offset}") # Flash assets based on configuration if(CONFIG_FLASH_DEFAULT_ASSETS) # Build default assets based on configuration build_default_assets_bin() esptool_py_flash_to_partition(flash "assets" "${GENERATED_ASSETS_LOCAL_FILE}") message(STATUS "Generated default assets flash configured: ${GENERATED_ASSETS_LOCAL_FILE} -> assets partition") elseif(CONFIG_FLASH_CUSTOM_ASSETS) # Flash custom assets get_assets_local_file("${CONFIG_CUSTOM_ASSETS_FILE}" ASSETS_LOCAL_FILE) esptool_py_flash_to_partition(flash "assets" "${ASSETS_LOCAL_FILE}") message(STATUS "Custom assets flash configured: ${ASSETS_LOCAL_FILE} -> assets partition") elseif(CONFIG_FLASH_EXPRESSION_ASSETS) set(ASSETS_NAME "expression_assets") set(ASSETS_PARTITION "assets") set(ASSETS_FILE "${CMAKE_BINARY_DIR}/${ASSETS_NAME}.bin") build_speaker_assets_bin("${ASSETS_PARTITION}" ${EMOTE_RESOLUTION} ${ASSETS_FILE} ${CONFIG_MMAP_FILE_NAME_LENGTH}) message(STATUS "Generated emote assets: ${ASSETS_FILE} -> ${ASSETS_PARTITION} partition") esptool_py_flash_to_partition(flash "${ASSETS_PARTITION}" "${ASSETS_FILE}") elseif(CONFIG_FLASH_NONE_ASSETS) message(STATUS "Assets flashing disabled (FLASH_NONE_ASSETS)") endif() else() message(STATUS "Assets partition not found, using v1 partition table") endif() ``` -------------------------------- ### Freenove-ESP32S3-DISPLAY-2.8-LCD Configuration Source: https://github.com/78/xiaozhi-esp32/blob/main/main/CMakeLists.txt Sets default text, icon fonts, and emoji collection for the freenove-esp32s3-display-2.8-lcd board. ```cmake set(BOARD_TYPE "freenove-esp32s3-display-2.8-lcd") set(BUILTIN_TEXT_FONT font_puhui_basic_20_4) set(BUILTIN_ICON_FONT font_awesome_20_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) ```