esp32c6: bringup deepsleep examples

This commit is contained in:
wuzhenghui 2023-02-18 14:13:52 +08:00
parent d3ec7880fe
commit 9eae151f7c
19 changed files with 282 additions and 87 deletions

View File

@ -22,6 +22,10 @@
#include "hal/gpio_hal.h"
#include "esp_rom_gpio.h"
#if (SOC_RTCIO_PIN_COUNT > 0)
#include "hal/rtc_io_hal.h"
#endif
static const char *GPIO_TAG = "gpio";
#define GPIO_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, GPIO_TAG, "%s", str)

View File

@ -37,6 +37,14 @@ extern "C" {
#define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17)
#define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature
#if SOC_PM_SUPPORT_EXT0_WAKEUP
#define RTC_EXT0_TRIG_EN PMU_EXT0_WAKEUP_EN //!< EXT0 wakeup
#else
#define RTC_EXT0_TRIG_EN 0
#endif
#if SOC_PM_SUPPORT_EXT1_WAKEUP
#define RTC_EXT1_TRIG_EN PMU_EXT1_WAKEUP_EN //!< EXT1 wakeup
#endif
#define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup
#define RTC_WIFI_TRIG_EN PMU_WIFI_SOC_WAKEUP_EN //!< WIFI wakeup (light sleep only)
@ -60,6 +68,12 @@ extern "C" {
RTC_USB_TRIG_EN | \
RTC_BROWNOUT_DET_TRIG_EN)
#if SOC_PM_SUPPORT_EXT0_WAKEUP
#define PMU_EXT0_WAKEUP_EN BIT(0)
#endif
#if SOC_PM_SUPPORT_EXT1_WAKEUP
#define PMU_EXT1_WAKEUP_EN BIT(1)
#endif
#define PMU_GPIO_WAKEUP_EN BIT(2)
#define PMU_WIFI_BEACON_WAKEUP_EN BIT(3)
@ -82,6 +96,7 @@ extern "C" {
#define PMU_SLEEP_PD_MEM_G1 BIT(7)
#define PMU_SLEEP_PD_MEM_G2 BIT(8)
#define PMU_SLEEP_PD_MEM_G3 BIT(9)
#define PMU_SLEEP_PD_MEM (PMU_SLEEP_PD_MEM_G0|PMU_SLEEP_PD_MEM_G1|PMU_SLEEP_PD_MEM_G2|PMU_SLEEP_PD_MEM_G3)
#define PMU_SLEEP_PD_XTAL BIT(10)
#define PMU_SLEEP_PD_RC_FAST BIT(11)
#define PMU_SLEEP_PD_XTAL32K BIT(12)

View File

@ -250,6 +250,7 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
* - ESP32: 0, 2, 4, 12-15, 25-27, 32-39;
* - ESP32-S2: 0-21;
* - ESP32-S3: 0-21.
* - ESP32-C6: 0-7.
* @param mode select logic function used to determine wakeup condition:
* - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low
* - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high

View File

@ -14,8 +14,8 @@
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/pmu_struct.h"
#include "hal/lp_aon_hal.h"
#include "esp_private/esp_pmu.h"
#include "esp32c6/rom/rtc.h"
#define HP(state) (PMU_MODE_HP_ ## state)
#define LP(state) (PMU_MODE_LP_ ## state)
@ -250,6 +250,9 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp)
uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
{
assert(PMU_instance()->hal);
lp_aon_hal_inform_wakeup_type(dslp);
pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt);
pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt);

View File

