mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Systimer reset alternative on S2 (and others) (v4.3)
This commit is contained in:
parent
44c701abb6
commit
fa85714845
@ -61,11 +61,11 @@ void esp_reset_reason_set_hint(esp_reset_reason_t hint);
|
|||||||
*/
|
*/
|
||||||
esp_reset_reason_t esp_reset_reason_get_hint(void);
|
esp_reset_reason_t esp_reset_reason_get_hint(void);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the time in microseconds since startup
|
* @brief Get the time in microseconds since startup
|
||||||
*
|
*
|
||||||
* @returns time since startup in microseconds
|
* @returns time since g_startup_time; definition should be fixed by system time provider
|
||||||
|
* no matter the underlying timer used.
|
||||||
*/
|
*/
|
||||||
int64_t esp_system_get_time(void);
|
int64_t esp_system_get_time(void);
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ TEST_CASE("Test rtc clk calibration compensation", "[rtc_clk]")
|
|||||||
// so that t2 > t1 remains true
|
// so that t2 > t1 remains true
|
||||||
int64_t t2 = esp_rtc_get_time_us();
|
int64_t t2 = esp_rtc_get_time_us();
|
||||||
|
|
||||||
TEST_ASSERT(t2 > t1);
|
TEST_ASSERT_GREATER_THAN(t1, t2);
|
||||||
|
|
||||||
// Restore calibration value
|
// Restore calibration value
|
||||||
esp_clk_slowclk_cal_set(esp_clk_slowclk_cal_get() * 2);
|
esp_clk_slowclk_cal_set(esp_clk_slowclk_cal_get() * 2);
|
||||||
@ -337,7 +337,7 @@ TEST_CASE("Test rtc clk calibration compensation", "[rtc_clk]")
|
|||||||
|
|
||||||
t2 = esp_rtc_get_time_us();
|
t2 = esp_rtc_get_time_us();
|
||||||
|
|
||||||
TEST_ASSERT(t2 > t1);
|
TEST_ASSERT_GREATER_THAN(t1, t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void trigger_deepsleep(void)
|
static void trigger_deepsleep(void)
|
||||||
@ -364,7 +364,7 @@ static void check_time_deepsleep_1(void)
|
|||||||
RESET_REASON reason = rtc_get_reset_reason(0);
|
RESET_REASON reason = rtc_get_reset_reason(0);
|
||||||
TEST_ASSERT(reason == DEEPSLEEP_RESET);
|
TEST_ASSERT(reason == DEEPSLEEP_RESET);
|
||||||
int64_t end = esp_rtc_get_time_us();
|
int64_t end = esp_rtc_get_time_us();
|
||||||
TEST_ASSERT(end > start);
|
TEST_ASSERT_GREATER_THAN(start, end);
|
||||||
|
|
||||||
esp_clk_slowclk_cal_set(esp_clk_slowclk_cal_get() * 2);
|
esp_clk_slowclk_cal_set(esp_clk_slowclk_cal_get() * 2);
|
||||||
|
|
||||||
@ -384,7 +384,7 @@ static void check_time_deepsleep_2(void)
|
|||||||
RESET_REASON reason = rtc_get_reset_reason(0);
|
RESET_REASON reason = rtc_get_reset_reason(0);
|
||||||
TEST_ASSERT(reason == DEEPSLEEP_RESET);
|
TEST_ASSERT(reason == DEEPSLEEP_RESET);
|
||||||
int64_t end = esp_rtc_get_time_us();
|
int64_t end = esp_rtc_get_time_us();
|
||||||
TEST_ASSERT(end > start);
|
TEST_ASSERT_GREATER_THAN(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_MULTIPLE_STAGES("Test rtc clk calibration compensation across deep sleep", "[rtc_clk][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", trigger_deepsleep, check_time_deepsleep_1, check_time_deepsleep_2);
|
TEST_CASE_MULTIPLE_STAGES("Test rtc clk calibration compensation across deep sleep", "[rtc_clk][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", trigger_deepsleep, check_time_deepsleep_1, check_time_deepsleep_2);
|
||||||
|
29
components/esp_system/README.md
Normal file
29
components/esp_system/README.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
## System Notes
|
||||||
|
|
||||||
|
### Timekeeping
|
||||||
|
|
||||||
|
The following are the timekeeping mechanisms available and their differences:
|
||||||
|
|
||||||
|
1. System time (`esp_system_get_time`)
|
||||||
|
|
||||||
|
Time with the origin at `g_startup_time`. The implementation is not handled by `esp_system`,
|
||||||
|
but it does provide a default implementation using RTC timer. Currently, `esp_timer`
|
||||||
|
provides system time, since the hardware timers are under the control of that
|
||||||
|
component. However, no matter the underlying timer, the system time provider
|
||||||
|
should maintain the definition of having the origin point at `g_startup_time`.
|
||||||
|
|
||||||
|
2. `esp_timer` time (`esp_timer_get_time`)
|
||||||
|
|
||||||
|
This is the time read from an underlying hardware timer, controlled through config. Origin
|
||||||
|
is at the point where the underlying timer starts counting.
|
||||||
|
|
||||||
|
3. `newlib` time (`gettimeofday`)
|
||||||
|
|
||||||
|
Timekeeping function in standard library. Can be set (`settimeofday`) or moved forward/backward (`adjtime`);
|
||||||
|
with the possibility of the changes being made persistent through config.
|
||||||
|
Currently implemented in terms of system time, as the point of origin is fixed.
|
||||||
|
If persistence is enabled, RTC time is also used in conjuction with system time.
|
||||||
|
|
||||||
|
4. RTC time (`esp_rtc_get_time_us`)
|
||||||
|
|
||||||
|
Time read from RTC timer.
|
@ -315,7 +315,6 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
|||||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_8M);
|
DPORT_CLEAR_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_8M);
|
||||||
DPORT_SET_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_RTC_SLOW);
|
DPORT_SET_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_RTC_SLOW);
|
||||||
|
|
||||||
periph_ll_reset(PERIPH_SYSTIMER_MODULE);
|
|
||||||
|
|
||||||
/* Enable RNG clock. */
|
/* Enable RNG clock. */
|
||||||
periph_module_enable(PERIPH_RNG_MODULE);
|
periph_module_enable(PERIPH_RNG_MODULE);
|
||||||
|
36
components/esp_system/test/test_system_time.c
Normal file
36
components/esp_system/test/test_system_time.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "unity.h"
|
||||||
|
|
||||||
|
#include "esp_private/system_internal.h"
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
#include "esp32/clk.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
|
#include "esp32s2/clk.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#include "esp32s3/clk.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
|
#include "esp32c3/clk.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE("Test effect of rtc clk calibration compensation on system time", "[esp_system]")
|
||||||
|
{
|
||||||
|
uint32_t prev_cal = esp_clk_slowclk_cal_get();
|
||||||
|
int64_t t1 = esp_system_get_time();
|
||||||
|
|
||||||
|
// Modify calibration value
|
||||||
|
esp_clk_slowclk_cal_set(prev_cal/2);
|
||||||
|
|
||||||
|
// Internally, the origin point of rtc clk has been adjusted
|
||||||
|
// so that t2 > t1 remains true
|
||||||
|
int64_t t2 = esp_system_get_time();
|
||||||
|
|
||||||
|
TEST_ASSERT_GREATER_THAN(t1, t2);
|
||||||
|
|
||||||
|
// Restore calibration value
|
||||||
|
esp_clk_slowclk_cal_set(prev_cal);
|
||||||
|
|
||||||
|
t2 = esp_system_get_time();
|
||||||
|
|
||||||
|
TEST_ASSERT_GREATER_THAN(t1, t2);
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
idf_build_get_property(target IDF_TARGET)
|
idf_build_get_property(target IDF_TARGET)
|
||||||
|
|
||||||
set(srcs "src/esp_timer.c"
|
set(srcs "src/esp_timer.c"
|
||||||
"src/ets_timer_legacy.c")
|
"src/ets_timer_legacy.c"
|
||||||
|
"src/system_time.c")
|
||||||
|
|
||||||
if(CONFIG_ESP_TIMER_IMPL_FRC2)
|
if(CONFIG_ESP_TIMER_IMPL_FRC2)
|
||||||
list(APPEND srcs "src/esp_timer_impl_frc_legacy.c")
|
list(APPEND srcs "src/esp_timer_impl_frc_legacy.c")
|
||||||
|
@ -186,8 +186,7 @@ esp_err_t esp_timer_delete(esp_timer_handle_t timer);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get time in microseconds since boot
|
* @brief Get time in microseconds since boot
|
||||||
* @return number of microseconds since esp_timer_init was called (this normally
|
* @return number of microseconds since underlying timer has been started
|
||||||
* happens early during application startup).
|
|
||||||
*/
|
*/
|
||||||
int64_t esp_timer_get_time(void);
|
int64_t esp_timer_get_time(void);
|
||||||
|
|
||||||
|
@ -117,3 +117,10 @@ uint64_t esp_timer_impl_get_counter_reg(void);
|
|||||||
* @return the value of the alarm register
|
* @return the value of the alarm register
|
||||||
*/
|
*/
|
||||||
uint64_t esp_timer_impl_get_alarm_reg(void);
|
uint64_t esp_timer_impl_get_alarm_reg(void);
|
||||||
|
|
||||||
|
#if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
|
||||||
|
/**
|
||||||
|
* @brief Initialize esp_timer as system time provider.
|
||||||
|
*/
|
||||||
|
void esp_timer_impl_init_system_time(void);
|
||||||
|
#endif
|
||||||
|
@ -384,9 +384,7 @@ esp_err_t esp_timer_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
|
#if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
|
||||||
// [refactor-todo] this logic, "esp_rtc_get_time_us() - g_startup_time", is also
|
esp_timer_impl_init_system_time();
|
||||||
// the weak definition of esp_system_get_time; find a way to remove this duplication.
|
|
||||||
esp_timer_private_advance(esp_rtc_get_time_us() - g_startup_time);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@ -517,20 +515,6 @@ int64_t IRAM_ATTR esp_timer_get_next_alarm(void)
|
|||||||
return next_alarm;
|
return next_alarm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provides strong definition for system time functions relied upon
|
|
||||||
// by core components.
|
|
||||||
#if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
|
|
||||||
int64_t IRAM_ATTR esp_system_get_time(void)
|
|
||||||
{
|
|
||||||
return esp_timer_get_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t IRAM_ATTR esp_system_get_time_resolution(void)
|
|
||||||
{
|
|
||||||
return 1000;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool esp_timer_is_active(esp_timer_handle_t timer)
|
bool esp_timer_is_active(esp_timer_handle_t timer)
|
||||||
{
|
{
|
||||||
return timer_armed(timer);
|
return timer_armed(timer);
|
||||||
|
53
components/esp_timer/src/system_time.c
Normal file
53
components/esp_timer/src/system_time.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 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.
|
||||||
|
|
||||||
|
// Provides strong definition for system time functions relied upon
|
||||||
|
// by core components.
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
|
||||||
|
#include "esp_timer.h"
|
||||||
|
#include "esp_timer_impl.h"
|
||||||
|
|
||||||
|
#include "esp_private/startup_internal.h"
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
#include "esp32/rtc.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
|
#include "esp32s2/rtc.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#include "esp32s3/rtc.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
|
#include "esp32c3/rtc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Correction for underlying timer to keep definition
|
||||||
|
// of system time consistent.
|
||||||
|
static int64_t s_correction_us = 0;
|
||||||
|
|
||||||
|
void esp_timer_impl_init_system_time(void)
|
||||||
|
{
|
||||||
|
s_correction_us = esp_rtc_get_time_us() - g_startup_time - esp_timer_impl_get_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t IRAM_ATTR esp_system_get_time(void)
|
||||||
|
{
|
||||||
|
return esp_timer_get_time() + s_correction_us;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t IRAM_ATTR esp_system_get_time_resolution(void)
|
||||||
|
{
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
#endif
|
@ -51,7 +51,7 @@
|
|||||||
// Offset between FRC timer and the RTC.
|
// Offset between FRC timer and the RTC.
|
||||||
// Initialized after reset or light sleep.
|
// Initialized after reset or light sleep.
|
||||||
#if defined(CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER) && defined(CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER)
|
#if defined(CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER) && defined(CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER)
|
||||||
uint64_t s_microseconds_offset = 0;
|
int64_t s_microseconds_offset = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER
|
#ifndef CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
|
|
||||||
|
#include "esp_private/system_internal.h"
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#include "esp32/clk.h"
|
#include "esp32/clk.h"
|
||||||
#define TARGET_DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ
|
#define TARGET_DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ
|
||||||
@ -403,7 +405,7 @@ void test_posix_timers_clock (void)
|
|||||||
TEST_ASSERT_EQUAL_INT(1000, ts.tv_nsec);
|
TEST_ASSERT_EQUAL_INT(1000, ts.tv_nsec);
|
||||||
|
|
||||||
TEST_ASSERT(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
|
TEST_ASSERT(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
|
||||||
delta_monotonic_us = esp_timer_get_time() - (ts.tv_sec * 1000000L + ts.tv_nsec / 1000L);
|
delta_monotonic_us = esp_system_get_time() - (ts.tv_sec * 1000000L + ts.tv_nsec / 1000L);
|
||||||
TEST_ASSERT(delta_monotonic_us > 0 || delta_monotonic_us == 0);
|
TEST_ASSERT(delta_monotonic_us > 0 || delta_monotonic_us == 0);
|
||||||
TEST_ASSERT_INT_WITHIN(5000L, 0, delta_monotonic_us);
|
TEST_ASSERT_INT_WITHIN(5000L, 0, delta_monotonic_us);
|
||||||
|
|
||||||
|
@ -580,7 +580,7 @@ UT_047:
|
|||||||
|
|
||||||
UT_C3:
|
UT_C3:
|
||||||
extends: .unit_test_c3_template
|
extends: .unit_test_c3_template
|
||||||
parallel: 29
|
parallel: 30
|
||||||
tags:
|
tags:
|
||||||
- ESP32C3_IDF
|
- ESP32C3_IDF
|
||||||
- UT_T1_1
|
- UT_T1_1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user