diff --git a/apps/code/executor_controller.cpp b/apps/code/executor_controller.cpp index 5f380cefb..1c91f67bc 100644 --- a/apps/code/executor_controller.cpp +++ b/apps/code/executor_controller.cpp @@ -3,6 +3,7 @@ extern "C" { #include #include "port.h" +#include "py/mphal.h" #include "py/compile.h" #include "py/runtime.h" #include "py/gc.h" @@ -17,7 +18,9 @@ mp_obj_t execute_from_str(const char *str) { mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false); mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_obj_t module_fun = mp_compile(&pt, lex->source_name, MP_EMIT_OPT_NONE, false); + mp_hal_set_interrupt_char((int)Ion::Keyboard::Key::A6); mp_call_function_0(module_fun); + mp_hal_set_interrupt_char(-1); // disable interrupt nlr_pop(); return 0; } else { diff --git a/python/Makefile b/python/Makefile index a4ba636ae..913ccc520 100644 --- a/python/Makefile +++ b/python/Makefile @@ -174,8 +174,10 @@ python/src/py/emitnative.o: CFLAGS += -DN_THUMB port_objs += $(addprefix python/port/,\ port.o \ + interrupt_helper.o \ modkandinsky.o \ modkandinsky_impl.o \ + mphalport.o \ ) # QSTR generation diff --git a/python/port/genhdr/qstrdefs.in.h b/python/port/genhdr/qstrdefs.in.h index 588a165d8..d241dacdd 100644 --- a/python/port/genhdr/qstrdefs.in.h +++ b/python/port/genhdr/qstrdefs.in.h @@ -165,6 +165,7 @@ Q(iter) Q(iterator) Q(join) Q(kandinsky) +Q(kbd_intr) Q(key) Q(keys) Q(len) @@ -197,6 +198,7 @@ Q(rindex) Q(round) Q(rsplit) Q(rstrip) +Q(schedule) Q(send) Q(sep) Q(set_pixel) diff --git a/python/port/interrupt_helper.cpp b/python/port/interrupt_helper.cpp new file mode 100644 index 000000000..546891889 --- /dev/null +++ b/python/port/interrupt_helper.cpp @@ -0,0 +1,19 @@ +#include "interrupt_helper.h" +#include +extern "C" { +#include "mphalport.h" +} + +void shouldInterrupt() { + static int c = 0; + c++; + if (c%20000 != 0) { + return; + } + c = 0; + Ion::Keyboard::State scan = Ion::Keyboard::scan(); + if (scan.keyDown((Ion::Keyboard::Key)mp_interrupt_char)) { + mp_keyboard_interrupt(); + } +} + diff --git a/python/port/interrupt_helper.h b/python/port/interrupt_helper.h new file mode 100644 index 000000000..4eb35bdde --- /dev/null +++ b/python/port/interrupt_helper.h @@ -0,0 +1,17 @@ +#ifndef PYTHON_INTERRUPT_HELPER_H +#define PYTHON_INTERRUPT_HELPER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* shouldInterrupt effectively does something once every 20000 calls. It checks + * if a key is down to raise an interruption flag. */ + +void shouldInterrupt(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/python/port/mpconfigport.h b/python/port/mpconfigport.h index d3f0142d5..e48575db1 100644 --- a/python/port/mpconfigport.h +++ b/python/port/mpconfigport.h @@ -103,3 +103,5 @@ extern const struct _mp_obj_module_t kandinsky_module; #define MICROPY_PORT_BUILTIN_MODULES \ { MP_ROM_QSTR(MP_QSTR_kandinsky), MP_ROM_PTR(&kandinsky_module) } + +#define MICROPY_KBD_EXCEPTION (1) diff --git a/python/port/mphalport.c b/python/port/mphalport.c new file mode 100644 index 000000000..736e658d0 --- /dev/null +++ b/python/port/mphalport.c @@ -0,0 +1,19 @@ +#include "py/mpstate.h" +#include "py/mphal.h" + +#if MICROPY_KBD_EXCEPTION + +int mp_interrupt_char; + +void mp_hal_set_interrupt_char(int c) { + if (c != -1) { + mp_obj_exception_clear_traceback(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))); + } + mp_interrupt_char = c; +} + +void mp_keyboard_interrupt(void) { + MP_STATE_VM(mp_pending_exception) = MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)); +} + +#endif diff --git a/python/port/mphalport.h b/python/port/mphalport.h index 60d68bd2d..c549bfd7a 100644 --- a/python/port/mphalport.h +++ b/python/port/mphalport.h @@ -1,2 +1,8 @@ -static inline mp_uint_t mp_hal_ticks_ms(void) { return 0; } -static inline void mp_hal_set_interrupt_char(char c) {} +#ifndef PYTHON_MPHALPORT_H +#define PYTHON_MPHALPORT_H + +extern int mp_interrupt_char; +void mp_hal_set_interrupt_char(int c); +void mp_keyboard_interrupt(void); + +#endif diff --git a/python/src/py/vm.c b/python/src/py/vm.c index bb120e775..904aa3c85 100644 --- a/python/src/py/vm.c +++ b/python/src/py/vm.c @@ -29,6 +29,11 @@ #include #include +/* TODO: We should rather not edit micropython file. + * Begining of the edited part */ +#include "../../port/interrupt_helper.h" +/* End of the edited part */ + #include "py/mpstate.h" #include "py/nlr.h" #include "py/emitglue.h" @@ -1278,6 +1283,12 @@ yield: pending_exception_check: MICROPY_VM_HOOK_LOOP +/* TODO: We should rather not edit micropython file. Find a way to call + * shouldInterrupt every now and then in the loop executing byte code without + * editing this file. + * Begining of the edited part */ + shouldInterrupt(); +/* End of the edited part */ #if MICROPY_ENABLE_SCHEDULER // This is an inlined variant of mp_handle_pending