• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010-2019 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 #pragma once
16 
17 #include "esp_err.h"
18 #include "esp_attr.h"
19 #include "soc/soc.h"
20 #include "soc/timer_periph.h"
21 #include "esp_intr_alloc.h"
22 #include "hal/timer_types.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #define TIMER_BASE_CLK   (APB_CLK_FREQ)  /*!< Frequency of the clock on the input of the timer groups */
29 
30 /**
31  * @brief Interrupt handle callback function. User need to retrun a bool value
32  *        in callback.
33  *
34  * @return
35  *     - True Do task yield at the end of ISR
36  *     - False Not do task yield at the end of ISR
37  *
38  * @note If you called FreeRTOS functions in callback, you need to return true or false based on
39  *       the retrun value of argument `pxHigherPriorityTaskWoken`.
40  *       For example, `xQueueSendFromISR` is called in callback, if the return value `pxHigherPriorityTaskWoken`
41  *       of any FreeRTOS calls is pdTRUE, return true; otherwise return false.
42  */
43 typedef bool (*timer_isr_t)(void *);
44 
45 /**
46  * @brief Interrupt handle, used in order to free the isr after use.
47  * Aliases to an int handle for now.
48  */
49 typedef intr_handle_t timer_isr_handle_t;
50 
51 /**
52  * @brief Read the counter value of hardware timer.
53  *
54  * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
55  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
56  * @param timer_val Pointer to accept timer counter value.
57  *
58  * @return
59  *     - ESP_OK Success
60  *     - ESP_ERR_INVALID_ARG Parameter error
61  */
62 esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *timer_val);
63 
64 /**
65  * @brief Read the counter value of hardware timer, in unit of a given scale.
66  *
67  * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
68  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
69  * @param time Pointer, type of double*, to accept timer counter value, in seconds.
70  *
71  * @return
72  *     - ESP_OK Success
73  *     - ESP_ERR_INVALID_ARG Parameter error
74  */
75 esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_num, double *time);
76 
77 /**
78  * @brief Set counter value to hardware timer.
79  *
80  * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
81  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
82  * @param load_val Counter value to write to the hardware timer.
83  *
84  * @return
85  *     - ESP_OK Success
86  *     - ESP_ERR_INVALID_ARG Parameter error
87  */
88 esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val);
89 
90 /**
91  * @brief Start the counter of hardware timer.
92  *
93  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
94  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
95  *
96  * @return
97  *     - ESP_OK Success
98  *     - ESP_ERR_INVALID_ARG Parameter error
99  */
100 esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num);
101 
102 /**
103  * @brief Pause the counter of hardware timer.
104  *
105  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
106  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
107  *
108  * @return
109  *     - ESP_OK Success
110  *     - ESP_ERR_INVALID_ARG Parameter error
111  */
112 esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num);
113 
114 /**
115  * @brief Set counting mode for hardware timer.
116  *
117  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
118  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
119  * @param counter_dir Counting direction of timer, count-up or count-down
120  *
121  * @return
122  *     - ESP_OK Success
123  *     - ESP_ERR_INVALID_ARG Parameter error
124  */
125 esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir);
126 
127 /**
128  * @brief Enable or disable counter reload function when alarm event occurs.
129  *
130  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
131  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
132  * @param reload Counter reload mode.
133  *
134  * @return
135  *     - ESP_OK Success
136  *     - ESP_ERR_INVALID_ARG Parameter error
137  */
138 esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload);
139 
140 /**
141  * @brief Set hardware timer source clock divider. Timer groups clock are divider from APB clock.
142  *
143  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
144  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
145  * @param divider Timer clock divider value. The divider's range is from from 2 to 65536.
146  *
147  * @return
148  *     - ESP_OK Success
149  *     - ESP_ERR_INVALID_ARG Parameter error
150  */
151 esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint32_t divider);
152 
153 /**
154  * @brief Set timer alarm value.
155  *
156  * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
157  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
158  * @param alarm_value A 64-bit value to set the alarm value.
159  *
160  * @return
161  *     - ESP_OK Success
162  *     - ESP_ERR_INVALID_ARG Parameter error
163  */
164 esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value);
165 
166 /**
167  * @brief Get timer alarm value.
168  *
169  * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
170  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
171  * @param alarm_value Pointer of A 64-bit value to accept the alarm value.
172  *
173  * @return
174  *     - ESP_OK Success
175  *     - ESP_ERR_INVALID_ARG Parameter error
176  */
177 esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *alarm_value);
178 
179 /**
180  * @brief Enable or disable generation of timer alarm events.
181  *
182  * @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
183  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
184  * @param alarm_en To enable or disable timer alarm function.
185  *
186  * @return
187  *     - ESP_OK Success
188  *     - ESP_ERR_INVALID_ARG Parameter error
189  */
190 esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en);
191 
192 /**
193  * @brief Add ISR handle callback for the corresponding timer.
194  *
195  * @param group_num Timer group number
196  * @param timer_num Timer index of timer group
197  * @param isr_handler Interrupt handler function, it is a callback function.
198  * @param arg Parameter for handler function
199  * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
200  *        ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
201  *
202  * @note This ISR handler will be called from an ISR.
203  *       This ISR handler do not need to handle interrupt status, and should be kept short.
204  *       If you want to realize some specific applications or write the whole ISR, you can
205  *       call timer_isr_register(...) to register ISR.
206  *
207  *       The callback should return a bool value to determine whether need to do YIELD at
208  *       the end of the ISR.
209  *
210  *       If the intr_alloc_flags value ESP_INTR_FLAG_IRAM is set,
211  *       the handler function must be declared with IRAM_ATTR attribute
212  *       and can only call functions in IRAM or ROM. It cannot call other timer APIs.
213  *
214  * @return
215  *     - ESP_OK Success
216  *     - ESP_ERR_INVALID_ARG Parameter error
217  */
218 esp_err_t timer_isr_callback_add(timer_group_t group_num, timer_idx_t timer_num, timer_isr_t isr_handler, void *arg, int intr_alloc_flags);
219 
220 /**
221  * @brief Remove ISR handle callback for the corresponding timer.
222  *
223  * @param group_num Timer group number
224  * @param timer_num Timer index of timer group
225  *
226  * @return
227  *     - ESP_OK Success
228  *     - ESP_ERR_INVALID_ARG Parameter error
229  */
230 esp_err_t timer_isr_callback_remove(timer_group_t group_num, timer_idx_t timer_num);
231 
232 /**
233  * @brief Register Timer interrupt handler, the handler is an ISR.
234  *        The handler will be attached to the same CPU core that this function is running on.
235  *
236  * @param group_num Timer group number
237  * @param timer_num Timer index of timer group
238  * @param fn Interrupt handler function.
239  * @param arg Parameter for handler function
240  * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
241  *        ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
242  * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will
243  *        be returned here.
244  *
245  * @note If use this function to reigster ISR, you need to write the whole ISR.
246  *       In the interrupt handler, you need to call timer_spinlock_take(..) before
247  *       your handling, and call timer_spinlock_give(...) after your handling.
248  *
249  *       If the intr_alloc_flags value ESP_INTR_FLAG_IRAM is set,
250  *       the handler function must be declared with IRAM_ATTR attribute
251  *       and can only call functions in IRAM or ROM. It cannot call other timer APIs.
252  *       Use direct register access to configure timers from inside the ISR in this case.
253  *
254  * @return
255  *     - ESP_OK Success
256  *     - ESP_ERR_INVALID_ARG Parameter error
257  */
258 esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, void (*fn)(void *), void *arg, int intr_alloc_flags, timer_isr_handle_t *handle);
259 
260 /** @brief Initializes and configure the timer.
261  *
262  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
263  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
264  * @param config Pointer to timer initialization parameters.
265  *
266  * @return
267  *     - ESP_OK Success
268  *     - ESP_ERR_INVALID_ARG Parameter error
269  */
270 esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer_config_t *config);
271 
272 /** @brief Deinitializes the timer.
273  *
274  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
275  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
276  *
277  * @return
278  *     - ESP_OK Success
279  *     - ESP_ERR_INVALID_ARG Parameter error
280  */
281 esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num);
282 
283 /** @brief Get timer configure value.
284  *
285  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
286  * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
287  * @param config Pointer of struct to accept timer parameters.
288  *
289  * @return
290  *     - ESP_OK Success
291  *     - ESP_ERR_INVALID_ARG Parameter error
292  */
293 esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config);
294 
295 /** @brief Enable timer group interrupt, by enable mask
296  *
297  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
298  * @param intr_mask Timer interrupt enable mask.
299  *          - TIMER_INTR_T0: t0 interrupt
300  *          - TIMER_INTR_T1: t1 interrupt
301  *          - TIMER_INTR_WDT: watchdog interrupt
302  *
303  * @return
304  *     - ESP_OK Success
305  *     - ESP_ERR_INVALID_ARG Parameter error
306  */
307 esp_err_t timer_group_intr_enable(timer_group_t group_num, timer_intr_t intr_mask);
308 
309 /** @brief Disable timer group interrupt, by disable mask
310  *
311  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
312  * @param intr_mask Timer interrupt disable mask.
313  *          - TIMER_INTR_T0: t0 interrupt
314  *          - TIMER_INTR_T1: t1 interrupt
315  *          - TIMER_INTR_WDT: watchdog interrupt
316  *
317  * @return
318  *     - ESP_OK Success
319  *     - ESP_ERR_INVALID_ARG Parameter error
320  */
321 esp_err_t timer_group_intr_disable(timer_group_t group_num, timer_intr_t intr_mask);
322 
323 /** @brief Enable timer interrupt
324  *
325  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
326  * @param timer_num Timer index.
327  *
328  * @return
329  *     - ESP_OK Success
330  *     - ESP_ERR_INVALID_ARG Parameter error
331  */
332 esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num);
333 
334 /** @brief Disable timer interrupt
335  *
336  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
337  * @param timer_num Timer index.
338  *
339  * @return
340  *     - ESP_OK Success
341  *     - ESP_ERR_INVALID_ARG Parameter error
342  */
343 esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num);
344 
345 /** @brief Clear timer interrupt status, just used in ISR
346  *
347  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
348  * @param timer_num Timer index.
349  *
350  */
351 void timer_group_intr_clr_in_isr(timer_group_t group_num, timer_idx_t timer_num) __attribute__((deprecated));
352 
353 /** @brief Clear timer interrupt status, just used in ISR
354  *
355  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
356  * @param timer_num Timer index.
357  *
358  */
359 void timer_group_clr_intr_status_in_isr(timer_group_t group_num, timer_idx_t timer_num);
360 
361 /** @brief Enable alarm interrupt, just used in ISR
362  *
363  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
364  * @param timer_num Timer index.
365  *
366  */
367 void timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num);
368 
369 /** @brief Get the current counter value, just used in ISR
370  *
371  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
372  * @param timer_num Timer index.
373  *
374  * @return
375  *     - Counter value
376  */
377 uint64_t timer_group_get_counter_value_in_isr(timer_group_t group_num, timer_idx_t timer_num);
378 
379 /** @brief Set the alarm threshold for the timer, just used in ISR
380  *
381  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
382  * @param timer_num Timer index.
383  * @param alarm_val Alarm threshold.
384  *
385  */
386 void timer_group_set_alarm_value_in_isr(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_val);
387 
388 /** @brief Enable/disable a counter, just used in ISR
389  *
390  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
391  * @param timer_num Timer index.
392  * @param counter_en Enable/disable.
393  *
394  */
395 void timer_group_set_counter_enable_in_isr(timer_group_t group_num, timer_idx_t timer_num, timer_start_t counter_en);
396 
397 /** @brief Get the masked interrupt status, just used in ISR
398  *
399  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
400  *
401  * @return
402  *     - Interrupt status
403  */
404 timer_intr_t timer_group_intr_get_in_isr(timer_group_t group_num) __attribute__((deprecated));
405 
406 /** @brief Get interrupt status, just used in ISR
407  *
408  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
409  *
410  * @return
411  *     - Interrupt status
412  */
413 uint32_t timer_group_get_intr_status_in_isr(timer_group_t group_num);
414 
415 /** @brief Clear the masked interrupt status, just used in ISR
416  *
417  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
418  * @param intr_mask Masked interrupt.
419  *
420  */
421 void timer_group_clr_intr_sta_in_isr(timer_group_t group_num, timer_intr_t intr_mask) __attribute__((deprecated));
422 
423 /** @brief Get auto reload enable status, just used in ISR
424  *
425  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
426  * @param timer_num Timer index
427  *
428  * @return
429  *     - True Auto reload enabled
430  *     - False Auto reload disabled
431  */
432 bool timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer_idx_t timer_num);
433 
434 /** @brief Take timer spinlock to enter critical protect
435  *
436  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
437  *
438  * @return
439  *     - ESP_OK Success
440  *     - ESP_ERR_INVALID_ARG Parameter error
441  */
442 esp_err_t timer_spinlock_take(timer_group_t group_num);
443 
444 /** @brief Give timer spinlock to exit critical protect
445  *
446  * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
447  *
448  * @return
449  *     - ESP_OK Success
450  *     - ESP_ERR_INVALID_ARG Parameter error
451  */
452 esp_err_t timer_spinlock_give(timer_group_t group_num);
453 
454 #ifdef __cplusplus
455 }
456 #endif
457