Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 127fcd6

Browse files
committed
cmodules/m5utils: Add binding for FreeRTOS soft timer.
Signed-off-by: lbuque <[email protected]>
1 parent 0a01ab1 commit 127fcd6

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed

m5stack/cmodules/m5utils/m5utils.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ static mp_obj_t m5_utils_remap(size_t n_args, const mp_obj_t *args) {
2626
}
2727
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(m5_utils_remap_obj, 5, 5, m5_utils_remap);
2828

29+
extern const mp_obj_type_t mp_m5utils_timer_type;
2930

3031
static const mp_rom_map_elem_t m5utils_module_globals_table[] = {
3132
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_m5utils) },
3233

3334
{ MP_ROM_QSTR(MP_QSTR_remap), MP_ROM_PTR(&m5_utils_remap_obj) },
35+
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&mp_m5utils_timer_type) },
3436
};
3537

3638
static MP_DEFINE_CONST_DICT(m5utils_module_globals, m5utils_module_globals_table);

m5stack/cmodules/m5utils/m5utils.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_library(usermod_M5UTILS INTERFACE)
66

77
target_sources(usermod_M5UTILS INTERFACE
88
${CMAKE_CURRENT_LIST_DIR}/m5utils.c
9+
${CMAKE_CURRENT_LIST_DIR}/timer.c
910
)
1011

