Przeglądaj źródła

LEDC: improved support for ESP32-C3 and refactored divisor calculation

As ESP32C3 does not have support for REF_TICK source clock, it is now not
possible to select it anymore.
Auto cfg clock has been improved for all boards.
Omar Chebib 4 lat temu
rodzic
commit
aa2ca7dd94

+ 37 - 4
components/driver/include/driver/ledc.h

@@ -16,10 +16,43 @@
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-#define LEDC_APB_CLK_HZ  (APB_CLK_FREQ)
-#define LEDC_REF_CLK_HZ  (REF_CLK_FREQ)
-#define LEDC_ERR_DUTY    (0xFFFFFFFF)
-#define LEDC_ERR_VAL     (-1)
+#define LEDC_APB_CLK_HZ         (APB_CLK_FREQ)
+#define LEDC_REF_CLK_HZ         (REF_CLK_FREQ)
+#define LEDC_ERR_DUTY           (0xFFFFFFFF)
+#define LEDC_ERR_VAL            (-1)
+
+/**
+ * @brief Configuration parameters of LEDC channel for ledc_channel_config function
+ */
+typedef struct {
+    int gpio_num;                   /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16 */
+    ledc_mode_t speed_mode;         /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */
+    ledc_channel_t channel;         /*!< LEDC channel (0 - 7) */
+    ledc_intr_type_t intr_type;     /*!< configure interrupt, Fade interrupt enable  or Fade interrupt disable */
+    ledc_timer_t timer_sel;         /*!< Select the timer source of channel (0 - 3) */
+    uint32_t duty;                  /*!< LEDC channel duty, the range of duty setting is [0, (2**duty_resolution)] */
+    int hpoint;                     /*!< LEDC channel hpoint value, the max value is 0xfffff */
+    struct {
+        unsigned int output_invert: 1;/*!< Enable (1) or disable (0) gpio output invert */
+    } flags;                        /*!< LEDC flags */
+
+} ledc_channel_config_t;
+
+/**
+ * @brief Configuration parameters of LEDC Timer timer for ledc_timer_config function
+ */
+typedef struct {
+    ledc_mode_t speed_mode;                /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */
+    union {
+        ledc_timer_bit_t duty_resolution;  /*!< LEDC channel duty resolution */
+        ledc_timer_bit_t bit_num __attribute__((deprecated)); /*!< Deprecated in ESP-IDF 3.0. This is an alias to 'duty_resolution' for backward compatibility with ESP-IDF 2.1 */
+    };
+    ledc_timer_t  timer_num;               /*!< The timer source of channel (0 - 3) */
+    uint32_t freq_hz;                      /*!< LEDC timer frequency (Hz) */
+    ledc_clk_cfg_t clk_cfg;                /*!< Configure LEDC source clock.
+                                                For low speed channels and high speed channels, you can specify the source clock using LEDC_USE_REF_TICK, LEDC_USE_APB_CLK or LEDC_AUTO_CLK.
+                                                For low speed channels, you can also specify the source clock using LEDC_USE_RTC8M_CLK, in this case, all low speed channel's source clock must be RTC8M_CLK*/
+} ledc_timer_config_t;
 
 
 typedef intr_handle_t ledc_isr_handle_t;
 typedef intr_handle_t ledc_isr_handle_t;
 
 

+ 200 - 33
components/driver/ledc.c

@@ -63,6 +63,8 @@ static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED;
 #define SLOW_CLK_CYC_CALIBRATE    (13)
 #define SLOW_CLK_CYC_CALIBRATE    (13)
 #define LEDC_FADE_TOO_SLOW_STR    "LEDC FADE TOO SLOW"
 #define LEDC_FADE_TOO_SLOW_STR    "LEDC FADE TOO SLOW"
 #define LEDC_FADE_TOO_FAST_STR    "LEDC FADE TOO FAST"
 #define LEDC_FADE_TOO_FAST_STR    "LEDC FADE TOO FAST"
+#define DIM(array)                (sizeof(array)/sizeof(*array))
+#define LEDC_IS_DIV_INVALID(div)  ((div) <= LEDC_LL_FRACTIONAL_MAX || (div) > LEDC_TIMER_DIV_NUM_MAX)
 
 
 static const char *LEDC_NOT_INIT = "LEDC is not initialized";
 static const char *LEDC_NOT_INIT = "LEDC is not initialized";
 static const char *LEDC_FADE_SERVICE_ERR_STR = "LEDC fade service not installed";
 static const char *LEDC_FADE_SERVICE_ERR_STR = "LEDC fade service not installed";
@@ -102,10 +104,12 @@ static uint32_t ledc_get_src_clk_freq(ledc_clk_cfg_t clk_cfg)
     uint32_t src_clk_freq = 0;
     uint32_t src_clk_freq = 0;
     if (clk_cfg == LEDC_USE_APB_CLK) {
     if (clk_cfg == LEDC_USE_APB_CLK) {
         src_clk_freq = LEDC_APB_CLK_HZ;
         src_clk_freq = LEDC_APB_CLK_HZ;
-    } else if (clk_cfg == LEDC_USE_REF_TICK) {
-        src_clk_freq = LEDC_REF_CLK_HZ;
     } else if (clk_cfg == LEDC_USE_RTC8M_CLK) {
     } else if (clk_cfg == LEDC_USE_RTC8M_CLK) {
         src_clk_freq = s_ledc_slow_clk_8M;
         src_clk_freq = s_ledc_slow_clk_8M;
+#if SOC_LEDC_SUPPORT_REF_TICK
+    } else if (clk_cfg == LEDC_USE_REF_TICK) {
+        src_clk_freq = LEDC_REF_CLK_HZ;
+#endif
 #if SOC_LEDC_SUPPORT_XTAL_CLOCK
 #if SOC_LEDC_SUPPORT_XTAL_CLOCK
     } else if (clk_cfg == LEDC_USE_XTAL_CLK) {
     } else if (clk_cfg == LEDC_USE_XTAL_CLK) {
         src_clk_freq = rtc_clk_xtal_freq_get() * 1000000;
         src_clk_freq = rtc_clk_xtal_freq_get() * 1000000;
@@ -175,7 +179,11 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_
     LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
     LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
     portENTER_CRITICAL(&ledc_spinlock);
     portENTER_CRITICAL(&ledc_spinlock);
     ledc_hal_set_clock_divider(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, clock_divider);
     ledc_hal_set_clock_divider(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, clock_divider);
+#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
+    /* Clock source can only be configured on boards which support timer-specific
+     * source clock. */
     ledc_hal_set_clock_source(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, clk_src);
     ledc_hal_set_clock_source(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, clk_src);
+#endif
     ledc_hal_set_duty_resolution(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, duty_resolution);
     ledc_hal_set_duty_resolution(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, duty_resolution);
     ledc_ls_timer_update(speed_mode, timer_sel);
     ledc_ls_timer_update(speed_mode, timer_sel);
     portEXIT_CRITICAL(&ledc_spinlock);
     portEXIT_CRITICAL(&ledc_spinlock);
@@ -259,52 +267,211 @@ esp_err_t ledc_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags,
     return ret;
     return ret;
 }
 }
 
 
