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