@ -565,7 +565,6 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
{
RvCoreCriticalSleepFrame * frame = rv_core_critical_regs_save();
if ((frame->pmufunc & 0x3) == 0x1) {
REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
REG_WRITE(LIGHT_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
}

View File

@ -21,7 +21,9 @@
#include "hal/gpio_hal.h"
#include "hal/rtc_io_hal.h"
#if !SOC_PMU_SUPPORTED
#if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#include "hal/rtc_hal.h"
#endif
@ -145,11 +147,11 @@ IRAM_ATTR void esp_sleep_isolate_digital_gpio(void)
}
}
}
#endif
#endif // !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
void esp_deep_sleep_wakeup_io_reset(void)
{
#if SOC_PM_SUPPORT_EXT_WAKEUP
#if SOC_PM_SUPPORT_EXT1_WAKEUP
uint32_t rtc_io_mask = rtc_hal_ext1_get_wakeup_pins();
// Disable ext1 wakeup before releasing hold, such that wakeup status can reflect the correct wakeup pin
rtc_hal_ext1_clear_wakeup_pins();

View File

@ -25,7 +25,9 @@
#include "driver/rtc_io.h"
#include "hal/rtc_io_hal.h"
#if !SOC_PMU_SUPPORTED
#if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#include "hal/rtc_cntl_ll.h"
#include "hal/rtc_hal.h"
#endif
@ -156,12 +158,16 @@ typedef struct {
portMUX_TYPE lock;
uint64_t sleep_duration;
uint32_t wakeup_triggers : 15;
#if SOC_PM_SUPPORT_EXT1_WAKEUP
uint32_t ext1_trigger_mode : 1;
uint32_t ext1_rtc_gpio_mask : 22; //22 is the maximum RTCIO number in all chips
uint32_t ext1_rtc_gpio_mask : 22; // 22 is the maximum RTCIO number in all chips
#endif
#if SOC_PM_SUPPORT_EXT0_WAKEUP
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;
#endif
uint32_t gpio_wakeup_mask : 8; // 8 is the maximum RTCIO number in all chips that support GPIO wakeup
uint32_t gpio_trigger_mode : 8;
uint32_t sleep_time_adjustment;
uint32_t ccount_ticks_record;
uint32_t sleep_time_overhead_out;
@ -237,14 +243,19 @@ static void RTC_IRAM_ATTR __attribute__((used, noinline)) esp_wake_stub_start(vo
* must be simple enough to ensure that there is no litteral data before the
* wake stub entry, otherwise, the litteral data before the wake stub entry
* will not be CRC checked. */
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150
static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void)
{
#define _SYM2STR(s) # s
#define SYM2STR(s) _SYM2STR(s)
#ifdef __riscv
__asm__ __volatile__ ("call " SYM2STR(esp_wake_stub_start) "\n");
__asm__ __volatile__ (
"addi sp, sp, -16 \n"
"sw ra, 0(sp) \n"
"jal ra, " SYM2STR(esp_wake_stub_start) "\n"
"lw ra, 0(sp) \n"
"addi sp, sp, 16 \n"
);
#else
// call4 has a larger effective addressing range (-524284 to 524288 bytes),
// which is sufficient for instruction addressing in RTC fast memory.
@ -252,7 +263,6 @@ static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void
#endif
}
#endif // !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
/* Wake from deep sleep stub
@ -537,8 +547,6 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
esp_sleep_isolate_digital_gpio();
#endif
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
extern char _rtc_text_start[];
#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM
@ -549,7 +557,12 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start;
#endif
esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)esp_wake_stub_entry, rtc_fast_length);
// Enter Deep Sleep
#if SOC_PMU_SUPPORTED
result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
#else
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
#endif
#else
#if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
/* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */
@ -563,9 +576,6 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
#endif
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
#else
result = ESP_OK;
#endif
} else {
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
@ -649,7 +659,14 @@ void IRAM_ATTR esp_deep_sleep_start(void)
// Correct the sleep time
s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US;
#if SOC_PMU_SUPPORTED
uint32_t force_pd_flags = PMU_SLEEP_PD_TOP | PMU_SLEEP_PD_VDDSDIO | PMU_SLEEP_PD_MODEM | PMU_SLEEP_PD_HP_PERIPH \
| PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_MEM | PMU_SLEEP_PD_XTAL | PMU_SLEEP_PD_RC_FAST \
| PMU_SLEEP_PD_XTAL32K |PMU_SLEEP_PD_RC32K;
#else
uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_INT_8M | RTC_SLEEP_PD_XTAL;
#endif
#if SOC_PM_SUPPORT_WIFI_PD
force_pd_flags |= RTC_SLEEP_PD_WIFI;
@ -1191,25 +1208,20 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void)
return gpio_mask;
}
#endif // SOC_PM_SUPPORT_EXT_WAKEUP
#endif // SOC_PM_SUPPORT_EXT1_WAKEUP
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
uint64_t esp_sleep_get_gpio_wakeup_status(void)
{
#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349
return 0;
#else
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) {
return 0;
}
return rtc_hal_gpio_get_wakeup_status();
#endif
}
static void gpio_deep_sleep_wakeup_prepare(void)
{
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349
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;
@ -1225,7 +1237,6 @@ static void gpio_deep_sleep_wakeup_prepare(void)
}
// Clear state from previous wakeup
rtc_hal_gpio_clear_wakeup_status();
#endif
}
esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)

