Merge branch 'feature/glitch_filter_h2' into 'master'

gpio: support glitch filter on esp32h2

Closes IDF-6286

See merge request espressif/esp-idf!22273
This commit is contained in:
morris 2023-02-14 13:07:44 +08:00
commit e0c98da169
14 changed files with 200 additions and 82 deletions

View File

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

View File

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

View File

@ -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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */

View File

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

View File

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

View File

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