PDM-mode of I2S peripheral through i2s driver
Posted: Fri Dec 15, 2017 2:45 pm
Hello there,
I've got an audio amplifier chip attached to the Rev. 1 ESP32 and I'm trying to get the PDM-mode of the i2s mode running without success so far. There are several things I struggle with and somehow no sound seems to emerge from my speakers, even though I tried multiple different combinations of parameters... I'm trying to get it to work with the i2s driver module i2s.c.
Here's what I do:
First, I initialize the module
This results in the following console output:
So... the clock is running at 512kHz? I'm not sure about I2S, but concerning PDM, from my understanding - mainly from the datasheet of the amplifier - the PDM clock frequency for a sampling rate of 16kHz should be at 2.048MHz for 128x oversampled PDM. If I read the chapter 11.4.7 "I2S PDM" of the ESP32 Technical reference manual, if I understand this right, it says that the PDM-Frequency will always be 48x128kHz, i.e. 6.144MHz. That would correspond to an audio sampling rate of 48kHz.
Is this correct? Is the PDM mode of the I2S peripheral built such, that it will always output 48kHz audio at a PDM-clock-rate of 6.144MHz? If so, then the frequency calculation for the APLL in i2s.c is definitely wrong!
After the initialisation, I just continuously feed a sine wave. I'm not sure in what format (endianness) it has to be, but as long as I don't hear no sound at all, I don't really care if the PCM data is read out correctly.
I also tried to use it without the audio PLL, but this seems to result in an extremely unstable clock (see trace below)!
I'd be happy for any pointers on what to do to get PDM working! I urgently need it!
EDIT: Removed section about signals being out-of-phase, as that does not seem to be relevant.
EDIT 2: Okay, at least without APLL it seems to be working on the ESP32-side, I do also have a hardware problem here... Nonetheless, a fix for the APLL calculation would be great!
I've got an audio amplifier chip attached to the Rev. 1 ESP32 and I'm trying to get the PDM-mode of the i2s mode running without success so far. There are several things I struggle with and somehow no sound seems to emerge from my speakers, even though I tried multiple different combinations of parameters... I'm trying to get it to work with the i2s driver module i2s.c.
Here's what I do:
First, I initialize the module
Code: Select all
const i2s_pin_config_t pdm_pin_cfg =
{
.bck_io_num = I2S_PIN_NO_CHANGE,
.ws_io_num = PDM_CLK_PIN,
.data_out_num = PDM_DATA_PIN,
.data_in_num = I2S_PIN_NO_CHANGE
};
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_PDM,
.sample_rate = 16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_PCM,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 8,
.dma_buf_len = 64,
.use_apll = 1,
};
ESP_ERROR_CHECK( i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL) );
ESP_ERROR_CHECK( i2s_set_pin(I2S_PORT, &pdm_pin_cfg) );
Code: Select all
I2S: APLL: Req RATE: 16000, real rate: 15999.001, BITS: 16, CLKM: 1, BCK: 8, MCLK: 5.208, SCLK: 511968.031250, diva: 1, divb:
0
Is this correct? Is the PDM mode of the I2S peripheral built such, that it will always output 48kHz audio at a PDM-clock-rate of 6.144MHz? If so, then the frequency calculation for the APLL in i2s.c is definitely wrong!
After the initialisation, I just continuously feed a sine wave. I'm not sure in what format (endianness) it has to be, but as long as I don't hear no sound at all, I don't really care if the PCM data is read out correctly.
Code: Select all
static const uint16_t mod_sin_table_a[] =
{
32767, 37892, 42892, 47642, 52026, 55936, 59276, 61962,
63930, 65130, 65534, 65130, 63930, 61962, 59276, 55936,
52026, 47642, 42892, 37892, 32766, 27641, 22641, 17891,
13507, 9597, 6257, 3571, 1603, 403, 0, 403,
1603, 3571, 6257, 9597, 13507, 17891, 22641, 27641,
};
for(;;)
{
assert(0 < i2s_write_bytes(I2S_PORT, (const char *)mod_sin_table_a, sizeof(mod_sin_table_a), portMAX_DELAY));
}
I'd be happy for any pointers on what to do to get PDM working! I urgently need it!
EDIT: Removed section about signals being out-of-phase, as that does not seem to be relevant.
EDIT 2: Okay, at least without APLL it seems to be working on the ESP32-side, I do also have a hardware problem here... Nonetheless, a fix for the APLL calculation would be great!