1 // Copyright 2017 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "sys/param.h"
16 #include "esp_timer_impl.h"
17 #include "esp_timer.h"
18 #include "esp_err.h"
19 #include "esp_system.h"
20 #include "esp_task.h"
21 #include "esp_attr.h"
22 #include "esp_intr_alloc.h"
23 #include "esp_log.h"
24 #include "esp32/clk.h"
25 #include "soc/frc_timer_reg.h"
26 #include "soc/rtc.h"
27 #include "freertos/FreeRTOS.h"
28 #include "freertos/task.h"
29 #include "freertos/semphr.h"
30 
31 /**
32  * @file esp_timer_frc.c
33  * @brief Implementation of chip-specific part of esp_timer
34  *
35  * This implementation uses FRC2 (legacy) timer of the ESP32. This timer is
36  * a 32-bit up-counting timer, with a programmable compare value (called 'alarm'
37  * hereafter). When the timer reaches compare value, interrupt is raised.
38  * The timer can be configured to produce an edge or a level interrupt.
39  *
40  * In this implementation the timer is used for two purposes:
41  * 1. To generate interrupts at certain moments — the upper layer of esp_timer
42  *    uses this to trigger callbacks of esp_timer objects.
43  *
44  * 2. To keep track of time relative to application start. This facility is
45  *    used both by the upper layer of esp_timer and by time functions, such as
46  *    gettimeofday.
47  *
48  * Whenever an esp_timer timer is armed (configured to fire once or
49  * periodically), timer_insert function of the upper layer calls
50  * esp_timer_impl_set_alarm to enable the interrupt at the required moment.
51  * This implementation sets up the timer interrupt to fire at the earliest of
52  * two moments:
53  * a) the time requested by upper layer
54  * b) the time when the timer count reaches 0xffffffff (i.e. is about to overflow)
55  *
56  * Whenever the interrupt fires and timer overflow is detected, interrupt hander
57  * increments s_time_base_us variable, which is used for timekeeping.
58  *
59  * When the interrupt fires, the upper layer is notified, and it dispatches
60  * the callbacks (if any timers have expired) and sets new alarm value (if any
61  * timers are still active).
62  *
63  * At any point in time, esp_timer_impl_get_time will return the current timer
64  * value (expressed in microseconds) plus s_time_base_us. To account for the
65  * case when the timer counter has overflown, but the interrupt has not fired
66  * yet (for example, because interupts are temporarily disabled),
67  * esp_timer_impl_get_time will also check timer overflow flag, and will add
68  * s_timer_us_per_overflow to the returned value.
69  *
70  */
71 
72 /* Timer is clocked from APB. To allow for integer scaling factor between ticks
73  * and microseconds, divider 1 is used. 16 or 256 would not work for APB
74  * frequencies such as 40 or 26 or 2 MHz.
75  */
76 #define TIMER_DIV           1
77 #define TIMER_DIV_CFG       FRC_TIMER_PRESCALER_1
78 
79 /* ALARM_OVERFLOW_VAL is used as timer alarm value when there are not timers
80  * enabled which need to fire within the next timer overflow period. This alarm
81  * is used to perform timekeeping (i.e. to track timer overflows).
82  * Due to the 0xffffffff cannot recognize the real overflow or the scenario that
83  * ISR happens follow set_alarm, so change the ALARM_OVERFLOW_VAL to resolve this problem.
84  * Set it to 0xefffffffUL. The remain 0x10000000UL(about 3 second) is enough to handle ISR.
85  */
86 #define DEFAULT_ALARM_OVERFLOW_VAL 0xefffffffUL
87 
88 /* Provision to set lower overflow value for unit testing. Lowering the
89  * overflow value helps check for race conditions which occur near overflow
90  * moment.
91  */
92 #ifndef ESP_TIMER_DYNAMIC_OVERFLOW_VAL
93 #define ALARM_OVERFLOW_VAL  DEFAULT_ALARM_OVERFLOW_VAL
94 #else
95 static uint32_t s_alarm_overflow_val = DEFAULT_ALARM_OVERFLOW_VAL;
96 #define ALARM_OVERFLOW_VAL (s_alarm_overflow_val)
97 #endif
98 
99 static const char* TAG = "esp_timer_impl";
100 
101 // Interrupt handle returned by the interrupt allocator
102 static intr_handle_t s_timer_interrupt_handle;
103 
104 // Function from the upper layer to be called when the interrupt happens.
105 // Registered in esp_timer_impl_init.
106 static intr_handler_t s_alarm_handler = NULL;
107 
108 // Time in microseconds from startup to the moment
109 // when timer counter was last equal to 0. This variable is updated each time
110 // when timer overflows, and when APB frequency switch is performed.
111 static uint64_t s_time_base_us;
112 
113 // Number of timer ticks per microsecond. Calculated from APB frequency.
114 static uint32_t s_timer_ticks_per_us;
115 
116 // Period between timer overflows, in microseconds.
117 // Equal to 2^32 / s_timer_ticks_per_us.
118 static uint32_t s_timer_us_per_overflow;
119 
120 // When frequency switch happens, timer counter is reset to 0, s_time_base_us
121 // is updated, and alarm value is re-calculated based on the new APB frequency.
122 // However because the frequency switch can happen before the final
123 // interrupt handler is invoked, interrupt handler may see a different alarm
124 // value than the one which caused an interrupt. This can cause interrupt handler
125 // to consider that the interrupt has happened due to timer overflow, incrementing
126 // s_time_base_us. To avoid this, frequency switch hook sets this flag if
127 // it needs to set timer alarm value to ALARM_OVERFLOW_VAL. Interrupt handler
128 // will not increment s_time_base_us if this flag is set.
129 static bool s_mask_overflow;
130 
131 #ifdef CONFIG_PM_USE_RTC_TIMER_REF
132 // If DFS is enabled, upon the first frequency change this value is set to the
133 // difference between esp_timer value and RTC timer value. On every subsequent
134 // frequency change, s_time_base_us is adjusted to maintain the same difference
135 // between esp_timer and RTC timer. (All mentioned values are in microseconds.)
136 static uint64_t s_rtc_time_diff = 0;
137 #endif
138 
139 // Spinlock used to protect access to static variables above and to the hardware
140 // registers.
141 portMUX_TYPE s_time_update_lock = portMUX_INITIALIZER_UNLOCKED;
142 
143 //Use FRC_TIMER_LOAD_VALUE(1) instead of UINT32_MAX, convenience to change FRC TIMER for future
144 #define TIMER_IS_AFTER_OVERFLOW(a) (ALARM_OVERFLOW_VAL < (a) && (a) <= FRC_TIMER_LOAD_VALUE(1))
145 
146 // Check if timer overflow has happened (but was not handled by ISR yet)
timer_overflow_happened(void)147 static inline bool IRAM_ATTR timer_overflow_happened(void)
148 {
149     return ((REG_READ(FRC_TIMER_CTRL_REG(1)) & FRC_TIMER_INT_STATUS) != 0 &&
150               ((REG_READ(FRC_TIMER_ALARM_REG(1)) == ALARM_OVERFLOW_VAL && TIMER_IS_AFTER_OVERFLOW(REG_READ(FRC_TIMER_COUNT_REG(1))) && !s_mask_overflow) ||
151                (!TIMER_IS_AFTER_OVERFLOW(REG_READ(FRC_TIMER_ALARM_REG(1))) && TIMER_IS_AFTER_OVERFLOW(REG_READ(FRC_TIMER_COUNT_REG(1))))));
152 }
153 
timer_count_reload(void)154 static inline void IRAM_ATTR timer_count_reload(void)
155 {
156     //this function should be only called the real overflow happened. And the count cannot be very approach to 0xffffffff.
157     assert(TIMER_IS_AFTER_OVERFLOW(REG_READ(FRC_TIMER_COUNT_REG(1))));
158 
159     /* Restart the timer count by current time count minus ALARM_OVERFLOW_VAL(0xefffffff), it may cause error, if current tick is near boundary.
160      * But even if the error happen 100% per overflow(the distance of each real overflow is about 50 second),
161      * the error is 0.0125us*N per 50s(the FRC time clock is 80MHz), the N is the ticks run by the line following,
162      * Normally, N is less than 10, assume N is 10, so the error accumulation is only 6.48ms per month.
163      * In fact, if the CPU frequency is large than 80MHz. The error accumulation will be more less than 6.48ms per month.
164      * so It can be adopted.
165      */
166     REG_WRITE(FRC_TIMER_LOAD_REG(1), REG_READ(FRC_TIMER_COUNT_REG(1)) - ALARM_OVERFLOW_VAL);
167 }
168 
esp_timer_impl_lock(void)169 void esp_timer_impl_lock(void)
170 {
171     portENTER_CRITICAL(&s_time_update_lock);
172 }
173 
esp_timer_impl_unlock(void)174 void esp_timer_impl_unlock(void)
175 {
176     portEXIT_CRITICAL(&s_time_update_lock);
177 }
178 
esp_timer_impl_get_time(void)179 int64_t IRAM_ATTR esp_timer_impl_get_time(void)
180 {
181     if (s_alarm_handler == NULL) {
182         return 0;
183     }
184     uint32_t timer_val;
185     uint64_t time_base;
186     uint32_t ticks_per_us;
187     bool overflow;
188 
189     do {
190         /* Read all values needed to calculate current time */
191         timer_val = REG_READ(FRC_TIMER_COUNT_REG(1));
192         time_base = s_time_base_us;
193         overflow = timer_overflow_happened();
194         ticks_per_us = s_timer_ticks_per_us;
195 
196         /* Read them again and compare */
197         /* In this function, do not call timer_count_reload() when overflow is true.
198          * Because there's remain count enough to allow FRC_TIMER_COUNT_REG grow
199          */
200         if (REG_READ(FRC_TIMER_COUNT_REG(1)) > timer_val &&
201                 time_base == *((volatile uint64_t*) &s_time_base_us) &&
202                 ticks_per_us == *((volatile uint32_t*) &s_timer_ticks_per_us) &&
203                 overflow == timer_overflow_happened()) {
204             break;
205         }
206 
207         /* If any value has changed (other than the counter increasing), read again */
208     } while(true);
209 
210     uint64_t result = time_base
211                         + timer_val / ticks_per_us;
212     return result;
213 }
214 
215 int64_t esp_timer_get_time(void) __attribute__((alias("esp_timer_impl_get_time")));
216 
esp_timer_impl_set_alarm(uint64_t timestamp)217 void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
218 {
219     portENTER_CRITICAL_SAFE(&s_time_update_lock);
220     timestamp_id[alarm_id] = timestamp;
221     timestamp = MIN(timestamp_id[0], timestamp_id[1]);
222     if (timestamp != UINT64_MAX) {
223         // Use calculated alarm value if it is less than ALARM_OVERFLOW_VAL.
224         // Note that if by the time we update ALARM_REG, COUNT_REG value is higher,
225         // interrupt will not happen for another ALARM_OVERFLOW_VAL timer ticks,
226         // so need to check if alarm value is too close in the future (e.g. <2 us away).
227         int32_t offset = s_timer_ticks_per_us * 2;
228         do {
229             // Adjust current time if overflow has happened
230             if (timer_overflow_happened() ||
231                 ((REG_READ(FRC_TIMER_COUNT_REG(1)) > ALARM_OVERFLOW_VAL) &&
232                 ((REG_READ(FRC_TIMER_CTRL_REG(1)) & FRC_TIMER_INT_STATUS) == 0))) {
233                 // 1. timer_overflow_happened() checks overflow with the interrupt flag.
234                 // 2. During several loops, the counter can be higher than the alarm and even step over ALARM_OVERFLOW_VAL boundary (the interrupt flag is not set).
235                 timer_count_reload();
236                 s_time_base_us += s_timer_us_per_overflow;
237             }
238             s_mask_overflow = false;
239             int64_t cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
240             // Alarm time relative to the moment when counter was 0
241             int64_t time_after_timebase_us = (int64_t)timestamp - s_time_base_us;
242             // Calculate desired timer compare value (may exceed 2^32-1)
243             int64_t compare_val = time_after_timebase_us * s_timer_ticks_per_us;
244 
245             compare_val = MAX(compare_val, cur_count + offset);
246             uint32_t alarm_reg_val = ALARM_OVERFLOW_VAL;
247             if (compare_val < ALARM_OVERFLOW_VAL) {
248                 alarm_reg_val = (uint32_t) compare_val;
249             }
250             REG_WRITE(FRC_TIMER_ALARM_REG(1), alarm_reg_val);
251             int64_t delta = (int64_t)alarm_reg_val - (int64_t)REG_READ(FRC_TIMER_COUNT_REG(1));
252             if (delta <= 0) {
253                 /*
254                     When the timestamp is a bit less than the current counter then the alarm = current_counter + offset.
255                     But due to CPU_freq in some case can be equal APB_freq the offset time can not exceed the overhead
256                     (the alarm will be less than the counter) and it leads to the infinity loop.
257                     To exclude this behavior to the offset was added the delta to have the opportunity to go through it.
258                 */
259                 offset += abs((int)delta) + s_timer_ticks_per_us * 2;
260             } else {
261                 break;
262             }
263         } while (1);
264     portEXIT_CRITICAL_SAFE(&s_time_update_lock);
265 }
266 
267 void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
268 {
269     esp_timer_impl_set_alarm_id(timestamp, 0);
270 }
271 
272 static void IRAM_ATTR timer_alarm_isr(void *arg)
273 {
274     portENTER_CRITICAL_ISR(&s_time_update_lock);
275     // Timekeeping: adjust s_time_base_us if counter has passed ALARM_OVERFLOW_VAL
276     if (timer_overflow_happened()) {
277         timer_count_reload();
278         s_time_base_us += s_timer_us_per_overflow;
279     }
280     s_mask_overflow = false;
281     // Clear interrupt status
282     REG_WRITE(FRC_TIMER_INT_REG(1), FRC_TIMER_INT_CLR);
283     // Set alarm to the next overflow moment. Later, upper layer function may
284     // call esp_timer_impl_set_alarm to change this to an earlier value.
285     REG_WRITE(FRC_TIMER_ALARM_REG(1), ALARM_OVERFLOW_VAL);
286     if ((REG_READ(FRC_TIMER_COUNT_REG(1)) > ALARM_OVERFLOW_VAL) &&
287         ((REG_READ(FRC_TIMER_CTRL_REG(1)) & FRC_TIMER_INT_STATUS) == 0)) {
288         /*
289             This check excludes the case when the alarm can be less than the counter.
290             Without this check, it is possible because DPORT uses 4-lvl, and users can use the 5 Hi-interrupt,
291             they can interrupt this function between FRC_TIMER_INT_CLR and setting the alarm = ALARM_OVERFLOW_VAL
292             that lead to the counter will go ahead leaving the alarm behind.
293         */
294         timer_count_reload();
295         s_time_base_us += s_timer_us_per_overflow;
296     }
297     portEXIT_CRITICAL_ISR(&s_time_update_lock);
298     // Call the upper layer handler
299     (*s_alarm_handler)(arg);
300 }
301 
302 void IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us)
303 {
304     portENTER_CRITICAL_ISR(&s_time_update_lock);
305     /* Bail out if the timer is not initialized yet */
306     if (s_timer_interrupt_handle == NULL) {
307         portEXIT_CRITICAL_ISR(&s_time_update_lock);
308         return;
309     }
310 
311     uint32_t new_ticks_per_us = apb_ticks_per_us / TIMER_DIV;
312     uint32_t alarm = REG_READ(FRC_TIMER_ALARM_REG(1));
313     uint32_t count = REG_READ(FRC_TIMER_COUNT_REG(1));
314     uint64_t ticks_to_alarm = alarm - count;
315     uint64_t new_ticks = (ticks_to_alarm * new_ticks_per_us) / s_timer_ticks_per_us;
316     uint32_t new_alarm_val;
317     if (alarm > count && new_ticks <= ALARM_OVERFLOW_VAL) {
318         new_alarm_val = new_ticks;
319     } else {
320         new_alarm_val = ALARM_OVERFLOW_VAL;
321         if (alarm != ALARM_OVERFLOW_VAL) {
322             s_mask_overflow = true;
323         }
324     }
325     REG_WRITE(FRC_TIMER_ALARM_REG(1), new_alarm_val);
326     REG_WRITE(FRC_TIMER_LOAD_REG(1), 0);
327 
328     s_time_base_us += count / s_timer_ticks_per_us;
329 
330 #ifdef CONFIG_PM_USE_RTC_TIMER_REF
331     // Due to the extra time required to read RTC time, don't attempt this
332     // adjustment when switching to a higher frequency (which usually
333     // happens in an interrupt).
334     if (new_ticks_per_us < s_timer_ticks_per_us) {
335         uint64_t rtc_time = esp_clk_rtc_time();
336         uint64_t new_rtc_time_diff = s_time_base_us - rtc_time;
337         if (s_rtc_time_diff != 0) {
338             uint64_t correction = new_rtc_time_diff - s_rtc_time_diff;
339             s_time_base_us -= correction;
340         } else {
341             s_rtc_time_diff = new_rtc_time_diff;
342         }
343     }
344 #endif // CONFIG_PM_USE_RTC_TIMER_REF
345 
346     s_timer_ticks_per_us = new_ticks_per_us;
347     s_timer_us_per_overflow = ALARM_OVERFLOW_VAL / new_ticks_per_us;
348 
349     portEXIT_CRITICAL_ISR(&s_time_update_lock);
350 }
351 
352 void esp_timer_impl_advance(int64_t time_us)
353 {
354     assert(time_us > 0 && "negative adjustments not supported yet");
355 
356     portENTER_CRITICAL(&s_time_update_lock);
357     uint64_t count = REG_READ(FRC_TIMER_COUNT_REG(1));
358     /* Trigger an ISR to handle past alarms and set new one.
359      * ISR handler will run once we exit the critical section.
360      */
361     REG_WRITE(FRC_TIMER_ALARM_REG(1), 0);
362     REG_WRITE(FRC_TIMER_LOAD_REG(1), 0);
363     s_time_base_us += count / s_timer_ticks_per_us + time_us;
364     portEXIT_CRITICAL(&s_time_update_lock);
365 }
366 
367 esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler)
368 {
369     s_alarm_handler = alarm_handler;
370 
371     esp_err_t err = esp_intr_alloc(ETS_TIMER2_INTR_SOURCE,
372             ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_IRAM,
373             &timer_alarm_isr, NULL, &s_timer_interrupt_handle);
374 
375     if (err != ESP_OK) {
376         ESP_EARLY_LOGE(TAG, "esp_intr_alloc failed (0x%0x)", err);
377         return err;
378     }
379 
380     uint32_t apb_freq = rtc_clk_apb_freq_get();
381     s_timer_ticks_per_us = apb_freq / 1000000 / TIMER_DIV;
382     assert(s_timer_ticks_per_us > 0
383             && apb_freq % TIMER_DIV == 0
384             && "APB frequency does not result in a valid ticks_per_us value");
385     s_timer_us_per_overflow = ALARM_OVERFLOW_VAL / s_timer_ticks_per_us;
386     s_time_base_us = 0;
387 
388     REG_WRITE(FRC_TIMER_ALARM_REG(1), ALARM_OVERFLOW_VAL);
389     REG_WRITE(FRC_TIMER_LOAD_REG(1), 0);
390     REG_WRITE(FRC_TIMER_CTRL_REG(1),
391             TIMER_DIV_CFG | FRC_TIMER_ENABLE | FRC_TIMER_LEVEL_INT);
392     REG_WRITE(FRC_TIMER_INT_REG(1), FRC_TIMER_INT_CLR);
393     ESP_ERROR_CHECK( esp_intr_enable(s_timer_interrupt_handle) );
394 
395     return ESP_OK;
396 }
397 
398 void esp_timer_impl_deinit(void)
399 {
400     esp_intr_disable(s_timer_interrupt_handle);
401 
402     REG_WRITE(FRC_TIMER_CTRL_REG(1), 0);
403     REG_WRITE(FRC_TIMER_ALARM_REG(1), 0);
404     REG_WRITE(FRC_TIMER_LOAD_REG(1), 0);
405 
406     esp_intr_free(s_timer_interrupt_handle);
407     s_timer_interrupt_handle = NULL;
408 }
409 
410 // FIXME: This value is safe for 80MHz APB frequency.
411 // Should be modified to depend on clock frequency.
412 
413 uint64_t IRAM_ATTR esp_timer_impl_get_min_period_us(void)
414 {
415     return 50;
416 }
417 
418 #ifdef ESP_TIMER_DYNAMIC_OVERFLOW_VAL
419 uint32_t esp_timer_impl_get_overflow_val(void)
420 {
421     return s_alarm_overflow_val;
422 }
423 
424 void esp_timer_impl_set_overflow_val(uint32_t overflow_val)
425 {
426     s_alarm_overflow_val = overflow_val;
427     /* update alarm value */
428     esp_timer_impl_update_apb_freq(esp_clk_apb_freq() / 1000000);
429 }
430 #endif // ESP_TIMER_DYNAMIC_OVERFLOW_VAL
431 
432 uint64_t esp_timer_impl_get_counter_reg(void)
433 {
434     return (uint64_t)REG_READ(FRC_TIMER_COUNT_REG(1));
435 }
436 
437 uint64_t esp_timer_impl_get_alarm_reg(void)
438 {
439     return (uint64_t)REG_READ(FRC_TIMER_ALARM_REG(1));
440 }
441 
442 void esp_timer_private_update_apb_freq(uint32_t apb_ticks_per_us) __attribute__((alias("esp_timer_impl_update_apb_freq")));
443 void esp_timer_private_advance(int64_t time_us) __attribute__((alias("esp_timer_impl_advance")));
444 void esp_timer_private_lock(void) __attribute__((alias("esp_timer_impl_lock")));
445 void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock")));
446