| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /*
- * SPDX-FileCopyrightText: 2010-2021 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/timer.h"
- #include "esp_log.h"
- #define TIMER_RESOLUTION_HZ 1000000 // 1MHz resolution
- #define TIMER_ALARM_PERIOD_S 0.5 // Alarm period 0.5s
- static const char *TAG = "example";
- /**
- * @brief A sample structure to pass events from the timer ISR to task
- */
- typedef struct {
- uint64_t timer_count_value;
- } example_timer_event_t;
- /**
- * @brief Timer user data, will be pass to timer alarm callback
- */
- typedef struct {
- xQueueHandle user_queue;
- int timer_group;
- int timer_idx;
- int alarm_value;
- bool auto_reload;
- } example_timer_user_data_t;
- static bool IRAM_ATTR timer_group_isr_callback(void *args)
- {
- BaseType_t high_task_awoken = pdFALSE;
- example_timer_user_data_t *user_data = (example_timer_user_data_t *) args;
- // fetch current count value
- uint64_t timer_count_value = timer_group_get_counter_value_in_isr(user_data->timer_group, user_data->timer_idx);
- example_timer_event_t evt = {
- .timer_count_value = timer_count_value,
- };
- // set new alarm value if necessary
- if (!user_data->auto_reload) {
- user_data->alarm_value += TIMER_ALARM_PERIOD_S * TIMER_RESOLUTION_HZ;
- timer_group_set_alarm_value_in_isr(user_data->timer_group, user_data->timer_idx, user_data->alarm_value);
- }
- // Send the event data back to the main program task
- xQueueSendFromISR(user_data->user_queue, &evt, &high_task_awoken);
- return high_task_awoken == pdTRUE; // return whether a task switch is needed
- }
- static void example_tg_timer_init(example_timer_user_data_t *user_data)
- {
- int group = user_data->timer_group;
- int timer = user_data->timer_idx;
- timer_config_t config = {
- .clk_src = TIMER_SRC_CLK_APB,
- .divider = APB_CLK_FREQ / TIMER_RESOLUTION_HZ,
- .counter_dir = TIMER_COUNT_UP,
- .counter_en = TIMER_PAUSE,
- .alarm_en = TIMER_ALARM_EN,
- .auto_reload = user_data->auto_reload,
- };
- ESP_ERROR_CHECK(timer_init(group, timer, &config));
- // For the timer counter to a initial value
- ESP_ERROR_CHECK(timer_set_counter_value(group, timer, 0));
- // Set alarm value and enable alarm interrupt
- ESP_ERROR_CHECK(timer_set_alarm_value(group, timer, user_data->alarm_value));
- ESP_ERROR_CHECK(timer_enable_intr(group, timer));
- // Hook interrupt callback
- ESP_ERROR_CHECK(timer_isr_callback_add(group, timer, timer_group_isr_callback, user_data, 0));
- // Start timer
- ESP_ERROR_CHECK(timer_start(group, timer));
- }
- static void example_tg_timer_deinit(int group, int timer)
- {
- ESP_ERROR_CHECK(timer_isr_callback_remove(group, timer));
- ESP_ERROR_CHECK(timer_deinit(group, timer));
- }
- void app_main(void)
- {
- example_timer_user_data_t *user_data = calloc(1, sizeof(example_timer_user_data_t));
- assert(user_data);
- user_data->user_queue = xQueueCreate(10, sizeof(example_timer_event_t));
- assert(user_data->user_queue);
- user_data->timer_group = 0;
- user_data->timer_idx = 0;
- user_data->alarm_value = TIMER_ALARM_PERIOD_S * TIMER_RESOLUTION_HZ;
- ESP_LOGI(TAG, "Init timer with auto-reload");
- user_data->auto_reload = true;
- example_tg_timer_init(user_data);
- example_timer_event_t evt;
- uint32_t test_count = 4;
- while (test_count--) {
- xQueueReceive(user_data->user_queue, &evt, portMAX_DELAY);
- ESP_LOGI(TAG, "Timer auto reloaded, count value in ISR: %llu", evt.timer_count_value);
- }
- example_tg_timer_deinit(user_data->timer_group, user_data->timer_idx);
- ESP_LOGI(TAG, "Init timer without auto-reload");
- user_data->auto_reload = false;
- example_tg_timer_init(user_data);
- test_count = 4;
- while (test_count--) {
- xQueueReceive(user_data->user_queue, &evt, portMAX_DELAY);
- ESP_LOGI(TAG, "Timer alarmed at %llu", evt.timer_count_value);
- }
- example_tg_timer_deinit(user_data->timer_group, user_data->timer_idx);
- vQueueDelete(user_data->user_queue);
- free(user_data);
- }
|