mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-22 01:02:57 +00:00
gptimer: add example with various use cases
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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_APB,
|
||||
.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, "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);
|
||||
|
||||
ESP_LOGI(TAG, "Start timer, auto-reload at alarm event");
|
||||
cbs.on_alarm = example_timer_on_alarm_cb_v2;
|
||||
ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
|
||||
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, "Update alarm value dynamically");
|
||||
cbs.on_alarm = example_timer_on_alarm_cb_v3;
|
||||
ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue));
|
||||
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, "Delete timer");
|
||||
ESP_ERROR_CHECK(gptimer_del_timer(gptimer));
|
||||
|
||||
vQueueDelete(queue);
|
||||
}
|
Reference in New Issue
Block a user