Explorar o código

Merge branch 'feature/glitch_filter_h2' into 'master'

gpio: support glitch filter on esp32h2

Closes IDF-6286

See merge request espressif/esp-idf!22273
morris %!s(int64=2) %!d(string=hai) anos
pai
achega
e0c98da169

+ 13 - 24
components/driver/gpio/gpio_flex_glitch_filter.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -8,11 +8,11 @@
 #include "freertos/FreeRTOS.h"
 #include "esp_check.h"
 #include "glitch_filter_priv.h"
-#include "esp_private/esp_clk.h"
 #include "esp_private/io_mux.h"
 #include "soc/soc_caps.h"
 #include "hal/gpio_glitch_filter_ll.h"
 #include "esp_pm.h"
+#include "clk_tree.h"
 
 static const char *TAG = "gpio-filter";
 
@@ -136,31 +136,20 @@ esp_err_t gpio_new_flex_glitch_filter(const gpio_flex_glitch_filter_config_t *co
     int filter_id = filter->filter_id;
 
     // set clock source
-    uint32_t clk_freq_mhz = 0;
-    switch (config->clk_src) {
-#if SOC_GPIO_FILTER_CLK_SUPPORT_XTAL
-    case GLITCH_FILTER_CLK_SRC_XTAL:
-        clk_freq_mhz = esp_clk_xtal_freq() / 1000000;
-        break;
-#endif // SOC_GPIO_FILTER_CLK_SUPPORT_XTAL
-
-#if SOC_GPIO_FILTER_CLK_SUPPORT_PLL_F80M
-    case GLITCH_FILTER_CLK_SRC_PLL_F80M:
-        clk_freq_mhz = 80;
+    uint32_t clk_freq_hz = 0;
+    ESP_GOTO_ON_ERROR(clk_tree_src_get_freq_hz((soc_module_clk_t)config->clk_src, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_freq_hz),
+                      err, TAG, "get clock source frequency failed");
+
+    // create pm_lock according to different clock source
 #if CONFIG_PM_ENABLE
-        sprintf(filter->pm_lock_name, "filter_%d", filter_id); // e.g. filter_0
-        ret  = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, filter->pm_lock_name, &filter->pm_lock);
-        ESP_RETURN_ON_ERROR(ret, TAG, "create NO_LIGHT_SLEEP lock failed");
+    esp_pm_lock_type_t lock_type = ESP_PM_NO_LIGHT_SLEEP;
+    sprintf(filter->pm_lock_name, "filter_%d", filter_id); // e.g. filter_0
+    ESP_GOTO_ON_ERROR(esp_pm_lock_create(lock_type, 0, filter->pm_lock_name, &filter->pm_lock),
+                      err, TAG, "create pm_lock failed");
 #endif
-        break;
-#endif // SOC_GPIO_FILTER_CLK_SUPPORT_PLL_F80M
-    default:
-        ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid clock source");
-        break;
-    }
 
-    uint32_t window_thres_ticks = clk_freq_mhz * config->window_thres_ns / 1000;
-    uint32_t window_width_ticks = clk_freq_mhz * config->window_width_ns / 1000;
+    uint32_t window_thres_ticks = clk_freq_hz / 1000000 * config->window_thres_ns / 1000;
+    uint32_t window_width_ticks = clk_freq_hz / 1000000 * config->window_width_ns / 1000;
     ESP_GOTO_ON_FALSE(window_thres_ticks && window_thres_ticks <= window_width_ticks && window_width_ticks <= GPIO_LL_GLITCH_FILTER_MAX_WINDOW,
                       ESP_ERR_INVALID_ARG, err, TAG, "invalid or out of range window width/threshold");
 

+ 11 - 29
components/driver/gpio/gpio_pin_glitch_filter.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -10,7 +10,7 @@
 #include "esp_pm.h"
 #include "glitch_filter_priv.h"
 #include "hal/gpio_ll.h"
-#include "esp_private/esp_clk.h"
+#include "clk_tree.h"
 #include "esp_private/io_mux.h"
 
 static const char *TAG = "gpio-filter";
