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();
|
s_config.ccount_ticks_record = cpu_ll_get_cycle_count();
|
||||||
static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED;
|
static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
portENTER_CRITICAL(&light_sleep_lock);
|
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
|
* section. Make sure the code on the other CPU is not holding esp_timer
|
||||||
* lock, otherwise there will be deadlock.
|
* lock, otherwise there will be deadlock.
|
||||||
*/
|
*/
|
||||||
@ -758,29 +758,16 @@ esp_err_t esp_light_sleep_start(void)
|
|||||||
|
|
||||||
s_light_sleep_wakeup = true;
|
s_light_sleep_wakeup = true;
|
||||||
|
|
||||||
// System timer has been clock gated for the duration of the sleep, correct for that.
|
// System timer has been stopped 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();
|
|
||||||
uint64_t rtc_ticks_at_end = rtc_time_get();
|
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 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,
|
* If sleep duration is too small(less than 1 rtc_slow_clk cycle), rtc_time_diff will be zero.
|
||||||
* for very small values of sleep_duration. Ignore those to keep esp_timer
|
* In this case, just ignore the time compensation and keep esp_timer monotonic.
|
||||||
* monotonic.
|
|
||||||
*/
|
*/
|
||||||
if (time_diff > 0) {
|
if (rtc_time_diff > 0) {
|
||||||
esp_timer_private_advance(time_diff);
|
esp_timer_private_set(high_res_time_at_start + rtc_time_diff);
|
||||||
}
|
}
|
||||||
esp_set_time_from_rtc();
|
esp_set_time_from_rtc();
|
||||||
|
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
*
|
||||||
// you may not use this file except in compliance with the License.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
@ -43,13 +35,20 @@ extern "C" {
|
|||||||
void esp_timer_private_update_apb_freq(uint32_t apb_ticks_per_us);
|
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.
|
* 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
|
* @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);
|
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);
|
portENTER_CRITICAL(&s_time_update_lock);
|
||||||
uint64_t now = esp_timer_impl_get_time();
|
timer_64b_reg_t dst = { .val = new_us * TICKS_PER_US };
|
||||||
timer_64b_reg_t dst = { .val = (now + time_diff_us) * TICKS_PER_US };
|
|
||||||
REG_WRITE(LOAD_LO_REG, dst.lo);
|
REG_WRITE(LOAD_LO_REG, dst.lo);
|
||||||
REG_WRITE(LOAD_HI_REG, dst.hi);
|
REG_WRITE(LOAD_HI_REG, dst.hi);
|
||||||
REG_WRITE(LOAD_REG, 1);
|
REG_WRITE(LOAD_REG, 1);
|
||||||
portEXIT_CRITICAL(&s_time_update_lock);
|
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)
|
esp_err_t esp_timer_impl_early_init(void)
|
||||||
{
|
{
|
||||||
periph_module_enable(PERIPH_LACT);
|
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_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_lock(void) __attribute__((alias("esp_timer_impl_lock")));
|
||||||
void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock")));
|
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
|
#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);
|
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);
|
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_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_lock(void) __attribute__((alias("esp_timer_impl_lock")));
|
||||||
void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock")));
|
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/esp_private/panic_internal.h
|
||||||
components/esp_system/test_eh_frame_parser/linker.ld
|
components/esp_system/test_eh_frame_parser/linker.ld
|
||||||
components/esp_system/ubsan.c
|
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.c
|
||||||
components/esp_timer/test/test_esp_timer_light_sleep.c
|
components/esp_timer/test/test_esp_timer_light_sleep.c
|
||||||
components/esp_timer/test/test_ets_timer.c
|
components/esp_timer/test/test_ets_timer.c
|
||||||
|
Loading…
Reference in New Issue
Block a user