summaryrefslogtreecommitdiff
path: root/lib/utils
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2016-12-09 19:27:41 -0800
committerScott Shawcroft <scott.shawcroft@gmail.com>2016-12-09 19:35:56 -0800
commitb6f1eebab30b0e687e07cc3e42d9db9fd48aab05 (patch)
tree0cbd3edb2a81de4df6d33a5775d9f9cb99b48e91 /lib/utils
parent6225b89c764f8e9e44fc03f9544e9d2162bb0659 (diff)
atmel-samd: Add APA102 support and flash more advanced status.
The new sequence is as follows: * Solid blue during the boot/settings script. * Solid green during the main/code script. * After main while waiting to enter repl or reset: * Fading green once main is done successfully. * On error produce a series of flashes: * Long flash color of script. * Long flash color of error: * Green = IndentationError * Cyan = SyntaxError * White = NameError * Orange = OSError * Yellow = Other error * Line number of the exception by digit. Number of flashes represents value. * Thousands = White * Hundreds = Blue * Tens = Yellow * Ones = Cyan * Off for a period and then repeats. At any point a write to the flash storage will flicker red. Fixes #63
Diffstat (limited to 'lib/utils')
-rw-r--r--lib/utils/pyexec.c38
-rw-r--r--lib/utils/pyexec.h9
2 files changed, 34 insertions, 13 deletions
diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c
index 7737d137f..63797158f 100644
--- a/lib/utils/pyexec.c
+++ b/lib/utils/pyexec.c
@@ -58,7 +58,7 @@ STATIC bool repl_display_debugging_info = 0;
// EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
// EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code
// EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile)
-STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
+STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind, int exec_flags, pyexec_result_t *result) {
int ret = 0;
uint32_t start = 0;
@@ -88,7 +88,7 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind,
mp_call_function_0(module_fun);
mp_hal_set_interrupt_char(-1); // disable interrupt
nlr_pop();
- ret = 1;
+ ret = 0;
if (exec_flags & EXEC_FLAG_PRINT_EOF) {
mp_hal_stdout_tx_strn("\x04", 1);
}
@@ -108,7 +108,21 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind,
ret = PYEXEC_FORCED_EXIT;
} else {
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
- ret = 0;
+ ret = PYEXEC_EXCEPTION;
+ }
+ }
+ if (result != NULL) {
+ result->return_code = ret;
+ if (ret != 0) {
+ mp_obj_t return_value = (mp_obj_t)nlr.ret_val;
+ result->exception_type = mp_obj_get_type(return_value);
+ result->exception_line = -1;
+
+ if (mp_obj_is_exception_instance(return_value)) {
+ size_t n, *values;
+ mp_obj_exception_get_traceback(return_value, &n, &values);
+ result->exception_line = values[n - 2];
+ }
}
}
@@ -203,7 +217,7 @@ STATIC int pyexec_raw_repl_process_char(int c) {
if (lex == NULL) {
mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04");
} else {
- int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
+ int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF, NULL);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
@@ -285,7 +299,7 @@ exec: ;
if (lex == NULL) {
printf("MemoryError\n");
} else {
- int ret = parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
+ int ret = parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL, NULL);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
@@ -361,7 +375,7 @@ raw_repl_reset:
if (lex == NULL) {
printf("\x04MemoryError\n\x04");
} else {
- int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
+ int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF, NULL);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
@@ -380,7 +394,7 @@ int pyexec_friendly_repl(void) {
#endif
friendly_repl_reset:
- mp_hal_stdout_tx_str("Adafruit MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n");
+ mp_hal_stdout_tx_str("\r\nAdafruit MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n");
// mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n");
// to test ctrl-C
@@ -487,7 +501,7 @@ friendly_repl_reset:
if (lex == NULL) {
printf("MemoryError\n");
} else {
- ret = parse_compile_execute(lex, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
+ ret = parse_compile_execute(lex, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL, NULL);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
@@ -497,7 +511,7 @@ friendly_repl_reset:
#endif // MICROPY_REPL_EVENT_DRIVEN
-int pyexec_file(const char *filename) {
+int pyexec_file(const char *filename, pyexec_result_t *exec_result) {
mp_lexer_t *lex = mp_lexer_new_from_file(filename);
if (lex == NULL) {
@@ -505,7 +519,7 @@ int pyexec_file(const char *filename) {
return false;
}
- return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0);
+ return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0, exec_result);
}
#if MICROPY_MODULE_FROZEN
@@ -516,12 +530,12 @@ int pyexec_frozen_module(const char *name) {
switch (frozen_type) {
#if MICROPY_MODULE_FROZEN_STR
case MP_FROZEN_STR:
- return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0);
+ return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0, NULL);
#endif
#if MICROPY_MODULE_FROZEN_MPY
case MP_FROZEN_MPY:
- return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE);
+ return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE, NULL);
#endif
default:
diff --git a/lib/utils/pyexec.h b/lib/utils/pyexec.h
index 0c7567e27..276e9a45a 100644
--- a/lib/utils/pyexec.h
+++ b/lib/utils/pyexec.h
@@ -31,6 +31,12 @@ typedef enum {
PYEXEC_MODE_FRIENDLY_REPL,
} pyexec_mode_kind_t;
+typedef struct {
+ int return_code;
+ const mp_obj_type_t * exception_type;
+ int exception_line;
+} pyexec_result_t;
+
extern pyexec_mode_kind_t pyexec_mode_kind;
// Set this to the value (eg PYEXEC_FORCED_EXIT) that will be propagated through
@@ -40,10 +46,11 @@ extern int pyexec_system_exit;
#define PYEXEC_FORCED_EXIT (0x100)
#define PYEXEC_SWITCH_MODE (0x200)
+#define PYEXEC_EXCEPTION (0x400)
int pyexec_raw_repl(void);
int pyexec_friendly_repl(void);
-int pyexec_file(const char *filename);
+int pyexec_file(const char *filename, pyexec_result_t *result);
int pyexec_frozen_module(const char *name);
void pyexec_event_repl_init(void);
int pyexec_event_repl_process_char(int c);