-// Setting the LEDC timer divisor with the given source clock, frequency and resolution.
+static inline uint32_t ledc_calculate_divisor(uint32_t src_clk_freq, int freq_hz, uint32_t precision)
+{
+    /**
+     * In order to find the right divisor, we need to divide the source clock
+     * frequency by the desired frequency. However, two things to note here:
+     * - The lowest LEDC_LL_FRACTIONAL_BITS bits of the result are the FRACTIONAL
+     *   part. The higher bits represent the integer part, this is why we need
+     *   to right shift the source frequency.
+     * - The `precision` parameter represents the granularity of the clock. It
+     *   **must** be a power of 2. It means that the resulted divisor is
+     *   a multiplier of `precision`.
+     *
+     * Let's take a concrete example, we need to generate a 5KHz clock out of
+     * a 80MHz clock (APB).
+     * If the precision is 1024 (10 bits), the resulted multiplier is:
+     * (80000000 << 8) / (5000 * 1024) = 4000 (0xfa0)
+     * Let's ignore the fractional part to simplify the exaplanation, so we get
+     * a result of 15 (0xf).
+     * This can be interpreted as: every 15 "precision" ticks, the resulted
+     * clock will go high, where one precision tick is made out of 1024 source
+     * clock ticks.
+     * Thus, every `15 * 1024` source clock ticks, the resulted clock will go
+     * high. */
+    return ( (uint64_t) src_clk_freq << LEDC_LL_FRACTIONAL_BITS ) / (freq_hz * precision);
+}
+
+static inline uint32_t ledc_auto_global_clk_divisor(int freq_hz, uint32_t precision, ledc_clk_cfg_t* clk_target)
+{
+    uint32_t div_param = 0;
+    uint32_t i = 0;
+    uint32_t clk_freq = 0;
+    /* This function will go through all the following clock sources to look
+     * for a valid divisor which generates the requested frequency. */
+    const ledc_clk_cfg_t glb_clks[] = LEDC_LL_GLOBAL_CLOCKS;
+
+    for (i = 0; i < DIM(glb_clks); i++) {
+        /* Before calculating the divisor, we need to have the RTC frequency.
+         * If it hasn't been mesured yet, try calibrating it now. */
+        if (glb_clks[i] == LEDC_SLOW_CLK_RTC8M && s_ledc_slow_clk_8M == 0 && !ledc_slow_clk_calibrate()) {
+            ESP_LOGD(LEDC_TAG, "Unable to retrieve RTC clock frequency, skipping it\n");
+            continue;
+        }
+
+        clk_freq = ledc_get_src_clk_freq(glb_clks[i]);
+        div_param = ledc_calculate_divisor(clk_freq, freq_hz, precision);
+
+        /* If the divisor is valid, we can return this value. */
+        if (!LEDC_IS_DIV_INVALID(div_param)) {
+            *clk_target = glb_clks[i];
+            break;
+        }
+    }
+
+    return div_param;
+
+}
+
+#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
+static inline uint32_t ledc_auto_timer_specific_clk_divisor(ledc_mode_t speed_mode, int freq_hz, uint32_t precision,
+                                                            ledc_clk_src_t* clk_source)
+{
+    uint32_t div_param = 0;
+    uint32_t i = 0;
+
+    /* Use an anonymous structure, only this function requires it.
+     * Get the list of the timer-specific clocks, try to find one for the reuested frequency.  */
+    const struct { ledc_clk_src_t clk; uint32_t freq; } specific_clks[] = LEDC_LL_TIMER_SPECIFIC_CLOCKS;
+
+    for (i = 0; i < DIM(specific_clks); i++) {
+        div_param = ledc_calculate_divisor(specific_clks[i].freq, freq_hz, precision);
+
+        /* If the divisor is valid, we can return this value. */
+        if (!LEDC_IS_DIV_INVALID(div_param)) {
+            *clk_source = specific_clks[i].clk;
+            break;
+        }
+    }
+
+#if SOC_LEDC_SUPPORT_HS_MODE
+    /* On board that support LEDC high-speed mode, APB clock becomes a timer-
+     * specific clock when in high speed mode. Check if it is necessary here
+     * to test APB. */
+    if (speed_mode == LEDC_HIGH_SPEED_MODE && i == DIM(specific_clks)) {
+        /* No divider was found yet, try with APB! */
+        div_param = ledc_calculate_divisor(LEDC_APB_CLK_HZ, freq_hz, precision);
+
+        if (!LEDC_IS_DIV_INVALID(div_param)) {
+            *clk_source = LEDC_APB_CLK;
+        }
+    }
+#endif
+
+    return div_param;
+}
+#endif
+
+/**
+ * @brief Try to find the clock with its divisor giving the frequency requested
+ * by the caller.
+ */
+static uint32_t ledc_auto_clk_divisor(ledc_mode_t speed_mode, int freq_hz, uint32_t precision,
+                                      ledc_clk_src_t* clk_source, ledc_clk_cfg_t* clk_target)
+{
+    uint32_t div_param = 0;
+
+#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
+    /* If the SoC presents timer-specific clock(s), try to achieve the given frequency
+     * thanks to it/them.
+     * clk_source parameter will returned by this function. */
+    div_param = ledc_auto_timer_specific_clk_divisor(speed_mode, freq_hz, precision, clk_source);
+
+    if (!LEDC_IS_DIV_INVALID(div_param)) {
+        /* The dividor is valid, no need try any other clock, return directly. */
+        return div_param;
+    }
+#endif
+
+    /* On ESP32, only low speed channel can use the global clocks. For other
+     * chips, there are no high speed channels. */
+    if (speed_mode == LEDC_LOW_SPEED_MODE) {
+        div_param = ledc_auto_global_clk_divisor(freq_hz, precision, clk_target);
+    }
+
+    return div_param;
+}
+
+/**
+ * @brief Function setting the LEDC timer divisor with the given source clock,
+ * frequency and resolution. If the clock configuration passed is
+ * LEDC_AUTO_CLK, the clock will be determined automatically (if possible).
+ */
 static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_num, ledc_clk_cfg_t clk_cfg, int freq_hz, int duty_resolution)
 static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_num, ledc_clk_cfg_t clk_cfg, int freq_hz, int duty_resolution)
 {
 {
     uint32_t div_param = 0;
     uint32_t div_param = 0;
-    uint32_t precision = ( 0x1 << duty_resolution );
-    ledc_clk_src_t timer_clk_src = LEDC_APB_CLK;
-    // Calculate the divisor
-    // User specified source clock(RTC8M_CLK) for low speed channel
-    if ((speed_mode == LEDC_LOW_SPEED_MODE) && (clk_cfg == LEDC_USE_RTC8M_CLK)) {
-        if (s_ledc_slow_clk_8M == 0) {
-            if (ledc_slow_clk_calibrate() == false) {
-                goto error;
-            }
+    const uint32_t precision = ( 0x1 << duty_resolution );
+    /* This variable represents the timer's mux value. It will be overwritten
+     * if a timer-specific clock is used. */
+    ledc_clk_src_t timer_clk_src = LEDC_SCLK;
+    uint32_t src_clk_freq = 0;
+
+    if (clk_cfg == LEDC_AUTO_CLK) {
+        /* User hasn't specified the speed, we should try to guess it. */
+        div_param = ledc_auto_clk_divisor(speed_mode, freq_hz, precision, &timer_clk_src, &clk_cfg);
+
+    } else if (clk_cfg == LEDC_USE_RTC8M_CLK) {
+        /* User specified source clock(RTC8M_CLK) for low speed channel.
+         * Make sure the speed mode is correct. */
+        ESP_RETURN_ON_FALSE((speed_mode == LEDC_LOW_SPEED_MODE), ESP_ERR_INVALID_ARG, LEDC_TAG, "RTC clock can only be used in low speed mode");
+
+        /* Before calculating the divisor, we need to have the RTC frequency.
+         * If it hasn't been mesured yet, try calibrating it now. */
+        if(s_ledc_slow_clk_8M == 0 && ledc_slow_clk_calibrate() == false) {
+            goto error;
         }
         }
-        div_param = ( (uint64_t) s_ledc_slow_clk_8M << 8 ) / freq_hz / precision;
+
+        /* We have the RTC clock frequency now. */
+        div_param = ledc_calculate_divisor(s_ledc_slow_clk_8M, freq_hz, precision);
+
     } else {
     } else {
-        // Automatically select APB or REF_TICK as the source clock.
-        if (clk_cfg == LEDC_AUTO_CLK) {
-            // Try calculating divisor based on LEDC_APB_CLK
-            div_param = ( (uint64_t) LEDC_APB_CLK_HZ << 8 ) / freq_hz / precision;
-            if (div_param > LEDC_TIMER_DIV_NUM_MAX) {
-                // APB_CLK results in divisor which too high. Try using REF_TICK as clock source.
-                timer_clk_src = LEDC_REF_TICK;
-                div_param = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision;
-            } else if (div_param < 256) {
-                // divisor is too low
-                goto error;
-            }
-            // User specified source clock(LEDC_APB_CLK_HZ or LEDC_REF_TICK)
-        } else {
-            timer_clk_src = (clk_cfg == LEDC_USE_REF_TICK) ? LEDC_REF_TICK : LEDC_APB_CLK;
-            uint32_t src_clk_freq = ledc_get_src_clk_freq(clk_cfg);
-            div_param = ( (uint64_t) src_clk_freq << 8 ) / freq_hz / precision;
+
+#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
+        if (LEDC_LL_IS_TIMER_SPECIFIC_CLOCK(speed_mode, clk_cfg)) {
+            /* Currently we can convert a timer specific clock to a source clock that
+             * easily because their values are identical in the enumerations (on purpose)
+             * If we decide to change the values in the future, we should consider defining
+             * a macro/function to convert timer-specific clock to clock source .*/
+            timer_clk_src = (ledc_clk_src_t) clk_cfg;
         }
         }
+#endif
+        src_clk_freq = ledc_get_src_clk_freq(clk_cfg);
+        div_param = ledc_calculate_divisor(src_clk_freq, freq_hz, precision);
     }
     }
-    if (div_param < 256 || div_param > LEDC_TIMER_DIV_NUM_MAX) {
+
+    if (LEDC_IS_DIV_INVALID(div_param)) {
         goto error;
         goto error;
     }
     }
+
+    /* The following debug message makes more sense for AUTO mode. */
+    ESP_LOGD(LEDC_TAG, "Using clock source %d (in %s mode), divisor: 0x%x\n",
+             timer_clk_src, (speed_mode == LEDC_LOW_SPEED_MODE ? "slow" : "fast"), div_param);
+
+    /* The following block configures the global clock.
+     * Thus, in theory, this only makes sense when the source clock is LEDC_SCLK
+     * and in LOW_SPEED_MODE (as FAST_SPEED_MODE doesn't present any global clock)
+     *
+     * However, in practice, on modules that support high-speed mode, no matter
+     * whether the source clock is a timer-specific one (e.g. REF_TICK) or not,
+     * the global clock MUST be configured when in low speed mode.
+     * When using high-speed mode, this is not necessary.
+     */
+#if SOC_LEDC_SUPPORT_HS_MODE
     if (speed_mode == LEDC_LOW_SPEED_MODE) {
     if (speed_mode == LEDC_LOW_SPEED_MODE) {
+#else
+    if (timer_clk_src == LEDC_SCLK) {
+#endif
+        ESP_LOGD(LEDC_TAG, "In slow speed mode, using clock %d", clk_cfg);
         portENTER_CRITICAL(&ledc_spinlock);
         portENTER_CRITICAL(&ledc_spinlock);
         ledc_hal_set_slow_clk(&(p_ledc_obj[speed_mode]->ledc_hal), clk_cfg);
         ledc_hal_set_slow_clk(&(p_ledc_obj[speed_mode]->ledc_hal), clk_cfg);
         portEXIT_CRITICAL(&ledc_spinlock);
         portEXIT_CRITICAL(&ledc_spinlock);
     }
     }
-    //Set the divisor
+
+    /* The divisor is correct, we can write in the hardware. */
     ledc_timer_set(speed_mode, timer_num, div_param, duty_resolution, timer_clk_src);
     ledc_timer_set(speed_mode, timer_num, div_param, duty_resolution, timer_clk_src);
-    // reset the timer
+
+    /* Reset the timer. */
     ledc_timer_rst(speed_mode, timer_num);
     ledc_timer_rst(speed_mode, timer_num);
     return ESP_OK;
     return ESP_OK;
 error:
 error:

+ 21 - 0
components/hal/esp32/include/hal/ledc_ll.h

@@ -22,6 +22,27 @@
 #include "soc/ledc_struct.h"
 #include "soc/ledc_struct.h"
 
 
 #define LEDC_LL_GET_HW() &LEDC
 #define LEDC_LL_GET_HW() &LEDC
+#define LEDC_LL_FRACTIONAL_BITS    (8)
+#define LEDC_LL_FRACTIONAL_MAX     ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
+
+#define LEDC_LL_GLOBAL_CLOCKS { \
+                                LEDC_USE_APB_CLK, \
+                                LEDC_USE_RTC8M_CLK, \
+                            }
+#define LEDC_LL_TIMER_SPECIFIC_CLOCKS \
+                            {\
+                                { \
+                                    .clk = LEDC_REF_TICK, \
+                                    .freq = LEDC_REF_CLK_HZ, \
+                                } \
+                            }
+
+/* On ESP32, APB clock is a timer-specific clock only in fast clock mode */
+#define LEDC_LL_IS_TIMER_SPECIFIC_CLOCK(SPEED, CLK) (\
+                                                     ((CLK) == LEDC_USE_REF_TICK) || \
+                                                     ((SPEED) == LEDC_HIGH_SPEED_MODE && (CLK) == LEDC_USE_APB_CLK) \
+                                                    )
+
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {

+ 8 - 26
components/hal/esp32c3/include/hal/ledc_ll.h

@@ -26,6 +26,13 @@ extern "C" {
 #endif
 #endif
 
 
 #define LEDC_LL_GET_HW() &LEDC
 #define LEDC_LL_GET_HW() &LEDC
+#define LEDC_LL_FRACTIONAL_BITS    (8)
+#define LEDC_LL_FRACTIONAL_MAX     ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
+#define LEDC_LL_GLOBAL_CLOCKS { \
+                                LEDC_USE_APB_CLK, \
+                                LEDC_USE_XTAL_CLK, \
+                                LEDC_USE_RTC8M_CLK, \
+                            }
 
 
 /**
 /**
  * @brief Set LEDC low speed timer clock
  * @brief Set LEDC low speed timer clock
@@ -155,27 +162,6 @@ static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_m
     *clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
     *clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
 }
 }
 
 
-/**
- * @brief Set LEDC timer clock source
- *
- * @param hw Beginning address of the peripheral registers
- * @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
- * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
- * @param clk_src Timer clock source
- *
- * @return None
- */
-static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src)
-{
-    if (clk_src == LEDC_REF_TICK) {
-        //REF_TICK can only be used when APB is selected.
-        hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 1;
-        hw->conf.apb_clk_sel = 1;
-    } else {
-        hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 0;
-    }
-}
-
 /**
 /**
  * @brief Get LEDC timer clock source
  * @brief Get LEDC timer clock source
  *
  *
@@ -188,11 +174,7 @@ static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mo
  */
  */
 static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
 static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
 {
 {
-    if (hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 1) {
-        *clk_src = LEDC_REF_TICK;
-    } else {
-        *clk_src = LEDC_APB_CLK;
-    }
+    *clk_src = LEDC_APB_CLK;
 }
 }
 
 
 /**
 /**

+ 8 - 26
components/hal/esp32h2/include/hal/ledc_ll.h

@@ -26,6 +26,13 @@ extern "C" {
 #endif
 #endif
 
 
 #define LEDC_LL_GET_HW() &LEDC
 #define LEDC_LL_GET_HW() &LEDC
+#define LEDC_LL_FRACTIONAL_BITS    (8)
+#define LEDC_LL_FRACTIONAL_MAX     ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
+#define LEDC_LL_GLOBAL_CLOCKS { \
+                                LEDC_USE_APB_CLK, \
+                                LEDC_USE_XTAL_CLK, \
+                                LEDC_USE_RTC8M_CLK, \
+                            }
 
 
 /**
 /**
  * @brief Set LEDC low speed timer clock
  * @brief Set LEDC low speed timer clock
@@ -155,27 +162,6 @@ static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_m
     *clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
     *clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
 }
 }
 
 
-/**
- * @brief Set LEDC timer clock source
- *
- * @param hw Beginning address of the peripheral registers
- * @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
- * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
- * @param clk_src Timer clock source
- *
- * @return None
- */
-static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src)
-{
-    if (clk_src == LEDC_REF_TICK) {
-        //REF_TICK can only be used when APB is selected.
-        hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 1;
-        hw->conf.apb_clk_sel = 1;
-    } else {
-        hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 0;
-    }
-}
-
 /**
 /**
  * @brief Get LEDC timer clock source
  * @brief Get LEDC timer clock source
  *
  *
@@ -188,11 +174,7 @@ static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mo
  */
  */
 static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
 static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
 {
 {
-    if (hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 1) {
-        *clk_src = LEDC_REF_TICK;
-    } else {
-        *clk_src = LEDC_APB_CLK;
-    }
+    *clk_src = LEDC_APB_CLK;
 }
 }
 
 
 /**
 /**

+ 16 - 0
components/hal/esp32s2/include/hal/ledc_ll.h

@@ -26,6 +26,22 @@ extern "C" {
 #endif
 #endif
 
 
 #define LEDC_LL_GET_HW() &LEDC
 #define LEDC_LL_GET_HW() &LEDC
+#define LEDC_LL_FRACTIONAL_BITS    (8)
+#define LEDC_LL_FRACTIONAL_MAX     ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
+#define LEDC_LL_GLOBAL_CLOCKS { \
+                                LEDC_USE_APB_CLK, \
+                                LEDC_USE_XTAL_CLK, \
+                                LEDC_USE_RTC8M_CLK, \
+                              }
+#define LEDC_LL_TIMER_SPECIFIC_CLOCKS \
+                            {\
+                                { \
+                                    .clk = LEDC_REF_TICK, \
+                                    .freq = LEDC_REF_CLK_HZ, \
+                                } \
+                            }
+
+#define LEDC_LL_IS_TIMER_SPECIFIC_CLOCK(SPEED, CLK) ((CLK) == LEDC_USE_REF_TICK)
 
 
 /**
 /**
  * @brief Set LEDC low speed timer clock
  * @brief Set LEDC low speed timer clock

+ 16 - 0
components/hal/esp32s3/include/hal/ledc_ll.h

@@ -26,6 +26,22 @@ extern "C" {
 #endif
 #endif
 
 
 #define LEDC_LL_GET_HW() &LEDC
 #define LEDC_LL_GET_HW() &LEDC
+#define LEDC_LL_FRACTIONAL_BITS    (8)
+#define LEDC_LL_FRACTIONAL_MAX     ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
+#define LEDC_LL_GLOBAL_CLOCKS { \
+                                LEDC_USE_APB_CLK, \
+                                LEDC_USE_XTAL_CLK, \
+                                LEDC_USE_RTC8M_CLK, \
+                              }
+#define LEDC_LL_TIMER_SPECIFIC_CLOCKS \
+                            {\
+                                { \
+                                    .clk = LEDC_REF_TICK, \
+                                    .freq = LEDC_REF_CLK_HZ, \
+                                } \
+                            }
+
+#define LEDC_LL_IS_TIMER_SPECIFIC_CLOCK(SPEED, CLK) ((CLK) == LEDC_USE_REF_TICK)
 
 
 /**
 /**
  * @brief Set LEDC low speed timer clock
  * @brief Set LEDC low speed timer clock

+ 9 - 26
components/hal/esp8684/include/hal/ledc_ll.h

@@ -17,6 +17,14 @@ extern "C" {
 #endif
 #endif
 
 
 #define LEDC_LL_GET_HW() &LEDC
 #define LEDC_LL_GET_HW() &LEDC
+#define LEDC_LL_FRACTIONAL_BITS    (8)
+#define LEDC_LL_FRACTIONAL_MAX     ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
+#define LEDC_LL_GLOBAL_CLOCKS { \
+                                LEDC_SLOW_CLK_APB, \
+                                LEDC_SLOW_CLK_XTAL, \
+                                LEDC_SLOW_CLK_RTC8M, \
+                              }
+
 
 
 /**
 /**
  * @brief Set LEDC low speed timer clock
  * @brief Set LEDC low speed timer clock
@@ -146,27 +154,6 @@ static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_m
     *clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
     *clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
 }
 }
 
 
-/**
- * @brief Set LEDC timer clock source
- *
- * @param hw Beginning address of the peripheral registers
- * @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
- * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
- * @param clk_src Timer clock source
- *
- * @return None
- */
-static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src)
-{
-    if (clk_src == LEDC_REF_TICK) {
-        //REF_TICK can only be used when APB is selected.
-        hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 1;
-        hw->conf.apb_clk_sel = 1;
-    } else {
-        hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 0;
-    }
-}
-
 /**
 /**
  * @brief Get LEDC timer clock source
  * @brief Get LEDC timer clock source
  *
  *
@@ -179,11 +166,7 @@ static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mo
  */
  */
 static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
 static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
 {
 {
-    if (hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 1) {
-        *clk_src = LEDC_REF_TICK;
-    } else {
-        *clk_src = LEDC_APB_CLK;
-    }
+    *clk_src = LEDC_APB_CLK;
 }
 }
 
 
 /**
 /**

+ 17 - 48
components/hal/include/hal/ledc_types.h

@@ -1,16 +1,8 @@
-// Copyright 2019 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: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 
 #pragma once
 #pragma once
 
 
@@ -50,11 +42,19 @@ typedef enum {
 #endif
 #endif
 } ledc_slow_clk_sel_t;
 } ledc_slow_clk_sel_t;
 
 
+/**
+ * In theory, the following enumeration shall be placed in LEDC driver's header.
+ * However, as the next enumeration, `ledc_clk_src_t`, makes the use of some of
+ * these values and to avoid mutual inclusion of the headers, we must define it
+ * here.
+ */
 typedef enum {
 typedef enum {
     LEDC_AUTO_CLK = 0,    /*!< The driver will automatically select the source clock(REF_TICK or APB) based on the giving resolution and duty parameter when init the timer*/
     LEDC_AUTO_CLK = 0,    /*!< The driver will automatically select the source clock(REF_TICK or APB) based on the giving resolution and duty parameter when init the timer*/
-    LEDC_USE_REF_TICK,    /*!< LEDC timer select REF_TICK clock as source clock*/
     LEDC_USE_APB_CLK,     /*!< LEDC timer select APB clock as source clock*/
     LEDC_USE_APB_CLK,     /*!< LEDC timer select APB clock as source clock*/
     LEDC_USE_RTC8M_CLK,   /*!< LEDC timer select RTC8M_CLK as source clock. Only for low speed channels and this parameter must be the same for all low speed channels*/
     LEDC_USE_RTC8M_CLK,   /*!< LEDC timer select RTC8M_CLK as source clock. Only for low speed channels and this parameter must be the same for all low speed channels*/
+#if SOC_LEDC_SUPPORT_REF_TICK
+    LEDC_USE_REF_TICK,    /*!< LEDC timer select REF_TICK clock as source clock*/
+#endif
 #if SOC_LEDC_SUPPORT_XTAL_CLOCK
 #if SOC_LEDC_SUPPORT_XTAL_CLOCK
     LEDC_USE_XTAL_CLK,    /*!< LEDC timer select XTAL clock as source clock*/
     LEDC_USE_XTAL_CLK,    /*!< LEDC timer select XTAL clock as source clock*/
 #endif
 #endif
@@ -64,11 +64,13 @@ typedef enum {
    LEDC_AUTO_CLK in the driver, as these enums have very similar names and user may pass
    LEDC_AUTO_CLK in the driver, as these enums have very similar names and user may pass
    one of these by mistake. */
    one of these by mistake. */
 typedef enum  {
 typedef enum  {
+#if SOC_LEDC_SUPPORT_REF_TICK
     LEDC_REF_TICK = LEDC_USE_REF_TICK, /*!< LEDC timer clock divided from reference tick (1Mhz) */
     LEDC_REF_TICK = LEDC_USE_REF_TICK, /*!< LEDC timer clock divided from reference tick (1Mhz) */
+#endif
     LEDC_APB_CLK = LEDC_USE_APB_CLK,  /*!< LEDC timer clock divided from APB clock (80Mhz) */
     LEDC_APB_CLK = LEDC_USE_APB_CLK,  /*!< LEDC timer clock divided from APB clock (80Mhz) */
+    LEDC_SCLK = LEDC_USE_APB_CLK      /*!< Selecting this value for LEDC_TICK_SEL_TIMER let the hardware take its source clock from LEDC_APB_CLK_SEL */
 } ledc_clk_src_t;
 } ledc_clk_src_t;
 
 
-
 typedef enum {
 typedef enum {
     LEDC_TIMER_0 = 0, /*!< LEDC timer 0 */
     LEDC_TIMER_0 = 0, /*!< LEDC timer 0 */
     LEDC_TIMER_1,     /*!< LEDC timer 1 */
     LEDC_TIMER_1,     /*!< LEDC timer 1 */
@@ -123,39 +125,6 @@ typedef enum {
     LEDC_FADE_MAX,
     LEDC_FADE_MAX,
 } ledc_fade_mode_t;
 } ledc_fade_mode_t;
 
 
-/**
- * @brief Configuration parameters of LEDC channel for ledc_channel_config function
- */
-typedef struct {
-    int gpio_num;                   /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16 */
-    ledc_mode_t speed_mode;         /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */
-    ledc_channel_t channel;         /*!< LEDC channel (0 - 7) */
-    ledc_intr_type_t intr_type;     /*!< configure interrupt, Fade interrupt enable  or Fade interrupt disable */
-    ledc_timer_t timer_sel;         /*!< Select the timer source of channel (0 - 3) */
-    uint32_t duty;                  /*!< LEDC channel duty, the range of duty setting is [0, (2**duty_resolution)] */
-    int hpoint;                     /*!< LEDC channel hpoint value, the max value is 0xfffff */
-    struct {
-        unsigned int output_invert: 1;/*!< Enable (1) or disable (0) gpio output invert */
-    } flags;                        /*!< LEDC flags */
-
-} ledc_channel_config_t;
-
-/**
- * @brief Configuration parameters of LEDC Timer timer for ledc_timer_config function
- */
-typedef struct {
-    ledc_mode_t speed_mode;                /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */
-    union {
-        ledc_timer_bit_t duty_resolution;  /*!< LEDC channel duty resolution */
-        ledc_timer_bit_t bit_num __attribute__((deprecated)); /*!< Deprecated in ESP-IDF 3.0. This is an alias to 'duty_resolution' for backward compatibility with ESP-IDF 2.1 */
-    };
-    ledc_timer_t  timer_num;               /*!< The timer source of channel (0 - 3) */
-    uint32_t freq_hz;                      /*!< LEDC timer frequency (Hz) */
-    ledc_clk_cfg_t clk_cfg;                /*!< Configure LEDC source clock.
-                                                For low speed channels and high speed channels, you can specify the source clock using LEDC_USE_REF_TICK, LEDC_USE_APB_CLK or LEDC_AUTO_CLK.
-                                                For low speed channels, you can also specify the source clock using LEDC_USE_RTC8M_CLK, in this case, all low speed channel's source clock must be RTC8M_CLK*/
-} ledc_timer_config_t;
-
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 60 - 32
components/hal/ledc_hal.c

@@ -1,16 +1,8 @@
-// Copyright 2019 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: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 
 // The HAL layer for LEDC (common part)
 // The HAL layer for LEDC (common part)
 
 
@@ -25,37 +17,73 @@ void ledc_hal_init(ledc_hal_context_t *hal, ledc_mode_t speed_mode)
     hal->speed_mode = speed_mode;
     hal->speed_mode = speed_mode;
 }
 }
 
 
+static inline ledc_clk_cfg_t ledc_hal_get_slow_clock_helper(ledc_hal_context_t *hal)
+{
+    ledc_slow_clk_sel_t slow_clk = LEDC_SLOW_CLK_APB;
+
+    ledc_hal_get_slow_clk_sel(hal, &slow_clk);
+
+    switch (slow_clk) {
+        case LEDC_SLOW_CLK_RTC8M:
+            return LEDC_USE_RTC8M_CLK;
+#if SOC_LEDC_SUPPORT_XTAL_CLOCK
+        case LEDC_SLOW_CLK_XTAL:
+            return LEDC_USE_XTAL_CLK;
+#endif
+        default:
+            return LEDC_USE_APB_CLK;
+    }
+}
+
 void ledc_hal_get_clk_cfg(ledc_hal_context_t *hal, ledc_timer_t timer_sel, ledc_clk_cfg_t *clk_cfg)
 void ledc_hal_get_clk_cfg(ledc_hal_context_t *hal, ledc_timer_t timer_sel, ledc_clk_cfg_t *clk_cfg)
 {
 {
-    ledc_clk_src_t clk_src = LEDC_APB_CLK;
+    /* Use the following variable to retrieve the clock source used by the LEDC
+     * hardware controler. */
+    ledc_clk_src_t clk_src;
+
+    /* Clock configuration to return to the driver. */
+    ledc_clk_cfg_t driver_clk = LEDC_USE_APB_CLK;
+
+    /* Get the timer-specific mux value. */
     ledc_hal_get_clock_source(hal, timer_sel, &clk_src);
     ledc_hal_get_clock_source(hal, timer_sel, &clk_src);
+#if SOC_LEDC_SUPPORT_REF_TICK
     if (clk_src == LEDC_REF_TICK) {
     if (clk_src == LEDC_REF_TICK) {
-        *clk_cfg = LEDC_USE_REF_TICK;
-    } else {
-        *clk_cfg = LEDC_USE_APB_CLK;
-        if (hal->speed_mode == LEDC_LOW_SPEED_MODE) {
-            ledc_slow_clk_sel_t slow_clk = LEDC_SLOW_CLK_APB;
-            ledc_hal_get_slow_clk_sel(hal, &slow_clk);
-            if (slow_clk == LEDC_SLOW_CLK_RTC8M) {
-                *clk_cfg = LEDC_USE_RTC8M_CLK;
-#if SOC_LEDC_SUPPORT_XTAL_CLOCK
-            } else if (slow_clk == LEDC_SLOW_CLK_XTAL) {
-                *clk_cfg = LEDC_USE_XTAL_CLK;
+        driver_clk = LEDC_USE_REF_TICK;
+    } else
 #endif
 #endif
-            }
-        }
+    /* If the timer-specific mux is not set to REF_TICK, it either means that:
+     * - The controler is in fast mode, and thus using APB clock (driver_clk
+     *   variable's default value)
+     * - The controler is in slow mode and so, using a global clock,
+     *   so we have to retrieve that clock here.
+     */
+    if (hal->speed_mode == LEDC_LOW_SPEED_MODE) {
+        /* If the source clock used by LEDC hardware is not REF_TICKS, it is
+         * necessary to retrieve the global clock source used. */
+        driver_clk = ledc_hal_get_slow_clock_helper(hal);
     }
     }
+
+    *clk_cfg = driver_clk;
 }
 }
 
 
 void ledc_hal_set_slow_clk(ledc_hal_context_t *hal, ledc_clk_cfg_t clk_cfg)
 void ledc_hal_set_slow_clk(ledc_hal_context_t *hal, ledc_clk_cfg_t clk_cfg)
 {
 {
     // For low speed channels, if RTC_8MCLK is used as the source clock, the `slow_clk_sel` register should be cleared, otherwise it should be set.
     // For low speed channels, if RTC_8MCLK is used as the source clock, the `slow_clk_sel` register should be cleared, otherwise it should be set.
-    ledc_slow_clk_sel_t slow_clk_sel = LEDC_SLOW_CLK_APB;
+    ledc_slow_clk_sel_t slow_clk_sel;
+
+    switch (clk_cfg) {
+        case LEDC_USE_RTC8M_CLK:
+            slow_clk_sel = LEDC_SLOW_CLK_RTC8M;
+            break;
 #if SOC_LEDC_SUPPORT_XTAL_CLOCK
 #if SOC_LEDC_SUPPORT_XTAL_CLOCK
-    slow_clk_sel = (clk_cfg == LEDC_USE_RTC8M_CLK) ? LEDC_SLOW_CLK_RTC8M :
-                                       ((clk_cfg == LEDC_USE_XTAL_CLK) ? LEDC_SLOW_CLK_XTAL : LEDC_SLOW_CLK_APB);
-#else
-    slow_clk_sel = (clk_cfg == LEDC_USE_RTC8M_CLK) ? LEDC_SLOW_CLK_RTC8M : LEDC_SLOW_CLK_APB;
+        case LEDC_USE_XTAL_CLK:
+            slow_clk_sel = LEDC_SLOW_CLK_XTAL;
+            break;
 #endif
 #endif
+        default:
+            slow_clk_sel = LEDC_SLOW_CLK_APB;
+            break;
+    }
+
     ledc_hal_set_slow_clk_sel(hal, slow_clk_sel);
     ledc_hal_set_slow_clk_sel(hal, slow_clk_sel);
 }
 }

+ 2 - 1
components/soc/esp32/include/soc/soc_caps.h

@@ -162,7 +162,8 @@
 #define SOC_LCD_I80_BUS_WIDTH      (24) /*!< Intel 8080 bus width */
 #define SOC_LCD_I80_BUS_WIDTH      (24) /*!< Intel 8080 bus width */
 
 
 /*-------------------------- LEDC CAPS ---------------------------------------*/
 /*-------------------------- LEDC CAPS ---------------------------------------*/
-#define SOC_LEDC_SUPPORT_HS_MODE  (1)
+#define SOC_LEDC_HAS_TIMER_SPECIFIC_MUX  (1)
+#define SOC_LEDC_SUPPORT_REF_TICK    (1)
 #define SOC_LEDC_SUPPORT_HS_MODE     (1)
 #define SOC_LEDC_SUPPORT_HS_MODE     (1)
 #define SOC_LEDC_CHANNEL_NUM         (8)
 #define SOC_LEDC_CHANNEL_NUM         (8)
 #define SOC_LEDC_TIMER_BIT_WIDE_NUM  (20)
 #define SOC_LEDC_TIMER_BIT_WIDE_NUM  (20)

+ 7 - 14
components/soc/esp32c3/include/soc/ledc_struct.h

@@ -1,16 +1,9 @@
-// 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: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
 #ifndef _SOC_LEDC_STRUCT_H_
 #ifndef _SOC_LEDC_STRUCT_H_
 #define _SOC_LEDC_STRUCT_H_
 #define _SOC_LEDC_STRUCT_H_
 #ifdef __cplusplus
 #ifdef __cplusplus
@@ -84,7 +77,7 @@ typedef volatile struct ledc_dev_s {
                     uint32_t clock_divider:    18;
                     uint32_t clock_divider:    18;
                     uint32_t pause:             1;
                     uint32_t pause:             1;
                     uint32_t rst:               1;
                     uint32_t rst:               1;
-                    uint32_t tick_sel:          1;
+                    uint32_t reserved24:        1;
                     uint32_t low_speed_update:  1;
                     uint32_t low_speed_update:  1;
                     uint32_t reserved26:        6;
                     uint32_t reserved26:        6;
                 };
                 };

+ 6 - 14
components/soc/esp32h2/include/soc/ledc_struct.h

@@ -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
+ */
 #ifndef _SOC_LEDC_STRUCT_H_
 #ifndef _SOC_LEDC_STRUCT_H_
 #define _SOC_LEDC_STRUCT_H_
 #define _SOC_LEDC_STRUCT_H_
 #ifdef __cplusplus
 #ifdef __cplusplus
@@ -84,7 +76,7 @@ typedef volatile struct ledc_dev_s {
                     uint32_t clock_divider:    18;
                     uint32_t clock_divider:    18;
                     uint32_t pause:             1;
                     uint32_t pause:             1;
                     uint32_t rst:               1;
                     uint32_t rst:               1;
-                    uint32_t tick_sel:          1;
+                    uint32_t reserved24:        1;
                     uint32_t low_speed_update:  1;
                     uint32_t low_speed_update:  1;
                     uint32_t reserved26:        6;
                     uint32_t reserved26:        6;
                 };
                 };

