1
6
7
16
17
21
27
28
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
51
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
90
91
92
93
102
103
104
105
106
107
108
109
112
113
114
115
119
120
121
122
123
124
125
126
127
128
133
134
135
136
137
138
139
140
141
142
143
144
149
150
151
152
153
154
158
159
160
161
162
163
164
165
166
167
172
173
174
175
176
177
178
179
180
181
182
183
184
185
190
191
192
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/* ... */
#include <stdint.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_std.h"
#include "driver/gpio.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "i2s_example_pins.h"9 includes
/* ... */
#define EXAMPLE_I2S_DUPLEX_MODE CONFIG_USE_DUPLEX
#define EXAMPLE_STD_BCLK_IO1 EXAMPLE_I2S_BCLK_IO1
#define EXAMPLE_STD_WS_IO1 EXAMPLE_I2S_WS_IO1
#define EXAMPLE_STD_DOUT_IO1 EXAMPLE_I2S_DOUT_IO1
#define EXAMPLE_STD_DIN_IO1 EXAMPLE_I2S_DIN_IO1 5 defines
#if !EXAMPLE_I2S_DUPLEX_MODE
#define EXAMPLE_STD_BCLK_IO2 EXAMPLE_I2S_BCLK_IO2
#define EXAMPLE_STD_WS_IO2 EXAMPLE_I2S_WS_IO2
#define EXAMPLE_STD_DOUT_IO2 EXAMPLE_I2S_DOUT_IO2
#define EXAMPLE_STD_DIN_IO2 EXAMPLE_I2S_DIN_IO2 /* ... */
#endif
#define EXAMPLE_BUFF_SIZE 2048
static i2s_chan_handle_t tx_chan;
static i2s_chan_handle_t rx_chan;
static void i2s_example_read_task(void *args)
{
uint8_t *r_buf = (uint8_t *)calloc(1, EXAMPLE_BUFF_SIZE);
assert(r_buf);
size_t r_bytes = 0;
ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));
/* ... */
while (1) {
if (i2s_channel_read(rx_chan, r_buf, EXAMPLE_BUFF_SIZE, &r_bytes, 1000) == ESP_OK) {
printf("Read Task: i2s read %d bytes\n-----------------------------------\n", r_bytes);
printf("[0] %x [1] %x [2] %x [3] %x\n[4] %x [5] %x [6] %x [7] %x\n\n",
r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]);
}{...} else {
printf("Read Task: i2s read failed\n");
}{...}
vTaskDelay(pdMS_TO_TICKS(200));
}{...}
free(r_buf);
vTaskDelete(NULL);
}{ ... }
static void i2s_example_write_task(void *args)
{
uint8_t *w_buf = (uint8_t *)calloc(1, EXAMPLE_BUFF_SIZE);
assert(w_buf);
for (int i = 0; i < EXAMPLE_BUFF_SIZE; i += 8) {
w_buf[i] = 0x12;
w_buf[i + 1] = 0x34;
w_buf[i + 2] = 0x56;
w_buf[i + 3] = 0x78;
w_buf[i + 4] = 0x9A;
w_buf[i + 5] = 0xBC;
w_buf[i + 6] = 0xDE;
w_buf[i + 7] = 0xF0;
}{...}
size_t w_bytes = EXAMPLE_BUFF_SIZE;
while (w_bytes == EXAMPLE_BUFF_SIZE) {
ESP_ERROR_CHECK(i2s_channel_preload_data(tx_chan, w_buf, EXAMPLE_BUFF_SIZE, &w_bytes));
}{...}
ESP_ERROR_CHECK(i2s_channel_enable(tx_chan));
while (1) {
if (i2s_channel_write(tx_chan, w_buf, EXAMPLE_BUFF_SIZE, &w_bytes, 1000) == ESP_OK) {
printf("Write Task: i2s write %d bytes\n", w_bytes);
}{...} else {
printf("Write Task: i2s write failed\n");
}{...}
vTaskDelay(pdMS_TO_TICKS(200));
}{...}
free(w_buf);
vTaskDelete(NULL);
}{ ... }
#if EXAMPLE_I2S_DUPLEX_MODE
static void i2s_example_init_std_duplex(void)
{
/* ... */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan));
/* ... */
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = EXAMPLE_STD_BCLK_IO1,
.ws = EXAMPLE_STD_WS_IO1,
.dout = EXAMPLE_STD_DOUT_IO1,
.din = EXAMPLE_STD_DOUT_IO1,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
}{...},
}{...},
}{...};
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &std_cfg));
}{ ... }
/* ... */#else
static void i2s_example_init_std_simplex(void)
{
/* ... */
i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_chan, NULL));
i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
ESP_ERROR_CHECK(i2s_new_channel(&rx_chan_cfg, NULL, &rx_chan));
/* ... */
i2s_std_config_t tx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = EXAMPLE_STD_BCLK_IO1,
.ws = EXAMPLE_STD_WS_IO1,
.dout = EXAMPLE_STD_DOUT_IO1,
.din = EXAMPLE_STD_DIN_IO1,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
}{...},
}{...},
}{...};
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &tx_std_cfg));
i2s_std_config_t rx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = EXAMPLE_STD_BCLK_IO2,
.ws = EXAMPLE_STD_WS_IO2,
.dout = EXAMPLE_STD_DOUT_IO2,
.din = EXAMPLE_STD_DIN_IO2,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
}{...},
}{...},
}{...};
/* ... */
rx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_RIGHT;
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &rx_std_cfg));
}{...}
/* ... */#endif
void app_main(void)
{
#if EXAMPLE_I2S_DUPLEX_MODE
i2s_example_init_std_duplex();
#else
i2s_example_init_std_simplex();
#endif
xTaskCreate(i2s_example_read_task, "i2s_example_read_task", 4096, NULL, 5, NULL);
xTaskCreate(i2s_example_write_task, "i2s_example_write_task", 4096, NULL, 5, NULL);
}{ ... }