@@ -84,36 +84,18 @@ esp_err_t gpio_new_pin_glitch_filter(const gpio_pin_glitch_filter_config_t *conf
     filter = heap_caps_calloc(1, sizeof(gpio_pin_glitch_filter_t), FILTER_MEM_ALLOC_CAPS);
     ESP_GOTO_ON_FALSE(filter, ESP_ERR_NO_MEM, err, TAG, "no memory for pin glitch filter");
 
-    // set clock source
-    switch (config->clk_src) {
-#if SOC_GPIO_FILTER_CLK_SUPPORT_XTAL
-    case GLITCH_FILTER_CLK_SRC_XTAL:
-        break;
-#endif // SOC_GPIO_FILTER_CLK_SUPPORT_XTAL
-
-#if SOC_GPIO_FILTER_CLK_SUPPORT_PLL_F80M
-    case GLITCH_FILTER_CLK_SRC_PLL_F80M:
+    // create pm lock according to different clock source
 #if CONFIG_PM_ENABLE
-        sprintf(filter->pm_lock_name, "filter_io_%d", config->gpio_num); // e.g. filter_io_0
-        ret  = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, filter->pm_lock_name, &filter->pm_lock);
-        ESP_RETURN_ON_ERROR(ret, TAG, "create NO_LIGHT_SLEEP lock failed");
-#endif
-        break;
-#endif // SOC_GPIO_FILTER_CLK_SUPPORT_PLL_F80M
-
+    esp_pm_lock_type_t lock_type = ESP_PM_NO_LIGHT_SLEEP;
 #if SOC_GPIO_FILTER_CLK_SUPPORT_APB
-    case GLITCH_FILTER_CLK_SRC_APB:
-#if CONFIG_PM_ENABLE
-        sprintf(filter->pm_lock_name, "filter_io_%d", config->gpio_num); // e.g. filter_io_0
-        ret  = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, filter->pm_lock_name, &filter->pm_lock);
-        ESP_RETURN_ON_ERROR(ret, TAG, "create APB_FREQ_MAX lock failed");
-#endif
-        break;
-#endif // SOC_GPIO_FILTER_CLK_SUPPORT_APB
-    default:
-        ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid clock source");
-        break;
+    if (config->clk_src == GLITCH_FILTER_CLK_SRC_APB) {
+        lock_type = ESP_PM_APB_FREQ_MAX;
     }
+#endif // SOC_GPIO_FILTER_CLK_SUPPORT_APB
+    sprintf(filter->pm_lock_name, "filter_io_%d", config->gpio_num); // e.g. filter_io_0
+    ESP_GOTO_ON_ERROR(esp_pm_lock_create(lock_type, 0, filter->pm_lock_name, &filter->pm_lock),
+                      err, TAG, "create pm_lock failed");
+#endif // CONFIG_PM_ENABLE
 
     // Glitch filter's clock source is same to the IOMUX clock
     ESP_GOTO_ON_ERROR(io_mux_set_clock_source((soc_module_clk_t)(config->clk_src)), err, TAG, "set IO MUX clock source failed");

+ 21 - 2
components/esp_hw_support/port/esp32h2/io_mux.c

@@ -1,13 +1,32 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
 
+#include "freertos/FreeRTOS.h"
 #include "esp_private/io_mux.h"
+#include "hal/gpio_ll.h"
+
+static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
+static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter)
 
 esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
 {
-    // TODO: IDF-6286
+    bool clk_conflict = false;
+    // check is the IO MUX has been set to another clock source
+    portENTER_CRITICAL(&s_io_mux_spinlock);
+    if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
+        clk_conflict = true;
+    } else {
+        s_io_mux_clk_src = clk_src;
+    }
+    portEXIT_CRITICAL(&s_io_mux_spinlock);
+
+    if (clk_conflict) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    gpio_ll_iomux_set_clk_src(clk_src);
     return ESP_OK;
 }

+ 55 - 0
components/hal/esp32h2/include/hal/dedic_gpio_cpu_ll.h

@@ -0,0 +1,55 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include "riscv/csr.h"
+
+/*fast gpio*/
+#define CSR_GPIO_OEN_USER   0x803
+#define CSR_GPIO_IN_USER    0x804
+#define CSR_GPIO_OUT_USER   0x805
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__attribute__((always_inline))
+static inline void dedic_gpio_cpu_ll_enable_output(uint32_t mask)
+{
+    RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask);
+}
+
+static inline void dedic_gpio_cpu_ll_write_all(uint32_t value)
+{
+    RV_WRITE_CSR(CSR_GPIO_OUT_USER, value);
+}
+
+__attribute__((always_inline))
+static inline uint32_t dedic_gpio_cpu_ll_read_in(void)
+{
+    uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER);
+    return value;
+}
+
+__attribute__((always_inline))
+static inline uint32_t dedic_gpio_cpu_ll_read_out(void)
+{
+    uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER);
+    return value;
+}
+
+__attribute__((always_inline))
+static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value)
+{
+    RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value);
+    RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value));
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 66 - 0
components/hal/esp32h2/include/hal/gpio_glitch_filter_ll.h

