Skip to content

Commit 6f1c1c0

Browse files
committed
Merge branch 'bugfix/fix_light_sleep_time_error_when_wakup' into 'master'
esp8266: fix light sleep time error when waking up See merge request sdk/ESP8266_RTOS_SDK!1259
2 parents 6f7089b + f7389b7 commit 6f1c1c0

File tree

2 files changed

+131
-85
lines changed

2 files changed

+131
-85
lines changed

components/esp8266/include/driver/rtc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ uint32_t rtc_light_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt);
109109
*
110110
* @return number of clock cycles
111111
*/
112-
uint32_t pm_usec2rtc(uint32_t time_in_us, uint32_t period);
112+
uint32_t us_to_rtc_clk(uint32_t time_in_us, uint32_t period);
113113

114114
/**
115115
* @brief Convert time interval from RTC_CLK to microseconds
@@ -119,7 +119,7 @@ uint32_t pm_usec2rtc(uint32_t time_in_us, uint32_t period);
119119
*
120120
* @return time interval in microseconds
121121
*/
122-
uint32_t pm_rtc2usec(uint32_t rtc_cycles, uint32_t period);
122+
uint32_t rtc_clk_to_us(uint32_t rtc_cycles, uint32_t period);
123123

124124
/**
125125
* @brief Get the calibration value of RTC clock

components/esp8266/source/esp_sleep.c

Lines changed: 129 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
#define FRC2_TICKS_PER_US (5)
4040
#define FRC2_TICKS_MAX (UINT32_MAX / 4)
4141

42-
#define SLEEP_PROC_TIME (3072)
42+
#define SLEEP_PROC_TIME (2735)
4343
#define WAKEUP_EARLY_TICKS (264) // PLL and STAL wait ticks
4444
#define MIN_SLEEP_US (6500)
4545
#define RTC_TICK_CAL (100)
@@ -61,6 +61,14 @@ typedef struct pm_soc_clk {
6161
uint32_t sleep_us;
6262
} pm_soc_clk_t;
6363

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+
6472
static uint16_t s_lock_cnt = 1;
6573
static esp_sleep_mode_t s_sleep_mode = ESP_CPU_WAIT;
6674
static uint32_t s_sleep_wakup_triggers;
@@ -82,6 +90,16 @@ static inline void restore_local_wdev(uint32_t reg)
8290
REG_WRITE(INT_ENA_WDEV, reg);
8391
}
8492

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+
85103
static inline void save_soc_clk(pm_soc_clk_t *clk)
86104
{
87105
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)
120138

121139
clk->cal_period = pm_rtc_clock_cali_proc();
122140

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);
124142

125143
return rtc_ticks;
126144
}
@@ -129,18 +147,24 @@ static inline void update_soc_clk(pm_soc_clk_t *clk)
129147
{
130148
extern uint32_t WdevTimOffSet;
131149

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;
139151

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 {
141166
slept_us = clk->sleep_us;
142-
else
143-
slept_us -= RTC_TICK_CAL;
167+
}
144168

145169
const uint32_t os_ccount = slept_us * g_esp_ticks_per_us + clk->ccount;
146170

@@ -196,16 +220,6 @@ static int cpu_reject_sleep(void)
196220
return ret;
197221
}
198222

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-
209223
rtc_cpu_freq_t rtc_clk_cpu_freq_get(void)
210224
{
211225
rtc_cpu_freq_t freq;
@@ -232,7 +246,7 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint32_t time_in_us)
232246
if (time_in_us <= MIN_SLEEP_US)
233247
return ESP_ERR_INVALID_ARG;
234248

235-
s_sleep_duration = time_in_us - SLEEP_PROC_TIME;
249+
s_sleep_duration = time_in_us;
236250
s_sleep_wakup_triggers |= RTC_TIMER_TRIG_EN;
237251

238252
return ESP_OK;
@@ -265,35 +279,104 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
265279
return ESP_OK;
266280
}
267281

268-
esp_err_t esp_light_sleep_start(void)
282+
static int esp_light_sleep_internal(const sleep_proc_t *proc)
269283
{
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+
}
275299

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+
}
278305

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+
}
283310

284-
rtc_clk_cpu_freq_set(cpu_freq);
311+
irqflag = soc_save_local_irq();
312+
wdevflag = save_local_wdev();
285313

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()) {
288320
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;
289335
}
290336

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:
291359
restore_local_wdev(wdevflag);
292360
soc_restore_local_irq(irqflag);
293361

362+
if (cpu_wait)
363+
soc_wait_int();
364+
294365
return ret;
295366
}
296367

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+
297380
void esp_sleep_lock(void)
298381
{
299382
const esp_irqflag_t irqflag = soc_save_local_irq();
@@ -315,49 +398,12 @@ void esp_sleep_set_mode(esp_sleep_mode_t mode)
315398

316399
void esp_sleep_start(void)
317400
{
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);
363409
}

0 commit comments

Comments
 (0)