+ 2 - 0
components/soc/esp32s2/include/soc/soc_caps.h

@@ -155,6 +155,8 @@
 #define SOC_LCD_I80_BUS_WIDTH      (24) /*!< Intel 8080 bus width */
 #define SOC_LCD_I80_BUS_WIDTH      (24) /*!< Intel 8080 bus width */
 
 
 /*-------------------------- LEDC CAPS ---------------------------------------*/
 /*-------------------------- LEDC CAPS ---------------------------------------*/
+#define SOC_LEDC_HAS_TIMER_SPECIFIC_MUX  (1)
+#define SOC_LEDC_SUPPORT_REF_TICK    (1)
 #define SOC_LEDC_SUPPORT_XTAL_CLOCK  (1)
 #define SOC_LEDC_SUPPORT_XTAL_CLOCK  (1)
 #define SOC_LEDC_CHANNEL_NUM         (8)
 #define SOC_LEDC_CHANNEL_NUM         (8)
 #define SOC_LEDC_TIMER_BIT_WIDE_NUM  (14)
 #define SOC_LEDC_TIMER_BIT_WIDE_NUM  (14)

+ 7 - 12
components/soc/esp32s3/include/soc/ledc_caps.h

@@ -1,15 +1,8 @@
-// Copyright 2015-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: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 
 #pragma once
 #pragma once
 
 
