SOC-ESP32S3部分:36-适配自己的板卡

飞书文档https://x509p6c8to.feishu.cn/wiki/RP4UwPrsKi4xuQkKLAAcKxD3n1b

如果你自己画了PCB板,需要把自己绘制的板卡配置小智AI工程,可以参考此文档。

下载源码

克隆或下载源码到本地,这里以1.5.5为例,大家可以自行修改其它版本

复制代码
虾哥版本的源码
https://github.com/78/xiaozhi-esp32/tree/v1.5.5

代码结构

仓库包含多个文件和文件夹,主要结构如下:

复制代码
.gitignore                    git工程管理文件
CMakeLists.txt                工程cmake构建文件
LICENSE                       MIT License 允许用户自由使用、修改和分发代码,只需在软件或文档中包含原作者的版权声明和许可声明即可。                
README.md                     README说明文档_中文
README_en.md                  README说明文档_英文
README_ja.md                  README说明文档_日文
partitions.csv                分区配置文件:16M Flash的分区表,默认选择,可以通过idf.py menuconfig修改,建议选择支持16M的硬件,后续扩展开发和OTA更方便
partitions_32M_sensecap.csv   分区配置文件:32M Flash的分区表
partitions_4M.csv             分区配置文件:4M Flash的分区表
partitions_8M.csv             分区配置文件:8M Flash的分区表
sdkconfig.defaults            idf sdk默认配置,工程目前支持esp32s3和esp32c3两款芯片,只有s3支持唤醒词,基于乐鑫esp-sr实现
sdkconfig.defaults.esp32c3    idf sdk esp32c3默认配置
sdkconfig.defaults.esp32s3    idf sdk esp32s3默认配置
docs/     文档文件,里面包含README文档使用的图片资料,还有一份服务器websocket交互协议
scripts/  脚本文件,包含音频编码测试脚本、烧录调试脚本、版本打包相关脚本
.github/  GitHub Actions 的配置文件(.yaml 格式),用于定义项目的自动化工作流程,例如代码的持续集成(CI),可以在每次代码推送到仓库时自动运行测试、代码检查等任务
main/     主要源码文件夹

添加构建配置

下方配置已经在工程中配置好,如果你需要自己重新设计硬件,可以参考下方流程,添加自己的板卡适配:

在xiaozhi-esp32/main/CMakeLists.txt 添加编译构建指令

复制代码
elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_1_54TFT_ML307)
    set(BOARD_TYPE "xingzhi-cube-1.54tft-ml307")
elseif(CONFIG_BOARD_TYPE_XINGZHI_AIO_S3)
    set(BOARD_TYPE "xiaozhi-all-in-one-s3")
endif()

在xiaozhi-esp32/main/Kconfig.projbuild添加配置指令

复制代码
    config BOARD_TYPE_XINGZHI_Cube_1_54TFT_ML307
        bool "无名科技星智1.54(ML307)"
    config BOARD_TYPE_XINGZHI_AIO_S3
        bool "xiaozhi All in One 多合一版本"
endchoice

在boards中添加文件夹:

xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3

在xiaozhi-all-in-one-s3文件夹中创建config.h文件xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3/config.h

这个文件主要配置板卡的硬件接口和相关参数

复制代码
#ifndef _BOARD_CONFIG_H_
#define _BOARD_CONFIG_H_

#include <driver/gpio.h>

// 该头文件用于配置 xiaozhi-all-in-one-s3 开发板的相关参数

/*
定义音频 I2S 接口相关的 GPIO 引脚
*/
// 音频 I2S 接口的主时钟信号(MCLK)
#define AUDIO_I2S_GPIO_MCLK     GPIO_NUM_6
// 音频 I2S 接口的字选择信号(WS)
#define AUDIO_I2S_GPIO_WS       GPIO_NUM_12
// 音频 I2S 接口的位时钟信号(BCLK)
#define AUDIO_I2S_GPIO_BCLK     GPIO_NUM_14
// 音频 I2S 接口的数据输入信号(DIN)
#define AUDIO_I2S_GPIO_DIN      GPIO_NUM_13
// 音频 I2S 接口的数据输出信号(DOUT)
#define AUDIO_I2S_GPIO_DOUT     GPIO_NUM_11

