Merge branch 'feat/support_tg_retention_v5.3' into 'release/v5.3'

change(esp_hw_support): do TG WDT/Timer retention by needs (v5.3)

See merge request espressif/esp-idf!31486
This commit is contained in:
Jiang Jiang Jian 2024-06-13 19:55:02 +08:00
commit e6230e49cb
48 changed files with 976 additions and 252 deletions

View File

@ -280,7 +280,7 @@ static void i2c_hw_enable(i2c_port_t i2c_num)
static esp_err_t i2c_sleep_retention_init(void *arg)
{
i2c_port_t i2c_num = *(i2c_port_t *)arg;
esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[i2c_num].link_list, i2c_regs_retention[i2c_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(i2c_num));
esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[i2c_num].link_list, i2c_regs_retention[i2c_num].link_num, REGDMA_LINK_PRI_I2C, I2C_SLEEP_RETENTION_MODULE(i2c_num));
ESP_RETURN_ON_ERROR(ret, I2C_TAG, "failed to allocate mem for sleep retention");
return ret;
}

View File

@ -28,6 +28,9 @@ typedef struct {
if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */
struct {
uint32_t intr_shared: 1; /*!< Set true, the timer interrupt number can be shared with other peripherals */
uint32_t backup_before_sleep: 1; /*!< If set, the driver will backup/restore the GPTimer registers before/after entering/exist sleep mode.
By this approach, the system can power off GPTimer's power domain.
This can save power, but at the expense of more RAM being consumed */
} flags; /*!< GPTimer config flags*/
} gptimer_config_t;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -30,6 +30,10 @@
#include "esp_clk_tree.h"
#include "gptimer_priv.h"
#if GPTIMER_USE_RETENTION_LINK
#include "esp_private/sleep_retention.h"
#endif
static const char *TAG = "gptimer";
#if SOC_PERIPH_CLK_CTRL_SHARED
@ -52,6 +56,37 @@ static void gptimer_release_group_handle(gptimer_group_t *group);
static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz);
static void gptimer_default_isr(void *args);
#if GPTIMER_USE_RETENTION_LINK
static esp_err_t sleep_tg_timer_retention_link_cb(void *arg)
{
uint32_t group_id = *(uint32_t *)arg;
esp_err_t err = sleep_retention_entries_create(tg_timer_regs_retention[group_id].link_list,
tg_timer_regs_retention[group_id].link_num,
REGDMA_LINK_PRI_6,
(group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER);
if (err == ESP_OK) {
ESP_LOGD(TAG, "Timer group %ld retention initialization", group_id);
}
ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for timer group %ld", group_id);
return err;
}
static void gptimer_create_retention_module(gptimer_group_t *group)
{
_lock_acquire(&s_platform.mutex);
int group_id = group->group_id;
if ((group->sleep_retention_initialized == true) && (group->retention_link_created == false)) {
esp_err_t err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER);
if (err != ESP_OK) {
ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for timer group %d retention, power domain can't turn off", group_id);
} else {
group->retention_link_created = true;
}
}
_lock_release(&s_platform.mutex);
}
#endif
static esp_err_t gptimer_register_to_group(gptimer_t *timer)
{
gptimer_group_t *group = NULL;
@ -129,6 +164,12 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
int group_id = group->group_id;
int timer_id = timer->timer_id;
#if GPTIMER_USE_RETENTION_LINK
if (config->flags.backup_before_sleep != 0) {
gptimer_create_retention_module(group);
}
#endif // GPTIMER_USE_RETENTION_LINK
// initialize HAL layer
timer_hal_init(&timer->hal, group_id, timer_id);
// select clock source, set clock resolution
@ -404,7 +445,6 @@ static gptimer_group_t *gptimer_acquire_group_handle(int group_id)
// someone acquired the group handle means we have a new object that refer to this group
s_platform.group_ref_counts[group_id]++;
}
_lock_release(&s_platform.mutex);
if (new_group) {
// !!! HARDWARE SHARED RESOURCE !!!
@ -417,7 +457,28 @@ static gptimer_group_t *gptimer_acquire_group_handle(int group_id)
}
}
ESP_LOGD(TAG, "new group (%d) @%p", group_id, group);
#if GPTIMER_USE_RETENTION_LINK
if (group->sleep_retention_initialized != true) {
sleep_retention_module_init_param_t init_param = {
.cbs = {
.create = {
.handle = sleep_tg_timer_retention_link_cb,
.arg = &group_id
},
},
.depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM)
};
esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER, &init_param);
if (err == ESP_OK) {
group->sleep_retention_initialized = true;
} else {
ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for timer group %d retention", group_id);
}
}
#endif // GPTIMER_USE_RETENTION_LINK
}
_lock_release(&s_platform.mutex);
return group;
}
@ -434,7 +495,6 @@ static void gptimer_release_group_handle(gptimer_group_t *group)
do_deinitialize = true;
s_platform.groups[group_id] = NULL;
}
_lock_release(&s_platform.mutex);
if (do_deinitialize) {
// disable bus clock for the timer group
@ -443,9 +503,18 @@ static void gptimer_release_group_handle(gptimer_group_t *group)
timer_ll_enable_bus_clock(group_id, false);
}
}
#if GPTIMER_USE_RETENTION_LINK
if (group->retention_link_created) {
sleep_retention_module_free((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER);
}
if (group->sleep_retention_initialized) {
sleep_retention_module_deinit((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER);
}
#endif
free(group);
ESP_LOGD(TAG, "del group (%d)", group_id);
}
_lock_release(&s_platform.mutex);
}
static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -39,12 +39,18 @@ extern "C" {
#define GPTIMER_PM_LOCK_NAME_LEN_MAX 16
#define GPTIMER_USE_RETENTION_LINK (SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
typedef struct gptimer_t gptimer_t;
typedef struct gptimer_group_t {
int group_id;
portMUX_TYPE spinlock; // to protect per-group register level concurrent access
gptimer_t *timers[SOC_TIMER_GROUP_TIMERS_PER_GROUP];
#if GPTIMER_USE_RETENTION_LINK
bool sleep_retention_initialized; // mark if the retention link is initialized
bool retention_link_created; // mark if the retention link is created
#endif
} gptimer_group_t;
typedef enum {

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,6 +13,15 @@
#include "soc/soc_caps.h"
#include "esp_attr.h"
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#include "esp_random.h"
#include "esp_rom_uart.h"
#include "esp_sleep.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/sleep_cpu.h"
#include "esp_private/esp_pmu.h"
#endif
#if CONFIG_GPTIMER_ISR_IRAM_SAFE
#define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR
#else
@ -596,3 +605,82 @@ TEST_CASE("gptimer_trig_alarm_with_old_count", "[gptimer]")
TEST_ESP_OK(gptimer_disable(timer));
TEST_ESP_OK(gptimer_del_timer(timer));
}
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
static gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
static uint32_t timer_resolution_hz[SOC_TIMER_GROUP_TOTAL_TIMERS];
static void test_gptimer_retention(gptimer_config_t *timer_config)
{
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
TEST_ESP_OK(gptimer_new_timer(timer_config, &timers[i]));
TEST_ESP_OK(gptimer_get_resolution(timers[i], &timer_resolution_hz[i]));
unsigned long long count_start_value = 0, count_end_value = 0;
// Let gptimer run for a while
TEST_ESP_OK(gptimer_enable(timers[i]));
TEST_ESP_OK(gptimer_start(timers[i]));
vTaskDelay((esp_random() % 500) / portTICK_PERIOD_MS);
TEST_ESP_OK(gptimer_stop(timers[i]));
TEST_ESP_OK(gptimer_disable(timers[i]));
TEST_ESP_OK(gptimer_get_raw_count(timers[i], &count_start_value));
esp_sleep_context_t sleep_ctx;
esp_sleep_set_sleep_context(&sleep_ctx);
TEST_ESP_OK(sleep_cpu_configure(true));
esp_rom_output_tx_wait_idle(0);
esp_sleep_enable_timer_wakeup(50 * 1000);
esp_light_sleep_start();
if (timer_config->flags.backup_before_sleep) {
TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP);
} else {
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP);
}
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
TEST_ESP_OK(gptimer_enable(timers[i]));
TEST_ESP_OK(gptimer_start(timers[i]));
uint32_t random_time_ms = 500 + esp_random() % 2000;
vTaskDelay(random_time_ms / portTICK_PERIOD_MS);
TEST_ESP_OK(gptimer_get_raw_count(timers[i], &count_end_value));
// Error tolerance is 2%
TEST_ASSERT_UINT_WITHIN(random_time_ms / 50, random_time_ms, 1000 * (count_end_value - count_start_value) / (unsigned long long)timer_resolution_hz[i]);
TEST_ESP_OK(gptimer_stop(timers[i]));
TEST_ESP_OK(gptimer_disable(timers[i]));
TEST_ESP_OK(gptimer_del_timer(timers[i]));
TEST_ESP_OK(sleep_cpu_configure(false));
}
}
TEST_CASE("gptimer context kept after peripheral powerdown lightsleep with backup_before_sleep enable", "[gptimer]")
{
printf("install gptimer driver\r\n");
gptimer_config_t timer_config = {
.resolution_hz = 10 * 1000, // 10KHz, 1 tick = 0.1ms
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.flags.backup_before_sleep = true
};
test_gptimer_retention(&timer_config);
}
TEST_CASE("gptimer context kept after peripheral powerdown lightsleep with backup_before_sleep disable", "[gptimer]")
{
printf("install gptimer driver\r\n");
gptimer_config_t timer_config = {
.resolution_hz = 10 * 1000, // 10KHz, 1 tick = 0.1ms
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.flags.backup_before_sleep = false
};
test_gptimer_retention(&timer_config);
}
#endif

