From 3f98317f1a8fd67e93256d602ef2aa7cdd65801d Mon Sep 17 00:00:00 2001 From: IhorNehrutsa <70886343+IhorNehrutsa@users.noreply.github.com> Date: Thu, 3 Aug 2023 18:04:05 +0300 Subject: [PATCH] esp32/machine_timer.c: Add find free timer id. ``id`` of -2 selects the ``id`` of a free timer. Check the timer `id` range. Check if the timer is already in use. Signed-off-by: IhorNehrutsa --- docs/library/machine.Timer.rst | 1 + ports/esp32/machine_timer.c | 37 ++++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) mode change 100644 => 100755 ports/esp32/machine_timer.c diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst index 44e6594080558..a26865cc4d3b4 100644 --- a/docs/library/machine.Timer.rst +++ b/docs/library/machine.Timer.rst @@ -31,6 +31,7 @@ Constructors Construct a new timer object of the given ``id``. ``id`` of -1 constructs a virtual timer (if supported by a board). + ``id`` of -2 selects the ``id`` of a free timer (Supported at ESP32 port). ``id`` shall not be passed as a keyword argument. See ``init`` for parameters of initialisation. diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c old mode 100644 new mode 100755 index aba3db1983fce..58f1cc9d53c81 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -38,6 +38,7 @@ #include "hal/timer_hal.h" #include "hal/timer_ll.h" #include "soc/timer_periph.h" +#include "soc/soc_caps.h" #define TIMER_DIVIDER 8 @@ -87,10 +88,40 @@ STATIC void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_pr mp_printf(print, "Timer(%u, mode=%q, period=%lu)", (self->group << 1) | self->index, mode, period); } +STATIC bool find_free_timer(mp_int_t *group, mp_int_t *index) { + // from highest to lowest id + for (*group = SOC_TIMER_GROUPS - 1; *group >= 0; --(*group)) { + for (*index = SOC_TIMER_GROUP_TIMERS_PER_GROUP - 1; *index >= 0; --(*index)) { + bool free = true; + // Check whether the timer is already initialized, if so skip it + for (machine_timer_obj_t *t = MP_STATE_PORT(machine_timer_obj_head); t; t = t->next) { + if (t->group == *group && t->index == *index) { + free = false; + break; + } + } + if (free) { + return true; + } + } + } + return false; +} + 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) { mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - mp_uint_t group = (mp_obj_get_int(args[0]) >> 1) & 1; - mp_uint_t index = mp_obj_get_int(args[0]) & 1; + mp_int_t group = (mp_obj_get_int(args[0]) >> 1) & 1; + mp_int_t index = mp_obj_get_int(args[0]) & 1; + + mp_int_t id = mp_obj_get_int(args[0]); + if (id == -2) { + if (!find_free_timer(&group, &index)) { + mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("out of Timers:%d"), SOC_TIMER_GROUP_TOTAL_TIMERS); + } + } else if ((id < 0) || (id > SOC_TIMER_GROUP_TOTAL_TIMERS)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("id must be from 0 to %d"), SOC_TIMER_GROUP_TOTAL_TIMERS); + + } machine_timer_obj_t *self = NULL; @@ -110,6 +141,8 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, // Add the timer to the linked-list of timers self->next = MP_STATE_PORT(machine_timer_obj_head); MP_STATE_PORT(machine_timer_obj_head) = self; + } else { + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("already used")); } if (n_args > 1 || n_kw > 0) {