Skip to content

Commit a6619dc

Browse files
authored
更新支持 元控·青春板卡 (#486)
* 更新支持 元控·青春板卡 * 更新README.md,修改多灯库使用问题
1 parent dff8f9c commit a6619dc

File tree

8 files changed

+550
-0
lines changed

8 files changed

+550
-0
lines changed

main/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ set(SOURCES "audio_codecs/audio_codec.cc"
22
"audio_codecs/no_audio_codec.cc"
33
"audio_codecs/box_audio_codec.cc"
44
"audio_codecs/es8311_audio_codec.cc"
5+
"audio_codecs/es8374_audio_codec.cc"
56
"audio_codecs/es8388_audio_codec.cc"
67
"led/single_led.cc"
78
"led/circular_strip.cc"
@@ -136,6 +137,8 @@ elseif(CONFIG_BOARD_TYPE_SENSECAP_WATCHER)
136137
set(BOARD_TYPE "sensecap-watcher")
137138
elseif(CONFIG_BOARD_TYPE_DOIT_S3_AIBOX)
138139
set(BOARD_TYPE "doit-s3-aibox")
140+
elseif(CONFIG_BOARD_TYPE_MIXGO_NOVA)
141+
set(BOARD_TYPE "mixgo-nova")
139142
elseif(CONFIG_BOARD_TYPE_ESP32_CGC)
140143
set(BOARD_TYPE "esp32-cgc")
141144
endif()

main/Kconfig.projbuild

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ choice BOARD_TYPE
160160
bool "SenseCAP Watcher"
161161
config BOARD_TYPE_DOIT_S3_AIBOX
162162
bool "四博智联AI陪伴盒子"
163+
config BOARD_TYPE_MIXGO_NOVA
164+
bool "元控·青春"
163165
endchoice
164166

165167
choice DISPLAY_OLED_TYPE
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#include "es8374_audio_codec.h"
2+
3+
#include <esp_log.h>
4+
5+
static const char TAG[] = "Es8374AudioCodec";
6+
7+
Es8374AudioCodec::Es8374AudioCodec(void* i2c_master_handle, i2c_port_t i2c_port, int input_sample_rate, int output_sample_rate,
8+
gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din,
9+
gpio_num_t pa_pin, uint8_t es8374_addr, bool use_mclk) {
10+
duplex_ = true; // 是否双工
11+
input_reference_ = false; // 是否使用参考输入,实现回声消除
12+
input_channels_ = 1; // 输入通道数
13+
input_sample_rate_ = input_sample_rate;
14+
output_sample_rate_ = output_sample_rate;
15+
pa_pin_ = pa_pin;
16+
CreateDuplexChannels(mclk, bclk, ws, dout, din);
17+
18+
// Do initialize of related interface: data_if, ctrl_if and gpio_if
19+
audio_codec_i2s_cfg_t i2s_cfg = {
20+
.port = I2S_NUM_0,
21+
.rx_handle = rx_handle_,
22+
.tx_handle = tx_handle_,
23+
};
24+
data_if_ = audio_codec_new_i2s_data(&i2s_cfg);
25+
assert(data_if_ != NULL);
26+
27+
// Output
28+
audio_codec_i2c_cfg_t i2c_cfg = {
29+
.port = i2c_port,
30+
.addr = es8374_addr,
31+
.bus_handle = i2c_master_handle,
32+
};
33+
ctrl_if_ = audio_codec_new_i2c_ctrl(&i2c_cfg);
34+
assert(ctrl_if_ != NULL);
35+
36+
gpio_if_ = audio_codec_new_gpio();
37+
assert(gpio_if_ != NULL);
38+
39+
es8374_codec_cfg_t es8374_cfg = {};
40+
es8374_cfg.ctrl_if = ctrl_if_;
41+
es8374_cfg.gpio_if = gpio_if_;
42+
es8374_cfg.codec_mode = ESP_CODEC_DEV_WORK_MODE_BOTH;
43+
es8374_cfg.pa_pin = pa_pin;
44+
codec_if_ = es8374_codec_new(&es8374_cfg);
45+
assert(codec_if_ != NULL);
46+
47+
esp_codec_dev_cfg_t dev_cfg = {
48+
.dev_type = ESP_CODEC_DEV_TYPE_OUT,
49+
.codec_if = codec_if_,
50+
.data_if = data_if_,
51+
};
52+
output_dev_ = esp_codec_dev_new(&dev_cfg);
53+
assert(output_dev_ != NULL);
54+
dev_cfg.dev_type = ESP_CODEC_DEV_TYPE_IN;
55+
input_dev_ = esp_codec_dev_new(&dev_cfg);
56+
assert(input_dev_ != NULL);
57+
esp_codec_set_disable_when_closed(output_dev_, false);
58+
esp_codec_set_disable_when_closed(input_dev_, false);
59+
ESP_LOGI(TAG, "Es8374AudioCodec initialized");
60+
}
61+
62+
Es8374AudioCodec::~Es8374AudioCodec() {
63+
ESP_ERROR_CHECK(esp_codec_dev_close(output_dev_));
64+
esp_codec_dev_delete(output_dev_);
65+
ESP_ERROR_CHECK(esp_codec_dev_close(input_dev_));
66+
esp_codec_dev_delete(input_dev_);
67+
68+
audio_codec_delete_codec_if(codec_if_);
69+
audio_codec_delete_ctrl_if(ctrl_if_);
70+
audio_codec_delete_gpio_if(gpio_if_);
71+
audio_codec_delete_data_if(data_if_);
72+
}
73+
74+
void Es8374AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din) {
75+
assert(input_sample_rate_ == output_sample_rate_);
76+
77+
i2s_chan_config_t chan_cfg = {
78+
.id = I2S_NUM_0,
79+
.role = I2S_ROLE_MASTER,
80+
.dma_desc_num = 6,
81+
.dma_frame_num = 240,
82+
.auto_clear_after_cb = true,
83+
.auto_clear_before_cb = false,
84+
.intr_priority = 0,
85+
};
86+
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle_, &rx_handle_));
87+
88+
i2s_std_config_t std_cfg = {
89+
.clk_cfg = {
90+
.sample_rate_hz = (uint32_t)output_sample_rate_,
91+
.clk_src = I2S_CLK_SRC_DEFAULT,
92+
.mclk_multiple = I2S_MCLK_MULTIPLE_256,
93+
#ifdef I2S_HW_VERSION_2
94+
.ext_clk_freq_hz = 0,
95+
#endif
96+
},
97+
.slot_cfg = {
98+
.data_bit_width = I2S_DATA_BIT_WIDTH_16BIT,
99+
.slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO,
100+
.slot_mode = I2S_SLOT_MODE_STEREO,
101+
.slot_mask = I2S_STD_SLOT_BOTH,
102+
.ws_width = I2S_DATA_BIT_WIDTH_16BIT,
103+
.ws_pol = false,
104+
.bit_shift = true,
105+
#ifdef I2S_HW_VERSION_2
106+
.left_align = true,
107+
.big_endian = false,
108+
.bit_order_lsb = false
109+
#endif
110+
},
111+
.gpio_cfg = {
112+
.mclk = mclk,
113+
.bclk = bclk,
114+
.ws = ws,
115+
.dout = dout,
116+
.din = din,
117+
.invert_flags = {
118+
.mclk_inv = false,
119+
.bclk_inv = false,
120+
.ws_inv = false
121+
}
122+
}
123+
};
124+
125+
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg));
126+
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle_, &std_cfg));
127+
ESP_LOGI(TAG, "Duplex channels created");
128+
}
129+
130+
void Es8374AudioCodec::SetOutputVolume(int volume) {
131+
ESP_ERROR_CHECK(esp_codec_dev_set_out_vol(output_dev_, volume));
132+
AudioCodec::SetOutputVolume(volume);
133+
}
134+
135+
void Es8374AudioCodec::EnableInput(bool enable) {
136+
if (enable == input_enabled_) {
137+
return;
138+
}
139+
if (enable) {
140+
esp_codec_dev_sample_info_t fs = {
141+
.bits_per_sample = 16,
142+
.channel = 1,
143+
.channel_mask = 0,
144+
.sample_rate = (uint32_t)input_sample_rate_,
145+
.mclk_multiple = 0,
146+
};
147+
ESP_ERROR_CHECK(esp_codec_dev_open(input_dev_, &fs));
148+
ESP_ERROR_CHECK(esp_codec_dev_set_in_gain(input_dev_, 40.0));
149+
} else {
150+
ESP_ERROR_CHECK(esp_codec_dev_close(input_dev_));
151+
}
152+
AudioCodec::EnableInput(enable);
153+
}
154+
155+
void Es8374AudioCodec::EnableOutput(bool enable) {
156+
if (enable == output_enabled_) {
157+
return;
158+
}
159+
if (enable) {
160+
// Play 16bit 1 channel
161+
esp_codec_dev_sample_info_t fs = {
162+
.bits_per_sample = 16,
163+
.channel = 1,
164+
.channel_mask = 0,
165+
.sample_rate = (uint32_t)output_sample_rate_,
166+
.mclk_multiple = 0,
167+
};
168+
ESP_ERROR_CHECK(esp_codec_dev_open(output_dev_, &fs));
169+
ESP_ERROR_CHECK(esp_codec_dev_set_out_vol(output_dev_, output_volume_));
170+
if (pa_pin_ != GPIO_NUM_NC) {
171+
gpio_set_level(pa_pin_, 1);
172+
}
173+
} else {
174+
ESP_ERROR_CHECK(esp_codec_dev_close(output_dev_));
175+
if (pa_pin_ != GPIO_NUM_NC) {
176+
gpio_set_level(pa_pin_, 0);
177+
}
178+
}
179+
AudioCodec::EnableOutput(enable);
180+
}
181+
182+
int Es8374AudioCodec::Read(int16_t* dest, int samples) {
183+
if (input_enabled_) {
184+
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_read(input_dev_, (void*)dest, samples * sizeof(int16_t)));
185+
}
186+
return samples;
187+
}
188+
189+
int Es8374AudioCodec::Write(const int16_t* data, int samples) {
190+
if (output_enabled_) {
191+
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_codec_dev_write(output_dev_, (void*)data, samples * sizeof(int16_t)));
192+
}
193+
return samples;
194+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef _ES8374_AUDIO_CODEC_H
2+
#define _ES8374_AUDIO_CODEC_H
3+
4+
#include "audio_codec.h"
5+
6+
#include <driver/i2c.h>
7+
#include <driver/gpio.h>
8+
#include <esp_codec_dev.h>
9+
#include <esp_codec_dev_defaults.h>
10+
11+
class Es8374AudioCodec : public AudioCodec {
12+
private:
13+
const audio_codec_data_if_t* data_if_ = nullptr;
14+
const audio_codec_ctrl_if_t* ctrl_if_ = nullptr;
15+
const audio_codec_if_t* codec_if_ = nullptr;
16+
const audio_codec_gpio_if_t* gpio_if_ = nullptr;
17+
18+
esp_codec_dev_handle_t output_dev_ = nullptr;
19+
esp_codec_dev_handle_t input_dev_ = nullptr;
20+
gpio_num_t pa_pin_ = GPIO_NUM_NC;
21+
22+
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
23+
24+
virtual int Read(int16_t* dest, int samples) override;
25+
virtual int Write(const int16_t* data, int samples) override;
26+
27+
public:
28+
Es8374AudioCodec(void* i2c_master_handle, i2c_port_t i2c_port, int input_sample_rate, int output_sample_rate,
29+
gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din,
30+
gpio_num_t pa_pin, uint8_t es8374_addr, bool use_mclk = true);
31+
virtual ~Es8374AudioCodec();
32+
33+
virtual void SetOutputVolume(int volume) override;
34+
virtual void EnableInput(bool enable) override;
35+
virtual void EnableOutput(bool enable) override;
36+
};
37+
38+
#endif // _ES8374_AUDIO_CODEC_H

