xtensa/esp32: Get CPU frequency from the rtc register

This commit is contained in:
chenwen 2020-11-06 17:26:23 +08:00 committed by Alan Carvalho de Assis
parent 1847a67e05
commit 39322e1158
5 changed files with 156 additions and 8 deletions

View File

@ -98,6 +98,34 @@ static inline void esp32_uart_tx_wait_idle(uint8_t uart_no)
****************************************************************************/
extern uint32_t g_ticks_per_us_pro;
#ifdef CONFIG_SMP
extern uint32_t g_ticks_per_us_app;
#endif
/****************************************************************************
* Name: esp32_update_cpu_freq
*
* Description:
* Set the real CPU ticks per us to the ets, so that ets_delay_us
* will be accurate. Call this function when CPU frequency is changed.
*
* Input Parameters:
* ticks_per_us - CPU ticks per us
*
* Returned Value:
* None
*
****************************************************************************/
void IRAM_ATTR esp32_update_cpu_freq(uint32_t ticks_per_us)
{
/* Update scale factors used by esp_rom_delay_us */
g_ticks_per_us_pro = ticks_per_us;
#ifdef CONFIG_SMP
g_ticks_per_us_app = ticks_per_us;
#endif
}
/****************************************************************************
* Name: esp32_set_cpu_freq

View File

@ -46,6 +46,23 @@
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp32_update_cpu_freq
*
* Description:
* Set the real CPU ticks per us to the ets, so that ets_delay_us
* will be accurate. Call this function when CPU frequency is changed.
*
* Input Parameters:
* ticks_per_us - CPU ticks per us
*
* Returned Value:
* None
*
****************************************************************************/
void esp32_update_cpu_freq(uint32_t ticks_per_us);
/****************************************************************************
* Name: esp32_set_cpu_freq
*

View File

@ -562,7 +562,7 @@ static int IRAM_ATTR esp32_sleep_start(uint32_t pd_flags)
/* Save current frequency and switch to XTAL */
cur_freq = esp_clk_cpu_freq() / MHZ;
cur_freq = esp_rtc_clk_get_cpu_freq();
esp32_rtc_cpu_freq_set_xtal();
/* Enter sleep */
@ -851,6 +851,7 @@ void esp32_sleep_enable_timer_wakeup(uint64_t time_in_us)
int esp32_light_sleep_start(void)
{
irqstate_t flags;
uint32_t pd_flags;
uint32_t flash_enable_time_us;
#ifndef CONFIG_ESP32_SPIRAM
@ -859,6 +860,7 @@ int esp32_light_sleep_start(void)
struct rtc_vddsdio_config_s vddsdio_config;
int ret = OK;
flags = enter_critical_section();
s_config.rtc_ticks_at_sleep_start = esp32_rtc_time_get();
/* Decide which power domains can be powered down */
@ -896,7 +898,7 @@ int esp32_light_sleep_start(void)
ret = esp32_light_sleep_inner(pd_flags, flash_enable_time_us,
vddsdio_config);
leave_critical_section(flags);
return ret;
}

View File

@ -23,8 +23,10 @@
****************************************************************************/
#include <stdint.h>
#include <assert.h>
#include "esp32_rtc.h"
#include "esp32_clockconfig.h"
#include "hardware/esp32_rtccntl.h"
#include "hardware/esp32_dport.h"
#include "hardware/esp32_i2s.h"
@ -622,22 +624,23 @@ void IRAM_ATTR esp32_rtc_update_to_xtal(int freq, int div)
{
uint32_t value = (((freq * MHZ) >> 12) & UINT16_MAX)
| ((((freq * MHZ) >> 12) & UINT16_MAX) << 16);
putreg32(value, RTC_APB_FREQ_REG);
esp32_update_cpu_freq(freq);
/* set divider from XTAL to APB clock */
REG_SET_FIELD(APB_CTRL_SYSCLK_CONF_REG, APB_CTRL_PRE_DIV_CNT, div - 1);
/* switch clock source */
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL,
RTC_CNTL_SOC_CLK_SEL_XTL);
/* adjust ref_tick */
modifyreg32(APB_CTRL_XTAL_TICK_CONF_REG, 0,
(freq * MHZ) / REF_CLK_FREQ - 1);
/* switch clock source */
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL,
RTC_CNTL_SOC_CLK_SEL_XTL);
putreg32(value, RTC_APB_FREQ_REG);
/* lower the voltage */
if (freq <= 2)
@ -1152,6 +1155,77 @@ void IRAM_ATTR esp32_rtc_cpu_freq_set_xtal(void)
esp32_rtc_bbpll_disable();
}
/****************************************************************************
* Name: esp_rtc_clk_get_cpu_freq
*
* Description:
* Get the currently used CPU frequency configuration.
*
* Input Parameters:
* None
*
* Returned Value:
* CPU frequency
*
****************************************************************************/
int IRAM_ATTR esp_rtc_clk_get_cpu_freq(void)
{
uint32_t source_freq_mhz;
uint32_t div;
uint32_t soc_clk_sel;
uint32_t cpuperiod_sel;
int freq_mhz = 0;
soc_clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL);
switch (soc_clk_sel)
{
case RTC_CNTL_SOC_CLK_SEL_XTL:
{
div = REG_GET_FIELD(APB_CTRL_SYSCLK_CONF_REG,
APB_CTRL_PRE_DIV_CNT) + 1;
source_freq_mhz = (uint32_t) esp32_rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div;
}
break;
case RTC_CNTL_SOC_CLK_SEL_PLL:
{
cpuperiod_sel = REG_GET_FIELD(DPORT_CPU_PER_CONF_REG,
DPORT_CPUPERIOD_SEL);
if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80)
{
freq_mhz = 80;
}
else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160)
{
freq_mhz = 160;
}
else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_240)
{
freq_mhz = 240;
}
else
{
DEBUGASSERT(0);
}
}
break;
case RTC_CNTL_SOC_CLK_SEL_8M:
{
freq_mhz = 8;
}
break;
case RTC_CNTL_SOC_CLK_SEL_APLL:
default:
DEBUGASSERT(0);
}
return freq_mhz;
}
/****************************************************************************
* Name: esp32_rtc_sleep_init
*
@ -1327,6 +1401,17 @@ void IRAM_ATTR esp32_rtc_sleep_init(uint32_t flags)
modifyreg32(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU, 0);
}
/* Keep the RTC8M_CLK on in light_sleep mode if the
* ledc low-speed channel is clocked by RTC8M_CLK.
*/
if (!cfg.deep_slp && GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG,
RTC_CNTL_DIG_CLK8M_EN_M))
{
REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD);
REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
}
/* enable VDDSDIO control by state machine */
modifyreg32(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE, 0);

View File

@ -258,6 +258,22 @@ void esp32_rtc_wait_for_slow_cycle(void);
void esp32_rtc_cpu_freq_set_xtal(void);
/****************************************************************************
* Name: esp_rtc_clk_get_cpu_freq
*
* Description:
* Get the currently used CPU frequency configuration.
*
* Input Parameters:
* None
*
* Returned Value:
* CPU frequency
*
****************************************************************************/
int esp_rtc_clk_get_cpu_freq(void);
/****************************************************************************
* Name: esp32_rtc_sleep_init
*