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 return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
355 (i2s_data_bit_width_t)cfg.bits_per_sample,
356 (i2s_slot_mode_t)cfg.channels);
359 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
360 return I2S_CHANNEL_DEFAULT_CONFIG(
361 (i2s_port_t)cfg.port_no,
362 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
365 i2s_pdm_tx_clk_config_t getTxClockConfig(I2SConfigESP32V1 &cfg) {
366 return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
369 bool startTX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
int txPin) {
370 i2s_pdm_tx_config_t pdm_tx_cfg = {
371 .clk_cfg = getTxClockConfig(cfg),
372 .slot_cfg = getTxSlotConfig(cfg),
375 .clk = (gpio_num_t)cfg.pin_bck,
376 .dout = (gpio_num_t)txPin,
384 if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
385 LOGE(
"i2s_channel_init_pdm_tx_mode %s",
"tx");
388 if (i2s_channel_enable(tx_chan) != ESP_OK) {
389 LOGE(
"i2s_channel_enable %s",
"tx");
395#if defined(USE_PDM_RX)
396 i2s_pdm_rx_slot_config_t getRxSlotConfig(I2SConfigESP32V1 &cfg) {
397 return I2S_PDM_RX_SLOT_DEFAULT_CONFIG(
398 (i2s_data_bit_width_t)cfg.bits_per_sample,
399 (i2s_slot_mode_t)cfg.channels);
401 i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
402 return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
404 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
405 i2s_pdm_rx_config_t pdm_rx_cfg = {
406 .clk_cfg = getRxClockConfig(cfg),
407 .slot_cfg = getRxSlotConfig(cfg),
410 .clk = (gpio_num_t)cfg.pin_bck,
411 .din = (gpio_num_t)rxPin,
419 if (i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg) != ESP_OK) {
420 LOGE(
"i2s_channel_init_pdm_rx_mode %s",
"rx");
423 if (i2s_channel_enable(rx_chan) != ESP_OK) {
424 LOGE(
"i2s_channel_enable %s",
"tx");
430 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan,
int rxPin) {
431 LOGE(
"PDM RX not supported");
442 struct DriverTDM :
public DriverCommon {
443 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
444 i2s_chan_handle_t &rx_chan,
int txPin,
int rxPin) {
445 i2s_tdm_config_t tdm_cfg = {
446 .clk_cfg = getClockConfig(cfg),
447 .slot_cfg = getSlotConfig(cfg),
450 .mclk = (gpio_num_t)cfg.pin_mck,
451 .bclk = (gpio_num_t)cfg.pin_bck,
452 .ws = (gpio_num_t)cfg.pin_ws,
453 .dout = (gpio_num_t)txPin,
454 .din = (gpio_num_t)rxPin,
464 if (cfg.rx_tx_mode == TX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
465 if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
466 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"tx");
470 if (cfg.rx_tx_mode == RX_MODE || cfg.rx_tx_mode == RXTX_MODE) {
471 if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
472 LOGE(
"i2s_channel_init_tdm_tx_mode %s",
"rx");
480 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
482 for (
int j = 0; j < cfg.channels; j++) {
486 i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
487 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
488 (i2s_tdm_slot_mask_t)slots);
490 switch (cfg.i2s_format) {
491 case I2S_RIGHT_JUSTIFIED_FORMAT:
493 case I2S_PHILIPS_FORMAT:
495 slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
496 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
497 (i2s_tdm_slot_mask_t)slots);
499 case I2S_LEFT_JUSTIFIED_FORMAT:
501 slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
502 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
503 (i2s_tdm_slot_mask_t)slots);
506 slot_cfg = I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(
507 (i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
508 (i2s_tdm_slot_mask_t)slots);
511 LOGE(
"TDM: Unsupported format");
517 i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
518 return I2S_CHANNEL_DEFAULT_CONFIG(
519 (i2s_port_t)cfg.port_no,
520 cfg.is_master ? I2S_ROLE_MASTER : I2S_ROLE_SLAVE);
523 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
524 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
539 LOGE(
"invalid channels: %d", cfg.
channels);
544 if (!newChannels(cfg, driver)) {
549 is_started = driver.startChannels(cfg, tx_chan, rx_chan, txPin, rxPin);
552 LOGE(
"Channels not started");
558 i2s_chan_config_t chan_cfg = driver.getChannelConfig(cfg);
561 if (i2s_new_channel(&chan_cfg, NULL, &rx_chan) != ESP_OK) {
567 if (i2s_new_channel(&chan_cfg, &tx_chan, NULL) != ESP_OK) {
573 if (i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan) != ESP_OK) {
581 DriverCommon &getDriver(I2SConfigESP32V1 &cfg) {
582 switch (cfg.signal_type) {
597 LOGE(
"Unsupported singal_type");