timer_group_example_main.c 4.8 KB

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