### Re: Document Requests

Posted:

**Fri Sep 28, 2018 1:58 am**You may want to email sales at espressif dot com for that, they can probably help you.

Page **4** of **4**

Posted: **Fri Sep 28, 2018 1:58 am**

You may want to email sales at espressif dot com for that, they can probably help you.

Posted: **Fri Sep 28, 2018 3:27 pm**

Solved, thank you.

Posted: **Tue Oct 16, 2018 2:31 am**

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 APLL-related 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 APLL-related 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 fixed-point 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 sub-registers:

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

Posted: **Sat Oct 20, 2018 11:33 am**

There are many HW bugs in ESP32 peripherals that should be mentioned in the "ECO and Workarounds for Bugs in ESP32" document.

For instance:

For instance:

- [SPI] dummy phase does not work while using mosi phase
- [SPI] CS setup time does not work in full duplex
- [SPI] there are some issues with DMA (see https://github.com/espressif/esp-idf/blob/129d32772e5e5eafe88be5b9eb34687e84a6f8b8/components/driver/spi_common.c#L365-L394)
- [I2C] FSM can get into a state when it is needed to reset the peripheral
- [UART] setting 2 stop bits does not work (see https://github.com/espressif/esp-idf/blob/8893438f08a295c18ee63f363bd0f6d375c2228a/components/driver/uart.c#L145-L149)