diff --git a/components/driver/gpio/gpio_flex_glitch_filter.c b/components/driver/gpio/gpio_flex_glitch_filter.c index 693bc208b2..a5661422d0 100644 --- a/components/driver/gpio/gpio_flex_glitch_filter.c +++ b/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 + 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"); -#if SOC_GPIO_FILTER_CLK_SUPPORT_PLL_F80M - case GLITCH_FILTER_CLK_SRC_PLL_F80M: - clk_freq_mhz = 80; + // 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"); diff --git a/components/driver/gpio/gpio_pin_glitch_filter.c b/components/driver/gpio/gpio_pin_glitch_filter.c index 3ea6badf6d..2d4ac96010 100644 --- a/components/driver/gpio/gpio_pin_glitch_filter.c +++ b/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"); diff --git a/components/esp_hw_support/port/esp32h2/io_mux.c b/components/esp_hw_support/port/esp32h2/io_mux.c index 28d99fa12c..a621deb8a3 100644 --- a/components/esp_hw_support/port/esp32h2/io_mux.c +++ b/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; } diff --git a/components/hal/esp32h2/include/hal/dedic_gpio_cpu_ll.h b/components/hal/esp32h2/include/hal/dedic_gpio_cpu_ll.h new file mode 100644 index 0000000000..e7c424a5d9 --- /dev/null +++ b/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 +#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 diff --git a/components/hal/esp32h2/include/hal/gpio_glitch_filter_ll.h b/components/hal/esp32h2/include/hal/gpio_glitch_filter_ll.h new file mode 100644 index 0000000000..7a577c296d --- /dev/null +++ b/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 +#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 diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 274c0a9e57..0b5b646967 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/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 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index ef98f85453..e667e7d8f0 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/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 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 1a26c84d32..5190279fa2 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/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 @@ -283,6 +287,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 diff --git a/components/soc/esp32h2/include/soc/clk_tree_defs.h b/components/soc/esp32h2/include/soc/clk_tree_defs.h index 6d77bda78c..32986416f9 100644 --- a/components/soc/esp32h2/include/soc/clk_tree_defs.h +++ b/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///////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32h2/include/soc/gpio_ext_struct.h b/components/soc/esp32h2/include/soc/gpio_ext_struct.h index 5ee44e94ea..d0388d3ad0 100644 --- a/components/soc/esp32h2/include/soc/gpio_ext_struct.h +++ b/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; diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index cfc57af1f7..2fc5c4ff4d 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/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 @@ -154,8 +154,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 @@ -174,7 +176,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 */ diff --git a/examples/peripherals/dedicated_gpio/soft_i2c/README.md b/examples/peripherals/dedicated_gpio/soft_i2c/README.md index ba7e613a46..ef4866a055 100644 --- a/examples/peripherals/dedicated_gpio/soft_i2c/README.md +++ b/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 diff --git a/examples/peripherals/dedicated_gpio/soft_spi/README.md b/examples/peripherals/dedicated_gpio/soft_spi/README.md index 2eab42366d..f7ec02a977 100644 --- a/examples/peripherals/dedicated_gpio/soft_spi/README.md +++ b/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 diff --git a/examples/peripherals/dedicated_gpio/soft_uart/README.md b/examples/peripherals/dedicated_gpio/soft_uart/README.md index 085feaa7e5..bfb18d6dca 100644 --- a/examples/peripherals/dedicated_gpio/soft_uart/README.md +++ b/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