diff --git a/README.md b/README.md index 64011bf..736fa56 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ - 乐鑫 ESP32-S3-BOX3 - M5Stack CoreS3 - AtomS3R + Echo Base +- AtomMatrix + Echo Base - 神奇按钮 2.4 - 微雪电子 ESP32-S3-Touch-AMOLED-1.8 - LILYGO T-Circle-S3 @@ -70,6 +71,9 @@ + + + diff --git a/README_en.md b/README_en.md index b4e1e3f..d1172b6 100644 --- a/README_en.md +++ b/README_en.md @@ -51,6 +51,7 @@ Breadboard setup shown below: - Espressif ESP32-S3-BOX3 - M5Stack CoreS3 - AtomS3R + Echo Base +- AtomMatrix + Echo Base - MagiClick 2.4 - Waveshare ESP32-S3-Touch-AMOLED-1.8 - LILYGO T-Circle-S3 @@ -70,6 +71,9 @@ Breadboard setup shown below: + + + diff --git a/docs/AtomMatrix-echo-base.jpg b/docs/AtomMatrix-echo-base.jpg new file mode 100644 index 0000000..979cf81 Binary files /dev/null and b/docs/AtomMatrix-echo-base.jpg differ diff --git a/docs/ESP32-BreadBoard.jpg b/docs/ESP32-BreadBoard.jpg new file mode 100644 index 0000000..f7a6fd4 Binary files /dev/null and b/docs/ESP32-BreadBoard.jpg differ diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index f68420d..ea8eb6e 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -41,6 +41,8 @@ if(CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI) set(BOARD_TYPE "bread-compact-wifi") elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ML307) set(BOARD_TYPE "bread-compact-ml307") +elseif(CONFIG_BOARD_TYPE_BREAD_COMPACT_ESP32) + set(BOARD_TYPE "bread-compact-esp32") elseif(CONFIG_BOARD_TYPE_ESP_BOX_3) set(BOARD_TYPE "esp-box-3") elseif(CONFIG_BOARD_TYPE_KEVIN_BOX_1) @@ -95,7 +97,8 @@ endif() 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") + "audio_codecs/cores3_audio_codec.cc" + "audio_codecs/es8388_audio_codec.cc") endif() idf_component_register(SRCS ${SOURCES} diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 7da7651..7889dc4 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -42,6 +42,8 @@ choice BOARD_TYPE bool "面包板新版接线(WiFi)+ LCD" config BOARD_TYPE_BREAD_COMPACT_ML307 bool "面包板新版接线(ML307 AT)" + config BOARD_TYPE_BREAD_COMPACT_ESP32 + bool "面包板 ESP32 DevKit" config BOARD_TYPE_ESP_BOX_3 bool "ESP BOX 3" config BOARD_TYPE_KEVIN_BOX_1 diff --git a/main/audio_codecs/no_audio_codec.cc b/main/audio_codecs/no_audio_codec.cc index 12e0d50..e38da64 100644 --- a/main/audio_codecs/no_audio_codec.cc +++ b/main/audio_codecs/no_audio_codec.cc @@ -94,8 +94,10 @@ ATK_NoAudioCodecDuplex::ATK_NoAudioCodecDuplex(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 = { .data_bit_width = I2S_DATA_BIT_WIDTH_16BIT, @@ -105,9 +107,11 @@ ATK_NoAudioCodecDuplex::ATK_NoAudioCodecDuplex(int input_sample_rate, int output .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 = I2S_GPIO_UNUSED, diff --git a/main/boards/bread-compact-esp32/README.md b/main/boards/bread-compact-esp32/README.md new file mode 100644 index 0000000..95e5828 --- /dev/null +++ b/main/boards/bread-compact-esp32/README.md @@ -0,0 +1,37 @@ +# 编译配置命令 + +**配置编译目标为 ESP32:** + +```bash +idf.py set-target esp32 +``` + +**打开 menuconfig:** + +```bash +idf.py menuconfig +``` + +**选择板子:** + +``` +Xiaozhi Assistant -> Board Type -> 面包板 ESP32 DevKit +``` + +**修改 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/bread-compact-esp32/config.h b/main/boards/bread-compact-esp32/config.h new file mode 100644 index 0000000..4b13152 --- /dev/null +++ b/main/boards/bread-compact-esp32/config.h @@ -0,0 +1,36 @@ +#ifndef _BOARD_CONFIG_H_ +#define _BOARD_CONFIG_H_ + +#include + +#define AUDIO_INPUT_SAMPLE_RATE 16000 +#define AUDIO_OUTPUT_SAMPLE_RATE 24000 + +// 如果使用 Duplex I2S 模式,请注释下面一行 +#define AUDIO_I2S_METHOD_SIMPLEX + +#ifdef AUDIO_I2S_METHOD_SIMPLEX + +#define AUDIO_I2S_MIC_GPIO_WS GPIO_NUM_25 +#define AUDIO_I2S_MIC_GPIO_SCK GPIO_NUM_26 +#define AUDIO_I2S_MIC_GPIO_DIN GPIO_NUM_32 + +#define AUDIO_I2S_SPK_GPIO_DOUT GPIO_NUM_33 +#define AUDIO_I2S_SPK_GPIO_BCLK GPIO_NUM_14 +#define AUDIO_I2S_SPK_GPIO_LRCK GPIO_NUM_27 + +#else + +#define AUDIO_I2S_GPIO_WS GPIO_NUM_4 +#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_5 +#define AUDIO_I2S_GPIO_DIN GPIO_NUM_6 +#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_7 + +#endif + +#define BOOT_BUTTON_GPIO GPIO_NUM_0 +#define TOUCH_BUTTON_GPIO GPIO_NUM_5 +#define BUILTIN_LED_GPIO GPIO_NUM_2 + + +#endif // _BOARD_CONFIG_H_ diff --git a/main/boards/bread-compact-esp32/esp32_bread_board.cc b/main/boards/bread-compact-esp32/esp32_bread_board.cc new file mode 100644 index 0000000..6bbb251 --- /dev/null +++ b/main/boards/bread-compact-esp32/esp32_bread_board.cc @@ -0,0 +1,80 @@ +#include "wifi_board.h" +#include "audio_codecs/no_audio_codec.h" +#include "system_reset.h" +#include "application.h" +#include "button.h" +#include "config.h" +#include "iot/thing_manager.h" +#include "led/single_led.h" + +#include +#include +#include + +#define TAG "ESP32-MarsbearSupport" + + +class CompactWifiBoard : public WifiBoard { +private: + Button boot_button_; + Button touch_button_; + + void InitializeButtons() { + + // 配置 GPIO + gpio_config_t io_conf = { + .pin_bit_mask = 1ULL << BUILTIN_LED_GPIO, // 设置需要配置的 GPIO 引脚 + .mode = GPIO_MODE_OUTPUT, // 设置为输出模式 + .pull_up_en = GPIO_PULLUP_DISABLE, // 禁用上拉 + .pull_down_en = GPIO_PULLDOWN_DISABLE, // 禁用下拉 + .intr_type = GPIO_INTR_DISABLE // 禁用中断 + }; + gpio_config(&io_conf); // 应用配置 + + boot_button_.OnClick([this]() { + auto& app = Application::GetInstance(); + if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { + ResetWifiConfiguration(); + } + gpio_set_level(BUILTIN_LED_GPIO, 1); + app.ToggleChatState(); + }); + touch_button_.OnPressDown([this]() { + gpio_set_level(BUILTIN_LED_GPIO, 1); + Application::GetInstance().StartListening(); + }); + touch_button_.OnPressUp([this]() { + gpio_set_level(BUILTIN_LED_GPIO, 0); + Application::GetInstance().StopListening(); + }); + } + + // 物联网初始化,添加对 AI 可见设备 + void InitializeIot() { + auto& thing_manager = iot::ThingManager::GetInstance(); + thing_manager.AddThing(iot::CreateThing("Speaker")); + thing_manager.AddThing(iot::CreateThing("Lamp")); + } + +public: + CompactWifiBoard() : boot_button_(BOOT_BUTTON_GPIO), touch_button_(TOUCH_BUTTON_GPIO) + { + InitializeButtons(); + InitializeIot(); + } + + virtual AudioCodec* GetAudioCodec() override + { +#ifdef AUDIO_I2S_METHOD_SIMPLEX + static NoAudioCodecSimplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, + AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK, AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK, AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN); +#else + static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, + AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN); +#endif + return &audio_codec; + } + +}; + +DECLARE_BOARD(CompactWifiBoard);