Skip to content

Commit 6a1eadc

Browse files
committed
fft: Enable build as extmod
1 parent 16d7cd0 commit 6a1eadc

4 files changed

Lines changed: 60 additions & 9 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ unix: $(UNIX_MICROPYTHON)
7979
check_unix: $(UNIX_MICROPYTHON)
8080
$(UNIX_MICROPYTHON) tests/test_trees.py
8181
$(UNIX_MICROPYTHON) tests/test_iir.py
82+
$(UNIX_MICROPYTHON) tests/test_fft.py
8283

8384
.PHONY: clean unix
8485

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11

2+
# When used as external C module, the .py is the top-level import,
3+
# and we need to merge the native module symbols at import time
4+
# When used as dynamic native modules (.mpy), .py and native code is merged at build time
5+
try:
6+
from emlearn_fft_c import *
7+
except ImportError as e:
8+
pass
9+
210
import math
311
import array
412
import gc
513

6-
714
def fill(fft, n):
815
# pre-compute the trigonometrics needed for FFT computation
916

src/emlearn_fft/fft.c

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// Include the header file to get access to the MicroPython API
2+
#ifdef MICROPY_ENABLE_DYNRUNTIME
23
#include "py/dynruntime.h"
4+
#else
5+
#include "py/runtime.h"
6+
#endif
37

48
#include <eml_common.h>
59

@@ -72,9 +76,12 @@ fft_forward(float *table_sin, float *table_cos, float real[], float imag[], size
7276
}
7377

7478

75-
7679
// MicroPython type for EmlFFT
77-
mp_obj_full_type_t mp_fft_type;
80+
#if MICROPY_ENABLE_DYNRUNTIME
81+
mp_obj_full_type_t fft_type;
82+
#else
83+
static const mp_obj_type_t fft_type;
84+
#endif
7885

7986
typedef struct _mp_obj_fft_t {
8087
mp_obj_base_t base;
@@ -228,6 +235,8 @@ static mp_obj_t fft_run(mp_obj_t self_obj, mp_obj_t real_obj, mp_obj_t imag_obj)
228235
static MP_DEFINE_CONST_FUN_OBJ_3(fft_run_obj, fft_run);
229236

230237

238+
239+
#ifdef MICROPY_ENABLE_DYNRUNTIME
231240
mp_map_elem_t mod_locals_dit_table[3];
232241
static MP_DEFINE_CONST_DICT(mod_locals_dit, mod_locals_dit_table);
233242

@@ -240,21 +249,54 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
240249
mp_printf(&mp_plat_print, "fft-mpy-init\n");
241250
#endif
242251

243-
mp_fft_type.base.type = (void*)&mp_type_type;
244-
mp_fft_type.flags = MP_TYPE_FLAG_NONE;
245-
mp_fft_type.name = MP_QSTR_FFT;
246-
MP_OBJ_TYPE_SET_SLOT(&mp_fft_type, make_new, fft_new, 0);
252+
fft_type.base.type = (void*)&mp_type_type;
253+
fft_type.flags = MP_TYPE_FLAG_NONE;
254+
fft_type.name = MP_QSTR_FFT;
255+
MP_OBJ_TYPE_SET_SLOT(&fft_type, make_new, fft_new, 0);
247256

248257
// methods
249258
mod_locals_dit_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_run), MP_OBJ_FROM_PTR(&fft_run_obj) };
250259
mod_locals_dit_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR___del__), MP_OBJ_FROM_PTR(&fft_del_obj) };
251260
mod_locals_dit_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&fft_fill_obj) };
252-
MP_OBJ_TYPE_SET_SLOT(&mp_fft_type, locals_dict, (void*)&mod_locals_dit, 3);
261+
MP_OBJ_TYPE_SET_SLOT(&fft_type, locals_dict, (void*)&mod_locals_dit, 3);
253262

254263
// Make the Factorial type available on the module.
255-
mp_store_global(MP_QSTR_FFT, MP_OBJ_FROM_PTR(&mp_fft_type));
264+
mp_store_global(MP_QSTR_FFT, MP_OBJ_FROM_PTR(&fft_type));
256265

257266
// This must be last, it restores the globals dict
258267
MP_DYNRUNTIME_INIT_EXIT
259268
}
269+
#else // extmod
270+
271+
// Define a class
272+
static const mp_rom_map_elem_t emlearn_fft_locals_dict_table[] = {
273+
{ MP_ROM_QSTR(MP_QSTR_run), MP_ROM_PTR(&fft_run_obj) },
274+
{ MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&fft_fill_obj) },
275+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&fft_del_obj) }
276+
};
277+
static MP_DEFINE_CONST_DICT(emlearn_fft_locals_dict, emlearn_fft_locals_dict_table);
278+
279+
280+
static MP_DEFINE_CONST_OBJ_TYPE(
281+
fft_type,
282+
MP_QSTR_emlfft,
283+
MP_TYPE_FLAG_NONE,
284+
make_new, fft_new,
285+
locals_dict, &emlearn_fft_locals_dict
286+
);
287+
288+
// Define module object.
289+
static const mp_rom_map_elem_t emlearn_fft_globals_table[] = {
290+
{ MP_ROM_QSTR(MP_QSTR_FFT), MP_ROM_PTR(&fft_type) }
291+
};
292+
static MP_DEFINE_CONST_DICT(emlearn_fft_globals, emlearn_fft_globals_table);
293+
294+
const mp_obj_module_t emlearn_fft_cmodule = {
295+
.base = { &mp_type_module },
296+
.globals = (mp_obj_dict_t *)&emlearn_fft_globals,
297+
};
298+
299+
MP_REGISTER_MODULE(MP_QSTR_emlearn_fft_c, emlearn_fft_cmodule);
300+
#endif
301+
260302

src/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
# NOTE: this is a different mechanism than
44
# Ref https://docs.micropython.org/en/latest/reference/manifest.html
55
module("emlearn_trees.py", base_path='./emlearn_trees')
6+
module("emlearn_fft.py", base_path='./emlearn_fft')

0 commit comments

Comments
 (0)