Skip to content

Commit 42b03de

Browse files
committed
esp: jc4880p443 audio support
1 parent 812bb3f commit 42b03de

File tree

5 files changed

+164
-8
lines changed

5 files changed

+164
-8
lines changed

esp/main/board_jc4880p443.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,15 @@
2424

2525
#define USE_HOSTED_WIFI
2626

27-
// TODO: I2S
27+
#define MIXER_BUF_LEN 512
28+
#define I2S_MCLK 13
29+
#define I2S_BCLK 12
30+
#define I2S_WS 10
31+
#define I2S_DOUT 9
32+
#define I2S_NUM 0
33+
34+
#define USE_ES8311
35+
#define ES8311_PA 11
36+
#define ES8311_I2C_NUM 0
37+
#define ES8311_I2C_SDA 7
38+
#define ES8311_I2C_SCL 8

esp/main/i2s.c

Lines changed: 115 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88
static i2s_chan_handle_t tx_chan; // I2S tx channel handler
99
void mixer_callback (void *opaque, uint8_t *stream, int free);
1010

11+
#ifndef MIXER_BUF_LEN
12+
#define MIXER_BUF_LEN 128
13+
#endif
14+
1115
static void i2s_task(void *arg)
1216
{
13-
int16_t buf[128];
17+
int16_t buf[MIXER_BUF_LEN];
1418
int core_id = esp_cpu_get_core_id();
1519
fprintf(stderr, "i2s runs on core %d\n", core_id);
1620

@@ -23,16 +27,114 @@ static void i2s_task(void *arg)
2327
i2s_channel_enable(tx_chan);
2428
for (;;) {
2529
size_t bwritten;
26-
memset(buf, 0, 128 * 2);
27-
mixer_callback(globals.pc, (uint8_t *) buf, 128 * 2);
28-
for (int i = 0; i < 128; i++) {
30+
memset(buf, 0, MIXER_BUF_LEN * 2);
31+
mixer_callback(globals.pc, (uint8_t *) buf, MIXER_BUF_LEN * 2);
32+
for (int i = 0; i < MIXER_BUF_LEN; i++) {
2933
buf[i] = buf[i] / 16;
3034
}
31-
i2s_channel_write(tx_chan, buf, 128 * 2, &bwritten, portMAX_DELAY);
35+
i2s_channel_write(tx_chan, buf, MIXER_BUF_LEN * 2, &bwritten, portMAX_DELAY);
3236
}
3337
i2s_channel_disable(tx_chan);
3438
}
3539

40+
#ifndef I2S_NUM
41+
#define I2S_NUM I2S_NUM_AUTO
42+
#endif
43+
44+
#ifdef USE_ES8311
45+
// adapted from: examples/peripherals/i2s/i2s_codec/i2s_es8311/main/i2s_es8311_example.c
46+
static i2s_chan_handle_t rx_chan; // I2S rx channel handler (not used)
47+
#include "esp_log.h"
48+
#include "driver/i2c_master.h"
49+
#include "esp_codec_dev_defaults.h"
50+
#include "esp_codec_dev.h"
51+
#include "esp_codec_dev_vol.h"
52+
static const char *TAG = "i2s";
53+
54+
static esp_err_t es8311_codec_init(void)
55+
{
56+
/* Initialize I2C peripheral */
57+
i2c_master_bus_handle_t i2c_bus_handle = NULL;
58+
i2c_master_bus_config_t i2c_mst_cfg = {
59+
.i2c_port = ES8311_I2C_NUM,
60+
.sda_io_num = ES8311_I2C_SDA,
61+
.scl_io_num = ES8311_I2C_SCL,
62+
.clk_source = I2C_CLK_SRC_DEFAULT,
63+
.glitch_ignore_cnt = 7,
64+
/* Pull-up internally for no external pull-up case.
65+
Suggest to use external pull-up to ensure a strong enough pull-up. */
66+
.flags.enable_internal_pullup = true,
67+
};
68+
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_cfg, &i2c_bus_handle));
69+
70+
/* Create control interface with I2C bus handle */
71+
audio_codec_i2c_cfg_t i2c_cfg = {
72+
.port = ES8311_I2C_NUM,
73+
.addr = ES8311_CODEC_DEFAULT_ADDR,
74+
.bus_handle = i2c_bus_handle,
75+
};
76+
const audio_codec_ctrl_if_t *ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
77+
assert(ctrl_if);
78+
79+
/* Create data interface with I2S bus handle */
80+
audio_codec_i2s_cfg_t i2s_cfg = {
81+
.port = I2S_NUM,
82+
.rx_handle = rx_chan,
83+
.tx_handle = tx_chan,
84+
};
85+
const audio_codec_data_if_t *data_if = audio_codec_new_i2s_data(&i2s_cfg);
86+
assert(data_if);
87+
88+
/* Create ES8311 interface handle */
89+
const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio();
90+
assert(gpio_if);
91+
es8311_codec_cfg_t es8311_cfg = {
92+
.ctrl_if = ctrl_if,
93+
.gpio_if = gpio_if,
94+
.codec_mode = ESP_CODEC_DEV_WORK_MODE_BOTH,
95+
.master_mode = false,
96+
.use_mclk = I2S_MCLK >= 0,
97+
.pa_pin = ES8311_PA,
98+
.pa_reverted = false,
99+
.hw_gain = {
100+
.pa_voltage = 5.0,
101+
.codec_dac_voltage = 3.3,
102+
},
103+
//.mclk_div = EXAMPLE_MCLK_MULTIPLE,
104+
};
105+
const audio_codec_if_t *es8311_if = es8311_codec_new(&es8311_cfg);
106+
assert(es8311_if);
107+
108+
/* Create the top codec handle with ES8311 interface handle and data interface */
109+
esp_codec_dev_cfg_t dev_cfg = {
110+
.dev_type = ESP_CODEC_DEV_TYPE_IN_OUT,
111+
.codec_if = es8311_if,
112+
.data_if = data_if,
113+
};
114+
esp_codec_dev_handle_t codec_handle = esp_codec_dev_new(&dev_cfg);
115+
assert(codec_handle);
116+
117+
/* Specify the sample configurations and open the device */
118+
esp_codec_dev_sample_info_t sample_cfg = {
119+
.bits_per_sample = I2S_DATA_BIT_WIDTH_16BIT,
120+
.channel = 2,
121+
.channel_mask = 0x03,
122+
.sample_rate = 44100,
123+
};
124+
if (esp_codec_dev_open(codec_handle, &sample_cfg) != ESP_CODEC_DEV_OK) {
125+
ESP_LOGE(TAG, "Open codec device failed");
126+
return ESP_FAIL;
127+
}
128+
129+
/* Set the initial volume and gain */
130+
if (esp_codec_dev_set_out_vol(codec_handle, 80) != ESP_CODEC_DEV_OK) {
131+
ESP_LOGE(TAG, "set output volume failed");
132+
return ESP_FAIL;
133+
}
134+
return ESP_OK;
135+
}
136+
#endif
137+
36138
void i2s_main()
37139
{
38140
#ifdef I2S_MCLK
@@ -41,9 +143,12 @@ void i2s_main()
41143
* it only requires the I2S controller id and I2S role
42144
* The tx and rx channels here are registered on different I2S controller,
43145
* Except ESP32 and ESP32-S2, others allow to register two separate tx & rx channels on a same controller */
44-
i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
146+
i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER);
147+
#ifdef USE_ES8311
148+
ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_chan, &rx_chan));
149+
#else
45150
ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_chan, NULL));
46-
151+
#endif
47152
/* Step 2: Setting the configurations of standard mode and initialize each channels one by one
48153
* The slot configuration and clock configuration can be generated by the macros
49154
* These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode.
@@ -65,6 +170,9 @@ void i2s_main()
65170
},
66171
};
67172
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &tx_std_cfg));
173+
#ifdef USE_ES8311
174+
ESP_ERROR_CHECK(es8311_codec_init());
175+
#endif
68176
xTaskCreatePinnedToCore(i2s_task, "i2s_task", 4096, NULL, 0, NULL, 0);
69177
#endif
70178
}

esp/main/idf_component.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,7 @@ dependencies:
3333
version: '*'
3434
rules:
3535
- if: "target in [esp32p4]"
36+
espressif/esp_codec_dev:
37+
version: ^1.3.4
38+
rules:
39+
- if: "target in [esp32p4]"

esp/sdkconfig.jc4880p443

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3973,6 +3973,37 @@ CONFIG_EPPP_LINK_CONN_MAX_RETRY=6
39733973
# CONFIG_EPPP_LINK_CHANNELS_SUPPORT is not set
39743974
# end of eppp_link
39753975

3976+
#
3977+
# Audio Codec Device Configuration
3978+
#
3979+
# default:
3980+
# CONFIG_CODEC_I2C_BACKWARD_COMPATIBLE is not set
3981+
# default:
3982+
CONFIG_CODEC_ES8311_SUPPORT=y
3983+
# default:
3984+
CONFIG_CODEC_ES7210_SUPPORT=y
3985+
# default:
3986+
CONFIG_CODEC_ES7243_SUPPORT=y
3987+
# default:
3988+
CONFIG_CODEC_ES7243E_SUPPORT=y
3989+
# default:
3990+
CONFIG_CODEC_ES8156_SUPPORT=y
3991+
# default:
3992+
CONFIG_CODEC_AW88298_SUPPORT=y
3993+
# default:
3994+
CONFIG_CODEC_ES8389_SUPPORT=y
3995+
# default:
3996+
CONFIG_CODEC_ES8374_SUPPORT=y
3997+
# default:
3998+
CONFIG_CODEC_ES8388_SUPPORT=y
3999+
# default:
4000+
CONFIG_CODEC_TAS5805M_SUPPORT=y
4001+
# default:
4002+
# CONFIG_CODEC_ZL38063_SUPPORT is not set
4003+
# default:
4004+
# CONFIG_CODEC_CJC8910_SUPPORT is not set
4005+
# end of Audio Codec Device Configuration
4006+
39764007
CONFIG_ESP_HOSTED_ENABLED=y
39774008

39784009
#

pc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
#endif
1616

1717
#ifdef BUILD_ESP32
18+
#ifndef MIXER_BUF_LEN
1819
#define MIXER_BUF_LEN 128
20+
#endif
1921
#define PC_STEP_COUNT 512
2022
void pcmalloc_init(void *ptr, long len);
2123
#else

0 commit comments

Comments
 (0)