diff --git a/components/esp32/clk.c b/components/esp32/clk.c index 319b31fbc..6e01cc2ea 100644 --- a/components/esp32/clk.c +++ b/components/esp32/clk.c @@ -15,10 +15,12 @@ #include #include #include +#include #include "sdkconfig.h" #include "esp_attr.h" #include "esp_log.h" #include "esp_clk.h" +#include "esp_clk_internal.h" #include "rom/ets_sys.h" #include "rom/uart.h" #include "rom/rtc.h" @@ -40,14 +42,13 @@ static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk); +// g_ticks_us defined in ROMs for PRO and APP CPU +extern uint32_t g_ticks_per_us_pro; +extern uint32_t g_ticks_per_us_app; + static const char* TAG = "clk"; -/* - * This function is not exposed as an API at this point, - * because FreeRTOS doesn't yet support dynamic changing of - * CPU frequency. Also we need to implement hooks for - * components which want to be notified of CPU frequency - * changes. - */ + + void esp_clk_init(void) { rtc_config_t cfg = RTC_CONFIG_DEFAULT(); @@ -90,10 +91,19 @@ void esp_clk_init(void) XTHAL_SET_CCOUNT( XTHAL_GET_CCOUNT() * freq_after / freq_before ); } +int IRAM_ATTR esp_clk_cpu_freq(void) +{ + return g_ticks_per_us_pro * 1000000; +} + +int IRAM_ATTR esp_clk_apb_freq(void) +{ + return MIN(g_ticks_per_us_pro, 80) * 1000000; +} + void IRAM_ATTR ets_update_cpu_frequency(uint32_t ticks_per_us) { - extern uint32_t g_ticks_per_us_pro; // g_ticks_us defined in ROM for PRO CPU - extern uint32_t g_ticks_per_us_app; // same defined for APP CPU + /* Update scale factors used by ets_delay_us */ g_ticks_per_us_pro = ticks_per_us; g_ticks_per_us_app = ticks_per_us; } diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 3aefdce0a..ccf8a1d4b 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -64,7 +64,7 @@ #include "esp_app_trace.h" #include "esp_efuse.h" #include "esp_spiram.h" -#include "esp_clk.h" +#include "esp_clk_internal.h" #include "esp_timer.h" #include "trax.h" diff --git a/components/esp32/esp_clk_internal.h b/components/esp32/esp_clk_internal.h new file mode 100644 index 000000000..d1fd434cc --- /dev/null +++ b/components/esp32/esp_clk_internal.h @@ -0,0 +1,39 @@ +// Copyright 2015-2017 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. + +#pragma once + +/** + * @file esp_clk_internal.h + * + * Private clock-related functions + */ + +/** + * @brief Initialize clock-related settings + * + * Called from cpu_start.c, not intended to be called from other places. + * This function configures the CPU clock, RTC slow and fast clocks, and + * performs RTC slow clock calibration. + */ +void esp_clk_init(void); + + +/** + * @brief Disables clock of some peripherals + * + * Called from cpu_start.c, not intended to be called from other places. + * This function disables clock of useless peripherals when cpu starts. + */ +void esp_perip_clk_init(void); diff --git a/components/esp32/include/esp_clk.h b/components/esp32/include/esp_clk.h index 5c6f5cb87..6526aa927 100644 --- a/components/esp32/include/esp_clk.h +++ b/components/esp32/include/esp_clk.h @@ -18,20 +18,8 @@ * @file esp_clk.h * * This file contains declarations of clock related functions. - * These functions are used in ESP-IDF components, but should not be considered - * to be part of public API. */ -/** - * @brief Initialize clock-related settings - * - * Called from cpu_start.c, not intended to be called from other places. - * This function configures the CPU clock, RTC slow and fast clocks, and - * performs RTC slow clock calibration. - */ -void esp_clk_init(void); - - /** * @brief Get the calibration value of RTC slow clock * @@ -42,7 +30,6 @@ void esp_clk_init(void); */ uint32_t esp_clk_slowclk_cal_get(); - /** * @brief Update the calibration value of RTC slow clock * @@ -55,10 +42,34 @@ uint32_t esp_clk_slowclk_cal_get(); void esp_clk_slowclk_cal_set(uint32_t value); /** - * @brief Disables clock of some peripherals + * @brief Return current CPU clock frequency + * When frequency switching is performed, this frequency may change. + * However it is guaranteed that the frequency never changes with a critical + * section. * - * Called from cpu_start.c, not intended to be called from other places. - * This function disables clock of useless peripherals when cpu starts. + * @return CPU clock frequency, in Hz */ -void esp_perip_clk_init(void); +int esp_clk_cpu_freq(void); +/** + * @brief Return current APB clock frequency + * + * When frequency switching is performed, this frequency may change. + * However it is guaranteed that the frequency never changes with a critical + * section. + * + * @return APB clock frequency, in Hz + */ +int esp_clk_apb_freq(void); + + +/** + * @brief Read value of RTC counter, converting it to microseconds + * @attention The value returned by this function may change abruptly when + * calibration value of RTC counter is updated via esp_clk_slowclk_cal_set + * function. This should not happen unless application calls esp_clk_slowclk_cal_set. + * In ESP-IDF, esp_clk_slowclk_cal_set is only called in startup code. + * + * @return Value or RTC counter, expressed in microseconds + */ +uint64_t esp_clk_rtc_time(); diff --git a/components/newlib/time.c b/components/newlib/time.c index 0357f6412..edb9a59fe 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -145,6 +145,15 @@ void esp_set_time_from_rtc() #endif // WITH_FRC1 && WITH_RTC } +uint64_t esp_clk_rtc_time(void) +{ +#ifdef WITH_RTC + return get_rtc_time_us(); +#else + return 0; +#endif +} + clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms) { clock_t t = xTaskGetTickCount() * (portTICK_PERIOD_MS * CLK_TCK / 1000);