Skip to content

Commit 00d6a79

Browse files
committed
stm32/machine_timer: Improve usability of Timer constructor and init.
Improvements are: - Default period is 1000ms with callback disabled. - if period is not specified then it's not updated (previously, if period was not specified then it was set to -1 and running the timer callback as fast as possible, making the REPL unresponsive). - Use uint64_t to compute delta_ms, and raise a ValueError if the period is too large. - If callback is not specified then it's not updated. - Specifying None for the callback will disable the timer. Signed-off-by: Damien George <[email protected]>
1 parent 6e0f9b9 commit 00d6a79

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

ports/stm32/machine_timer.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar
4242
enum { ARG_mode, ARG_callback, ARG_period, ARG_tick_hz, ARG_freq, };
4343
static const mp_arg_t allowed_args[] = {
4444
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SOFT_TIMER_MODE_PERIODIC} },
45-
{ MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
45+
{ MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
4646
{ MP_QSTR_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} },
4747
{ MP_QSTR_tick_hz, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} },
4848
{ MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
@@ -53,31 +53,44 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar
5353
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
5454

5555
self->mode = args[ARG_mode].u_int;
56+
57+
uint64_t delta_ms = self->delta_ms;
5658
if (args[ARG_freq].u_obj != mp_const_none) {
5759
// Frequency specified in Hz
5860
#if MICROPY_PY_BUILTINS_FLOAT
59-
self->delta_ms = (uint32_t)(MICROPY_FLOAT_CONST(1000.0) / mp_obj_get_float(args[ARG_freq].u_obj));
61+
delta_ms = (uint32_t)(MICROPY_FLOAT_CONST(1000.0) / mp_obj_get_float(args[ARG_freq].u_obj));
6062
#else
61-
self->delta_ms = 1000 / mp_obj_get_int(args[ARG_freq].u_obj);
63+
delta_ms = 1000 / mp_obj_get_int(args[ARG_freq].u_obj);
6264
#endif
63-
} else {
65+
} else if (args[ARG_period].u_int != 0xffffffff) {
6466
// Period specified
65-
self->delta_ms = args[ARG_period].u_int * 1000 / args[ARG_tick_hz].u_int;
67+
delta_ms = (uint64_t)args[ARG_period].u_int * 1000 / args[ARG_tick_hz].u_int;
6668
}
67-
if (self->delta_ms < 1) {
68-
self->delta_ms = 1;
69+
70+
if (delta_ms < 1) {
71+
delta_ms = 1;
72+
} else if (delta_ms >= 0x40000000) {
73+
mp_raise_ValueError(MP_ERROR_TEXT("period too large"));
6974
}
75+
self->delta_ms = (uint32_t)delta_ms;
7076
self->expiry_ms = mp_hal_ticks_ms() + self->delta_ms;
7177

72-
self->callback = args[ARG_callback].u_obj;
73-
soft_timer_insert(self);
78+
if (args[ARG_callback].u_obj != MP_OBJ_NULL) {
79+
self->callback = args[ARG_callback].u_obj;
80+
}
81+
82+
if (self->callback != mp_const_none) {
83+
soft_timer_insert(self);
84+
}
7485

7586
return mp_const_none;
7687
}
7788

7889
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) {
7990
machine_timer_obj_t *self = m_new_obj(machine_timer_obj_t);
8091
self->pairheap.base.type = &machine_timer_type;
92+
self->delta_ms = 1000;
93+
self->callback = mp_const_none;
8194

8295
// Get timer id (only soft timer (-1) supported at the moment)
8396
mp_int_t id = -1;

0 commit comments

Comments
 (0)