@@ -25,6 +25,31 @@ static const char *TAG = "gptimer";
2525
2626static void gptimer_default_isr (void * args );
2727
28+ #if GPTIMER_USE_RETENTION_LINK
29+ static esp_err_t gptimer_create_sleep_retention_link_cb (void * timer )
30+ {
31+ int group_id = ((gptimer_t * )timer )-> group -> group_id ;
32+ int timer_id = ((gptimer_t * )timer )-> timer_id ;
33+ esp_err_t err = sleep_retention_entries_create (tg_timer_reg_retention_info [group_id ][timer_id ].regdma_entry_array ,
34+ tg_timer_reg_retention_info [group_id ][timer_id ].array_size ,
35+ REGDMA_LINK_PRI_GPTIMER , tg_timer_reg_retention_info [group_id ][timer_id ].module );
36+ return err ;
37+ }
38+
39+ static void gptimer_create_retention_module (gptimer_t * timer )
40+ {
41+ int group_id = timer -> group -> group_id ;
42+ int timer_id = timer -> timer_id ;
43+ sleep_retention_module_t module = tg_timer_reg_retention_info [group_id ][timer_id ].module ;
44+ if (sleep_retention_is_module_inited (module ) && !sleep_retention_is_module_created (module )) {
45+ if (sleep_retention_module_allocate (module ) != ESP_OK ) {
46+ // even though the sleep retention module create failed, GPTimer driver should still work, so just warning here
47+ ESP_LOGW (TAG , "create retention link failed on TimerGroup%d Timer%d, power domain won't be turned off during sleep" , group_id , timer_id );
48+ }
49+ }
50+ }
51+ #endif // GPTIMER_USE_RETENTION_LINK
52+
2853static esp_err_t gptimer_register_to_group (gptimer_t * timer )
2954{
3055 gptimer_group_t * group = NULL ;
@@ -51,6 +76,24 @@ static esp_err_t gptimer_register_to_group(gptimer_t *timer)
5176 }
5277 }
5378 ESP_RETURN_ON_FALSE (timer_id != -1 , ESP_ERR_NOT_FOUND , TAG , "no free timer" );
79+
80+ #if GPTIMER_USE_RETENTION_LINK
81+ sleep_retention_module_t module = tg_timer_reg_retention_info [group -> group_id ][timer_id ].module ;
82+ sleep_retention_module_init_param_t init_param = {
83+ .cbs = {
84+ .create = {
85+ .handle = gptimer_create_sleep_retention_link_cb ,
86+ .arg = (void * )timer
87+ },
88+ },
89+ .depends = RETENTION_MODULE_BITMAP_INIT (CLOCK_SYSTEM )
90+ };
91+ if (sleep_retention_module_init (module , & init_param ) != ESP_OK ) {
92+ // even though the sleep retention module init failed, RMT driver should still work, so just warning here
93+ ESP_LOGW (TAG , "init sleep retention failed on TimerGroup%d Timer%d, power domain may be turned off during sleep" , group -> group_id , timer_id );
94+ }
95+ #endif // GPTIMER_USE_RETENTION_LINK
96+
5497 return ESP_OK ;
5598}
5699
@@ -61,6 +104,17 @@ static void gptimer_unregister_from_group(gptimer_t *timer)
61104 portENTER_CRITICAL (& group -> spinlock );
62105 group -> timers [timer_id ] = NULL ;
63106 portEXIT_CRITICAL (& group -> spinlock );
107+
108+ #if GPTIMER_USE_RETENTION_LINK
109+ sleep_retention_module_t module = tg_timer_reg_retention_info [group -> group_id ][timer_id ].module ;
110+ if (sleep_retention_is_module_created (module )) {
111+ sleep_retention_module_free (module );
112+ }
113+ if (sleep_retention_is_module_inited (module )) {
114+ sleep_retention_module_deinit (module );
115+ }
116+ #endif
117+
64118 // timer has a reference on group, release it now
65119 gptimer_release_group_handle (group );
66120}
@@ -109,7 +163,7 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
109163
110164 if (allow_pd ) {
111165#if GPTIMER_USE_RETENTION_LINK
112- gptimer_create_retention_module (group );
166+ gptimer_create_retention_module (timer );
113167#endif // GPTIMER_USE_RETENTION_LINK
114168 }
115169
0 commit comments