View File

@ -68,6 +68,9 @@ void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub)
// Go to sleep.
#if SOC_PMU_SUPPORTED
pmu_ll_hp_clear_wakeup_intr_status(&PMU);
pmu_ll_hp_clear_reject_intr_status(&PMU);
pmu_ll_hp_clear_reject_cause(&PMU);
pmu_ll_hp_set_sleep_enable(&PMU);
#else
rtc_cntl_ll_sleep_enable();
@ -87,8 +90,15 @@ void RTC_IRAM_ATTR esp_wake_stub_set_wakeup_time(uint64_t time_in_us)
{
#if SOC_LP_TIMER_SUPPORTED
uint64_t rtc_count_delta = lp_timer_ll_time_to_count(time_in_us);
uint64_t rtc_curr_count = lp_timer_hal_get_cycle_count(0);
lp_timer_hal_set_alarm_target(0, rtc_curr_count + rtc_count_delta);
lp_timer_ll_counter_snapshot(&LP_TIMER);
uint32_t lo = lp_timer_ll_get_counter_value_low(&LP_TIMER, 0);
uint32_t hi = lp_timer_ll_get_counter_value_high(&LP_TIMER, 0);
uint64_t rtc_curr_count = (uint64_t)hi << 32 | lo;
lp_timer_ll_clear_alarm_intr_status(&LP_TIMER);
lp_timer_ll_set_alarm_target(&LP_TIMER, 0, rtc_curr_count + rtc_count_delta);
lp_timer_ll_set_target_enable(&LP_TIMER, 0, true);
#else
uint64_t rtc_count_delta = rtc_cntl_ll_time_to_count(time_in_us);
uint64_t rtc_curr_count = rtc_cntl_ll_get_rtc_time();

View File

@ -17,6 +17,8 @@ SECTIONS
{
. = ALIGN(4);
_rtc_fast_start = ABSOLUTE(.);
_rtc_text_start = ABSOLUTE(.);
*(.rtc.entry.text)
mapping[rtc_text]

View File

@ -20,6 +20,7 @@
#include "soc/gpio_periph.h"
#include "soc/gpio_struct.h"
#include "soc/lp_aon_struct.h"
#include "soc/lp_io_struct.h"
#include "soc/pmu_reg.h"
#include "soc/usb_serial_jtag_reg.h"
#include "soc/pcr_struct.h"
@ -396,6 +397,24 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
LP_AON.gpio_hold0.gpio_hold0 &= ~GPIO_HOLD_MASK[gpio_num];
}
/**
* @brief Get digital gpio pad hold status.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number, only support output GPIOs
*
* @note caller must ensure that gpio_num is a digital io pad
*
* @return
* - true digital gpio pad is held
* - false digital gpio pad is unheld
*/
__attribute__((always_inline))
static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
{
return !!(LP_AON.gpio_hold0.gpio_hold0 & GPIO_HOLD_MASK[gpio_num]);
}
/**
* @brief Set pad input to a peripheral signal through the IOMUX.
*
@ -589,63 +608,6 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num
PIN_SLP_OUTPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
}
/**
* @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, uint32_t gpio_num, gpio_int_type_t intr_type)
{
HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function");
LP_AON.ext_wakeup_cntl.ext_wakeup_filter = 1;
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
wakeup_sel_mask |= BIT(gpio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, wakeup_sel_mask);
bool trigger_level = (intr_type == GPIO_INTR_LOW_LEVEL) ? 0 : 1;
uint32_t wakeup_level_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv);
if (trigger_level) {
wakeup_level_mask |= BIT(gpio_num);
} else {
wakeup_level_mask &= ~BIT(gpio_num);
}
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, wakeup_level_mask);
}
/**
* @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, uint32_t gpio_num)
{
HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function");
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
wakeup_sel_mask &= ~BIT(gpio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, wakeup_sel_mask);
}
/**
* @brief Get the status of whether an IO is used for deep-sleep wake-up.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
* @return True if the pin is enabled to wake up from deep-sleep
*/
static inline bool gpio_ll_deepsleep_wakeup_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
{
HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function");
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
return wakeup_sel_mask & BIT(gpio_num);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "hal/lp_aon_ll.h"
#define rtc_hal_ext1_get_wakeup_status() lp_aon_hal_ext1_get_wakeup_status()
#define rtc_hal_ext1_clear_wakeup_status() lp_aon_hal_ext1_clear_wakeup_status()
#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_hal_ext1_set_wakeup_pins(mask, mode)
#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_hal_ext1_clear_wakeup_pins()
#define rtc_hal_ext1_get_wakeup_pins() lp_aon_hal_ext1_get_wakeup_pins()
#define lp_aon_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status()
#define lp_aon_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status()
#define lp_aon_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode)
#define lp_aon_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins()
#define lp_aon_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins()
#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp)

View File

@ -0,0 +1,97 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for ESP32-C6 LP_AON register operations
#pragma once
#include <stdlib.h>
#include "soc/soc.h"
#include "soc/lp_aon_struct.h"
#include "hal/misc.h"
#include "esp32c6/rom/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get ext1 wakeup source status
* @return The lower 8 bits of the returned value are the bitmap of
* the wakeup source status, bit 0~7 corresponds to LP_IO 0~7
*/
static inline uint32_t lp_aon_ll_ext1_get_wakeup_status(void)
{
return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status);
}
/**
* @brief Clear the ext1 wakeup source status
*/
static inline void lp_aon_ll_ext1_clear_wakeup_status(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status_clr, 1);
}
/**
* @brief Set the wake-up LP_IO of the ext1 wake-up source
* @param mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7
* @param mode 0: Wake the chip when all selected GPIOs go low
* 1: Wake the chip when any of the selected GPIOs go high
*/
static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t mask, int mode)
{
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
wakeup_sel_mask |= mask;
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, wakeup_sel_mask);
uint32_t wakeup_level_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv);
if (mode) {
wakeup_level_mask |= mask;
} else {
wakeup_level_mask &= ~mask;
}
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, wakeup_level_mask);
}
/**
* @brief Clear all ext1 wakup-source setting
*/
static inline void lp_aon_ll_ext1_clear_wakeup_pins(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, 0);
}
/**
* @brief Get ext1 wakeup source setting
* @return The lower 8 bits of the returned value are the bitmap of
* the wakeup source status, bit 0~7 corresponds to LP_IO 0~7
*/
static inline uint32_t lp_aon_ll_ext1_get_wakeup_pins(void)
{
return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
}
/**
* @brief ROM obtains the wake-up type through LP_AON_STORE9_REG[0].
* Set the flag to inform
* @param true: deepsleep false: lightsleep
*/
static inline void lp_aon_ll_inform_wakeup_type(bool dslp)
{
if (dslp) {
REG_SET_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */
} else {
REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
}
}
#ifdef __cplusplus
}
#endif

