From 9994f493ed46d27c54fcbc202e871766ad2c4546 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 22 Aug 2024 15:21:17 +0800 Subject: [PATCH] feat(lp_io): Add LP_IO support for ESP32C61 --- .../test_apps/gpio/main/test_rtcio.c | 3 +- .../test_apps/gpio/main/test_rtcio.h | 19 + .../include/esp_private/io_mux.h | 3 +- .../esp_hw_support/port/esp32c61/io_mux.c | 36 +- components/hal/esp32c5/clk_tree_hal.c | 4 +- components/hal/esp32c5/include/hal/gpio_ll.h | 13 - components/hal/esp32c61/include/hal/gpio_ll.h | 13 - .../hal/esp32c61/include/hal/rtc_io_ll.h | 436 ++++++++++++++++++ .../soc/esp32c5/include/soc/io_mux_reg.h | 14 - .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 - components/soc/esp32c6/include/soc/soc_caps.h | 1 - .../esp32c61/include/soc/Kconfig.soc_caps.in | 20 + .../soc/esp32c61/include/soc/io_mux_reg.h | 37 -- .../soc/{lp_io_mux_reg.h => lp_iomux_reg.h} | 0 .../{lp_io_mux_struct.h => lp_iomux_struct.h} | 0 .../soc/esp32c61/include/soc/rtc_io_channel.h | 28 ++ .../soc/esp32c61/include/soc/soc_caps.h | 24 +- components/soc/esp32c61/rtc_io_periph.c | 32 ++ .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 - components/soc/esp32h2/include/soc/soc_caps.h | 1 - docs/docs_not_updated/esp32c61.txt | 1 - .../peripherals/gpio/esp32c61.inc | 12 +- .../peripherals/gpio/esp32c61.inc | 12 +- 23 files changed, 600 insertions(+), 117 deletions(-) create mode 100644 components/hal/esp32c61/include/hal/rtc_io_ll.h rename components/soc/esp32c61/include/soc/{lp_io_mux_reg.h => lp_iomux_reg.h} (100%) rename components/soc/esp32c61/include/soc/{lp_io_mux_struct.h => lp_iomux_struct.h} (100%) create mode 100644 components/soc/esp32c61/include/soc/rtc_io_channel.h create mode 100644 components/soc/esp32c61/rtc_io_periph.c diff --git a/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c index 9f34d0480c..cc1f4db8cf 100644 --- a/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c @@ -238,8 +238,7 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") #if SOC_DEEP_SLEEP_SUPPORTED && SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP // It is not necessary to test every rtcio pin, it will take too much ci testing time for deep sleep // Only tests on s_test_map[TEST_RTCIO_DEEP_SLEEP_PIN_INDEX] pin -// (ESP32: IO25, ESP32S2, S3: IO6, C6: IO5, H2: IO12, C5: IO5) these pads' default configuration is low level -#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 +// These pads' default configuration is low level static void rtcio_deep_sleep_hold_test_first_stage(void) { diff --git a/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h index af9241a98e..e3518e7428 100644 --- a/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h @@ -37,6 +37,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = { GPIO_NUM_38, //GPIO38 GPIO_NUM_39, //GPIO39 }; +#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO25 #elif defined CONFIG_IDF_TARGET_ESP32S2 // Has no input-only rtcio pins, all pins support pull-up/down #define RTCIO_SUPPORT_PU_PD(num) 1 @@ -65,6 +66,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = { GPIO_NUM_20, //GPIO20 GPIO_NUM_21, //GPIO21 }; +#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO6 #elif defined CONFIG_IDF_TARGET_ESP32S3 // Has no input-only rtcio pins, all pins support pull-up/down #define RTCIO_SUPPORT_PU_PD(num) 1 @@ -93,6 +95,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = { GPIO_NUM_20, //GPIO20 GPIO_NUM_21, //GPIO21 }; +#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO6 #elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C5 // Has no input-only rtcio pins, all pins support pull-up/down #define RTCIO_SUPPORT_PU_PD(num) 1 @@ -107,6 +110,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = { GPIO_NUM_6, //GPIO6 GPIO_NUM_7, //GPIO7 }; +#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO5 #elif CONFIG_IDF_TARGET_ESP32H2 #define TEST_GPIO_PIN_COUNT 8 const int s_test_map[TEST_GPIO_PIN_COUNT] = { @@ -119,6 +123,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = { GPIO_NUM_13, //GPIO13 GPIO_NUM_14, //GPIO14 }; +#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO12 #elif CONFIG_IDF_TARGET_ESP32P4 // Has no input-only rtcio pins, all pins support pull-up/down #define RTCIO_SUPPORT_PU_PD(num) 1 @@ -141,6 +146,20 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = { GPIO_NUM_14, //GPIO14 GPIO_NUM_15, //GPIO15 }; +#elif CONFIG_IDF_TARGET_ESP32C61 +// Has no input-only rtcio pins, all pins support pull-up/down +#define RTCIO_SUPPORT_PU_PD(num) 1 +#define TEST_GPIO_PIN_COUNT 7 +const int s_test_map[TEST_GPIO_PIN_COUNT] = { + GPIO_NUM_0, //GPIO0 + GPIO_NUM_1, //GPIO1 + GPIO_NUM_2, //GPIO2 + GPIO_NUM_3, //GPIO3 + GPIO_NUM_4, //GPIO4 + GPIO_NUM_5, //GPIO5 + GPIO_NUM_6, //GPIO6 +}; +#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 6 // IO6 #endif #ifdef __cplusplus diff --git a/components/esp_hw_support/include/esp_private/io_mux.h b/components/esp_hw_support/include/esp_private/io_mux.h index dd8ea49ffb..62d5c4d76d 100644 --- a/components/esp_hw_support/include/esp_private/io_mux.h +++ b/components/esp_hw_support/include/esp_private/io_mux.h @@ -37,7 +37,8 @@ typedef struct { } rtc_io_status_t; /** - * Enable/Disable LP_IO peripheral clock. + * @brief Enable/Disable LP_IO peripheral clock + * * @param gpio_num GPIO number * @param enable true to enable the clock / false to disable the clock */ diff --git a/components/esp_hw_support/port/esp32c61/io_mux.c b/components/esp_hw_support/port/esp32c61/io_mux.c index 326e0bf901..46ab45360c 100644 --- a/components/esp_hw_support/port/esp32c61/io_mux.c +++ b/components/esp_hw_support/port/esp32c61/io_mux.c @@ -6,13 +6,23 @@ #include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" +#include "esp_private/periph_ctrl.h" #include "hal/gpio_ll.h" +#include "hal/rtc_io_ll.h" -//TODO: [ESP32C61] IDf-9316 +#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() 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) +#if CONFIG_ULP_COPROC_ENABLED +RTC_DATA_ATTR +#endif +static rtc_io_status_t s_rtc_io_status = { + .rtc_io_enabled_cnt = { 0 }, + .rtc_io_using_mask = 0 +}; + esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) { bool clk_conflict = false; @@ -33,3 +43,27 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) return ESP_OK; } + +void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) +{ + portENTER_CRITICAL(&s_io_mux_spinlock); + if (enable) { + if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); + } + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++; + } else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) { + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--; + if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); + } + } + RTCIO_RCC_ATOMIC() { + if (s_rtc_io_status.rtc_io_using_mask == 0) { + rtcio_ll_enable_io_clock(false); + } else { + rtcio_ll_enable_io_clock(true); + } + } + portEXIT_CRITICAL(&s_io_mux_spinlock); +} diff --git a/components/hal/esp32c5/clk_tree_hal.c b/components/hal/esp32c5/clk_tree_hal.c index 15851b6c79..d7d648db89 100644 --- a/components/hal/esp32c5/clk_tree_hal.c +++ b/components/hal/esp32c5/clk_tree_hal.c @@ -73,10 +73,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) { - gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); + abort(); // TODO: IDF-10968 } void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) { - gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); + abort(); // TODO: IDF-10968 } diff --git a/components/hal/esp32c5/include/hal/gpio_ll.h b/components/hal/esp32c5/include/hal/gpio_ll.h index 1fd8241047..fdb79756f1 100644 --- a/components/hal/esp32c5/include/hal/gpio_ll.h +++ b/components/hal/esp32c5/include/hal/gpio_ll.h @@ -488,19 +488,6 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) PIN_FUNC_SELECT(pin_name, func); } -/** - * @brief Control the pin in the IOMUX - * - * @param bmap write mask of control value - * @param val Control value - * @param shift write mask shift of control value - */ -__attribute__((always_inline)) -static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) -{ - SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); -} - /** * @brief Select a function for the pin in the IOMUX * diff --git a/components/hal/esp32c61/include/hal/gpio_ll.h b/components/hal/esp32c61/include/hal/gpio_ll.h index 930c53e4af..b9327b68ce 100644 --- a/components/hal/esp32c61/include/hal/gpio_ll.h +++ b/components/hal/esp32c61/include/hal/gpio_ll.h @@ -486,19 +486,6 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) PIN_FUNC_SELECT(pin_name, func); } -/** - * @brief Control the pin in the IOMUX - * - * @param bmap write mask of control value - * @param val Control value - * @param shift write mask shift of control value - */ -__attribute__((always_inline)) -static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift) -{ - SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift); -} - /** * @brief Select a function for the pin in the IOMUX * diff --git a/components/hal/esp32c61/include/hal/rtc_io_ll.h b/components/hal/esp32c61/include/hal/rtc_io_ll.h new file mode 100644 index 0000000000..60bd5fd7d0 --- /dev/null +++ b/components/hal/esp32c61/include/hal/rtc_io_ll.h @@ -0,0 +1,436 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "soc/soc_caps.h" +#include "soc/pcr_struct.h" +#include "soc/lp_iomux_struct.h" +#include "soc/lp_aon_struct.h" +#include "soc/lp_gpio_struct.h" +#include "soc/lpperi_struct.h" +#include "soc/pmu_struct.h" +#include "hal/misc.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTCIO_LL_PIN_FUNC 1 + +typedef enum { + RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */ + RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ +} rtcio_ll_func_t; + +typedef enum { + RTCIO_LL_WAKEUP_DISABLE = 0, /*!< Disable GPIO interrupt */ + RTCIO_LL_WAKEUP_LOW_LEVEL = 0x4, /*!< GPIO interrupt type : input low level trigger */ + RTCIO_LL_WAKEUP_HIGH_LEVEL = 0x5, /*!< GPIO interrupt type : input high level trigger */ +} rtcio_ll_wake_type_t; + +typedef enum { + RTCIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */ + RTCIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */ + RTCIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */ + RTCIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */ + RTCIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */ + RTCIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */ +} rtcio_ll_intr_type_t; + +typedef enum { + RTCIO_LL_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */ + RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */ +} rtcio_ll_out_mode_t; + +/** + * @brief Select a RTC IOMUX function for the RTC IO + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param func Function to assign to the pin + */ +static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_sel = func; +} + +/** + * @brief Enable/Disable LP_GPIO peripheral clock. + * + * @param enable true to enable the clock / false to disable the clock + */ +static inline void _rtcio_ll_enable_io_clock(bool enable) +{ + LPPERI.clk_en.lp_io_ck_en = enable; + while (LPPERI.clk_en.lp_io_ck_en != enable) { + ; + } +} + +#define rtcio_ll_enable_io_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _rtcio_ll_enable_io_clock(__VA_ARGS__) + +/** + * @brief Select the rtcio function. + * + * @note The RTC function must be selected before the pad analog function is enabled. + * @note The clock gating 'PCR.iomux_conf.iomux_clk_en' is the gate of both 'lp_io' and 'etm_gpio' + * And it's default to be turned on, so we don't need to operate this clock gate here additionally + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param func Select pin function. + */ +static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) +{ + if (func == RTCIO_LL_FUNC_RTC) { + // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. + uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + sel_mask |= BIT(rtcio_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + // LP_GPIO is FUNC 1 + rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC); + } else if (func == RTCIO_LL_FUNC_DIGITAL) { + // Clear the bit to use digital GPIO module + uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + sel_mask &= ~BIT(rtcio_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + } +} + +/** + * Enable rtcio output. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_output_enable(int rtcio_num) +{ + LP_GPIO.enable_w1ts.enable_w1ts = BIT(rtcio_num); +} + +/** + * Disable rtcio output. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_output_disable(int rtcio_num) +{ + LP_GPIO.enable_w1tc.enable_w1tc = BIT(rtcio_num); +} + +/** + * Set RTCIO output level. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param level 0: output low; ~0: output high. + */ +static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) +{ + if (level) { + LP_GPIO.out_w1ts.out_w1ts = BIT(rtcio_num); + } else { + LP_GPIO.out_w1tc.out_w1tc = BIT(rtcio_num); + } +} + +/** + * Enable rtcio input. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_input_enable(int rtcio_num) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_ie = 1; +} + +/** + * Disable rtcio input. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_input_disable(int rtcio_num) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_ie = 0; +} + +/** + * Get RTCIO input level. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return 0: input low; ~0: input high. + */ +static inline uint32_t rtcio_ll_get_level(int rtcio_num) +{ + return (LP_GPIO.in.in_data_next >> rtcio_num) & 0x1; +} + +/** + * @brief Set RTC GPIO pad drive capability + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param strength Drive capability of the pad. Range: 0 ~ 3. + */ +static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_drv = strength; +} + +/** + * @brief Get RTC GPIO pad drive capability. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Drive capability of the pad. Range: 0 ~ 3. + */ +static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num) +{ + return LP_IO_MUX.gpion[rtcio_num].gpion_fun_drv; +} + +/** + * @brief Set RTC GPIO pad output mode. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return mode Output mode. + */ +static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t mode) +{ + LP_GPIO.pinn[rtcio_num].pinn_pad_driver = mode; +} + +/** + * RTC GPIO pullup enable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pullup_enable(int rtcio_num) +{ + /* Enable internal weak pull-up */ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu = 1; +} + +/** + * RTC GPIO pullup disable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pullup_disable(int rtcio_num) +{ + /* Disable internal weak pull-up */ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu = 0; +} + +/** + * RTC GPIO pulldown enable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pulldown_enable(int rtcio_num) +{ + /* Enable internal weak pull-down */ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd = 1; +} + +/** + * RTC GPIO pulldown disable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pulldown_disable(int rtcio_num) +{ + /* Enable internal weak pull-down */ + LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd = 0; +} + +/** + * Enable force hold function for an RTC IO pad. + * + * Enabling HOLD function will cause the pad to lock current status, such as, + * input/output enable, input/output value, function, drive strength values. + * This function is useful when going into light or deep sleep mode to prevent + * the pin configuration from changing. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_force_hold_enable(int rtcio_num) +{ + LP_AON.gpio_hold0.gpio_hold0 |= BIT(rtcio_num); +} + +/** + * Disable hold function on an RTC IO pad + * + * @note If disable the pad hold, the status of pad maybe changed in sleep mode. + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_force_hold_disable(int rtcio_num) +{ + LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num); +} + +/** + * Enable force hold function for all RTC IO pads + * + * Enabling HOLD function will cause the pad to lock current status, such as, + * input/output enable, input/output value, function, drive strength values. + * This function is useful when going into light or deep sleep mode to prevent + * the pin configuration from changing. + */ +static inline void rtcio_ll_force_hold_all(void) +{ + PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1; +} + +/** + * Disable hold function fon all RTC IO pads + * + * @note If disable the pad hold, the status of pad maybe changed in sleep mode. + */ +static inline void rtcio_ll_force_unhold_all(void) +{ + PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1; +} + +/** + * Enable wakeup function and set wakeup type from light sleep or deep sleep for rtcio. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param type Wakeup on high level or low level. + */ +static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type) +{ + LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable = 1; + LP_GPIO.pinn[rtcio_num].pinn_int_type = type; +} + +/** + * Disable wakeup function from light sleep or deep sleep for rtcio. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_wakeup_disable(int rtcio_num) +{ + LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable = 0; + LP_GPIO.pinn[rtcio_num].pinn_int_type = RTCIO_LL_WAKEUP_DISABLE; +} + +/** + * Enable interrupt function and set interrupt type + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param type Interrupt type on high level or low level. + */ + +static inline void rtcio_ll_intr_enable(int rtcio_num, rtcio_ll_intr_type_t type) +{ + LP_GPIO.pinn[rtcio_num].pinn_int_type = type; + + /* Work around for HW issue, + need to also enable this clk, so that LP_GPIO.status.status_interrupt can get updated, + and trigger the interrupt on the LP Core + */ + LP_GPIO.clock_gate.clk_en = 1; +} + +/** + * Enable rtc io output in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_output_in_sleep(int rtcio_num) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_oe = 1; +} + +/** + * Disable rtc io output in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_output_in_sleep(int rtcio_num) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_oe = 0; +} + +/** + * Enable rtc io input in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_input_in_sleep(int rtcio_num) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_ie = 1; +} + +/** + * Disable rtc io input in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_input_in_sleep(int rtcio_num) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_mcu_ie = 0; +} + +/** + * Enable rtc io keep another setting in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_sleep_setting(int rtcio_num) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_slp_sel = 1; +} + +/** + * Disable rtc io keep another setting in deep sleep. (Default) + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_sleep_setting(int rtcio_num) +{ + LP_IO_MUX.gpion[rtcio_num].gpion_slp_sel = 0; +} + +/** + * @brief Get the status of whether an IO is used for sleep wake-up. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return True if the pin is enabled to wake up from deep-sleep + */ +static inline bool rtcio_ll_wakeup_is_enabled(int rtcio_num) +{ + HAL_ASSERT(rtcio_num >= 0 && rtcio_num < SOC_RTCIO_PIN_COUNT && "io does not support deep sleep wake-up function"); + return LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable; +} + +/** + * @brief Get the rtc io interrupt status + * + * @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT. + */ +static inline uint32_t rtcio_ll_get_interrupt_status(void) +{ + return LP_GPIO.status.status_interrupt; +} + +/** + * @brief Clear all LP IO pads status + */ +static inline void rtcio_ll_clear_interrupt_status(void) +{ + LP_GPIO.status_w1tc.status_w1tc = 0x7F; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c5/include/soc/io_mux_reg.h b/components/soc/esp32c5/include/soc/io_mux_reg.h index cfb47a0e87..c5e4f2a87d 100644 --- a/components/soc/esp32c5/include/soc/io_mux_reg.h +++ b/components/soc/esp32c5/include/soc/io_mux_reg.h @@ -150,20 +150,6 @@ extern "C" { #define DIG_IO_HOLD_BIT_SHIFT 32 #define REG_IO_MUX_BASE DR_REG_IO_MUX_BASE -#define PIN_CTRL (REG_IO_MUX_BASE +0x00) - -#define CLK_OUT3 0x1f -#define CLK_OUT3_V CLK_OUT3 -#define CLK_OUT3_S 10 -#define CLK_OUT3_M (CLK_OUT3_V << CLK_OUT3_S) -#define CLK_OUT2 0x1f -#define CLK_OUT2_V CLK_OUT2 -#define CLK_OUT2_S 5 -#define CLK_OUT2_M (CLK_OUT2_V << CLK_OUT2_S) -#define CLK_OUT1 0x1f -#define CLK_OUT1_V CLK_OUT1 -#define CLK_OUT1_S 0 -#define CLK_OUT1_M (CLK_OUT1_V << CLK_OUT1_S) // definitions above are inherited from previous version of code, should double check // definitions below are generated from pin_txt.csv diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index b622e04558..0a1aa7da1f 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -551,10 +551,6 @@ config SOC_RTCIO_WAKE_SUPPORTED bool default y -config SOC_RTCIO_VALID_RTCIO_MASK - hex - default 0xFF - config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM int default 8 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index e432d7c75a..e55ed60b86 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -229,7 +229,6 @@ */ #define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_WAKE_SUPPORTED 1 -#define SOC_RTCIO_VALID_RTCIO_MASK (0xFF) /*-------------------------- Dedicated GPIO CAPS -----------------------------*/ #define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */ diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 7ff622e2f5..95a8367156 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -255,6 +255,10 @@ config SOC_GPIO_SUPPORT_RTC_INDEPENDENT bool default y +config SOC_LP_IO_CLOCK_IS_INDEPENDENT + bool + default y + config SOC_GPIO_IN_RANGE_MAX int default 21 @@ -291,6 +295,22 @@ config SOC_GPIO_CLOCKOUT_CHANNEL_NUM int default 3 +config SOC_RTCIO_PIN_COUNT + int + default 7 + +config SOC_RTCIO_INPUT_OUTPUT_SUPPORTED + bool + default y + +config SOC_RTCIO_HOLD_SUPPORTED + bool + default y + +config SOC_RTCIO_WAKE_SUPPORTED + bool + default y + config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM int default 8 diff --git a/components/soc/esp32c61/include/soc/io_mux_reg.h b/components/soc/esp32c61/include/soc/io_mux_reg.h index 11a3520c6b..fff0c3fa6e 100644 --- a/components/soc/esp32c61/include/soc/io_mux_reg.h +++ b/components/soc/esp32c61/include/soc/io_mux_reg.h @@ -135,43 +135,6 @@ extern "C" { #define HIGH_IO_HOLD_BIT_SHIFT 32 #define REG_IO_MUX_BASE DR_REG_IO_MUX_BASE -#define PIN_CTRL (REG_IO_MUX_BASE +0x00) -#define PAD_POWER_SEL BIT(15) -#define PAD_POWER_SEL_V 0x1 -#define PAD_POWER_SEL_M BIT(15) -#define PAD_POWER_SEL_S 15 - -#define PAD_POWER_SWITCH_DELAY 0x7 -#define PAD_POWER_SWITCH_DELAY_V 0x7 -#define PAD_POWER_SWITCH_DELAY_M (PAD_POWER_SWITCH_DELAY_V << PAD_POWER_SWITCH_DELAY_S) -#define PAD_POWER_SWITCH_DELAY_S 12 - -//TODO: [ESP32C61] IDF-9316, copy from verify -#define IO_MUX_CLK_OUT3 0x0000000F -#define IO_MUX_CLK_OUT3_M ((IO_MUX_CLK_OUT3_V)<<(IO_MUX_CLK_OUT3_S)) -#define IO_MUX_CLK_OUT3_V 0xF -#define IO_MUX_CLK_OUT3_S 8 -#define IO_MUX_CLK_OUT2 0x0000000F -#define IO_MUX_CLK_OUT2_M ((IO_MUX_CLK_OUT2_V)<<(IO_MUX_CLK_OUT2_S)) -#define IO_MUX_CLK_OUT2_V 0xF -#define IO_MUX_CLK_OUT2_S 4 -#define IO_MUX_CLK_OUT1 0x0000000F -#define IO_MUX_CLK_OUT1_M ((IO_MUX_CLK_OUT1_V)<<(IO_MUX_CLK_OUT1_S)) -#define IO_MUX_CLK_OUT1_V 0xF -#define IO_MUX_CLK_OUT1_S 0 - -#define CLK_OUT3 IO_MUX_CLK_OUT3 -#define CLK_OUT3_V IO_MUX_CLK_OUT3_V -#define CLK_OUT3_S IO_MUX_CLK_OUT3_S -#define CLK_OUT3_M IO_MUX_CLK_OUT3_M -#define CLK_OUT2 IO_MUX_CLK_OUT2 -#define CLK_OUT2_V IO_MUX_CLK_OUT2_V -#define CLK_OUT2_S IO_MUX_CLK_OUT2_S -#define CLK_OUT2_M IO_MUX_CLK_OUT2_M -#define CLK_OUT1 IO_MUX_CLK_OUT1 -#define CLK_OUT1_V IO_MUX_CLK_OUT1_V -#define CLK_OUT1_S IO_MUX_CLK_OUT1_S -#define CLK_OUT1_M IO_MUX_CLK_OUT1_M // definitions above are inherited from previous version of code, should double check // definitions below are generated from pin_txt.csv diff --git a/components/soc/esp32c61/include/soc/lp_io_mux_reg.h b/components/soc/esp32c61/include/soc/lp_iomux_reg.h similarity index 100% rename from components/soc/esp32c61/include/soc/lp_io_mux_reg.h rename to components/soc/esp32c61/include/soc/lp_iomux_reg.h diff --git a/components/soc/esp32c61/include/soc/lp_io_mux_struct.h b/components/soc/esp32c61/include/soc/lp_iomux_struct.h similarity index 100% rename from components/soc/esp32c61/include/soc/lp_io_mux_struct.h rename to components/soc/esp32c61/include/soc/lp_iomux_struct.h diff --git a/components/soc/esp32c61/include/soc/rtc_io_channel.h b/components/soc/esp32c61/include/soc/rtc_io_channel.h new file mode 100644 index 0000000000..36b9b5f80e --- /dev/null +++ b/components/soc/esp32c61/include/soc/rtc_io_channel.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#define RTCIO_GPIO0_CHANNEL 0 //RTCIO_CHANNEL_0 +#define RTCIO_CHANNEL_0_GPIO_NUM 0 + +#define RTCIO_GPIO1_CHANNEL 1 //RTCIO_CHANNEL_1 +#define RTCIO_CHANNEL_1_GPIO_NUM 1 + +#define RTCIO_GPIO2_CHANNEL 2 //RTCIO_CHANNEL_2 +#define RTCIO_CHANNEL_2_GPIO_NUM 2 + +#define RTCIO_GPIO3_CHANNEL 3 //RTCIO_CHANNEL_3 +#define RTCIO_CHANNEL_3_GPIO_NUM 3 + +#define RTCIO_GPIO4_CHANNEL 4 //RTCIO_CHANNEL_4 +#define RTCIO_CHANNEL_4_GPIO_NUM 4 + +#define RTCIO_GPIO5_CHANNEL 5 //RTCIO_CHANNEL_5 +#define RTCIO_CHANNEL_5_GPIO_NUM 5 + +#define RTCIO_GPIO6_CHANNEL 6 //RTCIO_CHANNEL_6 +#define RTCIO_CHANNEL_6_GPIO_NUM 6 diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index 00f1b32b98..367c260d8b 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -167,8 +167,9 @@ // Target has the full LP IO subsystem // On ESP32-C61, Digital IOs have their own registers to control pullup/down capability, independent of LP registers. #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) -// GPIO0~7 on ESP32C61 can support chip deep sleep wakeup -// \#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) //TODO:reopen + +// LP IO peripherals have independent clock gating to manage +#define SOC_LP_IO_CLOCK_IS_INDEPENDENT (1) #define SOC_GPIO_VALID_GPIO_MASK ((1U<`__. + - Some pins are used as strapping pins, which can be used to select in which boot mode to load the chip, etc.. The details can be found in `datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`_ > ``Strapping Pins``. - SPI0/1: GPIO14 ~ GPIO17 and GPIO19 ~ GPIO21 are usually used for SPI flash and not recommended for other uses. - USB-JTAG: GPIO12 and GPIO13 are used by USB-JTAG by default. If they are reconfigured to operate as normal GPIOs, USB-JTAG functionality will be disabled. diff --git a/docs/zh_CN/api-reference/peripherals/gpio/esp32c61.inc b/docs/zh_CN/api-reference/peripherals/gpio/esp32c61.inc index 016cd77ce5..43ab080398 100644 --- a/docs/zh_CN/api-reference/peripherals/gpio/esp32c61.inc +++ b/docs/zh_CN/api-reference/peripherals/gpio/esp32c61.inc @@ -40,12 +40,12 @@ * - GPIO3 - ADC1_CH1 - LP_GPIO3 - - Strapping 管脚 + - * - GPIO4 - ADC1_CH2 - LP_GPIO4 - - Strapping 管脚 + - * - GPIO5 - ADC1_CH3 @@ -60,17 +60,17 @@ * - GPIO7 - - - - Strapping 管脚 + - * - GPIO8 - - - - Strapping 管脚 + - * - GPIO9 - - - - Strapping 管脚 + - * - GPIO10 - @@ -134,7 +134,7 @@ .. note:: - - Strapping 管脚:GPIO3、GPIO4、GPIO7、GPIO8 和 GPIO9 是 Strapping 管脚。更多信息请参考 `ESP32-C61 技术规格书 <{IDF_TARGET_DATASHEET_CN_URL}>`_。 + - 其中一些管脚被用作 Strapping 管脚,可用于选择加载芯片的启动模式等。详细信息可以在 `ESP32-C61 技术规格书 <{IDF_TARGET_DATASHEET_CN_URL}>`_ > ``Strapping 管脚`` 章节中找到。 - SPI0/1:GPIO14 ~ GPIO17 和 GPIO19 ~ GPIO21 通常用于 SPI flash,不推荐用于其他用途。 - USB-JTAG:GPIO12 和 GPIO13 默认用于 USB-JTAG。如果将它们配置为普通 GPIO,驱动程序将禁用 USB-JTAG 功能。