1112
target_include_directories(usermod_M5UTILS INTERFACE
@@ -16,6 +17,7 @@ target_link_libraries(usermod INTERFACE usermod_M5UTILS)
1617

1718
set_source_files_properties(
1819
${CMAKE_CURRENT_LIST_DIR}/m5utils.c
20+
${CMAKE_CURRENT_LIST_DIR}/timer.c
1921
PROPERTIES COMPILE_FLAGS
2022
"-Wno-discarded-qualifiers -Wno-implicit-int"
2123
)

m5stack/cmodules/m5utils/timer.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
#include <py/runtime.h>
7+
#include <py/objstr.h>
8+
#include <py/objmodule.h>
9+
10+
#include "freertos/FreeRTOS.h"
11+
#include "freertos/timers.h"
12+
13+
typedef struct _mp_m5utils_timer_t {
14+
mp_obj_base_t base;
15+
TimerHandle_t timer_handler;
16+
mp_uint_t period_ms;
17+
mp_uint_t repeat;
18+
mp_obj_t callback;
19+
} mp_m5utils_timer_t;
20+
21+
extern const mp_obj_type_t mp_m5utils_timer_type;
22+
23+
static void vTimerCallback(TimerHandle_t timer) {
24+
mp_m5utils_timer_t *self = pvTimerGetTimerID(timer);
25+
if (self->callback != mp_const_none) {
26+
mp_sched_schedule(self->callback, self);
27+
}
28+
}
29+
30+
static mp_obj_t mp_m5utils_timer_init_helper(mp_m5utils_timer_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
31+
enum {
32+
ARG_mode,
33+
ARG_period,
34+
ARG_callback,
35+
};
36+
static const mp_arg_t allowed_args[] = {
37+
/* *FORMAT-OFF* */
38+
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
39+
{ MP_QSTR_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} },
40+
{ MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
41+
/* *FORMAT-ON* */
42+
};
43+
44+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
45+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
46+
47+
self->repeat = args[ARG_mode].u_int;
48+
self->period_ms = args[ARG_period].u_int;
49+
self->callback = args[ARG_callback].u_obj;
50+
51+
return mp_const_none;
52+
}
53+
54+
55+
static void mp_m5utils_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
56+
mp_m5utils_timer_t *self = MP_OBJ_TO_PTR(self_in);
57+
qstr mode = self->repeat ? MP_QSTR_PERIODIC : MP_QSTR_ONE_SHOT;
58+
59+
mp_printf(print, "Timer(mode=%q, period=%lu)", mode, self->period_ms);
60+
}
61+
62+
static mp_obj_t mp_m5utils_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
63+
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
64+
65+
mp_m5utils_timer_t *self = m_new_obj(mp_m5utils_timer_t);
66+
self->base.type = &mp_m5utils_timer_type;
67+
68+
mp_map_t kw_args;
69+
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
70+
mp_m5utils_timer_init_helper(self, n_args - 1, args + 1, &kw_args);
71+
72+
self->timer_handler = xTimerCreate("freertos timer", pdMS_TO_TICKS(self->period_ms), self->repeat, self, vTimerCallback);
73+
if (self->timer_handler == NULL) {
74+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed creating FreeRTOS timer"));
75+
}
76+
if (xTimerStart(self->timer_handler, 0) != pdPASS) {
77+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed starting FreeRTOS timer"));
78+
}
79+
return self;
80+
}
81+
82+
83+
static mp_obj_t mp_m5utils_timer_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
84+
mp_m5utils_timer_t *self = args[0];
85+
mp_m5utils_timer_init_helper(self, n_args - 1, args + 1, kw_args);
86+
if (self->timer_handler) {
87+
xTimerDelete(self->timer_handler, portMAX_DELAY);
88+
self->timer_handler = NULL;
89+
}
90+
self->timer_handler = xTimerCreate("freertos timer", pdMS_TO_TICKS(self->period_ms), self->repeat, self, vTimerCallback);
91+
if (self->timer_handler == NULL) {
92+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed creating FreeRTOS timer"));
93+
}
94+
if (xTimerStart(self->timer_handler, 0) != pdPASS) {
95+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed starting FreeRTOS timer"));
96+
}
97+
return mp_const_none;
98+
}
99+
static MP_DEFINE_CONST_FUN_OBJ_KW(mp_m5utils_timer_init_obj, 1, mp_m5utils_timer_init);
100+
101+
static mp_obj_t mp_m5utils_timer_deinit(mp_obj_t self_in) {
102+
mp_m5utils_timer_t *self = MP_OBJ_TO_PTR(self_in);
103+
if (self->timer_handler) {
104+
xTimerDelete(self->timer_handler, portMAX_DELAY);
105+
self->timer_handler = NULL;
106+
}
107+
108+
return mp_const_none;
109+
}
110+
static MP_DEFINE_CONST_FUN_OBJ_1(mp_m5utils_timer_deinit_obj, mp_m5utils_timer_deinit);
111+
112+
113+
114+
static const mp_rom_map_elem_t mp_m5utils_timer_locals_dict_table[] = {
115+
/* *FORMAT-OFF* */
116+
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&mp_m5utils_timer_init_obj) },
117+
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mp_m5utils_timer_deinit_obj) },
118+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_m5utils_timer_deinit_obj) },
119+
{ MP_ROM_QSTR(MP_QSTR_ONE_SHOT), MP_ROM_INT(false) },
120+
{ MP_ROM_QSTR(MP_QSTR_PERIODIC), MP_ROM_INT(true) },
121+
/* *FORMAT-ON* */
122+
};
123+
124+
static MP_DEFINE_CONST_DICT(mp_m5utils_timer_locals_dict, mp_m5utils_timer_locals_dict_table);
125+
126+
#ifdef MP_OBJ_TYPE_GET_SLOT
127+
MP_DEFINE_CONST_OBJ_TYPE(
128+
mp_m5utils_timer_type,
129+
MP_QSTR_Timer,
130+
MP_TYPE_FLAG_NONE,
131+
make_new, mp_m5utils_timer_make_new,
132+
print, mp_m5utils_timer_print,
133+
locals_dict, &mp_m5utils_timer_locals_dict
134+
);
135+
#else
136+
const mp_obj_type_t mp_m5utils_timer_type = {
137+
.base = { &mp_type_type },
138+
.name = MP_QSTR_Timer,
139+
.make_new = mp_m5utils_timer_make_new,
140+
.print = mp_m5utils_timer_print,
141+
.locals_dict = &mp_m5utils_timer_locals_dict,
142+
};
143+
#endif

0 commit comments

Comments
 (0)