| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /*
- * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: CC0-1.0
- */
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #include "driver/gptimer.h"
- #include "esp_log.h"
- static const char *TAG = "example";
- typedef struct {
- uint64_t event_count;
- } example_queue_element_t;
- static bool IRAM_ATTR example_timer_on_alarm_cb_v1(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
- {
- BaseType_t high_task_awoken = pdFALSE;
- QueueHandle_t queue = (QueueHandle_t)user_data;
- // stop timer immediately
- gptimer_stop(timer);
- // Retrieve count value and send to queue
- example_queue_element_t ele = {
- .event_count = edata->count_value
- };
- xQueueSendFromISR(queue, &ele, &high_task_awoken);
- // return whether we need to yield at the end of ISR
- return (high_task_awoken == pdTRUE);
- }
- static bool IRAM_ATTR example_timer_on_alarm_cb_v2(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
- {
- BaseType_t high_task_awoken = pdFALSE;
- QueueHandle_t queue = (QueueHandle_t)user_data;
- // Retrieve count value and send to queue
- example_queue_element_t ele = {
- .event_count = edata->count_value
- };
- xQueueSendFromISR(queue, &ele, &high_task_awoken);
- // return whether we need to yield at the end of ISR
- return (high_task_awoken == pdTRUE);
- }
- static bool IRAM_ATTR example_timer_on_alarm_cb_v3(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
- {
- BaseType_t high_task_awoken = pdFALSE;
- QueueHandle_t queue = (QueueHandle_t)user_data;
- // Retrieve count value and send to queue
- example_queue_element_t ele = {
- .event_count = edata->count_value
- };
- xQueueSendFromISR(queue, &ele, &high_task_awoken);
- // reconfigure alarm value
- gptimer_alarm_config_t alarm_config = {
- .alarm_count = edata->alarm_value + 1000000, // alarm in next 1s
- };
- gptimer_set_alarm_action(timer, &alarm_config);
- // return whether we need to yield at the end of ISR
- return (high_task_awoken == pdTRUE);
- }
- void app_main(void)
- {
- example_queue_element_t ele;
- QueueHandle_t queue = xQueueCreate(10, sizeof(example_queue_element_t));
- if (!queue) {
- ESP_LOGE(TAG, "Creating queue failed");
- return;
- }
- ESP_LOGI(TAG, "Create timer handle");
- gptimer_handle_t gptimer = NULL;
- gptimer_config_t timer_config = {
- .clk_src = GPTIMER_CLK_SRC_DEFAULT,
- .direction = GPTIMER_COUNT_UP,
- .resolution_hz = 1000000, // 1MHz, 1 tick=1us
- };
- ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
- gptimer_event_callbacks_t cbs = {
- .on_alarm = example_timer_on_alarm_cb_v1,
- };
- ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
- ESP_LOGI(TAG, "Enable timer");
- ESP_ERROR_CHECK(gptimer_enable(gptimer));
- ESP_LOGI(TAG, "Start timer, stop it at alarm event");
- gptimer_alarm_config_t alarm_config1 = {
- .alarm_count = 1000000, // period = 1s
- };
- ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config1));
- ESP_ERROR_CHECK(gptimer_start(gptimer));
- if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
- ESP_LOGI(TAG, "Timer stopped, count=%llu", ele.event_count);
- } else {
- ESP_LOGW(TAG, "Missed one count event");
- }
- ESP_LOGI(TAG, "Set count value");
- ESP_ERROR_CHECK(gptimer_set_raw_count(gptimer, 100));
- ESP_LOGI(TAG, "Get count value");
- uint64_t count;
- ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &count));
- ESP_LOGI(TAG, "Timer count value=%llu", count);
- // before updating the alarm callback, we should make sure the timer is not in the enable state
- ESP_LOGI(TAG, "Disable timer");
- ESP_ERROR_CHECK(gptimer_disable(gptimer));
- // set a new callback function
- cbs.on_alarm = example_timer_on_alarm_cb_v2;
- ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
- ESP_LOGI(TAG, "Enable timer");
- ESP_ERROR_CHECK(gptimer_enable(gptimer));
- ESP_LOGI(TAG, "Start timer, auto-reload at alarm event");
- gptimer_alarm_config_t alarm_config2 = {
- .reload_count = 0,
- .alarm_count = 1000000, // period = 1s
- .flags.auto_reload_on_alarm = true,
- };
- ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config2));
- ESP_ERROR_CHECK(gptimer_start(gptimer));
- int record = 4;
- while (record) {
- if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
- ESP_LOGI(TAG, "Timer reloaded, count=%llu", ele.event_count);
- record--;
- } else {
- ESP_LOGW(TAG, "Missed one count event");
- }
- }
- ESP_LOGI(TAG, "Stop timer");
- ESP_ERROR_CHECK(gptimer_stop(gptimer));
- ESP_LOGI(TAG, "Disable timer");
- ESP_ERROR_CHECK(gptimer_disable(gptimer));
- cbs.on_alarm = example_timer_on_alarm_cb_v3;
- ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
- ESP_LOGI(TAG, "Enable timer");
- ESP_ERROR_CHECK(gptimer_enable(gptimer));
- ESP_LOGI(TAG, "Start timer, update alarm value dynamically");
- gptimer_alarm_config_t alarm_config3 = {
- .alarm_count = 1000000, // period = 1s
- };
- ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config3));
- ESP_ERROR_CHECK(gptimer_start(gptimer));
- record = 4;
- while (record) {
- if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(2000))) {
- ESP_LOGI(TAG, "Timer alarmed, count=%llu", ele.event_count);
- record--;
- } else {
- ESP_LOGW(TAG, "Missed one count event");
- }
- }
- ESP_LOGI(TAG, "Stop timer");
- ESP_ERROR_CHECK(gptimer_stop(gptimer));
- ESP_LOGI(TAG, "Disable timer");
- ESP_ERROR_CHECK(gptimer_disable(gptimer));
- ESP_LOGI(TAG, "Delete timer");
- ESP_ERROR_CHECK(gptimer_del_timer(gptimer));
- vQueueDelete(queue);
- }
|