From 2e40ad0e8ab2da2973f820586cc85d8cc515da80 Mon Sep 17 00:00:00 2001 From: ooxxU <71391474@qq.com> Date: Fri, 24 Jan 2025 02:55:03 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=94=AF=E6=8C=81=20M5Stack=20=20Atom=20M?= =?UTF-8?q?atrix=20+=20ES8311=20+=20NS4150B=20(#105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2. 支持 ESP32 4M 的设备,修订 NoAudioCodec 兼容 ESP32 --- main/CMakeLists.txt | 9 ++ main/Kconfig.projbuild | 2 + main/audio_codecs/es8311_audio_codec.cc | 14 +- main/audio_codecs/no_audio_codec.cc | 39 +++-- main/boards/atommatrix-echo-base/README.md | 37 +++++ .../atommatrix_echo_base.cc | 138 ++++++++++++++++++ main/boards/atommatrix-echo-base/config.h | 30 ++++ 7 files changed, 252 insertions(+), 17 deletions(-) create mode 100644 main/boards/atommatrix-echo-base/README.md create mode 100644 main/boards/atommatrix-echo-base/atommatrix_echo_base.cc create mode 100644 main/boards/atommatrix-echo-base/config.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 5b87587a..2e82a24a 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -60,6 +60,8 @@ elseif(CONFIG_BOARD_TYPE_M5STACK_CORE_S3) set(BOARD_TYPE "m5stack-core-s3") elseif(CONFIG_BOARD_TYPE_ATOMS3R_ECHO_BASE) set(BOARD_TYPE "atoms3r-echo-base") +elseif(CONFIG_BOARD_TYPE_ATOMMATRIX_ECHO_BASE) + set(BOARD_TYPE "atommatrix-echo-base") elseif(CONFIG_BOARD_TYPE_XMINI_C3) set(BOARD_TYPE "xmini-c3") elseif(CONFIG_BOARD_TYPE_ESP32S3_KORVO2_V3) @@ -82,6 +84,13 @@ if(CONFIG_IDF_TARGET_ESP32S3) list(APPEND SOURCES "audio_processing/audio_processor.cc" "audio_processing/wake_word_detect.cc") endif() +# 如果目标芯片是 ESP32,则排除特定文件 +if(CONFIG_IDF_TARGET_ESP32) + # 排除 "audio_codecs/box_audio_codec.cc" 和 "audio_codecs/cores3_audio_codec.cc" + list(REMOVE_ITEM SOURCES "audio_codecs/box_audio_codec.cc" + "audio_codecs/cores3_audio_codec.cc") +endif() + idf_component_register(SRCS ${SOURCES} EMBED_FILES "assets/err_reg.p3" "assets/err_pin.p3" "assets/wificonfig.p3" "assets/upgrade.p3" INCLUDE_DIRS ${INCLUDE_DIRS} diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 98af4f9a..5fb7a721 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -62,6 +62,8 @@ choice BOARD_TYPE bool "M5Stack CoreS3" config BOARD_TYPE_ATOMS3R_ECHO_BASE bool "AtomS3R + Echo Base" + config BOARD_TYPE_ATOMMATRIX_ECHO_BASE + bool "AtomMatrix + Echo Base" config BOARD_TYPE_XMINI_C3 bool "虾哥 Mini C3" config BOARD_TYPE_ESP32S3_KORVO2_V3 diff --git a/main/audio_codecs/es8311_audio_codec.cc b/main/audio_codecs/es8311_audio_codec.cc index 8ad34e59..41719869 100644 --- a/main/audio_codecs/es8311_audio_codec.cc +++ b/main/audio_codecs/es8311_audio_codec.cc @@ -92,8 +92,10 @@ void Es8311AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp .clk_cfg = { .sample_rate_hz = (uint32_t)output_sample_rate_, .clk_src = I2S_CLK_SRC_DEFAULT, - .ext_clk_freq_hz = 0, - .mclk_multiple = I2S_MCLK_MULTIPLE_256 + .mclk_multiple = I2S_MCLK_MULTIPLE_256, + #ifdef I2S_HW_VERSION_2 + .ext_clk_freq_hz = 0, + #endif }, .slot_cfg = { .data_bit_width = I2S_DATA_BIT_WIDTH_16BIT, @@ -103,9 +105,11 @@ void Es8311AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp .ws_width = I2S_DATA_BIT_WIDTH_16BIT, .ws_pol = false, .bit_shift = true, - .left_align = true, - .big_endian = false, - .bit_order_lsb = false + #ifdef I2S_HW_VERSION_2 + .left_align = true, + .big_endian = false, + .bit_order_lsb = false + #endif }, .gpio_cfg = { .mclk = mclk, diff --git a/main/audio_codecs/no_audio_codec.cc b/main/audio_codecs/no_audio_codec.cc index f0cbcd0e..cc62f136 100644 --- a/main/audio_codecs/no_audio_codec.cc +++ b/main/audio_codecs/no_audio_codec.cc @@ -35,8 +35,11 @@ NoAudioCodecDuplex::NoAudioCodecDuplex(int input_sample_rate, int output_sample_ .clk_cfg = { .sample_rate_hz = (uint32_t)output_sample_rate_, .clk_src = I2S_CLK_SRC_DEFAULT, - .ext_clk_freq_hz = 0, - .mclk_multiple = I2S_MCLK_MULTIPLE_256 + .mclk_multiple = I2S_MCLK_MULTIPLE_256, + #ifdef I2S_HW_VERSION_2 + .ext_clk_freq_hz = 0, + #endif + }, .slot_cfg = { .data_bit_width = I2S_DATA_BIT_WIDTH_32BIT, @@ -46,9 +49,12 @@ NoAudioCodecDuplex::NoAudioCodecDuplex(int input_sample_rate, int output_sample_ .ws_width = I2S_DATA_BIT_WIDTH_32BIT, .ws_pol = false, .bit_shift = true, - .left_align = true, - .big_endian = false, - .bit_order_lsb = false + #ifdef I2S_HW_VERSION_2 + .left_align = true, + .big_endian = false, + .bit_order_lsb = false + #endif + }, .gpio_cfg = { .mclk = I2S_GPIO_UNUSED, @@ -89,8 +95,11 @@ NoAudioCodecSimplex::NoAudioCodecSimplex(int input_sample_rate, int output_sampl .clk_cfg = { .sample_rate_hz = (uint32_t)output_sample_rate_, .clk_src = I2S_CLK_SRC_DEFAULT, - .ext_clk_freq_hz = 0, - .mclk_multiple = I2S_MCLK_MULTIPLE_256 + .mclk_multiple = I2S_MCLK_MULTIPLE_256, + #ifdef I2S_HW_VERSION_2 + .ext_clk_freq_hz = 0, + #endif + }, .slot_cfg = { .data_bit_width = I2S_DATA_BIT_WIDTH_32BIT, @@ -100,9 +109,12 @@ NoAudioCodecSimplex::NoAudioCodecSimplex(int input_sample_rate, int output_sampl .ws_width = I2S_DATA_BIT_WIDTH_32BIT, .ws_pol = false, .bit_shift = true, - .left_align = true, - .big_endian = false, - .bit_order_lsb = false + #ifdef I2S_HW_VERSION_2 + .left_align = true, + .big_endian = false, + .bit_order_lsb = false + #endif + }, .gpio_cfg = { .mclk = I2S_GPIO_UNUSED, @@ -150,8 +162,11 @@ NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm(int input_sample_rate, int output .clk_cfg = { .sample_rate_hz = (uint32_t)output_sample_rate_, .clk_src = I2S_CLK_SRC_DEFAULT, - .ext_clk_freq_hz = 0, - .mclk_multiple = I2S_MCLK_MULTIPLE_256 + .mclk_multiple = I2S_MCLK_MULTIPLE_256, + #ifdef I2S_HW_VERSION_2 + .ext_clk_freq_hz = 0, + #endif + }, .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO), .gpio_cfg = { diff --git a/main/boards/atommatrix-echo-base/README.md b/main/boards/atommatrix-echo-base/README.md new file mode 100644 index 00000000..7651452d --- /dev/null +++ b/main/boards/atommatrix-echo-base/README.md @@ -0,0 +1,37 @@ +# 编译配置命令 + +**配置编译目标为 ESP32:** + +```bash +idf.py set-target esp32s3 +``` + +**打开 menuconfig:** + +```bash +idf.py menuconfig +``` + +**选择板子:** + +``` +Xiaozhi Assistant -> Board Type -> AtomMatrix + Echo Base +``` + +**修改 flash 大小:** + +``` +Serial flasher config -> Flash size -> 4 MB +``` + +**修改分区表:** + +``` +Partition Table -> Custom partition CSV file -> partitions_4M.csv +``` + +**编译:** + +```bash +idf.py build +``` \ No newline at end of file diff --git a/main/boards/atommatrix-echo-base/atommatrix_echo_base.cc b/main/boards/atommatrix-echo-base/atommatrix_echo_base.cc new file mode 100644 index 00000000..ccc6ec6e --- /dev/null +++ b/main/boards/atommatrix-echo-base/atommatrix_echo_base.cc @@ -0,0 +1,138 @@ +#include "wifi_board.h" +#include "audio_codecs/es8311_audio_codec.h" +#include "application.h" +#include "button.h" +#include "config.h" +#include "i2c_device.h" +#include "iot/thing_manager.h" + +#include +#include +#include +#include "led/circular_strip.h" + +#define TAG "XX+EchoBase" + +#define PI4IOE_ADDR 0x43 +#define PI4IOE_REG_CTRL 0x00 +#define PI4IOE_REG_IO_PP 0x07 +#define PI4IOE_REG_IO_DIR 0x03 +#define PI4IOE_REG_IO_OUT 0x05 +#define PI4IOE_REG_IO_PULLUP 0x0D + +class Pi4ioe : public I2cDevice { +public: + Pi4ioe(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) { + WriteReg(PI4IOE_REG_IO_PP, 0x00); // Set to high-impedance + WriteReg(PI4IOE_REG_IO_PULLUP, 0xFF); // Enable pull-up + WriteReg(PI4IOE_REG_IO_DIR, 0x6E); // Set input=0, output=1 + WriteReg(PI4IOE_REG_IO_OUT, 0xFF); // Set outputs to 1 + } + + void SetSpeakerMute(bool mute) { + WriteReg(PI4IOE_REG_IO_OUT, mute ? 0x00 : 0xFF); + } +}; + + +class AtomMatrixEchoBaseBoard : public WifiBoard { +private: + i2c_master_bus_handle_t i2c_bus_; + + Pi4ioe* pi4ioe_; + + Button face_button_; + + void InitializeI2c() { + // Initialize I2C peripheral + i2c_master_bus_config_t i2c_bus_cfg = { + .i2c_port = I2C_NUM_1, + .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 I2cDetect() { + uint8_t address; + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n"); + for (int i = 0; i < 128; i += 16) { + printf("%02x: ", i); + for (int j = 0; j < 16; j++) { + fflush(stdout); + address = i + j; + esp_err_t ret = i2c_master_probe(i2c_bus_, address, pdMS_TO_TICKS(200)); + if (ret == ESP_OK) { + printf("%02x ", address); + } else if (ret == ESP_ERR_TIMEOUT) { + printf("UU "); + } else { + printf("-- "); + } + } + printf("\r\n"); + } + } + + void InitializePi4ioe() { + ESP_LOGI(TAG, "Init PI4IOE"); + pi4ioe_ = new Pi4ioe(i2c_bus_, PI4IOE_ADDR); + pi4ioe_->SetSpeakerMute(false); + } + + + void InitializeButtons() { + face_button_.OnClick([this]() { + + ESP_LOGI(TAG, " ===>>> face_button_.OnClick "); + 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")); + } + +public: + AtomMatrixEchoBaseBoard() : face_button_(BOOT_BUTTON_GPIO) { + InitializeI2c(); + I2cDetect(); + InitializePi4ioe(); + InitializeButtons(); + InitializeIot(); + } + + virtual Led* GetLed() override { + + static CircularStrip led(BUILTIN_LED_GPIO, 25); + return &led; + } + + virtual AudioCodec* GetAudioCodec() override { + static Es8311AudioCodec* audio_codec = nullptr; + if (audio_codec == nullptr) { + audio_codec = new Es8311AudioCodec(i2c_bus_, I2C_NUM_1, 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_GPIO_PA, AUDIO_CODEC_ES8311_ADDR, false); + } + return audio_codec; + } + +}; + +DECLARE_BOARD(AtomMatrixEchoBaseBoard); diff --git a/main/boards/atommatrix-echo-base/config.h b/main/boards/atommatrix-echo-base/config.h new file mode 100644 index 00000000..d2c70ea7 --- /dev/null +++ b/main/boards/atommatrix-echo-base/config.h @@ -0,0 +1,30 @@ +#ifndef _BOARD_CONFIG_H_ +#define _BOARD_CONFIG_H_ + +// AtomMatrix+EchoBase Board configuration + +#include + +#define AUDIO_INPUT_REFERENCE true +#define AUDIO_INPUT_SAMPLE_RATE 24000 +#define AUDIO_OUTPUT_SAMPLE_RATE 24000 + +#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_NC +#define AUDIO_I2S_GPIO_WS GPIO_NUM_19 +#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_33 +#define AUDIO_I2S_GPIO_DIN GPIO_NUM_23 +#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_22 + +#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_25 +#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_21 +#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR +#define AUDIO_CODEC_GPIO_PA GPIO_NUM_NC + +#define BUILTIN_LED_GPIO GPIO_NUM_27 +#define BOOT_BUTTON_GPIO GPIO_NUM_39 +#define VOLUME_UP_BUTTON_GPIO GPIO_NUM_NC +#define VOLUME_DOWN_BUTTON_GPIO GPIO_NUM_NC + + + +#endif // _BOARD_CONFIG_H_