39
39
#define FRC2_TICKS_PER_US (5)
40
40
#define FRC2_TICKS_MAX (UINT32_MAX / 4)
41
41
42
- #define SLEEP_PROC_TIME (3072 )
42
+ #define SLEEP_PROC_TIME (2735 )
43
43
#define WAKEUP_EARLY_TICKS (264) // PLL and STAL wait ticks
44
44
#define MIN_SLEEP_US (6500)
45
45
#define RTC_TICK_CAL (100)
@@ -61,6 +61,14 @@ typedef struct pm_soc_clk {
61
61
uint32_t sleep_us ;
62
62
} pm_soc_clk_t ;
63
63
64
+ typedef struct sleep_proc {
65
+ uint32_t sleep_us ; // sleep microsecond
66
+
67
+ uint32_t wait_int : 1 ; // wait interrupt
68
+ uint32_t check_mode : 1 ; // check sleep mode
69
+ uint32_t flush_uart : 1 ; // flush UART
70
+ } sleep_proc_t ;
71
+
64
72
static uint16_t s_lock_cnt = 1 ;
65
73
static esp_sleep_mode_t s_sleep_mode = ESP_CPU_WAIT ;
66
74
static uint32_t s_sleep_wakup_triggers ;
@@ -82,6 +90,16 @@ static inline void restore_local_wdev(uint32_t reg)
82
90
REG_WRITE (INT_ENA_WDEV , reg );
83
91
}
84
92
93
+ uint32_t rtc_clk_to_us (uint32_t rtc_cycles , uint32_t period )
94
+ {
95
+ return (uint64_t )rtc_cycles * period / 4096 ;
96
+ }
97
+
98
+ uint32_t rtc_us_to_clk (uint32_t us , uint32_t period )
99
+ {
100
+ return (uint64_t )us * 4096 / period ;
101
+ }
102
+
85
103
static inline void save_soc_clk (pm_soc_clk_t * clk )
86
104
{
87
105
clk -> rtc_val = REG_READ (RTC_SLP_CNT_VAL );
@@ -120,7 +138,7 @@ static inline uint32_t sleep_rtc_ticks(pm_soc_clk_t *clk)
120
138
121
139
clk -> cal_period = pm_rtc_clock_cali_proc ();
122
140
123
- rtc_ticks = pm_usec2rtc (clk -> sleep_us - SLEEP_PROC_TIME , clk -> cal_period );
141
+ rtc_ticks = rtc_us_to_clk (clk -> sleep_us - SLEEP_PROC_TIME , clk -> cal_period );
124
142
125
143
return rtc_ticks ;
126
144
}
@@ -129,18 +147,24 @@ static inline void update_soc_clk(pm_soc_clk_t *clk)
129
147
{
130
148
extern uint32_t WdevTimOffSet ;
131
149
132
- uint32_t slept_us , total_rtc , end_rtc = REG_READ (RTC_SLP_CNT_VAL );
133
-
134
- if (end_rtc > clk -> rtc_val )
135
- total_rtc = end_rtc - clk -> rtc_val ;
136
- else
137
- total_rtc = UINT32_MAX - clk -> rtc_val + end_rtc ;
138
- slept_us = pm_rtc2usec (total_rtc , clk -> cal_period ) + RTC_TICK_OFF ;
150
+ uint32_t slept_us ;
139
151
140
- if (slept_us > clk -> sleep_us )
152
+ if (s_sleep_wakup_triggers & RTC_GPIO_TRIG_EN ) {
153
+ uint32_t total_rtc = 0 , end_rtc = REG_READ (RTC_SLP_CNT_VAL );
154
+
155
+ if (end_rtc > clk -> rtc_val )
156
+ total_rtc = end_rtc - clk -> rtc_val ;
157
+ else
158
+ total_rtc = UINT32_MAX - clk -> rtc_val + end_rtc ;
159
+ slept_us = rtc_clk_to_us (total_rtc , clk -> cal_period ) + RTC_TICK_OFF ;
160
+
161
+ if (slept_us >= clk -> sleep_us )
162
+ slept_us = clk -> sleep_us ;
163
+ else
164
+ slept_us -= RTC_TICK_CAL ;
165
+ } else {
141
166
slept_us = clk -> sleep_us ;
142
- else
143
- slept_us -= RTC_TICK_CAL ;
167
+ }
144
168
145
169
const uint32_t os_ccount = slept_us * g_esp_ticks_per_us + clk -> ccount ;
146
170
@@ -196,16 +220,6 @@ static int cpu_reject_sleep(void)
196
220
return ret ;
197
221
}
198
222
199
- void esp_wifi_hw_open (void )
200
- {
201
- phy_open_rf ();
202
- }
203
-
204
- void esp_wifi_hw_close (void )
205
- {
206
- phy_close_rf ();
207
- }
208
-
209
223
rtc_cpu_freq_t rtc_clk_cpu_freq_get (void )
210
224
{
211
225
rtc_cpu_freq_t freq ;
@@ -232,7 +246,7 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint32_t time_in_us)
232
246
if (time_in_us <= MIN_SLEEP_US )
233
247
return ESP_ERR_INVALID_ARG ;
234
248
235
- s_sleep_duration = time_in_us - SLEEP_PROC_TIME ;
249
+ s_sleep_duration = time_in_us ;
236
250
s_sleep_wakup_triggers |= RTC_TIMER_TRIG_EN ;
237
251
238
252
return ESP_OK ;
@@ -265,35 +279,104 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
265
279
return ESP_OK ;
266
280
}
267
281
268
- esp_err_t esp_light_sleep_start ( void )
282
+ static int esp_light_sleep_internal ( const sleep_proc_t * proc )
269
283
{
270
- esp_err_t ret ;
271
- esp_irqflag_t irqflag = soc_save_local_irq ();
272
- uint32_t wdevflag = save_local_wdev ();
273
- uint32_t period = pm_rtc_clock_cali_proc ();
274
- const uint32_t rtc_ticks = pm_usec2rtc (s_sleep_duration , period );
284
+ pm_soc_clk_t clk ;
285
+ esp_irqflag_t irqflag ;
286
+ uint32_t wdevflag ;
287
+ uint32_t sleep_us ;
288
+ uint64_t start_us ;
289
+ int ret = ESP_OK ;
290
+ int cpu_wait = proc -> wait_int ;
291
+
292
+ start_us = esp_timer_get_time ();
293
+
294
+ if (proc -> check_mode && cpu_is_wait_mode ()) {
295
+ if (proc -> wait_int )
296
+ soc_wait_int ();
297
+ return ESP_ERR_INVALID_ARG ;
298
+ }
275
299
276
- if (rtc_ticks > WAKEUP_EARLY_TICKS + 1 ) {
277
- const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get ();
300
+ if (cpu_reject_sleep ()) {
301
+ if (proc -> wait_int )
302
+ soc_wait_int ();
303
+ return ESP_ERR_INVALID_STATE ;
304
+ }
278
305
279
- pm_set_sleep_mode ( 2 );
280
- pm_set_sleep_cycles ( rtc_ticks - WAKEUP_EARLY_TICKS );
281
- rtc_light_sleep_start ( s_sleep_wakup_triggers , 0 );
282
- rtc_wakeup_init ();
306
+ if ( proc -> flush_uart ) {
307
+ uart_tx_wait_idle ( 0 );
308
+ uart_tx_wait_idle ( 1 );
309
+ }
283
310
284
- rtc_clk_cpu_freq_set (cpu_freq );
311
+ irqflag = soc_save_local_irq ();
312
+ wdevflag = save_local_wdev ();
285
313
286
- ret = ESP_OK ;
287
- } else {
314
+ if (proc -> check_mode && cpu_is_wait_mode ()) {
315
+ ret = ESP_ERR_INVALID_ARG ;
316
+ goto exit ;
317
+ }
318
+
319
+ if (cpu_reject_sleep ()) {
288
320
ret = ESP_ERR_INVALID_STATE ;
321
+ goto exit ;
322
+ }
323
+
324
+ save_soc_clk (& clk );
325
+ if (!proc -> sleep_us )
326
+ sleep_us = min_sleep_us (& clk );
327
+ else {
328
+ uint64_t total_us = esp_timer_get_time () - start_us ;
329
+
330
+ if (total_us >= proc -> sleep_us ) {
331
+ ret = ESP_ERR_INVALID_ARG ;
332
+ goto exit ;
333
+ } else
334
+ sleep_us = clk .sleep_us = proc -> sleep_us - total_us ;
289
335
}
290
336
337
+ if (sleep_us > MIN_SLEEP_US ) {
338
+ uint32_t rtc_ticks = sleep_rtc_ticks (& clk );
339
+
340
+ if (rtc_ticks > WAKEUP_EARLY_TICKS + 1 ) {
341
+ rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get ();
342
+
343
+ pm_set_sleep_mode (2 );
344
+ pm_set_sleep_cycles (rtc_ticks - WAKEUP_EARLY_TICKS );
345
+ rtc_light_sleep_start (s_sleep_wakup_triggers | RTC_TIMER_TRIG_EN , 0 );
346
+ rtc_wakeup_init ();
347
+
348
+ rtc_clk_cpu_freq_set (cpu_freq );
349
+
350
+ update_soc_clk (& clk );
351
+
352
+ cpu_wait = 0 ;
353
+ } else
354
+ ret = ESP_ERR_INVALID_ARG ;
355
+ } else
356
+ ret = ESP_ERR_INVALID_ARG ;
357
+
358
+ exit :
291
359
restore_local_wdev (wdevflag );
292
360
soc_restore_local_irq (irqflag );
293
361
362
+ if (cpu_wait )
363
+ soc_wait_int ();
364
+
294
365
return ret ;
295
366
}
296
367
368
+ esp_err_t esp_light_sleep_start (void )
369
+ {
370
+ const sleep_proc_t proc = {
371
+ .sleep_us = s_sleep_duration ,
372
+ .wait_int = 0 ,
373
+ .check_mode = 0 ,
374
+ .flush_uart = 1
375
+ };
376
+
377
+ return esp_light_sleep_internal (& proc );
378
+ }
379
+
297
380
void esp_sleep_lock (void )
298
381
{
299
382
const esp_irqflag_t irqflag = soc_save_local_irq ();
@@ -315,49 +398,12 @@ void esp_sleep_set_mode(esp_sleep_mode_t mode)
315
398
316
399
void esp_sleep_start (void )
317
400
{
318
- if (cpu_is_wait_mode () || cpu_reject_sleep ()) {
319
- soc_wait_int ();
320
- return ;
321
- }
322
-
323
- uart_tx_wait_idle (0 );
324
- uart_tx_wait_idle (1 );
325
-
326
- int cpu_wait = 1 ;
327
- pm_soc_clk_t clk ;
328
- const esp_irqflag_t irqflag = soc_save_local_irq ();
329
- const uint32_t wdevflag = save_local_wdev ();
330
-
331
- if (cpu_is_wait_mode () || cpu_reject_sleep ()) {
332
- cpu_wait = 0 ;
333
- goto exit ;
334
- }
335
-
336
- save_soc_clk (& clk );
337
-
338
- const uint32_t sleep_us = min_sleep_us (& clk );
339
- if (sleep_us > MIN_SLEEP_US ) {
340
- uint32_t rtc_ticks = sleep_rtc_ticks (& clk );
341
- if (rtc_ticks > WAKEUP_EARLY_TICKS + 1 ) {
342
- const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get ();
343
-
344
- pm_set_sleep_mode (2 );
345
- pm_set_sleep_cycles (rtc_ticks - WAKEUP_EARLY_TICKS );
346
- rtc_light_sleep_start (s_sleep_wakup_triggers | RTC_TIMER_TRIG_EN , 0 );
347
- rtc_wakeup_init ();
348
-
349
- rtc_clk_cpu_freq_set (cpu_freq );
350
-
351
- update_soc_clk (& clk );
352
-
353
- cpu_wait = 0 ;
354
- }
355
- }
356
-
357
- exit :
358
- restore_local_wdev (wdevflag );
359
- soc_restore_local_irq (irqflag );
360
-
361
- if (cpu_wait )
362
- soc_wait_int ();
401
+ const sleep_proc_t proc = {
402
+ .sleep_us = 0 ,
403
+ .wait_int = 1 ,
404
+ .check_mode = 1 ,
405
+ .flush_uart = 1 ,
406
+ };
407
+
408
+ esp_light_sleep_internal (& proc );
363
409
}
0 commit comments