#include "timer.h" #include #include "driver/gptimer.h" #include "esp_err.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" static const char *TAG = "TIMER"; static gptimer_handle_t gptimer = NULL; QueueHandle_t queue; typedef struct { uint64_t event_count; } queue_callback_element_t; queue_callback_element_t item; bool 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; queue_callback_element_t ele = { .event_count = edata->alarm_value}; xQueueSendFromISR(queue, &ele, &high_task_awoken); // return whether we need to yield at the end of ISR return (high_task_awoken == pdTRUE); } void yx_timer_init(struct timer_param_s *params) { // create queue queue = xQueueCreate(1, sizeof(queue_callback_element_t)); if (!queue) { ESP_LOGE(TAG, "creating queue error"); return; } gptimer_config_t timer_config = { // 初始化参数设置 .clk_src = GPTIMER_CLK_SRC_DEFAULT, // 选择时钟源 .direction = GPTIMER_COUNT_UP, // 向上计数 .resolution_hz = 1 * 1000 * 1000, // 1MHz, 1 tick = 1us 设置定时时间 }; ESP_LOGI(TAG, "Start timer, stop it at alarm event"); ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer)); // 创建一个通用定时器,返回任务句柄 gptimer_event_callbacks_t cbs = { // 中断回调函数(alrm中断) .on_alarm = example_timer_on_alarm_cb_v1, }; ESP_LOGI(TAG, "Enable timer"); ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue)); // 第一次调用这个函数需要在调用gptimer_enable之前 //ESP_ERROR_CHECK(gptimer_enable(gptimer)); // 使能定时器中断 ESP_LOGI(TAG, "Start timer, auto-reload at alarm event"); gptimer_alarm_config_t alarm_config = { .reload_count = 0, .alarm_count = 1000000 * params->interval, // period = 5s .flags.auto_reload_on_alarm = true, }; ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config)); } void yx_timer_start(struct timer_param_s *params) { gptimer_enable(gptimer); ESP_ERROR_CHECK(gptimer_start(gptimer)); if (xQueueReceive(queue, &item, portMAX_DELAY)) { if (params->timerCbFunc != NULL) { params->timerCbFunc(); } vQueueDelete(queue); } else { ESP_LOGW(TAG, "Missed one count event"); } } void yx_timer_stop(struct timer_param_s *params) { ESP_ERROR_CHECK(gptimer_stop(gptimer)); //gptimer_disable(gptimer); }