gptimer_example_main.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * SPDX-FileCopyrightText: 2010-2022 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/gptimer.h"
  11. #include "esp_log.h"
  12. static const char *TAG = "example";
  13. typedef struct {
  14. uint64_t event_count;
  15. } example_queue_element_t;
  16. static bool IRAM_ATTR example_timer_on_alarm_cb_v1(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  17. {
  18. BaseType_t high_task_awoken = pdFALSE;
  19. QueueHandle_t queue = (QueueHandle_t)user_data;
  20. // stop timer immediately
  21. gptimer_stop(timer);
  22. // Retrieve count value and send to queue
  23. example_queue_element_t ele = {
  24. .event_count = edata->count_value
  25. };
  26. xQueueSendFromISR(queue, &ele, &high_task_awoken);
  27. // return whether we need to yield at the end of ISR
  28. return (high_task_awoken == pdTRUE);
  29. }
  30. static bool IRAM_ATTR example_timer_on_alarm_cb_v2(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  31. {
  32. BaseType_t high_task_awoken = pdFALSE;
  33. QueueHandle_t queue = (QueueHandle_t)user_data;
  34. // Retrieve count value and send to queue
  35. example_queue_element_t ele = {
  36. .event_count = edata->count_value
  37. };
  38. xQueueSendFromISR(queue, &ele, &high_task_awoken);
  39. // return whether we need to yield at the end of ISR
  40. return (high_task_awoken == pdTRUE);
  41. }
  42. static bool IRAM_ATTR example_timer_on_alarm_cb_v3(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  43. {
  44. BaseType_t high_task_awoken = pdFALSE;
  45. QueueHandle_t queue = (QueueHandle_t)user_data;
  46. // Retrieve count value and send to queue
  47. example_queue_element_t ele = {
  48. .event_count = edata->count_value
  49. };
  50. xQueueSendFromISR(queue, &ele, &high_task_awoken);
  51. // reconfigure alarm value
  52. gptimer_alarm_config_t alarm_config = {
  53. .alarm_count = edata->alarm_value + 1000000, // alarm in next 1s
  54. };
  55. gptimer_set_alarm_action(timer, &alarm_config);
  56. // return whether we need to yield at the end of ISR
  57. return (high_task_awoken == pdTRUE);
  58. }
  59. void app_main(void)
  60. {
  61. example_queue_element_t ele;
  62. QueueHandle_t queue = xQueueCreate(10, sizeof(example_queue_element_t));
  63. if (!queue) {
  64. ESP_LOGE(TAG, "Creating queue failed");
  65. return;
  66. }
  67. ESP_LOGI(TAG, "Create timer handle");
  68. gptimer_handle_t gptimer = NULL;
  69. gptimer_config_t timer_config = {
  70. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  71. .direction = GPTIMER_COUNT_UP,
  72. .resolution_hz = 1000000, // 1MHz, 1 tick=1us
  73. };
  74. ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
  75. gptimer_event_callbacks_t cbs = {
  76. .on_alarm = example_timer_on_alarm_cb_v1,
  77. };
  78. ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
  79. ESP_LOGI(TAG, "Enable timer");
  80. ESP_ERROR_CHECK(gptimer_enable(gptimer));
  81. ESP_LOGI(TAG, "Start timer, stop it at alarm event");
  82. gptimer_alarm_config_t alarm_config1 = {
  83. .alarm_count = 1000000, // period = 1s
  84. };
  85. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config1));
  86. ESP_ERROR_CHECK(gptimer_start(gptimer));
  87. if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
  88. ESP_LOGI(TAG, "Timer stopped, count=%llu", ele.event_count);
  89. } else {
  90. ESP_LOGW(TAG, "Missed one count event");
  91. }
  92. ESP_LOGI(TAG, "Set count value");
  93. ESP_ERROR_CHECK(gptimer_set_raw_count(gptimer, 100));
  94. ESP_LOGI(TAG, "Get count value");
  95. uint64_t count;
  96. ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &count));
  97. ESP_LOGI(TAG, "Timer count value=%llu", count);
  98. // before updating the alarm callback, we should make sure the timer is not in the enable state
  99. ESP_LOGI(TAG, "Disable timer");
  100. ESP_ERROR_CHECK(gptimer_disable(gptimer));
  101. // set a new callback function
  102. cbs.on_alarm = example_timer_on_alarm_cb_v2;
  103. ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
  104. ESP_LOGI(TAG, "Enable timer");
  105. ESP_ERROR_CHECK(gptimer_enable(gptimer));
  106. ESP_LOGI(TAG, "Start timer, auto-reload at alarm event");
  107. gptimer_alarm_config_t alarm_config2 = {
  108. .reload_count = 0,
  109. .alarm_count = 1000000, // period = 1s
  110. .flags.auto_reload_on_alarm = true,
  111. };
  112. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config2));
  113. ESP_ERROR_CHECK(gptimer_start(gptimer));
  114. int record = 4;
  115. while (record) {
  116. if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
  117. ESP_LOGI(TAG, "Timer reloaded, count=%llu", ele.event_count);
  118. record--;
  119. } else {
  120. ESP_LOGW(TAG, "Missed one count event");
  121. }
  122. }
  123. ESP_LOGI(TAG, "Stop timer");
  124. ESP_ERROR_CHECK(gptimer_stop(gptimer));
  125. ESP_LOGI(TAG, "Disable timer");
  126. ESP_ERROR_CHECK(gptimer_disable(gptimer));
  127. cbs.on_alarm = example_timer_on_alarm_cb_v3;
  128. ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
  129. ESP_LOGI(TAG, "Enable timer");
  130. ESP_ERROR_CHECK(gptimer_enable(gptimer));
  131. ESP_LOGI(TAG, "Start timer, update alarm value dynamically");
  132. gptimer_alarm_config_t alarm_config3 = {
  133. .alarm_count = 1000000, // period = 1s
  134. };
  135. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config3));
  136. ESP_ERROR_CHECK(gptimer_start(gptimer));
  137. record = 4;
  138. while (record) {
  139. if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
  140. ESP_LOGI(TAG, "Timer alarmed, count=%llu", ele.event_count);
  141. record--;
  142. } else {
  143. ESP_LOGW(TAG, "Missed one count event");
  144. }
  145. }
  146. ESP_LOGI(TAG, "Stop timer");
  147. ESP_ERROR_CHECK(gptimer_stop(gptimer));
  148. ESP_LOGI(TAG, "Disable timer");
  149. ESP_ERROR_CHECK(gptimer_disable(gptimer));
  150. ESP_LOGI(TAG, "Delete timer");
  151. ESP_ERROR_CHECK(gptimer_del_timer(gptimer));
  152. vQueueDelete(queue);
  153. }