View File

@ -13,12 +13,14 @@
#pragma once
#include <stdlib.h>
#include <stdbool.h>
#include "soc/rtc_periph.h"
#include "soc/pcr_struct.h"
#include "soc/rtc_io_struct.h"
#include "soc/lp_aon_struct.h"
#include "soc/pmu_struct.h"
#include "hal/misc.h"
#include "hal/assert.h"
#include "hal/gpio_types.h"
#include "soc/io_mux_reg.h"
@ -366,6 +368,38 @@ static inline void rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num)
LP_IO.gpio[gpio_num].slp_sel = 0;
}
/**
* @brief Get the status of whether an IO is used for sleep wake-up.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
* @return True if the pin is enabled to wake up from deep-sleep
*/
static inline bool rtcio_ll_wakeup_is_enabled(gpio_num_t gpio_num)
{
HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function");
// On ESP32-C6, (lp_io pin number) == (gpio pin number)
return LP_IO.pin[gpio_num].wakeup_enable;
}
/**
* @brief Get the rtc io interrupt status
*
* @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT.
*/
static inline uint32_t rtcio_ll_get_interrupt_status(void)
{
return (uint32_t)(LP_IO.status.status_interrupt);
}
/**
* @brief Clear all LP IO pads status
*/
static inline void rtcio_ll_clear_interrupt_status(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.status_w1tc, status_w1tc, 0xff);
}
#ifdef __cplusplus
}
#endif

View File