@@ -17,6 +10,8 @@
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
+#define SOC_LEDC_HAS_TIMER_SPECIFIC_MUX  (1)
+#define SOC_LEDC_SUPPORT_REF_TICK    (1)
 #define SOC_LEDC_SUPPORT_XTAL_CLOCK  (1)
 #define SOC_LEDC_SUPPORT_XTAL_CLOCK  (1)
 #define SOC_LEDC_CHANNEL_NUM 8
 #define SOC_LEDC_CHANNEL_NUM 8
 #define SOC_LEDC_TIMER_BIT_WIDE_NUM  (14)
 #define SOC_LEDC_TIMER_BIT_WIDE_NUM  (14)

+ 1 - 1
components/soc/esp8684/include/soc/ledc_struct.h

@@ -76,7 +76,7 @@ typedef volatile struct ledc_dev_s {
                     uint32_t clock_divider                 :    18;  /*This register is used to configure the divisor for the divider in timer $x.; ; The least significant eight bits represent the fractional part.*/
                     uint32_t clock_divider                 :    18;  /*This register is used to configure the divisor for the divider in timer $x.; ; The least significant eight bits represent the fractional part.*/
                     uint32_t pause                         :    1;  /*This bit is used to suspend the counter in timer $x.*/
                     uint32_t pause                         :    1;  /*This bit is used to suspend the counter in timer $x.*/
                     uint32_t rst                           :    1;  /*This bit is used to reset timer $x. The counter will show 0 after reset.*/
                     uint32_t rst                           :    1;  /*This bit is used to reset timer $x. The counter will show 0 after reset.*/
-                    uint32_t tick_sel                      :    1;  /*This bit is used to select clock for timer $x. When this bit is set to 1 LEDC_APB_CLK_SEL[1:0] should be 1, otherwise the timer clock may be not accurate.; ; 1'h0: SLOW_CLK 1'h1: REF_TICK*/
+                    uint32_t reserved24                    :    1;  /*Reserved*/
                     uint32_t low_speed_update              :    1;  /*Set this bit to update LEDC_CLK_DIV_TIMER$x and LEDC_TIMER$x_DUTY_RES.*/
                     uint32_t low_speed_update              :    1;  /*Set this bit to update LEDC_CLK_DIV_TIMER$x and LEDC_TIMER$x_DUTY_RES.*/
                     uint32_t reserved26                    :    6;  /*Reserved*/
                     uint32_t reserved26                    :    6;  /*Reserved*/
                 };
                 };