View File

@ -4,3 +4,6 @@ CONFIG_PM_DFS_INIT_AUTO=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
# For TASK WDT timer PD_TOP sleep retention test
CONFIG_ESP_SLEEP_DEBUG=y
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y

View File

@ -52,7 +52,7 @@ static esp_err_t s_i2c_sleep_retention_init(void *arg)
{
i2c_bus_t *bus = (i2c_bus_t *)arg;
i2c_port_num_t port_num = bus->port_num;
esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[port_num].link_list, i2c_regs_retention[port_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(port_num));
esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[port_num].link_list, i2c_regs_retention[port_num].link_num, REGDMA_LINK_PRI_I2C, I2C_SLEEP_RETENTION_MODULE(port_num));
ESP_RETURN_ON_ERROR(ret, TAG, "failed to allocate mem for sleep retention");
return ret;
}

View File

@ -22,8 +22,6 @@ extern "C" {
#if SOC_PAU_SUPPORTED
#include "hal/pau_types.h"
#define REGDMA_LINK_DBG 0 /* Enable REGDMA link info dump apis*/
/**
* @brief Create a REGDMA continuous type linked list node without retention buffer and the retention buffer is passed in by the caller
* @param backup Register address to be backed up by REGDMA

View File

@ -14,7 +14,6 @@
#include "esp_check.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"

View File

@ -14,7 +14,7 @@
#include "esp_check.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_crc.h"
#include "esp_rom_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"
@ -391,12 +391,12 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{
*(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size);
*(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size);
}
static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{
if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
// resume uarts
for (int i = 0; i < SOC_UART_NUM; ++i) {
if (!uart_ll_is_enabled(i)) {

View File

@ -14,7 +14,7 @@
#include "esp_check.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_crc.h"
#include "esp_rom_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"
@ -431,12 +431,12 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{
*(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size);
*(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size);
}
static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{
if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
// resume uarts
for (int i = 0; i < SOC_UART_NUM; ++i) {
if (!uart_ll_is_enabled(i)) {

View File

@ -15,7 +15,7 @@
#include "esp_check.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_crc.h"
#include "esp_rom_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"
@ -431,12 +431,12 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{
*(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size);
*(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size);
}
static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{
if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
// resume uarts
for (int i = 0; i < SOC_UART_NUM; ++i) {
if (!uart_ll_is_enabled(i)) {

View File

@ -15,7 +15,7 @@
#include "esp_ipc_isr.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_crc.h"
#include "esp_rom_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"
@ -374,12 +374,12 @@ static TCM_IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
static TCM_IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{
*(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size);
*(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size);
}
static TCM_IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
{
if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
// resume uarts
for (int i = 0; i < SOC_UART_NUM; ++i) {
if (!uart_ll_is_enabled(i)) {

View File

@ -15,7 +15,6 @@
#include "esp_ipc_isr.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"

View File

@ -247,19 +247,6 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp)
}
pmu_sleep_analog_init(PMU_instance(), &config->analog, dslp);
pmu_sleep_param_init(PMU_instance(), &config->param, dslp);
// When light sleep (PD_TOP), the PAU will power down. so need use LP_SYS_BACKUP_DMA_CFG2_REG to store recover link address.
if (!dslp && PMU.hp_sys[PMU_MODE_HP_SLEEP].dig_power.top_pd_en) {
if (PMU.hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en ||
PMU.hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en) {
uint32_t link_sel = PMU.hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_mode & 0x3;
uint32_t link_addr = REG_READ(PAU_REGDMA_LINK_0_ADDR_REG + link_sel * 4);
lp_sys_ll_set_pau_link_addr(link_addr);
pmu_sleep_enable_regdma_backup();
}
} else {
pmu_sleep_disable_regdma_backup();
}
}
void pmu_sleep_increase_ldo_volt(void) {

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -8,6 +8,7 @@
#include <string.h>
#include <assert.h>
#include <sys/cdefs.h>
#include <inttypes.h>
#include "esp_private/regdma_link.h"
@ -445,9 +446,22 @@ static void regdma_link_update_stats_wrapper(void *link, int entry, int depth)
regdma_link_update_stats(regdma_link_get_stats(link), entry, depth);
}
static void regdma_link_iterator(void *link, int entry, void (*hook)(void *, int, int))
{
assert(entry < REGDMA_LINK_ENTRY_NUM);
int iter = 0;
while (link) {
if (hook) {
(*hook)(link, entry, iter++);
}
link = regdma_link_get_next(link, entry);
}
}
void regdma_link_stats(void *link, int entry)
{
regdma_link_recursive_impl(link, entry, 0, regdma_link_update_stats_wrapper);
regdma_link_iterator(link, entry, regdma_link_update_stats_wrapper);
}
static void regdma_link_destroy_wrapper(void *link, int entry, int depth)
@ -700,13 +714,17 @@ void * regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint
return NULL;
}
#if REGDMA_LINK_DBG
static __attribute__((unused)) const char *TAG = "regdma_link";
static const char* s_link_mode_str[] = { "CONTINUOUS", "ADDR_MAP", "WRITE", "WAIT" };
static const char* s_boolean_str[] = { "false", "true" };
static void print_info_link_data(FILE *out, const uint32_t buf[], int len)
{
for (int i = 0; i < len; i++) {
fprintf(out, ((i + 1) % 8) ? "%08lx " : "%08lx\n", buf[i]);
if (i % 8 == 0) {
fprintf(out, "\t\t");
}
fprintf(out, ((i + 1) % 8) ? "%08"PRIx32" " : "%08"PRIx32"\n", buf[i]);
}
if (len % 8) {
fprintf(out, "\n");
@ -717,9 +735,13 @@ static void print_info_continuous_wrapper(FILE *out, void *link)
{
regdma_link_head_t head = REGDMA_LINK_HEAD(link);
regdma_link_continuous_t *cons = __containerof(link, regdma_link_continuous_t, head);
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p\n",
cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next,
cons->body.backup, cons->body.restore, cons->body.mem);
assert((cons->stat.module & (cons->stat.module - 1)) == 0);
fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p\n" LOG_RESET_COLOR,
__builtin_ffs(cons->stat.module) - 1, cons->stat.id, link,
s_link_mode_str[cons->head.mode], cons->head.length, s_boolean_str[cons->head.branch], s_boolean_str[cons->head.skip_r], s_boolean_str[cons->head.skip_b], s_boolean_str[cons->head.eof],
cons->body.next,
cons->body.backup, cons->body.restore,
cons->body.mem);
print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length);
}
@ -727,18 +749,23 @@ static void print_info_addr_map_wrapper(FILE *out, void *link)
{
regdma_link_head_t head = REGDMA_LINK_HEAD(link);
regdma_link_addr_map_t *map = __containerof(link, regdma_link_addr_map_t, head);
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n",
map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next, map->body.backup,
map->body.restore, map->body.mem, map->body.map[0], map->body.map[1],
map->body.map[2], map->body.map[3]);
assert((map->stat.module & (map->stat.module - 1)) == 0);
fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p, map:{%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32"}\n" LOG_RESET_COLOR,
__builtin_ffs(map->stat.module) - 1, map->stat.id, link,
s_link_mode_str[map->head.mode], map->head.length, s_boolean_str[map->head.branch], s_boolean_str[map->head.skip_r], s_boolean_str[map->head.skip_b], s_boolean_str[map->head.eof],
map->body.next,
map->body.backup, map->body.restore,
map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]);
print_info_link_data(out, (const uint32_t *)map->body.mem, head.length);
}
static void print_info_write_wait_wrapper(FILE *out, void *link)
{
regdma_link_write_wait_t *ww = __containerof(link, regdma_link_write_wait_t, head);
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, value:%lx, mask:%lx\n",
ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next,
fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, value:%"PRIx32", mask:%"PRIx32"\n" LOG_RESET_COLOR,
__builtin_ffs(ww->stat.module) - 1, ww->stat.id, link,
s_link_mode_str[ww->head.mode], ww->head.length, s_boolean_str[ww->head.branch], s_boolean_str[ww->head.skip_r], s_boolean_str[ww->head.skip_b], s_boolean_str[ww->head.eof],
ww->body.next,
ww->body.backup, ww->body.value, ww->body.mask);
}
@ -746,9 +773,12 @@ static void print_info_branch_continuous_wrapper(FILE *out, void *link)
{
regdma_link_head_t head = REGDMA_LINK_HEAD(link);
regdma_link_branch_continuous_t *cons = __containerof(link, regdma_link_branch_continuous_t, head);
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p\n",
cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next[0], cons->body.next[1],
cons->body.next[2], cons->body.next[3], cons->body.backup, cons->body.restore,
assert((cons->stat.module & (cons->stat.module - 1)) == 0);
fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p\n" LOG_RESET_COLOR,
__builtin_ffs(cons->stat.module) - 1, cons->stat.id, link,
s_link_mode_str[cons->head.mode], cons->head.length, s_boolean_str[cons->head.branch], s_boolean_str[cons->head.skip_r], s_boolean_str[cons->head.skip_b], s_boolean_str[cons->head.eof],
cons->body.next,
cons->body.backup, cons->body.restore,
cons->body.mem);
print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length);
}
@ -757,20 +787,24 @@ static void print_info_branch_addr_map_wrapper(FILE *out, void *link)
{
regdma_link_head_t head = REGDMA_LINK_HEAD(link);
regdma_link_branch_addr_map_t *map = __containerof(link, regdma_link_branch_addr_map_t, head);
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n",
map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next[0], map->body.next[1], map->body.next[2],
map->body.next[3], map->body.backup, map->body.restore, map->body.mem, map->body.map[0],
map->body.map[1], map->body.map[2], map->body.map[3]);
assert((map->stat.module & (map->stat.module - 1)) == 0);
fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p, map:{%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32"}\n" LOG_RESET_COLOR,
__builtin_ffs(map->stat.module) - 1, map->stat.id, link,
s_link_mode_str[map->head.mode], map->head.length, s_boolean_str[map->head.branch], s_boolean_str[map->head.skip_r], s_boolean_str[map->head.skip_b], s_boolean_str[map->head.eof],
map->body.next,
map->body.backup, map->body.restore,
map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]);
print_info_link_data(out, (const uint32_t *)map->body.mem, head.length);
}
static void print_info_branch_write_wait_wrapper(FILE *out, void *link)
{
regdma_link_branch_write_wait_t *ww = __containerof(link, regdma_link_branch_write_wait_t, head);
fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, value:%lx, mask:%lx\n",
ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next[0], ww->body.next[1],
ww->body.next[2], ww->body.next[3], ww->body.backup, ww->body.value,
ww->body.mask);
fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, value:%"PRIx32", mask:%"PRIx32"\n" LOG_RESET_COLOR,
__builtin_ffs(ww->stat.module) - 1, ww->stat.id, link,
s_link_mode_str[ww->head.mode], ww->head.length, s_boolean_str[ww->head.branch], s_boolean_str[ww->head.skip_r], s_boolean_str[ww->head.skip_b], s_boolean_str[ww->head.eof],
ww->body.next,
ww->body.backup, ww->body.value, ww->body.mask);
}
static void print_link_info(FILE *out, void *args, int entry, int depth)
@ -808,4 +842,3 @@ void regdma_link_dump(FILE *out, void *link, int entry)
fprintf(out, "This REGDMA linked list is empty!\n");
}
}
#endif

View File

@ -674,8 +674,19 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep)
/**
* These save-restore workaround should be moved to lower layer
*/
FORCE_INLINE_ATTR void misc_modules_wake_prepare(void)
FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t pd_flags)
{
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
if (pd_flags & PMU_SLEEP_PD_TOP) {
// There is no driver to manage the flashboot watchdog, and it is definitely be in off state when
// the system is running, after waking up from pd_top sleep, shut it down by software here.
wdt_hal_context_t mwdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
wdt_hal_write_protect_disable(&mwdt_ctx);
wdt_hal_set_flashboot_en(&mwdt_ctx, false);
wdt_hal_write_protect_enable(&mwdt_ctx);
}
#endif
#if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP
sleep_console_usj_pad_restore();
#endif
@ -1043,7 +1054,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
sleep_retention_do_system_retention(false);
}
#endif
misc_modules_wake_prepare();
misc_modules_wake_prepare(pd_flags);
}
#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING

