|
16 | 16 | #include "driver/gptimer.h"
|
17 | 17 | #include "soc/soc_caps.h"
|
18 | 18 | #include "clk_tree.h"
|
19 |
| - |
20 |
| -inline uint64_t timerRead(hw_timer_t timer_handle){ |
| 19 | +#include "freertos/FreeRTOS.h" |
| 20 | +#include "freertos/task.h" |
| 21 | +#include "freertos/semphr.h" |
| 22 | + |
| 23 | +typedef void (*voidFuncPtr)(void); |
| 24 | +typedef void (*voidFuncPtrArg)(void*); |
| 25 | + |
| 26 | +// #if CONFIG_DISABLE_HAL_LOCKS |
| 27 | +// #define TIMER_MUTEX_LOCK() |
| 28 | +// #define TIMER_MUTEX_UNLOCK() |
| 29 | +// #else |
| 30 | +// #define TIMER_MUTEX_LOCK() do {} while (xSemaphoreTake(timer->lock, portMAX_DELAY) != pdPASS) |
| 31 | +// #define TIMER_MUTEX_UNLOCK() xSemaphoreGive(timer->lock) |
| 32 | +// #endif |
| 33 | + |
| 34 | +typedef struct { |
| 35 | + voidFuncPtr fn; |
| 36 | + void* arg; |
| 37 | +} interrupt_config_t; |
| 38 | + |
| 39 | +struct timer_struct_t { |
| 40 | + gptimer_handle_t timer_handle; |
| 41 | + interrupt_config_t interrupt_handle; |
| 42 | + // #if !CONFIG_DISABLE_HAL_LOCKS |
| 43 | + // xSemaphoreHandle lock; |
| 44 | + // #endif |
| 45 | +}; |
| 46 | + |
| 47 | +inline uint64_t timerRead(hw_timer_t * timer){ |
21 | 48 |
|
22 | 49 | uint64_t value;
|
23 |
| - gptimer_get_raw_count(timer_handle, &value); |
| 50 | + gptimer_get_raw_count(timer->timer_handle, &value); |
24 | 51 | return value;
|
25 | 52 | }
|
26 |
| -void timerWrite(hw_timer_t timer_handle, uint64_t val){ |
27 |
| - gptimer_set_raw_count(timer_handle, val); |
| 53 | + |
| 54 | +void timerWrite(hw_timer_t * timer, uint64_t val){ |
| 55 | + gptimer_set_raw_count(timer->timer_handle, val); |
28 | 56 | }
|
29 | 57 |
|
30 |
| -void timerAlarm(hw_timer_t timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count){ |
| 58 | +void timerAlarm(hw_timer_t * timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count){ |
31 | 59 | esp_err_t err = ESP_OK;
|
32 | 60 | gptimer_alarm_config_t alarm_cfg = {
|
33 | 61 | .alarm_count = alarm_value,
|
34 | 62 | .reload_count = reload_count,
|
35 | 63 | .flags.auto_reload_on_alarm = autoreload,
|
36 | 64 | };
|
37 |
| - err = gptimer_set_alarm_action(timer, &alarm_cfg); |
| 65 | + err = gptimer_set_alarm_action(timer->timer_handle, &alarm_cfg); |
38 | 66 | if (err != ESP_OK){
|
39 | 67 | log_e("Timer Alarm Write failed, error num=%d", err);
|
40 | 68 | }
|
41 | 69 | }
|
42 | 70 |
|
43 |
| -uint32_t timerGetFrequency(hw_timer_t timer_handle){ |
| 71 | +uint32_t timerGetFrequency(hw_timer_t * timer){ |
44 | 72 | uint32_t frequency;
|
45 |
| - gptimer_get_resolution(timer_handle, &frequency); |
| 73 | + gptimer_get_resolution(timer->timer_handle, &frequency); |
46 | 74 | return frequency;
|
47 | 75 | }
|
48 | 76 |
|
49 |
| -void timerStart(hw_timer_t timer_handle){ |
50 |
| - gptimer_start(timer_handle); |
| 77 | +void timerStart(hw_timer_t * timer){ |
| 78 | + gptimer_start(timer->timer_handle); |
51 | 79 | }
|
52 | 80 |
|
53 |
| -void timerStop(hw_timer_t timer_handle){ |
54 |
| - gptimer_stop(timer_handle); |
| 81 | +void timerStop(hw_timer_t * timer){ |
| 82 | + gptimer_stop(timer->timer_handle); |
55 | 83 | }
|
56 | 84 |
|
57 |
| -void timerRestart(hw_timer_t timer_handle){ |
58 |
| - gptimer_set_raw_count(timer_handle,0); |
| 85 | +void timerRestart(hw_timer_t * timer){ |
| 86 | + gptimer_set_raw_count(timer->timer_handle,0); |
59 | 87 | }
|
60 | 88 |
|
61 |
| -hw_timer_t timerBegin(uint32_t frequency){ |
| 89 | +hw_timer_t * timerBegin(uint32_t frequency){ |
62 | 90 |
|
63 | 91 | esp_err_t err = ESP_OK;
|
64 | 92 | hw_timer_t timer_handle;
|
@@ -89,69 +117,95 @@ hw_timer_t timerBegin(uint32_t frequency){
|
89 | 117 | .flags.intr_shared = true,
|
90 | 118 | };
|
91 | 119 |
|
92 |
| - err = gptimer_new_timer(&config, &timer_handle); |
| 120 | + hw_timer_t *timer = malloc(sizeof(hw_timer_t)); |
| 121 | + |
| 122 | + err = gptimer_new_timer(&config, &timer->timer_handle); |
93 | 123 | if (err != ESP_OK){
|
94 | 124 | log_e("Failed to create a new GPTimer, error num=%d", err);
|
| 125 | + free(timer); |
95 | 126 | return NULL;
|
96 | 127 | }
|
97 |
| - gptimer_enable(timer_handle); |
98 |
| - gptimer_start(timer_handle); |
99 |
| - return timer_handle; |
| 128 | + gptimer_enable(timer->timer_handle); |
| 129 | + gptimer_start(timer->timer_handle); |
| 130 | + return timer; |
100 | 131 | }
|
101 | 132 |
|
102 |
| -void timerEnd(hw_timer_t timer_handle){ |
| 133 | +void timerEnd(hw_timer_t * timer){ |
103 | 134 | esp_err_t err = ESP_OK;
|
104 |
| - gptimer_disable(timer_handle); |
105 |
| - err = gptimer_del_timer(timer_handle); |
| 135 | + gptimer_disable(timer->timer_handle); |
| 136 | + err = gptimer_del_timer(timer->timer_handle); |
106 | 137 | if (err != ESP_OK){
|
107 | 138 | log_e("Failed to destroy GPTimer, error num=%d", err);
|
108 |
| - } |
| 139 | + return; |
| 140 | + } |
| 141 | + free(timer); |
109 | 142 | }
|
110 | 143 |
|
111 |
| -bool IRAM_ATTR timerFnWrapper(hw_timer_t timer, const gptimer_alarm_event_data_t *edata, void *arg){ |
112 |
| - void (*fn)(void) = arg; |
113 |
| - fn(); |
| 144 | +bool IRAM_ATTR timerFnWrapper(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void * args){ |
| 145 | + interrupt_config_t * isr = (interrupt_config_t*)args; |
| 146 | + if(isr->fn) { |
| 147 | + if(isr->arg){ |
| 148 | + ((voidFuncPtrArg)isr->fn)(isr->arg); |
| 149 | + } else { |
| 150 | + isr->fn(); |
| 151 | + } |
| 152 | + } |
114 | 153 |
|
115 | 154 | // some additional logic or handling may be required here to approriately yield or not
|
116 | 155 | return false;
|
117 | 156 | }
|
118 | 157 |
|
119 |
| -void timerAttachInterrupt(hw_timer_t timer, void (*fn)(void)){ |
| 158 | + |
| 159 | +void timerAttachInterruptFunctionalArg(hw_timer_t * timer, void (*userFunc)(void*), void * arg){ |
120 | 160 | esp_err_t err = ESP_OK;
|
121 | 161 | gptimer_event_callbacks_t cbs = {
|
122 | 162 | .on_alarm = timerFnWrapper,
|
123 | 163 | };
|
124 | 164 |
|
125 |
| - gptimer_disable(timer); |
126 |
| - err = gptimer_register_event_callbacks(timer, &cbs, fn); |
| 165 | + timer->interrupt_handle.fn = (voidFuncPtr)userFunc; |
| 166 | + timer->interrupt_handle.arg = arg; |
| 167 | + |
| 168 | + gptimer_disable(timer->timer_handle); |
| 169 | + err = gptimer_register_event_callbacks(timer->timer_handle, &cbs, &timer->interrupt_handle); |
127 | 170 | if (err != ESP_OK){
|
128 | 171 | log_e("Timer Attach Interrupt failed, error num=%d", err);
|
129 | 172 | }
|
130 |
| - gptimer_enable(timer); |
| 173 | + gptimer_enable(timer->timer_handle); |
| 174 | +} |
| 175 | + |
| 176 | + |
| 177 | +void timerAttachInterruptArg(hw_timer_t * timer, void (*userFunc)(void*), void * arg){ |
| 178 | + timerAttachInterruptFunctionalArg(timer, userFunc, arg); |
| 179 | +} |
| 180 | + |
| 181 | +void timerAttachInterrupt(hw_timer_t * timer, voidFuncPtr userFunc){ |
| 182 | + timerAttachInterruptFunctionalArg(timer, (voidFuncPtrArg)userFunc, NULL); |
131 | 183 | }
|
132 | 184 |
|
133 |
| -void timerDetachInterrupt(hw_timer_t timer){ |
| 185 | +void timerDetachInterrupt(hw_timer_t * timer){ |
134 | 186 | esp_err_t err = ESP_OK;
|
135 |
| - err = gptimer_set_alarm_action(timer, NULL); |
| 187 | + err = gptimer_set_alarm_action(timer->timer_handle, NULL); |
| 188 | + timer->interrupt_handle.fn = NULL; |
| 189 | + timer->interrupt_handle.arg = NULL; |
136 | 190 | if (err != ESP_OK){
|
137 | 191 | log_e("Timer Detach Interrupt failed, error num=%d", err);
|
138 | 192 | }
|
139 | 193 | }
|
140 | 194 |
|
141 |
| -uint64_t timerReadMicros(hw_timer_t timer){ |
| 195 | +uint64_t timerReadMicros(hw_timer_t * timer){ |
142 | 196 | uint64_t timer_val = timerRead(timer);
|
143 |
| - uint32_t frequency = timerGetResolution(timer); |
| 197 | + uint32_t frequency = timerGetFrequency(timer); |
144 | 198 | return timer_val * 1000000 / frequency;
|
145 | 199 | }
|
146 | 200 |
|
147 |
| -uint64_t timerReadMilis(hw_timer_t timer){ |
| 201 | +uint64_t timerReadMilis(hw_timer_t * timer){ |
148 | 202 | uint64_t timer_val = timerRead(timer);
|
149 |
| - uint32_t frequency = timerGetResolution(timer); |
| 203 | + uint32_t frequency = timerGetFrequency(timer); |
150 | 204 | return timer_val * 1000 / frequency;
|
151 | 205 | }
|
152 | 206 |
|
153 |
| -double timerReadSeconds(hw_timer_t timer){ |
| 207 | +double timerReadSeconds(hw_timer_t * timer){ |
154 | 208 | uint64_t timer_val = timerRead(timer);
|
155 |
| - uint32_t frequency = timerGetResolution(timer); |
| 209 | + uint32_t frequency = timerGetFrequency(timer); |
156 | 210 | return (double)timer_val / frequency;
|
157 | 211 | }
|
0 commit comments