Page 1 of 1

APLL / GPIO16_EMAC_CLK_OUT - wrong frequency - unable to generate 50MHz clk with rev0 chip

Posted: Thu Oct 12, 2017 11:48 am
by sauttefk
I want to use the APLL to generate the required 50MHz for an external Ethernet PHY using the APLL and the EMAC_CLK_OUT on GPIO16.

Somehow the output frequency is unexpectedly divided by 5

According to the ECO and Workarounds for Bugs in ESP32 (issue 3.7) document the formula for the APLL frequency for rev0 chips is:
f_out = f_xtal × (sdm2 + 4) / (2 × (o_div + 2)) where f_xtal is 40MHz, sdm2 is 6 (4th parameter), o_div is 2 (5th parameter).
This evaluates to f_out = 40MHz × (6 + 4) / (2 × (2 + 2)) =>f_out = 400MHz / 8 => f_out = 50MHz
According to the ESP32 Technical Reference Manual (paragraph 3.2.7) the dividend of the formula (f_xtal × (sdm2 + 4)) has a frequency range from 350MHz to 500MHz (Where 400MHz lies well within).

I'm setting up set the correct parameters with rtc_clk_apll_enable(1, 0, 0, 6, 2) but the frequency I get on GPIO16 is 10MHz instead of 50MHz.

When I change o_div from 2 to 0, I get 20MHz (which prooves that the divisor works as described).
When I change sdm2 from 6 to 8, I get 12MHz (which prooves that the dividend works as described in the formula).
When I change sdm2 to 1 and o_div to 0 (rtc_clk_apll_enable(1, 0, 0, 1, 0)) - this also evaluates to 50MHz - the function call never returns, as the dividend now gets 200MHz which is out of the frequency range of the APLL but rtc_clk_apll_enable waits for a PLL-lock which never happens (which prooves that the dividend is lower than the specified minimum).
When I change sdm2 to 11 and o_div to 4 (rtc_clk_apll_enable(1, 0, 0, 11, 4)) - this also evaluates to 50MHz - but the dividend is now 600MHz and the PLL gets no lock (which prooves that the dividend is higher than the specified maximum).

My questions:
  • Is there any by 5 divider which has to be disabled?
  • Is the APLL somehow using the internal 8MHz clock instead of the external 40MHz crystal?
  • Can anybody provide me some code that generates a 50MHz clk on GPIO16?
The code that I'm currently using is as follows:

Code: Select all

#include "soc/rtc.h"
#include "soc/emac_ex_reg.h"

ESP_LOGD(TAG, "################ set up EMAC_CLK_OUT #############");
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, FUNC_GPIO16_EMAC_CLK_OUT);
REG_SET_FIELD(EMAC_EX_CLKOUT_CONF_REG, EMAC_EX_CLK_OUT_H_DIV_NUM, 0);
REG_SET_FIELD(EMAC_EX_CLKOUT_CONF_REG, EMAC_EX_CLK_OUT_DIV_NUM, 0);
REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_INT_OSC_EN);
ESP_LOGD(TAG, "################ before enabling APLL ############");
rtc_clk_apll_enable(1, 0, 0, 6, 2); // 50 MHz
ESP_LOGD(TAG, "################ APLL has a stable lock ##########");

Re: APLL / GPIO16_EMAC_CLK_OUT - wrong frequency - unable to generate 50MHz clk with rev0 chip

Posted: Thu Nov 30, 2017 7:19 am
by hwmaier
No bug. Just the order of initialization is wrong in above code. Refer to https://esp32.com/viewtopic.php?f=2&t=3308