Merge branch 'feature/esp32h4_rtcio_support' into 'master'

feat(lp_io): Add LP_IO support for ESP32H4

Closes IDF-12393

See merge request espressif/esp-idf!40599
This commit is contained in:
Song Ruo Jing
2025-07-28 19:58:05 +08:00
19 changed files with 887 additions and 184 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -18,6 +18,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "soc/rtc_io_periph.h" #include "soc/rtc_io_periph.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/rtc_io_ll.h"
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
static const char *TAG = "rtcio_test"; static const char *TAG = "rtcio_test";
@@ -233,6 +234,48 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]")
ESP_LOGI(TAG, "RTCIO hold test over"); ESP_LOGI(TAG, "RTCIO hold test over");
} }
#endif //SOC_RTCIO_HOLD_SUPPORTED #endif //SOC_RTCIO_HOLD_SUPPORTED
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT > 0)
/*
* test interrupt functionality
*/
TEST_CASE("RTCIO_interrupt_test", "[rtcio]")
{
gpio_num_t test_io = s_test_map[TEST_RTCIO_INTR_PIN_INDEX];
uint32_t rtc_io_idx = rtc_io_number_get(test_io);
TEST_ESP_OK(rtc_gpio_init(test_io));
TEST_ESP_OK(rtc_gpio_set_direction(test_io, RTC_GPIO_MODE_INPUT_OUTPUT));
TEST_ESP_OK(rtc_gpio_set_level(test_io, 0));
rtcio_ll_intr_enable(test_io, GPIO_INTR_HIGH_LEVEL);
int cnt = 0;
while (cnt < TEST_COUNT) {
TEST_ASSERT_EQUAL_INT(cnt % 2, rtc_gpio_get_level(test_io));
TEST_ASSERT_EQUAL_INT(cnt % 2, !!(rtcio_ll_get_interrupt_status() & (1 << rtc_io_idx)));
cnt++;
TEST_ESP_OK(rtc_gpio_set_level(test_io, cnt % 2));
rtcio_ll_clear_interrupt_status(); // since we are testing level-triggered interrupt, we need to clear the status after setting the level back
vTaskDelay(100 / portTICK_PERIOD_MS);
}
TEST_ESP_OK(rtc_gpio_set_level(test_io, 0));
rtcio_ll_intr_enable(test_io, GPIO_INTR_POSEDGE);
cnt = 0;
while (cnt < TEST_COUNT) {
TEST_ESP_OK(rtc_gpio_set_level(test_io, 1));
TEST_ASSERT_EQUAL_INT(1, !!(rtcio_ll_get_interrupt_status() & (1 << rtc_io_idx)));
rtcio_ll_clear_interrupt_status();
TEST_ESP_OK(rtc_gpio_set_level(test_io, 0));
TEST_ASSERT_EQUAL_INT(0, !!(rtcio_ll_get_interrupt_status() & (1 << rtc_io_idx)));
cnt++;
vTaskDelay(100 / portTICK_PERIOD_MS);
}
rtcio_ll_intr_enable(test_io, GPIO_INTR_DISABLE);
TEST_ESP_OK(rtc_gpio_deinit(test_io));
}
#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT > 0)
#endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
#if SOC_DEEP_SLEEP_SUPPORTED && SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP #if SOC_DEEP_SLEEP_SUPPORTED && SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -110,6 +110,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = {
GPIO_NUM_6, //GPIO6 GPIO_NUM_6, //GPIO6
GPIO_NUM_7, //GPIO7 GPIO_NUM_7, //GPIO7
}; };
#define TEST_RTCIO_INTR_PIN_INDEX 5 // IO5
#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO5 #define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO5
#elif CONFIG_IDF_TARGET_ESP32H2 #elif CONFIG_IDF_TARGET_ESP32H2
#define TEST_GPIO_PIN_COUNT 8 #define TEST_GPIO_PIN_COUNT 8
@@ -123,6 +124,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = {
GPIO_NUM_13, //GPIO13 GPIO_NUM_13, //GPIO13
GPIO_NUM_14, //GPIO14 GPIO_NUM_14, //GPIO14
}; };
#define TEST_RTCIO_INTR_PIN_INDEX 5 // IO12
#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO12 #define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO12
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
// Has no input-only rtcio pins, all pins support pull-up/down // Has no input-only rtcio pins, all pins support pull-up/down
@@ -146,6 +148,7 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = {
GPIO_NUM_14, //GPIO14 GPIO_NUM_14, //GPIO14
GPIO_NUM_15, //GPIO15 GPIO_NUM_15, //GPIO15
}; };
#define TEST_RTCIO_INTR_PIN_INDEX 2 // IO2
#elif CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32C5 #elif CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32C5
// Has no input-only rtcio pins, all pins support pull-up/down // Has no input-only rtcio pins, all pins support pull-up/down
#define RTCIO_SUPPORT_PU_PD(num) 1 #define RTCIO_SUPPORT_PU_PD(num) 1
@@ -159,7 +162,22 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = {
GPIO_NUM_5, //GPIO5 GPIO_NUM_5, //GPIO5
GPIO_NUM_6, //GPIO6 GPIO_NUM_6, //GPIO6
}; };
#define TEST_RTCIO_INTR_PIN_INDEX 6 // IO6
#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 6 // IO6 #define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 6 // IO6
#elif CONFIG_IDF_TARGET_ESP32H4
// Has no input-only rtcio pins, all pins support pull-up/down
#define RTCIO_SUPPORT_PU_PD(num) 1
#define TEST_GPIO_PIN_COUNT 6
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
};
#define TEST_RTCIO_INTR_PIN_INDEX 2 // IO2
#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 2 // IO2
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -16,9 +16,6 @@
static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE __attribute__((unused)) 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) 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 = { static rtc_io_status_t s_rtc_io_status = {
.rtc_io_enabled_cnt = { 0 }, .rtc_io_enabled_cnt = { 0 },
.rtc_io_using_mask = 0 .rtc_io_using_mask = 0

View File

@@ -0,0 +1,83 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/critical_section.h"
#include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
static portMUX_TYPE __attribute__((unused)) 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)
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;
// check is the IO MUX has been set to another clock source
esp_os_enter_critical(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true;
} else {
s_io_mux_clk_src = clk_src;
}
esp_os_exit_critical(&s_io_mux_spinlock);
if (clk_conflict) {
return ESP_ERR_INVALID_STATE;
}
gpio_ll_iomux_set_clk_src(clk_src);
return ESP_OK;
}
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{
assert(gpio_num != GPIO_NUM_NC);
esp_os_enter_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);
}
}
esp_os_exit_critical(&s_io_mux_spinlock);
}
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{
assert(gpio_num != GPIO_NUM_NC);
esp_os_enter_critical(&s_io_mux_spinlock);
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_status.rtc_io_using_mask == 0) {
RTCIO_RCC_ATOMIC() {
rtcio_ll_enable_io_clock(false);
}
}
esp_os_exit_critical(&s_io_mux_spinlock);
}

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -73,7 +73,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/ */
static inline void rtcio_ll_output_enable(int rtcio_num) static inline void rtcio_ll_output_enable(int rtcio_num)
{ {
RTCIO.enable_w1ts.w1ts = (1U << rtcio_num); RTCIO.enable_w1ts.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TS_S));
} }
/** /**
@@ -83,7 +83,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/ */
static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_output_disable(int rtcio_num)
{ {
RTCIO.enable_w1tc.w1tc = (1U << rtcio_num); RTCIO.enable_w1tc.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TC_S));
} }
/** /**
@@ -95,9 +95,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{ {
if (level) { if (level) {
RTCIO.out_w1ts.w1ts = (1U << rtcio_num); RTCIO.out_w1ts.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TS_S));
} else { } else {
RTCIO.out_w1tc.w1tc = (1U << rtcio_num); RTCIO.out_w1tc.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TC_S));
} }
} }

View File

@@ -105,7 +105,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/ */
static inline void rtcio_ll_output_enable(int rtcio_num) static inline void rtcio_ll_output_enable(int rtcio_num)
{ {
LP_GPIO.enable_w1ts.enable_w1ts = BIT(rtcio_num); LP_GPIO.enable_w1ts.val = BIT(rtcio_num);
} }
/** /**
@@ -115,7 +115,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/ */
static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_output_disable(int rtcio_num)
{ {
LP_GPIO.enable_w1tc.enable_w1tc = BIT(rtcio_num); LP_GPIO.enable_w1tc.val = BIT(rtcio_num);
} }
/** /**
@@ -127,9 +127,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{ {
if (level) { if (level) {
LP_GPIO.out_w1ts.out_w1ts = BIT(rtcio_num); LP_GPIO.out_w1ts.val = BIT(rtcio_num);
} else { } else {
LP_GPIO.out_w1tc.out_w1tc = BIT(rtcio_num); LP_GPIO.out_w1tc.val = BIT(rtcio_num);
} }
} }
@@ -428,7 +428,7 @@ static inline bool rtcio_ll_wakeup_is_enabled(int rtcio_num)
/** /**
* @brief Get the rtc io interrupt status * @brief Get the rtc io interrupt status
* *
* @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT. * @return bit 0~6 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT.
*/ */
static inline uint32_t rtcio_ll_get_interrupt_status(void) static inline uint32_t rtcio_ll_get_interrupt_status(void)
{ {
@@ -440,7 +440,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/ */
static inline void rtcio_ll_clear_interrupt_status(void) static inline void rtcio_ll_clear_interrupt_status(void)
{ {
LP_GPIO.status_w1tc.status_w1tc = 0x7F; LP_GPIO.status_w1tc.val = 0x7F;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -103,7 +103,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/ */
static inline void rtcio_ll_output_enable(int rtcio_num) static inline void rtcio_ll_output_enable(int rtcio_num)
{ {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_enable_w1ts, enable_w1ts, BIT(rtcio_num)); LP_IO.out_enable_w1ts.val = BIT(rtcio_num);
} }
/** /**
@@ -113,7 +113,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/ */
static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_output_disable(int rtcio_num)
{ {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_enable_w1tc, enable_w1tc, BIT(rtcio_num)); LP_IO.out_enable_w1tc.val = BIT(rtcio_num);
} }
/** /**
@@ -125,9 +125,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{ {
if (level) { if (level) {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1ts, out_w1ts, BIT(rtcio_num)); LP_IO.out_data_w1ts.val = BIT(rtcio_num);
} else { } else {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1tc, out_w1tc, BIT(rtcio_num)); LP_IO.out_data_w1tc.val = BIT(rtcio_num);
} }
} }
@@ -446,7 +446,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/ */
static inline void rtcio_ll_clear_interrupt_status(void) static inline void rtcio_ll_clear_interrupt_status(void)
{ {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.status_w1tc, status_intr_w1tc, 0xff); LP_IO.status_w1tc.val = 0xFF;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -98,27 +98,27 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
} }
/** /**
* Enable rtcio output. * @brief Enable rtcio output.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
static inline void rtcio_ll_output_enable(int rtcio_num) static inline void rtcio_ll_output_enable(int rtcio_num)
{ {
LP_GPIO.enable_w1ts.enable_w1ts = BIT(rtcio_num); LP_GPIO.enable_w1ts.val = BIT(rtcio_num);
} }
/** /**
* Disable rtcio output. * @brief Disable rtcio output.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_output_disable(int rtcio_num)
{ {
LP_GPIO.enable_w1tc.enable_w1tc = BIT(rtcio_num); LP_GPIO.enable_w1tc.val = BIT(rtcio_num);
} }
/** /**
* Set RTCIO output level. * @brief Set RTCIO output level.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param level 0: output low; ~0: output high. * @param level 0: output low; ~0: output high.
@@ -126,14 +126,14 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{ {
if (level) { if (level) {
LP_GPIO.out_w1ts.out_w1ts = BIT(rtcio_num); LP_GPIO.out_w1ts.val = BIT(rtcio_num);
} else { } else {
LP_GPIO.out_w1tc.out_w1tc = BIT(rtcio_num); LP_GPIO.out_w1tc.val = BIT(rtcio_num);
} }
} }
/** /**
* Enable rtcio input. * @brief Enable rtcio input.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -143,7 +143,7 @@ static inline void rtcio_ll_input_enable(int rtcio_num)
} }
/** /**
* Disable rtcio input. * @brief Disable rtcio input.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -153,7 +153,7 @@ static inline void rtcio_ll_input_disable(int rtcio_num)
} }
/** /**
* Get RTCIO input level. * @brief Get RTCIO input level.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @return 0: input low; ~0: input high. * @return 0: input low; ~0: input high.
@@ -197,7 +197,7 @@ static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t m
} }
/** /**
* RTC GPIO pullup enable. * @brief RTC GPIO pullup enable.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -208,7 +208,7 @@ static inline void rtcio_ll_pullup_enable(int rtcio_num)
} }
/** /**
* RTC GPIO pullup disable. * @brief RTC GPIO pullup disable.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -230,7 +230,7 @@ static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num)
} }
/** /**
* RTC GPIO pulldown enable. * @brief RTC GPIO pulldown enable.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -241,7 +241,7 @@ static inline void rtcio_ll_pulldown_enable(int rtcio_num)
} }
/** /**
* RTC GPIO pulldown disable. * @brief RTC GPIO pulldown disable.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -263,7 +263,7 @@ static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num)
} }
/** /**
* Enable force hold function for an RTC IO pad. * @brief Enable force hold function for an RTC IO pad.
* *
* Enabling HOLD function will cause the pad to lock current status, such as, * Enabling HOLD function will cause the pad to lock current status, such as,
* input/output enable, input/output value, function, drive strength values. * input/output enable, input/output value, function, drive strength values.
@@ -278,7 +278,7 @@ static inline void rtcio_ll_force_hold_enable(int rtcio_num)
} }
/** /**
* Disable hold function on an RTC IO pad * @brief Disable hold function on an RTC IO pad
* *
* @note If disable the pad hold, the status of pad maybe changed in sleep mode. * @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). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
@@ -289,7 +289,7 @@ static inline void rtcio_ll_force_hold_disable(int rtcio_num)
} }
/** /**
* Enable force hold function for all RTC IO pads * @brief Enable force hold function for all RTC IO pads
* *
* Enabling HOLD function will cause the pad to lock current status, such as, * Enabling HOLD function will cause the pad to lock current status, such as,
* input/output enable, input/output value, function, drive strength values. * input/output enable, input/output value, function, drive strength values.
@@ -302,7 +302,7 @@ static inline void rtcio_ll_force_hold_all(void)
} }
/** /**
* Disable hold function fon all RTC IO pads * @brief Disable hold function fon all RTC IO pads
* *
* @note If disable the pad hold, the status of pad maybe changed in sleep mode. * @note If disable the pad hold, the status of pad maybe changed in sleep mode.
*/ */
@@ -312,7 +312,7 @@ static inline void rtcio_ll_force_unhold_all(void)
} }
/** /**
* Enable wakeup function and set wakeup type from light sleep or deep sleep for rtcio. * @brief 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 rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param type Wakeup on high level or low level. * @param type Wakeup on high level or low level.
@@ -324,7 +324,7 @@ static inline void rtcio_ll_wakeup_enable(int rtcio_num, gpio_int_type_t type)
} }
/** /**
* Disable wakeup function from light sleep or deep sleep for rtcio. * @brief Disable wakeup function from light sleep or deep sleep for rtcio.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -335,7 +335,7 @@ static inline void rtcio_ll_wakeup_disable(int rtcio_num)
} }
/** /**
* Enable interrupt function and set interrupt type * @brief Enable interrupt function and set interrupt type
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param type Interrupt type on high level or low level. * @param type Interrupt type on high level or low level.
@@ -353,7 +353,7 @@ static inline void rtcio_ll_intr_enable(int rtcio_num, gpio_int_type_t type)
} }
/** /**
* Enable rtc io output in deep sleep. * @brief Enable rtc io output in deep sleep.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -363,7 +363,7 @@ static inline void rtcio_ll_enable_output_in_sleep(int rtcio_num)
} }
/** /**
* Disable rtc io output in deep sleep. * @brief Disable rtc io output in deep sleep.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -373,7 +373,7 @@ static inline void rtcio_ll_disable_output_in_sleep(int rtcio_num)
} }
/** /**
* Enable rtc io input in deep sleep. * @brief Enable rtc io input in deep sleep.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -383,7 +383,7 @@ static inline void rtcio_ll_enable_input_in_sleep(int rtcio_num)
} }
/** /**
* Disable rtc io input in deep sleep. * @brief Disable rtc io input in deep sleep.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -393,7 +393,7 @@ static inline void rtcio_ll_disable_input_in_sleep(int rtcio_num)
} }
/** /**
* Enable rtc io keep another setting in deep sleep. * @brief Enable rtc io keep another setting in deep sleep.
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -403,7 +403,7 @@ static inline void rtcio_ll_enable_sleep_setting(int rtcio_num)
} }
/** /**
* Disable rtc io keep another setting in deep sleep. (Default) * @brief Disable rtc io keep another setting in deep sleep. (Default)
* *
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/ */
@@ -427,7 +427,7 @@ static inline bool rtcio_ll_wakeup_is_enabled(int rtcio_num)
/** /**
* @brief Get the rtc io interrupt status * @brief Get the rtc io interrupt status
* *
* @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT. * @return bit 0~6 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT.
*/ */
static inline uint32_t rtcio_ll_get_interrupt_status(void) static inline uint32_t rtcio_ll_get_interrupt_status(void)
{ {
@@ -439,7 +439,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/ */
static inline void rtcio_ll_clear_interrupt_status(void) static inline void rtcio_ll_clear_interrupt_status(void)
{ {
LP_GPIO.status_w1tc.status_w1tc = 0x7F; LP_GPIO.status_w1tc.val = 0x7F;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -35,8 +35,9 @@ extern "C" {
// Get GPIO hardware instance with giving gpio num // Get GPIO hardware instance with giving gpio num
#define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL) #define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL)
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) #define GPIO_LL_PRO_CPU_2_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTERRUPT_PRO_SOURCE #define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTERRUPT_PRO_SOURCE
/** /**
@@ -191,8 +192,8 @@ static inline void gpio_ll_clear_intr_status_high(gpio_dev_t *hw, uint32_t mask)
__attribute__((always_inline)) __attribute__((always_inline))
static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, uint32_t gpio_num) static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, uint32_t gpio_num)
{ {
HAL_ASSERT(core_id == 0 && "target SoC only has a single core"); (void)core_id;
GPIO.pinn[gpio_num].pinn_int_ena = GPIO_LL_PRO_CPU_INTR_ENA; //enable pro cpu intr GPIO.pinn[gpio_num].pinn_int_ena = GPIO_LL_PRO_CPU_INTR_ENA; //enable intr
} }
/** /**
@@ -453,9 +454,9 @@ __attribute__((always_inline))
static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
{ {
if (gpio_num < 32) { if (gpio_num < 32) {
return !!(LP_AON.gpio_hold0.gpio_hold0 & GPIO_HOLD_MASK[gpio_num]); return !!(LP_AON.gpio_hold0.gpio_hold0 & BIT(gpio_num));
} else { } else {
return !!(LP_AON.gpio_hold1.gpio_hold1 & GPIO_HOLD_MASK[gpio_num]); return !!(LP_AON.gpio_hold1.gpio_hold1 & BIT(gpio_num - 32));
} }
} }

View File

@@ -0,0 +1,447 @@
/*
* SPDX-FileCopyrightText: 2025 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 <stdlib.h>
#include <stdbool.h>
#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/gpio_types.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_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(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_rtcio_ll_enable_io_clock(__VA_ARGS__); \
} while(0)
/**
* @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 = LP_AON.gpio_mux.gpio_mux_sel;
sel_mask |= BIT(rtcio_num);
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 = LP_AON.gpio_mux.gpio_mux_sel;
sel_mask &= ~BIT(rtcio_num);
LP_AON.gpio_mux.gpio_mux_sel = sel_mask;
}
}
/**
* @brief 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.val = BIT(rtcio_num);
}
/**
* @brief 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.val = BIT(rtcio_num);
}
/**
* @brief 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.val = BIT(rtcio_num);
} else {
LP_GPIO.out_w1tc.val = BIT(rtcio_num);
}
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief Get RTC GPIO pad pullup status.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @return Whether the pullup of the pad is enabled or not.
*/
static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num)
{
return LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu;
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief Get RTC GPIO pad pulldown status.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @return Whether the pulldown of the pad is enabled or not.
*/
static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num)
{
return LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd;
}
/**
* @brief 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);
}
/**
* @brief 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);
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief 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, gpio_int_type_t type)
{
LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable = 1;
LP_GPIO.pinn[rtcio_num].pinn_int_type = type;
}
/**
* @brief 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 = 0;
}
/**
* @brief 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, gpio_int_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;
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief 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;
}
/**
* @brief 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~5 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.val = 0x3F;
}
#ifdef __cplusplus
}
#endif

View File

@@ -137,7 +137,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/ */
static inline void rtcio_ll_output_enable(int rtcio_num) static inline void rtcio_ll_output_enable(int rtcio_num)
{ {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, reg_gpio_enable_data_w1ts, BIT(rtcio_num)); LP_GPIO.enable_w1ts.val = BIT(rtcio_num);
} }
/** /**
@@ -147,7 +147,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/ */
static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_output_disable(int rtcio_num)
{ {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1tc, reg_gpio_enable_data_w1tc, BIT(rtcio_num)); LP_GPIO.enable_w1tc.val = BIT(rtcio_num);
// Ensure no other output signal is routed via LP_GPIO matrix to this pin // Ensure no other output signal is routed via LP_GPIO matrix to this pin
LP_GPIO.func_out_sel_cfg[rtcio_num].func_out_sel = SIG_LP_GPIO_OUT_IDX; LP_GPIO.func_out_sel_cfg[rtcio_num].func_out_sel = SIG_LP_GPIO_OUT_IDX;
} }
@@ -161,9 +161,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{ {
if (level) { if (level) {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1ts, reg_gpio_out_data_w1ts, BIT(rtcio_num)); LP_GPIO.out_w1ts.val = BIT(rtcio_num);
} else { } else {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1tc, reg_gpio_out_data_w1tc, BIT(rtcio_num)); LP_GPIO.out_w1tc.val = BIT(rtcio_num);
} }
} }
@@ -474,7 +474,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/ */
static inline void rtcio_ll_clear_interrupt_status(void) static inline void rtcio_ll_clear_interrupt_status(void)
{ {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.status_w1tc, reg_gpio_status_data_w1tc, 0xFFFF); LP_GPIO.status_w1tc.val = 0xFFFF;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -84,7 +84,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/ */
static inline void rtcio_ll_output_enable(int rtcio_num) static inline void rtcio_ll_output_enable(int rtcio_num)
{ {
RTCIO.enable_w1ts.w1ts = (1U << rtcio_num); RTCIO.enable_w1ts.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TS_S));
} }
/** /**
@@ -94,7 +94,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/ */
static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_output_disable(int rtcio_num)
{ {
RTCIO.enable_w1tc.w1tc = (1U << rtcio_num); RTCIO.enable_w1tc.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TC_S));
} }
/** /**
@@ -106,9 +106,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{ {
if (level) { if (level) {
RTCIO.out_w1ts.w1ts = (1U << rtcio_num); RTCIO.out_w1ts.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TS_S));
} else { } else {
RTCIO.out_w1tc.w1tc = (1U << rtcio_num); RTCIO.out_w1tc.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TC_S));
} }
} }

View File

@@ -93,7 +93,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/ */
static inline void rtcio_ll_output_enable(int rtcio_num) static inline void rtcio_ll_output_enable(int rtcio_num)
{ {
RTCIO.enable_w1ts.w1ts = (1U << rtcio_num); RTCIO.enable_w1ts.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TS_S));
} }
/** /**
@@ -103,7 +103,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/ */
static inline void rtcio_ll_output_disable(int rtcio_num) static inline void rtcio_ll_output_disable(int rtcio_num)
{ {
RTCIO.enable_w1tc.w1tc = (1U << rtcio_num); RTCIO.enable_w1tc.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TC_S));
} }
/** /**
@@ -115,9 +115,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{ {
if (level) { if (level) {
RTCIO.out_w1ts.w1ts = (1U << rtcio_num); RTCIO.out_w1ts.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TS_S));
} else { } else {
RTCIO.out_w1tc.w1tc = (1U << rtcio_num); RTCIO.out_w1tc.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TC_S));
} }
} }

View File

@@ -275,6 +275,26 @@ config SOC_GPIO_ETM_TASKS_PER_GROUP
int int
default 8 default 8
config SOC_GPIO_SUPPORT_RTC_INDEPENDENT
bool
default y
config SOC_LP_IO_CLOCK_IS_INDEPENDENT
bool
default y
config SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
bool
default y
config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK
int
default 0
config SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT
int
default 6
config SOC_GPIO_SUPPORT_FORCE_HOLD config SOC_GPIO_SUPPORT_FORCE_HOLD
bool bool
default y default y
@@ -283,6 +303,26 @@ config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
bool bool
default y default y
config SOC_RTCIO_PIN_COUNT
int
default 6
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_RTCIO_EDGE_WAKE_SUPPORTED
bool
default y
config SOC_I2C_NUM config SOC_I2C_NUM
int int
default 2 default 2

View File

@@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2025 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

View File

@@ -219,9 +219,14 @@
// Target has the full LP IO subsystem // Target has the full LP IO subsystem
// On ESP32-H4, Digital IOs have their own registers to control pullup/down capability, independent of LP registers. // On ESP32-H4, Digital IOs have their own registers to control pullup/down capability, independent of LP registers.
// #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT 1 #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT 1
// #define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP 1
// #define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK (0ULL | BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5) // LP IO peripherals have independent clock gating to manage
#define SOC_LP_IO_CLOCK_IS_INDEPENDENT (1)
#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP 1
#define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK (0ULL | BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5)
#define SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT (6)
// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_6~GPIO_NUM_39) // digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_6~GPIO_NUM_39)
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK (SOC_GPIO_VALID_GPIO_MASK & ~((1ULL<<6) - 1)) #define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK (SOC_GPIO_VALID_GPIO_MASK & ~((1ULL<<6) - 1))
@@ -235,12 +240,13 @@
// #define SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX 1 TODO: [ESP32H4] IDF-12361 // #define SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX 1 TODO: [ESP32H4] IDF-12361
/*-------------------------- RTCIO CAPS --------------------------------------*/ /*-------------------------- RTCIO CAPS --------------------------------------*/
// #define SOC_RTCIO_PIN_COUNT 6 #define SOC_RTCIO_PIN_COUNT 6
// #define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 // This macro indicates that the target has separate RTC IOMUX hardware feature, #define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /*!< This macro indicates that the target has separate RTC IOMUX hardware feature,
// // so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.) so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.)
// // when the pins are switched to RTC function. when the pins are switched to RTC function. */
// #define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_HOLD_SUPPORTED 1
// #define SOC_RTCIO_WAKE_SUPPORTED 1 #define SOC_RTCIO_WAKE_SUPPORTED 1
#define SOC_RTCIO_EDGE_WAKE_SUPPORTED 1
/*-------------------------- Dedicated GPIO CAPS -----------------------------*/ /*-------------------------- Dedicated GPIO CAPS -----------------------------*/
// #define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */ // #define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */

View File

@@ -11,30 +11,30 @@ extern "C" {
#endif #endif
/** Group: Configuration Registers */ /** Group: Configuration Registers */
/** Type of gpio_out register /** Type of out register
* LP_GPIO output register * LP_GPIO output register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_out_data_orig : R/W/WTC; bitpos: [5:0]; default: 0; /** out_data_orig : R/W/WTC; bitpos: [5:0]; default: 0;
* Configures the output value of LP_GPIO0 ~ 5 output in simple LP_GPIO output mode. * Configures the output value of LP_GPIO0 ~ 5 output in simple LP_GPIO output mode.
* 0: Low level * 0: Low level
* 1: High level * 1: High level
* The value of bit0 ~ bit5 correspond to the output value of LP_GPIO0 ~ LP_GPIO5 * The value of bit0 ~ bit5 correspond to the output value of LP_GPIO0 ~ LP_GPIO5
* respectively. Bitxx ~ bitxx is invalid. * respectively. Bitxx ~ bitxx is invalid.
*/ */
uint32_t gpio_out_data_orig:6; uint32_t out_data_orig:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_out_reg_t; } lp_gpio_out_reg_t;
/** Type of gpio_out_w1ts register /** Type of out_w1ts register
* LP_GPIO output set register * LP_GPIO output set register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_out_w1ts : WT; bitpos: [5:0]; default: 0; /** out_w1ts : WT; bitpos: [5:0]; default: 0;
* Configures whether or not to set the output register LP_GPIO_OUT_REG of LP_GPIO0 ~ * Configures whether or not to set the output register LP_GPIO_OUT_REG of LP_GPIO0 ~
* LP_GPIO5. * LP_GPIO5.
* 0: Not set * 0: Not set
@@ -42,18 +42,18 @@ typedef union {
* Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid. * Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
* Recommended operation: use this register to set LP_GPIO_OUT_REG. * Recommended operation: use this register to set LP_GPIO_OUT_REG.
*/ */
uint32_t gpio_out_w1ts:6; uint32_t out_w1ts:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_out_w1ts_reg_t; } lp_gpio_out_w1ts_reg_t;
/** Type of gpio_out_w1tc register /** Type of out_w1tc register
* LP_GPIO output clear register * LP_GPIO output clear register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_out_w1tc : WT; bitpos: [5:0]; default: 0; /** out_w1tc : WT; bitpos: [5:0]; default: 0;
* Configures whether or not to clear the output register LP_GPIO_OUT_REG of LP_GPIO0 * Configures whether or not to clear the output register LP_GPIO_OUT_REG of LP_GPIO0
* ~ LP_GPIO5 output. * ~ LP_GPIO5 output.
* 0: Not clear * 0: Not clear
@@ -61,35 +61,35 @@ typedef union {
* Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid. * Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
* Recommended operation: use this register to clear LP_GPIO_OUT_REG. * Recommended operation: use this register to clear LP_GPIO_OUT_REG.
*/ */
uint32_t gpio_out_w1tc:6; uint32_t out_w1tc:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_out_w1tc_reg_t; } lp_gpio_out_w1tc_reg_t;
/** Type of gpio_enable register /** Type of enable register
* LP_GPIO output enable register * LP_GPIO output enable register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_enable_data : R/W/WTC; bitpos: [5:0]; default: 0; /** enable_data : R/W/WTC; bitpos: [5:0]; default: 0;
* Configures whether or not to enable the output of LP_GPIO0 ~ LP_GPIO5. * Configures whether or not to enable the output of LP_GPIO0 ~ LP_GPIO5.
* 0: Not enable * 0: Not enable
* 1: Enable * 1: Enable
* Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid. * Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
*/ */
uint32_t gpio_enable_data:6; uint32_t enable_data:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_enable_reg_t; } lp_gpio_enable_reg_t;
/** Type of gpio_enable_w1ts register /** Type of enable_w1ts register
* LP_GPIO output enable set register * LP_GPIO output enable set register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_enable_w1ts : WT; bitpos: [5:0]; default: 0; /** enable_w1ts : WT; bitpos: [5:0]; default: 0;
* Configures whether or not to set the output enable register LP_GPIO_ENABLE_REG of * Configures whether or not to set the output enable register LP_GPIO_ENABLE_REG of
* LP_GPIO0 ~ LP_GPIO5. * LP_GPIO0 ~ LP_GPIO5.
* 0: Not set * 0: Not set
@@ -97,18 +97,18 @@ typedef union {
* Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid. * Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
* Recommended operation: use this register to set LP_GPIO_ENABLE_REG. * Recommended operation: use this register to set LP_GPIO_ENABLE_REG.
*/ */
uint32_t gpio_enable_w1ts:6; uint32_t enable_w1ts:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_enable_w1ts_reg_t; } lp_gpio_enable_w1ts_reg_t;
/** Type of gpio_enable_w1tc register /** Type of enable_w1tc register
* LP_GPIO output enable clear register * LP_GPIO output enable clear register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_enable_w1tc : WT; bitpos: [5:0]; default: 0; /** enable_w1tc : WT; bitpos: [5:0]; default: 0;
* Configures whether or not to clear the output enable register LP_GPIO_ENABLE_REG of * Configures whether or not to clear the output enable register LP_GPIO_ENABLE_REG of
* LP_GPIO0 ~ LP_GPIO5. * LP_GPIO0 ~ LP_GPIO5.
* 0: Not clear * 0: Not clear
@@ -116,25 +116,25 @@ typedef union {
* Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid. * Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
* Recommended operation: use this register to clear LP_GPIO_ENABLE_REG. * Recommended operation: use this register to clear LP_GPIO_ENABLE_REG.
*/ */
uint32_t gpio_enable_w1tc:6; uint32_t enable_w1tc:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_enable_w1tc_reg_t; } lp_gpio_enable_w1tc_reg_t;
/** Type of gpio_in register /** Type of in register
* LP_GPIO input register * LP_GPIO input register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_in_data_next : RO; bitpos: [5:0]; default: 0; /** in_data_next : RO; bitpos: [5:0]; default: 0;
* Represents the input value of LP_GPIO0 ~ LP_GPIO5. Each bit represents a pin input * Represents the input value of LP_GPIO0 ~ LP_GPIO5. Each bit represents a pin input
* value: * value:
* 0: Low level * 0: Low level
* 1: High level * 1: High level
* Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid. * Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
*/ */
uint32_t gpio_in_data_next:6; uint32_t in_data_next:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
@@ -142,12 +142,12 @@ typedef union {
/** Group: Interrupt Status Registers */ /** Group: Interrupt Status Registers */
/** Type of gpio_status register /** Type of status register
* LP_GPIO interrupt status register * LP_GPIO interrupt status register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_status_interrupt : R/W/WTC; bitpos: [5:0]; default: 0; /** status_interrupt : R/W/WTC; bitpos: [5:0]; default: 0;
* The interrupt status of LP_GPIO0 ~ LP_GPIO5, can be configured by the software. * The interrupt status of LP_GPIO0 ~ LP_GPIO5, can be configured by the software.
* *
* - Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid. * - Bit0 ~ bit5 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
@@ -159,18 +159,18 @@ typedef union {
* LP_GPIO_PIN$n_INT_TYPE, or this bit is configured to 1 by the software. * LP_GPIO_PIN$n_INT_TYPE, or this bit is configured to 1 by the software.
* *
*/ */
uint32_t gpio_status_interrupt:6; uint32_t status_interrupt:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_status_reg_t; } lp_gpio_status_reg_t;
/** Type of gpio_status_w1ts register /** Type of status_w1ts register
* LP_GPIO interrupt status set register * LP_GPIO interrupt status set register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_status_w1ts : WT; bitpos: [5:0]; default: 0; /** status_w1ts : WT; bitpos: [5:0]; default: 0;
* Configures whether or not to set the interrupt status register * Configures whether or not to set the interrupt status register
* LP_GPIO_STATUS_INTERRUPT of LP_GPIO0 ~ LP_GPIO5. * LP_GPIO_STATUS_INTERRUPT of LP_GPIO0 ~ LP_GPIO5.
* *
@@ -179,18 +179,18 @@ typedef union {
* LP_GPIO_STATUS_INTERRUPT will be set to 1. \item Recommended operation: use this * LP_GPIO_STATUS_INTERRUPT will be set to 1. \item Recommended operation: use this
* register to set LP_GPIO_STATUS_INTERRUPT. * register to set LP_GPIO_STATUS_INTERRUPT.
*/ */
uint32_t gpio_status_w1ts:6; uint32_t status_w1ts:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_status_w1ts_reg_t; } lp_gpio_status_w1ts_reg_t;
/** Type of gpio_status_w1tc register /** Type of status_w1tc register
* LP_GPIO interrupt status clear register * LP_GPIO interrupt status clear register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_status_w1tc : WT; bitpos: [5:0]; default: 0; /** status_w1tc : WT; bitpos: [5:0]; default: 0;
* Configures whether or not to clear the interrupt status register * Configures whether or not to clear the interrupt status register
* LP_GPIO_STATUS_INTERRUPT of LP_GPIO0 ~ LP_GPIO5. * LP_GPIO_STATUS_INTERRUPT of LP_GPIO0 ~ LP_GPIO5.
* *
@@ -199,18 +199,18 @@ typedef union {
* LP_GPIO_STATUS_INTERRUPT will be cleared. \item Recommended operation: use this * LP_GPIO_STATUS_INTERRUPT will be cleared. \item Recommended operation: use this
* register to clear LP_GPIO_STATUS_INTERRUPT. * register to clear LP_GPIO_STATUS_INTERRUPT.
*/ */
uint32_t gpio_status_w1tc:6; uint32_t status_w1tc:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
} lp_gpio_status_w1tc_reg_t; } lp_gpio_status_w1tc_reg_t;
/** Type of gpio_status_next register /** Type of status_next register
* LP_GPIO interrupt source register * LP_GPIO interrupt source register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_status_interrupt_next : RO; bitpos: [5:0]; default: 0; /** status_interrupt_next : RO; bitpos: [5:0]; default: 0;
* Represents the interrupt source signal of LP_GPIO0 ~ LP_GPIO5. * Represents the interrupt source signal of LP_GPIO0 ~ LP_GPIO5.
* Bit0 ~ bit24 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid. * Bit0 ~ bit24 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
* Each bit represents: * Each bit represents:
@@ -219,7 +219,7 @@ typedef union {
* The interrupt could be rising edge interrupt, falling edge interrupt, level * The interrupt could be rising edge interrupt, falling edge interrupt, level
* sensitive interrupt and any edge interrupt. * sensitive interrupt and any edge interrupt.
*/ */
uint32_t gpio_status_interrupt_next:6; uint32_t status_interrupt_next:6;
uint32_t reserved_6:26; uint32_t reserved_6:26;
}; };
uint32_t val; uint32_t val;
@@ -227,12 +227,12 @@ typedef union {
/** Group: Pin Configuration Registers */ /** Group: Pin Configuration Registers */
/** Type of gpio_pinn register /** Type of pinn register
* LP_GPIOn configuration register * LP_GPIOn configuration register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_pinn_sync2_bypass : R/W; bitpos: [1:0]; default: 0; /** pinn_sync2_bypass : R/W; bitpos: [1:0]; default: 0;
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO * Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
* MUX operating clock for the second-level synchronization. * MUX operating clock for the second-level synchronization.
* 0: Not synchronize * 0: Not synchronize
@@ -240,14 +240,14 @@ typedef union {
* 2: Synchronize on rising edge * 2: Synchronize on rising edge
* 3: Synchronize on rising edge * 3: Synchronize on rising edge
*/ */
uint32_t gpio_pinn_sync2_bypass:2; uint32_t pinn_sync2_bypass:2;
/** gpio_pinn_pad_driver : R/W; bitpos: [2]; default: 0; /** pinn_pad_driver : R/W; bitpos: [2]; default: 0;
* Configures to select pin drive mode. * Configures to select pin drive mode.
* 0: Normal output * 0: Normal output
* 1: Open drain output * 1: Open drain output
*/ */
uint32_t gpio_pinn_pad_driver:1; uint32_t pinn_pad_driver:1;
/** gpio_pinn_sync1_bypass : R/W; bitpos: [4:3]; default: 0; /** pinn_sync1_bypass : R/W; bitpos: [4:3]; default: 0;
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO * Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
* MUX operating clock for the first-level synchronization. * MUX operating clock for the first-level synchronization.
* 0: Not synchronize * 0: Not synchronize
@@ -255,13 +255,13 @@ typedef union {
* 2: Synchronize on rising edge * 2: Synchronize on rising edge
* 3: Synchronize on rising edge * 3: Synchronize on rising edge
*/ */
uint32_t gpio_pinn_sync1_bypass:2; uint32_t pinn_sync1_bypass:2;
/** gpio_pinn_edge_wakeup_clr : WT; bitpos: [5]; default: 0; /** pinn_edge_wakeup_clr : WT; bitpos: [5]; default: 0;
* LP_GPIO wakeup clear register. * LP_GPIO wakeup clear register.
*/ */
uint32_t gpio_pinn_edge_wakeup_clr:1; uint32_t pinn_edge_wakeup_clr:1;
uint32_t reserved_6:1; uint32_t reserved_6:1;
/** gpio_pinn_int_type : R/W; bitpos: [9:7]; default: 0; /** pinn_int_type : R/W; bitpos: [9:7]; default: 0;
* Configures LP_GPIO interrupt type. * Configures LP_GPIO interrupt type.
* 0: LP_GPIO interrupt disabled * 0: LP_GPIO interrupt disabled
* 1: Rising edge trigger * 1: Rising edge trigger
@@ -270,14 +270,14 @@ typedef union {
* 4: Low level trigger * 4: Low level trigger
* 5: High level trigger * 5: High level trigger
*/ */
uint32_t gpio_pinn_int_type:3; uint32_t pinn_int_type:3;
/** gpio_pinn_wakeup_enable : R/W; bitpos: [10]; default: 0; /** pinn_wakeup_enable : R/W; bitpos: [10]; default: 0;
* Configures whether or not to enable LP_GPIO wake-up function. * Configures whether or not to enable LP_GPIO wake-up function.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
* This function only wakes up the CPU from Light-sleep. * This function only wakes up the CPU from Light-sleep.
*/ */
uint32_t gpio_pinn_wakeup_enable:1; uint32_t pinn_wakeup_enable:1;
uint32_t reserved_11:21; uint32_t reserved_11:21;
}; };
uint32_t val; uint32_t val;
@@ -285,24 +285,24 @@ typedef union {
/** Group: Output Configuration Registers */ /** Group: Output Configuration Registers */
/** Type of gpio_funcn_out_sel_cfg register /** Type of funcn_out_sel_cfg register
* Configuration register for LP_GPIOn output * Configuration register for LP_GPIOn output
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_funcn_out_inv_sel : R/W; bitpos: [0]; default: 0; /** funcn_out_inv_sel : R/W; bitpos: [0]; default: 0;
* Configures whether or not to invert the output value. * Configures whether or not to invert the output value.
* 0: Not invert * 0: Not invert
* 1: Invert * 1: Invert
*/ */
uint32_t gpio_funcn_out_inv_sel:1; uint32_t funcn_out_inv_sel:1;
uint32_t reserved_1:1; uint32_t reserved_1:1;
/** gpio_funcn_oe_inv_sel : R/W; bitpos: [2]; default: 0; /** funcn_oe_inv_sel : R/W; bitpos: [2]; default: 0;
* Configures whether or not to invert the output enable signal. * Configures whether or not to invert the output enable signal.
* 0: Not invert * 0: Not invert
* 1: Invert * 1: Invert
*/ */
uint32_t gpio_funcn_oe_inv_sel:1; uint32_t funcn_oe_inv_sel:1;
uint32_t reserved_3:29; uint32_t reserved_3:29;
}; };
uint32_t val; uint32_t val;
@@ -310,17 +310,17 @@ typedef union {
/** Group: Clock Gate Register */ /** Group: Clock Gate Register */
/** Type of gpio_clock_gate register /** Type of clock_gate register
* LP_GPIO clock gate register * LP_GPIO clock gate register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_clk_en : R/W; bitpos: [0]; default: 1; /** clk_en : R/W; bitpos: [0]; default: 1;
* Configures whether or not to enable clock gate. * Configures whether or not to enable clock gate.
* 0: Not enable * 0: Not enable
* 1: Enable, the clock is free running. * 1: Enable, the clock is free running.
*/ */
uint32_t gpio_clk_en:1; uint32_t clk_en:1;
uint32_t reserved_1:31; uint32_t reserved_1:31;
}; };
uint32_t val; uint32_t val;
@@ -328,15 +328,15 @@ typedef union {
/** Group: Version Register */ /** Group: Version Register */
/** Type of gpio_date register /** Type of date register
* LP_GPIO version register * LP_GPIO version register
*/ */
typedef union { typedef union {
struct { struct {
/** gpio_date : R/W; bitpos: [27:0]; default: 37769744; /** date : R/W; bitpos: [27:0]; default: 37769744;
* Version control register. * Version control register.
*/ */
uint32_t gpio_date:28; uint32_t date:28;
uint32_t reserved_28:4; uint32_t reserved_28:4;
}; };
uint32_t val; uint32_t val;
@@ -345,23 +345,23 @@ typedef union {
typedef struct { typedef struct {
uint32_t reserved_000; uint32_t reserved_000;
volatile lp_gpio_out_reg_t gpio_out; volatile lp_gpio_out_reg_t out;
volatile lp_gpio_out_w1ts_reg_t gpio_out_w1ts; volatile lp_gpio_out_w1ts_reg_t out_w1ts;
volatile lp_gpio_out_w1tc_reg_t gpio_out_w1tc; volatile lp_gpio_out_w1tc_reg_t out_w1tc;
volatile lp_gpio_enable_reg_t gpio_enable; volatile lp_gpio_enable_reg_t enable;
volatile lp_gpio_enable_w1ts_reg_t gpio_enable_w1ts; volatile lp_gpio_enable_w1ts_reg_t enable_w1ts;
volatile lp_gpio_enable_w1tc_reg_t gpio_enable_w1tc; volatile lp_gpio_enable_w1tc_reg_t enable_w1tc;
volatile lp_gpio_in_reg_t gpio_in; volatile lp_gpio_in_reg_t in;
volatile lp_gpio_status_reg_t gpio_status; volatile lp_gpio_status_reg_t status;
volatile lp_gpio_status_w1ts_reg_t gpio_status_w1ts; volatile lp_gpio_status_w1ts_reg_t status_w1ts;
volatile lp_gpio_status_w1tc_reg_t gpio_status_w1tc; volatile lp_gpio_status_w1tc_reg_t status_w1tc;
volatile lp_gpio_status_next_reg_t gpio_status_next; volatile lp_gpio_status_next_reg_t status_next;
volatile lp_gpio_pinn_reg_t gpio_pinn[6]; volatile lp_gpio_pinn_reg_t pinn[6];
uint32_t reserved_048[154]; uint32_t reserved_048[154];
volatile lp_gpio_funcn_out_sel_cfg_reg_t gpio_funcn_out_sel_cfg[6]; volatile lp_gpio_funcn_out_sel_cfg_reg_t funcn_out_sel_cfg[6];
uint32_t reserved_2c8[76]; uint32_t reserved_2c8[76];
volatile lp_gpio_clock_gate_reg_t gpio_clock_gate; volatile lp_gpio_clock_gate_reg_t clock_gate;
volatile lp_gpio_date_reg_t gpio_date; volatile lp_gpio_date_reg_t date;
} lp_gpio_dev_t; } lp_gpio_dev_t;
extern lp_gpio_dev_t LP_GPIO; extern lp_gpio_dev_t LP_GPIO;

View File

@@ -11,101 +11,101 @@ extern "C" {
#endif #endif
/** Group: Configuration Registers */ /** Group: Configuration Registers */
/** Type of io_mux_gpion register /** Type of gpion register
* LP IO MUX configuration register for LP_GPIOn * LP IO MUX configuration register for LP_GPIOn
*/ */
typedef union { typedef union {
struct { struct {
/** io_mux_gpion_mcu_oe : R/W; bitpos: [0]; default: 0; /** gpion_mcu_oe : R/W; bitpos: [0]; default: 0;
* Configures whether or not to enable the output of LP_GPIOn in sleep mode. * Configures whether or not to enable the output of LP_GPIOn in sleep mode.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_mcu_oe:1; uint32_t gpion_mcu_oe:1;
/** io_mux_gpion_slp_sel : R/W; bitpos: [1]; default: 0; /** gpion_slp_sel : R/W; bitpos: [1]; default: 0;
* Configures whether or not to enter sleep mode for LP_GPIOn. * Configures whether or not to enter sleep mode for LP_GPIOn.
* 0: Not enter * 0: Not enter
* 1: Enter * 1: Enter
*/ */
uint32_t io_mux_gpion_slp_sel:1; uint32_t gpion_slp_sel:1;
/** io_mux_gpion_mcu_wpd : R/W; bitpos: [2]; default: 0; /** gpion_mcu_wpd : R/W; bitpos: [2]; default: 0;
* Configure whether or not to enable pull-down resistor of LP_GPIOn in sleep mode. * Configure whether or not to enable pull-down resistor of LP_GPIOn in sleep mode.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_mcu_wpd:1; uint32_t gpion_mcu_wpd:1;
/** io_mux_gpion_mcu_wpu : R/W; bitpos: [3]; default: 0; /** gpion_mcu_wpu : R/W; bitpos: [3]; default: 0;
* Configures whether or not to enable pull-up resistor of LP_GPIOn during sleep mode. * Configures whether or not to enable pull-up resistor of LP_GPIOn during sleep mode.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_mcu_wpu:1; uint32_t gpion_mcu_wpu:1;
/** io_mux_gpion_mcu_ie : R/W; bitpos: [4]; default: 0; /** gpion_mcu_ie : R/W; bitpos: [4]; default: 0;
* Configures whether or not to enable the input of LP_GPIOn during sleep mode. * Configures whether or not to enable the input of LP_GPIOn during sleep mode.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_mcu_ie:1; uint32_t gpion_mcu_ie:1;
/** io_mux_gpion_mcu_drv : R/W; bitpos: [6:5]; default: 0; /** gpion_mcu_drv : R/W; bitpos: [6:5]; default: 0;
* Configures the drive strength of LP_GPIOn during sleep mode. * Configures the drive strength of LP_GPIOn during sleep mode.
* 0: ~5 mA * 0: ~5 mA
* 1: ~10 mA * 1: ~10 mA
* 2: ~20 mA * 2: ~20 mA
* 3: ~40 mA * 3: ~40 mA
*/ */
uint32_t io_mux_gpion_mcu_drv:2; uint32_t gpion_mcu_drv:2;
/** io_mux_gpion_fun_wpd : R/W; bitpos: [7]; default: 0; /** gpion_fun_wpd : R/W; bitpos: [7]; default: 0;
* Configures whether or not to enable pull-down resistor of LP_GPIOn. * Configures whether or not to enable pull-down resistor of LP_GPIOn.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_fun_wpd:1; uint32_t gpion_fun_wpd:1;
/** io_mux_gpion_fun_wpu : R/W; bitpos: [8]; default: 0; /** gpion_fun_wpu : R/W; bitpos: [8]; default: 0;
* Configures whether or not enable pull-up resistor of LP_GPIOn. * Configures whether or not enable pull-up resistor of LP_GPIOn.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_fun_wpu:1; uint32_t gpion_fun_wpu:1;
/** io_mux_gpion_fun_ie : R/W; bitpos: [9]; default: 0; /** gpion_fun_ie : R/W; bitpos: [9]; default: 0;
* Configures whether or not to enable input of LP_GPIOn. * Configures whether or not to enable input of LP_GPIOn.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_fun_ie:1; uint32_t gpion_fun_ie:1;
/** io_mux_gpion_fun_drv : R/W; bitpos: [11:10]; default: 2; /** gpion_fun_drv : R/W; bitpos: [11:10]; default: 2;
* Configures the drive strength of LP_GPIOn. * Configures the drive strength of LP_GPIOn.
* 0: ~5 mA * 0: ~5 mA
* 1: ~10 mA * 1: ~10 mA
* 2: ~20 mA * 2: ~20 mA
* 3: ~40 mA * 3: ~40 mA
*/ */
uint32_t io_mux_gpion_fun_drv:2; uint32_t gpion_fun_drv:2;
/** io_mux_gpion_mcu_sel : R/W; bitpos: [14:12]; default: 1; /** gpion_mcu_sel : R/W; bitpos: [14:12]; default: 1;
* Configures to select LP IO MUX function for this signal. * Configures to select LP IO MUX function for this signal.
* 0: Select Function 0 * 0: Select Function 0
* 1: Select Function 1 * 1: Select Function 1
* ...... * ......
*/ */
uint32_t io_mux_gpion_mcu_sel:3; uint32_t gpion_mcu_sel:3;
/** io_mux_gpion_filter_en : R/W; bitpos: [15]; default: 0; /** gpion_filter_en : R/W; bitpos: [15]; default: 0;
* Configures whether or not to enable filter for pin input signals. * Configures whether or not to enable filter for pin input signals.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_filter_en:1; uint32_t gpion_filter_en:1;
/** io_mux_gpion_hys_en : R/W; bitpos: [16]; default: 0; /** gpion_hys_en : R/W; bitpos: [16]; default: 0;
* Configures whether or not to enable the hysteresis function of the pin when * Configures whether or not to enable the hysteresis function of the pin when
* LP_IO_MUX_GPIOn_HYS_SEL is set to 1. * LP_IO_MUX_GPIOn_HYS_SEL is set to 1.
* 0: Disable * 0: Disable
* 1: Enable * 1: Enable
*/ */
uint32_t io_mux_gpion_hys_en:1; uint32_t gpion_hys_en:1;
/** io_mux_gpion_hys_sel : R/W; bitpos: [17]; default: 0; /** gpion_hys_sel : R/W; bitpos: [17]; default: 0;
* Configures to choose the signal for enabling the hysteresis function for LP_GPIOn. * Configures to choose the signal for enabling the hysteresis function for LP_GPIOn.
* 0: Choose the output enable signal of eFuse * 0: Choose the output enable signal of eFuse
* 1: Choose the output enable signal of LP_IO_MUX_GPIOn_HYS_EN * 1: Choose the output enable signal of LP_IO_MUX_GPIOn_HYS_EN
*/ */
uint32_t io_mux_gpion_hys_sel:1; uint32_t gpion_hys_sel:1;
uint32_t reserved_18:14; uint32_t reserved_18:14;
}; };
uint32_t val; uint32_t val;
@@ -113,15 +113,15 @@ typedef union {
/** Group: Version Register */ /** Group: Version Register */
/** Type of io_mux_date register /** Type of date register
* Version control register * Version control register
*/ */
typedef union { typedef union {
struct { struct {
/** io_mux_reg_date : R/W; bitpos: [27:0]; default: 37769744; /** reg_date : R/W; bitpos: [27:0]; default: 37769744;
* Version control register * Version control register
*/ */
uint32_t io_mux_reg_date:28; uint32_t reg_date:28;
uint32_t reserved_28:4; uint32_t reserved_28:4;
}; };
uint32_t val; uint32_t val;
@@ -129,9 +129,9 @@ typedef union {
typedef struct { typedef struct {
volatile lp_io_mux_gpion_reg_t io_mux_gpion[6]; volatile lp_io_mux_gpion_reg_t gpion[6];
uint32_t reserved_018[121]; uint32_t reserved_018[121];
volatile lp_io_mux_date_reg_t io_mux_date; volatile lp_io_mux_date_reg_t date;
} lp_iomux_dev_t; } lp_iomux_dev_t;
extern lp_iomux_dev_t LP_IO_MUX; extern lp_iomux_dev_t LP_IO_MUX;

View File

@@ -4,4 +4,47 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
// TODO: [ESP32H4] IDF-12393 #include "soc/rtc_io_periph.h"
const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
RTCIO_GPIO0_CHANNEL, //GPIO0
RTCIO_GPIO1_CHANNEL, //GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2
RTCIO_GPIO3_CHANNEL, //GPIO3
RTCIO_GPIO4_CHANNEL, //GPIO4
RTCIO_GPIO5_CHANNEL, //GPIO5
-1,//GPIO6
-1,//GPIO7
-1,//GPIO8
-1,//GPIO9
-1,//GPIO10
-1,//GPIO11
-1,//GPIO12
-1,//GPIO13
-1,//GPIO14
-1,//GPIO15
-1,//GPIO16
-1,//GPIO17
-1,//GPIO18
-1,//GPIO19
-1,//GPIO20
-1,//GPIO21
-1,//GPIO22
-1,//GPIO23
-1,//GPIO24
-1,//GPIO25
-1,//GPIO26
-1,//GPIO27
-1,//GPIO28
-1,//GPIO29
-1,//GPIO30
-1,//GPIO31
-1,//GPIO32
-1,//GPIO33
-1,//GPIO34
-1,//GPIO35
-1,//GPIO36
-1,//GPIO37
-1,//GPIO38
-1,//GPIO39
};