// 音频编解码器的功率放大器(PA)
#define AUDIO_CODEC_PA_PIN       GPIO_NUM_10
// 音频编解码器 I2C 通信的数据信号线(SDA)
#define AUDIO_CODEC_I2C_SDA_PIN  GPIO_NUM_5
// 音频编解码器 I2C 通信的时钟信号线(SCL)
#define AUDIO_CODEC_I2C_SCL_PIN  GPIO_NUM_4
// 音频编解码器 ES8311 的默认 I2C 地址
#define AUDIO_CODEC_ES8311_ADDR  ES8311_CODEC_DEFAULT_ADDR

/*
音频参数
*/
#define AUDIO_INPUT_SAMPLE_RATE  24000
// 音频输入的采样率设置为 24000Hz
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
// 音频输出的采样率设置为 24000Hz

/*
定义显示 SPI 接口相关的 GPIO 引脚
 */
// 显示 SPI 接口的时钟信号(SCLK)
#define DISPLAY_SPI_SCLK_PIN    GPIO_NUM_16
// 显示 SPI 接口的主输出从输入信号(MOSI)
#define DISPLAY_SPI_MOSI_PIN    GPIO_NUM_17
// 显示 SPI 接口的片选信号(CS)
#define DISPLAY_SPI_CS_PIN      GPIO_NUM_15
// 显示 SPI 接口的数据/命令选择信号(DC)
#define DISPLAY_SPI_DC_PIN      GPIO_NUM_21
// 显示 SPI 接口的复位信号(RESET)
#define DISPLAY_SPI_RESET_PIN   GPIO_NUM_18
// 显示 SPI 接口的时钟频率设置为 40MHz
#define DISPLAY_SPI_SCLK_HZ     (40 * 1000 * 1000)

// 显示屏背光灯控制引脚使用的 GPIO
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_42
// 显示屏背光灯输出是否反转
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT true

/*
显示参数
*/
// 显示屏的宽度为 172 像素
#define DISPLAY_WIDTH   172
// 显示屏的高度为 320 像素
#define DISPLAY_HEIGHT  320
// 是否交换 X 和 Y 坐标,这里设置为交换
#define DISPLAY_SWAP_XY false
// 是否在 Y 轴上镜像显示,这里设置为镜像
#define DISPLAY_MIRROR_Y false
// 是否在 X 轴上镜像显示,这里设置为不镜像
#define DISPLAY_MIRROR_X false
// 显示屏在 X 轴上的偏移量为 0
#define DISPLAY_OFFSET_X  34
// 显示屏在 Y 轴上的偏移量为 0
#define DISPLAY_OFFSET_Y  0

/**
 * 外设IO配置
 */
// 开发板上内置 LED 灯使用的 GPIO
#define BUILTIN_LED_GPIO        GPIO_NUM_9
// 开发板上的启动按钮使用的 GPIO
#define BOOT_BUTTON_GPIO        GPIO_NUM_0

#endif // _BOARD_CONFIG_H_

创建config.json,描述sdk配置说明,目前板卡无需特别配置,所以sdkconfig_append为空

xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3/config.json

复制代码
{
    "target": "esp32s3",
    "builds": [
        {
            "name": "xiaozhi-all-in-one-s3",
            "sdkconfig_append": []
        }
    ]
}

添加板卡实现xiaozhi_all_in_one_s3.cc文件xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3/xiaozhi_all_in_one_s3.cc

这个文件主要对板卡硬件初始化部分进行实现

复制代码
#include <wifi_station.h>
#include <esp_log.h>
#include <esp_efuse_table.h>
#include <driver/i2c_master.h>
#include <driver/spi_common.h>
#include <driver/gpio.h>
#include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h>
#include <esp_lcd_panel_vendor.h>

#include "wifi_board.h"
#include "audio_codecs/es8311_audio_codec.h"
#include "display/lcd_display.h"
#include "aio_lcd_display.h"
#include "application.h"
#include "button.h"
#include "iot/thing_manager.h"
#include "led/single_led.h"

#include "config.h"

#define TAG "XiaozhiAioBoard"

LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);

class XiaozhiAioBoard : public WifiBoard {
private:
    i2c_master_bus_handle_t codec_i2c_bus_;
    Button boot_button_;
    Display* display_;

