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) {
162 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
164 LOGI(
"tx: %d, rx: %d", txPin, rxPin);
165 i2s_std_config_t std_cfg;
166 std_cfg.clk_cfg = getClockConfig(cfg);
167 std_cfg.slot_cfg = getSlotConfig(cfg);
169 .mclk = (gpio_num_t)cfg.pin_mck,
170 .bclk = (gpio_num_t)cfg.pin_bck,
171 .ws = (gpio_num_t)cfg.pin_ws,
172 .dout = (gpio_num_t)txPin,
173 .din = (gpio_num_t)rxPin,
184 if (i2s_channel_init_std_mode(tx_chan, &std_cfg) != ESP_OK) {
185 LOGE(
"i2s_channel_init_std_mode %s",
"tx");
188 if (i2s_channel_enable(tx_chan) != ESP_OK) {
189 LOGE(
"i2s_channel_enable %s",
"tx");
195 if (i2s_channel_init_std_mode(rx_chan, &std_cfg) != ESP_OK) {
196 LOGE(
"i2s_channel_init_std_mode %s",
"rx");
199 if (i2s_channel_enable(rx_chan) != ESP_OK) {
200 LOGE(
"i2s_channel_enable %s",
"rx");
205 LOGD(
"%s - %s", __func__,
"started");
212 i2s_std_slot_config_t result;
213 switch (cfg.i2s_format) {
214 case I2S_LEFT_JUSTIFIED_FORMAT:
216 result = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(
221 result = I2S_STD_PCM_SLOT_DEFAULT_CONFIG(
226 result = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(
234 case I2SChannelSelect::Left:
235 result.slot_mask = I2S_STD_SLOT_LEFT;
237 case I2SChannelSelect::Right:
238 result.slot_mask = I2S_STD_SLOT_RIGHT;
241 LOGW(
"Using channel_format: I2SChannelSelect::Left for mono");
242 result.slot_mask = I2S_STD_SLOT_LEFT;
252 i2s_chan_config_t result = I2S_CHANNEL_DEFAULT_CONFIG(
253 (i2s_port_t)cfg.port_no,
254 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
258 if (size > 0) result.dma_frame_num = size / frame_size;
259 LOGI(
"dma_frame_num: %d", (
int)result.dma_frame_num);
260 result.auto_clear = cfg.auto_clear;
266 i2s_std_clk_config_t clk_cfg;
267 memset(&clk_cfg, 0,
sizeof(i2s_std_clk_config_t));
273 clk_cfg.mclk_multiple = (i2s_mclk_multiple_t)cfg.
mclk_multiple;
274 LOGI(
"mclk_multiple=%d", clk_cfg.mclk_multiple);
278 clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384;
279 LOGI(
"mclk_multiple=384");
282 clk_cfg.mclk_multiple = cfg.use_apll ? I2S_MCLK_MULTIPLE_128 : I2S_MCLK_MULTIPLE_256;
283 LOGI(
"mclk_multiple=%d", clk_cfg.mclk_multiple);
292 soc_periph_i2s_clk_src_t result = I2S_CLK_SRC_DEFAULT;
294 if (cfg.pin_mck != -1 && !cfg.is_master) {
295#if SOC_I2S_HW_VERSION_2
296 LOGI(
"pin_mclk is input");
297 result = I2S_CLK_SRC_EXTERNAL;
300 LOGE(
"pin_mclk as input not supported");
307#if SOC_I2S_SUPPORTS_APLL
308 result = I2S_CLK_SRC_APLL;
309 LOGI(
"clk_src is I2S_CLK_SRC_APLL");
310#elif SOC_I2S_SUPPORTS_PLL_F160M
311 result = I2S_CLK_SRC_PLL_160M;
312 LOGI(
"clk_src is I2S_CLK_SRC_PLL_160M");
320 i2s_chan_handle_t &rx_chan)
override {
322 auto clock_cfg = getClockConfig(cfg);
323 if (tx_chan !=
nullptr) {
324 i2s_channel_disable(tx_chan);
325 rc = i2s_channel_reconfig_std_clock(tx_chan, &clock_cfg) == ESP_OK;
326 i2s_channel_enable(tx_chan);
328 if (rx_chan !=
nullptr) {
329 i2s_channel_disable(rx_chan);
330 rc = i2s_channel_reconfig_std_clock(rx_chan, &clock_cfg) == ESP_OK;
331 i2s_channel_enable(rx_chan);
340 struct DriverPDM :
public DriverCommon {
341 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
342 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
343 if (cfg.rx_tx_mode == TX_MODE) {
344 return startTX(cfg, tx_chan, txPin);
345 }
else if (cfg.rx_tx_mode == RX_MODE) {
346 return startRX(cfg, rx_chan, rxPin);
348 LOGE(
"Only RX and TX is supported for PDM")
353 i2s_pdm_tx_slot_config_t getTxSlotConfig(I2SConfigESP32V1 &cfg) {
354#ifdef SOC_I2S_HW_VERSION_2
355 return I2S_PDM_TX_SLOT_DAC_DEFAULT_CONFIG(
356 (i2s_data_bit_width_t)cfg.bits_per_sample,
357 (i2s_slot_mode_t)cfg.channels);
359 return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
360 (i2s_data_bit_width_t)cfg.bits_per_sample,
361 (i2s_slot_mode_t)cfg.channels);
365 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
366 return I2S_CHANNEL_DEFAULT_CONFIG(
367 (i2s_port_t)cfg.port_no,
368 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
371 i2s_pdm_tx_clk_config_t getTxClockConfig(I2SConfigESP32V1 &cfg) {
372 return I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
375 bool startTX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
int txPin) {
376 i2s_pdm_tx_config_t pdm_tx_cfg = {
377 .clk_cfg = getTxClockConfig(cfg),
378 .slot_cfg = getTxSlotConfig(cfg),
381 .clk = (gpio_num_t)cfg.pin_bck,
382 .dout = (gpio_num_t)txPin,
390 if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
391 LOGE(
"i2s_channel_init_pdm_tx_mode %s",
"tx");
394 if (i2s_channel_enable(tx_chan) != ESP_OK) {
395 LOGE(
"i2s_channel_enable %s",
"tx");
401#if defined(USE_PDM_RX)
402 i2s_pdm_rx_slot_config_t getRxSlotConfig(I2SConfigESP32V1 &cfg) {
403 return I2S_PDM_RX_SLOT_DEFAULT_CONFIG(
404 (i2s_data_bit_width_t)cfg.bits_per_sample,
405 (i2s_slot_mode_t)cfg.channels);
407 i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
408 return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
410 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
411 i2s_pdm_rx_config_t pdm_rx_cfg = {
412 .clk_cfg = getRxClockConfig(cfg),
413 .slot_cfg = getRxSlotConfig(cfg),
416 .clk = (gpio_num_t)cfg.pin_bck,
417 .din = (gpio_num_t)rxPin,
425 if (i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg) != ESP_OK) {
426 LOGE(
"i2s_channel_init_pdm_rx_mode %s",
"rx");
429 if (i2s_channel_enable(rx_chan) != ESP_OK) {
430 LOGE(
"i2s_channel_enable %s",
"tx");
436 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
437 LOGE(
"PDM RX not supported");
448 struct DriverTDM :
public DriverCommon {
449 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
450 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
451 i2s_tdm_config_t tdm_cfg = {
452 .clk_cfg = getClockConfig(cfg),
453 .slot_cfg = getSlotConfig(cfg),
456 .mclk = (gpio_num_t)cfg.pin_mck,
457 .bclk = (gpio_num_t)cfg.pin_bck,
458 .ws = (gpio_num_t)cfg.pin_ws,
459 .dout = (gpio_num_t)txPin,
460 .din = (gpio_num_t)rxPin,
470 if (cfg.rx_tx_mode == TX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
471 if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
472 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"tx");
476 if (cfg.rx_tx_mode == RX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
477 if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
478 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"rx");
486 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
488 for (
int j = 0; j < cfg.channels; j++) {
492 i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
493 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
494 (i2s_tdm_slot_mask_t)slots);
496 switch (cfg.i2s_format) {
497 case I2S_RIGHT_JUSTIFIED_FORMAT:
499 case I2S_PHILIPS_FORMAT:
501 slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
502 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
503 (i2s_tdm_slot_mask_t)slots);
505 case I2S_LEFT_JUSTIFIED_FORMAT:
507 slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
508 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
509 (i2s_tdm_slot_mask_t)slots);
512 slot_cfg = I2S_TDM_PCM_LONG_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 LOGE(
"TDM: Unsupported format");
523 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
524 return I2S_CHANNEL_DEFAULT_CONFIG(
525 (i2s_port_t)cfg.port_no,
526 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
529 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
530 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
545 LOGE(
"invalid channels: %d", cfg.
channels);
550 if (!newChannels(cfg, driver)) {
555 is_started = driver.startChannels(cfg, tx_chan, rx_chan, txPin, rxPin);
558 LOGE(
"Channels not started");
564 i2s_chan_config_t chan_cfg = driver.getChannelConfig(cfg);
567 if (i2s_new_channel(&chan_cfg, NULL, &rx_chan) != ESP_OK) {
573 if (i2s_new_channel(&chan_cfg, &tx_chan, NULL) != ESP_OK) {
579 if (i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan) != ESP_OK) {
587 DriverCommon &getDriver(I2SConfigESP32V1 &cfg) {
588 switch (cfg.signal_type) {
603 LOGE(
"Unsupported signal_type");