Files
esp-idf/examples/peripherals/timer_group/main/timer_group_example_main.c
T

140 lines
4.7 KiB
C
Raw Normal View History

2021-09-27 12:46:51 +08:00
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
2016-11-23 02:15:27 +08:00
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/timer.h"
2021-02-01 14:10:15 +08:00
#define TIMER_DIVIDER (16) // Hardware timer clock divider
2017-09-25 06:20:12 +02:00
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
2016-11-23 02:15:27 +08:00
typedef struct {
2017-09-25 06:20:12 +02:00
int timer_group;
int timer_idx;
2021-02-01 14:10:15 +08:00
int alarm_interval;
bool auto_reload;
} example_timer_info_t;
/**
* @brief A sample structure to pass events from the timer ISR to task
*
*/
typedef struct {
example_timer_info_t info;
2017-09-25 06:20:12 +02:00
uint64_t timer_counter_value;
2021-02-01 14:10:15 +08:00
} example_timer_event_t;
2016-11-23 02:15:27 +08:00
2021-02-01 14:10:15 +08:00
static xQueueHandle s_timer_queue;
2016-11-23 02:15:27 +08:00
/*
2017-09-25 06:20:12 +02:00
* A simple helper function to print the raw timer counter value
* and the counter value converted to seconds
2016-11-23 02:15:27 +08:00
*/
2017-09-25 06:20:12 +02:00
static void inline print_timer_counter(uint64_t counter_value)
2016-11-23 02:15:27 +08:00
{
2021-02-01 14:10:15 +08:00
printf("Counter: 0x%08x%08x\r\n", (uint32_t) (counter_value >> 32),
(uint32_t) (counter_value));
2021-02-01 14:10:15 +08:00
printf("Time : %.8f s\r\n", (double) counter_value / TIMER_SCALE);
2016-11-23 02:15:27 +08:00
}
2021-02-01 14:10:15 +08:00
static bool IRAM_ATTR timer_group_isr_callback(void *args)
2016-11-23 02:15:27 +08:00
{
2021-02-01 14:10:15 +08:00
BaseType_t high_task_awoken = pdFALSE;
example_timer_info_t *info = (example_timer_info_t *) args;
uint64_t timer_counter_value = timer_group_get_counter_value_in_isr(info->timer_group, info->timer_idx);
/* Prepare basic event data that will be then sent back to task */
example_timer_event_t evt = {
.info.timer_group = info->timer_group,
.info.timer_idx = info->timer_idx,
.info.auto_reload = info->auto_reload,
.info.alarm_interval = info->alarm_interval,
.timer_counter_value = timer_counter_value
};
if (!info->auto_reload) {
timer_counter_value += info->alarm_interval * TIMER_SCALE;
timer_group_set_alarm_value_in_isr(info->timer_group, info->timer_idx, timer_counter_value);
2016-11-23 02:15:27 +08:00
}
2017-09-25 06:20:12 +02:00
/* Now just send the event data back to the main program task */
2021-02-01 14:10:15 +08:00
xQueueSendFromISR(s_timer_queue, &evt, &high_task_awoken);
return high_task_awoken == pdTRUE; // return whether we need to yield at the end of ISR
2016-11-23 02:15:27 +08:00
}
2021-02-01 14:10:15 +08:00
/**
* @brief Initialize selected timer of timer group
2017-09-25 06:20:12 +02:00
*
2021-02-01 14:10:15 +08:00
* @param group Timer Group number, index from 0
* @param timer timer ID, index from 0
* @param auto_reload whether auto-reload on alarm event
* @param timer_interval_sec interval of alarm
2016-11-23 02:15:27 +08:00
*/
2021-02-01 14:10:15 +08:00
static void example_tg_timer_init(int group, int timer, bool auto_reload, int timer_interval_sec)
2016-11-23 02:15:27 +08:00
{
2017-09-25 06:20:12 +02:00
/* Select and initialize basic parameters of the timer */
timer_config_t config = {
.divider = TIMER_DIVIDER,
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.auto_reload = auto_reload,
}; // default clock source is APB
2021-02-01 14:10:15 +08:00
timer_init(group, timer, &config);
2017-09-25 06:20:12 +02:00
/* Timer's counter will initially start from value below.
Also, if auto_reload is set, this value will be automatically reload on alarm */
2021-02-01 14:10:15 +08:00
timer_set_counter_value(group, timer, 0);
2017-09-25 06:20:12 +02:00
/* Configure the alarm value and the interrupt on alarm. */
2021-02-01 14:10:15 +08:00
timer_set_alarm_value(group, timer, timer_interval_sec * TIMER_SCALE);
timer_enable_intr(group, timer);
2017-09-25 06:20:12 +02:00
2021-02-01 14:10:15 +08:00
example_timer_info_t *timer_info = calloc(1, sizeof(example_timer_info_t));
timer_info->timer_group = group;
timer_info->timer_idx = timer;
timer_info->auto_reload = auto_reload;
timer_info->alarm_interval = timer_interval_sec;
timer_isr_callback_add(group, timer, timer_group_isr_callback, timer_info, 0);
timer_start(group, timer);
2016-11-23 02:15:27 +08:00
}
2021-02-01 14:10:15 +08:00
void app_main(void)
2016-11-23 02:15:27 +08:00
{
2021-02-01 14:10:15 +08:00
s_timer_queue = xQueueCreate(10, sizeof(example_timer_event_t));
example_tg_timer_init(TIMER_GROUP_0, TIMER_0, true, 3);
example_tg_timer_init(TIMER_GROUP_1, TIMER_0, false, 5);
2017-09-25 06:20:12 +02:00
while (1) {
2021-02-01 14:10:15 +08:00
example_timer_event_t evt;
xQueueReceive(s_timer_queue, &evt, portMAX_DELAY);
2017-09-25 06:20:12 +02:00
/* Print information that the timer reported an event */
2021-02-01 14:10:15 +08:00
if (evt.info.auto_reload) {
printf("Timer Group with auto reload\n");
2017-09-25 06:20:12 +02:00
} else {
2021-02-01 14:10:15 +08:00
printf("Timer Group without auto reload\n");
2017-09-25 06:20:12 +02:00
}
2021-02-01 14:10:15 +08:00
printf("Group[%d], timer[%d] alarm event\n", evt.info.timer_group, evt.info.timer_idx);
2017-09-25 06:20:12 +02:00
/* Print the timer values passed by event */
printf("------- EVENT TIME --------\n");
print_timer_counter(evt.timer_counter_value);
/* Print the timer values as visible by this task */
printf("-------- TASK TIME --------\n");
uint64_t task_counter_value;
2021-02-01 14:10:15 +08:00
timer_get_counter_value(evt.info.timer_group, evt.info.timer_idx, &task_counter_value);
2017-09-25 06:20:12 +02:00
print_timer_counter(task_counter_value);
}
2016-11-23 02:15:27 +08:00
}