gptimer_example_main.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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_APB,
  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, "Start timer, stop it at alarm event");
  80. gptimer_alarm_config_t alarm_config1 = {
  81. .alarm_count = 1000000, // period = 1s
  82. };
  83. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config1));
  84. ESP_ERROR_CHECK(gptimer_start(gptimer));
  85. if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
  86. ESP_LOGI(TAG, "Timer stopped, count=%llu", ele.event_count);
  87. } else {
  88. ESP_LOGW(TAG, "Missed one count event");
  89. }
  90. ESP_LOGI(TAG, "Set count value");
  91. ESP_ERROR_CHECK(gptimer_set_raw_count(gptimer, 100));
  92. ESP_LOGI(TAG, "Get count value");
  93. uint64_t count;
  94. ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &count));
  95. ESP_LOGI(TAG, "Timer count value=%llu", count);
  96. ESP_LOGI(TAG, "Start timer, auto-reload at alarm event");
  97. cbs.on_alarm = example_timer_on_alarm_cb_v2;
  98. ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
  99. gptimer_alarm_config_t alarm_config2 = {
  100. .reload_count = 0,
  101. .alarm_count = 1000000, // period = 1s
  102. .flags.auto_reload_on_alarm = true,
  103. };
  104. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config2));
  105. ESP_ERROR_CHECK(gptimer_start(gptimer));
  106. int record = 4;
  107. while (record) {
  108. if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
  109. ESP_LOGI(TAG, "Timer reloaded, count=%llu", ele.event_count);
  110. record--;
  111. } else {
  112. ESP_LOGW(TAG, "Missed one count event");
  113. }
  114. }
  115. ESP_LOGI(TAG, "Stop timer");
  116. ESP_ERROR_CHECK(gptimer_stop(gptimer));
  117. ESP_LOGI(TAG, "Update alarm value dynamically");
  118. cbs.on_alarm = example_timer_on_alarm_cb_v3;
  119. ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
  120. gptimer_alarm_config_t alarm_config3 = {
  121. .alarm_count = 1000000, // period = 1s
  122. };
  123. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config3));
  124. ESP_ERROR_CHECK(gptimer_start(gptimer));
  125. record = 4;
  126. while (record) {
  127. if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
  128. ESP_LOGI(TAG, "Timer alarmed, count=%llu", ele.event_count);
  129. record--;
  130. } else {
  131. ESP_LOGW(TAG, "Missed one count event");
  132. }
  133. }
  134. ESP_LOGI(TAG, "Stop timer");
  135. ESP_ERROR_CHECK(gptimer_stop(gptimer));
  136. ESP_LOGI(TAG, "Delete timer");
  137. ESP_ERROR_CHECK(gptimer_del_timer(gptimer));
  138. vQueueDelete(queue);
  139. }