Skip to content

Commit 0c38389

Browse files
committed
change(gptimer): optimize the registers to be backup
1 parent 216e653 commit 0c38389

File tree

19 files changed

+154
-259
lines changed

19 files changed

+154
-259
lines changed

components/esp_driver_gptimer/include/driver/gptimer.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -28,9 +28,9 @@ typedef struct {
2828
if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */
2929
struct {
3030
uint32_t intr_shared: 1; /*!< Set true, the timer interrupt number can be shared with other peripherals */
31-
uint32_t backup_before_sleep: 1; /*!< If set, the driver will backup/restore the GPTimer registers before/after entering/exist sleep mode.
32-
By this approach, the system can power off GPTimer's power domain.
33-
This can save power, but at the expense of more RAM being consumed */
31+
uint32_t allow_pd: 1; /*!< If set, driver allows the power domain to be powered off when system enters sleep mode.
32+
This can save power, but at the expense of more RAM being consumed to save register context. */
33+
uint32_t backup_before_sleep: 1; /*!< @deprecated, same meaning as allow_pd */
3434
} flags; /*!< GPTimer config flags*/
3535
} gptimer_config_t;
3636

components/esp_driver_gptimer/src/gptimer.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
9494
TAG, "invalid interrupt priority:%d", config->intr_priority);
9595
}
9696

97+
bool allow_pd = (config->flags.allow_pd == 1) || (config->flags.backup_before_sleep == 1);
9798
#if !SOC_TIMER_SUPPORT_SLEEP_RETENTION
98-
ESP_RETURN_ON_FALSE(config->flags.backup_before_sleep == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported");
99+
ESP_RETURN_ON_FALSE(allow_pd == false, ESP_ERR_NOT_SUPPORTED, TAG, "not able to power down in light sleep");
99100
#endif // SOC_TIMER_SUPPORT_SLEEP_RETENTION
100101

101102
timer = heap_caps_calloc(1, sizeof(gptimer_t), GPTIMER_MEM_ALLOC_CAPS);
@@ -106,11 +107,11 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
106107
int group_id = group->group_id;
107108
int timer_id = timer->timer_id;
108109

110+
if (allow_pd) {
109111
#if GPTIMER_USE_RETENTION_LINK
110-
if (config->flags.backup_before_sleep != 0) {
111112
gptimer_create_retention_module(group);
112-
}
113113
#endif // GPTIMER_USE_RETENTION_LINK
114+
}
114115

115116
// initialize HAL layer
116117
timer_hal_init(&timer->hal, group_id, timer_id);

components/esp_driver_gptimer/src/gptimer_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ gptimer_group_t *gptimer_acquire_group_handle(int group_id)
8787
}
8888
}
8989
#if GPTIMER_USE_RETENTION_LINK
90-
sleep_retention_module_t module = TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id);
90+
sleep_retention_module_t module = tg_timer_reg_retention_info[group_id].module;
9191
sleep_retention_module_init_param_t init_param = {
9292
.cbs = {
9393
.create = {

components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
set(srcs "test_app_main.c"
2-
"test_gptimer.c"
3-
"test_gptimer_sleep.c")
2+
"test_gptimer.c")
43

54
if(CONFIG_GPTIMER_ISR_IRAM_SAFE)
65
list(APPEND srcs "test_gptimer_iram.c")
@@ -10,6 +9,10 @@ if(CONFIG_SOC_TIMER_SUPPORT_ETM)
109
list(APPEND srcs "test_gptimer_etm.c")
1110
endif()
1211

12+
if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED AND CONFIG_PM_ENABLE)
13+
list(APPEND srcs "test_gptimer_sleep.c")
14+
endif()
15+
1316
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
1417
# the component can be registered as WHOLE_ARCHIVE
1518
idf_component_register(SRCS ${srcs}

components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c

Lines changed: 25 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,8 @@
1515
#include "esp_private/sleep_cpu.h"
1616
#include "esp_private/esp_sleep_internal.h"
1717
#include "esp_private/esp_pmu.h"
18-
#if !SOC_LIGHT_SLEEP_SUPPORTED
19-
#include "esp_private/gptimer.h"
20-
#include "esp_private/sleep_retention.h"
21-
#include "hal/timer_ll.h"
22-
#include "hal/wdt_hal.h"
23-
#endif
24-
25-
#if CONFIG_GPTIMER_ISR_IRAM_SAFE
26-
#define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR
27-
#else
28-
#define TEST_ALARM_CALLBACK_ATTR
29-
#endif // CONFIG_GPTIMER_ISR_IRAM_SAFE
3018

31-
static TEST_ALARM_CALLBACK_ATTR bool test_gptimer_alarm_stop_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
19+
static bool test_gptimer_alarm_stop_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
3220
{
3321
TaskHandle_t task_handle = (TaskHandle_t)user_data;
3422
BaseType_t high_task_wakeup;
@@ -37,75 +25,19 @@ static TEST_ALARM_CALLBACK_ATTR bool test_gptimer_alarm_stop_callback(gptimer_ha
3725
return high_task_wakeup == pdTRUE;
3826
}
3927

40-
/**
41-
* @brief This function abstracts the behavior of performing the Backup-Reset-Restore process on the specified
42-
* Timer group and is used as a helper function to test the retention function of the driver.
43-
* If light-sleep feature is supported, this function will enter and exit a real light sleep or PD_TOP
44-
* light sleep. Otherwise, it will trigger retention by software and reset the timer module to simulate
45-
* a light-sleep in/out process to verify the driver's support for GPTimer sleep retention.
46-
*
47-
* @param timer Timer handle to be reset, created by `gptimer_new_timer()`
48-
* @param back_up_before_sleep Whether to back up GPTimer registers before sleep
49-
*/
50-
static void test_gptimer_survival_after_sleep_helper(gptimer_handle_t timer, bool back_up_before_sleep)
51-
{
52-
#if SOC_LIGHT_SLEEP_SUPPORTED
53-
esp_sleep_context_t sleep_ctx;
54-
esp_sleep_set_sleep_context(&sleep_ctx);
55-
printf("go to light sleep for 2 seconds\r\n");
56-
#if ESP_SLEEP_POWER_DOWN_CPU
57-
TEST_ESP_OK(sleep_cpu_configure(true));
58-
#endif
59-
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(2 * 1000 * 1000));
60-
TEST_ESP_OK(esp_light_sleep_start());
61-
62-
printf("Waked up! Let's see if GPTimer driver can still work...\r\n");
63-
#if ESP_SLEEP_POWER_DOWN_CPU
64-
TEST_ESP_OK(sleep_cpu_configure(false));
65-
#endif
66-
67-
printf("check if the sleep happened as expected\r\n");
68-
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
69-
#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
70-
if (back_up_before_sleep) {
71-
// Verify that when GPTimer retention is configured and sleep is requested,
72-
// the TOP power domain should be allowed to power down.
73-
TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP);
74-
} else {
75-
// Verify that when GPTimer retention is not configured and sleep is requested, the TOP power
76-
// domain should not be allowed to power down to ensure the peripheral context is not lost.
77-
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP);
78-
}
79-
#endif
80-
esp_sleep_set_sleep_context(NULL);
81-
#elif SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
82-
if (back_up_before_sleep) {
83-
printf("Back up the timer group context in use and then reset it\r\n");
84-
sleep_retention_do_extra_retention(true);
85-
86-
int group_id;
87-
gptimer_get_group_id(timer, &group_id);
88-
_timer_ll_reset_register(group_id);
89-
90-
printf("Reset done! Let's restore its context and see if its driver can still work...\r\n");
91-
sleep_retention_do_extra_retention(false);
92-
}
93-
#endif
94-
}
95-
9628
/**
9729
* @brief Test the GPTimer driver can still work after light sleep
9830
*
99-
* @param back_up_before_sleep Whether to back up GPTimer registers before sleep
31+
* @param allow_pd Whether to allow power down the peripheral in light sleep
10032
*/
101-
static void test_gptimer_sleep_retention(bool back_up_before_sleep)
33+
static void test_gptimer_sleep_retention(bool allow_pd)
10234
{
10335
TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
10436
gptimer_config_t timer_config = {
10537
.resolution_hz = 10000, // 10KHz, 1 tick = 0.1ms
10638
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
10739
.direction = GPTIMER_COUNT_UP,
108-
.flags.backup_before_sleep = back_up_before_sleep,
40+
.flags.allow_pd = allow_pd,
10941
};
11042
gptimer_handle_t timer = NULL;
11143
TEST_ESP_OK(gptimer_new_timer(&timer_config, &timer));
@@ -135,7 +67,27 @@ static void test_gptimer_sleep_retention(bool back_up_before_sleep)
13567
// Note: don't enable the gptimer before going to sleep, ensure no power management lock is acquired by it
13668
TEST_ESP_OK(gptimer_disable(timer));
13769

138-
test_gptimer_survival_after_sleep_helper(timer, back_up_before_sleep);
70+
esp_sleep_context_t sleep_ctx;
71+
esp_sleep_set_sleep_context(&sleep_ctx);
72+
printf("go to light sleep for 2 seconds\r\n");
73+
#if ESP_SLEEP_POWER_DOWN_CPU
74+
TEST_ESP_OK(sleep_cpu_configure(true));
75+
#endif
76+
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(2 * 1000 * 1000));
77+
TEST_ESP_OK(esp_light_sleep_start());
78+
79+
printf("Waked up! Let's see if GPTimer driver can still work...\r\n");
80+
#if ESP_SLEEP_POWER_DOWN_CPU
81+
TEST_ESP_OK(sleep_cpu_configure(false));
82+
#endif
83+
84+
printf("check if the sleep happened as expected\r\n");
85+
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
86+
#if SOC_RMT_SUPPORT_SLEEP_RETENTION
87+
// check if the power domain also is powered down
88+
TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP);
89+
#endif
90+
esp_sleep_set_sleep_context(NULL);
13991

