Просмотр исходного кода

i2s: impove the clock division calculation

Reported from: https://esp32.com/viewtopic.php?f=25&t=24542&p=87595#p87595
laokaiyao 4 лет назад
Родитель
Сommit
af4e448928

+ 12 - 132
components/driver/i2s.c

@@ -916,124 +916,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 +931,19 @@ 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");
+        int div_min = (int)(RTC_APLL_FREQ_MIN / (float)mclk + 1);
+        int div_max = (int)(RTC_APLL_FREQ_MAX / (float)mclk);
+        div_min = div_min < 2 ? 2 : div_min;  // APLL / mclk >= 2
+        if (div_min > div_max) {
+            ESP_LOGE(TAG, "mclk frequency is too big for APLL colck source");
             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);
+        uint32_t expt_freq = div_min * mclk;
+        rtc_clk_apll_freq_set(expt_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 expt_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 +988,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 +1026,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 +1064,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 +1120,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;
 }

+ 47 - 0
components/esp_hw_support/port/esp32/rtc_clk.c

@@ -33,6 +33,10 @@
 #define RTC_SLOW_CLK_FREQ_8MD256    (RTC_FAST_CLK_FREQ_8M / 256)
 #define RTC_SLOW_CLK_FREQ_32K       32768
 
+/* APLL numerator frequency range */
+#define RTC_APLL_NUMERATOR_FREQ_MAX     500000000   // 500MHz
+#define RTC_APLL_NUMERATOR_FREQ_MIN     350000000   // 350MHz
+
 /* BBPLL configuration values */
 #define BBPLL_ENDIV5_VAL_320M       0x43
 #define BBPLL_BBADC_DSMP_VAL_320M   0x84
@@ -308,6 +312,49 @@ void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm
     }
 }
 
+uint32_t rtc_clk_apll_freq_set(uint32_t freq)
+{
+    if (freq < RTC_APLL_FREQ_MIN || freq > RTC_APLL_FREQ_MAX) {
+        return 0;
+    }
+    /* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2) */
+    uint32_t rtc_xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
+    if (rtc_xtal_freq == 0) {
+        // xtal_freq has not set yet
+        abort();
+    }
+    uint32_t o_div = 0;
+    uint32_t sdm0 = 0;
+    uint32_t sdm1 = 0;
+    uint32_t sdm2 = 0;
+    /**
+     * This formula is to satisfy the condition xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz
+     * '+ 1' in this formular is to get the ceil value
+     * We can also choose the condition xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz
+     * Then the formula should be o_div = (uint32_t)(RTC_APLL_NUMERATOR_FREQ_MAX / (float)(freq * 2)) - 2; */
+    o_div = (uint32_t)(RTC_APLL_NUMERATOR_FREQ_MIN / (float)(freq * 2) + 1) - 2;
+    // sdm2 = (uint32_t)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4
+    sdm2 = (uint32_t)(((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 = (uint32_t)(numrator * 65536.0 + 0.5) / 256;
+        // Get the closest sdm0
+        sdm0 = (uint32_t)(numrator * 65536.0 + 0.5) % 256;
+    }
+    rtc_clk_apll_enable(true, sdm0, sdm1, sdm2, o_div);
+    float real_freq = (float)rtc_xtal_freq * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) / (((float)o_div + 2) * 2);
+    SOC_LOGD(TAG, "APLL is working at %d Hz with coefficient [sdm0] %d [sdm1] %d [sdm2] %d [o_div] %d",
+             (uint32_t)(real_freq * 1000000), sdm0, sdm1, sdm2, o_div);
+    return (uint32_t)(real_freq * 1000000);
+}
+
 void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
 {
     REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);

+ 47 - 0
components/esp_hw_support/port/esp32s2/rtc_clk.c

@@ -31,6 +31,10 @@ static const char *TAG = "rtc_clk";
 #define RTC_PLL_FREQ_480M   480
 #define DELAY_RTC_CLK_SWITCH 5
 
+/* APLL numerator frequency range */
+#define RTC_APLL_NUMERATOR_FREQ_MAX     500000000   // 500MHz
+#define RTC_APLL_NUMERATOR_FREQ_MIN     350000000   // 350MHz
+
 // Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
 // On the ESP32-S2, 480MHz PLL is enabled at reset.
 static uint32_t s_cur_pll_freq = RTC_PLL_FREQ_480M;
@@ -145,6 +149,49 @@ void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm
     }
 }
 
