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