View File

@ -303,7 +303,6 @@ static void sleep_retention_entries_stats(void)
_lock_release_recursive(&s_retention.lock);
}
#if REGDMA_LINK_DBG
void sleep_retention_dump_entries(FILE *out)
{
_lock_acquire_recursive(&s_retention.lock);
@ -315,7 +314,6 @@ void sleep_retention_dump_entries(FILE *out)
}
_lock_release_recursive(&s_retention.lock);
}
#endif
void * sleep_retention_find_link_by_id(int id)
{

View File

@ -57,14 +57,6 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_uart0_retention_init(v
return ESP_OK;
}
static __attribute__((unused)) esp_err_t sleep_sys_periph_tg0_retention_init(void *arg)
{
esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Timer Group");
ESP_LOGD(TAG, "Timer Group sleep retention initialization");
return ESP_OK;
}
static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(void *arg)
{
esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH);
@ -92,7 +84,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_systimer_retention_ini
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_err_t sleep_sys_periph_l2_cache_retention_init(void)
{
esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH);
esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_HIGH, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (L2 Cache) retention");
ESP_LOGI(TAG, "L2 Cache sleep retention initialization");
return ESP_OK;
@ -102,7 +94,7 @@ esp_err_t sleep_sys_periph_l2_cache_retention_init(void)
#if SOC_PAU_IN_TOP_DOMAIN
esp_err_t sleep_pau_retention_init(void)
{
esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_SYS_PERIPH);
esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PAU) retention");
ESP_LOGI(TAG, "PAU sleep retention initialization");
return ESP_OK;
@ -126,8 +118,6 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a
#endif
err = sleep_sys_periph_uart0_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_tg0_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_iomux_retention_init(arg);
if(err) goto error;
err = sleep_sys_periph_spimem_retention_init(arg);
@ -147,9 +137,7 @@ bool peripheral_domain_pd_allowed(void)
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
const uint32_t inited_modules = sleep_retention_get_inited_modules();
const uint32_t created_modules = sleep_retention_get_created_modules();
const uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH));
return ((inited_modules & mask) == (created_modules & mask));
return (((inited_modules ^ created_modules) & TOP_DOMAIN_PERIPHERALS_BM) == 0);
#else
return false;
#endif

