REG_WRITE(FRC_TIMER_LOAD_REG(1), REG_READ(FRC_TIMER_COUNT_REG(1)) - ALARM_OVERFLOW_VAL);
}
+void esp_timer_impl_lock()
+{
+ portENTER_CRITICAL(&s_time_update_lock);
+}
+
+void esp_timer_impl_unlock()
+{
+ portEXIT_CRITICAL(&s_time_update_lock);
+}
+
uint64_t IRAM_ATTR esp_timer_impl_get_time()
{
uint32_t timer_val;
* @return minimal period of periodic timer, in microseconds
*/
uint64_t esp_timer_impl_get_min_period_us();
+
+/**
+ * @brief obtain internal critical section used esp_timer implementation
+ * This can be used when a sequence of calls to esp_timer has to be made,
+ * and it is necessary that the state of the timer is consistent between
+ * the calls. Should be treated in the same way as a spinlock.
+ * Call esp_timer_impl_unlock to release the lock
+ */
+void esp_timer_impl_lock();
+
+
+/**
+ * @brief counterpart of esp_timer_impl_lock
+ */
+void esp_timer_impl_unlock();
{
static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&light_sleep_lock);
+ /* We will be calling esp_timer_impl_advance inside DPORT access critical
+ * section. Make sure the code on the other CPU is not holding esp_timer
+ * lock, otherwise there will be deadlock.
+ */
+ esp_timer_impl_lock();
s_config.rtc_ticks_at_sleep_start = rtc_time_get();
uint64_t frc_time_at_start = esp_timer_get_time();
DPORT_STALL_OTHER_CPU_START();
}
esp_set_time_from_rtc();
+ esp_timer_impl_unlock();
DPORT_STALL_OTHER_CPU_END();
rtc_wdt_disable();
portEXIT_CRITICAL(&light_sleep_lock);
vSemaphoreDelete(done);
}
+TEST_CASE("light sleep stress test with periodic esp_timer", "[deepsleep]")
+{
+ void timer_func(void* arg)
+ {
+ ets_delay_us(50);
+ }
+
+ SemaphoreHandle_t done = xSemaphoreCreateCounting(2, 0);
+ esp_sleep_enable_timer_wakeup(1000);
+ esp_timer_handle_t timer;
+ esp_timer_create_args_t config = {
+ .callback = &timer_func,
+ };
+ TEST_ESP_OK(esp_timer_create(&config, &timer));
+ esp_timer_start_periodic(timer, 500);
+ xTaskCreatePinnedToCore(&test_light_sleep, "ls1", 4096, done, UNITY_FREERTOS_PRIORITY + 1, NULL, 0);
+#if portNUM_PROCESSORS == 2
+ xTaskCreatePinnedToCore(&test_light_sleep, "ls1", 4096, done, UNITY_FREERTOS_PRIORITY + 1, NULL, 1);
+#endif
+ xSemaphoreTake(done, portMAX_DELAY);
+#if portNUM_PROCESSORS == 2
+ xSemaphoreTake(done, portMAX_DELAY);
+#endif
+ vSemaphoreDelete(done);
+ esp_timer_stop(timer);
+ esp_timer_delete(timer);
+}
+
+
#ifdef CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
#define MAX_SLEEP_TIME_ERROR_US 200
#else