@@ -29,6 +29,7 @@ struct counter_esp32_top_data {
29
29
uint32_t ticks ;
30
30
void * user_data ;
31
31
bool auto_reload ;
32
+ uint32_t guard_period ;
32
33
};
33
34
34
35
struct counter_esp32_config {
@@ -144,33 +145,60 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
144
145
{
145
146
ARG_UNUSED (chan_id );
146
147
struct counter_esp32_data * data = dev -> data ;
148
+ bool absolute = alarm_cfg -> flags & COUNTER_ALARM_CFG_ABSOLUTE ;
147
149
uint32_t ticks = alarm_cfg -> ticks ;
150
+ uint32_t top = data -> top_data .ticks ;
151
+ uint32_t max_rel_val = data -> top_data .ticks ;
148
152
uint32_t now ;
153
+ uint32_t diff ;
154
+ int err = 0 ;
155
+ bool irq_on_late = 0 ;
149
156
150
157
if (ticks > data -> top_data .ticks ) {
151
158
return - EINVAL ;
152
159
}
153
160
161
+ data -> alarm_cfg .callback = alarm_cfg -> callback ;
162
+ data -> alarm_cfg .user_data = alarm_cfg -> user_data ;
163
+
154
164
counter_esp32_get_value (dev , & now );
155
165
156
- if (( alarm_cfg -> flags & COUNTER_ALARM_CFG_ABSOLUTE ) == 0 ) {
166
+ if (absolute == 0 ) {
157
167
ticks += now ;
158
168
if (ticks > data -> top_data .ticks ) {
159
169
ticks -= (data -> top_data .ticks + 1 );
160
170
}
161
171
timer_ll_set_alarm_value (data -> hal_ctx .dev , data -> hal_ctx .timer_id ,
162
172
(now + alarm_cfg -> ticks ));
163
173
} else {
174
+ irq_on_late = alarm_cfg -> flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE ;
175
+ max_rel_val = top - data -> top_data .guard_period ;
164
176
timer_ll_set_alarm_value (data -> hal_ctx .dev , data -> hal_ctx .timer_id ,
165
177
alarm_cfg -> ticks );
166
178
}
167
179
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 );
172
191
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 ;
174
202
}
175
203
176
204
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)
263
291
return 0 ;
264
292
}
265
293
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
+
266
317
static DEVICE_API (counter , counter_api ) = {
267
318
.start = counter_esp32_start ,
268
319
.stop = counter_esp32_stop ,
@@ -275,6 +326,8 @@ static DEVICE_API(counter, counter_api) = {
275
326
.get_pending_int = counter_esp32_get_pending_int ,
276
327
.get_top_value = counter_esp32_get_top_value ,
277
328
.get_freq = counter_esp32_get_freq ,
329
+ .get_guard_period = counter_esp32_get_guard_period ,
330
+ .set_guard_period = counter_esp32_set_guard_period ,
278
331
};
279
332
280
333
static void counter_esp32_isr (void * arg )
0 commit comments