mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp32c6: bringup deepsleep examples
This commit is contained in:
parent
d3ec7880fe
commit
9eae151f7c
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -17,6 +17,8 @@ SECTIONS
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_start = ABSOLUTE(.);
|
||||
_rtc_text_start = ABSOLUTE(.);
|
||||
*(.rtc.entry.text)
|
||||
|
||||
mapping[rtc_text]
|
||||
|
||||
|
@ -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
|
||||
|
24
components/hal/esp32c6/include/hal/lp_aon_hal.h
Normal file
24
components/hal/esp32c6/include/hal/lp_aon_hal.h
Normal 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)
|
97
components/hal/esp32c6/include/hal/lp_aon_ll.h
Normal file
97
components/hal/esp32c6/include/hal/lp_aon_ll.h
Normal 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
|
@ -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
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user