diff --git a/components/driver/gpio.c b/components/driver/gpio.c index e9e711989b..f20c56bd9c 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -554,9 +554,11 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) esp_err_t ret = ESP_OK; if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) { +#if SOC_RTCIO_WAKE_SUPPORTED if (rtc_gpio_is_valid_gpio(gpio_num)) { ret = rtc_gpio_wakeup_enable(gpio_num, intr_type); } +#endif portENTER_CRITICAL(&gpio_context.gpio_spinlock); gpio_hal_wakeup_enable(gpio_context.gpio_hal, gpio_num, intr_type); portEXIT_CRITICAL(&gpio_context.gpio_spinlock); @@ -572,10 +574,11 @@ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); esp_err_t ret = ESP_OK; - +#if SOC_RTCIO_WAKE_SUPPORTED if (rtc_gpio_is_valid_gpio(gpio_num)) { ret = rtc_gpio_wakeup_disable(gpio_num); } +#endif portENTER_CRITICAL(&gpio_context.gpio_spinlock); gpio_hal_wakeup_disable(gpio_context.gpio_hal, gpio_num); portEXIT_CRITICAL(&gpio_context.gpio_spinlock); @@ -630,7 +633,9 @@ esp_err_t gpio_hold_en(gpio_num_t gpio_num) int ret = ESP_OK; if (rtc_gpio_is_valid_gpio(gpio_num)) { +#if SOC_RTCIO_HOLD_SUPPORTED ret = rtc_gpio_hold_en(gpio_num); +#endif } else if (GPIO_HOLD_MASK[gpio_num]) { portENTER_CRITICAL(&gpio_context.gpio_spinlock); gpio_hal_hold_en(gpio_context.gpio_hal, gpio_num); @@ -648,7 +653,9 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num) int ret = ESP_OK; if (rtc_gpio_is_valid_gpio(gpio_num)) { +#if SOC_RTCIO_HOLD_SUPPORTED ret = rtc_gpio_hold_dis(gpio_num); +#endif }else if (GPIO_HOLD_MASK[gpio_num]) { portENTER_CRITICAL(&gpio_context.gpio_spinlock); gpio_hal_hold_dis(gpio_context.gpio_hal, gpio_num); @@ -678,7 +685,9 @@ void gpio_deep_sleep_hold_dis(void) esp_err_t gpio_force_hold_all() { +#if SOC_RTCIO_HOLD_SUPPORTED rtc_gpio_force_hold_all(); +#endif portENTER_CRITICAL(&gpio_context.gpio_spinlock); gpio_hal_force_hold_all(gpio_context.gpio_hal); portEXIT_CRITICAL(&gpio_context.gpio_spinlock); @@ -687,9 +696,11 @@ esp_err_t gpio_force_hold_all() esp_err_t gpio_force_unhold_all() { +#if SOC_RTCIO_HOLD_SUPPORTED rtc_gpio_force_hold_dis_all(); +#endif portENTER_CRITICAL(&gpio_context.gpio_spinlock); - gpio_hal_force_unhold_all(gpio_context.gpio_hal); + gpio_hal_force_unhold_all(); portEXIT_CRITICAL(&gpio_context.gpio_spinlock); return ESP_OK; } @@ -876,5 +887,35 @@ esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num) gpio_hal_sleep_pupd_config_unapply(gpio_context.gpio_hal, gpio_num); return ESP_OK; } -#endif -#endif +#endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL +#endif // SOC_GPIO_SUPPORT_SLP_SWITCH + +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) +{ + if (!gpio_hal_is_valid_deepsleep_wakeup_gpio(gpio_num)) { + ESP_LOGE(GPIO_TAG, "GPIO %d does not support deep sleep wakeup", gpio_num); + return ESP_ERR_INVALID_ARG; + } + if ((intr_type != GPIO_INTR_LOW_LEVEL) && (intr_type != GPIO_INTR_HIGH_LEVEL)) { + ESP_LOGE(GPIO_TAG, "GPIO wakeup only supports level mode, but edge mode set. gpio_num:%u", gpio_num); + return ESP_ERR_INVALID_ARG; + } + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_deepsleep_wakeup_enable(gpio_context.gpio_hal, gpio_num, intr_type); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + return ESP_OK; +} + +esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num) +{ + if (!gpio_hal_is_valid_deepsleep_wakeup_gpio(gpio_num)) { + ESP_LOGE(GPIO_TAG, "GPIO %d does not support deep sleep wakeup", gpio_num); + return ESP_ERR_INVALID_ARG; + } + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_deepsleep_wakeup_disable(gpio_context.gpio_hal, gpio_num); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + return ESP_OK; +} +#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index cac61ac99d..91dbde2a4d 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -516,6 +516,38 @@ esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num); #endif #endif +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + +#define GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num) ((gpio_num & ~SOC_GPIO_DEEP_SLEEP_WAKEUP_VALID_GPIO_MASK) == 0) + +/** + * @brief Enable GPIO deep-sleep wake-up function. + * + * @param gpio_num GPIO number. + * + * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used. + * + * @note Called by the SDK. User shouldn't call this directly in the APP. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type); + +/** + * @brief Disable GPIO deep-sleep wake-up function. + * + * @param gpio_num GPIO number + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num); + +#endif + #ifdef __cplusplus } #endif diff --git a/components/driver/rtc_io.c b/components/driver/rtc_io.c index 9c96b93b0b..5025fb36aa 100644 --- a/components/driver/rtc_io.c +++ b/components/driver/rtc_io.c @@ -21,7 +21,7 @@ #include "driver/rtc_io.h" #include "hal/rtc_io_hal.h" -static const char *RTCIO_TAG = "RTCIO"; +static const char __attribute__((__unused__)) *RTCIO_TAG = "RTCIO"; #define RTCIO_CHECK(a, str, ret_val) ({ \ if (!(a)) { \ @@ -164,29 +164,19 @@ esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num) esp_err_t rtc_gpio_hold_en(gpio_num_t gpio_num) { -#ifdef CONFIG_IDF_TARGET_ESP32C3 // should use HAL here, TODO ESP32-C3 IDF-2511 - RTCIO_CHECK(gpio_num <= GPIO_NUM_5, "RTCIO number error", ESP_ERR_INVALID_ARG); - REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, BIT(gpio_num)); -#else RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); RTCIO_ENTER_CRITICAL(); rtcio_hal_hold_enable(rtc_io_number_get(gpio_num)); RTCIO_EXIT_CRITICAL(); -#endif return ESP_OK; } esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num) { -#ifdef CONFIG_IDF_TARGET_ESP32C3 // should use HAL here, TODO ESP32-C3 IDF-2511 - RTCIO_CHECK(gpio_num <= GPIO_NUM_5, "RTCIO number error", ESP_ERR_INVALID_ARG); - REG_CLR_BIT(RTC_CNTL_PAD_HOLD_REG, BIT(gpio_num)); -#else RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); RTCIO_ENTER_CRITICAL(); rtcio_hal_hold_disable(rtc_io_number_get(gpio_num)); RTCIO_EXIT_CRITICAL(); -#endif return ESP_OK; } @@ -224,16 +214,6 @@ esp_err_t rtc_gpio_force_hold_dis_all(void) esp_err_t rtc_gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) { -#ifdef CONFIG_IDF_TARGET_ESP32C3 // should use HAL here, TODO ESP32-C3 IDF-2511 - RTCIO_CHECK(gpio_num <= GPIO_NUM_5, "RTCIO number error", ESP_ERR_INVALID_ARG); - REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_M >> gpio_num); - - uint32_t reg = REG_READ(RTC_CNTL_GPIO_WAKEUP_REG); - reg &= (~(RTC_CNTL_GPIO_PIN0_INT_TYPE_V << (RTC_CNTL_GPIO_PIN0_INT_TYPE_S - gpio_num * 3))); - reg |= (intr_type << (RTC_CNTL_GPIO_PIN0_INT_TYPE_S - gpio_num * 3)); - REG_WRITE(RTC_CNTL_GPIO_WAKEUP_REG, reg); - ESP_LOGD(RTCIO_TAG, "gpio wake up 0x%08x", REG_READ(RTC_CNTL_GPIO_WAKEUP_REG)); -#else RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); if (intr_type == GPIO_INTR_POSEDGE || intr_type == GPIO_INTR_NEGEDGE || intr_type == GPIO_INTR_ANYEDGE) { return ESP_ERR_INVALID_ARG; // Dont support this mode. @@ -241,21 +221,15 @@ esp_err_t rtc_gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) RTCIO_ENTER_CRITICAL(); rtcio_hal_wakeup_enable(rtc_io_number_get(gpio_num), intr_type); RTCIO_EXIT_CRITICAL(); -#endif // CONFIG_IDF_TARGET_ESP32C3 return ESP_OK; } esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num) { -#ifdef CONFIG_IDF_TARGET_ESP32C3 // should use HAL here, TODO ESP32-C3 IDF-2511 - RTCIO_CHECK(gpio_num <= GPIO_NUM_5, "RTCIO number error", ESP_ERR_INVALID_ARG); - REG_CLR_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_M >> gpio_num); -#else RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); RTCIO_ENTER_CRITICAL(); rtcio_hal_wakeup_disable(rtc_io_number_get(gpio_num)); RTCIO_EXIT_CRITICAL(); -#endif return ESP_OK; } diff --git a/components/esp_system/include/esp_sleep.h b/components/esp_system/include/esp_sleep.h index 900b1ff4e6..68360a76e2 100644 --- a/components/esp_system/include/esp_sleep.h +++ b/components/esp_system/include/esp_sleep.h @@ -34,6 +34,13 @@ typedef enum { ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high } esp_sleep_ext1_wakeup_mode_t; +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +typedef enum { + ESP_GPIO_WAKEUP_GPIO_LOW = 0, + ESP_GPIO_WAKEUP_GPIO_HIGH = 1 +} esp_deepsleep_gpio_wake_up_mode_t; +#endif + /** * @brief Power domains which can be powered down in sleep mode */ @@ -151,8 +158,6 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void); #endif // SOC_TOUCH_SENSOR_NUM > 0 -#if SOC_PM_SUPPORT_EXT_WAKEUP - /** * @brief Returns true if a GPIO number is valid for use as wakeup source. * @@ -164,6 +169,8 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void); */ bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num); +#if SOC_PM_SUPPORT_EXT_WAKEUP + /** * @brief Enable wakeup using a pin * @@ -224,6 +231,32 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode #endif // SOC_PM_SUPPORT_EXT_WAKEUP +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +/** + * @brief Enable wakeup using specific gpio pins + * + * This function enables an IO pin to wake the chip from deep sleep + * + * @note This function does not modify pin configuration. The pins are + * configured in esp_sleep_start, immediately before + * entering sleep mode. + * + * @note You don't need to care to pull-up or pull-down before using this + * function, because this will be done in esp_sleep_start based on + * param mask you give. BTW, when you use low level to wake up the + * chip, we strongly recommand you to add external registors(pull-up). + * + * @param gpio_pin_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs + * which are have RTC functionality can be used in this bit map. + * @param mode Select logic function used to determine wakeup condition: + * - ESP_GPIO_WAKEUP_GPIO_LOW: wake up when the gpio turn to low. + * - ESP_GPIO_WAKEUP_GPIO_HIGH: wake up when the gpio turn to high. + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if gpio num is more than 5 or mode is invalid, + */ +esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode); +#endif /** * @brief Enable wakeup from light sleep using GPIOs * @@ -279,6 +312,17 @@ esp_err_t esp_sleep_enable_wifi_wakeup(void); */ uint64_t esp_sleep_get_ext1_wakeup_status(void); +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +/** + * @brief Get the bit mask of GPIOs which caused wakeup (gpio) + * + * If wakeup was caused by another source, this function will return 0. + * + * @return bit mask, if GPIOn caused wakeup, BIT(n) will be set + */ +uint64_t esp_sleep_get_gpio_wakeup_status(void); +#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + /** * @brief Set power down mode for an RTC power domain in sleep mode * diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index beca4ae893..bcb769dfe5 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -71,6 +71,7 @@ #include "esp_flash_encrypt.h" #include "hal/rtc_io_hal.h" +#include "hal/gpio_hal.h" #include "hal/wdt_hal.h" #include "soc/rtc.h" #include "soc/efuse_reg.h" @@ -460,7 +461,11 @@ void IRAM_ATTR call_start_cpu0(void) esp_rom_uart_set_clock_baudrate(CONFIG_ESP_CONSOLE_UART_NUM, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE); #endif +#if SOC_RTCIO_HOLD_SUPPORTED rtcio_hal_unhold_all(); +#else + gpio_hal_force_unhold_all(); +#endif esp_cache_err_int_init(); diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index cbcd82b0ad..e8fdf6360a 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -71,8 +71,6 @@ #include "esp32c3/rom/rtc.h" #include "soc/extmem_reg.h" #include "esp_heap_caps.h" -#include "hal/rtc_hal.h" -#include "soc/rtc_caps.h" #endif // If light sleep time is less than that, don't power down flash @@ -139,6 +137,8 @@ typedef struct { uint32_t ext1_rtc_gpio_mask : 18; uint32_t ext0_trigger_level : 1; uint32_t ext0_rtc_gpio_num : 5; + uint32_t gpio_wakeup_mask : 6; + uint32_t gpio_trigger_mode :6; uint32_t sleep_time_adjustment; uint32_t ccount_ticks_record; uint32_t sleep_time_overhead_out; @@ -175,6 +175,9 @@ static void timer_wakeup_prepare(void); #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 static void touch_wakeup_prepare(void); #endif +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +static void esp_deep_sleep_wakeup_prepare(void); +#endif #if CONFIG_MAC_BB_PD #define MAC_BB_POWER_DOWN_CB_NO 2 @@ -473,6 +476,12 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) } #endif +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + if (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN) { + esp_deep_sleep_wakeup_prepare(); + } +#endif + #ifdef CONFIG_IDF_TARGET_ESP32 // Enable ULP wakeup if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { @@ -508,7 +517,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) */ #if CONFIG_IDF_TARGET_ESP32 reject_triggers = RTC_CNTL_LIGHT_SLP_REJECT_EN_M | RTC_CNTL_GPIO_REJECT_EN_M; -#elif CONFIG_IDF_TARGET_ESP32S2 +#else reject_triggers = s_config.wakeup_triggers; #endif } @@ -915,17 +924,17 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void) #endif // SOC_TOUCH_SENSOR_NUM > 0 -#if SOC_PM_SUPPORT_EXT_WAKEUP - bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num) { #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED return RTC_GPIO_IS_VALID_GPIO(gpio_num); #else - return GPIO_IS_VALID_GPIO(gpio_num); + return GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num); #endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED } +#if SOC_PM_SUPPORT_EXT_WAKEUP + esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) { if (level < 0 || level > 1) { @@ -1035,6 +1044,66 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void) #endif // SOC_PM_SUPPORT_EXT_WAKEUP +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +uint64_t esp_sleep_get_gpio_wakeup_status(void) +{ + if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) { + return 0; + } + + return rtc_hal_gpio_get_wakeup_pins(); +} + +static void esp_deep_sleep_wakeup_prepare(void) +{ + for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) { + if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) { + continue; + } + if (s_config.gpio_trigger_mode & BIT(gpio_idx)) { + ESP_ERROR_CHECK(gpio_pullup_dis(gpio_idx)); + ESP_ERROR_CHECK(gpio_pulldown_en(gpio_idx)); + } else { + ESP_ERROR_CHECK(gpio_pullup_en(gpio_idx)); + ESP_ERROR_CHECK(gpio_pulldown_dis(gpio_idx)); + } + rtc_hal_gpio_set_wakeup_pins(); + ESP_ERROR_CHECK(gpio_hold_en(gpio_idx)); + } +} + +esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode) +{ + if (mode > ESP_GPIO_WAKEUP_GPIO_HIGH) { + ESP_LOGE(TAG, "invalid mode"); + return ESP_ERR_INVALID_ARG; + } + gpio_int_type_t intr_type = ((mode == ESP_GPIO_WAKEUP_GPIO_LOW) ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL); + esp_err_t err = ESP_OK; + for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++, gpio_pin_mask >>= 1) { + if ((gpio_pin_mask & 1) == 0) { + continue; + } + if (!esp_sleep_is_valid_wakeup_gpio(gpio_idx)) { + ESP_LOGE(TAG, "invalid mask, please ensure gpio number is no more than 5"); + return ESP_ERR_INVALID_ARG; + } + err = gpio_deep_sleep_wakeup_enable(gpio_idx, intr_type); + + s_config.gpio_wakeup_mask |= BIT(gpio_idx); + if (mode == ESP_GPIO_WAKEUP_GPIO_HIGH) { + s_config.gpio_trigger_mode |= (mode << gpio_idx); + } else { + s_config.gpio_trigger_mode &= ~(mode << gpio_idx); + } + } + s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN; + rtc_hal_gpio_clear_wakeup_pins(); + return err; +} + +#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + esp_err_t esp_sleep_enable_gpio_wakeup(void) { #if CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_system/test/test_sleep.c b/components/esp_system/test/test_sleep.c index 18ae86d897..08fef33699 100644 --- a/components/esp_system/test/test_sleep.c +++ b/components/esp_system/test/test_sleep.c @@ -18,6 +18,7 @@ #include "test_utils.h" #include "sdkconfig.h" #include "esp_rom_sys.h" +#include "esp_timer.h" #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3, ESP32S3) @@ -30,6 +31,9 @@ #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/clk.h" #include "esp32s3/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/clk.h" +#include "esp32c3/rom/rtc.h" #endif #define ESP_EXT0_WAKEUP_LEVEL_LOW 0 @@ -527,3 +531,28 @@ static void check_time_deepsleep(void) TEST_CASE_MULTIPLE_STAGES("check a time after wakeup from deep sleep", "[deepsleep][reset=DEEPSLEEP_RESET]", trigger_deepsleep, check_time_deepsleep); #endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3, ESP32S3) + +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +static void gpio_deepsleep_wakeup_config(void) +{ + gpio_config_t io_conf = { + .mode = GPIO_MODE_INPUT, + .pin_bit_mask = ((1ULL << 2) | (1ULL << 4)) + }; + ESP_ERROR_CHECK(gpio_config(&io_conf)); +} + +TEST_CASE("wake up using GPIO (2 or 4 high)", "[deepsleep][ignore]") +{ + gpio_deepsleep_wakeup_config(); + ESP_ERROR_CHECK(esp_deep_sleep_enable_gpio_wakeup(((1ULL << 2) | (1ULL << 4)) , ESP_GPIO_WAKEUP_GPIO_HIGH)); + esp_deep_sleep_start(); +} + +TEST_CASE("wake up using GPIO (2 or 4 low)", "[deepsleep][ignore]") +{ + gpio_deepsleep_wakeup_config(); + ESP_ERROR_CHECK(esp_deep_sleep_enable_gpio_wakeup(((1ULL << 2) | (1ULL << 4)) , ESP_GPIO_WAKEUP_GPIO_LOW)); + esp_deep_sleep_start(); +} +#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 7f37281358..5fdd8f38bb 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -26,6 +26,7 @@ #include "soc/gpio_periph.h" #include "soc/rtc_cntl_reg.h" #include "hal/gpio_types.h" +#include "stdlib.h" #ifdef __cplusplus extern "C" { @@ -343,7 +344,11 @@ static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw) */ static inline void gpio_ll_hold_en(gpio_dev_t *hw, gpio_num_t gpio_num) { - SET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]); + if (gpio_num <= GPIO_NUM_5) { + REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, BIT(gpio_num)); + } else { + SET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]); + } } /** @@ -354,7 +359,11 @@ static inline void gpio_ll_hold_en(gpio_dev_t *hw, gpio_num_t gpio_num) */ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, gpio_num_t gpio_num) { - CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]); + if (gpio_num <= GPIO_NUM_5) { + REG_CLR_BIT(RTC_CNTL_PAD_HOLD_REG, BIT(gpio_num)); + } else { + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]); + } } /** @@ -390,11 +399,13 @@ static inline void gpio_ll_force_hold_all(gpio_dev_t *hw) { CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); + SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M); } -static inline void gpio_ll_force_unhold_all(gpio_dev_t *hw) +static inline void gpio_ll_force_unhold_all(void) { CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); + CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD); } @@ -509,6 +520,41 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, gpio_num_t gpio_n PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); } +/** + * @brief Enable GPIO deep-sleep wake-up function. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number. + * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used. + */ +static inline void gpio_ll_deepsleep_wakeup_enable(gpio_dev_t *hw, gpio_num_t gpio_num, gpio_int_type_t intr_type) +{ + if (gpio_num > GPIO_NUM_5) { + abort(); // gpio lager than 5 doesn't support. + } + REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_PIN_CLK_GATE); + REG_SET_BIT(RTC_CNTL_EXT_WAKEUP_CONF_REG, RTC_CNTL_GPIO_WAKEUP_FILTER); + SET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - gpio_num)); + uint32_t reg = REG_READ(RTC_CNTL_GPIO_WAKEUP_REG); + reg &= (~(RTC_CNTL_GPIO_PIN0_INT_TYPE_V << (RTC_CNTL_GPIO_PIN0_INT_TYPE_S - gpio_num * 3))); + reg |= (intr_type << (RTC_CNTL_GPIO_PIN0_INT_TYPE_S - gpio_num * 3)); + REG_WRITE(RTC_CNTL_GPIO_WAKEUP_REG, reg); +} + +/** + * @brief Disable GPIO deep-sleep wake-up function. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_deepsleep_wakeup_disable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + if (gpio_num > GPIO_NUM_5) { + abort(); // gpio lager than 5 doesn't support. + } + CLEAR_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - gpio_num)); + CLEAR_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_PIN0_INT_TYPE_S - gpio_num * 3); +} #ifdef __cplusplus } diff --git a/components/hal/esp32c3/include/hal/rtc_cntl_ll.h b/components/hal/esp32c3/include/hal/rtc_cntl_ll.h index bcc8d0fcdb..72385568a4 100644 --- a/components/hal/esp32c3/include/hal/rtc_cntl_ll.h +++ b/components/hal/esp32c3/include/hal/rtc_cntl_ll.h @@ -32,19 +32,18 @@ static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t) SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN_M); } -static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void) +static inline uint32_t rtc_cntl_ll_gpio_get_wakeup_pins(void) { - abort(); // ESP32-C3 TODO IDF-2106 + return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS); } -static inline void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +static inline void rtc_cntl_ll_gpio_set_wakeup_pins(void) { - abort(); // ESP32-C3 TODO IDF-2106 + REG_CLR_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR); } -static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void) +static inline void rtc_cntl_ll_gpio_clear_wakeup_pins(void) { - abort(); // ESP32-C3 TODO IDF-2106 REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR); } diff --git a/components/hal/esp32c3/include/hal/rtc_io_ll.h b/components/hal/esp32c3/include/hal/rtc_io_ll.h deleted file mode 100644 index 624b8e3ae1..0000000000 --- a/components/hal/esp32c3/include/hal/rtc_io_ll.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in soc/include/hal/readme.md - ******************************************************************************/ - - -/* Note: ESP32-C3 does not have a full RTC_IO module, this LL only controls - hold/wakeup/32kHz crystal functions for IOs */ - -#pragma once - -#include -#include "soc/rtc_cntl_reg.h" -#include "hal/rtc_io_types.h" -#include "hal/gpio_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - RTCIO_FUNC_RTC = 0x0, /*!< The pin controled by RTC module. */ - RTCIO_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ -} rtcio_ll_func_t; - -typedef enum { - RTCIO_WAKEUP_DISABLE = 0, /*!< Disable GPIO interrupt */ - RTCIO_WAKEUP_LOW_LEVEL = 0x4, /*!< GPIO interrupt type : input low level trigger */ - RTCIO_WAKEUP_HIGH_LEVEL = 0x5, /*!< GPIO interrupt type : input high level trigger */ -} rtcio_ll_wake_type_t; - -typedef enum { - RTCIO_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */ - RTCIO_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */ -} rtcio_ll_out_mode_t; - -/** - * @brief Select the rtcio function. - * - * @note The RTC function must be selected before the pad analog function is enabled. - * @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) -{ - abort(); // TODO ESP32-C3 IDF-2407 -} - -/** - * Enable force hold function for 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) -{ - abort(); // TODO ESP32-C3 IDF-2407 -} - -/** - * 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) -{ - abort(); // TODO ESP32-C3 IDF-2407 -} - -/** - * Enable force hold function for 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_all(void) -{ - abort(); // TODO ESP32-C3 IDF-2407 -} - -/** - * 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_unhold_all(void) -{ - CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M); -} - -/** - * Enable wakeup function and set wakeup type from light sleep status 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) -{ - abort(); // TODO ESP32-C3 IDF-2407 -} - -/** - * Disable wakeup function from light sleep status for rtcio. - * - * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). - */ -static inline void rtcio_ll_wakeup_disable(int rtcio_num) -{ - abort(); // TODO ESP32-C3 IDF-2407 -} - -static inline void rtcio_ll_ext0_set_wakeup_pin(int rtcio_num, int level) -{ - abort(); // TODO ESP32-C3 IDF-2106 IDF-2407 -} - - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 2ee9b08cf9..aa02c11199 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -413,7 +413,7 @@ static inline void gpio_ll_force_hold_all(gpio_dev_t *hw) SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); } -static inline void gpio_ll_force_unhold_all(gpio_dev_t *hw) +static inline void gpio_ll_force_unhold_all(void) { CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index f3011bbaa0..783def85e6 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -413,7 +413,7 @@ static inline void gpio_ll_force_hold_all(gpio_dev_t *hw) SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); } -static inline void gpio_ll_force_unhold_all(gpio_dev_t *hw) +static inline void gpio_ll_force_unhold_all(void) { CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD); diff --git a/components/hal/include/hal/gpio_hal.h b/components/hal/include/hal/gpio_hal.h index 31a1814c1a..5a403f529c 100644 --- a/components/hal/include/hal/gpio_hal.h +++ b/components/hal/include/hal/gpio_hal.h @@ -335,7 +335,7 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, gpio_num_t gpio_num); * * @param hal Context of the HAL layer * */ -#define gpio_hal_force_unhold_all(hal) gpio_ll_force_unhold_all((hal)->dev) +#define gpio_hal_force_unhold_all() gpio_ll_force_unhold_all() #endif #if SOC_GPIO_SUPPORT_SLP_SWITCH @@ -435,8 +435,37 @@ void gpio_hal_sleep_pupd_config_apply(gpio_hal_context_t *hal, gpio_num_t gpio_n * @param gpio_num GPIO number. */ void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, gpio_num_t gpio_num); -#endif -#endif +#endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL +#endif //SOC_GPIO_SUPPORT_SLP_SWITCH + +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + +/** + * @brief Enable GPIO deep-sleep wake-up function. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number. + * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used. + */ +#define gpio_hal_deepsleep_wakeup_enable(hal, gpio_num, intr_type) gpio_ll_deepsleep_wakeup_enable((hal)->dev, gpio_num, intr_type) + +/** + * @brief Disable GPIO deep-sleep wake-up function. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_deepsleep_wakeup_disable(hal, gpio_num) gpio_ll_deepsleep_wakeup_disable((hal)->dev, gpio_num) + +/** + * @brief Judge if the gpio is valid for waking up chip from deep-sleep + * + * @param gpio_num GPIO number + */ +#define gpio_hal_is_valid_deepsleep_wakeup_gpio(gpio_num) (gpio_num <= GPIO_NUM_5) + +#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/rtc_hal.h b/components/hal/include/hal/rtc_hal.h index e4874ad168..1473ce0d30 100644 --- a/components/hal/include/hal/rtc_hal.h +++ b/components/hal/include/hal/rtc_hal.h @@ -15,17 +15,33 @@ #pragma once #include "hal/gpio_types.h" -#include "hal/rtc_io_ll.h" #include "hal/rtc_cntl_ll.h" +#if !CONFIG_IDF_TARGET_ESP32C3 +#include "hal/rtc_io_ll.h" +#endif #define RTC_HAL_DMA_LINK_NODE_SIZE (16) +#if SOC_PM_SUPPORT_EXT_WAKEUP + #define rtc_hal_ext1_get_wakeup_pins() rtc_cntl_ll_ext1_get_wakeup_pins() #define rtc_hal_ext1_set_wakeup_pins(mask, mode) rtc_cntl_ll_ext1_set_wakeup_pins(mask, mode) #define rtc_hal_ext1_clear_wakeup_pins() rtc_cntl_ll_ext1_clear_wakeup_pins() +#endif + +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + +#define rtc_hal_gpio_get_wakeup_pins() rtc_cntl_ll_gpio_get_wakeup_pins() + +#define rtc_hal_gpio_clear_wakeup_pins() rtc_cntl_ll_gpio_clear_wakeup_pins() + +#define rtc_hal_gpio_set_wakeup_pins() rtc_cntl_ll_gpio_set_wakeup_pins() + +#endif + #define rtc_hal_set_wakeup_timer(ticks) rtc_cntl_ll_set_wakeup_timer(ticks) void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next); diff --git a/components/hal/include/hal/rtc_io_hal.h b/components/hal/include/hal/rtc_io_hal.h index 2ed0782db5..b5f1fd7f21 100644 --- a/components/hal/include/hal/rtc_io_hal.h +++ b/components/hal/include/hal/rtc_io_hal.h @@ -22,14 +22,17 @@ #pragma once +#include +#if !CONFIG_IDF_TARGET_ESP32C3 #include "soc/soc_caps.h" #include "hal/rtc_io_ll.h" -#include +#endif #ifdef __cplusplus extern "C" { #endif +#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED /** * Select the rtcio function. * @@ -39,8 +42,6 @@ extern "C" { */ #define rtcio_hal_function_select(rtcio_num, func) rtcio_ll_function_select(rtcio_num, func) -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED - /** * Enable rtcio output. * @@ -210,7 +211,6 @@ void rtcio_hal_set_direction_in_sleep(int rtcio_num, rtc_gpio_mode_t mode); * @param rtcio_num The index of rtcio. 0 ~ SOC_RTCIO_PIN_COUNT. */ #define rtcio_hal_unhold_all() rtcio_ll_force_unhold_all() - #endif // SOC_RTCIO_HOLD_SUPPORTED #if SOC_RTCIO_WAKE_SUPPORTED diff --git a/components/soc/esp32c3/gpio_periph.c b/components/soc/esp32c3/gpio_periph.c index 88ef3a7418..e72f7e20a7 100644 --- a/components/soc/esp32c3/gpio_periph.c +++ b/components/soc/esp32c3/gpio_periph.c @@ -40,12 +40,12 @@ const uint32_t GPIO_PIN_MUX_REG[SOC_GPIO_PIN_COUNT] = { }; const uint32_t GPIO_HOLD_MASK[SOC_GPIO_PIN_COUNT] = { - 0, //GPIO0 - 0, //GPIO1 - 0, //GPIO2 - 0, //GPIO3 - 0, //GPIO4 - 0, //GPIO5 + BIT(0), //GPIO0 + BIT(1), //GPIO1 + BIT(2), //GPIO2 + BIT(3), //GPIO3 + BIT(4), //GPIO4 + BIT(5), //GPIO5 BIT(5), //GPIO6 BIT(6), //GPIO7 BIT(3), //GPIO8 diff --git a/components/soc/esp32c3/include/soc/gpio_caps.h b/components/soc/esp32c3/include/soc/gpio_caps.h index 9b6924ed64..770b7b2ad1 100644 --- a/components/soc/esp32c3/include/soc/gpio_caps.h +++ b/components/soc/esp32c3/include/soc/gpio_caps.h @@ -26,7 +26,9 @@ extern "C" { // On ESP32-C3, Digital IOs have their own registers to control pullup/down/capability, independent with RTC registers. #define GPIO_SUPPORTS_RTC_INDEPENDENT (1) // Force hold is a new function of ESP32-C3 -#define GPIO_SUPPORTS_FORCE_HOLD (1) +#define SOC_GPIO_SUPPORT_FORCE_HOLD (1) +// GPIO0~5 on ESP32C3 can support chip deep sleep wakeup +#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) #define GPIO_MODE_DEF_DISABLE (0) #define GPIO_MODE_DEF_INPUT (BIT0) @@ -35,6 +37,7 @@ extern "C" { #define SOC_GPIO_VALID_GPIO_MASK ((1U<