3838#include "hal/timer_hal.h"
3939#include "hal/timer_ll.h"
4040#include "soc/timer_periph.h"
41+ #include "esp_private/esp_clk_tree_common.h"
42+ #include "esp_private/periph_ctrl.h"
4143#include "machine_timer.h"
4244
45+ #define TIMER_CLK_SRC GPTIMER_CLK_SRC_DEFAULT
4346#define TIMER_DIVIDER 8
4447
45- // TIMER_BASE_CLK is normally 80MHz. TIMER_DIVIDER ought to divide this exactly
46- #define TIMER_SCALE (APB_CLK_FREQ / TIMER_DIVIDER)
47-
4848#define TIMER_FLAGS 0
4949
5050const mp_obj_type_t machine_timer_type ;
5151
5252static 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 );
5353static mp_obj_t machine_timer_deinit (mp_obj_t self_in );
5454
55+ uint32_t machine_timer_freq_hz (void ) {
56+ // The timer source clock is APB or a fixed PLL (depending on chip), both constant frequency.
57+ uint32_t freq ;
58+ check_esp_err (esp_clk_tree_src_get_freq_hz (TIMER_CLK_SRC , ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED , & freq ));
59+ assert (freq % TIMER_DIVIDER == 0 ); // Source clock should divide evenly into TIMER_DIVIDER
60+ return freq / TIMER_DIVIDER ;
61+ }
62+
5563void machine_timer_deinit_all (void ) {
5664 // Disable, deallocate and remove all timers from list
5765 machine_timer_obj_t * * t = & MP_STATE_PORT (machine_timer_obj_head );
@@ -66,7 +74,7 @@ void machine_timer_deinit_all(void) {
6674static void machine_timer_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
6775 machine_timer_obj_t * self = self_in ;
6876 qstr mode = self -> repeat ? MP_QSTR_PERIODIC : MP_QSTR_ONE_SHOT ;
69- uint64_t period = self -> period / (TIMER_SCALE / 1000 ); // convert to ms
77+ uint64_t period = self -> period / (machine_timer_freq_hz () / 1000 ); // convert to ms
7078 #if SOC_TIMER_GROUP_TIMERS_PER_GROUP == 1
7179 mp_printf (print , "Timer(%u, mode=%q, period=%lu)" , self -> group , mode , period );
7280 #else
@@ -163,8 +171,18 @@ static void machine_timer_isr_handler(machine_timer_obj_t *self) {
163171void machine_timer_enable (machine_timer_obj_t * self ) {
164172 // Initialise the timer.
165173 timer_hal_init (& self -> hal_context , self -> group , self -> index );
174+
175+ PERIPH_RCC_ACQUIRE_ATOMIC (timer_group_periph_signals .groups [self -> index ].module , ref_count ) {
176+ if (ref_count == 0 ) {
177+ timer_ll_enable_bus_clock (self -> index , true);
178+ timer_ll_reset_register (self -> index );
179+ }
180+ }
181+
166182 timer_ll_enable_counter (self -> hal_context .dev , self -> index , false);
167- timer_ll_set_clock_source (self -> hal_context .dev , self -> index , GPTIMER_CLK_SRC_DEFAULT );
183+ esp_clk_tree_enable_src (TIMER_CLK_SRC , true);
184+ timer_ll_set_clock_source (self -> hal_context .dev , self -> index , TIMER_CLK_SRC );
185+ timer_ll_enable_clock (self -> hal_context .dev , self -> index , true);
168186 timer_ll_set_clock_prescale (self -> hal_context .dev , self -> index , TIMER_DIVIDER );
169187 timer_hal_set_counter_value (& self -> hal_context , 0 );
170188 timer_ll_set_count_direction (self -> hal_context .dev , self -> index , GPTIMER_COUNT_UP );
@@ -224,15 +242,15 @@ static mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n
224242
225243 #if MICROPY_PY_BUILTINS_FLOAT
226244 if (args [ARG_freq ].u_obj != mp_const_none ) {
227- self -> period = (uint64_t )(TIMER_SCALE / mp_obj_get_float (args [ARG_freq ].u_obj ));
245+ self -> period = (uint64_t )(machine_timer_freq_hz () / mp_obj_get_float (args [ARG_freq ].u_obj ));
228246 }
229247 #else
230248 if (args [ARG_freq ].u_int != 0xffffffff ) {
231249 self -> period = TIMER_SCALE / ((uint64_t )args [ARG_freq ].u_int );
232250 }
233251 #endif
234252 else {
235- self -> period = (((uint64_t )args [ARG_period ].u_int ) * TIMER_SCALE ) / args [ARG_tick_hz ].u_int ;
253+ self -> period = (((uint64_t )args [ARG_period ].u_int ) * machine_timer_freq_hz () ) / args [ARG_tick_hz ].u_int ;
236254 }
237255
238256 self -> repeat = args [ARG_mode ].u_int ;
@@ -268,7 +286,7 @@ static mp_obj_t machine_timer_value(mp_obj_t self_in) {
268286 mp_raise_ValueError (MP_ERROR_TEXT ("timer not set" ));
269287 }
270288 uint64_t result = timer_ll_get_counter_value (self -> hal_context .dev , self -> index );
271- return MP_OBJ_NEW_SMALL_INT ((mp_uint_t )(result / (TIMER_SCALE / 1000 ))); // value in ms
289+ return MP_OBJ_NEW_SMALL_INT ((mp_uint_t )(result / (machine_timer_freq_hz () / 1000 ))); // value in ms
272290}
273291static MP_DEFINE_CONST_FUN_OBJ_1 (machine_timer_value_obj , machine_timer_value ) ;
274292
0 commit comments