+uint32_t rtc_clk_apll_freq_set(uint32_t freq)
+{
+    if (freq < RTC_APLL_FREQ_MIN || freq > RTC_APLL_FREQ_MAX) {
+        return 0;
+    }
+    /* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2) */
+    uint32_t rtc_xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
+    if (rtc_xtal_freq == 0) {
+        // xtal_freq has not set yet
+        abort();
+    }
+    uint32_t o_div = 0;
+    uint32_t sdm0 = 0;
+    uint32_t sdm1 = 0;
+    uint32_t sdm2 = 0;
+    /**
+     * This formula is to satisfy the condition xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz
+     * '+ 1' in this formular is to get the ceil value
+     * We can also choose the condition xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz
+     * Then the formula should be o_div = (uint32_t)(RTC_APLL_NUMERATOR_FREQ_MAX / (float)(freq * 2)) - 2; */
+    o_div = (uint32_t)(RTC_APLL_NUMERATOR_FREQ_MIN / (float)(freq * 2) + 1) - 2;
+    // sdm2 = (uint32_t)(((o_div + 2) * 2) * apll_freq / xtal_freq) - 4
+    sdm2 = (uint32_t)(((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 = (uint32_t)(numrator * 65536.0 + 0.5) / 256;
+        // Get the closest sdm0
+        sdm0 = (uint32_t)(numrator * 65536.0 + 0.5) % 256;
+    }
+    rtc_clk_apll_enable(true, sdm0, sdm1, sdm2, o_div);
+    float real_freq = (float)rtc_xtal_freq * (4 + sdm2 + (float)sdm1/256.0 + (float)sdm0/65536.0) / (((float)o_div + 2) * 2);
+    SOC_LOGD(TAG, "APLL is working at %d Hz with coefficient [sdm0] %d [sdm1] %d [sdm2] %d [o_div] %d",
+             (uint32_t)(real_freq * 1000000), sdm0, sdm1, sdm2, o_div);
+    return (uint32_t)(real_freq * 1000000);
+}
+
 void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
 {
     REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);

+ 16 - 17
components/hal/i2s_hal.c

@@ -26,27 +26,26 @@ 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 = clk_cfg->sclk - clk_cfg->mclk * cal->mclk_div;
+    if (!freq_diff) {
         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);
         }
     }
 }

+ 17 - 13
components/soc/esp32/include/soc/rtc.h

@@ -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,6 +46,9 @@ extern "C" {
  * - rtc_init: initialization
  */
 
+/* APLL frequency range */
+#define RTC_APLL_FREQ_MAX               128000000   // 128MHz
+#define RTC_APLL_FREQ_MIN               16000000    // 16MHz
 
 /**
  * @brief Possible main XTAL frequency values.
@@ -268,6 +263,15 @@ bool rtc_clk_8md256_enabled(void);
 void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1,
         uint32_t sdm2, uint32_t o_div);
 
+/**
+ * @brief Set APLL clock freqency
+ * @param freq Expected APLL freqency (unit: Hz)
+ * @return
+ *      - 0: Failed, the expected APLL frequency is out of range
+ *      - else:  The true APLL clock (unit: Hz)
+ */
+uint32_t rtc_clk_apll_freq_set(uint32_t freq);
+
 /**
  * @brief Select source for RTC_SLOW_CLK
  * @param slow_freq clock source (one of rtc_slow_freq_t values)

+ 0 - 19
components/soc/esp32c3/include/soc/rtc.h

@@ -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)

+ 0 - 18
components/soc/esp32h2/include/soc/rtc.h

@@ -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)

+ 18 - 13
components/soc/esp32s2/include/soc/rtc.h

@@ -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>
@@ -81,6 +73,10 @@ extern "C" {
 #define DELAY_SLOW_CLK_SWITCH           300
 #define DELAY_8M_ENABLE                 50
 
+/* APLL frequency range */
+#define RTC_APLL_FREQ_MAX               128000000   // 128MHz
+#define RTC_APLL_FREQ_MIN               16000000    // 16MHz
+
 /* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
  * 10 cycles will take approximately 300 microseconds.
  */
@@ -413,6 +409,15 @@ bool rtc_clk_8md256_enabled(void);
  */
 void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div);
 
+/**
+ * @brief Set APLL clock freqency
+ * @param freq Expected APLL freqency (unit: Hz)
+ * @return
+ *      - 0: Failed, the expected APLL frequency is out of range
+ *      - else:  The true APLL clock (unit: Hz)
+ */
+uint32_t rtc_clk_apll_freq_set(uint32_t freq);
+
 /**
  * @brief Select source for RTC_SLOW_CLK
  * @param slow_freq clock source (one of rtc_slow_freq_t values)

+ 0 - 19
components/soc/esp32s3/include/soc/rtc.h

@@ -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)

+ 0 - 19
components/soc/esp8684/include/soc/rtc.h

@@ -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)

+ 0 - 2
tools/ci/check_copyright_ignore.txt

@@ -1632,7 +1632,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 +1854,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