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?
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 ##########");