In order to set I2S2 WS to 48KHz, SCLK to 3.072MHz, I Set the PLL2 Clock to 36864000Hz.
Actual behavior
The returned PLL2 clock is 36833333Hz, however WS is about 57.5kHz, it looks like the i2s.c driver is not correct.
Test code
Since the acutal clock of PLL2 cannot perfectly match the setting value. When the actual value is less than the setting value. The equation may get wrong result.
threshold = pll2_clock / (format->sample_rate 128) - 1;
We need to use float math function to get closer result.
threshold = round(1.0f pll2_clock / (format->sample_rate * 128) - 1);
The code in I2S.c:
static void extract_params(const audio_format_t format, uint32_t threshold, i2s_word_select_cycles_t wsc, i2s_word_length_t wlen, size_t block_align, uint32_t dma_divide16)
{
uint32_t pll2_clock = 0;
pll2_clock = sysctl_pll_get_freq(SYSCTL_PLL2);
configASSERT((format->sample_rate > pll2_clock / (1 << 23)) && (format->sample_rate < pll2_clock / (1 << 7)));
switch (format->bits_per_sample)
{
case 16:
wsc = SCLK_CYCLES_32;
wlen = RESOLUTION_16_BIT;
block_align = format->channels 2;
dma_divide16 = 1;
break;
case 24:
wsc = SCLK_CYCLES_32;
wlen = RESOLUTION_24_BIT;
block_align = format->channels 4;
dma_divide16 = 0;
break;
case 32:
wsc = SCLK_CYCLES_32;
wlen = RESOLUTION_32_BIT;
block_align = format->channels 4;
*dma_divide16 = 0;
break;
default:
configASSERT(!"Invlid bits per sample");
break;
}
// Fix Bug since the actual pll is not equal to set value. 2018/10/19
Expected behavior
In order to set I2S2 WS to 48KHz, SCLK to 3.072MHz, I Set the PLL2 Clock to 36864000Hz.
Actual behavior
The returned PLL2 clock is 36833333Hz, however WS is about 57.5kHz, it looks like the i2s.c driver is not correct.
Test code
Since the acutal clock of PLL2 cannot perfectly match the setting value. When the actual value is less than the setting value. The equation may get wrong result. threshold = pll2_clock / (format->sample_rate 128) - 1; We need to use float math function to get closer result. threshold = round(1.0f pll2_clock / (format->sample_rate * 128) - 1);
The code in I2S.c: static void extract_params(const audio_format_t format, uint32_t threshold, i2s_word_select_cycles_t wsc, i2s_word_length_t wlen, size_t block_align, uint32_t dma_divide16) { uint32_t pll2_clock = 0; pll2_clock = sysctl_pll_get_freq(SYSCTL_PLL2); configASSERT((format->sample_rate > pll2_clock / (1 << 23)) && (format->sample_rate < pll2_clock / (1 << 7))); switch (format->bits_per_sample) { case 16: wsc = SCLK_CYCLES_32; wlen = RESOLUTION_16_BIT; block_align = format->channels 2; dma_divide16 = 1; break; case 24: wsc = SCLK_CYCLES_32; wlen = RESOLUTION_24_BIT; block_align = format->channels 4; dma_divide16 = 0; break; case 32: wsc = SCLK_CYCLES_32; wlen = RESOLUTION_32_BIT; block_align = format->channels 4; *dma_divide16 = 0; break; default: configASSERT(!"Invlid bits per sample"); break; } // Fix Bug since the actual pll is not equal to set value. 2018/10/19
if 0
else
threshold = round(1.0f pll2_clock / (format->sample_rate * 128) - 1);
endif
}