diff --git a/meson.build b/meson.build index 8d951c6fafa2a101220452316fb5109bdd0ec00e..20b7040b216e7d4294c9a911230e71bd3b96e257 100644 --- a/meson.build +++ b/meson.build @@ -34,4 +34,6 @@ subdir('lib/') subdir('bootloader/') subdir('epicardium/') +subdir('pycardium/') + subdir('hw-tests/') diff --git a/pycardium/main.c b/pycardium/main.c new file mode 100644 index 0000000000000000000000000000000000000000..5c6b38a764f146ae4aa7f2e375478ef2677ad6dc --- /dev/null +++ b/pycardium/main.c @@ -0,0 +1,32 @@ +#include "py/runtime.h" +#include "py/gc.h" +#include "lib/utils/pyexec.h" + +static char *stack_top; +static char heap[4096]; + +int main(void) +{ + /* TODO: Replace this with a proper heap implementation */ + int stack_dummy; + stack_top = (char*)&stack_dummy; + + gc_init(heap, heap + sizeof(heap)); + + mp_init(); + pyexec_friendly_repl(); + + while (1) { + ; + } +} + +void gc_collect(void) +{ + /* TODO: Replace this with a proper heap implementation */ + void*dummy; + + gc_collect_start(); + gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t)); + gc_collect_end(); +} diff --git a/pycardium/meson.build b/pycardium/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..7bb11316fe865e7bbf1dae740eddb15dd950ffcd --- /dev/null +++ b/pycardium/meson.build @@ -0,0 +1,62 @@ +name = 'pycardium' + +modsrc = files( +) + +################################# +# MicroPython Generated Headers # +################################# + +version_h = custom_target( + 'mpversion.h', + output: 'mpversion.h', + command: [micropython_gen_version, '@OUTPUT@'], +) + +modules_h = custom_target( + 'moduledefs.h', + output: 'moduledefs.h', + input: [micropython_sources, modsrc], + command: [micropython_gen_modules, '@OUTPUT@', '@INPUT@'], +) + +qstr_h = custom_target( + 'qstrdefs.generated.h', + output: 'qstrdefs.generated.h', + input: [ + # 'modules/qstrdefs.h', + 'mpconfigport.h', + micropython_sources, + ], + depends: [modules_h, version_h], + command: [micropython_gen_qstr, meson.current_source_dir(), '@OUTPUT@', '@INPUT@'], +) + +mp_headers = [version_h, modules_h, qstr_h] + +################### +# MicroPython Lib # +################### + +upy = static_library( + 'micropython', + micropython_sources, + micropython_additional_sources, + mp_headers, + include_directories: micropython_includes, +) + +executable( + name + '.elf', + 'main.c', + 'mphalport.c', + modsrc, + mp_headers, + include_directories: micropython_includes, + dependencies: [max32665_startup_core1, board_card10, periphdriver], + link_whole: [max32665_startup_core1_lib, board_card10_lib], + link_with: upy, + link_args: [ + '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map', + ], +) diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h new file mode 100644 index 0000000000000000000000000000000000000000..3418da7188333e186894902dd597fa76c69fd84f --- /dev/null +++ b/pycardium/mpconfigport.h @@ -0,0 +1,48 @@ +/* Hardware Name */ +#define MICROPY_HW_BOARD_NAME "card10" +#define MICROPY_HW_MCU_NAME "max32665" + +/* MicroPython Config Options */ + +/* + * Right now, we do not support importing external modules + * though this might change in the future. + */ +#define MICROPY_ENABLE_EXTERNAL_IMPORT (0) + +#define MICROPY_ENABLE_DOC_STRING (1) +#define MICROPY_ENABLE_GC (1) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG) +#define MICROPY_PY_BUILTINS_HELP (1) +#define MICROPY_PY_BUILTINS_HELP_MODULES (1) + +/* + * This port is intended to be 32-bit, but unfortunately, int32_t for + * different targets may be defined in different ways - either as int + * or as long. This requires different printf formatting specifiers + * to print such value. So, we avoid int32_t and use int directly. + */ +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; /* must be pointer size */ +typedef unsigned mp_uint_t; /* must be pointer size */ + +typedef long mp_off_t; + +/* + * Make a pointer to RAM callable (eg set lower bit for Thumb code) + * (This scheme won't work if we want to mix Thumb and normal ARM code.) + */ +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1)) + +/* We need to provide a declaration/definition of alloca() */ +#include <alloca.h> + +/* TODO: Document this */ +#define MP_STATE_PORT MP_STATE_VM + +/* For some reason, we need to define readline history manually */ +#define MICROPY_PORT_ROOT_POINTERS \ + const char *readline_hist[16]; diff --git a/pycardium/mphalport.c b/pycardium/mphalport.c new file mode 100644 index 0000000000000000000000000000000000000000..5f69a7d2f656d01b5147a2a78745e99560fd6ef7 --- /dev/null +++ b/pycardium/mphalport.c @@ -0,0 +1,74 @@ +#include <stdint.h> + +#include "py/lexer.h" +#include "py/mpconfig.h" +#include "py/mperrno.h" +#include "py/obj.h" +#include "py/runtime.h" + +/****************************************************************************** + * Serial Communication + */ + +/* TODO: Use API boundary instead of direct communication */ +#include "uart.h" +extern mxc_uart_regs_t * ConsoleUart; + +/* Receive single character */ +int mp_hal_stdin_rx_chr(void) +{ + return UART_ReadByte(ConsoleUart); +} + +/* Send string of given length */ +void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) +{ + UART_Write(ConsoleUart, (uint8_t*)str, len); +} + +/****************************************************************************** + * Fatal Errors + */ + +void NORETURN nlr_jump_fail(void *val) +{ + /* TODO: Report error and restart */ + while (1) { + } +} + +/****************************************************************************** + * Stubs + */ + +mp_lexer_t *mp_lexer_new_from_file(const char *filename) +{ + /* TODO: Do we need an implementation for this? */ + mp_raise_OSError(MP_ENOENT); +} + +mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) +{ + /* TODO: Once fs is implemented, get this working as well */ + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); + +/****************************************************************************** + * TODO: Remove + */ + +int _getpid(void) +{ + ; +} + +int _kill(int pid, int f) +{ + ; +} + +void _exit(int r) +{ + ; +} diff --git a/pycardium/mphalport.h b/pycardium/mphalport.h new file mode 100644 index 0000000000000000000000000000000000000000..cf772d7f1a1a219e786ea0fbe0b4372088da0e67 --- /dev/null +++ b/pycardium/mphalport.h @@ -0,0 +1,7 @@ +#include "py/mpconfig.h" + +/* TODO: Replace this with a proper implementation */ +static inline mp_uint_t mp_hal_ticks_ms(void) { return 0; } + +/* TODO: Replace this with a proper implementation */ +static inline void mp_hal_set_interrupt_char(char c) {}