+ 0 - 5
tools/ci/check_copyright_ignore.txt

@@ -1333,7 +1333,6 @@ components/hal/include/hal/i2s_types.h
 components/hal/include/hal/interrupt_controller_hal.h
 components/hal/include/hal/interrupt_controller_hal.h
 components/hal/include/hal/interrupt_controller_types.h
 components/hal/include/hal/interrupt_controller_types.h
 components/hal/include/hal/ledc_hal.h
 components/hal/include/hal/ledc_hal.h
-components/hal/include/hal/ledc_types.h
 components/hal/include/hal/mcpwm_hal.h
 components/hal/include/hal/mcpwm_hal.h
 components/hal/include/hal/mcpwm_types.h
 components/hal/include/hal/mcpwm_types.h
 components/hal/include/hal/memprot_types.h
 components/hal/include/hal/memprot_types.h
@@ -1370,7 +1369,6 @@ components/hal/include/hal/usb_types_private.h
 components/hal/include/hal/wdt_hal.h
 components/hal/include/hal/wdt_hal.h
 components/hal/include/hal/wdt_types.h
 components/hal/include/hal/wdt_types.h
 components/hal/interrupt_controller_hal.c
 components/hal/interrupt_controller_hal.c
-components/hal/ledc_hal.c
 components/hal/ledc_hal_iram.c
 components/hal/ledc_hal_iram.c
 components/hal/mcpwm_hal.c
 components/hal/mcpwm_hal.c
 components/hal/mpu_hal.c
 components/hal/mpu_hal.c
