I'm struggling to understand how I need to configure the TLV320ADC5140 to take two PDM microphones (hardware-configured for left and right) on a single TLV320 channel and send the data via I2S.
Whatever configuration I try seems to always end up with only the right microphone data being received at my microcontroller (an ESP32) and the audio is always jittery.
I'm absolutely certain it's my understanding of how I need to configure the TLV320ADC5140 and would appreciate some pointers.
So far, I followed the 8-channel PDM example in the datasheet however, I've stripped it back by removing 6 of those channels:
/* ASI_CFG0: I2S mode and 32bit word length */ 0x07: 112 [0111 0000] /* PDMIN_CFG: PDMDIN1_EDGE ch1 positive, ch2 negative respective of INMP621 datasheet, page 5 */ 0x20: 192 [1100 0000] /* GPO1_CFG: PDM clock output, drive active low active high */ 0x22: 65 [0100 0001] /* GPI_CFG0: PDM data input channel 1 and 2 */ 0x2B: 69 [0100 0101] /* CH1_CFG0: configured for PDM input */ 0x3C: 64 [0100 0000] /* IN_CH_EN: enable channel 1 */ 0x73: 192 [1100 0000] /* ASI_OUT_CH_EN: enable channel 1 slot */ 0x74: 128 [1000 0000]
I guess I'm more confused about how both of the microphones on a single channel (with interleaved left/right data) maps to an output ASI slot. Does it still present as interleaved data over the I2S bus?
How is the frame size for the PDM interface determined? Is it 16-bits for left and 16-bits for the right channel, given that the ASI_WLEN is set to 32-bits?
Other relevant information:
- PDMCLK appears to be 3.072MHz
- FSYNC is 16kHz
- BCLK is 1.024MHz
- Sample rate is 16kHz
I2S bus is initialised as follows:
Audio::Audio() :
tlv {},
bck {21},
ws {25},
data {27},
sampleRate {16000},
bitsPerSample {32},
channelFormat {I2S_CHANNEL_FMT_RIGHT_LEFT},
communicationFormat {I2S_COMM_FORMAT_I2S}
{
/* zero the buffer */
std::memset(this->buffer, 0, BufferSize);
/* i2s configuration */
this->config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = this->sampleRate,
.bits_per_sample = i2s_bits_per_sample_t(this->bitsPerSample),
.channel_format = this->channelFormat,
.communication_format = this->communicationFormat,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 1024,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};
/* configure the GPIO pins */
this->pins = {
.bck_io_num = this->bck,
.ws_io_num = this->ws,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = this->data
};
}
Below is a scope trace showing BCLK and SDOUT. It looks like only half the data is being sent on SDOUT:

UPDATE:
I've updated ASI_CH1 = 32 so that it is I2S right slot 0 and I've set ASI_CH2 = 0 so that it is I2S left slot 0 and I now see more data on SDOUT:

Basically, I have absolutely no idea what I'm doing right now...


