21
21
#include "FreeRTOS.h"
22
22
#include "freertos/task.h"
23
23
#include "driver/soc.h"
24
+ #include "driver/gpio.h"
24
25
#include "esp8266/timer_struct.h"
26
+ #include "esp8266/gpio_struct.h"
25
27
#include "esp8266/rom_functions.h"
26
28
#include "driver/rtc.h"
27
29
#include "rom/uart.h"
37
39
#define FRC2_TICKS_PER_US (5)
38
40
#define FRC2_TICKS_MAX (UINT32_MAX / 4)
39
41
40
- #define SLEEP_MIN_TIME (1000)
41
- #define SLEEP_PROC_TIME (4450)
42
+ #define SLEEP_PROC_TIME (3072)
42
43
#define WAKEUP_EARLY_TICKS (264) // PLL and STAL wait ticks
43
- #define MIN_SLEEP_US (SLEEP_MIN_TIME + SLEEP_PROC_TIME)
44
+ #define MIN_SLEEP_US (6500)
45
+ #define RTC_TICK_CAL (100)
46
+ #define RTC_TICK_OFF (1245 + RTC_TICK_CAL)
44
47
45
48
#define TAG "esp8266_pm"
46
49
@@ -51,6 +54,11 @@ typedef struct pm_soc_clk {
51
54
uint32_t frc2_cnt ;
52
55
53
56
uint32_t wdev_cnt ;
57
+
58
+ uint32_t rtc_val ;
59
+ uint32_t cal_period ;
60
+
61
+ uint32_t sleep_us ;
54
62
} pm_soc_clk_t ;
55
63
56
64
static uint16_t s_lock_cnt = 1 ;
@@ -76,6 +84,8 @@ static inline void restore_local_wdev(uint32_t reg)
76
84
77
85
static inline void save_soc_clk (pm_soc_clk_t * clk )
78
86
{
87
+ clk -> rtc_val = REG_READ (RTC_SLP_CNT_VAL );
88
+
79
89
clk -> ccount = soc_get_ccount ();
80
90
81
91
clk -> frc2_enable = REG_READ (FRC2_CTL ) & FRC2_CNTL_ENABLE ;
@@ -96,24 +106,50 @@ static inline uint32_t min_sleep_us(pm_soc_clk_t *clk)
96
106
const uint32_t frc2_sleep_ticks = REG_READ (FRC2_ALARM ) - clk -> frc2_cnt ;
97
107
const uint32_t frc2_sleep_us = frc2_sleep_ticks < FRC2_TICKS_MAX ? frc2_sleep_ticks / FRC2_TICKS_PER_US : 0 ;
98
108
99
- return MIN (ccompare_sleep_us , frc2_sleep_us );
109
+ clk -> sleep_us = MIN (ccompare_sleep_us , frc2_sleep_us );
100
110
} else {
101
- return ccompare_sleep_us ;
111
+ clk -> sleep_us = ccompare_sleep_us ;
102
112
}
113
+
114
+ return clk -> sleep_us ;
115
+ }
116
+
117
+ static inline uint32_t sleep_rtc_ticks (pm_soc_clk_t * clk )
118
+ {
119
+ uint32_t rtc_ticks ;
120
+
121
+ clk -> cal_period = pm_rtc_clock_cali_proc ();
122
+
123
+ rtc_ticks = pm_usec2rtc (clk -> sleep_us - SLEEP_PROC_TIME , clk -> cal_period );
124
+
125
+ return rtc_ticks ;
103
126
}
104
127
105
- static inline void update_soc_clk (pm_soc_clk_t * clk , uint32_t us )
128
+ static inline void update_soc_clk (pm_soc_clk_t * clk )
106
129
{
107
130
extern uint32_t WdevTimOffSet ;
108
131
109
- const uint32_t os_ccount = us * g_esp_ticks_per_us + clk -> ccount ;
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 ;
139
+
140
+ if (slept_us > clk -> sleep_us )
141
+ slept_us = clk -> sleep_us ;
142
+ else
143
+ slept_us -= RTC_TICK_CAL ;
144
+
145
+ const uint32_t os_ccount = slept_us * g_esp_ticks_per_us + clk -> ccount ;
110
146
111
147
if (os_ccount >= _xt_tick_divisor )
112
148
soc_set_ccompare (os_ccount + 32 );
113
149
soc_set_ccount (os_ccount );
114
150
115
151
if (clk -> frc2_enable ) {
116
- const uint32_t frc2_cnt = us * FRC2_TICKS_PER_US + clk -> frc2_cnt - 1 ;
152
+ const uint32_t frc2_cnt = slept_us * FRC2_TICKS_PER_US + clk -> frc2_cnt - 1 ;
117
153
118
154
REG_WRITE (FRC2_LOAD , frc2_cnt );
119
155
}
@@ -122,9 +158,9 @@ static inline void update_soc_clk(pm_soc_clk_t *clk, uint32_t us)
122
158
uint32_t wdev_cnt = REG_READ (WDEV_COUNT_REG );
123
159
124
160
if (clk -> wdev_cnt < wdev_cnt )
125
- wdev_us = us - (wdev_cnt - clk -> wdev_cnt );
161
+ wdev_us = slept_us - (wdev_cnt - clk -> wdev_cnt );
126
162
else
127
- wdev_us = us - (UINT32_MAX - clk -> wdev_cnt + wdev_cnt );
163
+ wdev_us = slept_us - (UINT32_MAX - clk -> wdev_cnt + wdev_cnt );
128
164
129
165
WdevTimOffSet += wdev_us ;
130
166
}
@@ -134,6 +170,32 @@ static int cpu_is_wait_mode(void)
134
170
return (s_sleep_mode == ESP_CPU_WAIT ) || s_lock_cnt ;
135
171
}
136
172
173
+ static int cpu_reject_sleep (void )
174
+ {
175
+ int ret = 0 ;
176
+
177
+ if (s_sleep_wakup_triggers & RTC_GPIO_TRIG_EN ) {
178
+ for (int gpio = 0 ; gpio < 16 ; gpio ++ ) {
179
+ if (!GPIO .pin [gpio ].wakeup_enable )
180
+ continue ;
181
+
182
+ if (GPIO .pin [gpio ].int_type == GPIO_INTR_LOW_LEVEL ) {
183
+ if (!((GPIO .in >> gpio ) & 1 )) {
184
+ ret = 1 ;
185
+ break ;
186
+ }
187
+ } else if (GPIO .pin [gpio ].int_type == GPIO_INTR_HIGH_LEVEL ) {
188
+ if ((GPIO .in >> gpio ) & 1 ) {
189
+ ret = 1 ;
190
+ break ;
191
+ }
192
+ }
193
+ }
194
+ }
195
+
196
+ return ret ;
197
+ }
198
+
137
199
void esp_wifi_hw_open (void )
138
200
{
139
201
phy_open_rf ();
@@ -209,13 +271,13 @@ esp_err_t esp_light_sleep_start(void)
209
271
esp_irqflag_t irqflag = soc_save_local_irq ();
210
272
uint32_t wdevflag = save_local_wdev ();
211
273
uint32_t period = pm_rtc_clock_cali_proc ();
212
- const uint32_t sleep_rtc_ticks = pm_usec2rtc (s_sleep_duration , period );
274
+ const uint32_t rtc_ticks = pm_usec2rtc (s_sleep_duration , period );
213
275
214
- if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1 ) {
276
+ if (rtc_ticks > WAKEUP_EARLY_TICKS + 1 ) {
215
277
const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get ();
216
278
217
- rtc_lightsleep_init ( );
218
- pm_set_sleep_cycles (sleep_rtc_ticks - WAKEUP_EARLY_TICKS );
279
+ pm_set_sleep_mode ( 2 );
280
+ pm_set_sleep_cycles (rtc_ticks - WAKEUP_EARLY_TICKS );
219
281
rtc_light_sleep_start (s_sleep_wakup_triggers , 0 );
220
282
rtc_wakeup_init ();
221
283
@@ -253,7 +315,7 @@ void esp_sleep_set_mode(esp_sleep_mode_t mode)
253
315
254
316
void esp_sleep_start (void )
255
317
{
256
- if (cpu_is_wait_mode ()) {
318
+ if (cpu_is_wait_mode () || cpu_reject_sleep () ) {
257
319
soc_wait_int ();
258
320
return ;
259
321
}
@@ -266,7 +328,7 @@ void esp_sleep_start(void)
266
328
const esp_irqflag_t irqflag = soc_save_local_irq ();
267
329
const uint32_t wdevflag = save_local_wdev ();
268
330
269
- if (cpu_is_wait_mode ()) {
331
+ if (cpu_is_wait_mode () || cpu_reject_sleep () ) {
270
332
cpu_wait = 0 ;
271
333
goto exit ;
272
334
}
@@ -275,20 +337,18 @@ void esp_sleep_start(void)
275
337
276
338
const uint32_t sleep_us = min_sleep_us (& clk );
277
339
if (sleep_us > MIN_SLEEP_US ) {
278
- uint32_t period = pm_rtc_clock_cali_proc ();
279
- const uint32_t sleep_rtc_ticks = pm_usec2rtc (sleep_us - SLEEP_PROC_TIME , period );
280
-
281
- if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1 ) {
340
+ uint32_t rtc_ticks = sleep_rtc_ticks (& clk );
341
+ if (rtc_ticks > WAKEUP_EARLY_TICKS + 1 ) {
282
342
const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get ();
283
-
284
- rtc_lightsleep_init ( );
285
- pm_set_sleep_cycles (sleep_rtc_ticks - WAKEUP_EARLY_TICKS );
343
+
344
+ pm_set_sleep_mode ( 2 );
345
+ pm_set_sleep_cycles (rtc_ticks - WAKEUP_EARLY_TICKS );
286
346
rtc_light_sleep_start (s_sleep_wakup_triggers | RTC_TIMER_TRIG_EN , 0 );
287
347
rtc_wakeup_init ();
288
348
289
349
rtc_clk_cpu_freq_set (cpu_freq );
290
350
291
- update_soc_clk (& clk , sleep_us );
351
+ update_soc_clk (& clk );
292
352
293
353
cpu_wait = 0 ;
294
354
}
0 commit comments