@@ -0,0 +1,66 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/*******************************************************************************
+ * NOTICE
+ * The hal is not public api, don't use in application code.
+ * See readme.md in hal/include/hal/readme.md
+ ******************************************************************************/
+
+#pragma once
+
+#include <stdbool.h>
+#include "hal/assert.h"
+#include "soc/gpio_ext_struct.h"
+
+#define GPIO_LL_GLITCH_FILTER_MAX_WINDOW  64
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Enable GPIO glitch filter
+ *
+ * @param hw Glitch filter register base address
+ * @param filter_idx Glitch filter index
+ * @param enable True to enable, false to disable
+ */
+static inline void gpio_ll_glitch_filter_enable(gpio_glitch_filter_dev_t *hw, uint32_t filter_idx, bool enable)
+{
+    hw->glitch_filter_chn[filter_idx].filter_chn_en = enable;
+}
+
+/**
+ * @brief Set the input GPIO for the glitch filter
+ *
+ * @param hw Glitch filter register base address
+ * @param filter_idx Glitch filter index
+ * @param gpio_num GPIO number
+ */
+static inline void gpio_ll_glitch_filter_set_gpio(gpio_glitch_filter_dev_t *hw, uint32_t filter_idx, uint32_t gpio_num)
+{
+    hw->glitch_filter_chn[filter_idx].filter_chn_input_io_num = gpio_num;
+}
+
+/**
+ * @brief Set the coefficient of the glitch filter window
+ *
+ * @param hw Glitch filter register base address
+ * @param filter_idx Glitch filter index
+ * @param window_width Window width, in IOMUX clock ticks
+ * @param window_threshold Window threshold, in IOMUX clock ticks
+ */
+static inline void gpio_ll_glitch_filter_set_window_coeff(gpio_glitch_filter_dev_t *hw, uint32_t filter_idx, uint32_t window_width, uint32_t window_thres)
+{
+    HAL_ASSERT(window_thres <= window_width);
+    hw->glitch_filter_chn[filter_idx].filter_chn_window_width = window_width - 1;
+    hw->glitch_filter_chn[filter_idx].filter_chn_window_thres = window_thres - 1;
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 0 - 8
components/soc/esp32c6/include/soc/Kconfig.soc_caps.in

@@ -359,14 +359,6 @@ config SOC_GPIO_FLEX_GLITCH_FILTER_NUM
     int
     default 8
 
-config SOC_GPIO_FILTER_CLK_SUPPORT_XTAL
-    bool
-    default y
-
-config SOC_GPIO_FILTER_CLK_SUPPORT_PLL_F80M
-    bool
-    default y
-
 config SOC_GPIO_SUPPORT_ETM
     bool
     default y

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

@@ -161,8 +161,6 @@
 #define SOC_GPIO_PIN_COUNT                 31
 #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1
 #define SOC_GPIO_FLEX_GLITCH_FILTER_NUM    8
-#define SOC_GPIO_FILTER_CLK_SUPPORT_XTAL 1
-#define SOC_GPIO_FILTER_CLK_SUPPORT_PLL_F80M 1
 
 // GPIO peripheral has the ETM extension
 #define SOC_GPIO_SUPPORT_ETM          1

+ 12 - 0
components/soc/esp32h2/include/soc/Kconfig.soc_caps.in

@@ -3,6 +3,10 @@
 # using gen_soc_caps_kconfig.py, do not edit manually
 #####################################################
 
+config SOC_DEDICATED_GPIO_SUPPORTED
+    bool
+    default y
+
 config SOC_UART_SUPPORTED
     bool
     default y
@@ -291,6 +295,14 @@ config SOC_GPIO_PIN_COUNT
     int
     default 28
 
+config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
+    bool
+    default y
+
+config SOC_GPIO_FLEX_GLITCH_FILTER_NUM
+    int
+    default 8
+
 config SOC_GPIO_SUPPORT_ETM
     bool
     default y

+ 4 - 0
components/soc/esp32h2/include/soc/clk_tree_defs.h

@@ -371,7 +371,11 @@ typedef enum {
 typedef enum {
     GLITCH_FILTER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,         /*!< Select XTAL clock as the source clock */
     GLITCH_FILTER_CLK_SRC_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_F48M clock as the source clock */
+#if CONFIG_IDF_ENV_FPGA
+    GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,      /*!< Select XTAL as the default clock choice */
+#else
     GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F48M,  /*!< Select PLL_F48M clock as the default clock choice */
+#endif
 } soc_periph_glitch_filter_clk_src_t;
 
 //////////////////////////////////////////////////TWAI/////////////////////////////////////////////////////////////////

+ 8 - 8
components/soc/esp32h2/include/soc/gpio_ext_struct.h

@@ -112,22 +112,22 @@ typedef union {
  */
 typedef union {
     struct {
-        /** filter_ch0_en : R/W; bitpos: [0]; default: 0;
+        /** filter_chn_en : R/W; bitpos: [0]; default: 0;
          *  Glitch Filter channel enable bit.
          */
-        uint32_t filter_ch0_en:1;
-        /** filter_ch0_input_io_num : R/W; bitpos: [6:1]; default: 0;
+        uint32_t filter_chn_en:1;
+        /** filter_chn_input_io_num : R/W; bitpos: [6:1]; default: 0;
          *  Glitch Filter input io number.
          */
-        uint32_t filter_ch0_input_io_num:6;
-        /** filter_ch0_window_thres : R/W; bitpos: [12:7]; default: 0;
+        uint32_t filter_chn_input_io_num:6;
+        /** filter_chn_window_thres : R/W; bitpos: [12:7]; default: 0;
          *  Glitch Filter window threshold.
          */
-        uint32_t filter_ch0_window_thres:6;
-        /** filter_ch0_window_width : R/W; bitpos: [18:13]; default: 0;
+        uint32_t filter_chn_window_thres:6;
+        /** filter_chn_window_width : R/W; bitpos: [18:13]; default: 0;
          *  Glitch Filter window width.
          */
-        uint32_t filter_ch0_window_width:6;
+        uint32_t filter_chn_window_width:6;
         uint32_t reserved_19:13;
     };
     uint32_t val;

+ 5 - 4
components/soc/esp32h2/include/soc/soc_caps.h

@@ -26,7 +26,7 @@
 
 /*-------------------------- COMMON CAPS ---------------------------------------*/
 // #define SOC_ADC_SUPPORTED               1 // TODO: IDF-6214
-// #define SOC_DEDICATED_GPIO_SUPPORTED    1 // TODO: IDF-6241
+#define SOC_DEDICATED_GPIO_SUPPORTED    1
 #define SOC_UART_SUPPORTED              1
 #define SOC_GDMA_SUPPORTED              1
 #define SOC_ASYNC_MEMCPY_SUPPORTED      1
@@ -153,8 +153,10 @@
 
 /*-------------------------- GPIO CAPS ---------------------------------------*/
 // ESP32-H2 has 1 GPIO peripheral
-#define SOC_GPIO_PORT               (1U)
-#define SOC_GPIO_PIN_COUNT          (28)
+#define SOC_GPIO_PORT                        1U
+#define SOC_GPIO_PIN_COUNT                   28
+#define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER   1
+#define SOC_GPIO_FLEX_GLITCH_FILTER_NUM      8
 
 // GPIO peripheral has the ETM extension
 #define SOC_GPIO_SUPPORT_ETM          1
@@ -173,7 +175,6 @@
 // digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_0~6. GPIO_NUM_15~27)
 #define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000000FFF807FULL
 
-// TODO: IDF-6241
 /*-------------------------- Dedicated GPIO CAPS -----------------------------*/
 #define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */
 #define SOC_DEDIC_GPIO_IN_CHANNELS_NUM  (8) /*!< 8 inward channels on each CPU core */

+ 2 - 2
examples/peripherals/dedicated_gpio/soft_i2c/README.md

@@ -1,5 +1,5 @@
-| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
-| ----------------- | -------- | -------- | -------- | -------- | -------- |
+| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
+| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- |
 
 # Example: Software I2C Master via Dedicated/Fast GPIOs
 

+ 2 - 2
examples/peripherals/dedicated_gpio/soft_spi/README.md

@@ -1,5 +1,5 @@
-| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 |
-| ----------------- | -------- | -------- | -------- |
+| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 |
+| ----------------- | -------- | -------- | -------- | -------- |
 
 # Example: SPI software emulation using dedicated/fast GPIOs
 

+ 2 - 2
examples/peripherals/dedicated_gpio/soft_uart/README.md

@@ -1,5 +1,5 @@
-| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 |
-| ----------------- | -------- | -------- | -------- |
+| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 |
+| ----------------- | -------- | -------- | -------- | -------- |
 
 # Example: UART software emulation using dedicated/fast GPIOs