mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-22 01:27:11 +08:00
fix(esp8266): fix system and wifi sleep/wake process error
This commit is contained in:
@ -35,10 +35,30 @@ typedef enum {
|
|||||||
RTC_CPU_FREQ_160M = 1, //!< 160 MHz
|
RTC_CPU_FREQ_160M = 1, //!< 160 MHz
|
||||||
} rtc_cpu_freq_t;
|
} rtc_cpu_freq_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open RF hardware
|
||||||
|
*/
|
||||||
|
void phy_open_rf(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close RF hardware
|
||||||
|
*/
|
||||||
|
void phy_close_rf(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize RTC hardware
|
* @brief Initialize RTC hardware
|
||||||
*/
|
*/
|
||||||
void rtc_clk_init(void);
|
void rtc_init_2(uint8_t *init_param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize light sleep hardware
|
||||||
|
*/
|
||||||
|
void rtc_lightsleep_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize hardware when CPU wakes up from light sleep
|
||||||
|
*/
|
||||||
|
void rtc_wakeup_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the currently used CPU frequency configuration
|
* @brief Get the currently used CPU frequency configuration
|
||||||
@ -66,8 +86,6 @@ void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq);
|
|||||||
*
|
*
|
||||||
* @note CPU wakeup has 2672 ms time cost, so the real sleeping time is to_sleep_time_in_us - 2672
|
* @note CPU wakeup has 2672 ms time cost, so the real sleeping time is to_sleep_time_in_us - 2672
|
||||||
*
|
*
|
||||||
* @param rtc_ticks value of RTC counter at which wakeup from sleep will happen
|
|
||||||
*
|
|
||||||
* @param wakeup_opt bit mask wake up reasons to enable (RTC_xxx_TRIG_EN flags
|
* @param wakeup_opt bit mask wake up reasons to enable (RTC_xxx_TRIG_EN flags
|
||||||
* combined with OR)
|
* combined with OR)
|
||||||
* @param reject_opt bit mask of sleep reject reasons:
|
* @param reject_opt bit mask of sleep reject reasons:
|
||||||
@ -77,8 +95,7 @@ void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq);
|
|||||||
* an external host is communicating via SDIO slave
|
* an external host is communicating via SDIO slave
|
||||||
* @return non-zero if sleep was rejected by hardware
|
* @return non-zero if sleep was rejected by hardware
|
||||||
*/
|
*/
|
||||||
uint32_t rtc_light_sleep_start(uint32_t rtc_ticks, uint32_t wakeup_opt, uint32_t reject_opt);
|
uint32_t rtc_light_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert time interval from microseconds to RTC_CLK cycles
|
* @brief Convert time interval from microseconds to RTC_CLK cycles
|
||||||
*
|
*
|
||||||
@ -87,7 +104,7 @@ uint32_t rtc_light_sleep_start(uint32_t rtc_ticks, uint32_t wakeup_opt, uint32_t
|
|||||||
*
|
*
|
||||||
* @return number of clock cycles
|
* @return number of clock cycles
|
||||||
*/
|
*/
|
||||||
uint32_t rtc_time_us_to_clk(uint32_t time_in_us, uint32_t period);
|
uint32_t pm_usec2rtc(uint32_t time_in_us, uint32_t period);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert time interval from RTC_CLK to microseconds
|
* @brief Convert time interval from RTC_CLK to microseconds
|
||||||
@ -97,16 +114,21 @@ uint32_t rtc_time_us_to_clk(uint32_t time_in_us, uint32_t period);
|
|||||||
*
|
*
|
||||||
* @return time interval in microseconds
|
* @return time interval in microseconds
|
||||||
*/
|
*/
|
||||||
uint32_t rtc_time_clk_to_us(uint32_t rtc_cycles, uint32_t period);
|
uint32_t pm_rtc2usec(uint32_t rtc_cycles, uint32_t period);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the calibration value of RTC clock
|
* @brief Get the calibration value of RTC clock
|
||||||
*
|
|
||||||
* @param xtal_freq XTAL frequency, unit is MHz
|
|
||||||
*
|
*
|
||||||
* @return the calibration value
|
* @return the calibration value
|
||||||
*/
|
*/
|
||||||
uint32_t esp_clk_cal_get(uint32_t xtal_freq);
|
uint32_t pm_rtc_clock_cali_proc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure CPU sleep time by RTC clock ticks
|
||||||
|
*
|
||||||
|
* @param rtc_cycles Time interval in RTC_CLK cycles
|
||||||
|
*/
|
||||||
|
void pm_set_sleep_cycles(uint32_t rtc_cycles);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get current value of RTC counter
|
* @brief Get current value of RTC counter
|
||||||
|
@ -137,6 +137,9 @@
|
|||||||
#define TM1_EDGE_INT_DISABLE() CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1)
|
#define TM1_EDGE_INT_DISABLE() CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1)
|
||||||
//}}
|
//}}
|
||||||
|
|
||||||
|
#define DPORT_CTL_REG (PERIPHS_DPORT_BASEADDR + 0x14)
|
||||||
|
#define DPORT_CTL_DOUBLE_CLK BIT0
|
||||||
|
|
||||||
#define INT_ENA_WDEV 0x3ff20c18
|
#define INT_ENA_WDEV 0x3ff20c18
|
||||||
#define WDEV_TSF0_REACH_INT (BIT(27))
|
#define WDEV_TSF0_REACH_INT (BIT(27))
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
gwen:
|
gwen:
|
||||||
core: 743c778
|
core: 743c778
|
||||||
net80211: da5ae93
|
net80211: da5ae93
|
||||||
pp: 6a32b9b
|
pp: 2c0db4c
|
||||||
wpa: 743c778
|
wpa: 743c778
|
||||||
espnow: 743c778
|
espnow: 743c778
|
||||||
wps: 743c778
|
wps: 743c778
|
||||||
|
|
||||||
smartconfig: 2.8.2
|
smartconfig: 2.8.2
|
||||||
phy: 1149
|
phy: 1150.0
|
||||||
|
BIN
components/esp8266/lib/libclk.a
Normal file → Executable file
BIN
components/esp8266/lib/libclk.a
Normal file → Executable file
Binary file not shown.
Binary file not shown.
BIN
components/esp8266/lib/libpp.a
Executable file → Normal file
BIN
components/esp8266/lib/libpp.a
Executable file → Normal file
Binary file not shown.
BIN
components/esp8266/lib/libpp_dbg.a
Executable file → Normal file
BIN
components/esp8266/lib/libpp_dbg.a
Executable file → Normal file
Binary file not shown.
BIN
components/esp8266/lib/librtc.a
Executable file → Normal file
BIN
components/esp8266/lib/librtc.a
Executable file → Normal file
Binary file not shown.
@ -25,6 +25,7 @@
|
|||||||
#include "esp8266/rom_functions.h"
|
#include "esp8266/rom_functions.h"
|
||||||
#include "driver/rtc.h"
|
#include "driver/rtc.h"
|
||||||
#include "rom/uart.h"
|
#include "rom/uart.h"
|
||||||
|
#include "internal/phy_init_data.h"
|
||||||
|
|
||||||
#define FRC2_LOAD (0x60000620)
|
#define FRC2_LOAD (0x60000620)
|
||||||
#define FRC2_COUNT (0x60000624)
|
#define FRC2_COUNT (0x60000624)
|
||||||
@ -36,8 +37,10 @@
|
|||||||
#define FRC2_TICKS_PER_US (5)
|
#define FRC2_TICKS_PER_US (5)
|
||||||
#define FRC2_TICKS_MAX (UINT32_MAX / 4)
|
#define FRC2_TICKS_MAX (UINT32_MAX / 4)
|
||||||
|
|
||||||
#define MIN_SLEEP_US (3000)
|
#define SLEEP_MIN_TIME (1000)
|
||||||
#define WAKEUP_EARLY_TICKS (272) // about 2620ms
|
#define SLEEP_PROC_TIME (4450)
|
||||||
|
#define WAKEUP_EARLY_TICKS (264) // PLL and STAL wait ticks
|
||||||
|
#define MIN_SLEEP_US (SLEEP_MIN_TIME + SLEEP_PROC_TIME)
|
||||||
|
|
||||||
#define TAG "esp8266_pm"
|
#define TAG "esp8266_pm"
|
||||||
|
|
||||||
@ -113,12 +116,43 @@ static inline void update_soc_clk(pm_soc_clk_t *clk, uint32_t us)
|
|||||||
WdevTimOffSet += us;
|
WdevTimOffSet += us;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void esp_wifi_hw_open(void)
|
||||||
|
{
|
||||||
|
phy_open_rf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp_wifi_hw_close(void)
|
||||||
|
{
|
||||||
|
phy_close_rf();
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_cpu_freq_t rtc_clk_cpu_freq_get(void)
|
||||||
|
{
|
||||||
|
rtc_cpu_freq_t freq;
|
||||||
|
uint32_t reg = REG_READ(DPORT_CTL_REG);
|
||||||
|
|
||||||
|
if (reg & DPORT_CTL_DOUBLE_CLK)
|
||||||
|
freq = RTC_CPU_FREQ_160M;
|
||||||
|
else
|
||||||
|
freq = RTC_CPU_FREQ_80M;
|
||||||
|
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq)
|
||||||
|
{
|
||||||
|
if (RTC_CPU_FREQ_80M == cpu_freq)
|
||||||
|
REG_CLR_BIT(DPORT_CTL_REG, DPORT_CTL_DOUBLE_CLK);
|
||||||
|
else
|
||||||
|
REG_SET_BIT(DPORT_CTL_REG, DPORT_CTL_DOUBLE_CLK);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_sleep_enable_timer_wakeup(uint32_t time_in_us)
|
esp_err_t esp_sleep_enable_timer_wakeup(uint32_t time_in_us)
|
||||||
{
|
{
|
||||||
if (time_in_us <= MIN_SLEEP_US)
|
if (time_in_us <= MIN_SLEEP_US)
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
|
||||||
s_sleep_duration = time_in_us;
|
s_sleep_duration = time_in_us - SLEEP_PROC_TIME;
|
||||||
s_sleep_wakup_triggers |= RTC_TIMER_TRIG_EN;
|
s_sleep_wakup_triggers |= RTC_TIMER_TRIG_EN;
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@ -126,14 +160,16 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint32_t time_in_us)
|
|||||||
|
|
||||||
esp_err_t esp_light_sleep_start(void)
|
esp_err_t esp_light_sleep_start(void)
|
||||||
{
|
{
|
||||||
const uint32_t rtc_cal = esp_clk_cal_get(CRYSTAL_USED);
|
uint32_t period = pm_rtc_clock_cali_proc();
|
||||||
const uint32_t sleep_rtc_ticks = rtc_time_us_to_clk(s_sleep_duration, rtc_cal);
|
const uint32_t sleep_rtc_ticks = pm_usec2rtc(s_sleep_duration, period);
|
||||||
const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get();
|
const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get();
|
||||||
|
|
||||||
if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1) {
|
if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1) {
|
||||||
rtc_light_sleep_start(sleep_rtc_ticks - WAKEUP_EARLY_TICKS, s_sleep_wakup_triggers, 0);
|
rtc_lightsleep_init();
|
||||||
|
pm_set_sleep_cycles(sleep_rtc_ticks - WAKEUP_EARLY_TICKS);
|
||||||
|
rtc_light_sleep_start(s_sleep_wakup_triggers, 0);
|
||||||
|
rtc_wakeup_init();
|
||||||
|
|
||||||
rtc_clk_init();
|
|
||||||
rtc_clk_cpu_freq_set(cpu_freq);
|
rtc_clk_cpu_freq_set(cpu_freq);
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@ -180,15 +216,17 @@ void esp_sleep_start(void)
|
|||||||
|
|
||||||
const uint32_t sleep_us = min_sleep_us(&clk);
|
const uint32_t sleep_us = min_sleep_us(&clk);
|
||||||
if (sleep_us > MIN_SLEEP_US) {
|
if (sleep_us > MIN_SLEEP_US) {
|
||||||
const uint32_t rtc_cal = esp_clk_cal_get(CRYSTAL_USED);
|
uint32_t period = pm_rtc_clock_cali_proc();
|
||||||
const uint32_t sleep_rtc_ticks = rtc_time_us_to_clk(sleep_us, rtc_cal);
|
const uint32_t sleep_rtc_ticks = pm_usec2rtc(sleep_us - SLEEP_PROC_TIME, period);
|
||||||
|
|
||||||
if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1) {
|
if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1) {
|
||||||
const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get();
|
const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get();
|
||||||
|
|
||||||
rtc_light_sleep_start(sleep_rtc_ticks - WAKEUP_EARLY_TICKS, s_sleep_wakup_triggers | RTC_TIMER_TRIG_EN, 0);
|
rtc_lightsleep_init();
|
||||||
|
pm_set_sleep_cycles(sleep_rtc_ticks - WAKEUP_EARLY_TICKS);
|
||||||
|
rtc_light_sleep_start(s_sleep_wakup_triggers | RTC_TIMER_TRIG_EN, 0);
|
||||||
|
rtc_wakeup_init();
|
||||||
|
|
||||||
rtc_clk_init();
|
|
||||||
rtc_clk_cpu_freq_set(cpu_freq);
|
rtc_clk_cpu_freq_set(cpu_freq);
|
||||||
|
|
||||||
update_soc_clk(&clk, sleep_us);
|
update_soc_clk(&clk, sleep_us);
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include "internal/phy_init_data.h"
|
#include "internal/phy_init_data.h"
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
|
|
||||||
|
#include "driver/rtc.h"
|
||||||
|
|
||||||
static const char* TAG = "phy_init";
|
static const char* TAG = "phy_init";
|
||||||
|
|
||||||
static uint8_t phy_check_calibration_data(uint8_t* rf_cal_data)
|
static uint8_t phy_check_calibration_data(uint8_t* rf_cal_data)
|
||||||
@ -105,6 +107,8 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat
|
|||||||
uart_tx_wait_idle(1);
|
uart_tx_wait_idle(1);
|
||||||
uart_div_modify(1, UART_CLK_FREQ / uart_baudrate);
|
uart_div_modify(1, UART_CLK_FREQ / uart_baudrate);
|
||||||
|
|
||||||
|
rtc_init_2(local_init_data);
|
||||||
|
|
||||||
int ret = register_chipv6_phy(local_init_data);
|
int ret = register_chipv6_phy(local_init_data);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ESP_LOGI(TAG, "phy register error, ret:%d", ret);
|
ESP_LOGI(TAG, "phy register error, ret:%d", ret);
|
||||||
|
@ -390,13 +390,9 @@ BaseType_t xQueueGenericReceive(QueueHandle_t xQueue, void * const pvBuffer,
|
|||||||
|
|
||||||
void esp_internal_idle_hook(void)
|
void esp_internal_idle_hook(void)
|
||||||
{
|
{
|
||||||
extern void pmIdleHook(void);
|
|
||||||
extern void esp_task_wdt_reset(void);
|
|
||||||
|
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
pmIdleHook();
|
|
||||||
|
|
||||||
soc_wait_int();
|
esp_sleep_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DISABLE_FREERTOS
|
#ifndef DISABLE_FREERTOS
|
||||||
|
Binary file not shown.
Reference in New Issue
Block a user