View File

@ -142,7 +142,7 @@ menu "Power Management"
config PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
bool "Power down Digital Peripheral in light sleep (EXPERIMENTAL)"
depends on SOC_PM_SUPPORT_TOP_PD
depends on SOC_PM_SUPPORT_TOP_PD && SOC_PAU_SUPPORTED
select PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP if !SOC_CPU_IN_TOP_DOMAIN
default n #TODO: enable by default if periph init/deinit management supported (WIFI-5252)
help

View File

@ -14,6 +14,7 @@
#include "hal/timer_ll.h"
#include "freertos/FreeRTOS.h"
#include "esp_cpu.h"
#include "esp_check.h"
#include "esp_err.h"
#include "esp_attr.h"
#include "esp_log.h"
@ -23,6 +24,10 @@
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_int_wdt.h"
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#include "esp_private/sleep_retention.h"
#endif
#if SOC_TIMER_GROUPS > 1
/* If we have two hardware timer groups, use the second one for interrupt watchdog. */
@ -47,6 +52,38 @@
#endif // SOC_TIMER_GROUPS > 1
#if CONFIG_ESP_INT_WDT
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
static const char* TAG = "int_wdt";
static esp_err_t sleep_int_wdt_retention_init(void *arg)
{
uint32_t group_id = *(uint32_t *)arg;
esp_err_t err = sleep_retention_entries_create(tg_wdt_regs_retention[group_id].link_list,
tg_wdt_regs_retention[group_id].link_num,
REGDMA_LINK_PRI_SYS_PERIPH_LOW,
(group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT);
if (err == ESP_OK) {
ESP_LOGD(TAG, "Interrupt watchdog timer retention initialization");
}
ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for interrupt watchdog timer");
return err;
}
static esp_err_t esp_int_wdt_retention_enable(uint32_t group_id)
{
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_int_wdt_retention_init, .arg = &group_id } },
.depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM)
};
esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT);
if (err != ESP_OK) {
ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for interrupt watchdog timer retention");
}
}
return err;
}
#endif
static wdt_hal_context_t iwdt_context;
@ -122,6 +159,10 @@ void esp_int_wdt_init(void)
wdt_hal_enable(&iwdt_context);
wdt_hal_write_protect_enable(&iwdt_context);
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
esp_int_wdt_retention_enable(IWDT_TIMER_GROUP);
#endif
#if (CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_BTDM_CTRL_HLI)
#define APB_DCRSET (0x200c)
#define APB_ITCTRL (0x3f00)

View File

