esp_timer: don’t busy loop in esp_timer_impl_set_alarm
authorIvan Grokhotkov <ivan@espressif.com>
Wed, 23 May 2018 13:50:55 +0000 (21:50 +0800)
committerbot <bot@espressif.com>
Mon, 11 Jun 2018 02:37:19 +0000 (02:37 +0000)
Previously the loop in esp_timer_impl_set_alarm was necessary to catch
the case when timer count wraps around (goes from 2^32 - 1 to 0).
Since ALARM_OVERFLOW_VAL was reduced from 2^32 - 1 to 0xefffffff,
this is no longer necessary.

Fixes https://github.com/espressif/esp-idf/issues/1891

components/esp32/esp_timer_esp32.c

index b2c29721b2876e55b2c178dee18b426cb303c49d..83d27b950e682675c013e35d7ca105d2ec2e7ca5 100644 (file)
@@ -216,18 +216,6 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
     // Adjust current time if overflow has happened
     bool overflow = timer_overflow_happened();
     uint64_t cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
-    uint32_t offset = s_timer_ticks_per_us * 2; //remain 2us for more safe
-
-    //If overflow is going to happen in 1us, let's wait until it happens,
-    //else we think it will not happen before new alarm set.
-    //And we should wait current timer count less than ALARM_OVERFLOW_VAL,
-    //maybe equals to 0.
-    if (cur_count + offset >= ALARM_OVERFLOW_VAL) {
-        do {
-            overflow = timer_overflow_happened();
-            cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
-        } while(!overflow || cur_count == ALARM_OVERFLOW_VAL);
-    }
 
     if (overflow) {
         assert(time_after_timebase_us > s_timer_us_per_overflow);
@@ -237,13 +225,17 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
     // Calculate desired timer compare value (may exceed 2^32-1)
     uint64_t compare_val = time_after_timebase_us * s_timer_ticks_per_us;
     uint32_t alarm_reg_val = ALARM_OVERFLOW_VAL;
-    // Use calculated alarm value if it is less than 2^32-1
+    // Use calculated alarm value if it is less than ALARM_OVERFLOW_VAL.
+    // 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;
     if (compare_val < ALARM_OVERFLOW_VAL) {
-        // If we by the time we update ALARM_REG, COUNT_REG value is higher,
-        // interrupt will not happen for another 2^32 timer ticks, so need to
-        // check if alarm value is too close in the future (e.g. <1 us away).
         if (compare_val < cur_count + offset) {
             compare_val = cur_count + offset;
+            if (compare_val > ALARM_OVERFLOW_VAL) {
+                compare_val = ALARM_OVERFLOW_VAL;
+            }
         }
         alarm_reg_val = (uint32_t) compare_val;
     }