diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index decd4816a3..5176ecc9b7 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -863,6 +863,10 @@ msgstr "" msgid "Display rotation must be in 90 degree increments" msgstr "" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "" diff --git a/main.c b/main.c index 800843e419..35a78c551f 100644 --- a/main.c +++ b/main.c @@ -204,30 +204,20 @@ STATIC void stop_mp(void) { gc_deinit(); } -STATIC const char *_last_executing_filename = NULL; STATIC const char *_current_executing_filename = NULL; STATIC pyexec_result_t _exec_result = {0, MP_OBJ_NULL, 0}; -STATIC int _last_return_code = 0; -STATIC int _last_exception_line = 0; - -bool supervisor_execution_status_dirty(void) { - return _last_executing_filename != _current_executing_filename || - _last_return_code != _exec_result.return_code || - _last_exception_line != _exec_result.exception_line; -} void supervisor_execution_status(void) { mp_obj_exception_t *exception = MP_OBJ_TO_PTR(_exec_result.exception); - if ((_exec_result.return_code & PYEXEC_EXCEPTION) != 0 && - exception != NULL) { - mp_printf(&mp_plat_print, "@%d %q", _exec_result.exception_line, exception->base.type->name); - } else if (_current_executing_filename != NULL) { + if (_current_executing_filename != NULL) { serial_write(_current_executing_filename); + } else if ((_exec_result.return_code & PYEXEC_EXCEPTION) != 0 && + exception != NULL) { + mp_printf(&mp_plat_print, "@%d %q", _exec_result.exception_line, exception->base.type->name); + } else { + serial_write_compressed(translate("Done")); } - _last_executing_filename = _current_executing_filename; - _last_return_code = _exec_result.return_code; - _last_exception_line = _exec_result.exception_line; } #define STRING_LIST(...) {__VA_ARGS__, ""} @@ -254,13 +244,13 @@ STATIC bool maybe_run_list(const char *const *filenames) { } mp_hal_stdout_tx_str(_current_executing_filename); serial_write_compressed(translate(" output:\n")); - supervisor_title_bar_request_update(false); + supervisor_title_bar_update(); pyexec_file(_current_executing_filename, &_exec_result); #if CIRCUITPY_ATEXIT shared_module_atexit_execute(&_exec_result); #endif - _current_executing_filename = "Done"; - supervisor_title_bar_request_update(false); + _current_executing_filename = NULL; + supervisor_title_bar_update(); return true; } @@ -851,7 +841,11 @@ STATIC int run_repl(bool first_run) { exit_code = pyexec_raw_repl(); supervisor_title_bar_resume(); } else { + _current_executing_filename = "REPL"; + supervisor_title_bar_update(); exit_code = pyexec_friendly_repl(); + _current_executing_filename = NULL; + supervisor_title_bar_update(); } #if CIRCUITPY_ATEXIT pyexec_result_t result; diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 4d7d026aa5..6b6f629e18 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -369,7 +369,7 @@ CFLAGS += -DCIRCUITPY_SSL=$(CIRCUITPY_SSL) CIRCUITPY_STAGE ?= 0 CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE) -CIRCUITPY_STATUS_BAR ?= $(CIRCUITPY_WEB_WORKFLOW) +CIRCUITPY_STATUS_BAR ?= 1 CFLAGS += -DCIRCUITPY_STATUS_BAR=$(CIRCUITPY_STATUS_BAR) CIRCUITPY_STORAGE ?= 1 diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 849b9c3fe2..fdd0a0341a 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -34,6 +34,7 @@ #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/TileGrid.h" #include "supervisor/memory.h" +#include "supervisor/shared/title_bar.h" #if CIRCUITPY_RGBMATRIX #include "shared-module/displayio/__init__.h" @@ -65,7 +66,7 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid; bool reset_tiles = false; uint16_t width_in_tiles = width_px / scroll_area->tile_width; - // determine scale based on h + // determine scale based on width if (width_in_tiles < 80) { scale = 1; } @@ -103,9 +104,9 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { uint8_t *tiles = (uint8_t *)tilegrid_tiles->ptr; #if CIRCUITPY_REPL_LOGO - title_bar->x = blinka_bitmap.width; + title_bar->x = supervisor_blinka_sprite.pixel_width + 1; // Align the title bar to the bottom of the logo. - title_bar->y = blinka_bitmap.height - title_bar->tile_height; + title_bar->y = supervisor_blinka_sprite.pixel_height - title_bar->tile_height; #else title_bar->x = 0; title_bar->y = 0; @@ -120,11 +121,6 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { title_bar->full_change = true; scroll_area->x = 0; - #if CIRCUITPY_REPL_LOGO - scroll_area->y = blinka_bitmap.height; - #else - scroll_area->y = scroll_area->tile_height; - #endif scroll_area->top_left_y = 0; scroll_area->width_in_tiles = width_in_tiles; scroll_area->height_in_tiles = height_in_tiles - 1; @@ -132,10 +128,21 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { assert(height_in_tiles > 1); scroll_area->pixel_width = width_in_tiles * scroll_area->tile_width; scroll_area->pixel_height = (height_in_tiles - 1) * scroll_area->tile_height; + #if CIRCUITPY_REPL_LOGO + scroll_area->y = blinka_bitmap.height; + #else + scroll_area->y = title_bar->tile_height; + #endif + int16_t extra_height = (scroll_area->pixel_height + scroll_area->y) - height_px; + // Subtract extra height so that the bottom line fully shows. The top line will be under the + // title bar and Blinka logo. + scroll_area->y -= extra_height; scroll_area->tiles = tiles + width_in_tiles; scroll_area->full_change = true; common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, title_bar); + // Update the title bar since we just cleared the terminal. + supervisor_title_bar_update(); } #endif @@ -186,126 +193,9 @@ void supervisor_display_move_memory(void) { #endif } -#if CIRCUITPY_REPL_LOGO -uint32_t blinka_bitmap_data[32] = { - 0x00000011, 0x11000000, - 0x00000111, 0x53100000, - 0x00000111, 0x56110000, - 0x00000111, 0x11140000, - 0x00000111, 0x20002000, - 0x00000011, 0x13000000, - 0x00000001, 0x11200000, - 0x00000000, 0x11330000, - 0x00000000, 0x01122000, - 0x00001111, 0x44133000, - 0x00032323, 0x24112200, - 0x00111114, 0x44113300, - 0x00323232, 0x34112200, - 0x11111144, 0x44443300, - 0x11111111, 0x11144401, - 0x23232323, 0x21111110 -}; - -displayio_bitmap_t blinka_bitmap = { - .base = {.type = &displayio_bitmap_type }, - .width = 16, - .height = 16, - .data = blinka_bitmap_data, - .stride = 2, - .bits_per_value = 4, - .x_shift = 3, - .x_mask = 0x7, - .bitmask = 0xf, - .read_only = true -}; - -_displayio_color_t blinka_colors[7] = { - { - .rgb888 = 0x000000, - .rgb565 = 0x0000, - .luma = 0x00, - .chroma = 0, - .transparent = true - }, - { - .rgb888 = 0x8428bc, - .rgb565 = 0x8978, - .luma = 0xff, // We cheat the luma here. It is actually 0x60 - .hue = 184, - .chroma = 148 - }, - { - .rgb888 = 0xff89bc, - .rgb565 = 0xFCB8, - .luma = 0xb5, - .hue = 222, - .chroma = 118 - }, - { - .rgb888 = 0x7beffe, - .rgb565 = 0x869F, - .luma = 0xe0, - .hue = 124, - .chroma = 131 - }, - { - .rgb888 = 0x51395f, - .rgb565 = 0x5A0D, - .luma = 0x47, - .hue = 185, - .chroma = 38 - }, - { - .rgb888 = 0xffffff, - .rgb565 = 0xffff, - .luma = 0xff, - .chroma = 0 - }, - { - .rgb888 = 0x0736a0, - .rgb565 = 0x01f5, - .luma = 0x44, - .hue = 147, - .chroma = 153 - }, -}; - -displayio_palette_t blinka_palette = { - .base = {.type = &displayio_palette_type }, - .colors = blinka_colors, - .color_count = 7, - .needs_refresh = false -}; - -displayio_tilegrid_t blinka_sprite = { - .base = {.type = &displayio_tilegrid_type }, - .bitmap = &blinka_bitmap, - .pixel_shader = &blinka_palette, - .x = 0, - .y = 0, - .pixel_width = 16, - .pixel_height = 16, - .bitmap_width_in_tiles = 1, - .width_in_tiles = 1, - .height_in_tiles = 1, - .tile_width = 16, - .tile_height = 16, - .top_left_x = 16, - .top_left_y = 16, - .tiles = 0, - .partial_change = false, - .full_change = false, - .hidden = false, - .hidden_by_parent = false, - .moved = false, - .inline_tiles = true, - .in_group = true -}; -#endif - #if CIRCUITPY_TERMINALIO #if CIRCUITPY_REPL_LOGO -mp_obj_t members[] = { &blinka_sprite, &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, }; +mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_blinka_sprite, &supervisor_terminal_title_bar_text_grid, }; mp_obj_list_t splash_children = { .base = {.type = &mp_type_list }, .alloc = 3, @@ -313,7 +203,7 @@ mp_obj_list_t splash_children = { .items = members, }; #else -mp_obj_t members[] = { &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, }; +mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_terminal_title_bar_text_grid,}; mp_obj_list_t splash_children = { .base = {.type = &mp_type_list }, .alloc = 2, @@ -323,7 +213,7 @@ mp_obj_list_t splash_children = { #endif #else #if CIRCUITPY_REPL_LOGO -mp_obj_t members[] = { &blinka_sprite }; +mp_obj_t members[] = { &supervisor_blinka_sprite }; mp_obj_list_t splash_children = { .base = {.type = &mp_type_list }, .alloc = 1, diff --git a/supervisor/shared/display.h b/supervisor/shared/display.h index d965fdc764..7979bc30ab 100644 --- a/supervisor/shared/display.h +++ b/supervisor/shared/display.h @@ -42,6 +42,7 @@ extern const fontio_builtinfont_t supervisor_terminal_font; // These will change so they must live in RAM. +extern displayio_tilegrid_t supervisor_blinka_sprite; extern displayio_bitmap_t supervisor_terminal_font_bitmap; extern displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid; extern displayio_tilegrid_t supervisor_terminal_title_bar_text_grid; diff --git a/supervisor/shared/title_bar.c b/supervisor/shared/title_bar.c index 395b11105e..6a2462a399 100644 --- a/supervisor/shared/title_bar.c +++ b/supervisor/shared/title_bar.c @@ -39,6 +39,29 @@ static background_callback_t title_bar_background_cb; static bool _forced_dirty = false; static bool _suspended = false; + +void supervisor_title_bar_update(void) { + #if !CIRCUITPY_STATUS_BAR + return; + #endif + _forced_dirty = false; + // Neighboring "" "" are concatenated by the compiler. Without this separation, the hex code + // doesn't get terminated after two following characters and the value is invalid. + // This is the OSC command to set the title and the icon text. It can be up to 255 characters + // but some may be cut off. + serial_write("\x1b" "]0;"); + serial_write("🐍"); + #if CIRCUITPY_WEB_WORKFLOW + supervisor_web_workflow_status(); + serial_write(" | "); + #endif + supervisor_execution_status(); + serial_write(" | "); + serial_write(MICROPY_GIT_TAG); + // Send string terminator + serial_write("\x1b" "\\"); +} + static void title_bar_background(void *data) { #if !CIRCUITPY_STATUS_BAR return; @@ -52,27 +75,10 @@ static void title_bar_background(void *data) { dirty = dirty || supervisor_web_workflow_status_dirty(); #endif - dirty = dirty || supervisor_execution_status_dirty(); - if (!dirty) { return; } - _forced_dirty = false; - // Neighboring "" "" are concatenated by the compiler. Without this separation, the hex code - // doesn't get terminated after two following characters and the value is invalid. - // This is the OSC command to set the title and the icon text. It can be up to 255 characters - // but some may be cut off. - serial_write("\x1b" "]0;"); - serial_write("🐍 "); - #if CIRCUITPY_WEB_WORKFLOW - supervisor_web_workflow_status(); - serial_write(" | "); - #endif - supervisor_execution_status(); - serial_write(" | "); - serial_write(MICROPY_GIT_TAG); - // Send string terminator - serial_write("\x1b" "\\"); + supervisor_title_bar_update(); } void supervisor_title_bar_start(void) { diff --git a/supervisor/shared/title_bar.h b/supervisor/shared/title_bar.h index 6aeddfe121..092b5add32 100644 --- a/supervisor/shared/title_bar.h +++ b/supervisor/shared/title_bar.h @@ -31,8 +31,14 @@ void supervisor_title_bar_start(void); void supervisor_title_bar_suspend(void); void supervisor_title_bar_resume(void); + +// Update the title bar immediately. Useful from main.c where we know state has changed and the code +// will only be run once. +void supervisor_title_bar_update(void); + +// Use this if requesting from the background, as code is executing or if the status may not have +// changed. void supervisor_title_bar_request_update(bool force_dirty); // Provided by main.c -bool supervisor_execution_status_dirty(void); void supervisor_execution_status(void); diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index dc9dbd69a4..e5e543b79c 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -110,6 +110,160 @@ c_file.write( """ ) + +c_file.write( + """\ +#if CIRCUITPY_REPL_LOGO +""" +) +if tile_y == 16: + blinka_size = 16 + c_file.write( + """\ +uint32_t blinka_bitmap_data[32] = { + 0x00000011, 0x11000000, + 0x00000111, 0x53100000, + 0x00000111, 0x56110000, + 0x00000111, 0x11140000, + 0x00000111, 0x20002000, + 0x00000011, 0x13000000, + 0x00000001, 0x11200000, + 0x00000000, 0x11330000, + 0x00000000, 0x01122000, + 0x00001111, 0x44133000, + 0x00032323, 0x24112200, + 0x00111114, 0x44113300, + 0x00323232, 0x34112200, + 0x11111144, 0x44443300, + 0x11111111, 0x11144401, + 0x23232323, 0x21111110 +}; +""" + ) +else: + blinka_size = 12 + c_file.write( + """\ +uint32_t blinka_bitmap_data[28] = { + 0x00000111, 0x00000000, + 0x00001153, 0x10000000, + 0x00001156, 0x11000000, + 0x00001111, 0x14000000, + 0x00000112, 0x00200000, + 0x00000011, 0x30000000, + 0x00000011, 0x20000000, + 0x00011144, 0x13000000, + 0x00232324, 0x12000000, + 0x01111444, 0x13000000, + 0x32323234, 0x12010000, + 0x11111144, 0x44100000 +}; +""" + ) + +c_file.write( + """\ +displayio_bitmap_t blinka_bitmap = {{ + .base = {{.type = &displayio_bitmap_type }}, + .width = {0}, + .height = {0}, + .data = blinka_bitmap_data, + .stride = 2, + .bits_per_value = 4, + .x_shift = 3, + .x_mask = 0x7, + .bitmask = 0xf, + .read_only = true +}}; + +_displayio_color_t blinka_colors[7] = {{ + {{ + .rgb888 = 0x000000, + .rgb565 = 0x0000, + .luma = 0x00, + .chroma = 0, + .transparent = true + }}, + {{ + .rgb888 = 0x8428bc, + .rgb565 = 0x8978, + .luma = 0xff, // We cheat the luma here. It is actually 0x60 + .hue = 184, + .chroma = 148 + }}, + {{ + .rgb888 = 0xff89bc, + .rgb565 = 0xFCB8, + .luma = 0xb5, + .hue = 222, + .chroma = 118 + }}, + {{ + .rgb888 = 0x7beffe, + .rgb565 = 0x869F, + .luma = 0xe0, + .hue = 124, + .chroma = 131 + }}, + {{ + .rgb888 = 0x51395f, + .rgb565 = 0x5A0D, + .luma = 0x47, + .hue = 185, + .chroma = 38 + }}, + {{ + .rgb888 = 0xffffff, + .rgb565 = 0xffff, + .luma = 0xff, + .chroma = 0 + }}, + {{ + .rgb888 = 0x0736a0, + .rgb565 = 0x01f5, + .luma = 0x44, + .hue = 147, + .chroma = 153 + }}, +}}; + +displayio_palette_t blinka_palette = {{ + .base = {{.type = &displayio_palette_type }}, + .colors = blinka_colors, + .color_count = 7, + .needs_refresh = false +}}; + +displayio_tilegrid_t supervisor_blinka_sprite = {{ + .base = {{.type = &displayio_tilegrid_type }}, + .bitmap = &blinka_bitmap, + .pixel_shader = &blinka_palette, + .x = 0, + .y = 0, + .pixel_width = {0}, + .pixel_height = {0}, + .bitmap_width_in_tiles = 1, + .width_in_tiles = 1, + .height_in_tiles = 1, + .tile_width = {0}, + .tile_height = {0}, + .top_left_x = {0}, + .top_left_y = {0}, + .tiles = 0, + .partial_change = false, + .full_change = false, + .hidden = false, + .hidden_by_parent = false, + .moved = false, + .inline_tiles = true, + .in_group = true +}}; +#endif +""".format( + blinka_size + ) +) + c_file.write( """\ _displayio_color_t terminal_colors[2] = {