Skip to content

Commit df5ade9

Browse files
sylvioalveskartben
authored andcommitted
drivers: counter: esp32: add guard period support
Implements guard period support. Signed-off-by: Sylvio Alves <[email protected]>
1 parent 65473e8 commit df5ade9

File tree

1 file changed

+59
-6
lines changed

1 file changed

+59
-6
lines changed

drivers/counter/counter_esp32_tmr.c

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct counter_esp32_top_data {
2929
uint32_t ticks;
3030
void *user_data;
3131
bool auto_reload;
32+
uint32_t guard_period;
3233
};
3334

3435
struct counter_esp32_config {
@@ -144,33 +145,60 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
144145
{
145146
ARG_UNUSED(chan_id);
146147
struct counter_esp32_data *data = dev->data;
148+
bool absolute = alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE;
147149
uint32_t ticks = alarm_cfg->ticks;
150+
uint32_t top = data->top_data.ticks;
151+
uint32_t max_rel_val = data->top_data.ticks;
148152
uint32_t now;
153+
uint32_t diff;
154+
int err = 0;
155+
bool irq_on_late = 0;
149156

150157
if (ticks > data->top_data.ticks) {
151158
return -EINVAL;
152159
}
153160

161+
data->alarm_cfg.callback = alarm_cfg->callback;
162+
data->alarm_cfg.user_data = alarm_cfg->user_data;
163+
154164
counter_esp32_get_value(dev, &now);
155165

156-
if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
166+
if (absolute == 0) {
157167
ticks += now;
158168
if (ticks > data->top_data.ticks) {
159169
ticks -= (data->top_data.ticks + 1);
160170
}
161171
timer_ll_set_alarm_value(data->hal_ctx.dev, data->hal_ctx.timer_id,
162172
(now + alarm_cfg->ticks));
163173
} else {
174+
irq_on_late = alarm_cfg->flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
175+
max_rel_val = top - data->top_data.guard_period;
164176
timer_ll_set_alarm_value(data->hal_ctx.dev, data->hal_ctx.timer_id,
165177
alarm_cfg->ticks);
166178
}
167179

168-
timer_ll_enable_intr(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id), true);
169-
timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_ALARM_EN);
170-
data->alarm_cfg.callback = alarm_cfg->callback;
171-
data->alarm_cfg.user_data = alarm_cfg->user_data;
180+
diff = (alarm_cfg->ticks - now);
181+
if (diff > max_rel_val) {
182+
if (absolute) {
183+
err = -ETIME;
184+
}
185+
if (irq_on_late) {
186+
timer_ll_enable_intr(data->hal_ctx.dev,
187+
TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id), true);
188+
timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id,
189+
TIMER_ALARM_EN);
190+
timer_ll_set_alarm_value(data->hal_ctx.dev, data->hal_ctx.timer_id, 0);
172191

173-
return 0;
192+
} else {
193+
data->alarm_cfg.callback = NULL;
194+
}
195+
} else {
196+
timer_ll_enable_intr(data->hal_ctx.dev,
197+
TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id), true);
198+
timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_ALARM_EN);
199+
}
200+
201+
return err;
174202
}
175203

176204
static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id)
@@ -263,6 +291,29 @@ static int counter_esp32_reset(const struct device *dev)
263291
return 0;
264292
}
265293

294+
static uint32_t counter_esp32_get_guard_period(const struct device *dev, uint32_t flags)
295+
{
296+
struct counter_esp32_data *data = dev->data;
297+
298+
ARG_UNUSED(flags);
299+
300+
return data->top_data.guard_period;
301+
}
302+
303+
static int counter_esp32_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags)
304+
{
305+
struct counter_esp32_data *data = dev->data;
306+
307+
ARG_UNUSED(flags);
308+
309+
if (ticks > data->top_data.ticks) {
310+
return -EINVAL;
311+
}
312+
313+
data->top_data.guard_period = ticks;
314+
return 0;
315+
}
316+
266317
static DEVICE_API(counter, counter_api) = {
267318
.start = counter_esp32_start,
268319
.stop = counter_esp32_stop,
@@ -275,6 +326,8 @@ static DEVICE_API(counter, counter_api) = {
275326
.get_pending_int = counter_esp32_get_pending_int,
276327
.get_top_value = counter_esp32_get_top_value,
277328
.get_freq = counter_esp32_get_freq,
329+
.get_guard_period = counter_esp32_get_guard_period,
330+
.set_guard_period = counter_esp32_set_guard_period,
278331
};
279332

280333
static void counter_esp32_isr(void *arg)

0 commit comments

Comments
 (0)