@ -11,13 +11,19 @@
#include "hal/wdt_hal.h"
#include "hal/mwdt_ll.h"
#include "hal/timer_ll.h"
#include "esp_check.h"
#include "esp_err.h"
#include "esp_attr.h"
#include "esp_intr_alloc.h"
#include "esp_log.h"
#include "esp_private/system_internal.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_task_wdt_impl.h"
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#include "esp_private/sleep_retention.h"
#endif
#define TWDT_INSTANCE WDT_MWDT0
#define TWDT_TICKS_PER_US 500
#define TWDT_PRESCALER MWDT_LL_DEFAULT_CLK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz
@ -39,6 +45,48 @@ typedef struct {
* init function. */
static twdt_ctx_hard_t init_context;
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
static const char* TAG = "task_wdt";
static esp_err_t sleep_task_wdt_retention_init(void *arg)
{
uint32_t group_id = *(uint32_t *)arg;
esp_err_t err = sleep_retention_entries_create(tg_wdt_regs_retention[group_id].link_list,
tg_wdt_regs_retention[group_id].link_num,
REGDMA_LINK_PRI_SYS_PERIPH_LOW,
(group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT);
if (err == ESP_OK) {
ESP_LOGD(TAG, "Task watchdog timer retention initialization");
}
ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for task watchdog timer");
return err;
}
static esp_err_t esp_task_wdt_retention_enable(uint32_t group_id)
{
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_task_wdt_retention_init, .arg = &group_id } },
.depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM)
};
esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT);
if (err != ESP_OK) {
ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for task watchdog timer retention");
}
}
return err;
}
static esp_err_t esp_task_wdt_retention_disable(uint32_t group_id)
{
esp_err_t err = sleep_retention_module_free((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT);
if (err == ESP_OK) {
err = sleep_retention_module_deinit((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT);
}
return err;
}
#endif
esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config,
twdt_isr_callback callback,
twdt_ctx_t *obj)
@ -74,8 +122,11 @@ esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config,
/* Return the implementation context to the caller */
*obj = (twdt_ctx_t) ctx;
}
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
esp_task_wdt_retention_enable(TWDT_TIMER_GROUP);
#endif
}
return ret;
}
@ -118,6 +169,10 @@ void esp_task_wdt_impl_timer_free(twdt_ctx_t obj)
/* Deregister interrupt */
ESP_ERROR_CHECK(esp_intr_free(ctx->intr_handle));
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
ESP_ERROR_CHECK(esp_task_wdt_retention_disable(TWDT_TIMER_GROUP));
#endif
}
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -15,6 +15,13 @@
#include "test_utils.h"
#include "soc/rtc.h"
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#include "esp_sleep.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/sleep_cpu.h"
#include "esp_private/esp_pmu.h"
#endif
#define TASK_WDT_TIMEOUT_MS 1000
static volatile bool timeout_flag;
@ -41,6 +48,36 @@ TEST_CASE("Task WDT task timeout", "[task_wdt]")
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit());
}
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
TEST_CASE("Task WDT task timeout after peripheral powerdown lightsleep", "[task_wdt]")
{
timeout_flag = false;
esp_task_wdt_config_t twdt_config = {
.timeout_ms = TASK_WDT_TIMEOUT_MS,
.idle_core_mask = 0,
.trigger_panic = false,
};
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_init(&twdt_config));
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_add(NULL));
TEST_ESP_OK(sleep_cpu_configure(true));
esp_sleep_context_t sleep_ctx;
esp_sleep_set_sleep_context(&sleep_ctx);
esp_sleep_enable_timer_wakeup(10 * 1000);
esp_light_sleep_start();
TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP);
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
// Short delay to allow timeout to occur
esp_rom_delay_us(TASK_WDT_TIMEOUT_MS * 1000);
TEST_ASSERT_EQUAL(true, timeout_flag);
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_delete(NULL));
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit());
TEST_ESP_OK(sleep_cpu_configure(false));
}
#endif
#if SOC_MWDT_SUPPORT_XTAL
#if CONFIG_IDF_TARGET_ESP32H2
@ -92,7 +129,7 @@ TEST_CASE("Task WDT inactive when no task to watch", "[task_wdt]")
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_add(NULL));
esp_rom_delay_us(TASK_WDT_TIMEOUT_MS * 1000);
TEST_ASSERT_EQUAL(true, timeout_flag);
/* Remove the task we just addded and make sure the WDT is stopped*/
/* Remove the task we just added and make sure the WDT is stopped*/
timeout_flag = false;
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_delete(NULL));
esp_rom_delay_us(2 * TASK_WDT_TIMEOUT_MS * 1000);

View File

@ -1,3 +1,5 @@
# Default configuration
# Used for testing stack smashing protection
CONFIG_COMPILER_STACK_CHECK=y
CONFIG_ESP_SLEEP_DEBUG=y
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y

View File

@ -20,6 +20,10 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_
pau_ll_set_regdma_link2_addr(hal->dev, (*link_addr)[2]);
/* The link 3 of REGDMA is reserved, PMU state switching will not use
* REGDMA link 3 */
// When light sleep (PD_TOP), the PAU will power down. so need use LP_SYS_BACKUP_DMA_CFG2_REG
// to store recover link address. We always use link0 as the default retention entry.
lp_sys_ll_set_pau_link_addr((uint32_t)(*link_addr)[0]);
}
void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore)

View File

