xtensa/esp32: Get CPU frequency from the rtc register
This commit is contained in:
parent
1847a67e05
commit
39322e1158
@ -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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user