Document Requests

 Posts: 1931
 Joined: Thu Nov 26, 2015 4:08 am
Re: Document Requests
You may want to email sales at espressif dot com for that, they can probably help you.
Re: Document Requests
Greetings,
I'm working on an audio application and would like to be able to dynamically update the APLL settings to servo its clock rate to match an external reference. It's not at all clear how to do this.
The function rtc_clk_apll_enable() sets some registers and then waits for "calibration". What's happening here? Can we please get some detailed documentation of what these APLLrelated registers do and how to set them?
Also, the function i2s_apll_calculate_fi2s() in i2s.c is not at all correctly written. I have a new version of it (including comments describing the math behind it) that does this calculation in a sensible fashion based upon the equations in the documentation:
Thanks,
Douglas Mandell
Dolby Laboratories, Inc.
San Francisco
I'm working on an audio application and would like to be able to dynamically update the APLL settings to servo its clock rate to match an external reference. It's not at all clear how to do this.
The function rtc_clk_apll_enable() sets some registers and then waits for "calibration". What's happening here? Can we please get some detailed documentation of what these APLLrelated registers do and how to set them?
Also, the function i2s_apll_calculate_fi2s() in i2s.c is not at all correctly written. I have a new version of it (including comments describing the math behind it) that does this calculation in a sensible fashion based upon the equations in the documentation:
Code: Select all
static esp_err_t i2s_apll_calculate_fi2s(int rate, int bits_per_sample, int *sdm0, int *sdm1, int *sdm2, int *odir)
{
if (rate / (bits_per_sample * 2 * 8) < APLL_I2S_MIN_RATE)
return ESP_FAIL;
/* For maximum flexibility, we need to target the APLL frequency, fout, to be in the middle of its range,
or its geometric mean. Thus start with fout = sqrt(APLL_I2S_MIN_RATE * APLL_I2S_MIN_RATE).
In order to produce our target rate, we figure the divisor needed to get close from the mean APLL frequency.
Starting with the equation relating fout, rate, and o_div:
rate = fout / ((o_div + 2) * 2)
We solve for o_div:
(o_div + 2) * 2 = fout / rate
o_div + 2 = fout / (2 * rate)
o_div = fout / (2 * rate)  2
and can now calculate it directly. After rounding o_div to the nearest integer, we plug it back into the
formula and solve for sdm, which is really just a fixedpoint number with 6 bits of integer part and 16
bits of fraction. It only needs to be split into sdm0, sdm1, and sdm2 when we load it into the hardware
registers.
First, recalculate the actual fout using the integer version of o_div:
fout = rate * ((o_div + 2) * 2)
then use this value to calculate sdm by solving the following for sdm:
fout = xtal_freq * (4 + sdm / 65536)
4 + sdm / 65536 = fout / xtal_freq
sdm / 65536 = fout / xtal_freq  4
sdm = 65536 * (fout / xtal_freq  4)
sdm, rounded and converted to an integer, can now be broken into subregisters:
sdm2 = sdm >> 16
sdm1 = (sdm >> 8) & 0x000000ff
sdm0 = sdm & 0x000000ff
*/
/* not sure why a factor of 4 is needed in two places below; the docs imply it should be 2 */
float o_div_f = (float) APLL_GEO_MEAN_FREQ / (float)(4 * rate)  2.0;
*odir = (int)floorf(o_div_f + 0.5f);
float fout = (float)(rate * (*odir + 2) * 4);
float f_xtal = (float)rtc_clk_xtal_freq_get() * 1000000.0f;
int sdm = (int)floorf(65536.0f * (fout / f_xtal  4.0f) + 0.5f);
*sdm2 = sdm >> 16;
*sdm1 = (sdm >> 8) & 0x000000ff;
*sdm0 = sdm & 0x000000ff;
return ESP_OK;
}
Thanks,
Douglas Mandell
Dolby Laboratories, Inc.
San Francisco
Who is online
Users browsing this forum: No registered users and 3 guests