@ -18,24 +18,29 @@ typedef enum periph_retention_module {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1,
SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2,
/* modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_WIFI_MAC = 10,
SLEEP_RETENTION_MODULE_WIFI_BB = 11,
SLEEP_RETENTION_MODULE_BLE_MAC = 12,
SLEEP_RETENTION_MODULE_BT_BB = 13,
SLEEP_RETENTION_MODULE_802154_MAC = 14,
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 16,
SLEEP_RETENTION_MODULE_ADC = 17,
SLEEP_RETENTION_MODULE_GDMA_CH0 = 24,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 25,
SLEEP_RETENTION_MODULE_GDMA_CH2 = 26,
* TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 3,
/* Timer Group by target*/
SLEEP_RETENTION_MODULE_TG0_WDT = 4,
SLEEP_RETENTION_MODULE_TG1_WDT = 5,
SLEEP_RETENTION_MODULE_TG0_TIMER = 6,
SLEEP_RETENTION_MODULE_TG1_TIMER = 7,
/* GDMA by channel */
SLEEP_RETENTION_MODULE_GDMA_CH0 = 8,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 9,
SLEEP_RETENTION_MODULE_GDMA_CH2 = 10,
/* MISC Peripherals */
SLEEP_RETENTION_MODULE_ADC = 11,
SLEEP_RETENTION_MODULE_I2C0 = 12,
SLEEP_RETENTION_MODULE_RMT0 = 13,
/* Modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
SLEEP_RETENTION_MODULE_WIFI_BB = 27,
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
SLEEP_RETENTION_MODULE_BT_BB = 29,
SLEEP_RETENTION_MODULE_802154_MAC = 30,
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
@ -43,26 +48,45 @@ typedef enum periph_retention_module_bitmap {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM),
SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
/* Timer Group by target*/
SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT),
SLEEP_RETENTION_MODULE_BM_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER),
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER),
/* GDMA by channel */
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
/* MISC Peripherals */
SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC),
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0),
/* modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC),
SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB),
SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB),
SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC),
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
#define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM \
| SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM \
| SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \
| SLEEP_RETENTION_MODULE_BM_TASK_WDT \
| SLEEP_RETENTION_MODULE_BM_INT_WDT \
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \
| SLEEP_RETENTION_MODULE_BM_ADC \
| SLEEP_RETENTION_MODULE_BM_I2C0 \
| SLEEP_RETENTION_MODULE_BM_RMT0)
#ifdef __cplusplus
}
#endif

View File

@ -444,6 +444,7 @@
// #define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
// #define SOC_TIMER_SUPPORT_ETM (1)
// #define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
// #define SOC_MWDT_SUPPORT_XTAL (1)

View File

@ -54,21 +54,6 @@ const regdma_entries_config_t uart_regs_retention[] = {
};
_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions");
/* Timergroup Registers Context */
#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1)
const regdma_entries_config_t tg_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }
};
_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions");
/* IO MUX Registers Context */
#define N_REGS_IOMUX_0() (((IO_MUX_GPIO26_REG - REG_IO_MUX_BASE) / 4) + 1)
#define N_REGS_IOMUX_1() (((GPIO_FUNC30_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,3 +22,71 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
}
}
};
#if SOC_TIMER_SUPPORT_SLEEP_RETENTION
#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG
static const regdma_entries_config_t tg0_wdt_regs_retention[] = {
/*Timer group backup. should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
static const regdma_entries_config_t tg1_wdt_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
/* Registers in retention context:
* TIMG_T0CONFIG_REG
* TIMG_T0ALARMLO_REG
* TIMG_T0ALARMHI_REG
* TIMG_INT_ENA_TIMERS_REG
* TIMG_REGCLK_REG
*/
#define N_REGS_TG_TIMER_CFG 5
static const uint32_t tg_timer_regs_map[4] = {0x10000031, 0x80000000, 0, 0};
const regdma_entries_config_t tg0_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const regdma_entries_config_t tg1_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)},
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)},
};
const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)},
[1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)},
};
#endif

View File

@ -439,6 +439,7 @@
// #define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
// #define SOC_TIMER_SUPPORT_ETM (1)
// #define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
// #define SOC_MWDT_SUPPORT_XTAL (1)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,3 +22,71 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
}
}
};
#if SOC_TIMER_SUPPORT_SLEEP_RETENTION
#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG
static const regdma_entries_config_t tg0_wdt_regs_retention[] = {
/*Timer group backup. should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
static const regdma_entries_config_t tg1_wdt_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
/* Registers in retention context:
* TIMG_T0CONFIG_REG
* TIMG_T0ALARMLO_REG
* TIMG_T0ALARMHI_REG
* TIMG_INT_ENA_TIMERS_REG
* TIMG_REGCLK_REG
*/
#define N_REGS_TG_TIMER_CFG 5
static const uint32_t tg_timer_regs_map[4] = {0x10000031, 0x80000000, 0, 0};
const regdma_entries_config_t tg0_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const regdma_entries_config_t tg1_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)},
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)},
};
const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)},
[1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)},
};
#endif

View File

@ -1111,6 +1111,10 @@ config SOC_TIMER_SUPPORT_ETM
bool
default y
config SOC_TIMER_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MWDT_SUPPORT_XTAL
bool
default y

View File

@ -18,25 +18,29 @@ typedef enum periph_retention_module {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1,
SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2,
/* modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_WIFI_MAC = 10,
SLEEP_RETENTION_MODULE_WIFI_BB = 11,
SLEEP_RETENTION_MODULE_BLE_MAC = 12,
SLEEP_RETENTION_MODULE_BT_BB = 13,
SLEEP_RETENTION_MODULE_802154_MAC = 14,
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 16,
SLEEP_RETENTION_MODULE_ADC = 17,
SLEEP_RETENTION_MODULE_GDMA_CH0 = 24,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 25,
SLEEP_RETENTION_MODULE_GDMA_CH2 = 26,
SLEEP_RETENTION_MODULE_I2C0 = 27,
* TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 3,
/* Timer Group by target*/
SLEEP_RETENTION_MODULE_TG0_WDT = 4,
SLEEP_RETENTION_MODULE_TG1_WDT = 5,
SLEEP_RETENTION_MODULE_TG0_TIMER = 6,
SLEEP_RETENTION_MODULE_TG1_TIMER = 7,
/* GDMA by channel */
SLEEP_RETENTION_MODULE_GDMA_CH0 = 8,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 9,
SLEEP_RETENTION_MODULE_GDMA_CH2 = 10,
/* MISC Peripherals */
SLEEP_RETENTION_MODULE_ADC = 11,
SLEEP_RETENTION_MODULE_I2C0 = 12,
SLEEP_RETENTION_MODULE_RMT0 = 13,
/* Modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
SLEEP_RETENTION_MODULE_WIFI_BB = 27,
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
SLEEP_RETENTION_MODULE_BT_BB = 29,
SLEEP_RETENTION_MODULE_802154_MAC = 30,
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
@ -44,27 +48,45 @@ typedef enum periph_retention_module_bitmap {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM),
SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
/* Timer Group by target*/
SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT),
SLEEP_RETENTION_MODULE_BM_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER),
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER),
/* GDMA by channel */
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
/* MISC Peripherals */
SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC),
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0),
/* modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC),
SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB),
SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB),
SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC),
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
#define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM \
| SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM \
| SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \
| SLEEP_RETENTION_MODULE_BM_TASK_WDT \
| SLEEP_RETENTION_MODULE_BM_INT_WDT \
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \
| SLEEP_RETENTION_MODULE_BM_ADC \
| SLEEP_RETENTION_MODULE_BM_I2C0 \
| SLEEP_RETENTION_MODULE_BM_RMT0)
#ifdef __cplusplus
}
#endif

View File

@ -440,6 +440,7 @@
#define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
#define SOC_TIMER_SUPPORT_ETM (1)
#define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1)

View File

@ -54,21 +54,6 @@ const regdma_entries_config_t uart_regs_retention[] = {
};
_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions");
/* Timergroup Registers Context */
#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1)
const regdma_entries_config_t tg_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }
};
_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions");
/* IO MUX Registers Context */
#define N_REGS_IOMUX_0() (((IO_MUX_GPIO30_REG - REG_IO_MUX_BASE) / 4) + 1)
#define N_REGS_IOMUX_1() (((GPIO_FUNC34_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,3 +22,69 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
}
}
};
#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG
static const regdma_entries_config_t tg0_wdt_regs_retention[] = {
/*Timer group backup. should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
static const regdma_entries_config_t tg1_wdt_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
/* Registers in retention context:
* TIMG_T0CONFIG_REG
* TIMG_T0ALARMLO_REG
* TIMG_T0ALARMHI_REG
* TIMG_INT_ENA_TIMERS_REG
* TIMG_REGCLK_REG
*/
#define N_REGS_TG_TIMER_CFG 5
static const uint32_t tg_timer_regs_map[4] = {0x10000031, 0x80000000, 0, 0};
const regdma_entries_config_t tg0_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const regdma_entries_config_t tg1_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)},
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)},
};
const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)},
[1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)},
};

