Skip to content

Commit 15a68e6

Browse files
committed
refactor using GPtimer
1 parent fcc3b17 commit 15a68e6

File tree

2 files changed

+113
-246
lines changed

2 files changed

+113
-246
lines changed

cores/esp32/esp32-hal-timer.c

Lines changed: 93 additions & 209 deletions
Original file line numberDiff line numberDiff line change
@@ -13,261 +13,145 @@
1313
// limitations under the License.
1414

1515
#include "esp32-hal-timer.h"
16-
#include "driver/timer.h"
16+
#include "driver/gptimer.h"
1717
#include "soc/soc_caps.h"
18+
#include "clk_tree.h"
1819

19-
typedef union {
20-
struct {
21-
uint32_t reserved0: 10;
22-
uint32_t alarm_en: 1; /*When set alarm is enabled*/
23-
uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/
24-
uint32_t edge_int_en: 1; /*When set edge type interrupt will be generated during alarm*/
25-
uint32_t divider: 16; /*Timer clock (T0/1_clk) pre-scale value.*/
26-
uint32_t autoreload: 1; /*When set timer 0/1 auto-reload at alarming is enabled*/
27-
uint32_t increase: 1; /*When set timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/
28-
uint32_t enable: 1; /*When set timer 0/1 time-base counter is enabled*/
29-
};
30-
uint32_t val;
31-
} timer_cfg_t;
32-
33-
#define NUM_OF_TIMERS SOC_TIMER_GROUP_TOTAL_TIMERS
34-
35-
typedef struct hw_timer_s
36-
{
37-
uint8_t group;
38-
uint8_t num;
39-
} hw_timer_t;
40-
41-
// Works for all chips
42-
static hw_timer_t timer_dev[4] = {
43-
{0,0}, {1,0}, {0,1}, {1,1}
44-
};
45-
46-
// NOTE: (in IDF 5.0 there wont be need to know groups/numbers
47-
// timer_init() will list thru all timers and return free timer handle)
48-
49-
50-
inline uint64_t timerRead(hw_timer_t *timer){
20+
inline uint64_t timerRead(hw_timer_t timer_handle){
5121

5222
uint64_t value;
53-
timer_get_counter_value(timer->group, timer->num,&value);
23+
gptimer_get_raw_count(timer_handle, &value);
5424
return value;
5525
}
56-
57-
uint64_t timerAlarmRead(hw_timer_t *timer){
58-
uint64_t value;
59-
timer_get_alarm_value(timer->group, timer->num, &value);
60-
return value;
61-
}
62-
63-
void timerWrite(hw_timer_t *timer, uint64_t val){
64-
timer_set_counter_value(timer->group, timer->num, val);
65-
}
66-
67-
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){
68-
timer_set_alarm_value(timer->group, timer->num, alarm_value);
69-
timerSetAutoReload(timer,autoreload);
70-
}
71-
72-
void timerSetConfig(hw_timer_t *timer, uint32_t config){
73-
timer_cfg_t cfg;
74-
cfg.val = config;
75-
timer_set_alarm(timer->group, timer->num, cfg.alarm_en);
76-
timerSetDivider(timer,cfg.divider);
77-
timerSetAutoReload(timer,cfg.autoreload);
78-
timerSetCountUp(timer, cfg.increase);
79-
80-
if (cfg.enable) {
81-
timerStart(timer);
82-
}
83-
else{
84-
timerStop(timer);
85-
}
86-
return;
87-
}
88-
89-
uint32_t timerGetConfig(hw_timer_t *timer){
90-
timer_config_t timer_cfg;
91-
timer_get_config(timer->group, timer->num,&timer_cfg);
92-
93-
//Translate to default uint32_t
94-
timer_cfg_t cfg;
95-
cfg.alarm_en = timer_cfg.alarm_en;
96-
cfg.autoreload = timer_cfg.auto_reload;
97-
cfg.divider = timer_cfg.divider;
98-
cfg.edge_int_en = timer_cfg.intr_type;
99-
cfg.level_int_en = !timer_cfg.intr_type;
100-
cfg.enable = timer_cfg.counter_en;
101-
cfg.increase = timer_cfg.counter_dir;
102-
103-
return cfg.val;
104-
}
105-
106-
void timerSetCountUp(hw_timer_t *timer, bool countUp){
107-
timer_set_counter_mode(timer->group, timer->num,countUp);
108-
}
109-
110-
bool timerGetCountUp(hw_timer_t *timer){
111-
timer_cfg_t config;
112-
config.val = timerGetConfig(timer);
113-
return config.increase;
114-
}
115-
116-
void timerSetAutoReload(hw_timer_t *timer, bool autoreload){
117-
timer_set_auto_reload(timer->group, timer->num,autoreload);
118-
}
119-
120-
bool timerGetAutoReload(hw_timer_t *timer){
121-
timer_cfg_t config;
122-
config.val= timerGetConfig(timer);
123-
return config.autoreload;
124-
}
125-
126-
// Set divider from 2 to 65535
127-
void timerSetDivider(hw_timer_t *timer, uint16_t divider){
128-
if(divider < 2)
129-
{
130-
log_e("Timer divider must be set in range of 2 to 65535");
131-
return;
132-
}
133-
timer_set_divider(timer->group, timer->num,divider);
134-
}
135-
136-
uint16_t timerGetDivider(hw_timer_t *timer){
137-
timer_cfg_t config;
138-
config.val = timerGetConfig(timer);
139-
return config.divider;
140-
}
141-
142-
void timerStart(hw_timer_t *timer){
143-
timer_start(timer->group, timer->num);
26+
void timerWrite(hw_timer_t timer_handle, uint64_t val){
27+
gptimer_set_raw_count(timer_handle, val);
14428
}
14529

146-
void timerStop(hw_timer_t *timer){
147-
timer_pause(timer->group, timer->num);
148-
}
149-
150-
void timerRestart(hw_timer_t *timer){
151-
timerWrite(timer,0);
30+
void timerAlarmWrite(hw_timer_t timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count){
31+
esp_err_t err = ESP_OK;
32+
gptimer_alarm_config_t alarm_cfg = {
33+
.alarm_count = alarm_value,
34+
.reload_count = reload_count,
35+
.flags.auto_reload_on_alarm = autoreload,
36+
};
37+
err = gptimer_set_alarm_action(timer, &alarm_cfg);
38+
if (err != ESP_OK){
39+
log_e("Timer Alarm Write failed, error num=%d", err);
40+
}
15241
}
15342

154-
bool timerStarted(hw_timer_t *timer){
155-
timer_cfg_t config;
156-
config.val = timerGetConfig(timer);
157-
return config.enable;
43+
uint32_t timerGetResolution(hw_timer_t timer_handle){
44+
uint32_t resolution;
45+
gptimer_get_resolution(timer_handle, &resolution);
46+
return resolution;
15847
}
15948

160-
void timerAlarmEnable(hw_timer_t *timer){
161-
timer_set_alarm(timer->group, timer->num,true);
49+
void timerStart(hw_timer_t timer_handle){
50+
gptimer_start(timer_handle);
16251
}
16352

164-
void timerAlarmDisable(hw_timer_t *timer){
165-
timer_set_alarm(timer->group, timer->num,false);
53+
void timerStop(hw_timer_t timer_handle){
54+
gptimer_stop(timer_handle);
16655
}
16756

168-
bool timerAlarmEnabled(hw_timer_t *timer){
169-
timer_cfg_t config;
170-
config.val = timerGetConfig(timer);
171-
return config.alarm_en;
57+
void timerRestart(hw_timer_t timer_handle){
58+
gptimer_set_raw_count(timer_handle,0);
17259
}
17360

174-
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
175-
hw_timer_t * timer = (hw_timer_t *)arg;
176-
if(ev_type == APB_BEFORE_CHANGE){
177-
timerStop(timer);
178-
} else {
179-
old_apb /= 1000000;
180-
new_apb /= 1000000;
181-
uint16_t divider = (new_apb * timerGetDivider(timer)) / old_apb;
182-
timerSetDivider(timer,divider);
183-
timerStart(timer);
61+
hw_timer_t timerBegin(uint32_t resolution, bool countUp){
62+
63+
esp_err_t err = ESP_OK;
64+
hw_timer_t timer_handle;
65+
uint32_t counter_src_hz = 0;
66+
uint32_t divider = 0;
67+
soc_periph_gptimer_clk_src_t clk;
68+
69+
soc_periph_gptimer_clk_src_t gptimer_clks[] = SOC_GPTIMER_CLKS;
70+
for (size_t i = 0; i < sizeof(gptimer_clks) / sizeof(gptimer_clks[0]); i++){
71+
clk = gptimer_clks[i];
72+
clk_tree_src_get_freq_hz(clk, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz);
73+
divider = counter_src_hz / resolution;
74+
if((divider >= 2) && (divider <= 65536)){
75+
break;
76+
}
77+
else divider = 0;
18478
}
185-
}
18679

187-
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
188-
if(num >= NUM_OF_TIMERS)
189-
{
190-
log_e("Timer number %u exceeds available number of Timers.", num);
80+
if(divider == 0){
81+
log_e("Resolution cannot be reached with any clock source, aborting!");
19182
return NULL;
19283
}
19384

194-
hw_timer_t * timer = &timer_dev[num]; //Get Timer group/num from 0-3 number
195-
196-
timer_config_t config = {
197-
.divider = divider,
198-
.counter_dir = countUp,
199-
.counter_en = TIMER_PAUSE,
200-
.alarm_en = TIMER_ALARM_DIS,
201-
.auto_reload = false,
85+
gptimer_config_t config = {
86+
.clk_src = clk,
87+
.direction = countUp,
88+
.resolution_hz = resolution,
89+
.flags.intr_shared = true,
20290
};
20391

204-
timer_init(timer->group, timer->num, &config);
205-
timer_set_counter_value(timer->group, timer->num, 0);
206-
timerStart(timer);
207-
addApbChangeCallback(timer, _on_apb_change);
208-
return timer;
92+
err = gptimer_new_timer(&config, &timer_handle);
93+
if (err != ESP_OK){
94+
log_e("Failed to create a new GPTimer, error num=%d", err);
95+
return NULL;
96+
}
97+
gptimer_enable(timer_handle);
98+
gptimer_start(timer_handle);
99+
return timer_handle;
209100
}
210101

211-
void timerEnd(hw_timer_t *timer){
212-
removeApbChangeCallback(timer, _on_apb_change);
213-
timer_deinit(timer->group, timer->num);
102+
void timerEnd(hw_timer_t timer_handle){
103+
esp_err_t err = ESP_OK;
104+
gptimer_disable(timer_handle);
105+
err = gptimer_del_timer(timer_handle);
106+
if (err != ESP_OK){
107+
log_e("Failed to destroy GPTimer, error num=%d", err);
108+
}
214109
}
215110

216-
bool IRAM_ATTR timerFnWrapper(void *arg){
111+
bool IRAM_ATTR timerFnWrapper(hw_timer_t timer, const gptimer_alarm_event_data_t *edata, void *arg){
217112
void (*fn)(void) = arg;
218113
fn();
219114

220115
// some additional logic or handling may be required here to approriately yield or not
221116
return false;
222117
}
223118

224-
void timerAttachInterruptFlag(hw_timer_t *timer, void (*fn)(void), bool edge, int intr_alloc_flags){
225-
if(edge){
226-
log_w("EDGE timer interrupt is not supported! Setting to LEVEL...");
227-
}
228-
timer_isr_callback_add(timer->group, timer->num, timerFnWrapper, fn, intr_alloc_flags);
229-
}
119+
void timerAttachInterrupt(hw_timer_t timer, void (*fn)(void)){
120+
esp_err_t err = ESP_OK;
121+
gptimer_event_callbacks_t cbs = {
122+
.on_alarm = timerFnWrapper,
123+
};
230124

231-
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
232-
timerAttachInterruptFlag(timer, fn, edge, 0);
125+
gptimer_disable(timer);
126+
err = gptimer_register_event_callbacks(timer, &cbs, fn);
127+
if (err != ESP_OK){
128+
log_e("Timer Attach Interrupt failed, error num=%d", err);
129+
}
130+
gptimer_enable(timer);
233131
}
234132

235-
void timerDetachInterrupt(hw_timer_t *timer){
236-
timer_isr_callback_remove(timer->group, timer->num);
133+
void timerDetachInterrupt(hw_timer_t timer){
134+
esp_err_t err = ESP_OK;
135+
err = gptimer_set_alarm_action(timer, NULL);
136+
if (err != ESP_OK){
137+
log_e("Timer Detach Interrupt failed, error num=%d", err);
138+
}
237139
}
238140

239-
uint64_t timerReadMicros(hw_timer_t *timer){
141+
uint64_t timerReadMicros(hw_timer_t timer){
240142
uint64_t timer_val = timerRead(timer);
241-
uint16_t div = timerGetDivider(timer);
242-
return timer_val * div / (getApbFrequency() / 1000000);
143+
uint32_t resolution = timerGetResolution(timer);
144+
return timer_val * 1000000 / resolution;
243145
}
244146

245-
uint64_t timerReadMilis(hw_timer_t *timer){
147+
uint64_t timerReadMilis(hw_timer_t timer){
246148
uint64_t timer_val = timerRead(timer);
247-
uint16_t div = timerGetDivider(timer);
248-
return timer_val * div / (getApbFrequency() / 1000);
149+
uint32_t resolution = timerGetResolution(timer);
150+
return timer_val * 1000 / resolution;
249151
}
250152

251-
double timerReadSeconds(hw_timer_t *timer){
153+
double timerReadSeconds(hw_timer_t timer){
252154
uint64_t timer_val = timerRead(timer);
253-
uint16_t div = timerGetDivider(timer);
254-
return (double)timer_val * div / getApbFrequency();
255-
}
256-
257-
uint64_t timerAlarmReadMicros(hw_timer_t *timer){
258-
uint64_t timer_val = timerAlarmRead(timer);
259-
uint16_t div = timerGetDivider(timer);
260-
return timer_val * div / (getApbFrequency() / 1000000);
261-
}
262-
263-
uint64_t timerAlarmReadMilis(hw_timer_t *timer){
264-
uint64_t timer_val = timerAlarmRead(timer);
265-
uint16_t div = timerGetDivider(timer);
266-
return timer_val * div / (getApbFrequency() / 1000);
267-
}
268-
269-
double timerAlarmReadSeconds(hw_timer_t *timer){
270-
uint64_t timer_val = timerAlarmRead(timer);
271-
uint16_t div = timerGetDivider(timer);
272-
return (double)timer_val * div / getApbFrequency();
155+
uint32_t resolution = timerGetResolution(timer);
156+
return (double)timer_val / resolution;
273157
}

0 commit comments

Comments
 (0)