34 if (info.
equals(cfg))
return true;
37 LOGI(
"i2s_set_sample_rates: %d", (
int)info.
sample_rate);
38 return getDriver(cfg).changeSampleRate(cfg, rx_chan, tx_chan);
51 bool begin() {
return (!is_started) ?
begin(cfg) :
true; }
59 if (is_started)
end();
63 return begin(cfg, cfg.pin_data, I2S_GPIO_UNUSED);
67 return begin(cfg, I2S_GPIO_UNUSED,
68 cfg.pin_data_rx != I2S_GPIO_UNUSED ? cfg.pin_data_rx
71 return begin(cfg, cfg.pin_data, cfg.pin_data_rx);
73 LOGE(
"Did not expect go get here");
77 int available() {
return I2S_BUFFER_COUNT * I2S_BUFFER_SIZE; }
85 if (rx_chan !=
nullptr) {
86 i2s_channel_disable(rx_chan);
87 i2s_del_channel(rx_chan);
90 if (tx_chan !=
nullptr) {
91 i2s_channel_disable(tx_chan);
92 i2s_del_channel(tx_chan);
106 assert(tx_chan !=
nullptr);
107 if (i2s_channel_write(tx_chan, src, size_bytes, &result,
108 ticks_to_wait_write) != ESP_OK) {
114 size_t readBytes(
void *dest,
size_t size_bytes) {
116 if (i2s_channel_read(rx_chan, dest, size_bytes, &result,
117 ticks_to_wait_read) != ESP_OK) {
123 void setWaitTimeReadMs(TickType_t ms) {
124 ticks_to_wait_read = pdMS_TO_TICKS(ms);
126 void setWaitTimeWriteMs(TickType_t ms) {
127 ticks_to_wait_write = pdMS_TO_TICKS(ms);
132 i2s_std_config_t i2s_config;
133 i2s_chan_handle_t tx_chan =
nullptr;
134 i2s_chan_handle_t rx_chan =
nullptr;
135 bool is_started =
false;
136 TickType_t ticks_to_wait_read = portMAX_DELAY;
137 TickType_t ticks_to_wait_write = portMAX_DELAY;
141 i2s_chan_handle_t &tx_chan,
142 i2s_chan_handle_t &rx_chan,
int txPin,
148 i2s_chan_handle_t &tx_chan,
149 i2s_chan_handle_t &rx_chan) {
160 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
162 LOGI(
"tx: %d, rx: %d", txPin, rxPin);
163 i2s_std_config_t std_cfg;
164 std_cfg.clk_cfg = getClockConfig(cfg);
165 std_cfg.slot_cfg = getSlotConfig(cfg);
167 .mclk = (gpio_num_t)cfg.pin_mck,
168 .bclk = (gpio_num_t)cfg.pin_bck,
169 .ws = (gpio_num_t)cfg.pin_ws,
170 .dout = (gpio_num_t)txPin,
171 .din = (gpio_num_t)rxPin,
182 if (i2s_channel_init_std_mode(tx_chan, &std_cfg) != ESP_OK) {
183 LOGE(
"i2s_channel_init_std_mode %s",
"tx");
186 if (i2s_channel_enable(tx_chan) != ESP_OK) {
187 LOGE(
"i2s_channel_enable %s",
"tx");
193 if (i2s_channel_init_std_mode(rx_chan, &std_cfg) != ESP_OK) {
194 LOGE(
"i2s_channel_init_std_mode %s",
"rx");
197 if (i2s_channel_enable(rx_chan) != ESP_OK) {
198 LOGE(
"i2s_channel_enable %s",
"rx");
203 LOGD(
"%s - %s", __func__,
"started");
210 i2s_std_slot_config_t result;
211 switch (cfg.i2s_format) {
212 case I2S_LEFT_JUSTIFIED_FORMAT:
214 result = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(
219 result = I2S_STD_PCM_SLOT_DEFAULT_CONFIG(
224 result = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(
232 case I2SChannelSelect::Left:
233 result.slot_mask = I2S_STD_SLOT_LEFT;
235 case I2SChannelSelect::Right:
236 result.slot_mask = I2S_STD_SLOT_RIGHT;
239 LOGW(
"Using channel_format: I2SChannelSelect::Left for mono");
240 result.slot_mask = I2S_STD_SLOT_LEFT;
250 i2s_chan_config_t result = I2S_CHANNEL_DEFAULT_CONFIG(
251 (i2s_port_t)cfg.port_no,
252 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
256 frame_size = (frame_size == 0) ? 1 : frame_size;
257 if (size > 0) result.dma_frame_num = size / frame_size;
258 LOGI(
"dma_frame_num: %d", (
int)result.dma_frame_num);
259 result.auto_clear = cfg.auto_clear;
265 i2s_std_clk_config_t clk_cfg;
266 memset(&clk_cfg, 0,
sizeof(i2s_std_clk_config_t));
272 clk_cfg.mclk_multiple = (i2s_mclk_multiple_t)cfg.
mclk_multiple;
273 LOGI(
"mclk_multiple=%d", clk_cfg.mclk_multiple);
278 clk_cfg.mclk_multiple = cfg.use_apll ? I2S_MCLK_MULTIPLE_192: I2S_MCLK_MULTIPLE_384;
279 LOGI(
"mclk_multiple=384");
283 clk_cfg.mclk_multiple = cfg.use_apll ? I2S_MCLK_MULTIPLE_128 : I2S_MCLK_MULTIPLE_256;
284 LOGI(
"mclk_multiple=%d", clk_cfg.mclk_multiple);
293 soc_periph_i2s_clk_src_t result = I2S_CLK_SRC_DEFAULT;
295 if (cfg.pin_mck != -1 && !cfg.is_master) {
296#if SOC_I2S_HW_VERSION_2
297 LOGI(
"pin_mclk is input");
298 result = I2S_CLK_SRC_EXTERNAL;
301 LOGE(
"pin_mclk as input not supported");
308#if SOC_I2S_SUPPORTS_APLL
309 result = I2S_CLK_SRC_APLL;
310 LOGI(
"clk_src is I2S_CLK_SRC_APLL");
311#elif SOC_I2S_SUPPORTS_PLL_F160M
312 result = I2S_CLK_SRC_PLL_160M;
313 LOGI(
"clk_src is I2S_CLK_SRC_PLL_160M");
321 i2s_chan_handle_t &rx_chan)
override {
323 auto clock_cfg = getClockConfig(cfg);
324 if (tx_chan !=
nullptr) {
325 i2s_channel_disable(tx_chan);
326 rc = i2s_channel_reconfig_std_clock(tx_chan, &clock_cfg) == ESP_OK;
327 i2s_channel_enable(tx_chan);
329 if (rx_chan !=
nullptr) {
330 i2s_channel_disable(rx_chan);
331 rc = i2s_channel_reconfig_std_clock(rx_chan, &clock_cfg) == ESP_OK;
332 i2s_channel_enable(rx_chan);
341 struct DriverPDM :
public DriverCommon {
342 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
343 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
344 if (cfg.rx_tx_mode == TX_MODE) {
345 return startTX(cfg, tx_chan, txPin);
346 }
else if (cfg.rx_tx_mode == RX_MODE) {
347 return startRX(cfg, rx_chan, rxPin);
349 LOGE(
"Only RX and TX is supported for PDM")
354 i2s_pdm_tx_slot_config_t getTxSlotConfig(I2SConfigESP32V1 &cfg) {
355#ifdef SOC_I2S_HW_VERSION_2
356 return I2S_PDM_TX_SLOT_DAC_DEFAULT_CONFIG(
357 (i2s_data_bit_width_t)cfg.bits_per_sample,
358 (i2s_slot_mode_t)cfg.channels);
360 return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
361 (i2s_data_bit_width_t)cfg.bits_per_sample,
362 (i2s_slot_mode_t)cfg.channels);
366 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
367 return I2S_CHANNEL_DEFAULT_CONFIG(
368 (i2s_port_t)cfg.port_no,
369 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
372 i2s_pdm_tx_clk_config_t getTxClockConfig(I2SConfigESP32V1 &cfg) {
373#if defined(I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG)
374 return I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
376 return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
380 bool startTX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
int txPin) {
381 i2s_pdm_tx_config_t pdm_tx_cfg = {
382 .clk_cfg = getTxClockConfig(cfg),
383 .slot_cfg = getTxSlotConfig(cfg),
386 .clk = (gpio_num_t)cfg.pin_bck,
387 .dout = (gpio_num_t)txPin,
395 if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
396 LOGE(
"i2s_channel_init_pdm_tx_mode %s",
"tx");
399 if (i2s_channel_enable(tx_chan) != ESP_OK) {
400 LOGE(
"i2s_channel_enable %s",
"tx");
406#if defined(USE_PDM_RX)
407 i2s_pdm_rx_slot_config_t getRxSlotConfig(I2SConfigESP32V1 &cfg) {
408 return I2S_PDM_RX_SLOT_DEFAULT_CONFIG(
409 (i2s_data_bit_width_t)cfg.bits_per_sample,
410 (i2s_slot_mode_t)cfg.channels);
412 i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
413 return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
415 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
416 i2s_pdm_rx_config_t pdm_rx_cfg = {
417 .clk_cfg = getRxClockConfig(cfg),
418 .slot_cfg = getRxSlotConfig(cfg),
421 .clk = (gpio_num_t)cfg.pin_bck,
422 .din = (gpio_num_t)rxPin,
430 if (i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg) != ESP_OK) {
431 LOGE(
"i2s_channel_init_pdm_rx_mode %s",
"rx");
434 if (i2s_channel_enable(rx_chan) != ESP_OK) {
435 LOGE(
"i2s_channel_enable %s",
"tx");
441 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
442 LOGE(
"PDM RX not supported");
453 struct DriverTDM :
public DriverCommon {
454 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
455 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
456 i2s_tdm_config_t tdm_cfg = {
457 .clk_cfg = getClockConfig(cfg),
458 .slot_cfg = getSlotConfig(cfg),
461 .mclk = (gpio_num_t)cfg.pin_mck,
462 .bclk = (gpio_num_t)cfg.pin_bck,
463 .ws = (gpio_num_t)cfg.pin_ws,
464 .dout = (gpio_num_t)txPin,
465 .din = (gpio_num_t)rxPin,
475 if (cfg.rx_tx_mode == TX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
476 if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
477 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"tx");
481 if (cfg.rx_tx_mode == RX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
482 if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
483 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"rx");
491 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
493 for (
int j = 0; j < cfg.channels; j++) {
497 i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
498 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
499 (i2s_tdm_slot_mask_t)slots);
501 switch (cfg.i2s_format) {
502 case I2S_RIGHT_JUSTIFIED_FORMAT:
504 case I2S_PHILIPS_FORMAT:
506 slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
507 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
508 (i2s_tdm_slot_mask_t)slots);
510 case I2S_LEFT_JUSTIFIED_FORMAT:
512 slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
513 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
514 (i2s_tdm_slot_mask_t)slots);
517 slot_cfg = I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(
518 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
519 (i2s_tdm_slot_mask_t)slots);
522 LOGE(
"TDM: Unsupported format");
528 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
529 return I2S_CHANNEL_DEFAULT_CONFIG(
530 (i2s_port_t)cfg.port_no,
531 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
534 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
535 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
550 LOGE(
"invalid channels: %d", cfg.
channels);
555 if (!newChannels(cfg, driver)) {
560 is_started = driver.startChannels(cfg, tx_chan, rx_chan, txPin, rxPin);
563 LOGE(
"Channels not started");
569 i2s_chan_config_t chan_cfg = driver.getChannelConfig(cfg);
572 if (i2s_new_channel(&chan_cfg, NULL, &rx_chan) != ESP_OK) {
578 if (i2s_new_channel(&chan_cfg, &tx_chan, NULL) != ESP_OK) {
584 if (i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan) != ESP_OK) {
592 DriverCommon &getDriver(I2SConfigESP32V1 &cfg) {
593 switch (cfg.signal_type) {
608 LOGE(
"Unsupported signal_type");