timer_group_example_main.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "freertos/queue.h"
  10. #include "driver/timer.h"
  11. #define TIMER_DIVIDER (16) // Hardware timer clock divider
  12. #define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
  13. typedef struct {
  14. int timer_group;
  15. int timer_idx;
  16. int alarm_interval;
  17. bool auto_reload;
  18. } example_timer_info_t;
  19. /**
  20. * @brief A sample structure to pass events from the timer ISR to task
  21. *
  22. */
  23. typedef struct {
  24. example_timer_info_t info;
  25. uint64_t timer_counter_value;
  26. } example_timer_event_t;
  27. static xQueueHandle s_timer_queue;
  28. /*
  29. * A simple helper function to print the raw timer counter value
  30. * and the counter value converted to seconds
  31. */
  32. static void inline print_timer_counter(uint64_t counter_value)
  33. {
  34. printf("Counter: 0x%08x%08x\r\n", (uint32_t) (counter_value >> 32),
  35. (uint32_t) (counter_value));
  36. printf("Time : %.8f s\r\n", (double) counter_value / TIMER_SCALE);
  37. }
  38. static bool IRAM_ATTR timer_group_isr_callback(void *args)
  39. {
  40. BaseType_t high_task_awoken = pdFALSE;
  41. example_timer_info_t *info = (example_timer_info_t *) args;
  42. uint64_t timer_counter_value = timer_group_get_counter_value_in_isr(info->timer_group, info->timer_idx);
  43. /* Prepare basic event data that will be then sent back to task */
  44. example_timer_event_t evt = {
  45. .info.timer_group = info->timer_group,
  46. .info.timer_idx = info->timer_idx,
  47. .info.auto_reload = info->auto_reload,
  48. .info.alarm_interval = info->alarm_interval,
  49. .timer_counter_value = timer_counter_value
  50. };
  51. if (!info->auto_reload) {
  52. timer_counter_value += info->alarm_interval * TIMER_SCALE;
  53. timer_group_set_alarm_value_in_isr(info->timer_group, info->timer_idx, timer_counter_value);
  54. }
  55. /* Now just send the event data back to the main program task */
  56. xQueueSendFromISR(s_timer_queue, &evt, &high_task_awoken);
  57. return high_task_awoken == pdTRUE; // return whether we need to yield at the end of ISR
  58. }
  59. /**
  60. * @brief Initialize selected timer of timer group
  61. *
  62. * @param group Timer Group number, index from 0
  63. * @param timer timer ID, index from 0
  64. * @param auto_reload whether auto-reload on alarm event
  65. * @param timer_interval_sec interval of alarm
  66. */
  67. static void example_tg_timer_init(int group, int timer, bool auto_reload, int timer_interval_sec)
  68. {
  69. /* Select and initialize basic parameters of the timer */
  70. timer_config_t config = {
  71. .divider = TIMER_DIVIDER,
  72. .counter_dir = TIMER_COUNT_UP,
  73. .counter_en = TIMER_PAUSE,
  74. .alarm_en = TIMER_ALARM_EN,
  75. .auto_reload = auto_reload,
  76. }; // default clock source is APB
  77. timer_init(group, timer, &config);
  78. /* Timer's counter will initially start from value below.
  79. Also, if auto_reload is set, this value will be automatically reload on alarm */
  80. timer_set_counter_value(group, timer, 0);
  81. /* Configure the alarm value and the interrupt on alarm. */
  82. timer_set_alarm_value(group, timer, timer_interval_sec * TIMER_SCALE);
  83. timer_enable_intr(group, timer);
  84. example_timer_info_t *timer_info = calloc(1, sizeof(example_timer_info_t));
  85. timer_info->timer_group = group;
  86. timer_info->timer_idx = timer;
  87. timer_info->auto_reload = auto_reload;
  88. timer_info->alarm_interval = timer_interval_sec;
  89. timer_isr_callback_add(group, timer, timer_group_isr_callback, timer_info, 0);
  90. timer_start(group, timer);
  91. }
  92. void app_main(void)
  93. {
  94. s_timer_queue = xQueueCreate(10, sizeof(example_timer_event_t));
  95. example_tg_timer_init(TIMER_GROUP_0, TIMER_0, true, 3);
  96. example_tg_timer_init(TIMER_GROUP_1, TIMER_0, false, 5);
  97. while (1) {
  98. example_timer_event_t evt;
  99. xQueueReceive(s_timer_queue, &evt, portMAX_DELAY);
  100. /* Print information that the timer reported an event */
  101. if (evt.info.auto_reload) {
  102. printf("Timer Group with auto reload\n");
  103. } else {
  104. printf("Timer Group without auto reload\n");
  105. }
  106. printf("Group[%d], timer[%d] alarm event\n", evt.info.timer_group, evt.info.timer_idx);
  107. /* Print the timer values passed by event */
  108. printf("------- EVENT TIME --------\n");
  109. print_timer_counter(evt.timer_counter_value);
  110. /* Print the timer values as visible by this task */
  111. printf("-------- TASK TIME --------\n");
  112. uint64_t task_counter_value;
  113. timer_get_counter_value(evt.info.timer_group, evt.info.timer_idx, &task_counter_value);
  114. print_timer_counter(task_counter_value);
  115. }
  116. }