@@ -58,7 +58,9 @@ tmr.softwd(int)
58
58
#include "lualib.h"
59
59
#include "esp_timer.h"
60
60
#include "esp_misc.h"
61
+ #include "esp_system.h"
61
62
#include "modules.h"
63
+ #include "driver/timer.h"
62
64
63
65
#define NUM_TMR 7
64
66
@@ -68,35 +70,50 @@ tmr.softwd(int)
68
70
#define TIMER_MODE_AUTO 1
69
71
#define TIMER_IDLE_FLAG (1<<7)
70
72
73
+ #define TIMER_DIVIDER 16 // Hardware timer clock divider
74
+ #define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
75
+
76
+ #define TIMER_INTERVAL0_SEC (3.4179) // sample test interval for the first timer
77
+ #define TEST_WITHOUT_RELOAD 0 // testing will be done without auto reload
78
+ #define TEST_WITH_RELOAD 1 // testing will be done with auto reload
79
+
80
+
71
81
//well, the following are my assumptions
72
82
//why, oh why is there no good documentation
73
83
//chinese companies should learn from Atmel
74
84
extern void ets_delay_us (uint32_t us );
75
85
extern uint32_t system_get_time ();
76
86
//extern uint32_t system_rtc_clock_cali_proc();
77
87
extern uint32_t system_get_rtc_time ();
78
- extern void system_restart ();
79
88
extern void system_soft_wdt_feed ();
80
89
81
90
//in fact lua_State is constant, it's pointless to pass it around
82
91
//but hey, whatever, I'll just pass it, still we waste 28B here
83
92
typedef struct {
84
- os_timer_t os ;
93
+ // os_timer_t os;
85
94
lua_State * L ;
86
95
sint32_t lua_ref ;
87
96
uint32_t interval ;
88
97
uint8_t mode ;
89
98
}timer_struct_t ;
90
99
typedef timer_struct_t * my_timer_t ;
91
100
101
+ typedef struct {
102
+ int type ; // the type of timer's event
103
+ int timer_group ;
104
+ int timer_idx ;
105
+ uint64_t timer_counter_value ;
106
+ } timer_event_t ;
107
+
92
108
//everybody just love unions! riiiiight?
93
109
static union {
94
110
uint64_t block ;
95
111
uint32_t part [2 ];
96
112
} rtc_time ;
97
113
static sint32_t soft_watchdog = -1 ;
98
114
static timer_struct_t alarm_timers [NUM_TMR ];
99
- static os_timer_t rtc_timer ;
115
+ //static os_timer_t rtc_timer;
116
+ static xQueueHandle timer_queue ;
100
117
101
118
static void alarm_timer_common (void * arg ){
102
119
my_timer_t tmr = & alarm_timers [(uint32_t )arg ];
@@ -159,6 +176,80 @@ static int tmr_now(lua_State* L){
159
176
return 1 ;
160
177
}
161
178
179
+ /*
180
+ * Timer group0 ISR handler
181
+ *
182
+ * Note:
183
+ * We don't call the timer API here because they are not declared with IRAM_ATTR.
184
+ * If we're okay with the timer irq not being serviced while SPI flash cache is disabled,
185
+ * we can allocate this interrupt without the ESP_INTR_FLAG_IRAM flag and use the normal API.
186
+ */
187
+ void IRAM_ATTR timer_group0_isr (void * para )
188
+ {
189
+ int timer_idx = (int ) para ;
190
+
191
+ /* Retrieve the interrupt status and the counter value
192
+ from the timer that reported the interrupt */
193
+ uint32_t intr_status = TIMERG0 .int_st_timers .val ;
194
+ TIMERG0 .hw_timer [timer_idx ].update = 1 ;
195
+ uint64_t timer_counter_value =
196
+ ((uint64_t ) TIMERG0 .hw_timer [timer_idx ].cnt_high ) << 32
197
+ | TIMERG0 .hw_timer [timer_idx ].cnt_low ;
198
+
199
+ /* Prepare basic event data
200
+ that will be then sent back to the main program task */
201
+ timer_event_t evt ;
202
+ evt .timer_group = 0 ;
203
+ evt .timer_idx = timer_idx ;
204
+ evt .timer_counter_value = timer_counter_value ;
205
+
206
+ /* Clear the interrupt
207
+ and update the alarm time for the timer with without reload */
208
+ if ((intr_status & BIT (timer_idx )) && timer_idx == TIMER_0 ) {
209
+ evt .type = TEST_WITHOUT_RELOAD ;
210
+ TIMERG0 .int_clr_timers .t0 = 1 ;
211
+ timer_counter_value += (uint64_t ) (TIMER_INTERVAL0_SEC * TIMER_SCALE );
212
+ TIMERG0 .hw_timer [timer_idx ].alarm_high = (uint32_t ) (timer_counter_value >> 32 );
213
+ TIMERG0 .hw_timer [timer_idx ].alarm_low = (uint32_t ) timer_counter_value ;
214
+ } else if ((intr_status & BIT (timer_idx )) && timer_idx == TIMER_1 ) {
215
+ evt .type = TEST_WITH_RELOAD ;
216
+ TIMERG0 .int_clr_timers .t1 = 1 ;
217
+ } else {
218
+ evt .type = -1 ; // not supported even type
219
+ }
220
+
221
+ /* After the alarm has been triggered
222
+ we need enable it again, so it is triggered the next time */
223
+ TIMERG0 .hw_timer [timer_idx ].config .alarm_en = TIMER_ALARM_EN ;
224
+
225
+ /* Now just send the event data back to the main program task */
226
+ xQueueSendFromISR (timer_queue , & evt , NULL );
227
+ }
228
+
229
+ static void example_tg0_timer_init (int timer_idx , bool auto_reload , double timer_interval_sec ) {
230
+ /* Select and initialize basic parameters of the timer */
231
+ timer_config_t config ;
232
+ config .divider = TIMER_DIVIDER ;
233
+ config .counter_dir = TIMER_COUNT_UP ;
234
+ config .counter_en = TIMER_PAUSE ;
235
+ config .alarm_en = TIMER_ALARM_EN ;
236
+ config .intr_type = TIMER_INTR_LEVEL ;
237
+ config .auto_reload = auto_reload ;
238
+ timer_init (TIMER_GROUP_0 , timer_idx , & config );
239
+
240
+ /* Timer's counter will initially start from value below.
241
+ Also, if auto_reload is set, this value will be automatically reload on alarm */
242
+ timer_set_counter_value (TIMER_GROUP_0 , timer_idx , 0x00000000ULL );
243
+
244
+ /* Configure the alarm value and the interrupt on alarm. */
245
+ timer_set_alarm_value (TIMER_GROUP_0 , timer_idx , timer_interval_sec * TIMER_SCALE );
246
+ timer_enable_intr (TIMER_GROUP_0 , timer_idx );
247
+ timer_isr_register (TIMER_GROUP_0 , timer_idx , timer_group0_isr ,
248
+ (void * ) timer_idx , ESP_INTR_FLAG_IRAM , NULL );
249
+
250
+ timer_start (TIMER_GROUP_0 , timer_idx );
251
+ }
252
+
162
253
// Lua: tmr.register( id, interval, mode, function )
163
254
static int tmr_register (lua_State * L ){
164
255
uint32_t id = luaL_checkinteger (L , 1 );
@@ -175,16 +266,18 @@ static int tmr_register(lua_State* L){
175
266
lua_pushvalue (L , 4 );
176
267
sint32_t ref = luaL_ref (L , LUA_REGISTRYINDEX );
177
268
my_timer_t tmr = & alarm_timers [id ];
178
- if (!(tmr -> mode & TIMER_IDLE_FLAG ) && tmr -> mode != TIMER_MODE_OFF )
179
- os_timer_disarm (& tmr -> os );
269
+ if (!(tmr -> mode & TIMER_IDLE_FLAG ) && tmr -> mode != TIMER_MODE_OFF ) {
270
+ //os_timer_disarm(&tmr->os);
271
+ }
180
272
//there was a bug in this part, the second part of the following condition was missing
181
273
if (tmr -> lua_ref != LUA_NOREF && tmr -> lua_ref != ref )
182
274
luaL_unref (L , LUA_REGISTRYINDEX , tmr -> lua_ref );
183
275
tmr -> lua_ref = ref ;
184
276
tmr -> mode = mode |TIMER_IDLE_FLAG ;
185
277
tmr -> interval = interval ;
186
278
tmr -> L = L ;
187
- os_timer_setfn (& tmr -> os , alarm_timer_common , (void * )id );
279
+ //os_timer_setfn(&tmr->os, alarm_timer_common, (void*)id);
280
+ example_tg0_timer_init (TIMER_0 , TEST_WITHOUT_RELOAD , interval );
188
281
return 0 ;
189
282
}
190
283
@@ -198,7 +291,7 @@ static int tmr_start(lua_State* L){
198
291
lua_pushboolean (L , 0 );
199
292
}else {
200
293
tmr -> mode &= ~TIMER_IDLE_FLAG ;
201
- os_timer_arm (& tmr -> os , tmr -> interval , tmr -> mode == TIMER_MODE_AUTO );
294
+ // os_timer_arm(&tmr->os, tmr->interval, tmr->mode==TIMER_MODE_AUTO);
202
295
lua_pushboolean (L , 1 );
203
296
}
204
297
return 1 ;
@@ -218,7 +311,7 @@ static int tmr_stop(lua_State* L){
218
311
//we return false if the timer is idle (of not registered)
219
312
if (!(tmr -> mode & TIMER_IDLE_FLAG ) && tmr -> mode != TIMER_MODE_OFF ){
220
313
tmr -> mode |= TIMER_IDLE_FLAG ;
221
- os_timer_disarm (& tmr -> os );
314
+ // os_timer_disarm(&tmr->os);
222
315
lua_pushboolean (L , 1 );
223
316
}else {
224
317
lua_pushboolean (L , 0 );
@@ -231,8 +324,9 @@ static int tmr_unregister(lua_State* L){
231
324
uint8_t id = luaL_checkinteger (L , 1 );
232
325
//MOD_CHECK_ID(tmr,id);
233
326
my_timer_t tmr = & alarm_timers [id ];
234
- if (!(tmr -> mode & TIMER_IDLE_FLAG ) && tmr -> mode != TIMER_MODE_OFF )
235
- os_timer_disarm (& tmr -> os );
327
+ if (!(tmr -> mode & TIMER_IDLE_FLAG ) && tmr -> mode != TIMER_MODE_OFF ) {
328
+ //os_timer_disarm(&tmr->os);
329
+ }
236
330
if (tmr -> lua_ref != LUA_NOREF )
237
331
luaL_unref (L , LUA_REGISTRYINDEX , tmr -> lua_ref );
238
332
tmr -> lua_ref = LUA_NOREF ;
@@ -251,8 +345,8 @@ static int tmr_interval(lua_State* L){
251
345
if (tmr -> mode != TIMER_MODE_OFF ){
252
346
tmr -> interval = interval ;
253
347
if (!(tmr -> mode & TIMER_IDLE_FLAG )){
254
- os_timer_disarm (& tmr -> os );
255
- os_timer_arm (& tmr -> os , tmr -> interval , tmr -> mode == TIMER_MODE_AUTO );
348
+ // os_timer_disarm(&tmr->os);
349
+ // os_timer_arm(&tmr->os, tmr->interval, tmr->mode==TIMER_MODE_AUTO);
256
350
}
257
351
}
258
352
return 0 ;
@@ -313,7 +407,7 @@ void rtc_callback(void *arg){
313
407
if (soft_watchdog > 0 ){
314
408
soft_watchdog -- ;
315
409
if (soft_watchdog == 0 )
316
- system_restart ();
410
+ esp_restart ();
317
411
}
318
412
}
319
413
@@ -365,3 +459,38 @@ LUALIB_API int luaopen_tmr(lua_State *L)
365
459
return 1 ;
366
460
#endif
367
461
}
462
+
463
+
464
+ static void timer_evt_task (void * arg ) {
465
+ while (1 ) {
466
+ timer_event_t evt ;
467
+ xQueueReceive (timer_queue , & evt , portMAX_DELAY );
468
+
469
+ /* Print information that the timer reported an event */
470
+ if (evt .type == TEST_WITHOUT_RELOAD ) {
471
+ printf ("\n Example timer without reload\n" );
472
+ } else if (evt .type == TEST_WITH_RELOAD ) {
473
+ printf ("\n Example timer with auto reload\n" );
474
+ } else {
475
+ printf ("\n UNKNOWN EVENT TYPE\n" );
476
+ }
477
+ printf ("Group[%d], timer[%d] alarm event\n" , evt .timer_group , evt .timer_idx );
478
+
479
+ /* Print the timer values passed by event */
480
+ printf ("------- EVENT TIME --------\n" );
481
+ //print_timer_counter(evt.timer_counter_value);
482
+
483
+ /* Print the timer values as visible by this task */
484
+ printf ("-------- TASK TIME --------\n" );
485
+ uint64_t task_counter_value ;
486
+ timer_get_counter_value (evt .timer_group , evt .timer_idx , & task_counter_value );
487
+ //print_timer_counter(task_counter_value);
488
+ }
489
+ }
490
+
491
+ void tmr_init (void ) {
492
+ // timer task init
493
+ printf ("timer task init\r\n" );
494
+ timer_queue = xQueueCreate (10 , sizeof (timer_event_t ));
495
+ xTaskCreate (timer_evt_task , "timer_evt_task" , 2048 , NULL , 5 , NULL );
496
+ }
0 commit comments