12#include <driver/gptimer.h>
15#include <esp_memory_utils.h>
17#include <freertos/FreeRTOS.h>
18#include <hal/timer_hal.h>
19#include <hal/timer_ll.h>
20#include <rom/ets_sys.h>
31 portMUX_TYPE spinlock;
32 gptimer_t* timers[SOC_TIMER_GROUP_TIMERS_PER_GROUP];
45 uint32_t resolution_hz;
46 uint64_t reload_count;
48 gptimer_count_direction_t direction;
49 timer_hal_context_t hal;
50 std::atomic<gptimer_fsm_t> fsm;
53 portMUX_TYPE spinlock;
54 gptimer_alarm_cb_t on_alarm;
56 gptimer_clock_source_t clk_src;
57 esp_pm_lock_handle_t pm_lock;
59 char pm_lock_name[GPTIMER_PM_LOCK_NAME_LEN_MAX];
62 uint32_t intr_shared : 1;
63 uint32_t auto_reload_on_alarm : 1;
64 uint32_t alarm_en : 1;
72__attribute__((always_inline))
inline esp_err_t inlined_gptimer_get_raw_count(gptimer_handle_t timer, uint64_t* value) {
73 if (timer == NULL || value == NULL) {
74 return ESP_ERR_INVALID_ARG;
76 portENTER_CRITICAL_SAFE(&timer->spinlock);
77 timer_ll_trigger_soft_capture((&timer->hal)->dev, (&timer->hal)->timer_id);
78 *value = timer_ll_get_counter_value((&timer->hal)->dev, (&timer->hal)->timer_id);
79 portEXIT_CRITICAL_SAFE(&timer->spinlock);
83__attribute__((always_inline))
inline esp_err_t inlined_gptimer_set_raw_count(gptimer_handle_t timer, uint64_t value) {
85 return ESP_ERR_INVALID_ARG;
87 portENTER_CRITICAL_SAFE(&timer->spinlock);
95 uint64_t old_reload = timer_ll_get_reload_value((&timer->hal)->dev, (&timer->hal)->timer_id);
96 timer_ll_set_reload_value((&timer->hal)->dev, (&timer->hal)->timer_id, value);
97 timer_ll_trigger_soft_reload((&timer->hal)->dev, (&timer->hal)->timer_id);
99 timer_ll_set_reload_value((&timer->hal)->dev, (&timer->hal)->timer_id, old_reload);
100 portEXIT_CRITICAL_SAFE(&timer->spinlock);
104__attribute__((always_inline))
inline esp_err_t inlined_gptimer_set_alarm_action(gptimer_handle_t timer,
const gptimer_alarm_config_t* config) {
106 return ESP_ERR_INVALID_ARG;
109#if CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
112 if (esp_ptr_internal(config) ==
false) {
113 return ESP_ERR_INVALID_ARG;
117 bool valid_auto_reload = !config->flags.auto_reload_on_alarm || config->alarm_count != config->reload_count;
118 if (valid_auto_reload ==
false) {
119 return ESP_ERR_INVALID_ARG;
122 portENTER_CRITICAL_SAFE(&timer->spinlock);
123 timer->reload_count = config->reload_count;
124 timer->alarm_count = config->alarm_count;
125 timer->flags.auto_reload_on_alarm = config->flags.auto_reload_on_alarm;
126 timer->flags.alarm_en =
true;
128 timer_ll_set_reload_value(timer->hal.dev, timer->timer_id, config->reload_count);
129 timer_ll_set_alarm_value(timer->hal.dev, timer->timer_id, config->alarm_count);
130 portEXIT_CRITICAL_SAFE(&timer->spinlock);
132 portENTER_CRITICAL_SAFE(&timer->spinlock);
133 timer->flags.auto_reload_on_alarm =
false;
134 timer->flags.alarm_en =
false;
135 portEXIT_CRITICAL_SAFE(&timer->spinlock);
138 portENTER_CRITICAL_SAFE(&timer->spinlock);
139 timer_ll_enable_auto_reload(timer->hal.dev, timer->timer_id, timer->flags.auto_reload_on_alarm);
140 timer_ll_enable_alarm(timer->hal.dev, timer->timer_id, timer->flags.alarm_en);
141 portEXIT_CRITICAL_SAFE(&timer->spinlock);