mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
Merge branch 'bugfix/apll_coeff_calculate' into 'master'
i2s: impove the clock division calculation Closes IDFGH-6283 See merge request espressif/esp-idf!16095
This commit is contained in:
commit
952b4d848f
@ -29,8 +29,7 @@
|
||||
#include "esp_private/gdma.h"
|
||||
#endif
|
||||
|
||||
#include "soc/rtc.h"
|
||||
|
||||
#include "soc/clk_ctrl_os.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
@ -916,124 +915,6 @@ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num)
|
||||
/*-------------------------------------------------------------
|
||||
I2S clock operation
|
||||
-------------------------------------------------------------*/
|
||||
#if SOC_I2S_SUPPORTS_APLL
|
||||
/**
|
||||
* @brief Get APLL frequency
|
||||
*/
|
||||
static float i2s_apll_get_freq(int bits_per_sample, int sdm0, int sdm1, int sdm2, int odir)
|
||||
{
|
||||
int f_xtal = (int)rtc_clk_xtal_freq_get() * 1000000;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
/* ESP32 rev0 silicon issue for APLL range/accuracy, please see ESP32 ECO document for more information on this */
|
||||
if (esp_efuse_get_chip_ver() == 0) {
|
||||
sdm0 = 0;
|
||||
sdm1 = 0;
|
||||
}
|
||||
#endif
|
||||
float fout = f_xtal * (sdm2 + sdm1 / 256.0f + sdm0 / 65536.0f + 4);
|
||||
if (fout < SOC_I2S_APLL_MIN_FREQ || fout > SOC_I2S_APLL_MAX_FREQ) {
|
||||
return SOC_I2S_APLL_MAX_FREQ;
|
||||
}
|
||||
float fpll = fout / (2 * (odir + 2)); //== fi2s (N=1, b=0, a=1)
|
||||
return fpll / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief APLL calculate function, was described by following:
|
||||
* APLL Output frequency is given by the formula:
|
||||
*
|
||||
* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2)
|
||||
* apll_freq = fout / ((o_div + 2) * 2)
|
||||
*
|
||||
* The dividend in this expression should be in the range of 240 - 600 MHz.
|
||||
* In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
|
||||
* * sdm0 frequency adjustment parameter, 0..255
|
||||
* * sdm1 frequency adjustment parameter, 0..255
|
||||
* * sdm2 frequency adjustment parameter, 0..63
|
||||
* * o_div frequency divider, 0..31
|
||||
*
|
||||
* The most accurate way to find the sdm0..2 and odir parameters is to loop through them all,
|
||||
* then apply the above formula, finding the closest frequency to the desired one.
|
||||
* But 256*256*64*32 = 134,217,728 loops are too slow with ESP32
|
||||
* 1. We will choose the parameters with the highest level of change,
|
||||
* With 350MHz<fout<500MHz, we limit the sdm2 from 4 to 9,
|
||||
* Take average frequency close to the desired frequency, and select sdm2
|
||||
* 2. Next, we look for sequences of less influential and more detailed parameters,
|
||||
* also by taking the average of the largest and smallest frequencies closer to the desired frequency.
|
||||
* 3. And finally, loop through all the most detailed of the parameters, finding the best desired frequency
|
||||
*
|
||||
* @param[in] rate The I2S Frequency (MCLK)
|
||||
* @param[in] bits_per_sample The bits per sample
|
||||
* @param[out] sdm0 The sdm 0
|
||||
* @param[out] sdm1 The sdm 1
|
||||
* @param[out] sdm2 The sdm 2
|
||||
* @param[out] odir The odir
|
||||
*/
|
||||
static void i2s_apll_calculate_fi2s(int rate, int bits_per_sample, int *sdm0, int *sdm1, int *sdm2, int *odir)
|
||||
{
|
||||
int _odir, _sdm0, _sdm1, _sdm2;
|
||||
float avg;
|
||||
float min_rate, max_rate, min_diff;
|
||||
|
||||
*sdm0 = 0;
|
||||
*sdm1 = 0;
|
||||
*sdm2 = 0;
|
||||
*odir = 0;
|
||||
min_diff = SOC_I2S_APLL_MAX_FREQ;
|
||||
|
||||
for (_sdm2 = 4; _sdm2 < 9; _sdm2 ++) {
|
||||
max_rate = i2s_apll_get_freq(bits_per_sample, 255, 255, _sdm2, 0);
|
||||
min_rate = i2s_apll_get_freq(bits_per_sample, 0, 0, _sdm2, 31);
|
||||
avg = (max_rate + min_rate) / 2;
|
||||
if (abs(avg - rate) < min_diff) {
|
||||
min_diff = abs(avg - rate);
|
||||
*sdm2 = _sdm2;
|
||||
}
|
||||
}
|
||||
min_diff = SOC_I2S_APLL_MAX_FREQ;
|
||||
for (_odir = 0; _odir < 32; _odir ++) {
|
||||
max_rate = i2s_apll_get_freq(bits_per_sample, 255, 255, *sdm2, _odir);
|
||||
min_rate = i2s_apll_get_freq(bits_per_sample, 0, 0, *sdm2, _odir);
|
||||
avg = (max_rate + min_rate) / 2;
|
||||
if (abs(avg - rate) < min_diff) {
|
||||
min_diff = abs(avg - rate);
|
||||
*odir = _odir;
|
||||
}
|
||||
}
|
||||
min_diff = SOC_I2S_APLL_MAX_FREQ;
|
||||
for (_sdm2 = 4; _sdm2 < 9; _sdm2 ++) {
|
||||
max_rate = i2s_apll_get_freq(bits_per_sample, 255, 255, _sdm2, *odir);
|
||||
min_rate = i2s_apll_get_freq(bits_per_sample, 0, 0, _sdm2, *odir);
|
||||
avg = (max_rate + min_rate) / 2;
|
||||
if (abs(avg - rate) < min_diff) {
|
||||
min_diff = abs(avg - rate);
|
||||
*sdm2 = _sdm2;
|
||||
}
|
||||
}
|
||||
|
||||
min_diff = SOC_I2S_APLL_MAX_FREQ;
|
||||
for (_sdm1 = 0; _sdm1 < 256; _sdm1 ++) {
|
||||
max_rate = i2s_apll_get_freq(bits_per_sample, 255, _sdm1, *sdm2, *odir);
|
||||
min_rate = i2s_apll_get_freq(bits_per_sample, 0, _sdm1, *sdm2, *odir);
|
||||
avg = (max_rate + min_rate) / 2;
|
||||
if (abs(avg - rate) < min_diff) {
|
||||
min_diff = abs(avg - rate);
|
||||
*sdm1 = _sdm1;
|
||||
}
|
||||
}
|
||||
|
||||
min_diff = SOC_I2S_APLL_MAX_FREQ;
|
||||
for (_sdm0 = 0; _sdm0 < 256; _sdm0 ++) {
|
||||
avg = i2s_apll_get_freq(bits_per_sample, _sdm0, *sdm1, *sdm2, *odir);
|
||||
if (abs(avg - rate) < min_diff) {
|
||||
min_diff = abs(avg - rate);
|
||||
*sdm0 = _sdm0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Config I2S source clock and get its frequency
|
||||
*
|
||||
@ -1049,21 +930,29 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3
|
||||
{
|
||||
#if SOC_I2S_SUPPORTS_APLL
|
||||
if (use_apll) {
|
||||
int sdm0 = 0;
|
||||
int sdm1 = 0;
|
||||
int sdm2 = 0;
|
||||
int odir = 0;
|
||||
if ((mclk / p_i2s[i2s_num]->hal_cfg.chan_bits / p_i2s[i2s_num]->hal_cfg.total_chan) < SOC_I2S_APLL_MIN_RATE) {
|
||||
ESP_LOGE(TAG, "mclk is too small");
|
||||
/* Calculate the expected APLL */
|
||||
int div = (int)((SOC_APLL_MIN_HZ / mclk) + 1);
|
||||
/* apll_freq = mclk * div
|
||||
* when div = 1, hardware will still divide 2
|
||||
* when div = 0, the final mclk will be unpredictable
|
||||
* So the div here should be at least 2 */
|
||||
div = div < 2 ? 2 : div;
|
||||
uint32_t expt_freq = mclk * div;
|
||||
/* Set APLL coefficients to the given frequency */
|
||||
uint32_t real_freq = 0;
|
||||
esp_err_t ret = periph_rtc_apll_freq_set(expt_freq, &real_freq);
|
||||
if (ret == ESP_ERR_INVALID_ARG) {
|
||||
ESP_LOGE(TAG, "set APLL coefficients failed");
|
||||
return 0;
|
||||
}
|
||||
i2s_apll_calculate_fi2s(mclk, p_i2s[i2s_num]->hal_cfg.sample_bits, &sdm0, &sdm1, &sdm2, &odir);
|
||||
ESP_LOGI(TAG, "APLL Enabled, coefficient: sdm0=%d, sdm1=%d, sdm2=%d, odir=%d", sdm0, sdm1, sdm2, odir);
|
||||
rtc_clk_apll_enable(true, sdm0, sdm1, sdm2, odir);
|
||||
if (ret == ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGW(TAG, "APLL is occupied already, it is working at %d Hz", real_freq);
|
||||
}
|
||||
ESP_LOGI(TAG, "APLL expected frequency is %d Hz, real frequency is %d Hz", expt_freq, real_freq);
|
||||
/* Set I2S_APLL as I2S module clock source */
|
||||
i2s_hal_set_clock_src(&(p_i2s[i2s_num]->hal), I2S_CLK_APLL);
|
||||
/* In APLL mode, there is no sclk but only mclk, so return 0 here to indicate APLL mode */
|
||||
return 0;
|
||||
return real_freq;
|
||||
}
|
||||
/* Set I2S_D2CLK (160M) as default I2S module clock source */
|
||||
i2s_hal_set_clock_src(&(p_i2s[i2s_num]->hal), I2S_CLK_D2CLK);
|
||||
@ -1108,7 +997,7 @@ static esp_err_t i2s_calculate_adc_dac_clock(int i2s_num, i2s_hal_clock_cfg_t *c
|
||||
clk_cfg->mclk_div = clk_cfg->sclk / clk_cfg->mclk;
|
||||
|
||||
/* Check if the configuration is correct */
|
||||
ESP_RETURN_ON_FALSE(!clk_cfg->sclk || clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
ESP_RETURN_ON_FALSE(clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -1146,7 +1035,7 @@ static esp_err_t i2s_calculate_pdm_tx_clock(int i2s_num, i2s_hal_clock_cfg_t *cl
|
||||
clk_cfg->mclk_div = clk_cfg->sclk / clk_cfg->mclk;
|
||||
|
||||
/* Check if the configuration is correct */
|
||||
ESP_RETURN_ON_FALSE(!clk_cfg->sclk || clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
ESP_RETURN_ON_FALSE(clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -1184,7 +1073,7 @@ static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_hal_clock_cfg_t *cl
|
||||
clk_cfg->mclk_div = clk_cfg->sclk / clk_cfg->mclk;
|
||||
|
||||
/* Check if the configuration is correct */
|
||||
ESP_RETURN_ON_FALSE(!clk_cfg->sclk || clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
ESP_RETURN_ON_FALSE(clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -1240,7 +1129,7 @@ static esp_err_t i2s_calculate_common_clock(int i2s_num, i2s_hal_clock_cfg_t *cl
|
||||
clk_cfg->mclk_div = clk_cfg->sclk / clk_cfg->mclk;
|
||||
|
||||
/* Check if the configuration is correct */
|
||||
ESP_RETURN_ON_FALSE(!clk_cfg->sclk || clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
ESP_RETURN_ON_FALSE(clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -2003,6 +1892,13 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
|
||||
pre_alloc_i2s_obj->i2s_queue = NULL;
|
||||
}
|
||||
|
||||
#if SOC_I2S_SUPPORTS_APLL
|
||||
/* Power up APLL clock */
|
||||
if (i2s_config->use_apll) {
|
||||
periph_rtc_apll_acquire();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Step 7: Set I2S clocks and start. No need to give parameters since configurations has been set in 'i2s_driver_init' */
|
||||
ESP_GOTO_ON_ERROR(i2s_set_clk(i2s_num, 0, 0, 0), err, TAG, "I2S set clock failed");
|
||||
return ESP_OK;
|
||||
@ -2057,7 +1953,7 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
|
||||
if (p_i2s[i2s_num]->use_apll) {
|
||||
// switch back to PLL clock source
|
||||
i2s_hal_set_clock_src(&(p_i2s[i2s_num]->hal), I2S_CLK_D2CLK);
|
||||
rtc_clk_apll_enable(0, 0, 0, 0, 0);
|
||||
periph_rtc_apll_release();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "hal/emac_hal.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/clk_ctrl_os.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_sys.h"
|
||||
@ -56,6 +56,7 @@ typedef struct {
|
||||
bool isr_need_yield;
|
||||
bool flow_ctrl_enabled; // indicates whether the user want to do flow control
|
||||
bool do_flow_ctrl; // indicates whether we need to do software flow control
|
||||
bool use_apll; // Only use APLL in EMAC_DATA_INTERFACE_RMII && EMAC_CLK_OUT
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_handle_t pm_lock;
|
||||
#endif
|
||||
@ -299,30 +300,20 @@ static void emac_esp32_init_smi_gpio(emac_esp32_t *emac)
|
||||
}
|
||||
}
|
||||
|
||||
static void emac_config_apll_clock(void)
|
||||
static esp_err_t emac_config_apll_clock(void)
|
||||
{
|
||||
/* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2) */
|
||||
rtc_xtal_freq_t rtc_xtal_freq = rtc_clk_xtal_freq_get();
|
||||
switch (rtc_xtal_freq) {
|
||||
case RTC_XTAL_FREQ_40M: // Recommended
|
||||
/* 50 MHz = 40MHz * (4 + 6) / (2 * (2 + 2) = 50.000 */
|
||||
/* sdm0 = 0, sdm1 = 0, sdm2 = 6, o_div = 2 */
|
||||
rtc_clk_apll_enable(true, 0, 0, 6, 2);
|
||||
break;
|
||||
case RTC_XTAL_FREQ_26M:
|
||||
/* 50 MHz = 26MHz * (4 + 15 + 118 / 256 + 39/65536) / ((3 + 2) * 2) = 49.999992 */
|
||||
/* sdm0 = 39, sdm1 = 118, sdm2 = 15, o_div = 3 */
|
||||
rtc_clk_apll_enable(true, 39, 118, 15, 3);
|
||||
break;
|
||||
case RTC_XTAL_FREQ_24M:
|
||||
/* 50 MHz = 24MHz * (4 + 12 + 255 / 256 + 255/65536) / ((2 + 2) * 2) = 49.499977 */
|
||||
/* sdm0 = 255, sdm1 = 255, sdm2 = 12, o_div = 2 */
|
||||
rtc_clk_apll_enable(true, 255, 255, 12, 2);
|
||||
break;
|
||||
default: // Assume we have a 40M xtal
|
||||
rtc_clk_apll_enable(true, 0, 0, 6, 2);
|
||||
break;
|
||||
uint32_t expt_freq = 50000000; // 50MHz
|
||||
uint32_t real_freq = 0;
|
||||
esp_err_t ret = periph_rtc_apll_freq_set(expt_freq, &real_freq);
|
||||
ESP_RETURN_ON_FALSE(ret != ESP_ERR_INVALID_ARG, ESP_FAIL, TAG, "Set APLL clock coefficients failed");
|
||||
if (ret == ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGW(TAG, "APLL is occupied already, it is working at %d Hz", real_freq);
|
||||
}
|
||||
// If the difference of real APLL frequency is not within 50 ppm, i.e. 2500 Hz, the APLL is unavailable
|
||||
ESP_RETURN_ON_FALSE(abs(real_freq - expt_freq) <= 2500,
|
||||
ESP_ERR_INVALID_STATE, TAG, "The APLL is working at an unusable frequency");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t emac_esp32_init(esp_eth_mac_t *mac)
|
||||
@ -429,6 +420,9 @@ static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors)
|
||||
if (emac->intr_hdl) {
|
||||
esp_intr_free(emac->intr_hdl);
|
||||
}
|
||||
if (emac->use_apll) {
|
||||
periph_rtc_apll_release();
|
||||
}
|
||||
for (int i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
|
||||
free(emac->tx_buf[i]);
|
||||
}
|
||||
@ -546,7 +540,10 @@ static esp_err_t esp_emac_config_data_interface(const eth_mac_config_t *config,
|
||||
}
|
||||
/* Enable RMII clock */
|
||||
emac_ll_clock_enable_rmii_output(emac->hal.ext_regs);
|
||||
emac_config_apll_clock();
|
||||
// Power up APLL clock
|
||||
periph_rtc_apll_acquire();
|
||||
ESP_GOTO_ON_ERROR(emac_config_apll_clock(), err, TAG, "Configure APLL for RMII failed");
|
||||
emac->use_apll = true;
|
||||
} else {
|
||||
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC clock mode");
|
||||
}
|
||||
@ -589,6 +586,7 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
|
||||
emac->smi_mdio_gpio_num = config->smi_mdio_gpio_num;
|
||||
emac->flow_control_high_water_mark = FLOW_CONTROL_HIGH_WATER_MARK;
|
||||
emac->flow_control_low_water_mark = FLOW_CONTROL_LOW_WATER_MARK;
|
||||
emac->use_apll = false;
|
||||
emac->parent.set_mediator = emac_esp32_set_mediator;
|
||||
emac->parent.init = emac_esp32_init;
|
||||
emac->parent.deinit = emac_esp32_deinit;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include "soc/clk_ctrl_os.h"
|
||||
#include "esp_check.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define DELAY_RTC_CLK_SWITCH 5
|
||||
@ -14,6 +15,13 @@ static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static uint8_t s_periph_ref_counts = 0;
|
||||
static uint32_t s_rtc_clk_freq = 0; // Frequency of the 8M/256 clock in Hz
|
||||
#if SOC_CLK_APLL_SUPPORTED
|
||||
static const char *TAG = "clk_ctrl_os";
|
||||
// Current APLL frequency, in HZ. Zero if APLL is not enabled.
|
||||
static uint32_t s_cur_apll_freq = 0;
|
||||
static int s_apll_ref_cnt = 0;
|
||||
#endif
|
||||
|
||||
|
||||
bool periph_rtc_dig_clk8m_enable(void)
|
||||
{
|
||||
@ -51,3 +59,65 @@ void periph_rtc_dig_clk8m_disable(void)
|
||||
}
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
}
|
||||
|
||||
#if SOC_CLK_APLL_SUPPORTED
|
||||
void periph_rtc_apll_acquire(void)
|
||||
{
|
||||
portENTER_CRITICAL(&periph_spinlock);
|
||||
s_apll_ref_cnt++;
|
||||
if (s_apll_ref_cnt == 1) {
|
||||
// For the first time enable APLL, need to set power up
|
||||
rtc_clk_apll_enable(true);
|
||||
}
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
}
|
||||
|
||||
void periph_rtc_apll_release(void)
|
||||
{
|
||||
portENTER_CRITICAL(&periph_spinlock);
|
||||
assert(s_apll_ref_cnt > 0);
|
||||
s_apll_ref_cnt--;
|
||||
if (s_apll_ref_cnt == 0) {
|
||||
// If there is no peripheral using APLL, shut down the power
|
||||
s_cur_apll_freq = 0;
|
||||
rtc_clk_apll_enable(false);
|
||||
}
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
}
|
||||
|
||||
esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq)
|
||||
{
|
||||
uint32_t o_div = 0;
|
||||
uint32_t sdm0 = 0;
|
||||
uint32_t sdm1 = 0;
|
||||
uint32_t sdm2 = 0;
|
||||
// Guarantee 'periph_rtc_apll_acquire' has been called before set apll freq
|
||||
assert(s_apll_ref_cnt > 0);
|
||||
uint32_t apll_freq = rtc_clk_apll_coeff_calc(expt_freq, &o_div, &sdm0, &sdm1, &sdm2);
|
||||
|
||||
ESP_RETURN_ON_FALSE(apll_freq, ESP_ERR_INVALID_ARG, TAG, "APLL coefficients calculate failed");
|
||||
bool need_config = true;
|
||||
portENTER_CRITICAL(&periph_spinlock);
|
||||
/* If APLL is not in use or only one peripheral in use, its frequency can be changed as will
|
||||
* But when more than one peripheral refers APLL, its frequency is not allowed to change once it is set */
|
||||
if (s_cur_apll_freq == 0 || s_apll_ref_cnt < 2) {
|
||||
s_cur_apll_freq = apll_freq;
|
||||
} else {
|
||||
apll_freq = s_cur_apll_freq;
|
||||
need_config = false;
|
||||
}
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
*real_freq = apll_freq;
|
||||
|
||||
if (need_config) {
|
||||
ESP_LOGD(TAG, "APLL will working at %d Hz with coefficients [sdm0] %d [sdm1] %d [sdm2] %d [o_div] %d",
|
||||
apll_freq, sdm0, sdm1, sdm2, o_div);
|
||||
/* Set coefficients for APLL, notice that it doesn't mean APLL will start */
|
||||
rtc_clk_apll_coeff_set(o_div, sdm0, sdm1, sdm2);
|
||||
} else {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // SOC_I2S_SUPPORTS_APLL
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -37,6 +38,39 @@ void periph_rtc_dig_clk8m_disable(void);
|
||||
*/
|
||||
uint32_t periph_rtc_dig_clk8m_get_freq(void);
|
||||
|
||||
#if SOC_CLK_APLL_SUPPORTED
|
||||
/**
|
||||
* @brief Enable APLL power if it has not enabled
|
||||
*/
|
||||
void periph_rtc_apll_acquire(void);
|
||||
|
||||
/**
|
||||
* @brief Shut down APLL power if no peripherals using APLL
|
||||
*/
|
||||
void periph_rtc_apll_release(void);
|
||||
|
||||
/**
|
||||
* @brief Calculate and set APLL coefficients by given frequency
|
||||
* @note Have to call 'periph_rtc_apll_acquire' to enable APLL power before setting frequency
|
||||
* @note This calculation is based on the inequality:
|
||||
* xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= SOC_APLL_MULTIPLIER_OUT_MIN_HZ(350 MHz)
|
||||
* It will always calculate the minimum coefficients that can satisfy the inequality above, instead of loop them one by one.
|
||||
* which means more appropriate coefficients are likely to exist.
|
||||
* But this algorithm can meet almost all the cases and the accuracy can be guaranteed as well.
|
||||
* @note The APLL frequency is only allowed to set when there is only one peripheral refer to it.
|
||||
* If APLL is already set by another peripheral, this function will return `ESP_ERR_INVALID_STATE`
|
||||
* and output the current frequency by parameter `real_freq`.
|
||||
*
|
||||
* @param expt_freq Expected APLL frequency (unit: Hz)
|
||||
* @param real_freq APLL real working frequency [output] (unit: Hz)
|
||||
* @return
|
||||
* - ESP_OK: APLL frequency set success
|
||||
* - ESP_ERR_INVALID_ARG: The input expt_freq is out of APLL support range
|
||||
* - ESP_ERR_INVALID_STATE: APLL is refered by more than one peripherals, not allowed to change its frequency now
|
||||
*/
|
||||
esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq);
|
||||
#endif // SOC_CLK_APLL_SUPPORTED
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* This file lists register fields of APLL, located on an internal configuration
|
||||
* bus. These definitions are used via macros defined in regi2c_ctrl.h, by
|
||||
* rtc_clk_apll_enable function in rtc_clk.c.
|
||||
* rtc_clk_apll_freq_set and rtc_clk_apll_enable function in rtc_clk.c.
|
||||
*/
|
||||
|
||||
#define I2C_APLL 0X6D
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/sens_periph.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
@ -268,7 +269,7 @@ bool rtc_clk_8md256_enabled(void)
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
||||
}
|
||||
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div)
|
||||
void rtc_clk_apll_enable(bool enable)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1);
|
||||
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0);
|
||||
@ -279,32 +280,92 @@ void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FORCE_PD);
|
||||
}
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
uint8_t sdm_stop_val_2 = APLL_SDM_STOP_VAL_2_REV1;
|
||||
uint32_t is_rev0 = (GET_PERI_REG_BITS2(EFUSE_BLK0_RDATA3_REG, 1, 15) == 0);
|
||||
if (is_rev0) {
|
||||
sdm0 = 0;
|
||||
sdm1 = 0;
|
||||
sdm_stop_val_2 = APLL_SDM_STOP_VAL_2_REV0;
|
||||
uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm0, uint32_t *_sdm1, uint32_t *_sdm2)
|
||||
{
|
||||
uint32_t rtc_xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
if (rtc_xtal_freq == 0) {
|
||||
// xtal_freq has not set yet
|
||||
SOC_LOGE(TAG, "Get xtal clock frequency failed, it has not been set yet");
|
||||
abort();
|
||||
}
|
||||
/* Reference formula: apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) / ((o_div + 2) * 2)
|
||||
* ---------------------------------------------- -----------------
|
||||
* 350 MHz <= Numerator <= 500 MHz Denominator
|
||||
*/
|
||||
int o_div = 0; // range: 0~31
|
||||
int sdm0 = 0; // range: 0~255
|
||||
int sdm1 = 0; // range: 0~255
|
||||
int sdm2 = 0; // range: 0~63
|
||||
/* Firstly try to satisfy the condition that the operation frequency of numerator should be greater than 350 MHz,
|
||||
* i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz, '+1' in the following code is to get the ceil value.
|
||||
* With this condition, as we know the 'o_div' can't be greater than 31, then we can calculate the APLL minimum support frequency is
|
||||
* 350 MHz / ((31 + 2) * 2) = 5303031 Hz (for ceil) */
|
||||
o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MIN_HZ / (float)(freq * 2) + 1) - 2;
|
||||
if (o_div > 31) {
|
||||
SOC_LOGE(TAG, "Expected frequency is too small");
|
||||
return 0;
|
||||
}
|
||||
if (o_div < 0) {
|
||||
/* Try to satisfy the condition that the operation frequency of numerator should be smaller than 500 MHz,
|
||||
* i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz, we need to get the floor value in the following code.
|
||||
* With this condition, as we know the 'o_div' can't be smaller than 0, then we can calculate the APLL maximum support frequency is
|
||||
* 500 MHz / ((0 + 2) * 2) = 125000000 Hz */
|
||||
o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MAX_HZ / (float)(freq * 2)) - 2;
|
||||
if (o_div < 0) {
|
||||
SOC_LOGE(TAG, "Expected frequency is too big");
|
||||
return 0;
|
||||
}
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, sdm_stop_val_2);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
|
||||
}
|
||||
// sdm2 = (int)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4
|
||||
sdm2 = (int)(((o_div + 2) * 2 * freq) / (rtc_xtal_freq * 1000000)) - 4;
|
||||
// numrator = (((o_div + 2) * 2) * apll_freq / xtal_freq) - 4 - sdm2
|
||||
float numrator = (((o_div + 2) * 2 * freq) / ((float)rtc_xtal_freq * 1000000)) - 4 - sdm2;
|
||||
// If numrator is bigger than 255/256 + 255/65536 + (1/65536)/2 = 1 - (1 / 65536)/2, carry bit to sdm2
|
||||
if (numrator > 1.0 - (1.0 / 65536.0) / 2.0) {
|
||||
sdm2++;
|
||||
}
|
||||
// If numrator is smaller than (1/65536)/2, keep sdm0 = sdm1 = 0, otherwise calculate sdm0 and sdm1
|
||||
else if (numrator > (1.0 / 65536.0) / 2.0) {
|
||||
// Get the closest sdm1
|
||||
sdm1 = (int)(numrator * 65536.0 + 0.5) / 256;
|
||||
// Get the closest sdm0
|
||||
sdm0 = (int)(numrator * 65536.0 + 0.5) % 256;
|
||||
}
|
||||
uint32_t real_freq = (uint32_t)(rtc_xtal_freq * 1000000 * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) / (((float)o_div + 2) * 2));
|
||||
*_o_div = o_div;
|
||||
*_sdm0 = sdm0;
|
||||
*_sdm1 = sdm1;
|
||||
*_sdm2 = sdm2;
|
||||
return real_freq;
|
||||
}
|
||||
|
||||
/* calibration */
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_2);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_3);
|
||||
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
|
||||
{
|
||||
uint8_t sdm_stop_val_2 = APLL_SDM_STOP_VAL_2_REV1;
|
||||
uint32_t is_rev0 = (GET_PERI_REG_BITS2(EFUSE_BLK0_RDATA3_REG, 1, 15) == 0);
|
||||
if (is_rev0) {
|
||||
sdm0 = 0;
|
||||
sdm1 = 0;
|
||||
sdm_stop_val_2 = APLL_SDM_STOP_VAL_2_REV0;
|
||||
}
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, sdm_stop_val_2);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
|
||||
|
||||
/* wait for calibration end */
|
||||
while (!(REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_CAL_END))) {
|
||||
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
|
||||
esp_rom_delay_us(1);
|
||||
}
|
||||
/* calibration */
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_2);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_3);
|
||||
|
||||
/* wait for calibration end */
|
||||
while (!(REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_CAL_END))) {
|
||||
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
|
||||
esp_rom_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* This file lists register fields of APLL, located on an internal configuration
|
||||
* bus. These definitions are used via macros defined in regi2c_ctrl.h, by
|
||||
* rtc_clk_apll_enable function in rtc_clk.c.
|
||||
* rtc_clk_apll_freq_set and rtc_clk_apll_enable function in rtc_clk.c.
|
||||
*/
|
||||
|
||||
#define I2C_APLL 0X6D
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
@ -119,30 +120,90 @@ bool rtc_clk_8md256_enabled(void)
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
|
||||
}
|
||||
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div)
|
||||
void rtc_clk_apll_enable(bool enable)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1);
|
||||
REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_2_REV1);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
|
||||
|
||||
/* calibration */
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_2);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_3);
|
||||
|
||||
/* wait for calibration end */
|
||||
while (!(REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_CAL_END))) {
|
||||
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
|
||||
esp_rom_delay_us(1);
|
||||
uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm0, uint32_t *_sdm1, uint32_t *_sdm2)
|
||||
{
|
||||
uint32_t rtc_xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
if (rtc_xtal_freq == 0) {
|
||||
// xtal_freq has not set yet
|
||||
SOC_LOGE(TAG, "Get xtal clock frequency failed, it has not been set yet");
|
||||
abort();
|
||||
}
|
||||
/* Reference formula: apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) / ((o_div + 2) * 2)
|
||||
* ---------------------------------------------- -----------------
|
||||
* 350 MHz <= Numerator <= 500 MHz Denominator
|
||||
*/
|
||||
int o_div = 0; // range: 0~31
|
||||
int sdm0 = 0; // range: 0~255
|
||||
int sdm1 = 0; // range: 0~255
|
||||
int sdm2 = 0; // range: 0~63
|
||||
/* Firstly try to satisfy the condition that the operation frequency of numerator should be greater than 350 MHz,
|
||||
* i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz, '+1' in the following code is to get the ceil value.
|
||||
* With this condition, as we know the 'o_div' can't be greater than 31, then we can calculate the APLL minimum support frequency is
|
||||
* 350 MHz / ((31 + 2) * 2) = 5303031 Hz (for ceil) */
|
||||
o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MIN_HZ / (float)(freq * 2) + 1) - 2;
|
||||
if (o_div > 31) {
|
||||
SOC_LOGE(TAG, "Expected frequency is too small");
|
||||
return 0;
|
||||
}
|
||||
if (o_div < 0) {
|
||||
/* Try to satisfy the condition that the operation frequency of numerator should be smaller than 500 MHz,
|
||||
* i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz, we need to get the floor value in the following code.
|
||||
* With this condition, as we know the 'o_div' can't be smaller than 0, then we can calculate the APLL maximum support frequency is
|
||||
* 500 MHz / ((0 + 2) * 2) = 125000000 Hz */
|
||||
o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MAX_HZ / (float)(freq * 2)) - 2;
|
||||
if (o_div < 0) {
|
||||
SOC_LOGE(TAG, "Expected frequency is too big");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// sdm2 = (int)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4
|
||||
sdm2 = (int)(((o_div + 2) * 2 * freq) / (rtc_xtal_freq * 1000000)) - 4;
|
||||
// numrator = (((o_div + 2) * 2) * apll_freq / xtal_freq) - 4 - sdm2
|
||||
float numrator = (((o_div + 2) * 2 * freq) / ((float)rtc_xtal_freq * 1000000)) - 4 - sdm2;
|
||||
// If numrator is bigger than 255/256 + 255/65536 + (1/65536)/2 = 1 - (1 / 65536)/2, carry bit to sdm2
|
||||
if (numrator > 1.0 - (1.0 / 65536.0) / 2.0) {
|
||||
sdm2++;
|
||||
}
|
||||
// If numrator is smaller than (1/65536)/2, keep sdm0 = sdm1 = 0, otherwise calculate sdm0 and sdm1
|
||||
else if (numrator > (1.0 / 65536.0) / 2.0) {
|
||||
// Get the closest sdm1
|
||||
sdm1 = (int)(numrator * 65536.0 + 0.5) / 256;
|
||||
// Get the closest sdm0
|
||||
sdm0 = (int)(numrator * 65536.0 + 0.5) % 256;
|
||||
}
|
||||
uint32_t real_freq = (uint32_t)(rtc_xtal_freq * 1000000 * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) / (((float)o_div + 2) * 2));
|
||||
*_o_div = o_div;
|
||||
*_sdm0 = sdm0;
|
||||
*_sdm1 = sdm1;
|
||||
*_sdm2 = sdm2;
|
||||
return real_freq;
|
||||
}
|
||||
|
||||
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
|
||||
{
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_2_REV1);
|
||||
REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
|
||||
|
||||
/* calibration */
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_1);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_2);
|
||||
REGI2C_WRITE(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_3);
|
||||
|
||||
/* wait for calibration end */
|
||||
while (!(REGI2C_READ_MASK(I2C_APLL, I2C_APLL_OR_CAL_END))) {
|
||||
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
|
||||
esp_rom_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
|
||||
|
@ -26,27 +26,32 @@ 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 = abs(clk_cfg->sclk - clk_cfg->mclk * cal->mclk_div);
|
||||
if (!freq_diff) {
|
||||
return;
|
||||
}
|
||||
float decimal = freq_diff / (float)clk_cfg->mclk;
|
||||
// Carry bit if the decimal is greater than 1.0 - 1.0 / (63.0 * 2) = 125.0 / 126.0
|
||||
if (decimal > 125.0 / 126.0) {
|
||||
cal->mclk_div++;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -191,10 +191,34 @@ config SOC_I2C_SUPPORT_APB
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_APLL_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_APLL_MULTIPLIER_OUT_MIN_HZ
|
||||
int
|
||||
default 350000000
|
||||
|
||||
config SOC_APLL_MULTIPLIER_OUT_MAX_HZ
|
||||
int
|
||||
default 500000000
|
||||
|
||||
config SOC_APLL_MIN_HZ
|
||||
int
|
||||
default 5303031
|
||||
|
||||
config SOC_APLL_MAX_HZ
|
||||
int
|
||||
default 125000000
|
||||
|
||||
config SOC_I2S_NUM
|
||||
int
|
||||
default 2
|
||||
|
||||
config SOC_I2S_SUPPORTS_APLL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_PDM_TX
|
||||
bool
|
||||
default y
|
||||
@ -211,22 +235,6 @@ config SOC_I2S_SUPPORTS_DAC
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORTS_APLL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_APLL_MIN_FREQ
|
||||
int
|
||||
default 250000000
|
||||
|
||||
config SOC_I2S_APLL_MAX_FREQ
|
||||
int
|
||||
default 500000000
|
||||
|
||||
config SOC_I2S_APLL_MIN_RATE
|
||||
int
|
||||
default 10675
|
||||
|
||||
config SOC_I2S_TRANS_SIZE_ALIGN_WORD
|
||||
bool
|
||||
default y
|
||||
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
@ -54,7 +46,6 @@ extern "C" {
|
||||
* - rtc_init: initialization
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Possible main XTAL frequency values.
|
||||
*
|
||||
@ -260,13 +251,33 @@ bool rtc_clk_8md256_enabled(void);
|
||||
* In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
|
||||
*
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Calculate APLL clock coeffifcients
|
||||
*
|
||||
* @param freq expected APLL frequency
|
||||
* @param o_div frequency divider, 0..31
|
||||
* @param sdm0 frequency adjustment parameter, 0..255
|
||||
* @param sdm1 frequency adjustment parameter, 0..255
|
||||
* @param sdm2 frequency adjustment parameter, 0..63
|
||||
* @param o_div frequency divider, 0..31
|
||||
*
|
||||
* @return
|
||||
* - 0 Failed
|
||||
* - else Sucess
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1,
|
||||
uint32_t sdm2, uint32_t o_div);
|
||||
uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm0, uint32_t *_sdm1, uint32_t *_sdm2);
|
||||
|
||||
/**
|
||||
* @brief Set APLL clock coeffifcients
|
||||
*
|
||||
* @param o_div frequency divider, 0..31
|
||||
* @param sdm0 frequency adjustment parameter, 0..255
|
||||
* @param sdm1 frequency adjustment parameter, 0..255
|
||||
* @param sdm2 frequency adjustment parameter, 0..63
|
||||
*/
|
||||
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2);
|
||||
|
||||
/**
|
||||
* @brief Select source for RTC_SLOW_CLK
|
||||
|
@ -157,18 +157,23 @@
|
||||
|
||||
#define SOC_I2C_SUPPORT_APB (1)
|
||||
|
||||
/*-------------------------- APLL CAPS ----------------------------------------*/
|
||||
#define SOC_CLK_APLL_SUPPORTED (1)
|
||||
// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)
|
||||
#define SOC_APLL_MULTIPLIER_OUT_MIN_HZ (350000000) // 350 MHz
|
||||
#define SOC_APLL_MULTIPLIER_OUT_MAX_HZ (500000000) // 500 MHz
|
||||
#define SOC_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
|
||||
#define SOC_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
|
||||
|
||||
/*-------------------------- I2S CAPS ----------------------------------------*/
|
||||
// ESP32 have 2 I2S
|
||||
#define SOC_I2S_NUM (2)
|
||||
#define SOC_I2S_NUM (2U)
|
||||
#define SOC_I2S_SUPPORTS_APLL (1) // ESP32 support APLL
|
||||
#define SOC_I2S_SUPPORTS_PDM_TX (1)
|
||||
#define SOC_I2S_SUPPORTS_PDM_RX (1)
|
||||
#define SOC_I2S_SUPPORTS_ADC (1) // ESP32 support ADC and DAC
|
||||
#define SOC_I2S_SUPPORTS_DAC (1)
|
||||
|
||||
#define SOC_I2S_SUPPORTS_APLL (1)// ESP32 support APLL
|
||||
#define SOC_I2S_APLL_MIN_FREQ (250000000)
|
||||
#define SOC_I2S_APLL_MAX_FREQ (500000000)
|
||||
#define SOC_I2S_APLL_MIN_RATE (10675) //in Hz, I2S Clock rate limited by hardware
|
||||
#define SOC_I2S_TRANS_SIZE_ALIGN_WORD (1) // I2S DMA transfer size must be aligned to word
|
||||
#define SOC_I2S_LCD_I80_VARIANT (1) // I2S has a special LCD mode that can generate Intel 8080 TX timing
|
||||
|
||||
|
@ -157,7 +157,6 @@ typedef enum {
|
||||
RTC_CPU_FREQ_SRC_XTAL, //!< XTAL
|
||||
RTC_CPU_FREQ_SRC_PLL, //!< PLL (480M or 320M)
|
||||
RTC_CPU_FREQ_SRC_8M, //!< Internal 8M RTC oscillator
|
||||
RTC_CPU_FREQ_SRC_APLL //!< APLL
|
||||
} rtc_cpu_freq_src_t;
|
||||
|
||||
/**
|
||||
@ -363,24 +362,6 @@ bool rtc_clk_8m_enabled(void);
|
||||
*/
|
||||
bool rtc_clk_8md256_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable APLL
|
||||
*
|
||||
* Output frequency is given by the formula:
|
||||
* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2)
|
||||
*
|
||||
* The dividend in this expression should be in the range of 240 - 600 MHz.
|
||||
*
|
||||
* In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
|
||||
*
|
||||
* @param enable true to enable, false to disable
|
||||
* @param sdm0 frequency adjustment parameter, 0..255
|
||||
* @param sdm1 frequency adjustment parameter, 0..255
|
||||
* @param sdm2 frequency adjustment parameter, 0..63
|
||||
* @param o_div frequency divider, 0..31
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div);
|
||||
|
||||
/**
|
||||
* @brief Select source for RTC_SLOW_CLK
|
||||
* @param slow_freq clock source (one of rtc_slow_freq_t values)
|
||||
|
@ -369,24 +369,6 @@ bool rtc_clk_8m_enabled(void);
|
||||
*/
|
||||
bool rtc_clk_8md256_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable APLL
|
||||
*
|
||||
* Output frequency is given by the formula:
|
||||
* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2)
|
||||
*
|
||||
* The dividend in this expression should be in the range of 240 - 600 MHz.
|
||||
*
|
||||
* In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
|
||||
*
|
||||
* @param enable true to enable, false to disable
|
||||
* @param sdm0 frequency adjustment parameter, 0..255
|
||||
* @param sdm1 frequency adjustment parameter, 0..255
|
||||
* @param sdm2 frequency adjustment parameter, 0..63
|
||||
* @param o_div frequency divider, 0..31
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div);
|
||||
|
||||
/**
|
||||
* @brief Select source for RTC_SLOW_CLK
|
||||
* @param slow_freq clock source (one of rtc_slow_freq_t values)
|
||||
|
@ -279,6 +279,26 @@ config SOC_I2C_SUPPORT_APB
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_APLL_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_APLL_MULTIPLIER_OUT_MIN_HZ
|
||||
int
|
||||
default 350000000
|
||||
|
||||
config SOC_APLL_MULTIPLIER_OUT_MAX_HZ
|
||||
int
|
||||
default 500000000
|
||||
|
||||
config SOC_APLL_MIN_HZ
|
||||
int
|
||||
default 5303031
|
||||
|
||||
config SOC_APLL_MAX_HZ
|
||||
int
|
||||
default 125000000
|
||||
|
||||
config SOC_I2S_NUM
|
||||
int
|
||||
default 1
|
||||
@ -291,18 +311,6 @@ config SOC_I2S_SUPPORTS_DMA_EQUAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_APLL_MIN_FREQ
|
||||
int
|
||||
default 250000000
|
||||
|
||||
config SOC_I2S_APLL_MAX_FREQ
|
||||
int
|
||||
default 500000000
|
||||
|
||||
config SOC_I2S_APLL_MIN_RATE
|
||||
int
|
||||
default 10675
|
||||
|
||||
config SOC_I2S_LCD_I80_VARIANT
|
||||
bool
|
||||
default y
|
||||
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
@ -406,12 +398,33 @@ bool rtc_clk_8md256_enabled(void);
|
||||
* In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
|
||||
*
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Calculate APLL clock coeffifcients
|
||||
*
|
||||
* @param freq expected APLL frequency
|
||||
* @param o_div frequency divider, 0..31
|
||||
* @param sdm0 frequency adjustment parameter, 0..255
|
||||
* @param sdm1 frequency adjustment parameter, 0..255
|
||||
* @param sdm2 frequency adjustment parameter, 0..63
|
||||
* @param o_div frequency divider, 0..31
|
||||
*
|
||||
* @return
|
||||
* - 0 Failed
|
||||
* - else Sucess
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div);
|
||||
uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm0, uint32_t *_sdm1, uint32_t *_sdm2);
|
||||
|
||||
/**
|
||||
* @brief Set APLL clock coeffifcients
|
||||
*
|
||||
* @param o_div frequency divider, 0..31
|
||||
* @param sdm0 frequency adjustment parameter, 0..255
|
||||
* @param sdm1 frequency adjustment parameter, 0..255
|
||||
* @param sdm2 frequency adjustment parameter, 0..63
|
||||
*/
|
||||
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2);
|
||||
|
||||
/**
|
||||
* @brief Select source for RTC_SLOW_CLK
|
||||
|
@ -153,14 +153,19 @@
|
||||
#define SOC_I2C_SUPPORT_REF_TICK (1)
|
||||
#define SOC_I2C_SUPPORT_APB (1)
|
||||
|
||||
/*-------------------------- APLL CAPS ----------------------------------------*/
|
||||
#define SOC_CLK_APLL_SUPPORTED (1)
|
||||
// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)
|
||||
#define SOC_APLL_MULTIPLIER_OUT_MIN_HZ (350000000) // 350 MHz
|
||||
#define SOC_APLL_MULTIPLIER_OUT_MAX_HZ (500000000) // 500 MHz
|
||||
#define SOC_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
|
||||
#define SOC_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
|
||||
|
||||
/*-------------------------- I2S CAPS ----------------------------------------*/
|
||||
// ESP32-S2 have 1 I2S
|
||||
#define SOC_I2S_NUM (1U)
|
||||
#define SOC_I2S_SUPPORTS_APLL (1)// ESP32-S2 support APLL
|
||||
#define SOC_I2S_SUPPORTS_APLL (1) // ESP32-S2 support APLL
|
||||
#define SOC_I2S_SUPPORTS_DMA_EQUAL (1)
|
||||
#define SOC_I2S_APLL_MIN_FREQ (250000000)
|
||||
#define SOC_I2S_APLL_MAX_FREQ (500000000)
|
||||
#define SOC_I2S_APLL_MIN_RATE (10675) //in Hz, I2S Clock rate limited by hardware
|
||||
#define SOC_I2S_LCD_I80_VARIANT (1)
|
||||
|
||||
/*-------------------------- LCD CAPS ----------------------------------------*/
|
||||
|
@ -157,7 +157,6 @@ typedef enum {
|
||||
RTC_CPU_FREQ_SRC_XTAL, //!< XTAL
|
||||
RTC_CPU_FREQ_SRC_PLL, //!< PLL (480M or 320M)
|
||||
RTC_CPU_FREQ_SRC_8M, //!< Internal 8M RTC oscillator
|
||||
RTC_CPU_FREQ_SRC_APLL //!< APLL
|
||||
} rtc_cpu_freq_src_t;
|
||||
|
||||
/**
|
||||
@ -371,24 +370,6 @@ bool rtc_clk_8m_enabled(void);
|
||||
*/
|
||||
bool rtc_clk_8md256_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable APLL
|
||||
*
|
||||
* Output frequency is given by the formula:
|
||||
* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2)
|
||||
*
|
||||
* The dividend in this expression should be in the range of 240 - 600 MHz.
|
||||
*
|
||||
* In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
|
||||
*
|
||||
* @param enable true to enable, false to disable
|
||||
* @param sdm0 frequency adjustment parameter, 0..255
|
||||
* @param sdm1 frequency adjustment parameter, 0..255
|
||||
* @param sdm2 frequency adjustment parameter, 0..63
|
||||
* @param o_div frequency divider, 0..31
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div);
|
||||
|
||||
/**
|
||||
* @brief Select source for RTC_SLOW_CLK
|
||||
* @param slow_freq clock source (one of rtc_slow_freq_t values)
|
||||
|
@ -150,7 +150,6 @@ typedef enum {
|
||||
RTC_CPU_FREQ_SRC_XTAL, //!< XTAL
|
||||
RTC_CPU_FREQ_SRC_PLL, //!< PLL (480M)
|
||||
RTC_CPU_FREQ_SRC_8M, //!< Internal 8M RTC oscillator
|
||||
RTC_CPU_FREQ_SRC_APLL //!< APLL
|
||||
} rtc_cpu_freq_src_t;
|
||||
|
||||
/**
|
||||
@ -349,24 +348,6 @@ bool rtc_clk_8m_enabled(void);
|
||||
*/
|
||||
bool rtc_clk_8md256_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable APLL
|
||||
*
|
||||
* Output frequency is given by the formula:
|
||||
* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2)
|
||||
*
|
||||
* The dividend in this expression should be in the range of 240 - 600 MHz.
|
||||
*
|
||||
* In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
|
||||
*
|
||||
* @param enable true to enable, false to disable
|
||||
* @param sdm0 frequency adjustment parameter, 0..255
|
||||
* @param sdm1 frequency adjustment parameter, 0..255
|
||||
* @param sdm2 frequency adjustment parameter, 0..63
|
||||
* @param o_div frequency divider, 0..31
|
||||
*/
|
||||
void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div);
|
||||
|
||||
/**
|
||||
* @brief Select source for RTC_SLOW_CLK
|
||||
* @param slow_freq clock source (one of rtc_slow_freq_t values)
|
||||
|
@ -1135,7 +1135,6 @@ components/hal/include/hal/esp_flash_err.h
|
||||
components/hal/include/hal/gpio_hal.h
|
||||
components/hal/include/hal/i2c_hal.h
|
||||
components/hal/include/hal/i2c_types.h
|
||||
components/hal/include/hal/i2s_types.h
|
||||
components/hal/include/hal/interrupt_controller_hal.h
|
||||
components/hal/include/hal/interrupt_controller_types.h
|
||||
components/hal/include/hal/ledc_hal.h
|
||||
@ -1632,7 +1631,6 @@ components/soc/esp32/include/soc/pid.h
|
||||
components/soc/esp32/include/soc/reset_reasons.h
|
||||
components/soc/esp32/include/soc/rmt_reg.h
|
||||
components/soc/esp32/include/soc/rmt_struct.h
|
||||
components/soc/esp32/include/soc/rtc.h
|
||||
components/soc/esp32/include/soc/rtc_cntl_reg.h
|
||||
components/soc/esp32/include/soc/rtc_cntl_struct.h
|
||||
components/soc/esp32/include/soc/rtc_i2c_reg.h
|
||||
@ -1855,7 +1853,6 @@ components/soc/esp32s2/include/soc/pcnt_struct.h
|
||||
components/soc/esp32s2/include/soc/reset_reasons.h
|
||||
components/soc/esp32s2/include/soc/rmt_reg.h
|
||||
components/soc/esp32s2/include/soc/rmt_struct.h
|
||||
components/soc/esp32s2/include/soc/rtc.h
|
||||
components/soc/esp32s2/include/soc/rtc_cntl_reg.h
|
||||
components/soc/esp32s2/include/soc/rtc_cntl_struct.h
|
||||
components/soc/esp32s2/include/soc/rtc_i2c_reg.h
|
||||
|
Loading…
x
Reference in New Issue
Block a user