Skip to content

Commit 5214dec

Browse files
committed
PDM RX support
1 parent 177fbd5 commit 5214dec

File tree

1 file changed

+171
-124
lines changed

1 file changed

+171
-124
lines changed

src/AudioTools/CoreAudio/AudioI2S/I2SESP32V1.h

Lines changed: 171 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
#include "driver/i2s_tdm.h"
1212
#include "esp_system.h"
1313

14-
#define IS_I2S_IMPLEMENTED
15-
14+
#define IS_I2S_IMPLEMENTED
1615

1716
namespace audio_tools {
1817

@@ -106,7 +105,7 @@ class I2SDriverESP32V1 {
106105
size_t writeBytes(const void *src, size_t size_bytes) {
107106
TRACED();
108107
size_t result;
109-
assert(tx_chan !=nullptr);
108+
assert(tx_chan != nullptr);
110109
if (i2s_channel_write(tx_chan, src, size_bytes, &result,
111110
ticks_to_wait_write) != ESP_OK) {
112111
TRACEE();
@@ -140,11 +139,12 @@ class I2SDriverESP32V1 {
140139
TickType_t ticks_to_wait_write = portMAX_DELAY;
141140

142141
struct DriverCommon {
143-
virtual i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) = 0;
144142
virtual bool startChannels(I2SConfigESP32V1 &cfg,
145143
i2s_chan_handle_t &tx_chan,
146144
i2s_chan_handle_t &rx_chan, int txPin,
147145
int rxPin) = 0;
146+
147+
virtual i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) = 0;
148148
// changes the sample rate
149149
virtual bool changeSampleRate(I2SConfigESP32V1 &cfg,
150150
i2s_chan_handle_t &tx_chan,
@@ -154,6 +154,56 @@ class I2SDriverESP32V1 {
154154
};
155155

156156
struct DriverI2S : public DriverCommon {
157+
bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
158+
i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
159+
TRACED();
160+
LOGI("tx: %d, rx: %d", txPin, rxPin);
161+
i2s_std_config_t std_cfg = {
162+
.clk_cfg = getClockConfig(cfg),
163+
.slot_cfg = getSlotConfig(cfg),
164+
.gpio_cfg =
165+
{
166+
.mclk = (gpio_num_t)cfg.pin_mck,
167+
.bclk = (gpio_num_t)cfg.pin_bck,
168+
.ws = (gpio_num_t)cfg.pin_ws,
169+
.dout = (gpio_num_t)txPin,
170+
.din = (gpio_num_t)rxPin,
171+
.invert_flags =
172+
{
173+
.mclk_inv = false,
174+
.bclk_inv = false,
175+
.ws_inv = false,
176+
},
177+
},
178+
};
179+
180+
if (cfg.rx_tx_mode == RXTX_MODE || cfg.rx_tx_mode == TX_MODE) {
181+
if (i2s_channel_init_std_mode(tx_chan, &std_cfg) != ESP_OK) {
182+
LOGE("i2s_channel_init_std_mode %s", "tx");
183+
return false;
184+
}
185+
if (i2s_channel_enable(tx_chan) != ESP_OK) {
186+
LOGE("i2s_channel_enable %s", "tx");
187+
return false;
188+
}
189+
}
190+
191+
if (cfg.rx_tx_mode == RXTX_MODE || cfg.rx_tx_mode == RX_MODE) {
192+
if (i2s_channel_init_std_mode(rx_chan, &std_cfg) != ESP_OK) {
193+
LOGE("i2s_channel_init_std_mode %s", "rx");
194+
return false;
195+
}
196+
if (i2s_channel_enable(rx_chan) != ESP_OK) {
197+
LOGE("i2s_channel_enable %s", "rx");
198+
return false;
199+
}
200+
}
201+
202+
LOGD("%s - %s", __func__, "started");
203+
return true;
204+
}
205+
206+
protected:
157207
i2s_std_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
158208
TRACED();
159209
i2s_std_slot_config_t result;
@@ -212,10 +262,10 @@ class I2SDriverESP32V1 {
212262
TRACED();
213263
i2s_std_clk_config_t clk_cfg =
214264
I2S_STD_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
215-
if (cfg.mclk_multiple > 0){
216-
clk_cfg.mclk_multiple = (i2s_mclk_multiple_t) cfg.mclk_multiple;
265+
if (cfg.mclk_multiple > 0) {
266+
clk_cfg.mclk_multiple = (i2s_mclk_multiple_t)cfg.mclk_multiple;
217267
} else {
218-
if (cfg.pin_mck !=-1 && cfg.bits_per_sample == 24) {
268+
if (cfg.pin_mck != -1 && cfg.bits_per_sample == 24) {
219269
// mclk_multiple' should be the multiple of 3 while using 24-bit
220270
clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384;
221271
LOGI("mclk_multiple=384");
@@ -224,55 +274,6 @@ class I2SDriverESP32V1 {
224274
return clk_cfg;
225275
}
226276

227-
bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
228-
i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
229-
TRACED();
230-
LOGI("tx: %d, rx: %d", txPin, rxPin);
231-
i2s_std_config_t std_cfg = {
232-
.clk_cfg = getClockConfig(cfg),
233-
.slot_cfg = getSlotConfig(cfg),
234-
.gpio_cfg =
235-
{
236-
.mclk = (gpio_num_t)cfg.pin_mck,
237-
.bclk = (gpio_num_t)cfg.pin_bck,
238-
.ws = (gpio_num_t)cfg.pin_ws,
239-
.dout = (gpio_num_t)txPin,
240-
.din = (gpio_num_t)rxPin,
241-
.invert_flags =
242-
{
243-
.mclk_inv = false,
244-
.bclk_inv = false,
245-
.ws_inv = false,
246-
},
247-
},
248-
};
249-
250-
if (cfg.rx_tx_mode == RXTX_MODE || cfg.rx_tx_mode == TX_MODE) {
251-
if (i2s_channel_init_std_mode(tx_chan, &std_cfg) != ESP_OK) {
252-
LOGE("i2s_channel_init_std_mode %s", "tx");
253-
return false;
254-
}
255-
if (i2s_channel_enable(tx_chan) != ESP_OK) {
256-
LOGE("i2s_channel_enable %s", "tx");
257-
return false;
258-
}
259-
}
260-
261-
if (cfg.rx_tx_mode == RXTX_MODE || cfg.rx_tx_mode == RX_MODE) {
262-
if (i2s_channel_init_std_mode(rx_chan, &std_cfg) != ESP_OK) {
263-
LOGE("i2s_channel_init_std_mode %s", "rx");
264-
return false;
265-
}
266-
if (i2s_channel_enable(rx_chan) != ESP_OK) {
267-
LOGE("i2s_channel_enable %s", "rx");
268-
return false;
269-
}
270-
}
271-
272-
LOGD("%s - %s", __func__, "started");
273-
return true;
274-
}
275-
276277
bool changeSampleRate(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
277278
i2s_chan_handle_t &rx_chan) override {
278279
bool rc = false;
@@ -295,12 +296,30 @@ class I2SDriverESP32V1 {
295296
#ifdef USE_PDM
296297

297298
struct DriverPDM : public DriverCommon {
299+
bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
300+
i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
301+
if (cfg.rx_tx_mode == TX_MODE) {
302+
return startTX(cfg, tx_chan, txPin);
303+
} else if (cfg.rx_tx_mode == RX_MODE) {
304+
return startRX(cfg, tx_chan, txPin);
305+
}
306+
LOGE("Only RX and TX is supported for PDM")
307+
return false;
308+
}
309+
310+
protected:
298311
i2s_pdm_tx_slot_config_t getTxSlotConfig(I2SConfigESP32V1 &cfg) {
299312
return I2S_PDM_TX_SLOT_DEFAULT_CONFIG(
300313
(i2s_data_bit_width_t)cfg.bits_per_sample,
301314
(i2s_slot_mode_t)cfg.channels);
302315
}
303316

317+
i2s_pdm_rx_slot_config_t getRxSlotConfig(I2SConfigESP32V1 &cfg) {
318+
return I2S_PDM_RX_SLOT_DEFAULT_CONFIG(
319+
(i2s_data_bit_width_t)cfg.bits_per_sample,
320+
(i2s_slot_mode_t)cfg.channels);
321+
}
322+
304323
i2s_chan_config_t getChannelConfig(I2SConfigESP32V1 &cfg) {
305324
return I2S_CHANNEL_DEFAULT_CONFIG(
306325
(i2s_port_t)cfg.port_no,
@@ -311,37 +330,62 @@ class I2SDriverESP32V1 {
311330
return I2S_PDM_TX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
312331
}
313332

314-
bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
315-
i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
316-
if (cfg.rx_tx_mode == TX_MODE) {
317-
i2s_pdm_tx_config_t pdm_tx_cfg = {
318-
.clk_cfg = getTxClockConfig(cfg),
319-
.slot_cfg = getTxSlotConfig(cfg),
320-
.gpio_cfg =
321-
{
322-
.clk = (gpio_num_t)cfg.pin_bck,
323-
.dout = (gpio_num_t)txPin,
324-
.invert_flags =
325-
{
326-
.clk_inv = false,
327-
},
328-
},
329-
};
330-
331-
if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
332-
LOGE("i2s_channel_init_pdm_tx_mode %s", "tx");
333-
return false;
334-
}
335-
if (i2s_channel_enable(tx_chan) != ESP_OK) {
336-
LOGE("i2s_channel_enable %s", "tx");
337-
return false;
338-
}
339-
} else {
340-
LOGE("Only TX supported for PDM");
333+
i2s_pdm_rx_clk_config_t getRxClockConfig(I2SConfigESP32V1 &cfg) {
334+
return I2S_PDM_RX_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
335+
}
336+
337+
bool startTX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan, int txPin) {
338+
i2s_pdm_tx_config_t pdm_tx_cfg = {
339+
.clk_cfg = getTxClockConfig(cfg),
340+
.slot_cfg = getTxSlotConfig(cfg),
341+
.gpio_cfg =
342+
{
343+
.clk = (gpio_num_t)cfg.pin_bck,
344+
.dout = (gpio_num_t)txPin,
345+
.invert_flags =
346+
{
347+
.clk_inv = false,
348+
},
349+
},
350+
};
351+
352+
if (i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg) != ESP_OK) {
353+
LOGE("i2s_channel_init_pdm_tx_mode %s", "tx");
354+
return false;
355+
}
356+
if (i2s_channel_enable(tx_chan) != ESP_OK) {
357+
LOGE("i2s_channel_enable %s", "tx");
341358
return false;
342359
}
343360
return true;
344361
}
362+
363+
bool startRX(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &rx_chan, int rxPin) {
364+
i2s_pdm_rx_config_t pdm_rx_cfg = {
365+
.clk_cfg = getRxClockConfig(cfg),
366+
.slot_cfg = getRxSlotConfig(cfg),
367+
.gpio_cfg =
368+
{
369+
.clk = (gpio_num_t)cfg.pin_bck,
370+
.din = (gpio_num_t)rxPin,
371+
.invert_flags =
372+
{
373+
.clk_inv = false,
374+
},
375+
},
376+
};
377+
378+
if (i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg) != ESP_OK) {
379+
LOGE("i2s_channel_init_pdm_rx_mode %s", "rx");
380+
return false;
381+
}
382+
if (i2s_channel_enable(rx_chan) != ESP_OK) {
383+
LOGE("i2s_channel_enable %s", "tx");
384+
return false;
385+
}
386+
return true;
387+
}
388+
345389
} pdm;
346390

347391
#endif
@@ -350,26 +394,65 @@ class I2SDriverESP32V1 {
350394
// example at
351395
// https://github.com/espressif/esp-idf/blob/v5.3-dev/examples/peripherals/i2s/i2s_basic/i2s_tdm/main/i2s_tdm_example_main.c
352396
struct DriverTDM : public DriverCommon {
397+
bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
398+
i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
399+
i2s_tdm_config_t tdm_cfg = {
400+
.clk_cfg = getClockConfig(cfg),
401+
.slot_cfg = getSlotConfig(cfg),
402+
.gpio_cfg =
403+
{
404+
.mclk = (gpio_num_t)cfg.pin_mck,
405+
.bclk = (gpio_num_t)cfg.pin_bck,
406+
.ws = (gpio_num_t)cfg.pin_ws,
407+
.dout = (gpio_num_t)txPin,
408+
.din = (gpio_num_t)rxPin,
409+
.invert_flags =
410+
{
411+
.mclk_inv = false,
412+
.bclk_inv = false,
413+
.ws_inv = false,
414+
},
415+
},
416+
};
417+
418+
if (cfg.rx_tx_mode == TX_MODE) {
419+
if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
420+
LOGE("i2s_channel_init_tdm_tx_mode %s", "tx");
421+
return false;
422+
}
423+
}
424+
if (cfg.rx_tx_mode == RX_MODE) {
425+
if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
426+
LOGE("i2s_channel_init_tdm_tx_mode %s", "rx");
427+
return false;
428+
}
429+
return true;
430+
}
431+
LOGE("Only RX and TX is supported for TDM")
432+
return false;
433+
}
434+
435+
protected:
353436
i2s_tdm_slot_config_t getSlotConfig(I2SConfigESP32V1 &cfg) {
354437
int slots = 0;
355438
for (int j = 0; j < cfg.channels; j++) {
356439
slots |= 1 << j;
357440
}
358441
// setup default format
359442
i2s_tdm_slot_config_t slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
360-
(i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
361-
(i2s_tdm_slot_mask_t)slots);
443+
(i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
444+
(i2s_tdm_slot_mask_t)slots);
362445

363-
switch(cfg.i2s_format){
364-
case I2S_RIGHT_JUSTIFIED_FORMAT:
446+
switch (cfg.i2s_format) {
447+
case I2S_RIGHT_JUSTIFIED_FORMAT:
365448
case I2S_LSB_FORMAT:
366449
case I2S_PHILIPS_FORMAT:
367450
case I2S_STD_FORMAT:
368451
slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
369452
(i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
370453
(i2s_tdm_slot_mask_t)slots);
371454
break;
372-
case I2S_LEFT_JUSTIFIED_FORMAT:
455+
case I2S_LEFT_JUSTIFIED_FORMAT:
373456
case I2S_MSB_FORMAT:
374457
slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
375458
(i2s_data_bit_width_t)cfg.bits_per_sample, I2S_SLOT_MODE_STEREO,
@@ -397,42 +480,6 @@ class I2SDriverESP32V1 {
397480
return I2S_TDM_CLK_DEFAULT_CONFIG((uint32_t)cfg.sample_rate);
398481
}
399482

400-
bool startChannels(I2SConfigESP32V1 &cfg, i2s_chan_handle_t &tx_chan,
401-
i2s_chan_handle_t &rx_chan, int txPin, int rxPin) {
402-
i2s_tdm_config_t tdm_cfg = {
403-
.clk_cfg = getClockConfig(cfg),
404-
.slot_cfg = getSlotConfig(cfg),
405-
.gpio_cfg =
406-
{
407-
.mclk = (gpio_num_t)cfg.pin_mck,
408-
.bclk = (gpio_num_t)cfg.pin_bck,
409-
.ws = (gpio_num_t)cfg.pin_ws,
410-
.dout = (gpio_num_t)txPin,
411-
.din = (gpio_num_t)rxPin,
412-
.invert_flags =
413-
{
414-
.mclk_inv = false,
415-
.bclk_inv = false,
416-
.ws_inv = false,
417-
},
418-
},
419-
};
420-
421-
if (cfg.rx_tx_mode == TX_MODE) {
422-
if (i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg) != ESP_OK) {
423-
LOGE("i2s_channel_init_tdm_tx_mode %s", "tx");
424-
return false;
425-
}
426-
}
427-
if (cfg.rx_tx_mode == RX_MODE) {
428-
if (i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg) != ESP_OK) {
429-
LOGE("i2s_channel_init_tdm_tx_mode %s", "rx");
430-
return false;
431-
}
432-
return true;
433-
}
434-
return false;
435-
}
436483
} tdm;
437484

438485
#endif

0 commit comments

Comments
 (0)