Sfoglia il codice sorgente

Merge branch 'bufgix/esp_timer_set_alarm_v3.3' into 'release/v3.3'

esp_timer: Fix set_alarm. Case when timestamp < now_time (v3.3)

See merge request espressif/esp-idf!6997
Jiang Jiang Jian 6 anni fa
parent
commit
de9fd03b3e

+ 2 - 2
components/esp32/esp_timer_esp32.c

@@ -216,7 +216,7 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
     // Note that if by the time we update ALARM_REG, COUNT_REG value is higher,
     // interrupt will not happen for another ALARM_OVERFLOW_VAL timer ticks,
     // so need to check if alarm value is too close in the future (e.g. <2 us away).
-    const uint32_t offset = s_timer_ticks_per_us * 2;
+    const int32_t offset = s_timer_ticks_per_us * 2;
     do {
         // Adjust current time if overflow has happened
         if (timer_overflow_happened()) {
@@ -224,7 +224,7 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
             s_time_base_us += s_timer_us_per_overflow;
         }
         s_mask_overflow = false;
-        uint64_t cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
+        int64_t cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
         // Alarm time relative to the moment when counter was 0
         int64_t time_after_timebase_us = (int64_t)timestamp - s_time_base_us;
         // Calculate desired timer compare value (may exceed 2^32-1)

+ 19 - 0
components/esp32/test/test_esp_timer.c

@@ -4,6 +4,7 @@
 #include <sys/time.h>
 #include <sys/param.h>
 #include "unity.h"
+#include "soc/frc_timer_reg.h"
 #include "esp_timer.h"
 #include "esp_heap_caps.h"
 #include "freertos/FreeRTOS.h"
@@ -779,3 +780,21 @@ TEST_CASE("esp_timer_impl_set_alarm and using start_once do not lead that the Sy
 }
 
 #endif // !defined(CONFIG_FREERTOS_UNICORE) && defined(CONFIG_ESP32_DPORT_WORKAROUND)
+
+TEST_CASE("Test case when esp_timer_impl_set_alarm needs set timer < now_time", "[esp_timer]")
+{
+    REG_WRITE(FRC_TIMER_LOAD_REG(1), 0);
+    esp_timer_impl_advance(50331648); // 0xefffffff/80 = 50331647
+
+    ets_delay_us(2);
+
+    portDISABLE_INTERRUPTS();
+    esp_timer_impl_set_alarm(50331647);
+    uint32_t alarm_reg = REG_READ(FRC_TIMER_ALARM_REG(1));
+    uint32_t count_reg = REG_READ(FRC_TIMER_COUNT_REG(1));
+    portENABLE_INTERRUPTS();
+
+    const uint32_t offset = 80 * 2; // s_timer_ticks_per_us
+    printf("alarm_reg = 0x%x, count_reg 0x%x\n", alarm_reg, count_reg);
+    TEST_ASSERT(alarm_reg <= (count_reg + offset));
+}