    // IIC初始化
    void InitializeCodecI2c() {
        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_SCLK_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(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO));
    }

    // 屏幕初始化
    void InitializeSt7789Display() {
        esp_lcd_panel_io_handle_t panel_io = nullptr;
        esp_lcd_panel_handle_t panel = nullptr;
        ESP_LOGD(TAG, "Install panel IO");
        esp_lcd_panel_io_spi_config_t io_config = {};
        io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN;
        io_config.dc_gpio_num = DISPLAY_SPI_DC_PIN;
        io_config.spi_mode = 3;
        io_config.pclk_hz = DISPLAY_SPI_SCLK_HZ;
        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(SPI3_HOST, &io_config, &panel_io));

        // 初始化液晶屏驱动芯片ST7789
        ESP_LOGD(TAG, "Install LCD driver");
        esp_lcd_panel_dev_config_t panel_config = {};
        panel_config.reset_gpio_num = DISPLAY_SPI_RESET_PIN;
        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_ERROR_CHECK(esp_lcd_panel_reset(panel));
        ESP_ERROR_CHECK(esp_lcd_panel_init(panel));
        ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY));
        ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y));
        ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel, true));

        display_ = new AioLcdDisplay(panel_io, panel,
                            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY,
                            {
                                .text_font = &font_puhui_20_4,
                                .icon_font = &font_awesome_20_4,
                                .emoji_font = font_emoji_64_init(),
                            });
    }

    // 按键初始化
    void InitializeButtons() {
        boot_button_.OnClick([this]() {
            auto& app = Application::GetInstance();
            if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
                ResetWifiConfiguration();
            }
            app.ToggleChatState();
        });
    }

    // 物联网初始化,添加对 AI 可见设备
    void InitializeIot() {
        auto& thing_manager = iot::ThingManager::GetInstance();
        thing_manager.AddThing(iot::CreateThing("Speaker"));
        thing_manager.AddThing(iot::CreateThing("Backlight"));  
    }

public:
    XiaozhiAioBoard() : boot_button_(BOOT_BUTTON_GPIO) { 
        InitializeCodecI2c();
        InitializeSpi();
        InitializeSt7789Display();
        InitializeButtons();
        InitializeIot();
        GetAudioCodec()->SetOutputVolume(90);
        GetBacklight()->RestoreBrightness();
    }

    virtual Led* GetLed() override {
        static SingleLed led_strip(BUILTIN_LED_GPIO);
        return &led_strip;
    }

    virtual Display* GetDisplay() override {
        return display_;
    }

    virtual Backlight* GetBacklight() override {
        static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
        return &backlight;
    }

    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;
    }
};

DECLARE_BOARD(XiaozhiAioBoard);

添加README.md工程使用说明书

xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3/README.md

复制代码
# 编译配置命令

**配置编译目标为 ESP32S3:**

```bash
idf.py set-target esp32s3
```

**打开 menuconfig:**

```bash
idf.py menuconfig
```

**选择板子:**

```
Xiaozhi Assistant -> Board Type -> xiaozhi All in One 多合一版本
```


**编译:**

```bash
idf.py build
```

最后按说明书进行配置编译即可

复制代码
idf.py set-target esp32s3
idf.py menuconfig
Xiaozhi Assistant -> Board Type -> xiaozhi All in One 多合一版本
idf.py build
相关推荐
azwsm1 小时前
电路元器件和GPIO控制器
单片机·嵌入式硬件
kebidaixu4 小时前
FreeRTOS 移植到 STM32F407VETX 记录(一)
stm32·单片机·嵌入式硬件
CSDN官方博客5 小时前
「谁说嵌入式只是调包和焊板子?」—— 2026嵌入式全栈技术征锋令
嵌入式硬件·物联网·embedding
点灯小铭5 小时前
基于单片机的数码管定时插座设计与定时开关功能实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
点灯小铭8 小时前
基于单片机的多模式智能洗衣机设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
项目題供诗8 小时前
STM32-AD单通道&AD多通道(十九)
stm32·单片机·嵌入式硬件
南岸的水8 小时前
BMS国标充电解析
单片机·嵌入式硬件·mcu
清风6666668 小时前
基于单片机的可调数控电源设计
单片机·嵌入式硬件·mongodb·毕业设计·课程设计·期末大作业
sramdram8 小时前
低功耗国产蓝牙芯片,蓝牙MCU方案
单片机·嵌入式硬件·mcu·蓝牙mcu·蓝牙方案
yuan199979 小时前
CMS8S5880 电子锁程序(51单片机)
单片机·嵌入式硬件·51单片机