mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
rtc: add function to en/disable the rtc clock
This commit is contained in:
parent
f09b8ae7a4
commit
e338a2e3df
@ -5,8 +5,12 @@ if(${target} STREQUAL "esp32")
|
||||
list(APPEND requires efuse)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "compare_set.c"
|
||||
"cpu_util.c"
|
||||
set(srcs "compare_set.c" "cpu_util.c")
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "clk_ctrl_os.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES ${requires}
|
||||
PRIV_REQUIRES efuse
|
||||
|
56
components/esp_hw_support/clk_ctrl_os.c
Normal file
56
components/esp_hw_support/clk_ctrl_os.c
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include "soc/clk_ctrl_os.h"
|
||||
|
||||
#define DELAY_RTC_CLK_SWITCH 5
|
||||
|
||||
static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static uint8_t s_periph_ref_counts = 0;
|
||||
static uint32_t s_rtc_clk_freq = 0; // Frequency of the 8M/256 clock in Hz
|
||||
|
||||
bool periph_rtc_dig_clk8m_enable(void)
|
||||
{
|
||||
portENTER_CRITICAL(&periph_spinlock);
|
||||
if (s_periph_ref_counts == 0) {
|
||||
rtc_dig_clk8m_enable();
|
||||
s_rtc_clk_freq = rtc_clk_freq_cal(rtc_clk_cal(RTC_CAL_8MD256, 100));
|
||||
if (s_rtc_clk_freq == 0) {
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
s_periph_ref_counts++;
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t periph_rtc_dig_clk8m_get_freq(void)
|
||||
{
|
||||
return s_rtc_clk_freq * 256;
|
||||
}
|
||||
|
||||
void periph_rtc_dig_clk8m_disable(void)
|
||||
{
|
||||
portENTER_CRITICAL(&periph_spinlock);
|
||||
assert(s_periph_ref_counts > 0);
|
||||
s_periph_ref_counts--;
|
||||
if (s_periph_ref_counts == 0) {
|
||||
s_rtc_clk_freq = 0;
|
||||
rtc_dig_clk8m_disable();
|
||||
}
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
}
|
@ -2,3 +2,7 @@ COMPONENT_SRCDIRS := . port/$(IDF_TARGET)
|
||||
COMPONENT_ADD_INCLUDEDIRS := . include port/$(IDF_TARGET)/private_include
|
||||
|
||||
port/$(IDF_TARGET)/rtc_clk.o: CFLAGS += -fno-jump-tables -fno-tree-switch-conversion
|
||||
|
||||
ifdef IS_BOOTLOADER_BUILD
|
||||
COMPONENT_OBJEXCLUDE += clk_ctrl_os.o
|
||||
endif
|
||||
|
50
components/esp_hw_support/include/soc/clk_ctrl_os.h
Normal file
50
components/esp_hw_support/include/soc/clk_ctrl_os.h
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "soc/rtc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief This function is used to enable the digital 8m rtc clock,
|
||||
* to support the peripherals.
|
||||
*
|
||||
* @note If this function is called a number of times, the `periph_rtc_dig_clk8m_disable`
|
||||
* function needs to be called same times to disable.
|
||||
*
|
||||
* @return true: success for enable the rtc 8M clock, false: rtc 8M clock enable failed
|
||||
*/
|
||||
bool periph_rtc_dig_clk8m_enable(void);
|
||||
|
||||
/**
|
||||
* @brief This function is used to disable the rtc digital clock, which should be called
|
||||
* with the `periph_rtc_dig_clk8m_enable` pairedly
|
||||
*
|
||||
* @note If this function is called a number of times, the `periph_rtc_dig_clk8m_disable`
|
||||
* function needs to be called same times to disable.
|
||||
*/
|
||||
void periph_rtc_dig_clk8m_disable(void);
|
||||
|
||||
/**
|
||||
* @brief This function is used to get the real clock frequency value of the rtc clock
|
||||
*
|
||||
* @return The real clock value
|
||||
*/
|
||||
uint32_t periph_rtc_dig_clk8m_get_freq(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -101,6 +101,7 @@
|
||||
|
||||
#define RTC_PLL_FREQ_320M 320
|
||||
#define RTC_PLL_FREQ_480M 480
|
||||
#define DELAY_RTC_CLK_SWITCH 5
|
||||
|
||||
static void rtc_clk_cpu_freq_to_8m(void);
|
||||
static void rtc_clk_bbpll_disable(void);
|
||||
@ -773,6 +774,18 @@ uint32_t rtc_clk_apb_freq_get(void)
|
||||
return freq_hz - remainder;
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_disable(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
||||
}
|
||||
|
||||
/* Name used in libphy.a:phy_chip_v7.o
|
||||
* TODO: update the library to use rtc_clk_xtal_freq_get
|
||||
*/
|
||||
|
@ -167,3 +167,11 @@ void rtc_clk_wait_for_slow_cycle(void)
|
||||
esp_rom_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
|
||||
{
|
||||
if (cal_val == 0) {
|
||||
return 0; // cal_val will be denominator, return 0 as the symbol of failure.
|
||||
}
|
||||
return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ static const char *TAG = "rtc_clk";
|
||||
|
||||
#define RTC_PLL_FREQ_320M 320
|
||||
#define RTC_PLL_FREQ_480M 480
|
||||
#define DELAY_RTC_CLK_SWITCH 5
|
||||
|
||||
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
||||
static int s_cur_pll_freq;
|
||||
@ -559,6 +560,18 @@ void rtc_clk_8m_divider_set(uint32_t div)
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_disable(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
||||
}
|
||||
|
||||
/* Name used in libphy.a:phy_chip_v7.o
|
||||
* TODO: update the library to use rtc_clk_xtal_freq_get
|
||||
*/
|
||||
|
@ -179,3 +179,11 @@ void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any mor
|
||||
esp_rom_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
|
||||
{
|
||||
if (cal_val == 0) {
|
||||
return 0; // cal_val will be denominator, return 0 as the symbol of failure.
|
||||
}
|
||||
return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ static const char *TAG = "rtc_clk";
|
||||
|
||||
#define RTC_PLL_FREQ_320M 320
|
||||
#define RTC_PLL_FREQ_480M 480
|
||||
#define DELAY_RTC_CLK_SWITCH 5
|
||||
|
||||
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
||||
// On the ESP32-S2, 480MHz PLL is enabled at reset.
|
||||
@ -539,6 +540,18 @@ void rtc_clk_8m_divider_set(uint32_t div)
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_disable(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
||||
}
|
||||
|
||||
/* Name used in libphy.a:phy_chip_v7.o
|
||||
* TODO: update the library to use rtc_clk_xtal_freq_get
|
||||
*/
|
||||
|
@ -184,3 +184,11 @@ void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any mor
|
||||
esp_rom_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
|
||||
{
|
||||
if (cal_val == 0) {
|
||||
return 0; // cal_val will be denominator, return 0 as the symbol of failure.
|
||||
}
|
||||
return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ static const char *TAG = "rtc_clk";
|
||||
|
||||
#define RTC_PLL_FREQ_320M 320
|
||||
#define RTC_PLL_FREQ_480M 480
|
||||
#define DELAY_RTC_CLK_SWITCH 5
|
||||
|
||||
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
|
||||
static int s_cur_pll_freq = RTC_PLL_FREQ_480M;
|
||||
@ -556,6 +557,18 @@ void rtc_clk_8m_divider_set(uint32_t div)
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_disable(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
esp_rom_delay_us(DELAY_RTC_CLK_SWITCH);
|
||||
}
|
||||
|
||||
/* Name used in libphy.a:phy_chip_v7.o
|
||||
* TODO: update the library to use rtc_clk_xtal_freq_get
|
||||
*/
|
||||
|
@ -178,3 +178,11 @@ void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any mor
|
||||
esp_rom_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
|
||||
{
|
||||
if (cal_val == 0) {
|
||||
return 0; // cal_val will be denominator, return 0 as the symbol of failure.
|
||||
}
|
||||
return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
|
||||
}
|
||||
|
@ -459,6 +459,29 @@ uint64_t rtc_time_get(void);
|
||||
*/
|
||||
void rtc_clk_wait_for_slow_cycle(void);
|
||||
|
||||
/**
|
||||
* @brief Enable the rtc digital 8M clock
|
||||
*
|
||||
* This function is used to enable the digital rtc 8M clock to support peripherals.
|
||||
* For enabling the analog 8M clock, using `rtc_clk_8M_enable` function above.
|
||||
*/
|
||||
void rtc_dig_clk8m_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable the rtc digital 8M clock
|
||||
*
|
||||
* This function is used to disable the digital rtc 8M clock, which is only used to support peripherals.
|
||||
*/
|
||||
void rtc_dig_clk8m_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Caculate the real clock value after the clock calibration
|
||||
*
|
||||
* @param cal_val average slow clock period in microseconds, can be return from `rtc_clk_cal`
|
||||
* @return The real value of the clock has been measured
|
||||
*/
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val);
|
||||
|
||||
/**
|
||||
* @brief sleep configuration for rtc_sleep_init function
|
||||
*/
|
||||
|
@ -562,6 +562,29 @@ uint64_t rtc_deep_slp_time_get(void);
|
||||
*/
|
||||
void rtc_clk_wait_for_slow_cycle(void);
|
||||
|
||||
/**
|
||||
* @brief Enable the rtc digital 8M clock
|
||||
*
|
||||
* This function is used to enable the digital rtc 8M clock to support peripherals.
|
||||
* For enabling the analog 8M clock, using `rtc_clk_8M_enable` function above.
|
||||
*/
|
||||
void rtc_dig_clk8m_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable the rtc digital 8M clock
|
||||
*
|
||||
* This function is used to disable the digital rtc 8M clock, which is only used to support peripherals.
|
||||
*/
|
||||
void rtc_dig_clk8m_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Caculate the real clock value after the clock calibration
|
||||
*
|
||||
* @param cal_val average slow clock period in microseconds, can be return from `rtc_clk_cal`
|
||||
* @return The real value of the clock has been measured
|
||||
*/
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val);
|
||||
|
||||
/**
|
||||
* @brief Power down flags for rtc_sleep_pd function
|
||||
*/
|
||||
|
@ -588,6 +588,29 @@ uint64_t rtc_deep_slp_time_get(void);
|
||||
*/
|
||||
void rtc_clk_wait_for_slow_cycle(void);
|
||||
|
||||
/**
|
||||
* @brief Enable the rtc digital 8M clock
|
||||
*
|
||||
* This function is used to enable the digital rtc 8M clock to support peripherals.
|
||||
* For enabling the analog 8M clock, using `rtc_clk_8M_enable` function above.
|
||||
*/
|
||||
void rtc_dig_clk8m_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable the rtc digital 8M clock
|
||||
*
|
||||
* This function is used to disable the digital rtc 8M clock, which is only used to support peripherals.
|
||||
*/
|
||||
void rtc_dig_clk8m_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Caculate the real clock value after the clock calibration
|
||||
*
|
||||
* @param cal_val average slow clock period in microseconds, can be return from `rtc_clk_cal`
|
||||
* @return The real value of the clock has been measured
|
||||
*/
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val);
|
||||
|
||||
/**
|
||||
* @brief Power down flags for rtc_sleep_pd function
|
||||
*/
|
||||
|
@ -562,6 +562,29 @@ uint64_t rtc_deep_slp_time_get(void);
|
||||
*/
|
||||
void rtc_clk_wait_for_slow_cycle(void);
|
||||
|
||||
/**
|
||||
* @brief Enable the rtc digital 8M clock
|
||||
*
|
||||
* This function is used to enable the digital rtc 8M clock to support peripherals.
|
||||
* For enabling the analog 8M clock, using `rtc_clk_8M_enable` function above.
|
||||
*/
|
||||
void rtc_dig_clk8m_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable the rtc digital 8M clock
|
||||
*
|
||||
* This function is used to disable the digital rtc 8M clock, which is only used to support peripherals.
|
||||
*/
|
||||
void rtc_dig_clk8m_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Caculate the real clock value after the clock calibration
|
||||
*
|
||||
* @param cal_val average slow clock period in microseconds, can be return from `rtc_clk_cal`
|
||||
* @return The real value of the clock has been measured
|
||||
*/
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val);
|
||||
|
||||
/**
|
||||
* @brief Power up flags for rtc_sleep_pd function
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user