@@ -1928,7 +1926,6 @@ components/soc/esp32c3/include/soc/interrupt_core0_reg.h
 components/soc/esp32c3/include/soc/interrupt_reg.h
 components/soc/esp32c3/include/soc/interrupt_reg.h
 components/soc/esp32c3/include/soc/io_mux_reg.h
 components/soc/esp32c3/include/soc/io_mux_reg.h
 components/soc/esp32c3/include/soc/ledc_reg.h
 components/soc/esp32c3/include/soc/ledc_reg.h
-components/soc/esp32c3/include/soc/ledc_struct.h
 components/soc/esp32c3/include/soc/mmu.h
 components/soc/esp32c3/include/soc/mmu.h
 components/soc/esp32c3/include/soc/nrx_reg.h
 components/soc/esp32c3/include/soc/nrx_reg.h
 components/soc/esp32c3/include/soc/periph_defs.h
 components/soc/esp32c3/include/soc/periph_defs.h
@@ -2007,7 +2004,6 @@ components/soc/esp32h2/include/soc/interrupt_core0_reg.h
 components/soc/esp32h2/include/soc/interrupt_reg.h
 components/soc/esp32h2/include/soc/interrupt_reg.h
 components/soc/esp32h2/include/soc/io_mux_reg.h
 components/soc/esp32h2/include/soc/io_mux_reg.h
 components/soc/esp32h2/include/soc/ledc_reg.h
 components/soc/esp32h2/include/soc/ledc_reg.h
