@@ -24,11 +24,11 @@ static void counter_esp32_isr(void *arg);
24
24
25
25
typedef bool (* timer_isr_t )(void * );
26
26
27
- struct timer_isr_func_t {
28
- timer_isr_t fn ;
29
- void * args ;
30
- struct intr_handle_data_t * timer_isr_handle ;
31
- timer_group_t isr_timer_group ;
27
+ struct counter_esp32_top_data {
28
+ counter_top_callback_t callback ;
29
+ uint32_t ticks ;
30
+ void * user_data ;
31
+ bool auto_reload ;
32
32
};
33
33
34
34
struct counter_esp32_config {
@@ -45,10 +45,10 @@ struct counter_esp32_config {
45
45
46
46
struct counter_esp32_data {
47
47
struct counter_alarm_cfg alarm_cfg ;
48
+ struct counter_esp32_top_data top_data ;
48
49
uint32_t ticks ;
49
50
uint32_t clock_src_hz ;
50
51
timer_hal_context_t hal_ctx ;
51
- struct timer_isr_func_t timer_isr_fun ;
52
52
};
53
53
54
54
static int counter_esp32_init (const struct device * dev )
@@ -65,8 +65,13 @@ static int counter_esp32_init(const struct device *dev)
65
65
*/
66
66
clock_control_on (cfg -> clock_dev , cfg -> clock_subsys );
67
67
68
- timer_hal_init (& data -> hal_ctx , cfg -> group , cfg -> index );
69
68
data -> alarm_cfg .callback = NULL ;
69
+ data -> top_data .callback = NULL ;
70
+ data -> top_data .user_data = NULL ;
71
+ data -> top_data .auto_reload = false;
72
+ data -> top_data .ticks = cfg -> counter_info .max_top_value ;
73
+
74
+ timer_hal_init (& data -> hal_ctx , cfg -> group , cfg -> index );
70
75
timer_ll_enable_intr (data -> hal_ctx .dev , TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ),
71
76
false);
72
77
timer_ll_clear_intr_status (data -> hal_ctx .dev , TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ));
@@ -139,11 +144,20 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
139
144
{
140
145
ARG_UNUSED (chan_id );
141
146
struct counter_esp32_data * data = dev -> data ;
147
+ uint32_t ticks = alarm_cfg -> ticks ;
142
148
uint32_t now ;
143
149
150
+ if (ticks > data -> top_data .ticks ) {
151
+ return - EINVAL ;
152
+ }
153
+
144
154
counter_esp32_get_value (dev , & now );
145
155
146
156
if ((alarm_cfg -> flags & COUNTER_ALARM_CFG_ABSOLUTE ) == 0 ) {
157
+ ticks += now ;
158
+ if (ticks > data -> top_data .ticks ) {
159
+ ticks -= (data -> top_data .ticks + 1 );
160
+ }
147
161
timer_ll_set_alarm_value (data -> hal_ctx .dev , data -> hal_ctx .timer_id ,
148
162
(now + alarm_cfg -> ticks ));
149
163
} else {
@@ -163,23 +177,59 @@ static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id)
163
177
{
164
178
ARG_UNUSED (chan_id );
165
179
struct counter_esp32_data * data = dev -> data ;
166
-
167
180
timer_ll_enable_intr (data -> hal_ctx .dev , TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ),
168
181
false);
169
182
timer_ll_enable_alarm (data -> hal_ctx .dev , data -> hal_ctx .timer_id , TIMER_ALARM_DIS );
183
+ timer_ll_clear_intr_status (data -> hal_ctx .dev , TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ));
184
+
185
+ data -> alarm_cfg .callback = NULL ;
186
+ data -> alarm_cfg .user_data = NULL ;
170
187
171
188
return 0 ;
172
189
}
173
190
174
191
static int counter_esp32_set_top_value (const struct device * dev , const struct counter_top_cfg * cfg )
175
192
{
176
193
const struct counter_esp32_config * config = dev -> config ;
194
+ struct counter_esp32_data * data = dev -> data ;
195
+ uint32_t now ;
177
196
178
- if (cfg -> ticks != config -> counter_info .max_top_value ) {
197
+ if (data -> alarm_cfg .callback ) {
198
+ return - EBUSY ;
199
+ }
200
+
201
+ if (cfg -> ticks > config -> counter_info .max_top_value ) {
179
202
return - ENOTSUP ;
203
+ }
204
+
205
+ counter_esp32_get_value (dev , & now );
206
+
207
+ if (!(cfg -> flags & COUNTER_TOP_CFG_DONT_RESET )) {
208
+ timer_hal_set_counter_value (& data -> hal_ctx , 0 );
180
209
} else {
181
- return 0 ;
210
+ if (now > cfg -> ticks ) {
211
+ if (cfg -> flags & COUNTER_TOP_CFG_RESET_WHEN_LATE ) {
212
+ timer_hal_set_counter_value (& data -> hal_ctx , 0 );
213
+ } else {
214
+ return - ETIME ;
215
+ }
216
+ }
182
217
}
218
+
219
+ data -> top_data .ticks = cfg -> ticks ;
220
+ data -> top_data .callback = cfg -> callback ;
221
+ data -> top_data .user_data = cfg -> user_data ;
222
+ data -> top_data .auto_reload = (cfg -> callback != NULL );
223
+
224
+ timer_ll_clear_intr_status (data -> hal_ctx .dev , TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ));
225
+ timer_ll_set_alarm_value (data -> hal_ctx .dev , data -> hal_ctx .timer_id , cfg -> ticks );
226
+ timer_ll_enable_intr (data -> hal_ctx .dev , TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ), true);
227
+ timer_ll_enable_alarm (data -> hal_ctx .dev , data -> hal_ctx .timer_id , TIMER_ALARM_EN );
228
+
229
+ timer_ll_enable_auto_reload (data -> hal_ctx .dev , data -> hal_ctx .timer_id ,
230
+ cfg -> callback ? TIMER_AUTORELOAD_EN : TIMER_AUTORELOAD_DIS );
231
+
232
+ return 0 ;
183
233
}
184
234
185
235
static uint32_t counter_esp32_get_pending_int (const struct device * dev )
@@ -191,9 +241,9 @@ static uint32_t counter_esp32_get_pending_int(const struct device *dev)
191
241
192
242
static uint32_t counter_esp32_get_top_value (const struct device * dev )
193
243
{
194
- const struct counter_esp32_config * config = dev -> config ;
244
+ struct counter_esp32_data * data = dev -> data ;
195
245
196
- return config -> counter_info . max_top_value ;
246
+ return data -> top_data . ticks ;
197
247
}
198
248
199
249
uint32_t counter_esp32_get_freq (const struct device * dev )
@@ -233,11 +283,25 @@ static void counter_esp32_isr(void *arg)
233
283
struct counter_esp32_data * data = dev -> data ;
234
284
uint32_t now ;
235
285
236
- counter_esp32_cancel_alarm (dev , 0 );
237
286
counter_esp32_get_value (dev , & now );
238
287
239
288
if (data -> alarm_cfg .callback ) {
240
289
data -> alarm_cfg .callback (dev , 0 , now , data -> alarm_cfg .user_data );
290
+ timer_ll_enable_intr (data -> hal_ctx .dev ,
291
+ TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ), false);
292
+ timer_ll_enable_alarm (data -> hal_ctx .dev , data -> hal_ctx .timer_id , TIMER_ALARM_DIS );
293
+ data -> alarm_cfg .callback = NULL ;
294
+ data -> alarm_cfg .user_data = NULL ;
295
+ }
296
+
297
+ if (data -> top_data .callback ) {
298
+ data -> top_data .callback (dev , data -> top_data .user_data );
299
+ if (data -> top_data .auto_reload ) {
300
+ timer_ll_enable_intr (data -> hal_ctx .dev ,
301
+ TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ), true);
302
+ timer_ll_enable_alarm (data -> hal_ctx .dev , data -> hal_ctx .timer_id ,
303
+ TIMER_ALARM_EN );
304
+ }
241
305
}
242
306
243
307
timer_ll_clear_intr_status (data -> hal_ctx .dev , TIMER_LL_EVENT_ALARM (data -> hal_ctx .timer_id ));
0 commit comments