4#if defined(ESP32) && !USE_LEGACY_I2S || defined(DOXYGEN)
7#include "driver/i2s_pdm.h"
8#include "driver/i2s_std.h"
9#include "driver/i2s_tdm.h"
10#include "esp_system.h"
12#define IS_I2S_IMPLEMENTED
17#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
78 LOGE(
"Did not expect go get here");
188 LOGE(
"i2s_channel_init_std_mode %s",
"tx");
192 LOGE(
"i2s_channel_enable %s",
"tx");
199 LOGE(
"i2s_channel_init_std_mode %s",
"rx");
203 LOGE(
"i2s_channel_enable %s",
"rx");
244 LOGW(
"Using channel_format: I2SChannelSelect::Left for mono");
261 frame_size = (frame_size == 0) ? 1 : frame_size;
262 if (size > 0) result.dma_frame_num = size / frame_size;
263 LOGI(
"dma_frame_num: %d", (
int)result.dma_frame_num);
284 LOGI(
"mclk_multiple=384");
301#if SOC_I2S_HW_VERSION_2
302 LOGI(
"pin_mclk is input");
306 LOGE(
"pin_mclk as input not supported");
313#if SOC_I2S_SUPPORTS_APLL
315 LOGI(
"clk_src is I2S_CLK_SRC_APLL");
316#elif SOC_I2S_SUPPORTS_PLL_F160M
318 LOGI(
"clk_src is I2S_CLK_SRC_PLL_160M");
348 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
350 return startTX(cfg, tx_chan, txPin);
352 return startRX(cfg, rx_chan, rxPin);
354 LOGE(
"Only RX and TX is supported for PDM")
359 i2s_pdm_tx_slot_config_t getTxSlotConfig(I2SConfigESP32V1 &cfg) {
360#ifdef SOC_I2S_HW_VERSION_2
361 return I2S_PDM_TX_SLOT_DAC_DEFAULT_CONFIG(
362 (i2s_data_bit_width_t)cfg.bits_per_sample,
363 (i2s_slot_mode_t)cfg.channels);
365 return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
366 (i2s_data_bit_width_t)cfg.bits_per_sample,
367 (i2s_slot_mode_t)cfg.channels);
371 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
372 return I2S_CHANNEL_DEFAULT_CONFIG(
373 (i2s_port_t)cfg.port_no,
374 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
377 i2s_pdm_tx_clk_config_t getTxClockConfig(I2SConfigESP32V1 &cfg) {
378#if defined(I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG)
379 return I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
381 return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
385 bool startTX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
int txPin) {
386 i2s_pdm_tx_config_t pdm_tx_cfg = {
387 .clk_cfg = getTxClockConfig(cfg),
388 .slot_cfg = getTxSlotConfig(cfg),
391 .clk = (gpio_num_t)cfg.pin_bck,
392 .dout = (gpio_num_t)txPin,
393#if SOC_I2S_PDM_MAX_TX_LINES > 1
394 .dout2 = I2S_GPIO_UNUSED,
403 if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
404 LOGE(
"i2s_channel_init_pdm_tx_mode %s",
"tx");
407 if (i2s_channel_enable(tx_chan) != ESP_OK) {
408 LOGE(
"i2s_channel_enable %s",
"tx");
414#if defined(USE_PDM_RX)
415 i2s_pdm_rx_slot_config_t getRxSlotConfig(I2SConfigESP32V1 &cfg) {
416 return I2S_PDM_RX_SLOT_DEFAULT_CONFIG(
417 (i2s_data_bit_width_t)cfg.bits_per_sample,
418 (i2s_slot_mode_t)cfg.channels);
420 i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
421 return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
423 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
424 i2s_pdm_rx_config_t pdm_rx_cfg = {
425 .clk_cfg = getRxClockConfig(cfg),
426 .slot_cfg = getRxSlotConfig(cfg),
429 .clk = (gpio_num_t)cfg.pin_bck,
430 .din = (gpio_num_t)rxPin,
438 if (i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg) != ESP_OK) {
439 LOGE(
"i2s_channel_init_pdm_rx_mode %s",
"rx");
442 if (i2s_channel_enable(rx_chan) != ESP_OK) {
443 LOGE(
"i2s_channel_enable %s",
"tx");
449 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
450 LOGE(
"PDM RX not supported");
462 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
463 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
464 i2s_tdm_config_t tdm_cfg = {
465 .clk_cfg = getClockConfig(cfg),
466 .slot_cfg = getSlotConfig(cfg),
469 .mclk = (gpio_num_t)cfg.pin_mck,
470 .bclk = (gpio_num_t)cfg.pin_bck,
471 .ws = (gpio_num_t)cfg.pin_ws,
472 .dout = (gpio_num_t)txPin,
473 .din = (gpio_num_t)rxPin,
483 if (cfg.rx_tx_mode == TX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
484 if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
485 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"tx");
489 if (cfg.rx_tx_mode == RX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
490 if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
491 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"rx");
499 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
501 for (
int j = 0; j < cfg.channels; j++) {
505 i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
506 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
507 (i2s_tdm_slot_mask_t)slots);
509 switch (cfg.i2s_format) {
514 slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
515 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
516 (i2s_tdm_slot_mask_t)slots);
520 slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
521 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
522 (i2s_tdm_slot_mask_t)slots);
525 slot_cfg = I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(
526 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
527 (i2s_tdm_slot_mask_t)slots);
530 LOGE(
"TDM: Unsupported format");
536 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
537 return I2S_CHANNEL_DEFAULT_CONFIG(
538 (i2s_port_t)cfg.port_no,
539 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
542 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
543 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
571 LOGE(
"Channels not started");
616 LOGE(
"Unsupported signal_type");
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define TRACEE()
Definition AudioLoggerIDF.h:34
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define assert(T)
Definition avr.h:10
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:30
@ RXTX_MODE
Definition AudioTypes.h:30
@ TX_MODE
Definition AudioTypes.h:30
@ RX_MODE
Definition AudioTypes.h:30