View File

@ -1115,6 +1115,10 @@ config SOC_TIMER_SUPPORT_ETM
bool
default y
config SOC_TIMER_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MWDT_SUPPORT_XTAL
bool
default y

View File

@ -18,24 +18,28 @@ typedef enum periph_retention_module {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1,
SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2,
/* modem module, which includes BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BLE_MAC = 12,
SLEEP_RETENTION_MODULE_BT_BB = 13,
SLEEP_RETENTION_MODULE_802154_MAC = 14,
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 16,
SLEEP_RETENTION_MODULE_ADC = 17,
SLEEP_RETENTION_MODULE_GDMA_CH0 = 24,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 25,
SLEEP_RETENTION_MODULE_GDMA_CH2 = 26,
SLEEP_RETENTION_MODULE_I2C0 = 27,
SLEEP_RETENTION_MODULE_I2C1 = 28,
* TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 3,
/* Timer Group by target*/
SLEEP_RETENTION_MODULE_TG0_WDT = 4,
SLEEP_RETENTION_MODULE_TG1_WDT = 5,
SLEEP_RETENTION_MODULE_TG0_TIMER = 6,
SLEEP_RETENTION_MODULE_TG1_TIMER = 7,
/* GDMA by channel */
SLEEP_RETENTION_MODULE_GDMA_CH0 = 8,
SLEEP_RETENTION_MODULE_GDMA_CH1 = 9,
SLEEP_RETENTION_MODULE_GDMA_CH2 = 10,
/* MISC Peripherals */
SLEEP_RETENTION_MODULE_ADC = 11,
SLEEP_RETENTION_MODULE_I2C0 = 12,
SLEEP_RETENTION_MODULE_I2C1 = 13,
SLEEP_RETENTION_MODULE_RMT0 = 14,
/* Modem module, which includes BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
SLEEP_RETENTION_MODULE_BT_BB = 29,
SLEEP_RETENTION_MODULE_802154_MAC = 30,
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
@ -43,27 +47,45 @@ typedef enum periph_retention_module_bitmap {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM),
SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
/* Timer Group by target*/
SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT),
SLEEP_RETENTION_MODULE_BM_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER),
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER),
/* GDMA by channel */
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
/* MISC Peripherals */
SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC),
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
SLEEP_RETENTION_MODULE_BM_I2C1 = BIT(SLEEP_RETENTION_MODULE_I2C1),
SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0),
/* modem module, which includes BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB),
SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC),
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
SLEEP_RETENTION_MODULE_BM_I2C1 = BIT(SLEEP_RETENTION_MODULE_I2C1),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t) -1
} periph_retention_module_bitmap_t;
#define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM \
| SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM \
| SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \
| SLEEP_RETENTION_MODULE_BM_TASK_WDT \
| SLEEP_RETENTION_MODULE_BM_INT_WDT \
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \
| SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \
| SLEEP_RETENTION_MODULE_BM_ADC \
| SLEEP_RETENTION_MODULE_BM_I2C0 \
| SLEEP_RETENTION_MODULE_BM_I2C1 \
| SLEEP_RETENTION_MODULE_BM_RMT0)
#ifdef __cplusplus
}
#endif

View File

@ -438,6 +438,7 @@
#define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
#define SOC_TIMER_SUPPORT_ETM (1)
#define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1)

View File

@ -54,21 +54,6 @@ const regdma_entries_config_t uart_regs_retention[] = {
};
_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions");
/* Timergroup Registers Context */
#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1)
const regdma_entries_config_t tg_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }
};
_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions");
/* IO MUX Registers Context */
#define N_REGS_IOMUX_0() (((IO_MUX_GPIO27_REG - REG_IO_MUX_BASE) / 4) + 1)
#define N_REGS_IOMUX_1() (((GPIO_FUNC31_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,3 +22,69 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
}
}
};
#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG
static const regdma_entries_config_t tg0_wdt_regs_retention[] = {
/*Timer group backup. should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
static const regdma_entries_config_t tg1_wdt_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
/* Registers in retention context:
* TIMG_T0CONFIG_REG
* TIMG_T0ALARMLO_REG
* TIMG_T0ALARMHI_REG
* TIMG_INT_ENA_TIMERS_REG
* TIMG_REGCLK_REG
*/
#define N_REGS_TG_TIMER_CFG 5
static const uint32_t tg_timer_regs_map[4] = {0x10000031, 0x80000000, 0, 0};
const regdma_entries_config_t tg0_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const regdma_entries_config_t tg1_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)},
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)},
};
const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)},
[1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)},
};

View File

@ -1355,6 +1355,10 @@ config SOC_TIMER_SUPPORT_ETM
bool
default y
config SOC_TIMER_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MWDT_SUPPORT_XTAL
bool
default y

View File

@ -17,10 +17,14 @@ typedef enum periph_retention_module {
SLEEP_RETENTION_MODULE_MIN = 0,
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1,
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 16,
* TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_SYS_PERIPH = 2,
/* Timer Group by target*/
SLEEP_RETENTION_MODULE_TG0_WDT = 3,
SLEEP_RETENTION_MODULE_TG1_WDT = 4,
SLEEP_RETENTION_MODULE_TG0_TIMER = 5,
SLEEP_RETENTION_MODULE_TG1_TIMER = 6,
SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
@ -28,14 +32,25 @@ typedef enum periph_retention_module {
typedef enum periph_retention_module_bitmap {
/* clock module, which includes system and modem */
SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM),
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
/* Timer Group by target*/
SLEEP_RETENTION_MODULE_BM_TG0_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT),
SLEEP_RETENTION_MODULE_BM_TG1_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER),
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER),
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
#define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM \
| SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \
| SLEEP_RETENTION_MODULE_BM_TG0_WDT \
| SLEEP_RETENTION_MODULE_BM_TG1_WDT \
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER)
#ifdef __cplusplus
}
#endif

View File

