arduino-audio-tools
Loading...
Searching...
No Matches
I2SESP32V1.h
Go to the documentation of this file.
1#pragma once
2
3#include "AudioToolsConfig.h"
4#if defined(ESP32) && !USE_LEGACY_I2S || defined(DOXYGEN)
5
7#include "driver/i2s_pdm.h"
8#include "driver/i2s_std.h"
9#include "driver/i2s_tdm.h"
10#include "esp_system.h"
11
12#define IS_I2S_IMPLEMENTED
13
14namespace audio_tools {
15
16// i2s_port_t not valid any more in ESP-IDF v6, but we keep it for compatibility
17#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
18using i2s_port_t = int;
19#endif
20
29 public:
32 I2SConfigESP32V1 c(mode);
33 return c;
34 }
37 // nothing to do
38 if (is_started) {
39 if (info.equals(cfg)) return true;
40 if (info.equalsExSampleRate(cfg)) {
42 LOGI("i2s_set_sample_rates: %d", (int)info.sample_rate);
44 }
45 } else {
46 LOGE("not started");
47 }
48 return false;
49 }
50
52 bool begin(RxTxMode mode) { return begin(defaultConfig(mode)); }
53
56 bool begin() { return (!is_started) ? begin(cfg) : true; }
57
60 TRACED();
61 this->cfg = cfg;
62
63 // stop if it is already open
64 if (is_started) end();
65
66 switch (cfg.rx_tx_mode) {
67 case TX_MODE:
69 case RX_MODE:
70 // usually we expet cfg.pin_data but if the used assinged rx we might
71 // consider this one
74 : cfg.pin_data);
75 default:
77 }
78 LOGE("Did not expect go get here");
79 }
80
83
86
88 void end() {
89 TRACED();
90 if (rx_chan != nullptr) {
93 rx_chan = nullptr;
94 }
95 if (tx_chan != nullptr) {
98 tx_chan = nullptr;
99 }
100
101 is_started = false;
102 }
103
106
108 size_t writeBytes(const void *src, size_t size_bytes) {
109 TRACED();
110 size_t result;
111 assert(tx_chan != nullptr);
112 if (i2s_channel_write(tx_chan, src, size_bytes, &result,
114 TRACEE();
115 }
116 return result;
117 }
118
119 size_t readBytes(void *dest, size_t size_bytes) {
120 size_t result = 0;
121 if (i2s_channel_read(rx_chan, dest, size_bytes, &result,
123 TRACEE();
124 }
125 return result;
126 }
127
134
135 protected:
138 i2s_chan_handle_t tx_chan = nullptr; // I2S tx channel handler
139 i2s_chan_handle_t rx_chan = nullptr; // I2S rx channel handler
140 bool is_started = false;
143
148 int rxPin) = 0;
149
151 // changes the sample rate
155 return false;
156 }
157
158 protected:
160 int get_bits_eff(int bits) { return (bits == 24) ? 32 : bits; }
161 };
162
163 struct DriverI2S : public DriverCommon {
166 TRACED();
167 LOGI("tx: %d, rx: %d", txPin, rxPin);
169 std_cfg.clk_cfg = getClockConfig(cfg);
170 std_cfg.slot_cfg = getSlotConfig(cfg);
171 std_cfg.gpio_cfg = {
172 .mclk = (gpio_num_t)cfg.pin_mck,
173 .bclk = (gpio_num_t)cfg.pin_bck,
174 .ws = (gpio_num_t)cfg.pin_ws,
175 .dout = (gpio_num_t)txPin,
176 .din = (gpio_num_t)rxPin,
177 .invert_flags =
178 {
179 .mclk_inv = false,
180 .bclk_inv = false,
181 .ws_inv = false,
182 },
183 };
184
185
188 LOGE("i2s_channel_init_std_mode %s", "tx");
189 return false;
190 }
192 LOGE("i2s_channel_enable %s", "tx");
193 return false;
194 }
195 }
196
199 LOGE("i2s_channel_init_std_mode %s", "rx");
200 return false;
201 }
203 LOGE("i2s_channel_enable %s", "rx");
204 return false;
205 }
206 }
207
208 LOGD("%s - %s", __func__, "started");
209 return true;
210 }
211
212 protected:
214 TRACED();
216 switch (cfg.i2s_format) {
218 case I2S_MSB_FORMAT:
222 break;
223 case I2S_PCM:
227 break;
228 default:
232 }
233
234 // Update slot_mask if only one channel
235 if (cfg.channels == 1) {
236 switch (cfg.channel_format) {
238 result.slot_mask = I2S_STD_SLOT_LEFT;
239 break;
241 result.slot_mask = I2S_STD_SLOT_RIGHT;
242 break;
243 default:
244 LOGW("Using channel_format: I2SChannelSelect::Left for mono");
245 result.slot_mask = I2S_STD_SLOT_LEFT;
246 break;
247 }
248 }
249
250 return result;
251 }
252
254 TRACED();
258 // use the legicy size parameters for frame num
259 int size = cfg.buffer_size * cfg.buffer_count;
260 int frame_size = get_bits_eff(cfg.bits_per_sample) * cfg.channels / 8;
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);
264 result.auto_clear = cfg.auto_clear;
265 return result;
266 }
267
269 TRACED();
270 i2s_std_clk_config_t clk_cfg;// = I2S_STD_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
271 memset(&clk_cfg, 0, sizeof(i2s_std_clk_config_t));
272 clk_cfg.sample_rate_hz = cfg.sample_rate;
273 clk_cfg.clk_src = getClockSource(cfg);
274 // clk_cfg.ext_clk_freq_hz = 0;
275
276 if (cfg.mclk_multiple > 0) {
278 LOGI("mclk_multiple=%d", clk_cfg.mclk_multiple);
279 } else {
280 if (cfg.bits_per_sample == 24) {
281 // mclk_multiple' should be the multiple of 3 while using 24-bit
282 // using the apll seems to double the frequency
284 LOGI("mclk_multiple=384");
285 } else {
286 // when use_appll is true, the multiple of 128 gives 256kHz
287 // using the apll seems to double the frequency
289 LOGI("mclk_multiple=%d", clk_cfg.mclk_multiple);
290 }
291 }
292
293 return clk_cfg;
294 }
295
299 // use mclk pin as input in slave mode if supported
300 if (cfg.pin_mck != -1 && !cfg.is_master) {
301#if SOC_I2S_HW_VERSION_2
302 LOGI("pin_mclk is input");
303 result = I2S_CLK_SRC_EXTERNAL;
304 return result;
305#else
306 LOGE("pin_mclk as input not supported");
307#endif
308 }
309
310 // select APLL clock if possible
311 if (cfg.use_apll) {
312 // select clock source
313#if SOC_I2S_SUPPORTS_APLL
314 result = I2S_CLK_SRC_APLL;
315 LOGI("clk_src is I2S_CLK_SRC_APLL");
316#elif SOC_I2S_SUPPORTS_PLL_F160M
317 result = I2S_CLK_SRC_PLL_160M;
318 LOGI("clk_src is I2S_CLK_SRC_PLL_160M");
319#endif
320 }
321
322 return result;
323 }
324
341
343
344#ifdef USE_PDM
345
346 struct DriverPDM : public DriverCommon {
347 bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
348 i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
349 if (cfg.rx_tx_mode == TX_MODE) {
350 return startTX(cfg, tx_chan, txPin);
351 } else if (cfg.rx_tx_mode == RX_MODE) {
352 return startRX(cfg, rx_chan, rxPin);
353 }
354 LOGE("Only RX and TX is supported for PDM")
355 return false;
356 }
357
358 protected:
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);
364#else
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);
368#endif
369 }
370
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);
375 }
376
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);
380#else
381 return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
382#endif
383 }
384
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),
389 .gpio_cfg =
390 {
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, // required in IDF v6+
395#endif
396 .invert_flags =
397 {
398 .clk_inv = false,
399 },
400 },
401 };
402
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");
405 return false;
406 }
407 if (i2s_channel_enable(tx_chan) != ESP_OK) {
408 LOGE("i2s_channel_enable %s", "tx");
409 return false;
410 }
411 return true;
412 }
413
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);
419 }
420 i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
421 return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
422 }
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),
427 .gpio_cfg =
428 {
429 .clk = (gpio_num_t)cfg.pin_bck,
430 .din = (gpio_num_t)rxPin,
431 .invert_flags =
432 {
433 .clk_inv = false,
434 },
435 },
436 };
437
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");
440 return false;
441 }
442 if (i2s_channel_enable(rx_chan) != ESP_OK) {
443 LOGE("i2s_channel_enable %s", "tx");
444 return false;
445 }
446 return true;
447 }
448#else
449 bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan, int rxPin) {
450 LOGE("PDM RX not supported");
451 return false;
452 }
453#endif
454 } pdm;
455
456#endif
457
458#ifdef USE_TDM
459 // example at
460 // https://github.com/espressif/esp-idf/blob/v5.3-dev/examples/peripherals/i2s/i2s_basic/i2s_tdm/main/i2s_tdm_example_main.c
461 struct DriverTDM : public DriverCommon {
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),
467 .gpio_cfg =
468 {
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,
474 .invert_flags =
475 {
476 .mclk_inv = false,
477 .bclk_inv = false,
478 .ws_inv = false,
479 },
480 },
481 };
482
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");
486 return false;
487 }
488 }
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");
492 return false;
493 }
494 }
495 return true;
496 }
497
498 protected:
499 i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
500 int slots = 0;
501 for (int j = 0; j < cfg.channels; j++) {
502 slots |= 1 << j;
503 }
504 // setup default format
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);
508
509 switch (cfg.i2s_format) {
511 case I2S_LSB_FORMAT:
513 case I2S_STD_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);
517 break;
519 case I2S_MSB_FORMAT:
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);
523 break;
524 case I2S_PCM:
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);
528 break;
529 default:
530 LOGE("TDM: Unsupported format");
531 }
532
533 return slot_cfg;
534 }
535
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);
540 }
541
542 i2s_tdm_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg) {
543 return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
544 }
545
546 } tdm;
547
548#endif
549
551
554 TRACED();
555 cfg.logInfo();
556 this->cfg = cfg;
557 if (cfg.channels <= 0 || cfg.channels > 2) {
558 LOGE("invalid channels: %d", cfg.channels);
559 return false;
560 }
561
562 DriverCommon &driver = getDriver(cfg);
563 if (!newChannels(cfg, driver)) {
564 end();
565 return false;
566 }
567
569 if (!is_started) {
570 end();
571 LOGE("Channels not started");
572 }
573 return is_started;
574 }
575
578 switch (cfg.rx_tx_mode) {
579 case RX_MODE:
581 LOGE("i2s_channel");
582 return false;
583 }
584 break;
585 case TX_MODE:
587 LOGE("i2s_channel");
588 return false;
589 }
590 break;
591 default:
593 LOGE("i2s_channel");
594 return false;
595 }
596 }
597 return true;
598 }
599
601 switch (cfg.signal_type) {
602 case Digital:
603 return i2s;
604#ifdef USE_PDM
605 case Analog:
606 case PDM:
607 return pdm;
608#endif
609#ifdef USE_TDM
610 case TDM:
611 return tdm;
612#endif
613 default:
614 break;
615 }
616 LOGE("Unsupported signal_type");
617 return i2s;
618 }
619};
620
621using I2SDriver = I2SDriverESP32V1;
622
623} // namespace audio_tools
624
625#endif
#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_BUFFER_SIZE
Definition AudioToolsConfig.h:102
#define I2S_BUFFER_COUNT
Definition AudioToolsConfig.h:106
#define assert(T)
Definition avr.h:10
Configuration for ESP32 i2s for IDF > 5.0.
Definition I2SConfigESP32V1.h:21
int buffer_count
not used any more
Definition I2SConfigESP32V1.h:65
int pin_mck
Definition I2SConfigESP32V1.h:63
RxTxMode rx_tx_mode
public settings
Definition I2SConfigESP32V1.h:54
int pin_ws
Definition I2SConfigESP32V1.h:59
bool auto_clear
Definition I2SConfigESP32V1.h:69
I2SSignalType signal_type
Definition I2SConfigESP32V1.h:56
int pin_data
Definition I2SConfigESP32V1.h:61
int pin_data_rx
Definition I2SConfigESP32V1.h:62
bool use_apll
Definition I2SConfigESP32V1.h:68
int mclk_multiple
masterclock multiple (-1 = use default)
Definition I2SConfigESP32V1.h:73
bool is_master
Definition I2SConfigESP32V1.h:57
int pin_bck
Definition I2SConfigESP32V1.h:60
I2SFormat i2s_format
Definition I2SConfigESP32V1.h:55
void logInfo(const char *source="")
Definition I2SConfigESP32V1.h:75
int port_no
Definition I2SConfigESP32V1.h:58
I2SChannelSelect channel_format
Select left or right channel when channels == 1.
Definition I2SConfigESP32V1.h:71
int buffer_size
not used any more
Definition I2SConfigESP32V1.h:67
Basic I2S API for the ESP32 (using the new API). https://docs.espressif.com/projects/esp-idf/en/v5....
Definition I2SESP32V1.h:28
I2SConfigESP32V1 defaultConfig(RxTxMode mode)
Provides the default configuration.
Definition I2SESP32V1.h:31
void setWaitTimeWriteMs(TickType_t ms)
Definition I2SESP32V1.h:131
bool begin(I2SConfigESP32V1 cfg)
starts the DAC
Definition I2SESP32V1.h:59
i2s_chan_handle_t rx_chan
Definition I2SESP32V1.h:139
TickType_t ticks_to_wait_read
Definition I2SESP32V1.h:141
audio_tools::I2SDriverESP32V1::DriverI2S i2s
void setWaitTimeReadMs(TickType_t ms)
Definition I2SESP32V1.h:128
int available()
we assume the data is already available in the buffer
Definition I2SESP32V1.h:82
bool is_started
Definition I2SESP32V1.h:140
bool begin()
Definition I2SESP32V1.h:56
bool setAudioInfo(AudioInfo info)
Potentially updates the sample rate (if supported)
Definition I2SESP32V1.h:36
i2s_chan_handle_t tx_chan
Definition I2SESP32V1.h:138
bool newChannels(I2SConfigESP32V1 &cfg, DriverCommon &driver)
Definition I2SESP32V1.h:576
int availableForWrite()
We limit the write size to the buffer size.
Definition I2SESP32V1.h:85
I2SConfigESP32V1 config()
provides the actual configuration
Definition I2SESP32V1.h:105
DriverCommon & getDriver(I2SConfigESP32V1 &cfg)
Definition I2SESP32V1.h:600
void end()
stops the I2C and unistalls the driver
Definition I2SESP32V1.h:88
bool begin(RxTxMode mode)
starts the DAC with the default config
Definition I2SESP32V1.h:52
bool begin(I2SConfigESP32V1 cfg, int txPin, int rxPin)
-> protected methods from I2SDriverESP32V1
Definition I2SESP32V1.h:553
TickType_t ticks_to_wait_write
Definition I2SESP32V1.h:142
size_t writeBytes(const void *src, size_t size_bytes)
writes the data to the I2S interface
Definition I2SESP32V1.h:108
I2SConfigESP32V1 cfg
Definition I2SESP32V1.h:136
i2s_std_config_t i2s_config
Definition I2SESP32V1.h:137
size_t readBytes(void *dest, size_t size_bytes)
Definition I2SESP32V1.h:119
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
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
@ Digital
Definition AudioTypes.h:442
@ PDM
Definition AudioTypes.h:444
@ TDM
Definition AudioTypes.h:445
@ Analog
Definition AudioTypes.h:443
I2SDriverESP32 I2SDriver
Definition I2SESP32.h:400
@ I2S_STD_FORMAT
Definition AudioTypes.h:421
@ I2S_PHILIPS_FORMAT
Definition AudioTypes.h:424
@ I2S_LSB_FORMAT
Definition AudioTypes.h:422
@ I2S_LEFT_JUSTIFIED_FORMAT
Definition AudioTypes.h:426
@ I2S_RIGHT_JUSTIFIED_FORMAT
Definition AudioTypes.h:425
@ I2S_MSB_FORMAT
Definition AudioTypes.h:423
@ I2S_PCM
Definition AudioTypes.h:427
int i2s_port_t
Definition I2SESP32V1.h:18
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:55
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:57
bool equals(AudioInfo alt)
Returns true if alt values are the same like the current values.
Definition AudioTypes.h:87
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
bool equalsExSampleRate(AudioInfo alt)
Checks if only the sample rate is different.
Definition AudioTypes.h:90
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:61
virtual i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg)=0
int get_bits_eff(int bits)
24 bits are stored in a 32 bit integer
Definition I2SESP32V1.h:160
virtual bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, i2s_chan_handle_t &rx_chan, int txPin, int rxPin)=0
virtual bool changeSampleRate(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, i2s_chan_handle_t &rx_chan)
Definition I2SESP32V1.h:152
Definition I2SESP32V1.h:163
bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, i2s_chan_handle_t &rx_chan, int txPin, int rxPin)
Definition I2SESP32V1.h:164
i2s_std_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg)
Definition I2SESP32V1.h:213
i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg)
Definition I2SESP32V1.h:253
i2s_std_clk_config_t getClockConfig(I2SConfigESP32V1 &cfg)
Definition I2SESP32V1.h:268
bool changeSampleRate(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, i2s_chan_handle_t &rx_chan) override
Definition I2SESP32V1.h:325
soc_periph_i2s_clk_src_t getClockSource(I2SConfigESP32V1 &cfg)
select clock source dependent on is_master and use_apll
Definition I2SESP32V1.h:297