4#if defined(ESP32) && !USE_LEGACY_I2S || defined(DOXYGEN)
8#include "driver/i2s_pdm.h"
9#include "driver/i2s_std.h"
10#include "driver/i2s_tdm.h"
11#include "esp_system.h"
13#define IS_I2S_IMPLEMENTED
18#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
23#if ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(5, 1, 4)
24#define I2S_MCLK_MULTIPLE_192 static_cast<i2s_mclk_multiple_t>(192)
85 LOGE(
"Did not expect go get here");
119 if (i2s_channel_write(
tx_chan, src, size_bytes, &result,
128 if (i2s_channel_read(
rx_chan, dest, size_bytes, &result,
154 i2s_chan_handle_t &
rx_chan,
int txPin,
172 i2s_chan_handle_t &
rx_chan,
int txPin,
int rxPin) {
174 LOGI(
"tx: %d, rx: %d", txPin, rxPin);
175 i2s_std_config_t std_cfg;
182 .dout = (gpio_num_t)txPin,
183 .din = (gpio_num_t)rxPin,
194 if (i2s_channel_init_std_mode(
tx_chan, &std_cfg) != ESP_OK) {
195 LOGE(
"i2s_channel_init_std_mode %s",
"tx");
198 if (i2s_channel_enable(
tx_chan) != ESP_OK) {
199 LOGE(
"i2s_channel_enable %s",
"tx");
205 if (i2s_channel_init_std_mode(
rx_chan, &std_cfg) != ESP_OK) {
206 LOGE(
"i2s_channel_init_std_mode %s",
"rx");
209 if (i2s_channel_enable(
rx_chan) != ESP_OK) {
210 LOGE(
"i2s_channel_enable %s",
"rx");
215 LOGD(
"%s - %s", __func__,
"started");
222 i2s_std_slot_config_t result;
226 result = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(
231 result = I2S_STD_PCM_SLOT_DEFAULT_CONFIG(
236 result = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(
245 result.slot_mask = I2S_STD_SLOT_LEFT;
248 result.slot_mask = I2S_STD_SLOT_RIGHT;
251 LOGW(
"Using channel_format: I2SChannelSelect::Left for mono");
252 result.slot_mask = I2S_STD_SLOT_LEFT;
262 i2s_chan_config_t result = I2S_CHANNEL_DEFAULT_CONFIG(
268 frame_size = (frame_size == 0) ? 1 : frame_size;
269 if (size > 0) result.dma_frame_num = size / frame_size;
270 if (result.dma_frame_num == 0) result.dma_frame_num = 1;
271 LOGI(
"frame_size: %d", (
int)frame_size);
272 LOGI(
"dma_frame_num: %d", (
int)result.dma_frame_num);
273 LOGI(
"total buffer size: %d", (
int)(result.dma_frame_num * frame_size));
280 i2s_std_clk_config_t clk_cfg;
281 memset(&clk_cfg, 0,
sizeof(i2s_std_clk_config_t));
288 LOGI(
"mclk_multiple=%d", clk_cfg.mclk_multiple);
294 LOGI(
"mclk_multiple=384");
298 clk_cfg.mclk_multiple =
cfg.
use_apll ? I2S_MCLK_MULTIPLE_128 : I2S_MCLK_MULTIPLE_256;
299 LOGI(
"mclk_multiple=%d", clk_cfg.mclk_multiple);
308 soc_periph_i2s_clk_src_t result = I2S_CLK_SRC_DEFAULT;
311#if SOC_I2S_HW_VERSION_2
312 LOGI(
"pin_mclk is input");
313 result = I2S_CLK_SRC_EXTERNAL;
316 LOGE(
"pin_mclk as input not supported");
323#if SOC_I2S_SUPPORTS_APLL
324 result = I2S_CLK_SRC_APLL;
325 LOGI(
"clk_src is I2S_CLK_SRC_APLL");
326#elif SOC_I2S_SUPPORTS_PLL_F160M
327 result = I2S_CLK_SRC_PLL_160M;
328 LOGI(
"clk_src is I2S_CLK_SRC_PLL_160M");
336 i2s_chan_handle_t &
rx_chan)
override {
341 rc = i2s_channel_reconfig_std_clock(
tx_chan, &clock_cfg) == ESP_OK;
346 rc = i2s_channel_reconfig_std_clock(
rx_chan, &clock_cfg) == ESP_OK;
356 struct DriverPDM :
public DriverCommon {
358 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
360 return startTX(cfg, tx_chan, txPin);
362 return startRX(cfg, rx_chan, rxPin);
364 LOGE(
"Only RX and TX is supported for PDM")
369 i2s_pdm_tx_slot_config_t getTxSlotConfig(I2SConfigESP32V1 &cfg) {
370#ifdef SOC_I2S_HW_VERSION_2
371 return I2S_PDM_TX_SLOT_DAC_DEFAULT_CONFIG(
372 (i2s_data_bit_width_t)cfg.bits_per_sample,
373 (i2s_slot_mode_t)cfg.channels);
375 return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
376 (i2s_data_bit_width_t)cfg.bits_per_sample,
377 (i2s_slot_mode_t)cfg.channels);
381 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
382 return I2S_CHANNEL_DEFAULT_CONFIG(
383 (i2s_port_t)cfg.port_no,
384 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
387 i2s_pdm_tx_clk_config_t getTxClockConfig(I2SConfigESP32V1 &cfg) {
388#if defined(I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG)
389 return I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
391 return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
395 bool startTX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
int txPin) {
396 i2s_pdm_tx_config_t pdm_tx_cfg = {
397 .clk_cfg = getTxClockConfig(cfg),
398 .slot_cfg = getTxSlotConfig(cfg),
401 .clk = (gpio_num_t)cfg.pin_bck,
402 .dout = (gpio_num_t)txPin,
403#if SOC_I2S_PDM_MAX_TX_LINES > 1
404 .dout2 = I2S_GPIO_UNUSED,
413 if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
414 LOGE(
"i2s_channel_init_pdm_tx_mode %s",
"tx");
417 if (i2s_channel_enable(tx_chan) != ESP_OK) {
418 LOGE(
"i2s_channel_enable %s",
"tx");
424#if defined(USE_PDM_RX)
425 i2s_pdm_rx_slot_config_t getRxSlotConfig(I2SConfigESP32V1 &cfg) {
426 return I2S_PDM_RX_SLOT_DEFAULT_CONFIG(
427 (i2s_data_bit_width_t)cfg.bits_per_sample,
428 (i2s_slot_mode_t)cfg.channels);
430 i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
431 return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
433 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
434 i2s_pdm_rx_config_t pdm_rx_cfg = {
435 .clk_cfg = getRxClockConfig(cfg),
436 .slot_cfg = getRxSlotConfig(cfg),
439 .clk = (gpio_num_t)cfg.pin_bck,
440 .din = (gpio_num_t)rxPin,
448 if (i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg) != ESP_OK) {
449 LOGE(
"i2s_channel_init_pdm_rx_mode %s",
"rx");
452 if (i2s_channel_enable(rx_chan) != ESP_OK) {
453 LOGE(
"i2s_channel_enable %s",
"tx");
459 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
460 LOGE(
"PDM RX not supported");
471 struct DriverTDM :
public DriverCommon {
472 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
473 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
474 i2s_tdm_config_t tdm_cfg = {
475 .clk_cfg = getClockConfig(cfg),
476 .slot_cfg = getSlotConfig(cfg),
479 .mclk = (gpio_num_t)cfg.pin_mck,
480 .bclk = (gpio_num_t)cfg.pin_bck,
481 .ws = (gpio_num_t)cfg.pin_ws,
482 .dout = (gpio_num_t)txPin,
483 .din = (gpio_num_t)rxPin,
493 if (cfg.rx_tx_mode == TX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
494 if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
495 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"tx");
499 if (cfg.rx_tx_mode == RX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
500 if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
501 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"rx");
509 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
511 for (
int j = 0; j < cfg.channels; j++) {
515 i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
516 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
517 (i2s_tdm_slot_mask_t)slots);
519 switch (cfg.i2s_format) {
524 slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
525 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
526 (i2s_tdm_slot_mask_t)slots);
530 slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
531 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
532 (i2s_tdm_slot_mask_t)slots);
535 slot_cfg = I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(
536 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
537 (i2s_tdm_slot_mask_t)slots);
540 LOGE(
"TDM: Unsupported format");
546 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
547 return I2S_CHANNEL_DEFAULT_CONFIG(
548 (i2s_port_t)cfg.port_no,
549 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
552 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
553 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
581 LOGE(
"Channels not started");
590 if (i2s_new_channel(&chan_cfg, NULL, &
rx_chan) != ESP_OK) {
596 if (i2s_new_channel(&chan_cfg, &
tx_chan, NULL) != ESP_OK) {
626 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 I2S_MCLK_MULTIPLE_192
Definition I2SDriverESP32V1.h:24
#define portMAX_DELAY
Definition QueueZephyr.h:14
#define pdMS_TO_TICKS(ms)
Definition QueueZephyr.h:17
uint32_t TickType_t
Definition QueueZephyr.h:11
#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:26
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26