diff options
Diffstat (limited to 'ports/esp32')
-rw-r--r-- | ports/esp32/machine_timer.c | 34 | ||||
-rw-r--r-- | ports/esp32/machine_timer.h | 9 | ||||
-rw-r--r-- | ports/esp32/machine_uart.c | 4 | ||||
-rw-r--r-- | ports/esp32/mpconfigport.h | 2 |
4 files changed, 32 insertions, 17 deletions
diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index a104288f6..3fb893aad 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -38,13 +38,13 @@ #include "hal/timer_hal.h" #include "hal/timer_ll.h" #include "soc/timer_periph.h" +#include "esp_private/esp_clk_tree_common.h" +#include "esp_private/periph_ctrl.h" #include "machine_timer.h" +#define TIMER_CLK_SRC GPTIMER_CLK_SRC_DEFAULT #define TIMER_DIVIDER 8 -// TIMER_BASE_CLK is normally 80MHz. TIMER_DIVIDER ought to divide this exactly -#define TIMER_SCALE (APB_CLK_FREQ / TIMER_DIVIDER) - #define TIMER_FLAGS 0 const mp_obj_type_t machine_timer_type; @@ -52,6 +52,14 @@ const mp_obj_type_t machine_timer_type; 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); static mp_obj_t machine_timer_deinit(mp_obj_t self_in); +uint32_t machine_timer_freq_hz(void) { + // The timer source clock is APB or a fixed PLL (depending on chip), both constant frequency. + uint32_t freq; + check_esp_err(esp_clk_tree_src_get_freq_hz(TIMER_CLK_SRC, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq)); + assert(freq % TIMER_DIVIDER == 0); // Source clock should divide evenly into TIMER_DIVIDER + return freq / TIMER_DIVIDER; +} + void machine_timer_deinit_all(void) { // Disable, deallocate and remove all timers from list machine_timer_obj_t **t = &MP_STATE_PORT(machine_timer_obj_head); @@ -66,7 +74,7 @@ void machine_timer_deinit_all(void) { static void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_timer_obj_t *self = self_in; qstr mode = self->repeat ? MP_QSTR_PERIODIC : MP_QSTR_ONE_SHOT; - uint64_t period = self->period / (TIMER_SCALE / 1000); // convert to ms + uint64_t period = self->period / (machine_timer_freq_hz() / 1000); // convert to ms #if SOC_TIMER_GROUP_TIMERS_PER_GROUP == 1 mp_printf(print, "Timer(%u, mode=%q, period=%lu)", self->group, mode, period); #else @@ -163,8 +171,18 @@ static void machine_timer_isr_handler(machine_timer_obj_t *self) { void machine_timer_enable(machine_timer_obj_t *self) { // Initialise the timer. timer_hal_init(&self->hal_context, self->group, self->index); + + PERIPH_RCC_ACQUIRE_ATOMIC(timer_group_periph_signals.groups[self->index].module, ref_count) { + if (ref_count == 0) { + timer_ll_enable_bus_clock(self->index, true); + timer_ll_reset_register(self->index); + } + } + timer_ll_enable_counter(self->hal_context.dev, self->index, false); - timer_ll_set_clock_source(self->hal_context.dev, self->index, GPTIMER_CLK_SRC_DEFAULT); + esp_clk_tree_enable_src(TIMER_CLK_SRC, true); + timer_ll_set_clock_source(self->hal_context.dev, self->index, TIMER_CLK_SRC); + timer_ll_enable_clock(self->hal_context.dev, self->index, true); timer_ll_set_clock_prescale(self->hal_context.dev, self->index, TIMER_DIVIDER); timer_hal_set_counter_value(&self->hal_context, 0); timer_ll_set_count_direction(self->hal_context.dev, self->index, GPTIMER_COUNT_UP); @@ -224,7 +242,7 @@ static mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n #if MICROPY_PY_BUILTINS_FLOAT if (args[ARG_freq].u_obj != mp_const_none) { - self->period = (uint64_t)(TIMER_SCALE / mp_obj_get_float(args[ARG_freq].u_obj)); + self->period = (uint64_t)(machine_timer_freq_hz() / mp_obj_get_float(args[ARG_freq].u_obj)); } #else if (args[ARG_freq].u_int != 0xffffffff) { @@ -232,7 +250,7 @@ static mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n } #endif else { - self->period = (((uint64_t)args[ARG_period].u_int) * TIMER_SCALE) / args[ARG_tick_hz].u_int; + self->period = (((uint64_t)args[ARG_period].u_int) * machine_timer_freq_hz()) / args[ARG_tick_hz].u_int; } self->repeat = args[ARG_mode].u_int; @@ -268,7 +286,7 @@ static mp_obj_t machine_timer_value(mp_obj_t self_in) { mp_raise_ValueError(MP_ERROR_TEXT("timer not set")); } uint64_t result = timer_ll_get_counter_value(self->hal_context.dev, self->index); - return MP_OBJ_NEW_SMALL_INT((mp_uint_t)(result / (TIMER_SCALE / 1000))); // value in ms + return MP_OBJ_NEW_SMALL_INT((mp_uint_t)(result / (machine_timer_freq_hz() / 1000))); // value in ms } static MP_DEFINE_CONST_FUN_OBJ_1(machine_timer_value_obj, machine_timer_value); diff --git a/ports/esp32/machine_timer.h b/ports/esp32/machine_timer.h index 10fe2f39c..5dd0ce95a 100644 --- a/ports/esp32/machine_timer.h +++ b/ports/esp32/machine_timer.h @@ -34,13 +34,6 @@ #include "hal/timer_ll.h" #include "soc/timer_periph.h" -#define TIMER_DIVIDER 8 - -// TIMER_BASE_CLK is normally 80MHz. TIMER_DIVIDER ought to divide this exactly -#define TIMER_SCALE (APB_CLK_FREQ / TIMER_DIVIDER) - -#define TIMER_FLAGS 0 - typedef struct _machine_timer_obj_t { mp_obj_base_t base; @@ -64,4 +57,6 @@ machine_timer_obj_t *machine_timer_create(mp_uint_t timer); void machine_timer_enable(machine_timer_obj_t *self); void machine_timer_disable(machine_timer_obj_t *self); +uint32_t machine_timer_freq_hz(void); + #endif // MICROPY_INCLUDED_ESP32_MACHINE_TIMER_H diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c index 661c07138..c4dab2cae 100644 --- a/ports/esp32/machine_uart.c +++ b/ports/esp32/machine_uart.c @@ -58,7 +58,7 @@ #define UART_IRQ_RXIDLE (0x1000) #define UART_IRQ_BREAK (1 << UART_BREAK) #define MP_UART_ALLOWED_FLAGS (UART_IRQ_RX | UART_IRQ_RXIDLE | UART_IRQ_BREAK) -#define RXIDLE_TIMER_MIN (5000) // 500 us +#define RXIDLE_TIMER_MIN (machine_timer_freq_hz() * 5 / 10000) // 500us minimum rxidle time #define UART_QUEUE_SIZE (3) enum { @@ -535,7 +535,7 @@ static void uart_irq_configure_timer(machine_uart_obj_t *self, mp_uint_t trigger self->mp_irq_obj->ishard = false; uint32_t baudrate; uart_get_baudrate(self->uart_num, &baudrate); - mp_int_t period = TIMER_SCALE * 20 / baudrate + 1; + mp_int_t period = machine_timer_freq_hz() * 20 / baudrate + 1; if (period < RXIDLE_TIMER_MIN) { period = RXIDLE_TIMER_MIN; } diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index cc10fd0b7..e47b333c7 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -139,11 +139,13 @@ #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/esp32/machine_pwm.c" #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 (1) +#ifndef MICROPY_PY_MACHINE_I2C_TARGET // I2C target hardware is limited on ESP32 (eg read event comes after the read) so we only support newer SoCs. // ESP32C6 does not have enough flash space so also disable it on that SoC. #define MICROPY_PY_MACHINE_I2C_TARGET (SOC_I2C_SUPPORT_SLAVE && !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32C6) #define MICROPY_PY_MACHINE_I2C_TARGET_INCLUDEFILE "ports/esp32/machine_i2c_target.c" #define MICROPY_PY_MACHINE_I2C_TARGET_MAX (2) +#endif #define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) |