forked from espressif/esp-idf
Merge branch 'feature/example_deep_sleep_wake_stub' into 'master'
make wake stub worked on ESP32/S2/C3/S3 Closes IDFGH-6564 See merge request espressif/esp-idf!17952
This commit is contained in:
@@ -79,6 +79,10 @@ if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "mspi_timing_tuning.c" "port/${target}/mspi_timing_config.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED)
|
||||
list(APPEND srcs "sleep_wake_stub.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_IDF_TARGET_ESP32H2)
|
||||
list(REMOVE_ITEM srcs
|
||||
"adc_share_hw_ctrl.c" # TODO: IDF-6215
|
||||
|
68
components/esp_hw_support/include/esp_wake_stub.h
Normal file
68
components/esp_hw_support/include/esp_wake_stub.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_sleep.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RTC_STR(str) (__extension__({static const RTC_RODATA_ATTR char _fmt[] = (str); (const char *)&_fmt;}))
|
||||
#define RTC_LOG_FORMAT(letter, format) LOG_COLOR_ ## letter format LOG_RESET_COLOR "\n"
|
||||
|
||||
#define ESP_RTC_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { esp_rom_printf(RTC_STR(format), ##__VA_ARGS__); \
|
||||
esp_wake_stub_uart_tx_wait_idle(0); }
|
||||
|
||||
#define ESP_RTC_LOGE( format, ... ) ESP_RTC_LOG(ESP_LOG_ERROR, RTC_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define ESP_RTC_LOGW( format, ... ) ESP_RTC_LOG(ESP_LOG_WARN, RTC_LOG_FORMAT(W, format), ##__VA_ARGS__)
|
||||
#define ESP_RTC_LOGI( format, ... ) ESP_RTC_LOG(ESP_LOG_INFO, RTC_LOG_FORMAT(I, format), ##__VA_ARGS__)
|
||||
#define ESP_RTC_LOGD( format, ... ) ESP_RTC_LOG(ESP_LOG_DEBUG, RTC_LOG_FORMAT(D, format), ##__VA_ARGS__)
|
||||
#define ESP_RTC_LOGV( format, ... ) ESP_RTC_LOG(ESP_LOG_VERBOSE, RTC_LOG_FORMAT(V, format), ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Enter deep-sleep mode from deep sleep wake stub code
|
||||
*
|
||||
* This should be called from the wake stub code.
|
||||
*
|
||||
* @param new_stub new wake stub function will be set
|
||||
*/
|
||||
void esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub);
|
||||
|
||||
/**
|
||||
* @brief Wait while uart transmission is in progress
|
||||
*
|
||||
* This function is waiting while uart transmission is not completed,
|
||||
* and this function should be called from the wake stub code.
|
||||
*
|
||||
* @param uart_no UART port to wait idle
|
||||
*/
|
||||
void esp_wake_stub_uart_tx_wait_idle(uint8_t uart_no);
|
||||
|
||||
/**
|
||||
* @brief Set wakeup time from deep sleep stub.
|
||||
*
|
||||
* This should be called from the wake stub code.
|
||||
*
|
||||
* @param time_in_us wakeup time in us
|
||||
*/
|
||||
void esp_wake_stub_set_wakeup_time(uint64_t time_in_us);
|
||||
|
||||
/**
|
||||
* @brief Get wakeup cause from deep sleep stub.
|
||||
*
|
||||
* This should be called from the wake stub code.
|
||||
*
|
||||
* @return wakeup casue value
|
||||
*/
|
||||
uint32_t esp_wake_stub_get_wakeup_cause(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -7,6 +7,7 @@
|
||||
#include <stdint.h>
|
||||
#include "esp_rom_sys.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/timer_periph.h"
|
||||
#include "esp_hw_log.h"
|
||||
@@ -152,20 +153,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
int attempts = 1000;
|
||||
while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
|
||||
esp_rom_delay_us(1); // might take 1 RTC slowclk period, don't flood RTC bus
|
||||
if (attempts) {
|
||||
if (--attempts == 0 && clk_ll_xtal32k_digi_is_enabled()) {
|
||||
ESP_HW_LOGE(TAG, "rtc_time_get() 32kHz xtal has been stopped");
|
||||
}
|
||||
}
|
||||
}
|
||||
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
return rtc_cntl_ll_get_rtc_time();
|
||||
}
|
||||
|
||||
void rtc_clk_wait_for_slow_cycle(void)
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
@@ -166,10 +167,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
return rtc_cntl_ll_get_rtc_time();
|
||||
}
|
||||
|
||||
uint64_t rtc_light_slp_time_get(void)
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
@@ -169,10 +170,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
return rtc_cntl_ll_get_rtc_time();
|
||||
}
|
||||
|
||||
uint64_t rtc_light_slp_time_get(void)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/lp_timer_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "assert.h"
|
||||
@@ -206,10 +207,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(LP_TIMER_UPDATE_REG, LP_TIMER_MAIN_TIMER_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(LP_TIMER_MAIN_BUF0_LOW_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(LP_TIMER_MAIN_BUF0_HIGH_REG)) << 32;
|
||||
return t;
|
||||
return rtc_cntl_ll_get_rtc_time();
|
||||
}
|
||||
|
||||
uint64_t rtc_light_slp_time_get(void)
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
@@ -163,10 +164,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
return rtc_cntl_ll_get_rtc_time();
|
||||
}
|
||||
|
||||
uint64_t rtc_light_slp_time_get(void)
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
|
||||
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||
@@ -234,10 +235,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
return rtc_cntl_ll_get_rtc_time();
|
||||
}
|
||||
|
||||
uint64_t rtc_light_slp_time_get(void)
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
|
||||
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||
@@ -168,10 +169,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
return rtc_cntl_ll_get_rtc_time();
|
||||
}
|
||||
|
||||
uint64_t rtc_light_slp_time_get(void)
|
||||
|
@@ -1272,11 +1272,7 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
|
||||
return ESP_SLEEP_WAKEUP_UNDEFINED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
#else
|
||||
uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
#endif
|
||||
uint32_t wakeup_cause = rtc_cntl_ll_get_wakeup_cause();
|
||||
|
||||
if (wakeup_cause & RTC_TIMER_TRIG_EN) {
|
||||
return ESP_SLEEP_WAKEUP_TIMER;
|
||||
|
81
components/esp_hw_support/sleep_wake_stub.c
Normal file
81
components/esp_hw_support/sleep_wake_stub.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_sleep.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "hal/uart_ll.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
#include "esp32c6/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
#include "esp32h2/rom/rtc.h"
|
||||
#endif
|
||||
|
||||
void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub)
|
||||
{
|
||||
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
||||
extern char _rtc_text_start[];
|
||||
#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM
|
||||
extern char _rtc_noinit_end[];
|
||||
size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start;
|
||||
#else
|
||||
extern char _rtc_force_fast_end[];
|
||||
size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start;
|
||||
#endif // CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM
|
||||
esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)new_stub, rtc_fast_length);
|
||||
#else
|
||||
// Set the pointer of the wake stub function.
|
||||
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub);
|
||||
set_rtc_memory_crc();
|
||||
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_MEM
|
||||
|
||||
// Go to sleep.
|
||||
rtc_cntl_ll_sleep_enable();
|
||||
// A few CPU cycles may be necessary for the sleep to start...
|
||||
while (true) {};
|
||||
// never reaches here.
|
||||
}
|
||||
|
||||
void RTC_IRAM_ATTR esp_wake_stub_uart_tx_wait_idle(uint8_t uart_no)
|
||||
{
|
||||
while (!uart_ll_is_tx_idle(UART_LL_GET_HW(uart_no))) {};
|
||||
}
|
||||
|
||||
void RTC_IRAM_ATTR esp_wake_stub_set_wakeup_time(uint64_t time_in_us)
|
||||
{
|
||||
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();
|
||||
rtc_cntl_ll_set_wakeup_timer(rtc_curr_count + rtc_count_delta);
|
||||
}
|
||||
|
||||
uint32_t RTC_IRAM_ATTR esp_wake_stub_get_wakeup_cause(void)
|
||||
{
|
||||
return rtc_cntl_ll_get_wakeup_cause();
|
||||
}
|
@@ -63,7 +63,7 @@ SECTIONS
|
||||
|
||||
mapping[rtc_data]
|
||||
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
|
||||
} > rtc_data_location
|
||||
|
@@ -59,7 +59,7 @@ SECTIONS
|
||||
|
||||
mapping[rtc_data]
|
||||
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > rtc_data_location
|
||||
|
||||
@@ -67,7 +67,7 @@ SECTIONS
|
||||
.rtc.bss (NOLOAD) :
|
||||
{
|
||||
_rtc_bss_start = ABSOLUTE(.);
|
||||
*rtc_wake_stub*.*(.bss .bss.*)
|
||||
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
|
||||
*rtc_wake_stub*.*(COMMON)
|
||||
|
||||
mapping[rtc_bss]
|
||||
|
@@ -59,7 +59,7 @@ SECTIONS
|
||||
|
||||
mapping[rtc_data]
|
||||
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
@@ -67,7 +67,7 @@ SECTIONS
|
||||
.rtc.bss (NOLOAD) :
|
||||
{
|
||||
_rtc_bss_start = ABSOLUTE(.);
|
||||
*rtc_wake_stub*.*(.bss .bss.*)
|
||||
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
|
||||
*rtc_wake_stub*.*(COMMON)
|
||||
|
||||
mapping[rtc_bss]
|
||||
|
@@ -59,7 +59,7 @@ SECTIONS
|
||||
|
||||
mapping[rtc_data]
|
||||
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
@@ -67,7 +67,7 @@ SECTIONS
|
||||
.rtc.bss (NOLOAD) :
|
||||
{
|
||||
_rtc_bss_start = ABSOLUTE(.);
|
||||
*rtc_wake_stub*.*(.bss .bss.*)
|
||||
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
|
||||
*rtc_wake_stub*.*(COMMON)
|
||||
|
||||
mapping[rtc_bss]
|
||||
|
@@ -61,7 +61,7 @@ SECTIONS
|
||||
|
||||
mapping[rtc_data]
|
||||
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > rtc_data_location
|
||||
|
||||
@@ -69,7 +69,7 @@ SECTIONS
|
||||
.rtc.bss (NOLOAD) :
|
||||
{
|
||||
_rtc_bss_start = ABSOLUTE(.);
|
||||
*rtc_wake_stub*.*(.bss .bss.*)
|
||||
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
|
||||
*rtc_wake_stub*.*(COMMON)
|
||||
|
||||
mapping[rtc_bss]
|
||||
|
@@ -71,7 +71,7 @@ SECTIONS
|
||||
|
||||
mapping[rtc_data]
|
||||
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > rtc_data_location
|
||||
|
||||
|
@@ -65,7 +65,7 @@ SECTIONS
|
||||
|
||||
mapping[rtc_data]
|
||||
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > rtc_data_location
|
||||
|
||||
|
@@ -445,8 +445,7 @@ __attribute__((unused)) static float get_time_ms(void)
|
||||
|
||||
__attribute__((unused)) static uint32_t get_cause(void)
|
||||
{
|
||||
uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, \
|
||||
RTC_CNTL_WAKEUP_CAUSE);
|
||||
uint32_t wakeup_cause = rtc_cntl_ll_get_wakeup_cause();
|
||||
return wakeup_cause;
|
||||
}
|
||||
|
||||
|
@@ -8,71 +8,107 @@
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "clk_tree_ll.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ext1_clear_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_status(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask);
|
||||
SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1,
|
||||
mode, RTC_CNTL_EXT_WAKEUP1_LV_S);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL_M);
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ulp_wakeup_enable(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ulp_wakeup_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_WAKEUP_FORCE_EN);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ulp_int_clear(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ulp_int_clear(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_SAR_INT_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, wait_cycle);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_system(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
{
|
||||
uint32_t rtc_cntl_rst = (cpu_no == 0) ? RTC_CNTL_SW_PROCPU_RST : RTC_CNTL_SW_APPCPU_RST;
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, rtc_cntl_rst);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
int attempts = 1000;
|
||||
while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
|
||||
esp_rom_delay_us(1);
|
||||
if (attempts) {
|
||||
if (--attempts == 0 && clk_ll_xtal32k_digi_is_enabled()) {
|
||||
esp_rom_printf("32KHz xtal has been stopped\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
uint32_t slow_clk_value = REG_READ(RTC_CNTL_STORE1_REG);
|
||||
return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -10,12 +10,13 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
|
||||
@@ -24,18 +25,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_gpio_get_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void)
|
||||
{
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
|
||||
REG_CLR_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention(uint32_t addr)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention(uint32_t addr)
|
||||
{
|
||||
/* write memory address to register */
|
||||
REG_SET_FIELD(SYSCON_RETENTION_CTRL_REG, SYSCON_RETENTION_LINK_ADDR, (uint32_t)addr);
|
||||
@@ -45,21 +46,45 @@ static inline void rtc_cntl_ll_enable_cpu_retention(uint32_t addr)
|
||||
REG_SET_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_system(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
uint32_t slow_clk_value = REG_READ(RTC_CNTL_STORE1_REG);
|
||||
return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -10,12 +10,13 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
|
||||
@@ -24,48 +25,72 @@ 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_gpio_get_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void)
|
||||
{
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
|
||||
REG_CLR_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t addr)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t addr)
|
||||
{
|
||||
REG_SET_FIELD(SYSCON_RETENTION_CTRL_REG, SYSCON_RETENTION_LINK_ADDR, (uint32_t)addr);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention_clock(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention_clock(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
{
|
||||
/* Enable retention when cpu sleep enable */
|
||||
REG_SET_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_system(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
uint32_t slow_clk_value = REG_READ(RTC_CNTL_STORE1_REG);
|
||||
return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -9,57 +9,81 @@
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/lp_aon_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
{
|
||||
// TODO: IDF-5645
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t addr)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t addr)
|
||||
{
|
||||
// TODO: IDF-5718 has removed the retention feature
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention_clock(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention_clock(void)
|
||||
{
|
||||
// TODO: IDF-5718 has removed the retention feature
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
{
|
||||
// TODO: IDF-5718 has removed the retention feature
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
{
|
||||
// TODO: IDF-5718 has removed the retention feature
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_system(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
|
||||
{
|
||||
REG_SET_BIT(LP_AON_SYS_CFG_REG, LP_AON_HPSYS_SW_RESET);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
{
|
||||
REG_SET_BIT(LP_AON_CPUCORE0_CFG_REG, LP_AON_CPU_CORE0_SW_RESET);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
// TODO: IDF-6064
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
// TODO: IDF-6064
|
||||
return 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
// TODO: IDF-6064
|
||||
return 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
// TODO: IDF-6064
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -8,63 +8,87 @@
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-6401
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_gpio_get_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_gpio_get_wakeup_pins(void)
|
||||
{
|
||||
return 0;
|
||||
// ESP32H2-TODO: IDF-6401
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-6401
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-6401
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_gpio_set_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_set_wakeup_pins(void)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-5718
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_gpio_clear_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_clear_wakeup_pins(void)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-5718
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t addr)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t addr)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-5718 has removed the retention feature
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention_clock(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention_clock(void)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-5718 has removed the retention feature
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-5718 has removed the retention feature
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-5718 has removed the retention feature
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
// TODO: IDF-6572
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
// TODO: IDF-6572
|
||||
return 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
// TODO: IDF-6572
|
||||
return 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
// TODO: IDF-6572
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -10,12 +10,13 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
|
||||
@@ -24,37 +25,61 @@ 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_gpio_get_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void)
|
||||
{
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
|
||||
REG_CLR_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention(uint32_t addr)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention(uint32_t addr)
|
||||
{
|
||||
// ESP32H4-TODO: IDF-3383
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
{
|
||||
// ESP32H4-TODO: IDF-3383
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_system(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
uint32_t slow_clk_value = REG_READ(RTC_CNTL_STORE1_REG);
|
||||
return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -9,12 +9,13 @@
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
|
||||
@@ -23,55 +24,79 @@ 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 void rtc_cntl_ll_ext1_clear_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_status(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask);
|
||||
SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1,
|
||||
mode, RTC_CNTL_EXT_WAKEUP1_LV_S);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL_M);
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ulp_int_clear(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ulp_int_clear(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_ULP_CP_INT_CLR);
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR);
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_TRAP_INT_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, wait_cycle);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_system(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
uint32_t slow_clk_value = REG_READ(RTC_CNTL_STORE1_REG);
|
||||
return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/apb_ctrl_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -18,7 +19,7 @@ extern "C" {
|
||||
#define RTC_CNTL_LL_RETENTION_TARGET_CPU (BIT(0))
|
||||
#define RTC_CNTL_LL_RETENTION_TARGET_TAGMEM (BIT(1))
|
||||
|
||||
static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
|
||||
@@ -27,46 +28,46 @@ 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 void rtc_cntl_ll_ext1_clear_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_status(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask);
|
||||
SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1,
|
||||
mode, RTC_CNTL_EXT_WAKEUP1_LV_S);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL_M);
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void)
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_set_tagmem_retention_link_addr(uint32_t link_addr)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_tagmem_retention_link_addr(uint32_t link_addr)
|
||||
{
|
||||
REG_SET_FIELD(APB_CTRL_RETENTION_CTRL1_REG, APB_CTRL_RETENTION_TAG_LINK_ADDR, link_addr);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_tagmem_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_tagmem_retention(void)
|
||||
{
|
||||
/* Enable i/d-cache tagmem retenttion. cpu: 1, tagmem: 2, cpu + tagmem: 3 */
|
||||
uint32_t target = REG_GET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_TARGET);
|
||||
REG_SET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_TARGET, (target | RTC_CNTL_LL_RETENTION_TARGET_TAGMEM));
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_icache_tagmem_retention(uint32_t start_point, uint32_t vld_size, uint32_t size)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_icache_tagmem_retention(uint32_t start_point, uint32_t vld_size, uint32_t size)
|
||||
{
|
||||
REG_SET_FIELD(APB_CTRL_RETENTION_CTRL2_REG, APB_CTRL_RET_ICACHE_START_POINT, start_point);
|
||||
REG_SET_FIELD(APB_CTRL_RETENTION_CTRL2_REG, APB_CTRL_RET_ICACHE_VLD_SIZE, vld_size);
|
||||
@@ -74,7 +75,7 @@ static inline void rtc_cntl_ll_enable_icache_tagmem_retention(uint32_t start_poi
|
||||
REG_SET_BIT(APB_CTRL_RETENTION_CTRL2_REG, APB_CTRL_RET_ICACHE_ENABLE);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_dcache_tagmem_retention(uint32_t start_point, uint32_t vld_size, uint32_t size)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_dcache_tagmem_retention(uint32_t start_point, uint32_t vld_size, uint32_t size)
|
||||
{
|
||||
REG_SET_FIELD(APB_CTRL_RETENTION_CTRL3_REG, APB_CTRL_RET_DCACHE_START_POINT, start_point);
|
||||
REG_SET_FIELD(APB_CTRL_RETENTION_CTRL3_REG, APB_CTRL_RET_DCACHE_VLD_SIZE, vld_size);
|
||||
@@ -82,34 +83,34 @@ static inline void rtc_cntl_ll_enable_dcache_tagmem_retention(uint32_t start_poi
|
||||
REG_SET_BIT(APB_CTRL_RETENTION_CTRL3_REG, APB_CTRL_RET_DCACHE_ENABLE);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_tagmem_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_tagmem_retention(void)
|
||||
{
|
||||
/* Enable i/d-cache tagmem retenttion. cpu: 1, tagmem: 2, cpu + tagmem: 3 */
|
||||
uint32_t target = REG_GET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_TARGET);
|
||||
REG_SET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_TARGET, (target & ~RTC_CNTL_LL_RETENTION_TARGET_TAGMEM));
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_icache_tagmem_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_icache_tagmem_retention(void)
|
||||
{
|
||||
REG_CLR_BIT(APB_CTRL_RETENTION_CTRL2_REG, APB_CTRL_RET_ICACHE_ENABLE);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_dcache_tagmem_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_dcache_tagmem_retention(void)
|
||||
{
|
||||
REG_CLR_BIT(APB_CTRL_RETENTION_CTRL3_REG, APB_CTRL_RET_DCACHE_ENABLE);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t link_addr)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t link_addr)
|
||||
{
|
||||
REG_SET_FIELD(APB_CTRL_RETENTION_CTRL_REG, APB_CTRL_RETENTION_CPU_LINK_ADDR, link_addr);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention_clock(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention_clock(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN); /* Enable internal 20 MHz clock */
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
{
|
||||
uint32_t target = REG_GET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_TARGET);
|
||||
|
||||
@@ -118,41 +119,65 @@ static inline void rtc_cntl_ll_enable_cpu_retention(void)
|
||||
REG_SET_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_config_cpu_retention_timing(int wait, int clkoff_wait, int done_wait)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_config_cpu_retention_timing(int wait, int clkoff_wait, int done_wait)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_WAIT, wait);
|
||||
REG_SET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_CLKOFF_WAIT, clkoff_wait);
|
||||
REG_SET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_DONE_WAIT, done_wait);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_ulp_int_clear(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_ulp_int_clear(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_ULP_CP_INT_CLR);
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR);
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_TRAP_INT_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, wait_cycle);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_system(void)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
{
|
||||
uint32_t rtc_cntl_rst = (cpu_no == 0) ? RTC_CNTL_SW_PROCPU_RST : RTC_CNTL_SW_APPCPU_RST;
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, rtc_cntl_rst);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
uint32_t slow_clk_value = REG_READ(RTC_CNTL_STORE1_REG);
|
||||
return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -115,3 +115,12 @@ CRC Check For Wake Stubs
|
||||
.. note::
|
||||
|
||||
When the `CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP` option is enabled, all the RTC fast memory except the wake stubs area is added to the heap.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. only:: SOC_RTC_FAST_MEM_SUPPORTED
|
||||
|
||||
ESP-IDF provides an example to show how to implement the Deep-sleep wake stub.
|
||||
|
||||
- :example:`system/deep_sleep_wake_stub`
|
||||
|
@@ -42,6 +42,12 @@ examples/system/deep_sleep:
|
||||
temporary: true
|
||||
reason: target(s) not supported yet
|
||||
|
||||
examples/system/deep_sleep_wake_stub:
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2"]
|
||||
temporary: true
|
||||
reason: target(s) is not supported yet
|
||||
|
||||
examples/system/efuse:
|
||||
disable_test:
|
||||
- if: IDF_TARGET == "esp32s3"
|
||||
|
@@ -68,7 +68,7 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
|
||||
|
||||
## Example Output
|
||||
|
||||
On initial startup, this example will detect that this is the first boot and output the following low:
|
||||
On initial startup, this example will detect that this is the first boot and output the following log:
|
||||
|
||||
```
|
||||
...
|
||||
|
6
examples/system/deep_sleep_wake_stub/CMakeLists.txt
Normal file
6
examples/system/deep_sleep_wake_stub/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(deep_sleep_wake_stub)
|
75
examples/system/deep_sleep_wake_stub/README.md
Normal file
75
examples/system/deep_sleep_wake_stub/README.md
Normal file
@@ -0,0 +1,75 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- |
|
||||
|
||||
# Deep Sleep Wake Stub Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
The [Deep-sleep wake stub](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/deep-sleep-stub.html) is used to RTC fast boot mode that avoid the SPI flash booting, thus speeding up the wakeup process. This example demonstrates how to implement the wake stub.
|
||||
|
||||
In this example, the `CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` Kconfig option is used, which allows you to reduce the boot time of the bootloader during waking up from deep sleep. The bootloader stores in rtc memory the address of a running partition and uses it when it wakes up. This example allows you to skip all image checks and speed up the boot.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
This example should be able to run on any commonly available ESP32/ESP32-S2/ESP32-S3/ESP32-C3 development board without any extra hardware if only **Timer** wake up sources are used.
|
||||
|
||||
### Configure the project
|
||||
|
||||
|
||||
```
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
* **Wake up time** can be configured via `Example configuration > Wake up interval in seconds`
|
||||
Wake up sources that are unused or unconnected should be disabled in configuration to prevent inadvertent triggering of wake up as a result of floating pins.
|
||||
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(Replace PORT with the name of the serial port to use.)
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
On initial startup, this example will detect that this is the first boot and output the following log:
|
||||
|
||||
```
|
||||
...
|
||||
I (309) cpu_start: Starting scheduler on PRO CPU.
|
||||
I (0) cpu_start: Starting scheduler on APP CPU.
|
||||
Not a deep sleep reset
|
||||
Enabling timer wakeup, 10s
|
||||
Entering deep sleep
|
||||
```
|
||||
|
||||
The ESP chips will then enter deep sleep. When a timer wake up occurs, if deep sleep wake stub enabled, the ESP chips will boot from RTC memory and execute stub code. The output log such as the following:
|
||||
|
||||
```
|
||||
...
|
||||
ESP-ROM:esp32s3-20210327
|
||||
Build:Mar 27 2021
|
||||
rst:0x5 (DSLEEP),boot:0x8 (SPI_FAST_FLASH_BOOT)
|
||||
wake stub: wakeup count is 1, wakeup cause is 8
|
||||
wake stub: going to deep sleep
|
||||
ESP-ROM:esp32s3-20210327
|
||||
Build:Mar 27 2021
|
||||
rst:0x5 (DSLEEP),boot:0x8 (SPI_FAST_FLASH_BOOT)
|
||||
wake stub: wakeup count is 2, wakeup cause is 8
|
||||
wake stub: going to deep sleep
|
||||
ESP-ROM:esp32s3-20210327
|
||||
Build:Mar 27 2021
|
||||
rst:0x5 (DSLEEP),boot:0x8 (SPI_FAST_FLASH_BOOT)
|
||||
wake stub: wakeup count is 3, wakeup cause is 8
|
||||
wake stub: going to deep sleep
|
||||
```
|
3
examples/system/deep_sleep_wake_stub/main/CMakeLists.txt
Normal file
3
examples/system/deep_sleep_wake_stub/main/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "wake_stub_example_main.c"
|
||||
"rtc_wake_stub_example.c"
|
||||
INCLUDE_DIRS ".")
|
10
examples/system/deep_sleep_wake_stub/main/Kconfig.projbuild
Normal file
10
examples/system/deep_sleep_wake_stub/main/Kconfig.projbuild
Normal file
@@ -0,0 +1,10 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config WAKE_UP_TIME
|
||||
int "Wake up interval in seconds"
|
||||
default 10
|
||||
range 1 60
|
||||
help
|
||||
Configurable wake up interval in seconds.
|
||||
|
||||
endmenu
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_wake_stub.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/*
|
||||
* Deep sleep wake stub function is a piece of code that will be loaded into 'RTC Fast Memory'.
|
||||
* The first way is to use the RTC_IRAM_ATTR attribute to place a function into RTC memory,
|
||||
* The second way is to place the function into any source file whose name starts with rtc_wake_stub.
|
||||
* Files names rtc_wake_stub* have their contents automatically put into RTC memory by the linker.
|
||||
*
|
||||
* First, call esp_set_deep_sleep_wake_stub to set the wake stub function as the RTC stub entry,
|
||||
* The wake stub function runs immediately as soon as the chip wakes up - before any normal
|
||||
* initialisation, bootloader, or ESP-IDF code has run. After the wake stub runs, the SoC
|
||||
* can go back to sleep or continue to start ESP-IDF normally.
|
||||
*
|
||||
* Wake stub code must be carefully written, there are some rules for wake stub:
|
||||
* 1) The wake stub code can only access data loaded in RTC memory.
|
||||
* 2) The wake stub code can only call functions implemented in ROM or loaded into RTC Fast Memory.
|
||||
* 3) RTC memory must include any read-only data (.rodata) used by the wake stub.
|
||||
*/
|
||||
|
||||
// counter value, stored in RTC memory
|
||||
static uint32_t s_count = 0;
|
||||
static const uint32_t s_max_count = 20;
|
||||
|
||||
// wakeup_cause stored in RTC memory
|
||||
static uint32_t wakeup_cause;
|
||||
|
||||
// wake up stub function stored in RTC memory
|
||||
void wake_stub_example(void)
|
||||
{
|
||||
// Get wakeup cause.
|
||||
wakeup_cause = esp_wake_stub_get_wakeup_cause();
|
||||
// Increment the counter.
|
||||
s_count++;
|
||||
// Print the counter value and wakeup cause.
|
||||
ESP_RTC_LOGI("wake stub: wakeup count is %d, wakeup cause is %d", s_count, wakeup_cause);
|
||||
|
||||
if (s_count >= s_max_count) {
|
||||
// Reset s_count
|
||||
s_count = 0;
|
||||
|
||||
// Set the default wake stub.
|
||||
// There is a default version of this function provided in esp-idf.
|
||||
esp_default_wake_deep_sleep();
|
||||
|
||||
// Return from the wake stub function to continue
|
||||
// booting the firmware.
|
||||
return;
|
||||
}
|
||||
// s_count is < s_max_count, go back to deep sleep.
|
||||
|
||||
// Set wakeup time in stub, if need to check GPIOs or read some sensor periodically in the stub.
|
||||
esp_wake_stub_set_wakeup_time(CONFIG_WAKE_UP_TIME*1000000);
|
||||
|
||||
// Print status.
|
||||
ESP_RTC_LOGI("wake stub: going to deep sleep");
|
||||
|
||||
// Set stub entry, then going to deep sleep again.
|
||||
esp_wake_stub_sleep(&wake_stub_example);
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void wake_stub_example(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_wake_stub.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "rtc_wake_stub_example.h"
|
||||
|
||||
// sleep_enter_time stored in RTC memory
|
||||
static RTC_DATA_ATTR struct timeval sleep_enter_time;
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000;
|
||||
|
||||
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TIMER) {
|
||||
printf("Wake up from timer. Time spent in deep sleep: %dms\n", sleep_time_ms);
|
||||
}
|
||||
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
|
||||
const int wakeup_time_sec = CONFIG_WAKE_UP_TIME;
|
||||
printf("Enabling timer wakeup, %ds\n", wakeup_time_sec);
|
||||
esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
// Isolate GPIO12 pin from external circuits. This is needed for modules
|
||||
// which have an external pull-up resistor on GPIO12 (such as ESP32-WROVER)
|
||||
// to minimize current consumption.
|
||||
rtc_gpio_isolate(GPIO_NUM_12);
|
||||
#endif
|
||||
|
||||
// Set the wake stub function
|
||||
esp_set_deep_sleep_wake_stub(&wake_stub_example);
|
||||
|
||||
printf("Entering deep sleep\n");
|
||||
gettimeofday(&sleep_enter_time, NULL);
|
||||
|
||||
esp_deep_sleep_start();
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', ['default',], indirect=True)
|
||||
def test_deep_sleep_wake_stub(config: str, dut: Dut) -> None:
|
||||
if config == 'default':
|
||||
dut.expect_exact('Enabling timer wakeup, 10s', timeout=10)
|
||||
dut.expect_exact('Entering deep sleep', timeout=10)
|
||||
|
||||
start_sleep = time.time()
|
||||
logging.info('Waiting for wakeup...')
|
||||
dut.expect_exact('wake stub: going to deep sleep')
|
||||
|
||||
sleep_time = time.time() - start_sleep
|
||||
logging.info('Host measured sleep time at {:.2f}s'.format(sleep_time))
|
||||
assert 8 < sleep_time < 12 # note: high tolerance as measuring time on the host may have some timing skew
|
1
examples/system/deep_sleep_wake_stub/sdkconfig.defaults
Normal file
1
examples/system/deep_sleep_wake_stub/sdkconfig.defaults
Normal file
@@ -0,0 +1 @@
|
||||
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
|
Reference in New Issue
Block a user