diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c index 8d58211bd8..95680ecce3 100644 --- a/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -13,21 +13,24 @@ * NOTE: To run this special feature test case, a slope analog signal is needed. * A simple RC circuit used here to generate continuous slope signal. * - * +---------+ - * | | - * | (intr)26|----------------+ C:1000uF - * | | | ++ + - * | (wave)27|______+-----+___+___|| |_____ - * | | +-----+ || | | - * | ESP32 | R:10k ++ + | - * | | | - * | GND|------------------------------+ - * +---------+ + * +--------------+ + * | | + * | (intr)HYS_IO |----------------+ C:1000uF + * | | | ++ + + * | (wave)WAVE_IO|______+-----+___+___|| |_____ + * | | +-----+ || | | + * | ESP32 | R:10k ++ + | + * | | | + * | GND |------------------------------+ + * +--------------+ * * or you can connect your slop signals from signal generator to ESP32 pin * which enabled the hysteresis feature directly to have a test. **/ +#define TEST_GPIO_HYS_IO 4 +#define TEST_GPIO_WAVE_IO 5 + static void test_gpio_hysteresis_intr_handler(void *args) { esp_rom_printf("%" PRIu32 "\n", ++ * ((uint32_t *)args)); @@ -36,37 +39,35 @@ static void test_gpio_hysteresis_intr_handler(void *args) // This case is now tested only manually TEST_CASE("GPIO Input hysteresis filter", "[gpio_filter][timeout=50][ignore]") { - const gpio_num_t TEST_HYS_IO = 26; - const gpio_num_t TEST_WAVE_IO = 27; uint32_t intr_cnt = 0; gpio_config_t gpio_cfg = { - .pin_bit_mask = (1 << TEST_WAVE_IO), + .pin_bit_mask = (1 << TEST_GPIO_WAVE_IO), .mode = GPIO_MODE_OUTPUT, .pull_down_en = GPIO_PULLDOWN_ENABLE, }; TEST_ESP_OK(gpio_config(&gpio_cfg)); - gpio_cfg.pin_bit_mask = 1 << TEST_HYS_IO; + gpio_cfg.pin_bit_mask = 1 << TEST_GPIO_HYS_IO; gpio_cfg.mode = GPIO_MODE_INPUT; gpio_cfg.intr_type = GPIO_INTR_ANYEDGE; gpio_cfg.hys_ctrl_mode = GPIO_HYS_SOFT_ENABLE; TEST_ESP_OK(gpio_config(&gpio_cfg)); gpio_install_isr_service(0); - gpio_isr_handler_add(TEST_HYS_IO, test_gpio_hysteresis_intr_handler, &intr_cnt); + gpio_isr_handler_add(TEST_GPIO_HYS_IO, test_gpio_hysteresis_intr_handler, &intr_cnt); // generate 5 rising and falling slopes to test gpio interrupt for (uint8_t i = 0; i < 5; i++) { printf("----falling %dth\n", i); - gpio_set_level(TEST_WAVE_IO, 0); + gpio_set_level(TEST_GPIO_WAVE_IO, 0); vTaskDelay(1500); printf("----rising %dth\n", i); - gpio_set_level(TEST_WAVE_IO, 1); + gpio_set_level(TEST_GPIO_WAVE_IO, 1); vTaskDelay(1500); } - gpio_isr_handler_remove(TEST_HYS_IO); + gpio_isr_handler_remove(TEST_GPIO_HYS_IO); gpio_uninstall_isr_service(); // should shot ISR exactly 10 times TEST_ASSERT_UINT32_WITHIN(1, 10, intr_cnt); diff --git a/components/hal/esp32c61/include/hal/gpio_ll.h b/components/hal/esp32c61/include/hal/gpio_ll.h index 1f38fea40e..930c53e4af 100644 --- a/components/hal/esp32c61/include/hal/gpio_ll.h +++ b/components/hal/esp32c61/include/hal/gpio_ll.h @@ -259,6 +259,31 @@ static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num) IO_MUX.gpion[gpio_num].gpion_filter_en = 0; } +/** + * @brief Enable GPIO hysteresis + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_pin_input_hysteresis_enable(gpio_dev_t *hw, uint32_t gpio_num) +{ + // Always set hys_sel to 1 to use software control hysteresis, since no efuse bit reserved for hysteresis on ESP32C61 + IO_MUX.gpion[gpio_num].gpion_hys_sel = 1; + IO_MUX.gpion[gpio_num].gpion_hys_en = 1; +} + +/** + * @brief Disable GPIO hysteresis + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_pin_input_hysteresis_disable(gpio_dev_t *hw, uint32_t gpio_num) +{ + IO_MUX.gpion[gpio_num].gpion_hys_sel = 1; + IO_MUX.gpion[gpio_num].gpion_hys_en = 0; +} + /** * @brief Disable output mode on GPIO. * diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 0284406515..b0f36b2348 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -231,6 +231,10 @@ config SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER bool default y +config SOC_GPIO_SUPPORT_PIN_HYS_FILTER + bool + default y + config SOC_GPIO_SUPPORT_RTC_INDEPENDENT bool default y diff --git a/components/soc/esp32c61/include/soc/io_mux_struct.h b/components/soc/esp32c61/include/soc/io_mux_struct.h index b1af65d8dc..3f2fec5452 100644 --- a/components/soc/esp32c61/include/soc/io_mux_struct.h +++ b/components/soc/esp32c61/include/soc/io_mux_struct.h @@ -102,8 +102,8 @@ typedef union { uint32_t gpion_hys_en:1; /** gpion_hys_sel : R/W; bitpos: [17]; default: 0; * Configures to choose the signal for enabling the hysteresis function for GPIOn. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIOn_HYS_EN\\ + * 0: Choose the output enable signal of eFuse, there is no efuse bit for it, should never set to 0\\ + * 1: Choose the output enable signal of IO_MUX_GPIOn_HYS_EN, always set to 1\\ */ uint32_t gpion_hys_sel:1; uint32_t reserved_18:14; diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index f3bedfa321..1fe6398e25 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -162,6 +162,7 @@ #define SOC_GPIO_PORT 1U #define SOC_GPIO_PIN_COUNT 22 #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 +#define SOC_GPIO_SUPPORT_PIN_HYS_FILTER 1 // GPIO peripheral has the ETM extension // \#define SOC_GPIO_SUPPORT_ETM 1 //TODO: [ESP32C61] IDF-9318