14092
uint64_t count_value_after_sleep = 0;
14193
TEST_ESP_OK(gptimer_get_raw_count(timer, &count_value_after_sleep));

components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static void test_rmt_tx_rx_sleep_retention(bool allow_pd)
113113
#endif
114114
esp_sleep_set_sleep_context(NULL);
115115

116-
// enable both channels, pm lock will be acquired, so no light sleep will event happen during the transaction
116+
// enable both channels, pm lock will be acquired, so no light sleep will even happen during the transaction
117117
TEST_ESP_OK(rmt_enable(tx_channel));
118118
TEST_ESP_OK(rmt_enable(rx_channel));
119119

components/hal/esp32c5/include/hal/timer_ll.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ extern "C" {
2424
// Get timer group register base address with giving group number
2525
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
2626
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
27-
#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER)
2827

2928
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
3029
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \

components/hal/esp32c6/include/hal/timer_ll.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ extern "C" {
2424
// Get timer group register base address with giving group number
2525
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
2626
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
27-
#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER)
2827

2928
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
3029
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \

components/hal/esp32c61/include/hal/timer_ll.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ extern "C" {
2424
// Get timer group register base address with giving group number
2525
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
2626
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
27-
#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER)
2827

2928
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
3029
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \

components/hal/esp32h2/include/hal/timer_ll.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ extern "C" {
2424
// Get timer group register base address with giving group number
2525
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
2626
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
27-
#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER)
2827

2928
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
3029
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \

0 commit comments

Comments
 (0)