Skip to content

Commit

Permalink
esp32/machine_timer.c: Add find free timer id.
Browse files Browse the repository at this point in the history
``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 <Ihor.Nehrutsa@gmail.com>
  • Loading branch information
IhorNehrutsa authored and IhorNehrutsa committed Jan 8, 2024
1 parent a00c9d5 commit a2e89b1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/library/machine.Timer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
37 changes: 35 additions & 2 deletions ports/esp32/machine_timer.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;

Expand All @@ -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) {
Expand Down

0 comments on commit a2e89b1

Please sign in to comment.