Skip to content
Snippets Groups Projects
Commit 10fb934d authored by pippin's avatar pippin
Browse files

st3m,mpy: show last bits of python errors on display

This is implemented with a tiny terminal emulator which the stdout of
micropython is passed through. This allows us to detect what state the
interepreter connection of micropython might be in, and show a REPL splash or
text accordingly.
parent b63a92b5
No related branches found
No related tags found
No related merge requests found
...@@ -119,7 +119,7 @@ soft_reset: ...@@ -119,7 +119,7 @@ soft_reset:
// run boot-up scripts // run boot-up scripts
pyexec_frozen_module("_boot.py"); pyexec_frozen_module("_boot.py");
pyexec_file_if_exists("boot.py"); int ret = pyexec_file_if_exists("boot.py");
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
int ret = pyexec_file_if_exists("/flash/sys/main.py"); int ret = pyexec_file_if_exists("/flash/sys/main.py");
if (ret & PYEXEC_FORCED_EXIT) { if (ret & PYEXEC_FORCED_EXIT) {
...@@ -127,7 +127,15 @@ soft_reset: ...@@ -127,7 +127,15 @@ soft_reset:
} }
} }
if (ret == 1)
{
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL)
st3m_mode_set(st3m_mode_kind_mpremote, NULL);
else
st3m_mode_set(st3m_mode_kind_repl, NULL); st3m_mode_set(st3m_mode_kind_repl, NULL);
}
else
st3m_mode_set(st3m_mode_kind_exception, NULL);
for (;;) { for (;;) {
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_timer.h" #include "esp_timer.h"
#include "st3m_term.h"
#include "py/obj.h" #include "py/obj.h"
#include "py/objstr.h" #include "py/objstr.h"
...@@ -122,12 +123,14 @@ int mp_hal_stdin_rx_chr(void) { ...@@ -122,12 +123,14 @@ int mp_hal_stdin_rx_chr(void) {
} }
} }
void mp_hal_stdout_tx_strn(const char *str, size_t len) { void mp_hal_stdout_tx_strn(const char *str, size_t len) {
// Only release the GIL if many characters are being sent // Only release the GIL if many characters are being sent
bool release_gil = len > 20; bool release_gil = len > 20;
if (release_gil) { if (release_gil) {
MP_THREAD_GIL_EXIT(); MP_THREAD_GIL_EXIT();
} }
st3m_term_feed(str, len);
fwrite(str, len, 1, stdout); fwrite(str, len, 1, stdout);
if (release_gil) { if (release_gil) {
MP_THREAD_GIL_ENTER(); MP_THREAD_GIL_ENTER();
......
...@@ -17,6 +17,7 @@ idf_component_register( ...@@ -17,6 +17,7 @@ idf_component_register(
st3m_captouch.c st3m_captouch.c
st3m_ringbuffer.c st3m_ringbuffer.c
st3m_tar.c st3m_tar.c
st3m_term.c
st3m_fs.c st3m_fs.c
st3m_fs_flash.c st3m_fs_flash.c
st3m_fs_sd.c st3m_fs_sd.c
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "st3m_gfx.h" #include "st3m_gfx.h"
#include "st3m_io.h" #include "st3m_io.h"
#include "st3m_term.h"
static st3m_mode_t _mode = { static st3m_mode_t _mode = {
.kind = st3m_mode_kind_starting, .kind = st3m_mode_kind_starting,
...@@ -62,17 +63,27 @@ void st3m_mode_update_display(bool *restartable) { ...@@ -62,17 +63,27 @@ void st3m_mode_update_display(bool *restartable) {
case st3m_mode_kind_disk: case st3m_mode_kind_disk:
st3m_gfx_splash("Disk Mode"); st3m_gfx_splash("Disk Mode");
break; break;
case st3m_mode_kind_exception:
if (!_mode.shown) {
_mode.shown = true;
st3m_term_draw(6);
}
if (restartable != NULL) *restartable = true;
break;
case st3m_mode_kind_repl: case st3m_mode_kind_repl:
case st3m_mode_kind_mpremote:
if (!_mode.shown) { if (!_mode.shown) {
_mode.shown = true; _mode.shown = true;
const char *lines[] = { const char *lines[] = {
"Send Ctrl-D over USB", "Send Ctrl-D over USB or",
"or press left shoulder button", "press left shoulder button",
"to restart.", "to restart.",
NULL, NULL,
}; };
st3m_gfx_textview_t tv = { st3m_gfx_textview_t tv = {
.title = "In REPL", .title = _mode.kind == st3m_mode_kind_repl
? "In REPL"
: "mpremote active",
.lines = lines, .lines = lines,
}; };
st3m_gfx_show_textview(&tv); st3m_gfx_show_textview(&tv);
......
...@@ -9,6 +9,8 @@ typedef enum { ...@@ -9,6 +9,8 @@ typedef enum {
st3m_mode_kind_repl = 3, st3m_mode_kind_repl = 3,
st3m_mode_kind_disk = 4, st3m_mode_kind_disk = 4,
st3m_mode_kind_fatal = 5, st3m_mode_kind_fatal = 5,
st3m_mode_kind_exception = 6,
st3m_mode_kind_mpremote = 7,
} st3m_mode_kind_t; } st3m_mode_kind_t;
typedef struct { typedef struct {
......
#include "st3m_term.h"
#include "st3m_gfx.h"
/* a tiny dumb terminal */
#define ST3M_TERM_COLS 27
#define ST3M_TERM_LINES 16
static char st3m_term[ST3M_TERM_LINES][ST3M_TERM_COLS];
static int st3m_term_cx = 0;
static int st3m_term_cy = 0;
void st3m_term_feed(const char *str, size_t len) {
for (int i = 0; i < len; i++) {
char c = str[i];
switch (c) {
case '\t': {
char *space_buf = " ";
do {
st3m_term_feed(space_buf, 1);
} while ((st3m_term_cx & 7) != 0);
} break;
case '\b':
st3m_term_cx--;
if (st3m_term_cx < 0) st3m_term_cx = 0;
break;
case '\r':
st3m_term_cx = 0;
break;
case '\n':
st3m_term_cx = 0;
st3m_term_cy++;
if (st3m_term_cy >= ST3M_TERM_LINES) st3m_term_cy = 0;
memset(st3m_term[st3m_term_cy], 0, ST3M_TERM_COLS);
break;
default:
st3m_term[st3m_term_cy][st3m_term_cx] = c;
st3m_term_cx++;
if (st3m_term_cx >= ST3M_TERM_COLS) {
st3m_term_cx = 0;
st3m_term_cy++;
if (st3m_term_cy >= ST3M_TERM_LINES) st3m_term_cy = 0;
memset(st3m_term[st3m_term_cy], 0, ST3M_TERM_COLS);
}
}
}
}
// returns a line from terminal scrollback
// line_no is a value 0..15
const char *st3m_term_get_line(int line_no) {
return st3m_term[(st3m_term_cy - line_no - 1) & 15];
}
// draws the last bit of terminal output, avoiding the last skip_lines
// lines added.
void st3m_term_draw(int skip_lines) {
st3m_ctx_desc_t *target = st3m_gfx_drawctx_free_get(portMAX_DELAY);
Ctx *ctx = target->ctx;
float font_size = 20.0;
float y = 64;
ctx_save(ctx);
ctx_font_size(ctx, font_size);
ctx_text_align(ctx, CTX_TEXT_ALIGN_LEFT); // XXX this should not be needed
ctx_gray(ctx, 0.0);
ctx_rectangle(ctx, -120, -120, 240, 240);
ctx_fill(ctx);
ctx_gray(ctx, 1.0);
for (int i = 0; i < 7 && y > -70; i++) {
ctx_move_to(ctx, -100, y);
ctx_text(ctx, st3m_term_get_line(i + skip_lines));
y -= font_size;
}
ctx_restore(ctx);
st3m_gfx_drawctx_pipe_put(target);
}
#pragma once
#include "esp_err.h"
#include <stdint.h>
void st3m_imu_init(void);
void st3m_term_feed(const char *str, size_t len);
const char *st3m_term_get_line(int line_no);
void st3m_term_draw(int skip_lines);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment