i2s: impove the clock division calculation

Reported from: https://esp32.com/viewtopic.php?f=25&t=24542&p=87595#p87595
This commit is contained in:
laokaiyao
2021-11-24 16:08:00 +08:00
parent 355e8bba76
commit af4e448928
11 changed files with 157 additions and 252 deletions

View File

@@ -26,27 +26,26 @@ static void i2s_hal_mclk_div_decimal_cal(i2s_hal_clock_cfg_t *clk_cfg, i2s_ll_mc
cal->mclk_div = clk_cfg->mclk_div;
cal->a = 1;
cal->b = 0;
/* If sclk = 0 means APLL clock applied, mclk_div should set to 1 */
if (!clk_cfg->sclk) {
cal->mclk_div = 1;
uint32_t freq_diff = clk_cfg->sclk - clk_cfg->mclk * cal->mclk_div;
if (!freq_diff) {
return;
}
uint32_t freq_diff = clk_cfg->sclk - clk_cfg->mclk * cal->mclk_div;
uint32_t min = ~0;
for (int a = 2; a <= I2S_LL_MCLK_DIVIDER_MAX; a++) {
for (int b = 1; b < a; b++) {
ma = freq_diff * a;
mb = clk_cfg->mclk * b;
if (ma == mb) {
cal->a = a;
cal->b = b;
return;
}
if (abs((mb - ma)) < min) {
cal->a = a;
cal->b = b;
min = abs(mb - ma);
}
// Calculate the closest 'b' in this loop, no need to loop 'b' to seek the closest value
int b = (int)(a * (freq_diff / (double)clk_cfg->mclk) + 0.5);
ma = freq_diff * a;
mb = clk_cfg->mclk * b;
if (ma == mb) {
cal->a = a;
cal->b = b;
return;
}
if (abs((mb - ma)) < min) {
cal->a = a;
cal->b = b;
min = abs(mb - ma);
}
}
}