forked from espressif/esp-idf
Merge branch 'feature/gpio_filter_esp32c6' into 'master'
GPIO glitch filter driver Closes IDF-5810, IDF-6059, and IDF-5913 See merge request espressif/esp-idf!20567
This commit is contained in:
@@ -3,6 +3,7 @@ idf_build_get_property(target IDF_TARGET)
|
||||
set(srcs
|
||||
"gpio/gpio.c"
|
||||
"gpio/rtc_io.c"
|
||||
"gpio/gpio_glitch_filter_ops.c"
|
||||
"gptimer/gptimer.c"
|
||||
"sdspi_crc.c"
|
||||
"sdspi_host.c"
|
||||
@@ -57,6 +58,14 @@ if(CONFIG_SOC_DEDICATED_GPIO_SUPPORTED)
|
||||
list(APPEND srcs "gpio/dedic_gpio.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER)
|
||||
list(APPEND srcs "gpio/gpio_pin_glitch_filter.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_GPIO_FLEX_GLITCH_FILTER_NUM GREATER 0)
|
||||
list(APPEND srcs "gpio/gpio_flex_glitch_filter.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_SDM_SUPPORTED)
|
||||
list(APPEND srcs "sdm.c" "deprecated/sigma_delta_legacy.c")
|
||||
endif()
|
||||
|
40
components/driver/gpio/glitch_filter_priv.h
Normal file
40
components/driver/gpio/glitch_filter_priv.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/gpio_filter.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#define FILTER_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct gpio_glitch_filter_t gpio_glitch_filter_t;
|
||||
|
||||
typedef enum {
|
||||
GLITCH_FILTER_FSM_INIT,
|
||||
GLITCH_FILTER_FSM_ENABLE,
|
||||
} glitch_filter_fsm_t;
|
||||
|
||||
/**
|
||||
* @brief Glitch Filter base class
|
||||
*/
|
||||
struct gpio_glitch_filter_t {
|
||||
glitch_filter_fsm_t fsm;
|
||||
gpio_num_t gpio_num;
|
||||
esp_err_t (*enable)(gpio_glitch_filter_t *filter);
|
||||
esp_err_t (*disable)(gpio_glitch_filter_t *filter);
|
||||
esp_err_t (*del)(gpio_glitch_filter_t *filter);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
142
components/driver/gpio/gpio_flex_glitch_filter.c
Normal file
142
components/driver/gpio/gpio_flex_glitch_filter.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_check.h"
|
||||
#include "glitch_filter_priv.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/gpio_glitch_filter_ll.h"
|
||||
|
||||
static const char *TAG = "gpio-filter";
|
||||
|
||||
typedef struct gpio_flex_glitch_filter_t gpio_flex_glitch_filter_t;
|
||||
|
||||
typedef struct gpio_flex_glitch_filter_group_t {
|
||||
gpio_glitch_filter_dev_t *hw;
|
||||
gpio_flex_glitch_filter_t *filters[SOC_GPIO_FLEX_GLITCH_FILTER_NUM];
|
||||
portMUX_TYPE spinlock;
|
||||
} gpio_flex_glitch_filter_group_t;
|
||||
|
||||
struct gpio_flex_glitch_filter_t {
|
||||
gpio_glitch_filter_t base;
|
||||
gpio_flex_glitch_filter_group_t *group;
|
||||
uint32_t filter_id;
|
||||
};
|
||||
|
||||
static gpio_flex_glitch_filter_group_t s_gpio_glitch_filter_group = {
|
||||
.hw = &GLITCH_FILTER,
|
||||
.spinlock = portMUX_INITIALIZER_UNLOCKED,
|
||||
};
|
||||
|
||||
static esp_err_t gpio_filter_register_to_group(gpio_flex_glitch_filter_t *filter)
|
||||
{
|
||||
gpio_flex_glitch_filter_group_t *group = &s_gpio_glitch_filter_group;
|
||||
int filter_id = -1;
|
||||
// loop to search free one in the group
|
||||
portENTER_CRITICAL(&group->spinlock);
|
||||
for (int j = 0; j < SOC_GPIO_FLEX_GLITCH_FILTER_NUM; j++) {
|
||||
if (!group->filters[j]) {
|
||||
filter_id = j;
|
||||
group->filters[j] = filter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL(&group->spinlock);
|
||||
|
||||
ESP_RETURN_ON_FALSE(filter_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free gpio glitch filter");
|
||||
filter->filter_id = filter_id;
|
||||
filter->group = group;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_filter_destroy(gpio_flex_glitch_filter_t *filter)
|
||||
{
|
||||
gpio_flex_glitch_filter_group_t *group = &s_gpio_glitch_filter_group;
|
||||
int filter_id = filter->filter_id;
|
||||
|
||||
// unregister the filter from the group
|
||||
if (filter->group) {
|
||||
portENTER_CRITICAL(&group->spinlock);
|
||||
group->filters[filter_id] = NULL;
|
||||
portEXIT_CRITICAL(&group->spinlock);
|
||||
}
|
||||
|
||||
free(filter);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_flex_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_flex_glitch_filter_t *flex_filter = __containerof(filter, gpio_flex_glitch_filter_t, base);
|
||||
return gpio_filter_destroy(flex_filter);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_flex_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_flex_glitch_filter_t *flex_filter = __containerof(filter, gpio_flex_glitch_filter_t, base);
|
||||
|
||||
int filter_id = flex_filter->filter_id;
|
||||
gpio_ll_glitch_filter_enable(s_gpio_glitch_filter_group.hw, filter_id, false);
|
||||
filter->fsm = GLITCH_FILTER_FSM_INIT;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_new_flex_glitch_filter(const gpio_flex_glitch_filter_config_t *config, gpio_glitch_filter_handle_t *ret_filter)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
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;
|
||||
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;
|
||||
|
||||
// make sure the filter is disabled
|
||||
gpio_ll_glitch_filter_enable(s_gpio_glitch_filter_group.hw, filter_id, false);
|
||||
// apply the filter to the GPIO
|
||||
gpio_ll_glitch_filter_set_gpio(s_gpio_glitch_filter_group.hw, filter_id, config->gpio_num);
|
||||
// set filter coefficient
|
||||
gpio_ll_glitch_filter_set_window_coeff(s_gpio_glitch_filter_group.hw, filter_id, window_width_ticks, window_thres_ticks);
|
||||
|
||||
filter->base.gpio_num = config->gpio_num;
|
||||
filter->base.fsm = GLITCH_FILTER_FSM_INIT;
|
||||
filter->base.del = gpio_flex_glitch_filter_del;
|
||||
filter->base.enable = gpio_flex_glitch_filter_enable;
|
||||
filter->base.disable = gpio_flex_glitch_filter_disable;
|
||||
|
||||
*ret_filter = &(filter->base);
|
||||
return ESP_OK;
|
||||
err:
|
||||
if (filter) {
|
||||
gpio_filter_destroy(filter);
|
||||
}
|
||||
return ret;
|
||||
}
|
30
components/driver/gpio/gpio_glitch_filter_ops.c
Normal file
30
components/driver/gpio/gpio_glitch_filter_ops.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "glitch_filter_priv.h"
|
||||
|
||||
static const char *TAG = "gpio-filter";
|
||||
|
||||
/////////// Public abstract functions ///////////
|
||||
|
||||
esp_err_t gpio_del_glitch_filter(gpio_glitch_filter_handle_t filter)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(filter, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
return filter->del(filter);
|
||||
}
|
||||
|
||||
esp_err_t gpio_glitch_filter_enable(gpio_glitch_filter_handle_t filter)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(filter, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
return filter->enable(filter);
|
||||
}
|
||||
|
||||
esp_err_t gpio_glitch_filter_disable(gpio_glitch_filter_handle_t filter)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(filter, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
return filter->disable(filter);
|
||||
}
|
69
components/driver/gpio/gpio_pin_glitch_filter.c
Normal file
69
components/driver/gpio/gpio_pin_glitch_filter.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_check.h"
|
||||
#include "glitch_filter_priv.h"
|
||||
#include "hal/gpio_ll.h"
|
||||
|
||||
static const char *TAG = "gpio-filter";
|
||||
|
||||
/**
|
||||
* @brief Type of GPIO pin glitch filter
|
||||
*/
|
||||
typedef struct gpio_pin_glitch_filter_t {
|
||||
gpio_glitch_filter_t base;
|
||||
} gpio_pin_glitch_filter_t;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_ll_pin_filter_enable(NULL, filter->gpio_num);
|
||||
filter->fsm = GLITCH_FILTER_FSM_ENABLE;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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_ll_pin_filter_disable(NULL, filter->gpio_num);
|
||||
filter->fsm = GLITCH_FILTER_FSM_INIT;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_new_pin_glitch_filter(const gpio_pin_glitch_filter_config_t *config, gpio_glitch_filter_handle_t *ret_filter)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
gpio_pin_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");
|
||||
|
||||
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");
|
||||
|
||||
filter->base.gpio_num = config->gpio_num;
|
||||
filter->base.fsm = GLITCH_FILTER_FSM_INIT;
|
||||
filter->base.del = gpio_pin_glitch_filter_del;
|
||||
filter->base.enable = gpio_pin_glitch_filter_enable;
|
||||
filter->base.disable = gpio_pin_glitch_filter_disable;
|
||||
|
||||
*ret_filter = &(filter->base);
|
||||
return ESP_OK;
|
||||
err:
|
||||
if (filter) {
|
||||
free(filter);
|
||||
}
|
||||
return ret;
|
||||
}
|
112
components/driver/include/driver/gpio_filter.h
Normal file
112
components/driver/include/driver/gpio_filter.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Typedef of GPIO glitch filter handle
|
||||
*/
|
||||
typedef struct gpio_glitch_filter_t *gpio_glitch_filter_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration of GPIO pin glitch filter
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_num_t gpio_num; /*!< GPIO number */
|
||||
} gpio_pin_glitch_filter_config_t;
|
||||
|
||||
/**
|
||||
* @brief Create a pin glitch filter
|
||||
*
|
||||
* @note Pin glitch filter parameters are fixed, pulses shorter than two sample clocks (IO-MUX's source clock) will be filtered out.
|
||||
* It's independent with "flex" glitch filter. See also `gpio_new_flex_glitch_filter`.
|
||||
* @note The created filter handle can later be deleted by `gpio_del_glitch_filter`.
|
||||
*
|
||||
* @param[in] config Glitch filter configuration
|
||||
* @param[out] ret_filter Returned glitch filter handle
|
||||
* @return
|
||||
* - ESP_OK: Create a pin glitch filter successfully
|
||||
* - ESP_ERR_INVALID_ARG: Create a pin glitch filter failed because of invalid arguments (e.g. wrong GPIO number)
|
||||
* - ESP_ERR_NO_MEM: Create a pin glitch filter failed because of out of memory
|
||||
* - ESP_FAIL: Create a pin glitch filter failed because of other error
|
||||
*/
|
||||
esp_err_t gpio_new_pin_glitch_filter(const gpio_pin_glitch_filter_config_t *config, gpio_glitch_filter_handle_t *ret_filter);
|
||||
|
||||
/**
|
||||
* @brief Configuration of GPIO flex glitch filter
|
||||
*/
|
||||
typedef struct {
|
||||
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. */
|
||||
} gpio_flex_glitch_filter_config_t;
|
||||
|
||||
/**
|
||||
* @brief Allocate a flex glitch filter
|
||||
*
|
||||
* @note "flex" means the filter parameters (window, threshold) are adjustable. It's independent with pin glitch filter.
|
||||
* See also `gpio_new_pin_glitch_filter`.
|
||||
* @note The created filter handle can later be deleted by `gpio_del_glitch_filter`.
|
||||
*
|
||||
* @param[in] config Glitch filter configuration
|
||||
* @param[out] ret_filter Returned glitch filter handle
|
||||
* @return
|
||||
* - ESP_OK: Allocate a flex glitch filter successfully
|
||||
* - ESP_ERR_INVALID_ARG: Allocate a flex glitch filter failed because of invalid arguments (e.g. wrong GPIO number, filter parameters out of range)
|
||||
* - ESP_ERR_NO_MEM: Allocate a flex glitch filter failed because of out of memory
|
||||
* - ESP_ERR_NOT_FOUND: Allocate a flex glitch filter failed because the underlying hardware resources are used up
|
||||
* - ESP_FAIL: Allocate a flex glitch filter failed because of other error
|
||||
*/
|
||||
esp_err_t gpio_new_flex_glitch_filter(const gpio_flex_glitch_filter_config_t *config, gpio_glitch_filter_handle_t *ret_filter);
|
||||
|
||||
/**
|
||||
* @brief Delete a glitch filter
|
||||
*
|
||||
* @param[in] filter Glitch filter handle returned from `gpio_new_flex_glitch_filter` or `gpio_new_pin_glitch_filter`
|
||||
* @return
|
||||
* - ESP_OK: Delete glitch filter successfully
|
||||
* - ESP_ERR_INVALID_ARG: Delete glitch filter failed because of invalid arguments
|
||||
* - ESP_ERR_INVALID_STATE: Delete glitch filter failed because the glitch filter is still in working
|
||||
* - ESP_FAIL: Delete glitch filter failed because of other error
|
||||
*/
|
||||
esp_err_t gpio_del_glitch_filter(gpio_glitch_filter_handle_t filter);
|
||||
|
||||
/**
|
||||
* @brief Enable a glitch filter
|
||||
*
|
||||
* @param[in] filter Glitch filter handle returned from `gpio_new_flex_glitch_filter` or `gpio_new_pin_glitch_filter`
|
||||
* @return
|
||||
* - ESP_OK: Enable glitch filter successfully
|
||||
* - ESP_ERR_INVALID_ARG: Enable glitch filter failed because of invalid arguments
|
||||
* - ESP_ERR_INVALID_STATE: Enable glitch filter failed because the glitch filter is already enabled
|
||||
* - ESP_FAIL: Enable glitch filter failed because of other error
|
||||
*/
|
||||
esp_err_t gpio_glitch_filter_enable(gpio_glitch_filter_handle_t filter);
|
||||
|
||||
/**
|
||||
* @brief Disable a glitch filter
|
||||
*
|
||||
* @param[in] filter Glitch filter handle returned from `gpio_new_flex_glitch_filter` or `gpio_new_pin_glitch_filter`
|
||||
* @return
|
||||
* - ESP_OK: Disable glitch filter successfully
|
||||
* - ESP_ERR_INVALID_ARG: Disable glitch filter failed because of invalid arguments
|
||||
* - ESP_ERR_INVALID_STATE: Disable glitch filter failed because the glitch filter is not enabled yet
|
||||
* - ESP_FAIL: Disable glitch filter failed because of other error
|
||||
*/
|
||||
esp_err_t gpio_glitch_filter_disable(gpio_glitch_filter_handle_t filter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -1,6 +1,10 @@
|
||||
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()
|
||||
|
151
components/driver/test_apps/gpio/main/test_gpio_filter.c
Normal file
151
components/driver/test_apps/gpio/main/test_gpio_filter.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "driver/gpio_filter.h"
|
||||
#include "driver/dedic_gpio.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
|
||||
TEST_CASE("GPIO pin glitch filter life cycle", "[gpio_filter]")
|
||||
{
|
||||
gpio_glitch_filter_handle_t filter = NULL;
|
||||
gpio_pin_glitch_filter_config_t config = {};
|
||||
TEST_ESP_OK(gpio_new_pin_glitch_filter(&config, &filter));
|
||||
|
||||
TEST_ESP_OK(gpio_glitch_filter_enable(filter));
|
||||
// can't delete filter if it's not disabled
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, gpio_del_glitch_filter(filter));
|
||||
|
||||
TEST_ESP_OK(gpio_glitch_filter_disable(filter));
|
||||
|
||||
TEST_ESP_OK(gpio_del_glitch_filter(filter));
|
||||
}
|
||||
|
||||
#endif // SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
|
||||
#if SOC_GPIO_FLEX_GLITCH_FILTER_NUM > 0
|
||||
|
||||
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 = {};
|
||||
|
||||
// install filter with wrong parameters
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_new_flex_glitch_filter(&config, &filters[0]));
|
||||
|
||||
config.window_thres_ns = 75;
|
||||
config.window_width_ns = 100;
|
||||
for (int i = 0; i < SOC_GPIO_FLEX_GLITCH_FILTER_NUM; i++) {
|
||||
TEST_ESP_OK((gpio_new_flex_glitch_filter(&config, &filters[i])));
|
||||
}
|
||||
// no more hardware resource
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, gpio_new_flex_glitch_filter(&config, &filters[0]));
|
||||
|
||||
TEST_ESP_OK(gpio_glitch_filter_enable(filters[0]));
|
||||
// can't delete filter if it's not disabled
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, gpio_del_glitch_filter(filters[0]));
|
||||
TEST_ESP_OK(gpio_glitch_filter_disable(filters[0]));
|
||||
|
||||
for (int i = 0; i < SOC_GPIO_FLEX_GLITCH_FILTER_NUM; i++) {
|
||||
TEST_ESP_OK(gpio_del_glitch_filter(filters[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief In order to generate the short glitch pulse, we use CPU CSR register to control the GPIO level,
|
||||
* which is also called the Fast GPIO or Dedicated GPIO.
|
||||
* @note Because the CPU instruction / CSR register is not compatible in all ESP chips,
|
||||
* at the moment, this test only works for Espressif's RISC-V core (e.g. ESP32C6)
|
||||
*/
|
||||
#if SOC_DEDICATED_GPIO_SUPPORTED
|
||||
|
||||
#include "hal/dedic_gpio_cpu_ll.h"
|
||||
|
||||
static void test_gpio_intr_callback(void *args)
|
||||
{
|
||||
SemaphoreHandle_t sem = (SemaphoreHandle_t)args;
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
esp_rom_printf("event fired\r\n");
|
||||
xSemaphoreGiveFromISR(sem, &high_task_wakeup);
|
||||
if (high_task_wakeup) {
|
||||
esp_rom_printf("high priority task wake up\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]")
|
||||
{
|
||||
const gpio_num_t test_gpio = 0;
|
||||
|
||||
printf("initialize GPIO for input and out\r\n");
|
||||
gpio_config_t gpio_cfg = {
|
||||
.mode = GPIO_MODE_INPUT_OUTPUT,
|
||||
.pin_bit_mask = BIT64(test_gpio),
|
||||
.intr_type = GPIO_INTR_POSEDGE,
|
||||
.pull_down_en = GPIO_PULLDOWN_ENABLE,
|
||||
};
|
||||
TEST_ESP_OK(gpio_config(&gpio_cfg));
|
||||
|
||||
printf("install fast gpio to generate the glitch signal\r\n");
|
||||
dedic_gpio_bundle_handle_t bundle = NULL;
|
||||
dedic_gpio_bundle_config_t bundle_cfg = {
|
||||
.gpio_array = (int[]){test_gpio},
|
||||
.array_size = 1,
|
||||
.flags.out_en = true,
|
||||
};
|
||||
TEST_ESP_OK(dedic_gpio_new_bundle(&bundle_cfg, &bundle));
|
||||
// initial output value to zero
|
||||
asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
|
||||
printf("apply glitch filter to the GPIO\r\n");
|
||||
gpio_glitch_filter_handle_t filter;
|
||||
gpio_flex_glitch_filter_config_t filter_cfg = {
|
||||
.gpio_num = test_gpio,
|
||||
.window_thres_ns = 1500, // pulse whose width is shorter than 1500 will be filtered out
|
||||
.window_width_ns = 1500,
|
||||
};
|
||||
TEST_ESP_OK((gpio_new_flex_glitch_filter(&filter_cfg, &filter)));
|
||||
TEST_ESP_OK(gpio_glitch_filter_enable(filter));
|
||||
|
||||
printf("install gpio interrupt\r\n");
|
||||
gpio_install_isr_service(0);
|
||||
SemaphoreHandle_t sem = xSemaphoreCreateBinary();
|
||||
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("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
|
||||
// should timeout, because the glitch is filtered out
|
||||
TEST_ASSERT_EQUAL(pdFALSE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
||||
|
||||
printf("disable the glitch filter\r\n");
|
||||
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("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
|
||||
|
||||
// this time we should see the GPIO interrupt fired up
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
||||
|
||||
TEST_ESP_OK(gpio_isr_handler_remove(test_gpio));
|
||||
gpio_uninstall_isr_service();
|
||||
|
||||
printf("disable gpio glitch filter\r\n");
|
||||
TEST_ESP_OK(gpio_del_glitch_filter(filter));
|
||||
TEST_ESP_OK(dedic_gpio_del_bundle(bundle));
|
||||
vSemaphoreDelete(sem);
|
||||
}
|
||||
|
||||
#endif // SOC_DEDICATED_GPIO_SUPPORTED
|
||||
#endif // SOC_GPIO_FLEX_GLITCH_FILTER_NUM > 0
|
@@ -284,6 +284,8 @@ TWAI_ISR_ATTR static void twai_intr_handler_main(void *arg)
|
||||
|
||||
static void twai_configure_gpio(gpio_num_t tx, gpio_num_t rx, gpio_num_t clkout, gpio_num_t bus_status)
|
||||
{
|
||||
// assert the GPIO number is not a negative number (shift operation on a negative number is undefined)
|
||||
assert(tx >= 0 && rx >= 0);
|
||||
int controller_id = p_twai_obj->controller_id;
|
||||
// if TX and RX set to the same GPIO, which means we want to create a loop-back in the GPIO matrix
|
||||
bool io_loop_back = (tx == rx);
|
||||
@@ -408,8 +410,8 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_
|
||||
TWAI_CHECK(t_config != NULL, ESP_ERR_INVALID_ARG);
|
||||
TWAI_CHECK(f_config != NULL, ESP_ERR_INVALID_ARG);
|
||||
TWAI_CHECK(g_config->rx_queue_len > 0, ESP_ERR_INVALID_ARG);
|
||||
TWAI_CHECK(g_config->tx_io >= 0 && g_config->tx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
|
||||
TWAI_CHECK(g_config->rx_io >= 0 && g_config->rx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
|
||||
TWAI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(g_config->tx_io), ESP_ERR_INVALID_ARG);
|
||||
TWAI_CHECK(GPIO_IS_VALID_GPIO(g_config->rx_io), ESP_ERR_INVALID_ARG);
|
||||
#ifndef CONFIG_TWAI_ISR_IN_IRAM
|
||||
TWAI_CHECK(!(g_config->intr_flags & ESP_INTR_FLAG_IRAM), ESP_ERR_INVALID_ARG);
|
||||
#endif
|
||||
|
@@ -185,7 +185,29 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
*/
|
||||
static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -193,7 +193,29 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
*/
|
||||
static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
|
66
components/hal/esp32c6/include/hal/gpio_glitch_filter_ll.h
Normal file
66
components/hal/esp32c6/include/hal/gpio_glitch_filter_ll.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 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
|
@@ -201,6 +201,28 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable output mode on GPIO.
|
||||
*
|
||||
|
@@ -193,6 +193,28 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_EN(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_DIS(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable output mode on GPIO.
|
||||
*
|
||||
|
@@ -193,6 +193,28 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_EN(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_DIS(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable output mode on GPIO.
|
||||
*
|
||||
|
@@ -187,7 +187,29 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
*/
|
||||
static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -200,7 +200,29 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
*/
|
||||
static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -207,6 +207,10 @@ config SOC_GPIO_PIN_COUNT
|
||||
int
|
||||
default 21
|
||||
|
||||
config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_SUPPORTS_RTC_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
@@ -65,6 +65,11 @@
|
||||
#define MCU_SEL_M (MCU_SEL_V << MCU_SEL_S)
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
/* Pin filter (Pulse width shorter than 2 clock cycles will be filtered out) */
|
||||
#define FILTER_EN (BIT(15))
|
||||
#define FILTER_EN_M (FILTER_EN_V << FILTER_EN_S)
|
||||
#define FILTER_EN_V 1
|
||||
#define FILTER_EN_S 15
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
@@ -86,6 +91,8 @@
|
||||
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN)
|
||||
#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN)
|
||||
|
||||
#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_XTAL_32K_P_U
|
||||
#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_XTAL_32K_N_U
|
||||
|
@@ -102,8 +102,9 @@
|
||||
|
||||
/*-------------------------- GPIO CAPS ---------------------------------------*/
|
||||
// ESP32-C2 has 1 GPIO peripheral
|
||||
#define SOC_GPIO_PORT (1U)
|
||||
#define SOC_GPIO_PIN_COUNT (21)
|
||||
#define SOC_GPIO_PORT 1U
|
||||
#define SOC_GPIO_PIN_COUNT 21
|
||||
#define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 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.
|
||||
|
@@ -299,6 +299,10 @@ config SOC_GPIO_PIN_COUNT
|
||||
int
|
||||
default 22
|
||||
|
||||
config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_SUPPORTS_RTC_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
@@ -64,6 +64,11 @@
|
||||
#define MCU_SEL_M (MCU_SEL_V << MCU_SEL_S)
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
/* Pin filter (Pulse width shorter than 2 clock cycles will be filtered out) */
|
||||
#define FILTER_EN (BIT(15))
|
||||
#define FILTER_EN_M (FILTER_EN_V << FILTER_EN_S)
|
||||
#define FILTER_EN_V 1
|
||||
#define FILTER_EN_S 15
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
@@ -85,6 +90,8 @@
|
||||
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN)
|
||||
#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN)
|
||||
|
||||
#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_XTAL_32K_P_U
|
||||
#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_XTAL_32K_N_U
|
||||
|
@@ -140,8 +140,9 @@
|
||||
|
||||
/*-------------------------- GPIO CAPS ---------------------------------------*/
|
||||
// ESP32-C3 has 1 GPIO peripheral
|
||||
#define SOC_GPIO_PORT (1U)
|
||||
#define SOC_GPIO_PIN_COUNT (22)
|
||||
#define SOC_GPIO_PORT 1U
|
||||
#define SOC_GPIO_PIN_COUNT 22
|
||||
#define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 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.
|
||||
|
@@ -279,6 +279,14 @@ config SOC_GPIO_PIN_COUNT
|
||||
int
|
||||
default 31
|
||||
|
||||
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
|
||||
|
@@ -70,22 +70,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;
|
||||
|
@@ -63,6 +63,11 @@
|
||||
#define MCU_SEL_M (MCU_SEL_V << MCU_SEL_S)
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
/* Pin filter (Pulse width shorter than 2 clock cycles will be filtered out) */
|
||||
#define FILTER_EN (BIT(15))
|
||||
#define FILTER_EN_M (FILTER_EN_V << FILTER_EN_S)
|
||||
#define FILTER_EN_V 1
|
||||
#define FILTER_EN_S 15
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
@@ -83,6 +88,8 @@
|
||||
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN)
|
||||
#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN)
|
||||
|
||||
#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_XTAL_32K_P_U
|
||||
#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_XTAL_32K_N_U
|
||||
|
@@ -150,8 +150,10 @@
|
||||
|
||||
/*-------------------------- GPIO CAPS ---------------------------------------*/
|
||||
// ESP32-C6 has 1 GPIO peripheral
|
||||
#define SOC_GPIO_PORT (1U)
|
||||
#define SOC_GPIO_PIN_COUNT (31)
|
||||
#define SOC_GPIO_PORT 1U
|
||||
#define SOC_GPIO_PIN_COUNT 31
|
||||
#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
|
||||
|
@@ -64,6 +64,11 @@
|
||||
#define MCU_SEL_M (MCU_SEL_V << MCU_SEL_S)
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
/* Pin filter (Pulse width shorter than 2 clock cycles will be filtered out) */
|
||||
#define FILTER_EN (BIT(15))
|
||||
#define FILTER_EN_M (FILTER_EN_V << FILTER_EN_S)
|
||||
#define FILTER_EN_V 1
|
||||
#define FILTER_EN_S 15
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
@@ -85,6 +90,8 @@
|
||||
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN)
|
||||
#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN)
|
||||
|
||||
#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_XTAL_32K_P_U
|
||||
#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_XTAL_32K_N_U
|
||||
|
@@ -63,6 +63,11 @@
|
||||
#define MCU_SEL_M (MCU_SEL_V << MCU_SEL_S)
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
/* Pin filter (Pulse width shorter than 2 clock cycles will be filtered out) */
|
||||
#define FILTER_EN (BIT(15))
|
||||
#define FILTER_EN_M (FILTER_EN_V << FILTER_EN_S)
|
||||
#define FILTER_EN_V 1
|
||||
#define FILTER_EN_S 15
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
@@ -83,6 +88,8 @@
|
||||
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN)
|
||||
#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN)
|
||||
|
||||
#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_GPIO0_U
|
||||
#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_GPIO1_U
|
||||
|
@@ -271,6 +271,10 @@ config SOC_GPIO_PORT
|
||||
int
|
||||
default 1
|
||||
|
||||
config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_PIN_COUNT
|
||||
int
|
||||
default 41
|
||||
|
@@ -137,7 +137,9 @@
|
||||
|
||||
/*-------------------------- GPIO CAPS ---------------------------------------*/
|
||||
// ESP32-H4 has 1 GPIO peripheral
|
||||
#define SOC_GPIO_PORT (1U)
|
||||
#define SOC_GPIO_PORT 1U
|
||||
#define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1
|
||||
#define SOC_GPIO_PIN_COUNT (41)
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2
|
||||
|
@@ -283,6 +283,10 @@ config SOC_GPIO_PIN_COUNT
|
||||
int
|
||||
default 47
|
||||
|
||||
config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_SUPPORT_RTC_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
@@ -64,6 +64,11 @@
|
||||
#define MCU_SEL_M (MCU_SEL_V << MCU_SEL_S)
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
/* Pin filter (Pulse width shorter than 2 clock cycles will be filtered out) */
|
||||
#define FILTER_EN (BIT(15))
|
||||
#define FILTER_EN_M (FILTER_EN_V << FILTER_EN_S)
|
||||
#define FILTER_EN_V 1
|
||||
#define FILTER_EN_S 15
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
@@ -84,6 +89,8 @@
|
||||
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN)
|
||||
#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN)
|
||||
|
||||
#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_GPIO0_U
|
||||
#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_GPIO1_U
|
||||
|
@@ -134,8 +134,9 @@
|
||||
|
||||
/*-------------------------- GPIO CAPS ---------------------------------------*/
|
||||
// ESP32-S2 has 1 GPIO peripheral
|
||||
#define SOC_GPIO_PORT (1U)
|
||||
#define SOC_GPIO_PIN_COUNT (47)
|
||||
#define SOC_GPIO_PORT 1U
|
||||
#define SOC_GPIO_PIN_COUNT 47
|
||||
#define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 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.
|
||||
|
@@ -347,6 +347,10 @@ config SOC_GPIO_PIN_COUNT
|
||||
int
|
||||
default 49
|
||||
|
||||
config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_SUPPORT_RTC_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
@@ -63,6 +63,11 @@
|
||||
#define MCU_SEL_M (MCU_SEL_V << MCU_SEL_S)
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
/* Pin filter (Pulse width shorter than 2 clock cycles will be filtered out) */
|
||||
#define FILTER_EN (BIT(15))
|
||||
#define FILTER_EN_M (FILTER_EN_V << FILTER_EN_S)
|
||||
#define FILTER_EN_V 1
|
||||
#define FILTER_EN_S 15
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
@@ -83,6 +88,8 @@
|
||||
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN)
|
||||
#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN)
|
||||
|
||||
#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_GPIO0_U
|
||||
#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_GPIO1_U
|
||||
|
@@ -142,8 +142,9 @@
|
||||
|
||||
/*-------------------------- GPIO CAPS ---------------------------------------*/
|
||||
// ESP32-S3 has 1 GPIO peripheral
|
||||
#define SOC_GPIO_PORT (1U)
|
||||
#define SOC_GPIO_PIN_COUNT (49)
|
||||
#define SOC_GPIO_PORT 1U
|
||||
#define SOC_GPIO_PIN_COUNT 49
|
||||
#define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 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)
|
||||
|
@@ -105,7 +105,6 @@ api-reference/peripherals/secure_element
|
||||
api-reference/peripherals/ledc
|
||||
api-reference/peripherals/sdio_slave
|
||||
api-reference/peripherals/clk_tree
|
||||
api-reference/peripherals/sdm
|
||||
api-reference/peripherals/touch_pad
|
||||
api-reference/peripherals/adc_calibration
|
||||
api-reference/peripherals/ds
|
||||
|
@@ -68,6 +68,7 @@ INPUT = \
|
||||
$(PROJECT_PATH)/components/driver/include/driver/dedic_gpio.h \
|
||||
$(PROJECT_PATH)/components/driver/include/driver/gpio.h \
|
||||
$(PROJECT_PATH)/components/driver/include/driver/gpio_etm.h \
|
||||
$(PROJECT_PATH)/components/driver/include/driver/gpio_filter.h \
|
||||
$(PROJECT_PATH)/components/driver/include/driver/gptimer.h \
|
||||
$(PROJECT_PATH)/components/driver/include/driver/gptimer_etm.h \
|
||||
$(PROJECT_PATH)/components/driver/include/driver/gptimer_types.h \
|
||||
|
@@ -21,6 +21,36 @@ GPIO Summary
|
||||
:SOC_ULP_SUPPORTED: - The :doc:`Ultra Low Power co-processor <../../api-reference/system/ulp>` is running
|
||||
- Analog functions such as ADC/DAC/etc are in use.
|
||||
|
||||
|
||||
.. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER or SOC_GPIO_FLEX_GLITCH_FILTER_NUM
|
||||
|
||||
GPIO Glitch Filter
|
||||
------------------
|
||||
|
||||
The {IDF_TARGET_NAME} chip features hardware filters to remove unwanted glitch pulses from the input GPIO, which can help reduce false triggering of the interrupt and prevent a noise being routed to the peripheral side.
|
||||
|
||||
.. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
|
||||
Each GPIO can be configured with a glitch filter, which can be used to filter out pulses shorter than **two** sample clock cycles. The duration of the filter is not configurable. The sample clock is the clock source of the IO-MUX. In the driver, we call this kind of filter as "pin glitch filter". You can create the filter handle by calling :cpp:func:`gpio_new_pin_glitch_filter`. All the configurations for a pin glitch filter are listed in the :cpp:type:`gpio_pin_glitch_filter_config_t` structure.
|
||||
|
||||
- :cpp:member:`gpio_pin_glitch_filter_config_t::gpio_num` sets the GPIO number to enable the glitch filter.
|
||||
|
||||
.. only:: SOC_GPIO_FLEX_GLITCH_FILTER_NUM
|
||||
|
||||
{IDF_TARGET_FLEX_GLITCH_FILTER_NUM:default="8"}
|
||||
|
||||
{IDF_TARGET_NAME} provides {IDF_TARGET_FLEX_GLITCH_FILTER_NUM} flexible glitch filters, whose duration is configurable. We refer to this kind of filter as "flex flitch filter". Each of them can be applied to any input GPIO. However, applying multiple filters to the same GPIO doesn't make difference from one. You can create the filter handle by calling :cpp:func:`gpio_new_flex_glitch_filter`. All the configurations for a flexible glitch filter are listed in the :cpp:type:`gpio_flex_glitch_filter_config_t` structure.
|
||||
|
||||
- :cpp:member:`gpio_flex_glitch_filter_config_t::gpio_num` sets the GPIO that will be applied the flex glitch filter.
|
||||
- :cpp:member:`gpio_flex_glitch_filter_config_t::window_width_ns` and :cpp:member:`gpio_flex_glitch_filter_config_t::window_thres_ns` are the key parameters of the glitch filter. During :cpp:member:`gpio_flex_glitch_filter_config_t::window_width_ns`, any pulse whose width is shorter than :cpp:member:`gpio_flex_glitch_filter_config_t::window_thres_ns` will be discarded. Please note that, you can't set :cpp:member:`gpio_flex_glitch_filter_config_t::window_thres_ns` bigger than :cpp:member:`gpio_flex_glitch_filter_config_t::window_width_ns`.
|
||||
|
||||
.. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER and SOC_GPIO_FLEX_GLITCH_FILTER_NUM
|
||||
|
||||
Please note, the "pin glitch filter" and "flex glitch filter" are independent. You can enable both of them for the same GPIO.
|
||||
|
||||
The glitch filter is disabled by default, and can be enabled by calling :cpp:func:`gpio_glitch_filter_enable`. To recycle the filter, you can call :cpp:func:`gpio_del_glitch_filter`. Please note, before deleting the filter, you should disable it first by calling :cpp:func:`gpio_glitch_filter_disable`.
|
||||
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
@@ -40,3 +70,11 @@ API Reference - Normal GPIO
|
||||
|
||||
.. include-build-file:: inc/rtc_io.inc
|
||||
.. include-build-file:: inc/rtc_io_types.inc
|
||||
|
||||
|
||||
.. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER or SOC_GPIO_FLEX_GLITCH_FILTER_NUM
|
||||
|
||||
API Reference - GPIO Glitch Filter
|
||||
----------------------------------
|
||||
|
||||
.. include-build-file:: inc/gpio_filter.inc
|
||||
|
@@ -21,6 +21,35 @@ GPIO 汇总
|
||||
:SOC_ULP_SUPPORTED: - :doc:`超低功耗协处理器 (ULP) <../../api-reference/system/ulp>` 运行时
|
||||
- 使用 ADC/DAC 等模拟功能时
|
||||
|
||||
.. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER or SOC_GPIO_FLEX_GLITCH_FILTER_NUM
|
||||
|
||||
GPIO 毛刺过滤器
|
||||
---------------
|
||||
|
||||
{IDF_TARGET_NAME} 内置硬件的过滤器可以帮助过滤掉 GPIO 输入端口上的毛刺信号, 这可以一定程度上避免错误地触发中断或者是错把噪声当成有效的外设信号。
|
||||
|
||||
.. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER
|
||||
|
||||
每个 GPIO 都可以使用独立的毛刺过滤器,该过滤器可以将那些脉冲宽度窄于 **2** 个采样时钟的信号剔除掉, 并且这个宽度是无法配置的。GPIO 对输入信号的采样时钟通常是 IO-MUX 的时钟源。在驱动中, 我们将此类过滤器称为 “pin glitch filter“。 你可以调用 :cpp:func:`gpio_new_pin_glitch_filter` 函数来创建一个过滤器句柄。过滤器的相关配置保存在 :cpp:type:`gpio_pin_glitch_filter_config_t` 结构体中。
|
||||
|
||||
- :cpp:member:`gpio_pin_glitch_filter_config_t::gpio_num` 设置哪个 GPIO 需要开启毛刺过滤器。
|
||||
|
||||
.. only:: SOC_GPIO_FLEX_GLITCH_FILTER_NUM
|
||||
|
||||
{IDF_TARGET_FLEX_GLITCH_FILTER_NUM:default="8"}
|
||||
|
||||
{IDF_TARGET_NAME} 提供了 {IDF_TARGET_FLEX_GLITCH_FILTER_NUM} 个灵活的毛刺过滤器, 被过滤信号的脉冲宽度可以由软件进行配置。我们称此类过滤器为 "flex flitch filter"。每个过滤器可以分配给任意一个 GPIO, 但是将多个过滤器应用在同一个 GPIO 上并不能带来更好的效果。你可以调用 :cpp:func:`gpio_new_flex_glitch_filter` 函数来创建一个过滤器句柄。过滤器的相关配置保存在 :cpp:type:`gpio_flex_glitch_filter_config_t` 结构体中。
|
||||
|
||||
- :cpp:member:`gpio_flex_glitch_filter_config_t::gpio_num` 设置哪个 GPIO 需要使用毛刺过滤器。
|
||||
- :cpp:member:`gpio_flex_glitch_filter_config_t::window_width_ns` 和 :cpp:member:`gpio_flex_glitch_filter_config_t::window_thres_ns` 是毛刺过滤器的关键参数。在:cpp:member:`gpio_flex_glitch_filter_config_t::window_width_ns` 时间内,任何脉冲信号,如果它的宽度小于 :cpp:member:`gpio_flex_glitch_filter_config_t::window_thres_ns`, 那么该脉冲信号就会被滤除掉。:cpp:member:`gpio_flex_glitch_filter_config_t::window_thres_ns` 的值不能大于 :cpp:member:`gpio_flex_glitch_filter_config_t::window_width_ns`。
|
||||
|
||||
.. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER and SOC_GPIO_FLEX_GLITCH_FILTER_NUM
|
||||
|
||||
请注意, "pin glitch filter" 和 "flex glitch filter" 是各自独立的,你可以给同一个 GPIO 同时启用他们两种滤波器。
|
||||
|
||||
毛刺滤波器默认情况下是处于关闭状态的, 你需要调用 :cpp:func:`gpio_glitch_filter_enable` 去使能它。如果要回收这个过滤器,你可以调用 :cpp:func:`gpio_del_glitch_filter` 函数。注意, 在你回收过滤器句柄之前, 请确保它是处于关闭状态的,如果不是,你需要调用 :cpp:func:`gpio_glitch_filter_disable`。
|
||||
|
||||
|
||||
应用示例
|
||||
-------------------
|
||||
|
||||
@@ -40,3 +69,10 @@ API 参考 - 普通 GPIO
|
||||
|
||||
.. include-build-file:: inc/rtc_io.inc
|
||||
.. include-build-file:: inc/rtc_io_types.inc
|
||||
|
||||
.. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER or SOC_GPIO_FLEX_GLITCH_FILTER_NUM
|
||||
|
||||
API 参考 - GPIO 毛刺过滤器
|
||||
--------------------------
|
||||
|
||||
.. include-build-file:: inc/gpio_filter.inc
|
||||
|
Reference in New Issue
Block a user