35
35
#include "modmachine.h"
36
36
#include "mphalport.h"
37
37
38
- #include "driver/timer .h"
38
+ #include "hal/timer_hal .h"
39
39
#include "hal/timer_ll.h"
40
+ #include "soc/timer_periph.h"
40
41
41
- #define TIMER_INTR_SEL TIMER_INTR_LEVEL
42
42
#define TIMER_DIVIDER 8
43
43
44
44
// TIMER_BASE_CLK is normally 80MHz. TIMER_DIVIDER ought to divide this exactly
48
48
49
49
typedef struct _machine_timer_obj_t {
50
50
mp_obj_base_t base ;
51
+
52
+ timer_hal_context_t hal_context ;
51
53
mp_uint_t group ;
52
54
mp_uint_t index ;
53
55
@@ -80,15 +82,9 @@ void machine_timer_deinit_all(void) {
80
82
81
83
STATIC void machine_timer_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
82
84
machine_timer_obj_t * self = self_in ;
83
-
84
- timer_config_t config ;
85
- mp_printf (print , "Timer(%p; " , self );
86
-
87
- timer_get_config (self -> group , self -> index , & config );
88
-
89
- mp_printf (print , "alarm_en=%d, " , config .alarm_en );
90
- mp_printf (print , "auto_reload=%d, " , config .auto_reload );
91
- mp_printf (print , "counter_en=%d)" , config .counter_en );
85
+ qstr mode = self -> repeat ? MP_QSTR_PERIODIC : MP_QSTR_ONE_SHOT ;
86
+ uint64_t period = self -> period / (TIMER_SCALE / 1000 ); // convert to ms
87
+ mp_printf (print , "Timer(%u, mode=%q, period=%lu)" , (self -> group << 1 ) | self -> index , mode , period );
92
88
}
93
89
94
90
STATIC mp_obj_t machine_timer_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
@@ -126,8 +122,14 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args,
126
122
}
127
123
128
124
STATIC void machine_timer_disable (machine_timer_obj_t * self ) {
125
+ if (self -> hal_context .dev != NULL ) {
126
+ // Disable the counter and alarm.
127
+ timer_ll_enable_counter (self -> hal_context .dev , self -> index , false);
128
+ timer_ll_enable_alarm (self -> hal_context .dev , self -> index , false);
129
+ }
130
+
129
131
if (self -> handle ) {
130
- timer_pause ( self -> group , self -> index );
132
+ // Free the interrupt handler.
131
133
esp_intr_free (self -> handle );
132
134
self -> handle = NULL ;
133
135
}
@@ -138,39 +140,47 @@ STATIC void machine_timer_disable(machine_timer_obj_t *self) {
138
140
139
141
STATIC void machine_timer_isr (void * self_in ) {
140
142
machine_timer_obj_t * self = self_in ;
141
- timg_dev_t * device = self -> group ? & (TIMERG1 ) : & (TIMERG0 );
142
143
143
- #if CONFIG_IDF_TARGET_ESP32S3
144
- device -> hw_timer [self -> index ].update .tn_update = 1 ;
145
- #else
146
- device -> hw_timer [self -> index ].update .tx_update = 1 ;
147
- #endif
144
+ uint32_t intr_status = timer_ll_get_intr_status (self -> hal_context .dev );
148
145
149
- timer_ll_clear_intr_status (device , self -> index );
150
- timer_ll_set_alarm_value (device , self -> index , self -> repeat );
151
-
152
- mp_sched_schedule (self -> callback , self );
153
- mp_hal_wake_main_task_from_isr ();
146
+ if (intr_status & TIMER_LL_EVENT_ALARM (self -> index )) {
147
+ timer_ll_clear_intr_status (self -> hal_context .dev , TIMER_LL_EVENT_ALARM (self -> index ));
148
+ if (self -> repeat ) {
149
+ timer_ll_enable_alarm (self -> hal_context .dev , self -> index , true);
150
+ }
151
+ mp_sched_schedule (self -> callback , self );
152
+ mp_hal_wake_main_task_from_isr ();
153
+ }
154
154
}
155
155
156
156
STATIC void machine_timer_enable (machine_timer_obj_t * self ) {
157
- timer_config_t config ;
158
- config .alarm_en = TIMER_ALARM_EN ;
159
- config .auto_reload = self -> repeat ;
160
- config .counter_dir = TIMER_COUNT_UP ;
161
- config .divider = TIMER_DIVIDER ;
162
- config .intr_type = TIMER_INTR_LEVEL ;
163
- config .counter_en = TIMER_PAUSE ;
164
- #if SOC_TIMER_GROUP_SUPPORT_XTAL
165
- config .clk_src = TIMER_SRC_CLK_APB ;
166
- #endif
167
-
168
- check_esp_err (timer_init (self -> group , self -> index , & config ));
169
- check_esp_err (timer_set_counter_value (self -> group , self -> index , 0x00000000 ));
170
- check_esp_err (timer_set_alarm_value (self -> group , self -> index , self -> period ));
171
- check_esp_err (timer_enable_intr (self -> group , self -> index ));
172
- check_esp_err (timer_isr_register (self -> group , self -> index , machine_timer_isr , (void * )self , TIMER_FLAGS , & self -> handle ));
173
- check_esp_err (timer_start (self -> group , self -> index ));
157
+ // Initialise the timer.
158
+ timer_hal_init (& self -> hal_context , self -> group , self -> index );
159
+ timer_ll_enable_counter (self -> hal_context .dev , self -> index , false);
160
+ timer_ll_set_clock_source (self -> hal_context .dev , self -> index , GPTIMER_CLK_SRC_APB );
161
+ timer_ll_set_clock_prescale (self -> hal_context .dev , self -> index , TIMER_DIVIDER );
162
+ timer_hal_set_counter_value (& self -> hal_context , 0 );
163
+ timer_ll_set_count_direction (self -> hal_context .dev , self -> index , GPTIMER_COUNT_UP );
164
+
165
+ // Allocate and enable the alarm interrupt.
166
+ timer_ll_enable_intr (self -> hal_context .dev , TIMER_LL_EVENT_ALARM (self -> index ), false);
167
+ timer_ll_clear_intr_status (self -> hal_context .dev , TIMER_LL_EVENT_ALARM (self -> index ));
168
+ ESP_ERROR_CHECK (
169
+ esp_intr_alloc (timer_group_periph_signals .groups [self -> group ].timer_irq_id [self -> index ],
170
+ TIMER_FLAGS , machine_timer_isr , self , & self -> handle )
171
+ );
172
+ timer_ll_enable_intr (self -> hal_context .dev , TIMER_LL_EVENT_ALARM (self -> index ), true);
173
+
174
+ // Enable the alarm to trigger at the given period.
175
+ timer_ll_set_alarm_value (self -> hal_context .dev , self -> index , self -> period );
176
+ timer_ll_enable_alarm (self -> hal_context .dev , self -> index , true);
177
+
178
+ // Set the counter to reload at 0 if it's in repeat mode.
179
+ timer_ll_set_reload_value (self -> hal_context .dev , self -> index , 0 );
180
+ timer_ll_enable_auto_reload (self -> hal_context .dev , self -> index , self -> repeat );
181
+
182
+ // Enable the counter.
183
+ timer_ll_enable_counter (self -> hal_context .dev , self -> index , true);
174
184
}
175
185
176
186
STATIC mp_obj_t machine_timer_init_helper (machine_timer_obj_t * self , mp_uint_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
@@ -234,11 +244,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_timer_init_obj, 1, machine_timer_init)
234
244
235
245
STATIC mp_obj_t machine_timer_value (mp_obj_t self_in ) {
236
246
machine_timer_obj_t * self = self_in ;
237
- double result ;
238
-
239
- timer_get_counter_time_sec (self -> group , self -> index , & result );
240
-
241
- return MP_OBJ_NEW_SMALL_INT ((mp_uint_t )(result * 1000 )); // value in ms
247
+ uint64_t result = timer_ll_get_counter_value (self -> hal_context .dev , self -> index );
248
+ return MP_OBJ_NEW_SMALL_INT ((mp_uint_t )(result / (TIMER_SCALE / 1000 ))); // value in ms
242
249
}
243
250
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (machine_timer_value_obj , machine_timer_value );
244
251
0 commit comments