main/boards/mixgo-nova/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Mixgo_Nova(元控·青春) 开发板
2+
3+
<img src="https://mixly.cn/public/icon/2024/6/09705006c1c643beb96338791ee1dea0_m.png" alt="Mixgo_Nova" width="200"/>
4+
5+
&zwnj;**[Mixgo_Nova](https://mixly.cn/fredqian/mixgo_nova)**&zwnj; 是一款专为物联网、教育及创客项目设计的多功能开发板,集成丰富传感器与无线通信模块,支持图形化编程(Mixly)和离线语音交互,适合快速原型开发与教学。
6+
7+
---
8+
9+
## 🛠️ 编译配置命令
10+
11+
**ES8374 CODE MIC采集问题:**
12+
13+
```
14+
managed_components\espressif__esp_codec_dev\device\es8374
15+
16+
static int es8374_config_adc_input(audio_codec_es8374_t *codec, es_adc_input_t input)
17+
{
18+
int ret = 0;
19+
int reg = 0;
20+
ret |= es8374_read_reg(codec, 0x21, &reg);
21+
if (ret == 0) {
22+
reg = (reg & 0xcf) | 0x24;
23+
ret |= es8374_write_reg(codec, 0x21, reg);
24+
}
25+
return ret;
26+
}
27+
28+
PS: L386 reg = (reg & 0xcf) | 0x14; 改成 reg = (reg & 0xcf) | 0x24;
29+
```
30+
31+
**配置编译目标为 ESP32S3:**
32+
33+
```bash
34+
idf.py set-target esp32s3
35+
```
36+
37+
**打开 menuconfig:**
38+
39+
```bash
40+
idf.py menuconfig
41+
```
42+
43+
**选择板子:**
44+
45+
```
46+
Xiaozhi Assistant -> Board Type -> 元控·青春
47+
```
48+
49+
**修改 psram 配置:**
50+
51+
```
52+
Component config -> ESP PSRAM -> SPI RAM config -> Mode (QUAD/OCT) -> QUAD Mode PSRAM
53+
```
54+
55+
**修改 Flash 配置:**
56+
57+
```
58+
Serial flasher config -> Flash size -> 8 MB
59+
Partition Table -> Custom partition CSV file -> partitions_8M.csv
60+
```
61+
62+
**编译:**
63+
64+
```bash
65+
idf.py build
66+
```
67+
68+
**合并BIN:**
69+
70+
```bash
71+
idf.py merge-bin -o xiaozhi-nova.bin -f raw
72+
```

main/boards/mixgo-nova/config.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef _BOARD_CONFIG_H_
2+
#define _BOARD_CONFIG_H_
3+
4+
#include <driver/gpio.h>
5+
6+
#define AUDIO_INPUT_SAMPLE_RATE 24000
7+
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
8+
9+
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_35
10+
#define AUDIO_I2S_GPIO_WS GPIO_NUM_47
11+
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_34
12+
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_33
13+
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_48
14+
15+
#define AUDIO_CODEC_PA_PIN GPIO_NUM_NC
16+
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_37
17+
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_36
18+
#define AUDIO_CODEC_ES8374_ADDR ES8374_CODEC_DEFAULT_ADDR
19+
20+
#define BUILTIN_LED_GPIO GPIO_NUM_38
21+
#define BOOT_BUTTON_GPIO GPIO_NUM_0
22+
#define VOLUME_UP_BUTTON_GPIO GPIO_NUM_NC
23+
#define VOLUME_DOWN_BUTTON_GPIO GPIO_NUM_NC
24+
25+
#define DISPLAY_MOSI_PIN GPIO_NUM_40
26+
#define DISPLAY_CLK_PIN GPIO_NUM_41
27+
#define DISPLAY_DC_PIN GPIO_NUM_18
28+
#define DISPLAY_CS_PIN GPIO_NUM_45
29+
#define DISPLAY_RST_PIN GPIO_NUM_NC
30+
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_14
31+
#define DISPLAY_WIDTH 128
32+
#define DISPLAY_HEIGHT 160
33+
#define DISPLAY_MIRROR_X true
34+
#define DISPLAY_MIRROR_Y true
35+
#define DISPLAY_SWAP_XY false
36+
#define DISPLAY_INVERT_COLOR false
37+
#define DISPLAY_OFFSET_X 2
38+
#define DISPLAY_OFFSET_Y 1
39+
#define DISPLAY_RGB_ORDER LCD_RGB_ELEMENT_ORDER_RGB
40+
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT false
41+
42+
#endif // _BOARD_CONFIG_H_

main/boards/mixgo-nova/config.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"target": "esp32s3",
3+
"builds": [
4+
{
5+
"name": "mixgo-nova",
6+
"sdkconfig_append": [
7+
"CONFIG_SPIRAM_MODE_QUAD=y",
8+
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
9+
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions_8M.csv\"",
10+
"CONFIG_LCD_ST7735_128X160=y"
11+
]
12+
}
13+
]
14+
}

0 commit comments

Comments
 (0)