From 672ac58ad5c0bb00cb8aa5838cf39c292d3c4987 Mon Sep 17 00:00:00 2001 From: morris Date: Fri, 16 Dec 2022 15:37:02 +0800 Subject: [PATCH 1/4] io_mux: can set different clock source --- components/esp_hw_support/CMakeLists.txt | 3 +- .../include/esp_private/io_mux.h | 31 ++++++++++++++++++ components/esp_hw_support/port/esp32/io_mux.c | 13 ++++++++ .../esp_hw_support/port/esp32c2/io_mux.c | 13 ++++++++ .../esp_hw_support/port/esp32c3/io_mux.c | 13 ++++++++ .../esp_hw_support/port/esp32c6/io_mux.c | 32 +++++++++++++++++++ .../esp_hw_support/port/esp32h2/io_mux.c | 13 ++++++++ .../esp_hw_support/port/esp32h4/io_mux.c | 13 ++++++++ .../esp_hw_support/port/esp32s2/io_mux.c | 13 ++++++++ .../esp_hw_support/port/esp32s3/io_mux.c | 13 ++++++++ .../hal/esp32c6/include/hal/clk_tree_ll.h | 2 +- components/hal/esp32c6/include/hal/gpio_ll.h | 22 +++++++++++++ 12 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 components/esp_hw_support/include/esp_private/io_mux.h create mode 100644 components/esp_hw_support/port/esp32/io_mux.c create mode 100644 components/esp_hw_support/port/esp32c2/io_mux.c create mode 100644 components/esp_hw_support/port/esp32c3/io_mux.c create mode 100644 components/esp_hw_support/port/esp32c6/io_mux.c create mode 100644 components/esp_hw_support/port/esp32h2/io_mux.c create mode 100644 components/esp_hw_support/port/esp32h4/io_mux.c create mode 100644 components/esp_hw_support/port/esp32s2/io_mux.c create mode 100644 components/esp_hw_support/port/esp32s3/io_mux.c diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 956f768668..5579e80906 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -25,7 +25,8 @@ if(NOT BOOTLOADER_BUILD) "sleep_gpio.c" "sleep_mac_bb.c" "regi2c_ctrl.c" - "adc_share_hw_ctrl.c") + "adc_share_hw_ctrl.c" + "port/${target}/io_mux.c") if(NOT CONFIG_IDF_TARGET_ESP32 AND NOT CONFIG_IDF_TARGET_ESP32S2) list(APPEND srcs "sleep_retention.c") diff --git a/components/esp_hw_support/include/esp_private/io_mux.h b/components/esp_hw_support/include/esp_private/io_mux.h new file mode 100644 index 0000000000..3c3056d762 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/io_mux.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set the clock source for IO MUX + * + * @note IO MUX clock is shared by submodules like SDM, Glitch Filter. + * The submodule drivers should call this function to detect if the user set the clock differently. + * + * @param clk_src The clock source for IO MUX + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: The IO MUX has been set to another clock source + */ +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/port/esp32/io_mux.c b/components/esp_hw_support/port/esp32/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c2/io_mux.c b/components/esp_hw_support/port/esp32c2/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32c2/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c3/io_mux.c b/components/esp_hw_support/port/esp32c3/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32c3/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32c6/io_mux.c b/components/esp_hw_support/port/esp32c6/io_mux.c new file mode 100644 index 0000000000..ea7446b2ba --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/io_mux.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2022 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) +{ + 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/esp_hw_support/port/esp32h2/io_mux.c b/components/esp_hw_support/port/esp32h2/io_mux.c new file mode 100644 index 0000000000..28d99fa12c --- /dev/null +++ b/components/esp_hw_support/port/esp32h2/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // TODO: IDF-6286 + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32h4/io_mux.c b/components/esp_hw_support/port/esp32h4/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32h4/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32s2/io_mux.c b/components/esp_hw_support/port/esp32s2/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32s2/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/esp_hw_support/port/esp32s3/io_mux.c b/components/esp_hw_support/port/esp32s3/io_mux.c new file mode 100644 index 0000000000..d17a300030 --- /dev/null +++ b/components/esp_hw_support/port/esp32s3/io_mux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/io_mux.h" + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + // IO MUX clock source is not selectable + return ESP_OK; +} diff --git a/components/hal/esp32c6/include/hal/clk_tree_ll.h b/components/hal/esp32c6/include/hal/clk_tree_ll.h index c5fb811055..f64cf3cefd 100644 --- a/components/hal/esp32c6/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c6/include/hal/clk_tree_ll.h @@ -63,7 +63,7 @@ typedef struct { static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void) { SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C | - PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); + PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG) ; } diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index 05b7b9445b..c787097bd0 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -23,6 +23,8 @@ #include "soc/lp_io_struct.h" #include "soc/pmu_reg.h" #include "soc/usb_serial_jtag_reg.h" +#include "soc/pcr_struct.h" +#include "soc/clk_tree_defs.h" #include "hal/gpio_types.h" #include "hal/assert.h" @@ -454,6 +456,26 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, gpio_ll_iomux_func_sel(IO_MUX_GPIO0_REG + (gpio_num * 4), func); } +/** + * @brief Set clock source of IO MUX module + * + * @param src IO MUX clock source (only a subset of soc_module_clk_t values are valid) + */ +static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) +{ + switch (src) { + case SOC_MOD_CLK_XTAL: + PCR.iomux_clk_conf.iomux_func_clk_sel = 3; + break; + case SOC_MOD_CLK_PLL_F80M: + PCR.iomux_clk_conf.iomux_func_clk_sel = 1; + break; + default: + // Unsupported IO_MUX clock source + HAL_ASSERT(false); + } +} + /** * @brief Enable GPIO pin to use sleep mode pin functions during light sleep. * From cbe297e5a090fbb71fe9bdd888f58fbb2ff0f8a2 Mon Sep 17 00:00:00 2001 From: morris Date: Tue, 13 Dec 2022 14:39:38 +0800 Subject: [PATCH 2/4] sdm: support derive clock source from IO MUX --- components/driver/sdm.c | 21 +++++++++++++++++++ .../soc/esp32/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32/include/soc/soc_caps.h | 1 + .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c3/include/soc/soc_caps.h | 1 + .../esp32c6/include/soc/Kconfig.soc_caps.in | 8 +++++++ .../soc/esp32c6/include/soc/clk_tree_defs.h | 10 ++++----- components/soc/esp32c6/include/soc/soc_caps.h | 6 ++++-- .../esp32h2/include/soc/Kconfig.soc_caps.in | 8 +++++++ components/soc/esp32h2/include/soc/soc_caps.h | 6 ++++-- .../esp32h4/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32h4/include/soc/soc_caps.h | 1 + .../esp32s2/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s2/include/soc/soc_caps.h | 1 + .../esp32s3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s3/include/soc/soc_caps.h | 1 + .../test_utils/ref_clock_impl_rmt_pcnt.c | 2 +- 17 files changed, 76 insertions(+), 10 deletions(-) diff --git a/components/driver/sdm.c b/components/driver/sdm.c index 6a0830ca3a..fb98b6ca24 100644 --- a/components/driver/sdm.c +++ b/components/driver/sdm.c @@ -26,6 +26,7 @@ #include "hal/sdm_ll.h" #include "soc/sdm_periph.h" #include "esp_private/esp_clk.h" +#include "esp_private/io_mux.h" #if CONFIG_SDM_CTRL_FUNC_IN_IRAM #define SDM_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) @@ -209,6 +210,7 @@ esp_err_t sdm_new_channel(const sdm_config_t *config, sdm_channel_handle_t *ret_ ESP_GOTO_ON_FALSE(group->clk_src == 0 || group->clk_src == config->clk_src, ESP_ERR_INVALID_ARG, err, TAG, "clock source conflict"); uint32_t src_clk_hz = 0; switch (config->clk_src) { +#if SOC_SDM_CLK_SUPPORT_APB case SDM_CLK_SRC_APB: src_clk_hz = esp_clk_apb_freq(); #if CONFIG_PM_ENABLE @@ -217,12 +219,31 @@ esp_err_t sdm_new_channel(const sdm_config_t *config, sdm_channel_handle_t *ret_ ESP_RETURN_ON_ERROR(ret, TAG, "create APB_FREQ_MAX lock failed"); #endif break; +#endif // SOC_SDM_CLK_SUPPORT_APB +#if SOC_SDM_CLK_SUPPORT_XTAL + case SDM_CLK_SRC_XTAL: + src_clk_hz = esp_clk_xtal_freq(); + break; +#endif // SOC_SDM_CLK_SUPPORT_XTAL +#if SOC_SDM_CLK_SUPPORT_PLL_F80M + case SDM_CLK_SRC_PLL_F80M: + src_clk_hz = 80 * 1000 * 1000; +#if CONFIG_PM_ENABLE + sprintf(chan->pm_lock_name, "sdm_%d_%d", group->group_id, chan_id); // e.g. sdm_0_0 + ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, chan->pm_lock_name, &chan->pm_lock); + ESP_RETURN_ON_ERROR(ret, TAG, "create NO_LIGHT_SLEEP lock failed"); +#endif + break; +#endif // SOC_SDM_CLK_SUPPORT_PLL_F80M default: ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "clock source %d is not support", config->clk_src); break; } group->clk_src = config->clk_src; + // SDM clock comes from IO MUX, but IO MUX clock might be shared with other submodules as well + ESP_GOTO_ON_ERROR(io_mux_set_clock_source((soc_module_clk_t)(group->clk_src)), err, TAG, "set IO MUX clock source failed"); + // GPIO configuration gpio_config_t gpio_conf = { .intr_type = GPIO_INTR_DISABLE, diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index 3c1e3ebb8b..b231f66e3e 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -523,6 +523,10 @@ config SOC_SDM_CHANNELS_PER_GROUP int default 8 +config SOC_SDM_CLK_SUPPORT_APB + bool + default y + config SOC_SPI_HD_BOTH_INOUT_SUPPORTED bool default y diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index c99948a251..9ea655428a 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -261,6 +261,7 @@ /*-------------------------- Sigma Delta Modulator CAPS -----------------*/ #define SOC_SDM_GROUPS 1U #define SOC_SDM_CHANNELS_PER_GROUP 8 +#define SOC_SDM_CLK_SUPPORT_APB 1 /*-------------------------- SPI CAPS ----------------------------------------*/ #define SOC_SPI_HD_BOTH_INOUT_SUPPORTED 1 //Support enabling MOSI and MISO phases together under Halfduplex mode diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 871bb7d359..761e4eb823 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -551,6 +551,10 @@ config SOC_SDM_CHANNELS_PER_GROUP int default 4 +config SOC_SDM_CLK_SUPPORT_APB + bool + default y + config SOC_SPI_PERIPH_NUM int default 2 diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index e8b25f27ca..6b17c23afc 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -262,6 +262,7 @@ /*-------------------------- Sigma Delta Modulator CAPS -----------------*/ #define SOC_SDM_GROUPS 1U #define SOC_SDM_CHANNELS_PER_GROUP 4 +#define SOC_SDM_CLK_SUPPORT_APB 1 /*-------------------------- SPI CAPS ----------------------------------------*/ #define SOC_SPI_PERIPH_NUM 2 diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 085a860374..0840ff0105 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -659,6 +659,14 @@ config SOC_SDM_CHANNELS_PER_GROUP int default 4 +config SOC_SDM_CLK_SUPPORT_PLL_F80M + bool + default y + +config SOC_SDM_CLK_SUPPORT_XTAL + bool + default y + config SOC_SPI_PERIPH_NUM int default 2 diff --git a/components/soc/esp32c6/include/soc/clk_tree_defs.h b/components/soc/esp32c6/include/soc/clk_tree_defs.h index 422a77f6fd..86ec1608c0 100644 --- a/components/soc/esp32c6/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c6/include/soc/clk_tree_defs.h @@ -101,7 +101,7 @@ typedef enum { } soc_rtc_fast_clk_src_t; // Naming convention: SOC_MOD_CLK_{[upstream]clock_name}_[attr] -// {[upstream]clock_name}: APB, (BB)PLL, etc. +// {[upstream]clock_name}: XTAL, (BB)PLL, etc. // [attr] - optional: FAST, SLOW, D, F /** * @brief Supported clock sources for modules (CPU, peripherals, RTC, etc.) @@ -115,7 +115,6 @@ typedef enum { SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */ SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or RC_FAST_D256 by configuring soc_rtc_slow_clk_src_t */ // For digital domain: peripherals, WIFI, BLE - SOC_MOD_CLK_APB, /*!< APB_CLK is highly dependent on the CPU_CLK source */ // TODO: IDF-6343 This should be removed on ESP32C6! Impacts on all following peripheral drivers! SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL, and has a fixed frequency of 80MHz */ SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from PLL, and has a fixed frequency of 160MHz */ SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from PLL, and has a fixed frequency of 240MHz */ @@ -291,14 +290,15 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of SDM */ -#define SOC_SDM_CLKS {SOC_MOD_CLK_APB} +#define SOC_SDM_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL} /** * @brief Sigma Delta Modulator clock source */ typedef enum { - SDM_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */ - SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */ + SDM_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL clock as the source clock */ + SDM_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the source clock */ + SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the default clock choice */ } soc_periph_sdm_clk_src_t; //////////////////////////////////////////////////TWAI///////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 4b78381fb4..4e65652589 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -309,8 +309,10 @@ #define SOC_SHA_SUPPORT_SHA256 (1) /*-------------------------- Sigma Delta Modulator CAPS -----------------*/ -#define SOC_SDM_GROUPS 1U -#define SOC_SDM_CHANNELS_PER_GROUP 4 +#define SOC_SDM_GROUPS 1U +#define SOC_SDM_CHANNELS_PER_GROUP 4 +#define SOC_SDM_CLK_SUPPORT_PLL_F80M 1 +#define SOC_SDM_CLK_SUPPORT_XTAL 1 // TODO: IDF-5334 (Copy from esp32c3, need check) /*-------------------------- SPI CAPS ----------------------------------------*/ diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 58be5ab21a..f727b2e4d8 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -511,6 +511,14 @@ config SOC_SDM_CHANNELS_PER_GROUP int default 4 +config SOC_SDM_CLK_SUPPORT_PLL_F80M + bool + default y + +config SOC_SDM_CLK_SUPPORT_XTAL + bool + default y + config SOC_SPI_PERIPH_NUM int default 2 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 562fdbbc81..bd3ba808fc 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -292,8 +292,10 @@ // TODO: IDF-6220 /*-------------------------- Sigma Delta Modulator CAPS -----------------*/ -#define SOC_SDM_GROUPS 1U -#define SOC_SDM_CHANNELS_PER_GROUP 4 +#define SOC_SDM_GROUPS 1U +#define SOC_SDM_CHANNELS_PER_GROUP 4 +#define SOC_SDM_CLK_SUPPORT_PLL_F80M 1 +#define SOC_SDM_CLK_SUPPORT_XTAL 1 // TODO: IDF-6245 (Copy from esp32c6, need check) /*-------------------------- SPI CAPS ----------------------------------------*/ diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index 6fba2353c0..8332c22713 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -531,6 +531,10 @@ config SOC_SDM_CHANNELS_PER_GROUP int default 4 +config SOC_SDM_CLK_SUPPORT_APB + bool + default y + config SOC_SPI_PERIPH_NUM int default 2 diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index da112d4597..743b02647a 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -270,6 +270,7 @@ /*-------------------------- Sigma Delta Modulator CAPS -----------------*/ #define SOC_SDM_GROUPS 1U #define SOC_SDM_CHANNELS_PER_GROUP 4 +#define SOC_SDM_CLK_SUPPORT_APB 1 /*-------------------------- SPI CAPS ----------------------------------------*/ #define SOC_SPI_PERIPH_NUM 2 diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 352f0622dd..2fe4d9a5ae 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -547,6 +547,10 @@ config SOC_SDM_CHANNELS_PER_GROUP int default 8 +config SOC_SDM_CLK_SUPPORT_APB + bool + default y + config SOC_SPI_HD_BOTH_INOUT_SUPPORTED bool default y diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 5fc78fd97d..106f17885c 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -244,6 +244,7 @@ /*-------------------------- Sigma Delta Modulator CAPS -----------------*/ #define SOC_SDM_GROUPS 1U #define SOC_SDM_CHANNELS_PER_GROUP 8 +#define SOC_SDM_CLK_SUPPORT_APB 1 /*-------------------------- SPI CAPS ----------------------------------------*/ #define SOC_SPI_HD_BOTH_INOUT_SUPPORTED 1 //Support enabling MOSI and MISO phases together under Halfduplex mode diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 7a108d03ca..b0bdeb62e5 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -667,6 +667,10 @@ config SOC_SDM_CHANNELS_PER_GROUP int default 8 +config SOC_SDM_CLK_SUPPORT_APB + bool + default y + config SOC_SPI_PERIPH_NUM int default 3 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 0ae868a7f5..c454eec821 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -275,6 +275,7 @@ /*-------------------------- Sigma Delta Modulator CAPS -----------------*/ #define SOC_SDM_GROUPS 1 #define SOC_SDM_CHANNELS_PER_GROUP 8 +#define SOC_SDM_CLK_SUPPORT_APB 1 /*-------------------------- SPI CAPS ----------------------------------------*/ #define SOC_SPI_PERIPH_NUM 3 diff --git a/tools/unit-test-app/components/test_utils/ref_clock_impl_rmt_pcnt.c b/tools/unit-test-app/components/test_utils/ref_clock_impl_rmt_pcnt.c index 30710ab61b..f747b25fed 100644 --- a/tools/unit-test-app/components/test_utils/ref_clock_impl_rmt_pcnt.c +++ b/tools/unit-test-app/components/test_utils/ref_clock_impl_rmt_pcnt.c @@ -33,11 +33,11 @@ #define REF_CLOCK_GPIO 0 // GPIO used to combine RMT out signal with PCNT input signal #define REF_CLOCK_PRESCALER_MS 30 // PCNT high threshold interrupt fired every 30ms +// peripheral driver handles static pcnt_unit_handle_t s_pcnt_unit; static pcnt_channel_handle_t s_pcnt_chan; static rmt_channel_handle_t s_rmt_chan; static rmt_encoder_handle_t s_rmt_encoder; -static volatile uint32_t s_milliseconds; void ref_clock_init(void) { From ca1b182b2531f72be643609038dded9eee281b0a Mon Sep 17 00:00:00 2001 From: morris Date: Fri, 16 Dec 2022 15:59:08 +0800 Subject: [PATCH 3/4] glitch_filter: support derive clock source form IO MUX --- components/driver/gpio/glitch_filter_priv.h | 2 + .../driver/gpio/gpio_flex_glitch_filter.c | 64 ++++++++++++++--- .../driver/gpio/gpio_pin_glitch_filter.c | 71 ++++++++++++++++++- .../driver/include/driver/gpio_filter.h | 3 + .../test_apps/gpio/main/test_gpio_filter.c | 40 ++++++----- .../hal/include/hal/glitch_filter_types.h | 24 +++++++ .../esp32c2/include/soc/Kconfig.soc_caps.in | 4 ++ .../soc/esp32c2/include/soc/clk_tree_defs.h | 18 ++++- components/soc/esp32c2/include/soc/soc_caps.h | 1 + .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 ++ .../soc/esp32c3/include/soc/clk_tree_defs.h | 18 ++++- components/soc/esp32c3/include/soc/soc_caps.h | 1 + .../esp32c6/include/soc/Kconfig.soc_caps.in | 8 +++ .../soc/esp32c6/include/soc/clk_tree_defs.h | 23 +++++- components/soc/esp32c6/include/soc/soc_caps.h | 2 + .../soc/esp32h2/include/soc/clk_tree_defs.h | 19 ++++- .../esp32h4/include/soc/Kconfig.soc_caps.in | 4 ++ .../soc/esp32h4/include/soc/clk_tree_defs.h | 18 ++++- components/soc/esp32h4/include/soc/soc_caps.h | 1 + .../esp32s2/include/soc/Kconfig.soc_caps.in | 4 ++ .../soc/esp32s2/include/soc/clk_tree_defs.h | 18 ++++- components/soc/esp32s2/include/soc/soc_caps.h | 1 + .../esp32s3/include/soc/Kconfig.soc_caps.in | 4 ++ .../soc/esp32s3/include/soc/clk_tree_defs.h | 18 ++++- components/soc/esp32s3/include/soc/soc_caps.h | 1 + 25 files changed, 335 insertions(+), 36 deletions(-) create mode 100644 components/hal/include/hal/glitch_filter_types.h diff --git a/components/driver/gpio/glitch_filter_priv.h b/components/driver/gpio/glitch_filter_priv.h index 5d05244e44..e9d14bb871 100644 --- a/components/driver/gpio/glitch_filter_priv.h +++ b/components/driver/gpio/glitch_filter_priv.h @@ -13,6 +13,8 @@ #define FILTER_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT +#define GLITCH_FILTER_PM_LOCK_NAME_LEN_MAX 16 + #ifdef __cplusplus extern "C" { #endif diff --git a/components/driver/gpio/gpio_flex_glitch_filter.c b/components/driver/gpio/gpio_flex_glitch_filter.c index a7105805df..693bc208b2 100644 --- a/components/driver/gpio/gpio_flex_glitch_filter.c +++ b/components/driver/gpio/gpio_flex_glitch_filter.c @@ -9,8 +9,10 @@ #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" static const char *TAG = "gpio-filter"; @@ -26,6 +28,10 @@ struct gpio_flex_glitch_filter_t { gpio_glitch_filter_t base; gpio_flex_glitch_filter_group_t *group; uint32_t filter_id; + esp_pm_lock_handle_t pm_lock; +#if CONFIG_PM_ENABLE + char pm_lock_name[GLITCH_FILTER_PM_LOCK_NAME_LEN_MAX]; // pm lock name +#endif }; static gpio_flex_glitch_filter_group_t s_gpio_glitch_filter_group = { @@ -66,6 +72,10 @@ static esp_err_t gpio_filter_destroy(gpio_flex_glitch_filter_t *filter) portEXIT_CRITICAL(&group->spinlock); } + if (filter->pm_lock) { + esp_pm_lock_delete(filter->pm_lock); + } + free(filter); return ESP_OK; } @@ -82,6 +92,11 @@ static esp_err_t gpio_flex_glitch_filter_enable(gpio_glitch_filter_t *filter) ESP_RETURN_ON_FALSE(filter->fsm == GLITCH_FILTER_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "filter not in init state"); gpio_flex_glitch_filter_t *flex_filter = __containerof(filter, gpio_flex_glitch_filter_t, base); + // acquire pm lock + if (flex_filter->pm_lock) { + esp_pm_lock_acquire(flex_filter->pm_lock); + } + int filter_id = flex_filter->filter_id; gpio_ll_glitch_filter_enable(s_gpio_glitch_filter_group.hw, filter_id, true); filter->fsm = GLITCH_FILTER_FSM_ENABLE; @@ -95,6 +110,12 @@ static esp_err_t gpio_flex_glitch_filter_disable(gpio_glitch_filter_t *filter) int filter_id = flex_filter->filter_id; gpio_ll_glitch_filter_enable(s_gpio_glitch_filter_group.hw, filter_id, false); + + // release pm lock + if (flex_filter->pm_lock) { + esp_pm_lock_release(flex_filter->pm_lock); + } + filter->fsm = GLITCH_FILTER_FSM_INIT; return ESP_OK; } @@ -105,19 +126,46 @@ esp_err_t gpio_new_flex_glitch_filter(const gpio_flex_glitch_filter_config_t *co gpio_flex_glitch_filter_t *filter = NULL; ESP_GOTO_ON_FALSE(config && ret_filter, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_GOTO_ON_FALSE(GPIO_IS_VALID_GPIO(config->gpio_num), ESP_ERR_INVALID_ARG, err, TAG, "invalid gpio number"); - // Glitch filter's clock source is same to the IOMUX clock - // TODO: IDF-6345 task will make the IOMUX clock source configurable, and we should opt the glitch filter clock source accordingly - uint32_t clk_freq_mhz = esp_clk_xtal_freq() / 1000000; + + // allocate driver object + filter = heap_caps_calloc(1, sizeof(gpio_flex_glitch_filter_t), FILTER_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(filter, ESP_ERR_NO_MEM, err, TAG, "no memory for flex glitch filter"); + + // register the filter to the group + ESP_GOTO_ON_ERROR(gpio_filter_register_to_group(filter), err, TAG, "register filter to group failed"); + 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; +#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"); +#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; 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"); - filter = heap_caps_calloc(1, sizeof(gpio_flex_glitch_filter_t), FILTER_MEM_ALLOC_CAPS); - ESP_GOTO_ON_FALSE(filter, ESP_ERR_NO_MEM, err, TAG, "no memory for flex glitch filter"); - // register the filter to the group - ESP_GOTO_ON_ERROR(gpio_filter_register_to_group(filter), err, TAG, "register filter to group failed"); - int filter_id = filter->filter_id; + // 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"); // make sure the filter is disabled gpio_ll_glitch_filter_enable(s_gpio_glitch_filter_group.hw, filter_id, false); diff --git a/components/driver/gpio/gpio_pin_glitch_filter.c b/components/driver/gpio/gpio_pin_glitch_filter.c index e2068ba74d..3ea6badf6d 100644 --- a/components/driver/gpio/gpio_pin_glitch_filter.c +++ b/components/driver/gpio/gpio_pin_glitch_filter.c @@ -7,8 +7,11 @@ #include #include "freertos/FreeRTOS.h" #include "esp_check.h" +#include "esp_pm.h" #include "glitch_filter_priv.h" #include "hal/gpio_ll.h" +#include "esp_private/esp_clk.h" +#include "esp_private/io_mux.h" static const char *TAG = "gpio-filter"; @@ -17,19 +20,39 @@ static const char *TAG = "gpio-filter"; */ typedef struct gpio_pin_glitch_filter_t { gpio_glitch_filter_t base; + esp_pm_lock_handle_t pm_lock; +#if CONFIG_PM_ENABLE + char pm_lock_name[GLITCH_FILTER_PM_LOCK_NAME_LEN_MAX]; // pm lock name +#endif } gpio_pin_glitch_filter_t; +static esp_err_t gpio_filter_destroy(gpio_pin_glitch_filter_t *filter) +{ + if (filter->pm_lock) { + esp_pm_lock_delete(filter->pm_lock); + } + + free(filter); + return ESP_OK; +} + static esp_err_t gpio_pin_glitch_filter_del(gpio_glitch_filter_t *filter) { ESP_RETURN_ON_FALSE(filter->fsm == GLITCH_FILTER_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "filter not in init state"); gpio_pin_glitch_filter_t *pin_filter = __containerof(filter, gpio_pin_glitch_filter_t, base); - free(pin_filter); - return ESP_OK; + return gpio_filter_destroy(pin_filter); } static esp_err_t gpio_pin_glitch_filter_enable(gpio_glitch_filter_t *filter) { ESP_RETURN_ON_FALSE(filter->fsm == GLITCH_FILTER_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "filter not in init state"); + gpio_pin_glitch_filter_t *pin_filter = __containerof(filter, gpio_pin_glitch_filter_t, base); + + // acquire pm lock + if (pin_filter->pm_lock) { + esp_pm_lock_acquire(pin_filter->pm_lock); + } + gpio_ll_pin_filter_enable(NULL, filter->gpio_num); filter->fsm = GLITCH_FILTER_FSM_ENABLE; return ESP_OK; @@ -38,7 +61,15 @@ static esp_err_t gpio_pin_glitch_filter_enable(gpio_glitch_filter_t *filter) static esp_err_t gpio_pin_glitch_filter_disable(gpio_glitch_filter_t *filter) { ESP_RETURN_ON_FALSE(filter->fsm == GLITCH_FILTER_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "filter not in enable state"); + gpio_pin_glitch_filter_t *pin_filter = __containerof(filter, gpio_pin_glitch_filter_t, base); + gpio_ll_pin_filter_disable(NULL, filter->gpio_num); + + // release pm lock + if (pin_filter->pm_lock) { + esp_pm_lock_release(pin_filter->pm_lock); + } + filter->fsm = GLITCH_FILTER_FSM_INIT; return ESP_OK; } @@ -53,6 +84,40 @@ 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: +#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 + +#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; + } + + // 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"); + filter->base.gpio_num = config->gpio_num; filter->base.fsm = GLITCH_FILTER_FSM_INIT; filter->base.del = gpio_pin_glitch_filter_del; @@ -63,7 +128,7 @@ esp_err_t gpio_new_pin_glitch_filter(const gpio_pin_glitch_filter_config_t *conf return ESP_OK; err: if (filter) { - free(filter); + gpio_filter_destroy(filter); } return ret; } diff --git a/components/driver/include/driver/gpio_filter.h b/components/driver/include/driver/gpio_filter.h index 7ee33432ba..1225084d76 100644 --- a/components/driver/include/driver/gpio_filter.h +++ b/components/driver/include/driver/gpio_filter.h @@ -9,6 +9,7 @@ #include #include #include "esp_err.h" +#include "hal/glitch_filter_types.h" #include "driver/gpio.h" #ifdef __cplusplus @@ -24,6 +25,7 @@ typedef struct gpio_glitch_filter_t *gpio_glitch_filter_handle_t; * @brief Configuration of GPIO pin glitch filter */ typedef struct { + glitch_filter_clock_source_t clk_src; /*!< Clock source for the glitch filter */ gpio_num_t gpio_num; /*!< GPIO number */ } gpio_pin_glitch_filter_config_t; @@ -48,6 +50,7 @@ esp_err_t gpio_new_pin_glitch_filter(const gpio_pin_glitch_filter_config_t *conf * @brief Configuration of GPIO flex glitch filter */ typedef struct { + glitch_filter_clock_source_t clk_src; /*!< Clock source for the glitch filter */ gpio_num_t gpio_num; /*!< GPIO number */ uint32_t window_width_ns; /*!< Sample window width (in ns) */ uint32_t window_thres_ns; /*!< Sample window threshold (in ns), during the `window_width_ns` sample window, any pulse whose width < window_thres_ns will be discarded. */ diff --git a/components/driver/test_apps/gpio/main/test_gpio_filter.c b/components/driver/test_apps/gpio/main/test_gpio_filter.c index a385cfc807..31f33e0245 100644 --- a/components/driver/test_apps/gpio/main/test_gpio_filter.c +++ b/components/driver/test_apps/gpio/main/test_gpio_filter.c @@ -19,7 +19,9 @@ TEST_CASE("GPIO pin glitch filter life cycle", "[gpio_filter]") { gpio_glitch_filter_handle_t filter = NULL; - gpio_pin_glitch_filter_config_t config = {}; + gpio_pin_glitch_filter_config_t config = { + .clk_src = GLITCH_FILTER_CLK_SRC_DEFAULT, + }; TEST_ESP_OK(gpio_new_pin_glitch_filter(&config, &filter)); TEST_ESP_OK(gpio_glitch_filter_enable(filter)); @@ -38,7 +40,9 @@ TEST_CASE("GPIO pin glitch filter life cycle", "[gpio_filter]") TEST_CASE("GPIO flex glitch filter life cycle", "[gpio_filter]") { gpio_glitch_filter_handle_t filters[SOC_GPIO_FLEX_GLITCH_FILTER_NUM]; - gpio_flex_glitch_filter_config_t config = {}; + gpio_flex_glitch_filter_config_t config = { + .clk_src = GLITCH_FILTER_CLK_SRC_DEFAULT, + }; // install filter with wrong parameters TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_new_flex_glitch_filter(&config, &filters[0])); @@ -82,6 +86,19 @@ static void test_gpio_intr_callback(void *args) } } +// put the simulation code in the IRAM to avoid cache miss +NOINLINE_ATTR IRAM_ATTR static void test_gpio_simulate_glitch_pulse(void) +{ + // the following code is used to generate a short glitch pulse + // around 10ns @CPU160MHz + asm volatile( + "csrrsi zero, %0, 0x1\n" + "csrrsi zero, %0, 0x1\n" + "csrrci zero, %0, 0x1" + :: "i"(CSR_GPIO_OUT_USER) + ); +} + TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]") { const gpio_num_t test_gpio = 0; @@ -109,9 +126,10 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]") printf("apply glitch filter to the GPIO\r\n"); gpio_glitch_filter_handle_t filter; gpio_flex_glitch_filter_config_t filter_cfg = { + .clk_src = GLITCH_FILTER_CLK_SRC_DEFAULT, .gpio_num = test_gpio, - .window_thres_ns = 1500, // pulse whose width is shorter than 1500 will be filtered out - .window_width_ns = 1500, + .window_thres_ns = 500, + .window_width_ns = 500, }; TEST_ESP_OK((gpio_new_flex_glitch_filter(&filter_cfg, &filter))); TEST_ESP_OK(gpio_glitch_filter_enable(filter)); @@ -122,12 +140,7 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]") TEST_ESP_OK(gpio_isr_handler_add(test_gpio, test_gpio_intr_callback, sem)); printf("generate rising edge glitch signal\r\n"); - asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); - asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); - asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); - asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); - - asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); + test_gpio_simulate_glitch_pulse(); // should timeout, because the glitch is filtered out TEST_ASSERT_EQUAL(pdFALSE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000))); @@ -136,12 +149,7 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]") TEST_ESP_OK(gpio_glitch_filter_disable(filter)); printf("generate rising edge glitch signal again\r\n"); - asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); - asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); - asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); - asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); - - asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER)); + test_gpio_simulate_glitch_pulse(); // this time we should see the GPIO interrupt fired up TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000))); diff --git a/components/hal/include/hal/glitch_filter_types.h b/components/hal/include/hal/glitch_filter_types.h new file mode 100644 index 0000000000..e242ef1705 --- /dev/null +++ b/components/hal/include/hal/glitch_filter_types.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER || (SOC_GPIO_FLEX_GLITCH_FILTER_NUM > 0) +typedef soc_periph_glitch_filter_clk_src_t glitch_filter_clock_source_t; // glitch filter clock source +#else +typedef int glitch_filter_clock_source_t; // glitch filter clock source, fallback to integer type +#endif // SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER || (SOC_GPIO_FLEX_GLITCH_FILTER_NUM > 0) + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 1b0a5008c9..132de6cc97 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -211,6 +211,10 @@ config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER bool default y +config SOC_GPIO_FILTER_CLK_SUPPORT_APB + bool + default y + config SOC_GPIO_SUPPORTS_RTC_INDEPENDENT bool default y diff --git a/components/soc/esp32c2/include/soc/clk_tree_defs.h b/components/soc/esp32c2/include/soc/clk_tree_defs.h index d1dcbebfd2..bb3b0f4ac4 100644 --- a/components/soc/esp32c2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c2/include/soc/clk_tree_defs.h @@ -102,6 +102,7 @@ typedef enum { SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */ SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or RC_FAST_D256 by configuring soc_rtc_slow_clk_src_t */ // For digital domain: peripherals, WIFI, BLE + SOC_MOD_CLK_APB, /*!< APB_CLK is always 40MHz no matter it derives from XTAL or PLL */ SOC_MOD_CLK_PLL_F40M, /*!< PLL_F40M_CLK is derived from PLL, and has a fixed frequency of 40MHz */ SOC_MOD_CLK_PLL_F60M, /*!< PLL_F60M_CLK is derived from PLL, and has a fixed frequency of 60MHz */ SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL, and has a fixed frequency of 80MHz */ @@ -177,7 +178,7 @@ typedef enum { * @brief Type of UART clock source, reserved for the legacy UART driver */ typedef enum { - UART_SCLK_PLL_F40M = SOC_MOD_CLK_PLL_F40M, /*!< UART source clock is APB CLK */ + UART_SCLK_PLL_F40M = SOC_MOD_CLK_PLL_F40M, /*!< UART source clock is PLL_F40M CLK */ UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */ UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */ UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F40M, /*!< UART source clock default choice is PLL_F40M */ @@ -215,6 +216,21 @@ typedef enum { ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */ } soc_periph_adc_digi_clk_src_t; +//////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Glitch Filter + */ +#define SOC_GLITCH_FILTER_CLKS {SOC_MOD_CLK_APB} + +/** + * @brief Glitch filter clock source + */ +typedef enum { + GLITCH_FILTER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB clock as the source clock */ + GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB clock as the default clock choice */ +} soc_periph_glitch_filter_clk_src_t; + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index edad367a10..e81e44c9b0 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -106,6 +106,7 @@ #define SOC_GPIO_PORT 1U #define SOC_GPIO_PIN_COUNT 21 #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 +#define SOC_GPIO_FILTER_CLK_SUPPORT_APB 1 // Target has no full RTC IO subsystem, so GPIO is 100% "independent" of RTC // On ESP32-C2, Digital IOs have their own registers to control pullup/down capability, independent of RTC registers. diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 761e4eb823..25d1a42c3f 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -303,6 +303,10 @@ config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER bool default y +config SOC_GPIO_FILTER_CLK_SUPPORT_APB + bool + default y + config SOC_GPIO_SUPPORTS_RTC_INDEPENDENT bool default y diff --git a/components/soc/esp32c3/include/soc/clk_tree_defs.h b/components/soc/esp32c3/include/soc/clk_tree_defs.h index 4cc452c760..e8550b73a6 100644 --- a/components/soc/esp32c3/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c3/include/soc/clk_tree_defs.h @@ -243,7 +243,7 @@ typedef enum { I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, } soc_periph_i2c_clk_src_t; -//////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////SDM/////////////////////////////////////////////////////////////////// /** * @brief Array initializer for all supported clock sources of SDM @@ -258,6 +258,22 @@ typedef enum { SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */ } soc_periph_sdm_clk_src_t; +//////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Glitch Filter + */ +#define SOC_GLITCH_FILTER_CLKS {SOC_MOD_CLK_APB} + +/** + * @brief Glitch filter clock source + */ + +typedef enum { + GLITCH_FILTER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB clock as the source clock */ + GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB clock as the default clock choice */ +} soc_periph_glitch_filter_clk_src_t; + //////////////////////////////////////////////////TWAI///////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 6b17c23afc..f5c3fc66b7 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -144,6 +144,7 @@ #define SOC_GPIO_PORT 1U #define SOC_GPIO_PIN_COUNT 22 #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 +#define SOC_GPIO_FILTER_CLK_SUPPORT_APB 1 // Target has no full RTC IO subsystem, so GPIO is 100% "independent" of RTC // On ESP32-C3, Digital IOs have their own registers to control pullup/down capability, independent of RTC registers. diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 0840ff0105..6824140233 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -307,6 +307,14 @@ 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/clk_tree_defs.h b/components/soc/esp32c6/include/soc/clk_tree_defs.h index 86ec1608c0..60ac2b1a3b 100644 --- a/components/soc/esp32c6/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c6/include/soc/clk_tree_defs.h @@ -123,7 +123,7 @@ typedef enum { SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */ } soc_module_clk_t; -//////////////////////////////////////////////////SYSTIMER/////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////SYSTIMER////////////////////////////////////////////////////////////// /** * @brief Type of SYSTIMER clock source @@ -285,7 +285,7 @@ typedef enum { I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, } soc_periph_i2c_clk_src_t; -//////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////SDM/////////////////////////////////////////////////////////////////// /** * @brief Array initializer for all supported clock sources of SDM @@ -301,7 +301,24 @@ typedef enum { SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the default clock choice */ } soc_periph_sdm_clk_src_t; -//////////////////////////////////////////////////TWAI///////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Glitch Filter + */ +#define SOC_GLITCH_FILTER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL} + +/** + * @brief Glitch filter clock source + */ + +typedef enum { + GLITCH_FILTER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL clock as the source clock */ + GLITCH_FILTER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the source clock */ + GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the default clock choice */ +} soc_periph_glitch_filter_clk_src_t; + +//////////////////////////////////////////////////TWAI////////////////////////////////////////////////////////////////// /** * @brief Array initializer for all supported clock sources of TWAI diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 4e65652589..c45b501c4b 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -158,6 +158,8 @@ #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/clk_tree_defs.h b/components/soc/esp32h2/include/soc/clk_tree_defs.h index 6e812c3220..7c744587c9 100644 --- a/components/soc/esp32h2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h2/include/soc/clk_tree_defs.h @@ -308,7 +308,7 @@ typedef enum { I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, } soc_periph_i2c_clk_src_t; -//////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////SDM/////////////////////////////////////////////////////////////////// /** * @brief Array initializer for all supported clock sources of SDM @@ -323,6 +323,23 @@ typedef enum { SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */ } soc_periph_sdm_clk_src_t; +//////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Glitch Filter + */ +#define SOC_GLITCH_FILTER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL} + +/** + * @brief Glitch filter clock source + */ + +typedef enum { + GLITCH_FILTER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL clock as the source clock */ + GLITCH_FILTER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the source clock */ + GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the default clock choice */ +} soc_periph_glitch_filter_clk_src_t; + //////////////////////////////////////////////////TWAI///////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index 8332c22713..8641bc2625 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -283,6 +283,10 @@ config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER bool default y +config SOC_GPIO_FILTER_CLK_SUPPORT_APB + bool + default y + config SOC_GPIO_PIN_COUNT int default 41 diff --git a/components/soc/esp32h4/include/soc/clk_tree_defs.h b/components/soc/esp32h4/include/soc/clk_tree_defs.h index 7841bc8240..bd4964915e 100644 --- a/components/soc/esp32h4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h4/include/soc/clk_tree_defs.h @@ -248,7 +248,7 @@ typedef enum { I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, } soc_periph_i2c_clk_src_t; -//////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////SDM/////////////////////////////////////////////////////////////////// /** * @brief Array initializer for all supported clock sources of SDM @@ -263,6 +263,22 @@ typedef enum { SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */ } soc_periph_sdm_clk_src_t; +//////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Glitch Filter + */ +#define SOC_GLITCH_FILTER_CLKS {SOC_MOD_CLK_APB} + +/** + * @brief Glitch filter clock source + */ + +typedef enum { + GLITCH_FILTER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB clock as the source clock */ + GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB clock as the default clock choice */ +} soc_periph_glitch_filter_clk_src_t; + //////////////////////////////////////////////////TWAI///////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index 743b02647a..4ed7ca997f 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -142,6 +142,7 @@ // ESP32-H4 has 1 GPIO peripheral #define SOC_GPIO_PORT 1U #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 +#define SOC_GPIO_FILTER_CLK_SUPPORT_APB 1 #if CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1 #define SOC_GPIO_PIN_COUNT (41) diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 2fe4d9a5ae..f7826613e1 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -287,6 +287,10 @@ config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER bool default y +config SOC_GPIO_FILTER_CLK_SUPPORT_APB + bool + default y + config SOC_GPIO_SUPPORT_RTC_INDEPENDENT bool default y diff --git a/components/soc/esp32s2/include/soc/clk_tree_defs.h b/components/soc/esp32s2/include/soc/clk_tree_defs.h index d6ca50c19d..11f8950f75 100644 --- a/components/soc/esp32s2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s2/include/soc/clk_tree_defs.h @@ -259,7 +259,7 @@ typedef enum { I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, } soc_periph_i2c_clk_src_t; -//////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////SDM/////////////////////////////////////////////////////////////////// /** * @brief Array initializer for all supported clock sources of SDM @@ -274,6 +274,22 @@ typedef enum { SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */ } soc_periph_sdm_clk_src_t; +//////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Glitch Filter + */ +#define SOC_GLITCH_FILTER_CLKS {SOC_MOD_CLK_APB} + +/** + * @brief Glitch filter clock source + */ + +typedef enum { + GLITCH_FILTER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB clock as the source clock */ + GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB clock as the default clock choice */ +} soc_periph_glitch_filter_clk_src_t; + ////////////////////////////////////////////////////DAC///////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 106f17885c..2662eb4d84 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -138,6 +138,7 @@ #define SOC_GPIO_PORT 1U #define SOC_GPIO_PIN_COUNT 47 #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 +#define SOC_GPIO_FILTER_CLK_SUPPORT_APB 1 // On ESP32-S2 those PADs which have RTC functions must set pullup/down/capability via RTC register. // On ESP32-S2, Digital IOs have their own registers to control pullup/down/capability, independent with RTC registers. diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index b0bdeb62e5..f73671173f 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -351,6 +351,10 @@ config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER bool default y +config SOC_GPIO_FILTER_CLK_SUPPORT_APB + bool + default y + config SOC_GPIO_SUPPORT_RTC_INDEPENDENT bool default y diff --git a/components/soc/esp32s3/include/soc/clk_tree_defs.h b/components/soc/esp32s3/include/soc/clk_tree_defs.h index 1965546ece..1d305cb2ae 100644 --- a/components/soc/esp32s3/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s3/include/soc/clk_tree_defs.h @@ -288,7 +288,7 @@ typedef enum { I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, } soc_periph_i2c_clk_src_t; -//////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////SDM/////////////////////////////////////////////////////////////////// /** * @brief Array initializer for all supported clock sources of SDM @@ -303,6 +303,22 @@ typedef enum { SDM_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */ } soc_periph_sdm_clk_src_t; +//////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of Glitch Filter + */ +#define SOC_GLITCH_FILTER_CLKS {SOC_MOD_CLK_APB} + +/** + * @brief Glitch filter clock source + */ + +typedef enum { + GLITCH_FILTER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB clock as the source clock */ + GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB clock as the default clock choice */ +} soc_periph_glitch_filter_clk_src_t; + //////////////////////////////////////////////////TWAI///////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index c454eec821..801f562c38 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -146,6 +146,7 @@ #define SOC_GPIO_PORT 1U #define SOC_GPIO_PIN_COUNT 49 #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 +#define SOC_GPIO_FILTER_CLK_SUPPORT_APB 1 // On ESP32-S3, Digital IOs have their own registers to control pullup/down/capability, independent with RTC registers. #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) From d5b4108085109056deab34af8ab5c2f6ec7bc961 Mon Sep 17 00:00:00 2001 From: morris Date: Wed, 21 Dec 2022 21:31:03 +0800 Subject: [PATCH 4/4] gpio: combine sdm, glitch filter, fast gpio tests into one app --- components/driver/.build-test-rules.yml | 4 -- .../driver/test_apps/gpio/main/CMakeLists.txt | 8 ---- .../driver/test_apps/gpio/pytest_gpio.py | 24 +---------- .../{sdm => gpio_extensions}/CMakeLists.txt | 4 +- .../test_apps/gpio_extensions/README.md | 2 + .../gpio_extensions/main/CMakeLists.txt | 18 ++++++++ .../main/test_app_main.c | 24 +++++------ .../main/test_dedicated_gpio.c | 0 .../main/test_gpio_filter.c | 0 .../{sdm => gpio_extensions}/main/test_sdm.c | 0 .../gpio_extensions/pytest_gpio_extensions.py | 43 +++++++++++++++++++ .../sdkconfig.ci.iram_safe | 2 + .../sdkconfig.ci.release | 0 .../sdkconfig.defaults | 0 components/driver/test_apps/sdm/README.md | 2 - .../driver/test_apps/sdm/main/CMakeLists.txt | 7 --- components/driver/test_apps/sdm/pytest_sdm.py | 25 ----------- 17 files changed, 80 insertions(+), 83 deletions(-) rename components/driver/test_apps/{sdm => gpio_extensions}/CMakeLists.txt (85%) create mode 100644 components/driver/test_apps/gpio_extensions/README.md create mode 100644 components/driver/test_apps/gpio_extensions/main/CMakeLists.txt rename components/driver/test_apps/{sdm => gpio_extensions}/main/test_app_main.c (55%) rename components/driver/test_apps/{gpio => gpio_extensions}/main/test_dedicated_gpio.c (100%) rename components/driver/test_apps/{gpio => gpio_extensions}/main/test_gpio_filter.c (100%) rename components/driver/test_apps/{sdm => gpio_extensions}/main/test_sdm.c (100%) create mode 100644 components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py rename components/driver/test_apps/{sdm => gpio_extensions}/sdkconfig.ci.iram_safe (71%) rename components/driver/test_apps/{sdm => gpio_extensions}/sdkconfig.ci.release (100%) rename components/driver/test_apps/{sdm => gpio_extensions}/sdkconfig.defaults (100%) delete mode 100644 components/driver/test_apps/sdm/README.md delete mode 100644 components/driver/test_apps/sdm/main/CMakeLists.txt delete mode 100644 components/driver/test_apps/sdm/pytest_sdm.py diff --git a/components/driver/.build-test-rules.yml b/components/driver/.build-test-rules.yml index 520cd0a6e9..25fef7f738 100644 --- a/components/driver/.build-test-rules.yml +++ b/components/driver/.build-test-rules.yml @@ -76,10 +76,6 @@ components/driver/test_apps/sdio: temporary: true reason: Not supported. -components/driver/test_apps/sdm: - disable: - - if: SOC_SDM_SUPPORTED != 1 - components/driver/test_apps/temperature_sensor: disable: - if: SOC_TEMP_SENSOR_SUPPORTED != 1 diff --git a/components/driver/test_apps/gpio/main/CMakeLists.txt b/components/driver/test_apps/gpio/main/CMakeLists.txt index 09dabd06a5..ebc552aaf8 100644 --- a/components/driver/test_apps/gpio/main/CMakeLists.txt +++ b/components/driver/test_apps/gpio/main/CMakeLists.txt @@ -1,14 +1,6 @@ set(srcs "test_app_main.c" "test_gpio.c") -if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER OR (CONFIG_SOC_GPIO_FLEX_GLITCH_FILTER_NUM GREATER 0)) - list(APPEND srcs "test_gpio_filter.c") -endif() - -if(CONFIG_SOC_DEDICATED_GPIO_SUPPORTED) - list(APPEND srcs "test_dedicated_gpio.c") -endif() - if(CONFIG_SOC_SDM_SUPPORTED) list(APPEND srcs "test_sigma_delta_legacy.c") endif() diff --git a/components/driver/test_apps/gpio/pytest_gpio.py b/components/driver/test_apps/gpio/pytest_gpio.py index b78c80c2a6..0f59bff3f5 100644 --- a/components/driver/test_apps/gpio/pytest_gpio.py +++ b/components/driver/test_apps/gpio/pytest_gpio.py @@ -17,28 +17,6 @@ def test_gpio(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='gpio') -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) -def test_gpio_filter(dut: IdfDut) -> None: - dut.run_all_single_board_cases(group='gpio_filter') - - -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) -def test_dedic_gpio(dut: IdfDut) -> None: - dut.run_all_single_board_cases(group='dedic_gpio') - - @pytest.mark.esp32 @pytest.mark.esp32c3 @pytest.mark.esp32c6 @@ -46,7 +24,7 @@ def test_dedic_gpio(dut: IdfDut) -> None: @pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize('config', CONFIGS, indirect=True) -def test_sigma_delta(dut: IdfDut) -> None: +def test_legacy_sigma_delta(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='sigma_delta') diff --git a/components/driver/test_apps/sdm/CMakeLists.txt b/components/driver/test_apps/gpio_extensions/CMakeLists.txt similarity index 85% rename from components/driver/test_apps/sdm/CMakeLists.txt rename to components/driver/test_apps/gpio_extensions/CMakeLists.txt index 9830fb8ada..17a9e49590 100644 --- a/components/driver/test_apps/sdm/CMakeLists.txt +++ b/components/driver/test_apps/gpio_extensions/CMakeLists.txt @@ -2,13 +2,13 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(sdm_test) +project(gpio_extension_test) if(CONFIG_COMPILER_DUMP_RTL_FILES) add_custom_target(check_test_app_sections ALL COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py --rtl-dir ${CMAKE_BINARY_DIR}/esp-idf/driver/ - --elf-file ${CMAKE_BINARY_DIR}/sdm_test.elf + --elf-file ${CMAKE_BINARY_DIR}/gpio_extension_test.elf find-refs --from-sections=.iram0.text --to-sections=.flash.text,.flash.rodata diff --git a/components/driver/test_apps/gpio_extensions/README.md b/components/driver/test_apps/gpio_extensions/README.md new file mode 100644 index 0000000000..7e7523ec85 --- /dev/null +++ b/components/driver/test_apps/gpio_extensions/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/gpio_extensions/main/CMakeLists.txt b/components/driver/test_apps/gpio_extensions/main/CMakeLists.txt new file mode 100644 index 0000000000..6175f6f23d --- /dev/null +++ b/components/driver/test_apps/gpio_extensions/main/CMakeLists.txt @@ -0,0 +1,18 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_DEDICATED_GPIO_SUPPORTED) + list(APPEND srcs "test_dedicated_gpio.c") +endif() + +if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER OR (CONFIG_SOC_GPIO_FLEX_GLITCH_FILTER_NUM GREATER 0)) + list(APPEND srcs "test_gpio_filter.c") +endif() + +if(CONFIG_SOC_SDM_SUPPORTED) + list(APPEND srcs "test_sdm.c") +endif() + +# In order for the cases defined by `TEST_CASE` to be linked into the final elf, +# the component can be registered as WHOLE_ARCHIVE +idf_component_register(SRCS ${srcs} + WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/sdm/main/test_app_main.c b/components/driver/test_apps/gpio_extensions/main/test_app_main.c similarity index 55% rename from components/driver/test_apps/sdm/main/test_app_main.c rename to components/driver/test_apps/gpio_extensions/main/test_app_main.c index 6394c16e0c..b53eec62b8 100644 --- a/components/driver/test_apps/sdm/main/test_app_main.c +++ b/components/driver/test_apps/gpio_extensions/main/test_app_main.c @@ -8,8 +8,8 @@ #include "unity_test_runner.h" #include "esp_heap_caps.h" -// Some resources are lazy allocated in pulse_cnt driver, the threshold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (-200) +// Some resources are lazy allocated in the driver, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-300) static size_t before_free_8bit; static size_t before_free_32bit; @@ -37,15 +37,15 @@ void tearDown(void) void app_main(void) { - // ____ ____ ___ ___ ____ ____ __ __ - // / ___| _ \_ _/ _ \ / ___|| _ \| \/ | - // | | _| |_) | | | | | \___ \| | | | |\/| | - // | |_| | __/| | |_| | ___) | |_| | | | | - // \____|_| |___\___/ |____/|____/|_| |_| - printf(" ____ ____ ___ ___ ____ ____ __ __\r\n"); - printf(" / ___| _ \\_ _/ _ \\ / ___|| _ \\| \\/ |\r\n"); - printf("| | _| |_) | | | | | \\___ \\| | | | |\\/| |\r\n"); - printf("| |_| | __/| | |_| | ___) | |_| | | | |\r\n"); - printf(" \\____|_| |___\\___/ |____/|____/|_| |_|\r\n"); + // ____ ____ ___ ___ _____ _ _____ _ + // / ___| _ \_ _/ _ \ | ____|_ _| |_ |_ _|__ ___| |_ + // | | _| |_) | | | | | | _| \ \/ / __| | |/ _ \/ __| __| + // | |_| | __/| | |_| | | |___ > <| |_ | | __/\__ \ |_ + // \____|_| |___\___/ |_____/_/\_\\__| |_|\___||___/\__| + printf(" ____ ____ ___ ___ _____ _ _____ _\r\n"); + printf(" / ___| _ \\_ _/ _ \\ | ____|_ _| |_ |_ _|__ ___| |_\r\n"); + printf("| | _| |_) | | | | | | _| \\ \\/ / __| | |/ _ \\/ __| __|\r\n"); + printf("| |_| | __/| | |_| | | |___ > <| |_ | | __/\\__ \\ |_\r\n"); + printf(" \\____|_| |___\\___/ |_____/_/\\_\\\\__| |_|\\___||___/\\__|\r\n"); unity_run_menu(); } diff --git a/components/driver/test_apps/gpio/main/test_dedicated_gpio.c b/components/driver/test_apps/gpio_extensions/main/test_dedicated_gpio.c similarity index 100% rename from components/driver/test_apps/gpio/main/test_dedicated_gpio.c rename to components/driver/test_apps/gpio_extensions/main/test_dedicated_gpio.c diff --git a/components/driver/test_apps/gpio/main/test_gpio_filter.c b/components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c similarity index 100% rename from components/driver/test_apps/gpio/main/test_gpio_filter.c rename to components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c diff --git a/components/driver/test_apps/sdm/main/test_sdm.c b/components/driver/test_apps/gpio_extensions/main/test_sdm.c similarity index 100% rename from components/driver/test_apps/sdm/main/test_sdm.c rename to components/driver/test_apps/gpio_extensions/main/test_sdm.c diff --git a/components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py b/components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py new file mode 100644 index 0000000000..e245bb1993 --- /dev/null +++ b/components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py @@ -0,0 +1,43 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded_idf import IdfDut + +CONFIGS = [ + 'iram_safe', + 'release', +] + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize('config', CONFIGS, indirect=True) +def test_sdm(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='sdm') + + +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize('config', CONFIGS, indirect=True) +def test_gpio_filter(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='gpio_filter') + + +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize('config', CONFIGS, indirect=True) +def test_dedic_gpio(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='dedic_gpio') diff --git a/components/driver/test_apps/sdm/sdkconfig.ci.iram_safe b/components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe similarity index 71% rename from components/driver/test_apps/sdm/sdkconfig.ci.iram_safe rename to components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe index 35876c662b..7e63e6d096 100644 --- a/components/driver/test_apps/sdm/sdkconfig.ci.iram_safe +++ b/components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe @@ -5,3 +5,5 @@ CONFIG_COMPILER_OPTIMIZATION_NONE=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y # silent the error check, as the error string are stored in rodata, causing RTL check failure CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +# GPIO test uses IPC call, the default stack size of IPC task can satisfy the -O0 optimization +CONFIG_ESP_IPC_TASK_STACK_SIZE=2048 diff --git a/components/driver/test_apps/sdm/sdkconfig.ci.release b/components/driver/test_apps/gpio_extensions/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/sdm/sdkconfig.ci.release rename to components/driver/test_apps/gpio_extensions/sdkconfig.ci.release diff --git a/components/driver/test_apps/sdm/sdkconfig.defaults b/components/driver/test_apps/gpio_extensions/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/sdm/sdkconfig.defaults rename to components/driver/test_apps/gpio_extensions/sdkconfig.defaults diff --git a/components/driver/test_apps/sdm/README.md b/components/driver/test_apps/sdm/README.md deleted file mode 100644 index 6f026d8e9e..0000000000 --- a/components/driver/test_apps/sdm/README.md +++ /dev/null @@ -1,2 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/sdm/main/CMakeLists.txt b/components/driver/test_apps/sdm/main/CMakeLists.txt deleted file mode 100644 index c304c90d3a..0000000000 --- a/components/driver/test_apps/sdm/main/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set(srcs "test_app_main.c" - "test_sdm.c") - -# In order for the cases defined by `TEST_CASE` to be linked into the final elf, -# the component can be registered as WHOLE_ARCHIVE -idf_component_register(SRCS ${srcs} - WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/sdm/pytest_sdm.py b/components/driver/test_apps/sdm/pytest_sdm.py deleted file mode 100644 index d40b9ee056..0000000000 --- a/components/driver/test_apps/sdm/pytest_sdm.py +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: CC0-1.0 - -import pytest -from pytest_embedded import Dut - - -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - 'iram_safe', - 'release', - ], - indirect=True, -) -def test_sdm(dut: Dut) -> None: - dut.expect_exact('Press ENTER to see the list of tests') - dut.write('*') - dut.expect_unity_test_output()