mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
system/sleep: simplify code for time compensation when wakeup from light sleep
This commit is contained in:
parent
317f6292c7
commit
30e7af2ffb
@ -650,7 +650,7 @@ esp_err_t esp_light_sleep_start(void)
|
||||
s_config.ccount_ticks_record = cpu_ll_get_cycle_count();
|
||||
static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
portENTER_CRITICAL(&light_sleep_lock);
|
||||
/* We will be calling esp_timer_private_advance inside DPORT access critical
|
||||
/* We will be calling esp_timer_private_set inside DPORT access critical
|
||||
* section. Make sure the code on the other CPU is not holding esp_timer
|
||||
* lock, otherwise there will be deadlock.
|
||||
*/
|
||||
@ -758,29 +758,16 @@ esp_err_t esp_light_sleep_start(void)
|
||||
|
||||
s_light_sleep_wakeup = true;
|
||||
|
||||
// System timer has been clock gated for the duration of the sleep, correct for that.
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
/**
|
||||
* On esp32c3, rtc_time_get() is non-blocking, esp_timer_get_time() is
|
||||
* blocking, and the measurement data shows that this order is better.
|
||||
*/
|
||||
uint64_t high_res_time_at_end = esp_timer_get_time();
|
||||
// System timer has been stopped for the duration of the sleep, correct for that.
|
||||
uint64_t rtc_ticks_at_end = rtc_time_get();
|
||||
#else
|
||||
uint64_t rtc_ticks_at_end = rtc_time_get();
|
||||
uint64_t high_res_time_at_end = esp_timer_get_time();
|
||||
#endif
|
||||
|
||||
uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period);
|
||||
uint64_t high_res_time_diff = high_res_time_at_end - high_res_time_at_start;
|
||||
|
||||
int64_t time_diff = rtc_time_diff - high_res_time_diff;
|
||||
/* Small negative values (up to 1 RTC_SLOW clock period) are possible,
|
||||
* for very small values of sleep_duration. Ignore those to keep esp_timer
|
||||
* monotonic.
|
||||
/**
|
||||
* If sleep duration is too small(less than 1 rtc_slow_clk cycle), rtc_time_diff will be zero.
|
||||
* In this case, just ignore the time compensation and keep esp_timer monotonic.
|
||||
*/
|
||||
if (time_diff > 0) {
|
||||
esp_timer_private_advance(time_diff);
|
||||
if (rtc_time_diff > 0) {
|
||||
esp_timer_private_set(high_res_time_at_start + rtc_time_diff);
|
||||
}
|
||||
esp_set_time_from_rtc();
|
||||
|
||||
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -43,13 +35,20 @@ extern "C" {
|
||||
void esp_timer_private_update_apb_freq(uint32_t apb_ticks_per_us);
|
||||
|
||||
/**
|
||||
* @brief Adjust current esp_timer time by a certain value
|
||||
* @brief Set esp_timer time to a certain value
|
||||
*
|
||||
* Called from light sleep code to synchronize esp_timer time with RTC time.
|
||||
*
|
||||
* @param time_us adjustment to apply to esp_timer time, in microseconds
|
||||
* @param new_us the value to be set to esp_timer time, in microseconds
|
||||
*/
|
||||
void esp_timer_private_advance(int64_t time_us);
|
||||
void esp_timer_private_set(uint64_t new_us);
|
||||
|
||||
/**
|
||||
* @brief Adjust current esp_timer time by a certain value
|
||||
*
|
||||
* @param time_diff_us adjustment to apply to esp_timer time, in microseconds
|
||||
*/
|
||||
void esp_timer_private_advance(int64_t time_diff_us);
|
||||
|
||||
/**
|
||||
* @brief obtain internal critical section used esp_timer implementation
|
||||
|
@ -195,17 +195,22 @@ void IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us)
|
||||
portEXIT_CRITICAL(&s_time_update_lock);
|
||||
}
|
||||
|
||||
void esp_timer_impl_advance(int64_t time_diff_us)
|
||||
void esp_timer_impl_set(uint64_t new_us)
|
||||
{
|
||||
portENTER_CRITICAL(&s_time_update_lock);
|
||||
uint64_t now = esp_timer_impl_get_time();
|
||||
timer_64b_reg_t dst = { .val = (now + time_diff_us) * TICKS_PER_US };
|
||||
timer_64b_reg_t dst = { .val = new_us * TICKS_PER_US };
|
||||
REG_WRITE(LOAD_LO_REG, dst.lo);
|
||||
REG_WRITE(LOAD_HI_REG, dst.hi);
|
||||
REG_WRITE(LOAD_REG, 1);
|
||||
portEXIT_CRITICAL(&s_time_update_lock);
|
||||
}
|
||||
|
||||
void esp_timer_impl_advance(int64_t time_diff_us)
|
||||
{
|
||||
uint64_t now = esp_timer_impl_get_time();
|
||||
esp_timer_impl_set(now + time_diff_us);
|
||||
}
|
||||
|
||||
esp_err_t esp_timer_impl_early_init(void)
|
||||
{
|
||||
periph_module_enable(PERIPH_LACT);
|
||||
@ -286,6 +291,7 @@ uint64_t esp_timer_impl_get_alarm_reg(void)
|
||||
}
|
||||
|
||||
void esp_timer_private_update_apb_freq(uint32_t apb_ticks_per_us) __attribute__((alias("esp_timer_impl_update_apb_freq")));
|
||||
void esp_timer_private_advance(int64_t time_us) __attribute__((alias("esp_timer_impl_advance")));
|
||||
void esp_timer_private_set(uint64_t new_us) __attribute__((alias("esp_timer_impl_set")));
|
||||
void esp_timer_private_advance(int64_t time_diff_us) __attribute__((alias("esp_timer_impl_advance")));
|
||||
void esp_timer_private_lock(void) __attribute__((alias("esp_timer_impl_lock")));
|
||||
void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock")));
|
||||
|
@ -101,10 +101,19 @@ void IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us)
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_timer_impl_advance(int64_t time_us)
|
||||
void esp_timer_impl_set(uint64_t new_us)
|
||||
{
|
||||
portENTER_CRITICAL_SAFE(&s_time_update_lock);
|
||||
systimer_hal_counter_value_advance(&systimer_hal, SYSTIMER_LL_COUNTER_CLOCK, time_us);
|
||||
systimer_counter_value_t new_count = { .val = new_us * SYSTIMER_LL_TICKS_PER_US };
|
||||
systimer_ll_set_counter_value(systimer_hal.dev, SYSTIMER_LL_COUNTER_CLOCK, new_count.val);
|
||||
systimer_ll_apply_counter_value(systimer_hal.dev, SYSTIMER_LL_COUNTER_CLOCK);
|
||||
portEXIT_CRITICAL_SAFE(&s_time_update_lock);
|
||||
}
|
||||
|
||||
void esp_timer_impl_advance(int64_t time_diff_us)
|
||||
{
|
||||
portENTER_CRITICAL_SAFE(&s_time_update_lock);
|
||||
systimer_hal_counter_value_advance(&systimer_hal, SYSTIMER_LL_COUNTER_CLOCK, time_diff_us);
|
||||
portEXIT_CRITICAL_SAFE(&s_time_update_lock);
|
||||
}
|
||||
|
||||
@ -192,6 +201,7 @@ uint64_t esp_timer_impl_get_alarm_reg(void)
|
||||
}
|
||||
|
||||
void esp_timer_private_update_apb_freq(uint32_t apb_ticks_per_us) __attribute__((alias("esp_timer_impl_update_apb_freq")));
|
||||
void esp_timer_private_advance(int64_t time_us) __attribute__((alias("esp_timer_impl_advance")));
|
||||
void esp_timer_private_set(uint64_t new_us) __attribute__((alias("esp_timer_impl_set")));
|
||||
void esp_timer_private_advance(int64_t time_diff_us) __attribute__((alias("esp_timer_impl_advance")));
|
||||
void esp_timer_private_lock(void) __attribute__((alias("esp_timer_impl_lock")));
|
||||
void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock")));
|
||||
|
@ -694,7 +694,6 @@ components/esp_system/test_eh_frame_parser/eh_frame_parser_impl.h
|
||||
components/esp_system/test_eh_frame_parser/esp_private/panic_internal.h
|
||||
components/esp_system/test_eh_frame_parser/linker.ld
|
||||
components/esp_system/ubsan.c
|
||||
components/esp_timer/include/esp_private/esp_timer_private.h
|
||||
components/esp_timer/test/test_esp_timer.c
|
||||
components/esp_timer/test/test_esp_timer_light_sleep.c
|
||||
components/esp_timer/test/test_ets_timer.c
|
||||
|
Loading…
Reference in New Issue
Block a user