@ -536,6 +536,7 @@
#define SOC_TIMER_GROUP_SUPPORT_RC_FAST 1
#define SOC_TIMER_GROUP_TOTAL_TIMERS 4
#define SOC_TIMER_SUPPORT_ETM 1
#define SOC_TIMER_SUPPORT_SLEEP_RETENTION 1
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1)

View File

@ -52,21 +52,6 @@ const regdma_entries_config_t uart_regs_retention[] = {
};
_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions");
/* Timergroup Registers Context */
#define N_REGS_TG0() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1)
const regdma_entries_config_t tg_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, /* TG0 */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG0(), 0, 0), .owner = ENTRY(0) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) },
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) },
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) },
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) },
};
_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions");
/* IO MUX Registers Context */
#define N_REGS_IOMUX_0() (((IO_MUX_GPIO54_REG - REG_IO_MUX_BASE) / 4) + 1)
#define N_REGS_IOMUX_1() (((GPIO_ZERO_DET1_FILTER_CNT_REG - DR_REG_GPIO_BASE) / 4) + 1)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -24,3 +24,79 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
}
}
};
#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG
static const regdma_entries_config_t tg0_wdt_regs_retention[] = {
/*Timer group backup. should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
static const regdma_entries_config_t tg1_wdt_regs_retention[] = {
/*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
/* Registers in retention context:
* TIMG_T0CONFIG_REG / TIMG_T1CONFIG_REG
* TIMG_T0ALARMLO_REG / TIMG_T1ALARMLO_REG
* TIMG_T0ALARMHI_REG / TIMG_T1ALARMHI_REG
* TIMG_INT_ENA_TIMERS_REG
* TIMG_REGCLK_REG
*/
#define N_REGS_TG_TIMER_CFG 8
static const uint32_t tg_timer_regs_map[4] = {0x10006231, 0x80000000, 0x0, 0x0};
const regdma_entries_config_t tg0_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T1UPDATE_REG(0), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T1UPDATE_REG(0), 0x0, TIMG_T1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x06), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x07), TIMG_T1LO_REG(0), TIMG_T1LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x08), TIMG_T1HI_REG(0), TIMG_T1LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x09), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x0a), TIMG_T1LOAD_REG(0), 0x1, TIMG_T1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const regdma_entries_config_t tg1_timer_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \
tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2)
},
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x02), TIMG_T1UPDATE_REG(1), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T1UPDATE_REG(1), 0x0, TIMG_T1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x06), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x07), TIMG_T1LO_REG(1), TIMG_T1LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x08), TIMG_T1HI_REG(1), TIMG_T1LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x09), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x0a), TIMG_T1LOAD_REG(1), 0x1, TIMG_T1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)},
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)},
};
const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = {
[0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)},
[1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)},
};

View File

@ -37,15 +37,19 @@ extern "C" {
#define REGDMA_TEEAPM_LINK(_pri) ((0x0f << 8) | _pri)
#define REGDMA_UART_LINK(_pri) ((0x10 << 8) | _pri)
#define REGDMA_TIMG_LINK(_pri) ((0x11 << 8) | _pri)
#define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri)
#define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri)
#define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri)
#define REGDMA_BLE_MAC_LINK(_pri) ((0x15 << 8) | _pri)
#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x16 << 8) | _pri)
#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x17 << 8) | _pri)
#define REGDMA_GDMA_LINK(_pri) ((0x18 << 8) | _pri)
#define REGDMA_I2C_LINK(_pri) ((0x19 << 8) | _pri)
#define REGDMA_IOMUX_LINK(_pri) ((0x11 << 8) | _pri)
#define REGDMA_SPIMEM_LINK(_pri) ((0x12 << 8) | _pri)
#define REGDMA_SYSTIMER_LINK(_pri) ((0x13 << 8) | _pri)
#define REGDMA_BLE_MAC_LINK(_pri) ((0x14 << 8) | _pri)
#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x15 << 8) | _pri)
#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x16 << 8) | _pri)
#define REGDMA_GDMA_LINK(_pri) ((0x17 << 8) | _pri)
#define REGDMA_I2C_LINK(_pri) ((0x18 << 8) | _pri)
#define REGDMA_RMT_LINK(_pri) ((0x19 << 8) | _pri)
#define REGDMA_TG0_WDT_LINK(_pri) ((0x1A << 8) | _pri)
#define REGDMA_TG1_WDT_LINK(_pri) ((0x1B << 8) | _pri)
#define REGDMA_TG0_TIMER_LINK(_pri) ((0x1C << 8) | _pri)
#define REGDMA_TG1_TIMER_LINK(_pri) ((0x1D << 8) | _pri)
#define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri)
#define REGDMA_LINK_PRI_SYS_CLK REGDMA_LINK_PRI_0
@ -56,8 +60,12 @@ extern "C" {
#define REGDMA_LINK_PRI_BT_MAC_BB REGDMA_LINK_PRI_5
#define REGDMA_LINK_PRI_SYS_PERIPH_HIGH REGDMA_LINK_PRI_5 // INT_MTX & HP_SYSTEM & Console UART
#define REGDMA_LINK_PRI_SYS_PERIPH_LOW REGDMA_LINK_PRI_6 // TG0 & IO MUX & SPI MEM & Systimer
#define REGDMA_LINK_PRI_IEEE802154 REGDMA_LINK_PRI_7
#define REGDMA_LINK_PRI_GDMA REGDMA_LINK_PRI_7
#define REGDMA_LINK_PRI_GENERAL_PERIPH REGDMA_LINK_PRI_7 // Low retenion priority for general peripherals
#define REGDMA_LINK_PRI_IEEE802154 REGDMA_LINK_PRI_GENERAL_PERIPH
#define REGDMA_LINK_PRI_GDMA REGDMA_LINK_PRI_GENERAL_PERIPH
#define REGDMA_LINK_PRI_RMT REGDMA_LINK_PRI_GENERAL_PERIPH
#define REGDMA_LINK_PRI_GPTIMER REGDMA_LINK_PRI_GENERAL_PERIPH
#define REGDMA_LINK_PRI_I2C REGDMA_LINK_PRI_GENERAL_PERIPH
typedef enum {
REGDMA_LINK_PRI_0 = 0,

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -11,6 +11,7 @@
#include "soc/timer_group_struct.h"
#include "soc/soc_caps.h"
#include "soc/periph_defs.h"
#include "soc/regdma.h"
#ifdef __cplusplus
extern "C" {
@ -28,6 +29,16 @@ typedef struct {
extern const timer_group_signal_conn_t timer_group_periph_signals;
#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && SOC_PAU_SUPPORTED
typedef struct {
const regdma_entries_config_t *link_list;
uint32_t link_num;
} tg_reg_ctx_link_t;
extern const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS];
extern const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS];
#endif
#ifdef __cplusplus
}
#endif