| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- /* General Purpose Timer example
- This example code is in the Public Domain (or CC0 licensed, at your option.)
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
- */
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #include "driver/timer.h"
- #define TIMER_DIVIDER (16) // Hardware timer clock divider
- #define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
- typedef struct {
- int timer_group;
- int timer_idx;
- 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;
- uint64_t timer_counter_value;
- } example_timer_event_t;
- static xQueueHandle s_timer_queue;
- /*
- * A simple helper function to print the raw timer counter value
- * and the counter value converted to seconds
- */
- static void inline print_timer_counter(uint64_t counter_value)
- {
- printf("Counter: 0x%08x%08x\r\n", (uint32_t) (counter_value >> 32),
- (uint32_t) (counter_value));
- printf("Time : %.8f s\r\n", (double) counter_value / TIMER_SCALE);
- }
- static bool IRAM_ATTR timer_group_isr_callback(void *args)
- {
- 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);
- }
- /* Now just send the event data back to the main program task */
- xQueueSendFromISR(s_timer_queue, &evt, &high_task_awoken);
- return high_task_awoken == pdTRUE; // return whether we need to yield at the end of ISR
- }
- /**
- * @brief Initialize selected timer of timer group
- *
- * @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
- */
- static void example_tg_timer_init(int group, int timer, bool auto_reload, int timer_interval_sec)
- {
- /* 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
- timer_init(group, timer, &config);
- /* Timer's counter will initially start from value below.
- Also, if auto_reload is set, this value will be automatically reload on alarm */
- timer_set_counter_value(group, timer, 0);
- /* Configure the alarm value and the interrupt on alarm. */
- timer_set_alarm_value(group, timer, timer_interval_sec * TIMER_SCALE);
- timer_enable_intr(group, timer);
- 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);
- }
- void app_main(void)
- {
- 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);
- while (1) {
- example_timer_event_t evt;
- xQueueReceive(s_timer_queue, &evt, portMAX_DELAY);
- /* Print information that the timer reported an event */
- if (evt.info.auto_reload) {
- printf("Timer Group with auto reload\n");
- } else {
- printf("Timer Group without auto reload\n");
- }
- printf("Group[%d], timer[%d] alarm event\n", evt.info.timer_group, evt.info.timer_idx);
- /* 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;
- timer_get_counter_value(evt.info.timer_group, evt.info.timer_idx, &task_counter_value);
- print_timer_counter(task_counter_value);
- }
- }
|