3 #include "AudioConfig.h"
4 #if defined(ESP32) && defined(USE_I2S) && \
5 ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) || \
8 #include "AudioTools/CoreAudio/AudioI2S/I2SConfig.h"
9 #include "driver/i2s_pdm.h"
10 #include "driver/i2s_std.h"
11 #include "driver/i2s_tdm.h"
12 #include "esp_system.h"
14 #define IS_I2S_IMPLEMENTED
36 if (info.
equals(cfg))
return true;
39 LOGI(
"i2s_set_sample_rates: %d", (
int)info.
sample_rate);
40 return getDriver(cfg).changeSampleRate(cfg, rx_chan, tx_chan);
53 bool begin() {
return (!is_started) ?
begin(cfg) :
true; }
61 if (is_started)
end();
65 return begin(cfg, cfg.pin_data, I2S_GPIO_UNUSED);
69 return begin(cfg, I2S_GPIO_UNUSED,
70 cfg.pin_data_rx != I2S_GPIO_UNUSED ? cfg.pin_data_rx
73 return begin(cfg, cfg.pin_data, cfg.pin_data_rx);
75 LOGE(
"Did not expect go get here");
79 int available() {
return I2S_BUFFER_COUNT * I2S_BUFFER_SIZE; }
87 if (rx_chan !=
nullptr) {
88 i2s_channel_disable(rx_chan);
89 i2s_del_channel(rx_chan);
92 if (tx_chan !=
nullptr) {
93 i2s_channel_disable(tx_chan);
94 i2s_del_channel(tx_chan);
108 assert(tx_chan !=
nullptr);
109 if (i2s_channel_write(tx_chan, src, size_bytes, &result,
110 ticks_to_wait_write) != ESP_OK) {
116 size_t readBytes(
void *dest,
size_t size_bytes) {
118 if (i2s_channel_read(rx_chan, dest, size_bytes, &result,
119 ticks_to_wait_read) != ESP_OK) {
125 void setWaitTimeReadMs(TickType_t ms) {
126 ticks_to_wait_read = pdMS_TO_TICKS(ms);
128 void setWaitTimeWriteMs(TickType_t ms) {
129 ticks_to_wait_write = pdMS_TO_TICKS(ms);
134 i2s_std_config_t i2s_config;
135 i2s_chan_handle_t tx_chan =
nullptr;
136 i2s_chan_handle_t rx_chan =
nullptr;
137 bool is_started =
false;
138 TickType_t ticks_to_wait_read = portMAX_DELAY;
139 TickType_t ticks_to_wait_write = portMAX_DELAY;
143 i2s_chan_handle_t &tx_chan,
144 i2s_chan_handle_t &rx_chan,
int txPin,
150 i2s_chan_handle_t &tx_chan,
151 i2s_chan_handle_t &rx_chan) {
163 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
165 LOGI(
"tx: %d, rx: %d", txPin, rxPin);
166 i2s_std_config_t std_cfg = {
167 .clk_cfg = getClockConfig(cfg),
168 .slot_cfg = getSlotConfig(cfg),
171 .mclk = (gpio_num_t)cfg.pin_mck,
172 .bclk = (gpio_num_t)cfg.pin_bck,
173 .ws = (gpio_num_t)cfg.pin_ws,
174 .dout = (gpio_num_t)txPin,
175 .din = (gpio_num_t)rxPin,
186 if (i2s_channel_init_std_mode(tx_chan, &std_cfg) != ESP_OK) {
187 LOGE(
"i2s_channel_init_std_mode %s",
"tx");
190 if (i2s_channel_enable(tx_chan) != ESP_OK) {
191 LOGE(
"i2s_channel_enable %s",
"tx");
197 if (i2s_channel_init_std_mode(rx_chan, &std_cfg) != ESP_OK) {
198 LOGE(
"i2s_channel_init_std_mode %s",
"rx");
201 if (i2s_channel_enable(rx_chan) != ESP_OK) {
202 LOGE(
"i2s_channel_enable %s",
"rx");
207 LOGD(
"%s - %s", __func__,
"started");
214 i2s_std_slot_config_t result;
215 switch (cfg.i2s_format) {
216 case I2S_LEFT_JUSTIFIED_FORMAT:
218 result = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(
223 result = I2S_STD_PCM_SLOT_DEFAULT_CONFIG(
228 result = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(
236 case I2SChannelSelect::Left:
237 result.slot_mask = I2S_STD_SLOT_LEFT;
239 case I2SChannelSelect::Right:
240 result.slot_mask = I2S_STD_SLOT_RIGHT;
243 LOGW(
"Using channel_format: I2SChannelSelect::Left for mono");
244 result.slot_mask = I2S_STD_SLOT_LEFT;
254 i2s_chan_config_t result = I2S_CHANNEL_DEFAULT_CONFIG(
255 (i2s_port_t)cfg.port_no,
256 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
260 if (size > 0) result.dma_frame_num = size / frame_size;
261 LOGI(
"dma_frame_num: %d", (
int)result.dma_frame_num);
262 result.auto_clear = cfg.auto_clear;
268 i2s_std_clk_config_t clk_cfg =
269 I2S_STD_CLK_DEFAULT_CONFIG((uint32_t)cfg.
sample_rate);
271 clk_cfg.mclk_multiple = (i2s_mclk_multiple_t)cfg.
mclk_multiple;
275 clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384;
276 LOGI(
"mclk_multiple=384");
283 i2s_chan_handle_t &rx_chan)
override {
285 auto clock_cfg = getClockConfig(cfg);
286 if (tx_chan !=
nullptr) {
287 i2s_channel_disable(tx_chan);
288 rc = i2s_channel_reconfig_std_clock(tx_chan, &clock_cfg) == ESP_OK;
289 i2s_channel_enable(tx_chan);
291 if (rx_chan !=
nullptr) {
292 i2s_channel_disable(rx_chan);
293 rc = i2s_channel_reconfig_std_clock(rx_chan, &clock_cfg) == ESP_OK;
294 i2s_channel_enable(rx_chan);
305 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
307 return startTX(cfg, tx_chan, txPin);
309 return startRX(cfg, rx_chan, rxPin);
311 LOGE(
"Only RX and TX is supported for PDM")
316 i2s_pdm_tx_slot_config_t getTxSlotConfig(I2SConfigESP32V1 &cfg) {
317 return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
318 (i2s_data_bit_width_t)cfg.bits_per_sample,
319 (i2s_slot_mode_t)cfg.channels);
322 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
323 return I2S_CHANNEL_DEFAULT_CONFIG(
324 (i2s_port_t)cfg.port_no,
325 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
328 i2s_pdm_tx_clk_config_t getTxClockConfig(I2SConfigESP32V1 &cfg) {
329 return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
332 bool startTX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
int txPin) {
333 i2s_pdm_tx_config_t pdm_tx_cfg = {
334 .clk_cfg = getTxClockConfig(cfg),
335 .slot_cfg = getTxSlotConfig(cfg),
338 .clk = (gpio_num_t)cfg.pin_bck,
339 .dout = (gpio_num_t)txPin,
347 if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
348 LOGE(
"i2s_channel_init_pdm_tx_mode %s",
"tx");
351 if (i2s_channel_enable(tx_chan) != ESP_OK) {
352 LOGE(
"i2s_channel_enable %s",
"tx");
358 #if defined(USE_PDM_RX)
359 i2s_pdm_rx_slot_config_t getRxSlotConfig(I2SConfigESP32V1 &cfg) {
360 return I2S_PDM_RX_SLOT_DEFAULT_CONFIG(
361 (i2s_data_bit_width_t)cfg.bits_per_sample,
362 (i2s_slot_mode_t)cfg.channels);
364 i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
365 return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
367 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
368 i2s_pdm_rx_config_t pdm_rx_cfg = {
369 .clk_cfg = getRxClockConfig(cfg),
370 .slot_cfg = getRxSlotConfig(cfg),
373 .clk = (gpio_num_t)cfg.pin_bck,
374 .din = (gpio_num_t)rxPin,
382 if (i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg) != ESP_OK) {
383 LOGE(
"i2s_channel_init_pdm_rx_mode %s",
"rx");
386 if (i2s_channel_enable(rx_chan) != ESP_OK) {
387 LOGE(
"i2s_channel_enable %s",
"tx");
393 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
394 LOGE(
"PDM RX not supported");
405 struct DriverTDM :
public DriverCommon {
406 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
407 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
408 i2s_tdm_config_t tdm_cfg = {
409 .clk_cfg = getClockConfig(cfg),
410 .slot_cfg = getSlotConfig(cfg),
413 .mclk = (gpio_num_t)cfg.pin_mck,
414 .bclk = (gpio_num_t)cfg.pin_bck,
415 .ws = (gpio_num_t)cfg.pin_ws,
416 .dout = (gpio_num_t)txPin,
417 .din = (gpio_num_t)rxPin,
427 if (cfg.rx_tx_mode == TX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
428 if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
429 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"tx");
433 if (cfg.rx_tx_mode == RX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
434 if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
435 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"rx");
443 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
445 for (
int j = 0; j < cfg.channels; j++) {
449 i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
450 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
451 (i2s_tdm_slot_mask_t)slots);
453 switch (cfg.i2s_format) {
454 case I2S_RIGHT_JUSTIFIED_FORMAT:
456 case I2S_PHILIPS_FORMAT:
458 slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
459 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
460 (i2s_tdm_slot_mask_t)slots);
462 case I2S_LEFT_JUSTIFIED_FORMAT:
464 slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
465 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
466 (i2s_tdm_slot_mask_t)slots);
469 slot_cfg = I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(
470 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
471 (i2s_tdm_slot_mask_t)slots);
474 LOGE(
"TDM: Unsupported format");
480 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
481 return I2S_CHANNEL_DEFAULT_CONFIG(
482 (i2s_port_t)cfg.port_no,
483 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
486 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
487 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
502 LOGE(
"invalid channels: %d", cfg.
channels);
507 if (!newChannels(cfg, driver)) {
512 is_started = driver.startChannels(cfg, tx_chan, rx_chan, txPin, rxPin);
515 LOGE(
"Channels not started");
521 i2s_chan_config_t chan_cfg = driver.getChannelConfig(cfg);
524 if (i2s_new_channel(&chan_cfg, NULL, &rx_chan) != ESP_OK) {
530 if (i2s_new_channel(&chan_cfg, &tx_chan, NULL) != ESP_OK) {
536 if (i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan) != ESP_OK) {
544 DriverCommon &getDriver(I2SConfigESP32V1 &cfg) {
545 switch (cfg.signal_type) {
560 LOGE(
"Unsupported singal_type");
565 using I2SDriver = I2SDriverESP32V1;
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition: AudioTypes.h:28