From 1a1dbef992442682413f6103e36440a26bc2dad7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 25 Jan 2019 16:59:18 -0800 Subject: Hook up the terminal based on the first display. --- shared-module/displayio/Display.c | 13 +++++ shared-module/displayio/Group.c | 18 ++++-- shared-module/displayio/TileGrid.c | 15 ++++- shared-module/displayio/TileGrid.h | 1 + shared-module/displayio/__init__.c | 106 +++++++----------------------------- shared-module/displayio/__init__.h | 3 + shared-module/terminalio/Terminal.c | 44 ++++++++++++++- 7 files changed, 105 insertions(+), 95 deletions(-) (limited to 'shared-module') diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 7946111b7..fd082c19d 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -30,6 +30,8 @@ #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/ParallelBus.h" #include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/display.h" #include @@ -47,6 +49,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, self->set_column_command = set_column_command; self->set_row_command = set_row_command; self->write_ram_command = write_ram_command; + self->refresh = false; self->current_group = NULL; self->colstart = colstart; self->rowstart = rowstart; @@ -86,9 +89,19 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, i += 2 + data_size; } self->end_transaction(self->bus); + + supervisor_start_terminal(width, height); + + // Set the group after initialization otherwise we may send pixels while we delay in + // initialization. + self->refresh = true; + self->current_group = &circuitpython_splash; } void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { + if (root_group == NULL) { + root_group = &circuitpython_splash; + } self->current_group = root_group; common_hal_displayio_display_refresh_soon(self); } diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 46898fb8e..bbbd83486 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -105,12 +105,19 @@ bool displayio_group_needs_refresh(displayio_group_t *self) { } for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i]; - if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + if (displayio_tilegrid_needs_refresh(layer)) { + return true; + } + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + if (displayio_group_needs_refresh(layer)) { + return true; + } + } else if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { if (displayio_sprite_needs_refresh(layer)) { return true; } } - // TODO: Tiled layer } return false; } @@ -119,9 +126,12 @@ void displayio_group_finish_refresh(displayio_group_t *self) { self->needs_refresh = false; for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i]; - if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + displayio_tilegrid_finish_refresh(layer); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_finish_refresh(layer); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { displayio_sprite_finish_refresh(layer); } - // TODO: Tiled layer } } diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 44874e283..ed724bf10 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -33,6 +33,7 @@ #include "shared-bindings/displayio/Shape.h" void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, + uint16_t bitmap_width_in_tiles, mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile) { uint32_t total_tiles = width * height; @@ -44,8 +45,9 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ self->tiles = (uint8_t*) m_malloc(total_tiles, false); self->inline_tiles = false; } + self->bitmap_width_in_tiles = bitmap_width_in_tiles; self->width_in_tiles = width; - self->height_in_tiles = width; + self->height_in_tiles = height; self->total_width = width * tile_width; self->total_height = height * tile_height; self->tile_width = tile_width; @@ -87,10 +89,13 @@ bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t if (self->inline_tiles) { tiles = (uint8_t*) &self->tiles; } + if (tiles == NULL) { + return false; + } uint16_t tile_location = (y / self->tile_height) * self->width_in_tiles + x / self->tile_width; uint8_t tile = tiles[tile_location]; - uint16_t tile_x = tile_x = (tile % self->width_in_tiles) * self->tile_width + x % self->tile_width; - uint16_t tile_y = tile_y = (tile / self->width_in_tiles) * self->tile_height + y % self->tile_height; + uint16_t tile_x = tile_x = (tile % self->bitmap_width_in_tiles) * self->tile_width + x % self->tile_width; + uint16_t tile_y = tile_y = (tile / self->bitmap_width_in_tiles) * self->tile_height + y % self->tile_height; uint32_t value = 0; if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { @@ -118,7 +123,11 @@ void common_hal_displayio_textgrid_set_tile(displayio_tilegrid_t *self, uint16_t if (self->inline_tiles) { tiles = (uint8_t*) &self->tiles; } + if (tiles == NULL) { + return; + } tiles[y * self->width_in_tiles + x] = tile_index; + self->needs_refresh = true; } bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self) { diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h index c24a606a3..84e3e7ef2 100644 --- a/shared-module/displayio/TileGrid.h +++ b/shared-module/displayio/TileGrid.h @@ -38,6 +38,7 @@ typedef struct { mp_obj_t pixel_shader; uint16_t x; uint16_t y; + uint16_t bitmap_width_in_tiles; uint16_t width_in_tiles; uint16_t height_in_tiles; uint16_t total_width; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 61228f8d2..dbfeacc3d 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -9,6 +9,7 @@ #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/Sprite.h" #include "supervisor/shared/display.h" +#include "supervisor/memory.h" #include "supervisor/usb.h" primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; @@ -68,76 +69,24 @@ void displayio_refresh_displays(void) { } } -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 -}; - -uint32_t blinka_transparency[1] = {0x80000000}; - -// These colors are RGB 565 with the bytes swapped. -uint32_t blinka_colors[8] = {0x78890000, 0x9F86B8FC, 0xffff0D5A, 0x0000f501, - 0x00000000, 0x00000000, 0x00000000, 0x00000000}; - -displayio_palette_t blinka_palette = { - .base = {.type = &displayio_palette_type }, - .opaque = blinka_transparency, - .colors = blinka_colors, - .color_count = 16, - .needs_refresh = false -}; - -displayio_sprite_t blinka_sprite = { - .base = {.type = &displayio_sprite_type }, - .bitmap = &blinka_bitmap, - .pixel_shader = &blinka_palette, - .x = 0, - .y = 0, - .width = 16, - .height = 16, - .needs_refresh = false -}; - -mp_obj_t splash_children[1] = { - &blinka_sprite, -}; +void common_hal_displayio_release_displays(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; + if (bus_type == NULL) { + continue; + } else if (bus_type == &displayio_fourwire_type) { + common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); + } else if (bus_type == &displayio_parallelbus_type) { + common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); + } + displays[i].fourwire_bus.base.type = &mp_type_NoneType; + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + displays[i].display.base.type = &mp_type_NoneType; + } -displayio_group_t splash = { - .base = {.type = &displayio_group_type }, - .x = 0, - .y = 0, - .scale = 2, - .size = 1, - .max_size = 1, - .children = splash_children, - .needs_refresh = true -}; + supervisor_stop_terminal(); +} void reset_displays(void) { // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. @@ -168,23 +117,6 @@ void reset_displays(void) { continue; } displayio_display_obj_t* display = &displays[i].display; - common_hal_displayio_display_show(display, &splash); - } -} - -void common_hal_displayio_release_displays(void) { - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; - if (bus_type == NULL) { - continue; - } else if (bus_type == &displayio_fourwire_type) { - common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); - } else if (bus_type == &displayio_parallelbus_type) { - common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); - } - displays[i].fourwire_bus.base.type = &mp_type_NoneType; - } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - displays[i].display.base.type = &mp_type_NoneType; + common_hal_displayio_display_show(display, &circuitpython_splash); } } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index fdabd4ec4..5b56ed55c 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -29,6 +29,7 @@ #include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/ParallelBus.h" typedef struct { @@ -41,6 +42,8 @@ typedef struct { extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +extern displayio_group_t circuitpython_splash; + void displayio_refresh_displays(void); void reset_displays(void); diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index c47f9f6cf..1cd5d341e 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -28,7 +28,7 @@ #include "shared-bindings/displayio/TileGrid.h" -void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, uint8_t* unicode_characters, uint16_t unicode_characters_len) { +void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, const uint8_t* unicode_characters, uint16_t unicode_characters_len) { self->cursor_x = 0; self->cursor_y = 0; self->tilegrid = tilegrid; @@ -38,6 +38,7 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, d size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) { const byte* i = data; + uint16_t start_y = self->cursor_y; while (i < data + len) { unichar c = utf8_get_char(i); i = utf8_next_char(i); @@ -51,6 +52,40 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con self->cursor_x = 0; } else if (c == '\n') { self->cursor_y++; + // Commands below are used by MicroPython in the REPL + } else if (c == '\b') { + if (self->cursor_x > 0) { + self->cursor_x--; + } + } else if (c == 0x1b) { + if (i[0] == '[') { + if (i[1] == 'K') { + // Clear the rest of the line. + for (uint16_t j = self->cursor_x; j < self->tilegrid->width_in_tiles; j++) { + common_hal_displayio_textgrid_set_tile(self->tilegrid, j, self->cursor_y, 0); + } + i += 2; + } else { + // Handle commands of the form \x1b[####D + uint16_t n = 0; + uint8_t j = 1; + for (; j < 6; j++) { + if ('0' <= i[j] && i[j] <= '9') { + n = n * 10 + (i[j] - '0'); + } else { + c = i[j]; + } + } + if (c == 'D') { + if (n > self->cursor_x) { + self->cursor_x = 0; + } else { + self->cursor_x -= n; + } + i += j; + } + } + } } } else { // Do a linear search of the mapping for unicode. @@ -73,6 +108,13 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con if (self->cursor_y >= self->tilegrid->height_in_tiles) { self->cursor_y %= self->tilegrid->height_in_tiles; } + if (self->cursor_y != start_y) { + // clear the new row + for (uint16_t j = 0; j < self->tilegrid->width_in_tiles; j++) { + common_hal_displayio_textgrid_set_tile(self->tilegrid, j, self->cursor_y, 0); + start_y = self->cursor_y; + } + } } return i - data; } -- cgit v1.2.3