-components/soc/esp32h2/include/soc/ledc_struct.h
 components/soc/esp32h2/include/soc/mmu.h
 components/soc/esp32h2/include/soc/mmu.h
 components/soc/esp32h2/include/soc/nrx_reg.h
 components/soc/esp32h2/include/soc/nrx_reg.h
 components/soc/esp32h2/include/soc/periph_defs.h
 components/soc/esp32h2/include/soc/periph_defs.h
@@ -2206,7 +2202,6 @@ components/soc/esp32s3/include/soc/interrupt_core1_struct.h
 components/soc/esp32s3/include/soc/interrupt_reg.h
 components/soc/esp32s3/include/soc/interrupt_reg.h
 components/soc/esp32s3/include/soc/interrupt_struct.h
 components/soc/esp32s3/include/soc/interrupt_struct.h
 components/soc/esp32s3/include/soc/io_mux_reg.h
 components/soc/esp32s3/include/soc/io_mux_reg.h
-components/soc/esp32s3/include/soc/ledc_caps.h
 components/soc/esp32s3/include/soc/ledc_reg.h
 components/soc/esp32s3/include/soc/ledc_reg.h
 components/soc/esp32s3/include/soc/ledc_struct.h
 components/soc/esp32s3/include/soc/ledc_struct.h
 components/soc/esp32s3/include/soc/mmu.h
 components/soc/esp32s3/include/soc/mmu.h