@ -448,7 +448,7 @@ void gpio_hal_sleep_pupd_config_apply(gpio_hal_context_t *hal, uint32_t gpio_num
void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, uint32_t gpio_num);
#endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0)
/**
* @brief Enable GPIO deep-sleep wake-up function.
*

View File

@ -53,7 +53,7 @@ typedef struct rtc_cntl_sleep_retent {
#endif // SOC_PM_SUPPORT_EXT1_WAKEUP
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0)
#define rtc_hal_gpio_get_wakeup_status() rtc_cntl_ll_gpio_get_wakeup_status()

View File

@ -254,6 +254,36 @@ void rtcio_hal_isolate(int rtc_num);
#endif
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT > 0)
#define gpio_hal_deepsleep_wakeup_enable(hal, gpio_num, intr_type) rtcio_hal_wakeup_enable(gpio_num, intr_type)
#define gpio_hal_deepsleep_wakeup_disable(hal, gpio_num) rtcio_hal_wakeup_disable(gpio_num)
#define gpio_hal_deepsleep_wakeup_is_enabled(hal, gpio_num) rtcio_hal_wakeup_is_enabled(gpio_num)
#define rtc_hal_gpio_get_wakeup_status() rtcio_hal_get_interrupt_status()
#define rtc_hal_gpio_clear_wakeup_status() rtcio_hal_clear_interrupt_status()
/**
* @brief Get the status of whether an IO is used for sleep wake-up.
*
* @param hw Peripheral GPIO hardware instance address.
* @param rtcio_num GPIO number
* @return True if the pin is enabled to wake up from deep-sleep
*/
#define rtcio_hal_wakeup_is_enabled(rtcio_num) rtcio_ll_wakeup_is_enabled(rtcio_num)
/**
* @brief Get the rtc io interrupt status
*
* @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT.
*/
#define rtcio_hal_get_interrupt_status() rtcio_ll_get_interrupt_status()
/**
* @brief Clear all LP IO pads status
*/
#define rtcio_hal_clear_interrupt_status() rtcio_ll_clear_interrupt_status()
#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
#ifdef __cplusplus
}
#endif

View File

@ -11,7 +11,7 @@ The following wake up sources are demonstrated in this example (refer to the [Wa
- **Timer:** An RTC timer that can be programmed to trigger a wake up after a preset time. This example will trigger a wake up every 20 seconds.
- **EXT0:** External wake up 0 can trigger wakeup when one predefined RTC GPIO is at a predefined logic level. This example uses GPIO25 in ESP32 or GPIO3 in ESP32-S2/S3 to trigger a wake up when the pin is HIGH. (This wake up source is only available on ESP32, ESP32-S2, and ESP32-S3.)
- **EXT1:** External wake up 1 which is tied to multiple RTC GPIOs. This example uses GPIO2 and GPIO4 to trigger a wake up with any one of the two pins are HIGH. (This wake up source is only available on ESP32, ESP32-S2, and ESP32-S3.)
- **EXT1:** External wake up 1 which is tied to multiple RTC GPIOs. This example uses GPIO2 and GPIO4 to trigger a wake up with any one of the two pins are HIGH. (This wake up source is available on ESP32, ESP32-S2, ESP32-S3 and ESP32-C6.)
- **GPIO:** Pads powered by VDD3P3_RTC can be used to trigger a wake up from deep sleep. You may choose the pin and trigger level in menuconfig. (This wake up source is unavailable on ESP32, ESP32-S2, and ESP32-S3.)
- **Touch:** Touch pad sensor interrupt. This example uses touch pads connected to GPIO32, GPIO33 in ESP32 or GPIO9 in ESP32-S2/S3 to trigger a wake up when any of the pads are pressed.
- **ULP:** Ultra Low Power Coprocessor which can continue to run during deep sleep. This example utilizes the ULP and constantly sample the chip's temperature and trigger a wake up if the chips temperature exceeds ~5 degrees Celsius.

View File

@ -62,6 +62,7 @@ menu "Example Configuration"
int "Enable wakeup from GPIO"
default 0 if !IDF_TARGET_ESP32H4_BETA_VERSION_2
default 7 if IDF_TARGET_ESP32H4_BETA_VERSION_2
range 0 7 if IDF_TARGET_ESP32C6
range 0 5 if !IDF_TARGET_ESP32H4_BETA_VERSION_2
range 7 12 if IDF_TARGET_ESP32H4_BETA_VERSION_2

View File

@ -34,7 +34,7 @@ static const uint32_t s_max_count = 20;
static uint32_t wakeup_cause;
// wake up stub function stored in RTC memory
void wake_stub_example(void)
void __attribute__((aligned(4))) wake_stub_example(void)
{
// Get wakeup cause.
wakeup_cause = esp_wake_stub_get_wakeup_cause();