fix(esp8266): fix system and wifi sleep/wake process error

This commit is contained in:
dongheng
2019-09-18 17:03:08 +08:00
parent 6f3983d39e
commit 4d4e1c0564
12 changed files with 91 additions and 28 deletions

View File

@ -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

View File

@ -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))

View File

@ -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

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

BIN
components/esp8266/lib/librtc.a Executable file → Normal file

Binary file not shown.

View File

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

View File

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

View File

@ -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