summaryrefslogtreecommitdiff
path: root/shared-module
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2019-01-31 16:03:51 -0500
committerGitHub <noreply@github.com>2019-01-31 16:03:51 -0500
commit7c443fbef2b92bfdd382db9aeaddcdcecbc02cd0 (patch)
tree93c06f6ba863e234148555f41042b354286cb52e /shared-module
parent63d456127b783efb376bd2b25598cc9e7f9dceb6 (diff)
parentd72cd5b2d6cbc95665c41a43d6d914e71ac58017 (diff)
Merge pull request #1510 from tannewt/terminalio
Add a terminal that shows by default on displays.
Diffstat (limited to 'shared-module')
-rw-r--r--shared-module/displayio/Display.c95
-rw-r--r--shared-module/displayio/Display.h14
-rw-r--r--shared-module/displayio/Group.c26
-rw-r--r--shared-module/displayio/TileGrid.c (renamed from shared-module/displayio/Sprite.c)80
-rw-r--r--shared-module/displayio/TileGrid.h59
-rw-r--r--shared-module/displayio/__init__.c113
-rw-r--r--shared-module/displayio/__init__.h3
-rw-r--r--shared-module/terminalio/Terminal.c127
-rw-r--r--shared-module/terminalio/Terminal.h (renamed from shared-module/displayio/Sprite.h)32
-rw-r--r--shared-module/terminalio/__init__.c27
-rw-r--r--shared-module/terminalio/__init__.h30
11 files changed, 468 insertions, 138 deletions
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index 7946111b7..ef0334d10 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -29,7 +29,10 @@
#include "py/runtime.h"
#include "shared-bindings/displayio/FourWire.h"
#include "shared-bindings/displayio/ParallelBus.h"
+#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/time/__init__.h"
+#include "shared-module/displayio/__init__.h"
+#include "supervisor/shared/display.h"
#include <stdint.h>
@@ -40,16 +43,19 @@
void common_hal_displayio_display_construct(displayio_display_obj_t* self,
mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart,
uint16_t color_depth, uint8_t set_column_command, uint8_t set_row_command,
- uint8_t write_ram_command, uint8_t* init_sequence, uint16_t init_sequence_len) {
+ uint8_t write_ram_command, uint8_t* init_sequence, uint16_t init_sequence_len,
+ const mcu_pin_obj_t* backlight_pin) {
self->width = width;
self->height = height;
self->color_depth = color_depth;
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;
+ self->auto_brightness = false;
if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) {
self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction;
@@ -86,9 +92,33 @@ 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;
+
+ // Always set the backlight type in case we're reusing memory.
+ self->backlight_inout.base.type = &mp_type_NoneType;
+ if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) {
+ pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 5000, false);
+ if (result != PWMOUT_OK) {
+ self->backlight_inout.base.type = &digitalio_digitalinout_type;
+ common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin);
+ never_reset_pin_number(backlight_pin->number);
+ } else {
+ self->backlight_pwm.base.type = &pulseio_pwmout_type;
+ common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm);
+ }
+ }
}
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);
}
@@ -105,6 +135,42 @@ int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* sel
return 0;
}
+bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self) {
+ return self->auto_brightness;
+}
+
+void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness) {
+ self->auto_brightness = auto_brightness;
+}
+
+mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self) {
+ if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
+ uint16_t duty_cycle = common_hal_pulseio_pwmout_get_duty_cycle(&self->backlight_pwm);
+ return duty_cycle / ((mp_float_t) 0xffff);
+ } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
+ if (common_hal_digitalio_digitalinout_get_value(&self->backlight_inout)) {
+ return 1.0;
+ } else {
+ return 0.0;
+ }
+ }
+ return -1.0;
+}
+
+bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness) {
+ self->updating_backlight = true;
+ bool ok = false;
+ if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
+ common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness));
+ ok = true;
+ } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
+ common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99);
+ ok = true;
+ }
+ self->updating_backlight = false;
+ return ok;
+}
+
void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
// TODO(tannewt): Handle displays with single byte bounds.
self->begin_transaction(self->bus);
@@ -114,8 +180,8 @@ void displayio_display_start_region_update(displayio_display_obj_t* self, uint16
data[1] = __builtin_bswap16(x1 - 1 + self->colstart);
self->send(self->bus, false, (uint8_t*) data, 4);
self->send(self->bus, true, &self->set_row_command, 1);
- data[0] = __builtin_bswap16(y0 + 1 + self->rowstart);
- data[1] = __builtin_bswap16(y1 + self->rowstart);
+ data[0] = __builtin_bswap16(y0 + self->rowstart);
+ data[1] = __builtin_bswap16(y1 - 1 + self->rowstart);
self->send(self->bus, false, (uint8_t*) data, 4);
self->send(self->bus, true, &self->write_ram_command, 1);
}
@@ -145,3 +211,26 @@ bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixe
self->send(self->bus, false, (uint8_t*) pixels, length * 4);
return true;
}
+
+void displayio_display_update_backlight(displayio_display_obj_t* self) {
+ if (!self->auto_brightness || self->updating_backlight) {
+ return;
+ }
+ if (ticks_ms - self->last_backlight_refresh < 100) {
+ return;
+ }
+ // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target
+ // should account for ambient light when possible.
+ common_hal_displayio_display_set_brightness(self, 1.0);
+
+ self->last_backlight_refresh = ticks_ms;
+}
+
+void release_display(displayio_display_obj_t* self) {
+ if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
+ common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm);
+ common_hal_pulseio_pwmout_deinit(&self->backlight_pwm);
+ } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
+ common_hal_digitalio_digitalinout_deinit(&self->backlight_inout);
+ }
+}
diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h
index 1f1355d31..0d7393aff 100644
--- a/shared-module/displayio/Display.h
+++ b/shared-module/displayio/Display.h
@@ -27,7 +27,9 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H
#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H
-#include "shared-module/displayio/Group.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/displayio/Group.h"
+#include "shared-bindings/pulseio/PWMOut.h"
typedef bool (*display_bus_begin_transaction)(mp_obj_t bus);
typedef void (*display_bus_send)(mp_obj_t bus, bool command, uint8_t *data, uint32_t data_length);
@@ -50,6 +52,16 @@ typedef struct {
display_bus_begin_transaction begin_transaction;
display_bus_send send;
display_bus_end_transaction end_transaction;
+ union {
+ digitalio_digitalinout_obj_t backlight_inout;
+ pulseio_pwmout_obj_t backlight_pwm;
+ };
+ uint64_t last_backlight_refresh;
+ bool auto_brightness:1;
+ bool updating_backlight:1;
} displayio_display_obj_t;
+void displayio_display_update_backlight(displayio_display_obj_t* self);
+void release_display(displayio_display_obj_t* self);
+
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H
diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c
index 255349d7c..95043e4f3 100644
--- a/shared-module/displayio/Group.c
+++ b/shared-module/displayio/Group.c
@@ -27,7 +27,7 @@
#include "shared-bindings/displayio/Group.h"
#include "py/runtime.h"
-#include "shared-bindings/displayio/Sprite.h"
+#include "shared-bindings/displayio/TileGrid.h"
void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size) {
mp_obj_t* children = m_new(mp_obj_t, max_size);
@@ -40,10 +40,10 @@ void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer)
}
mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type);
if (native_layer == MP_OBJ_NULL) {
- native_layer = mp_instance_cast_to_native_base(layer, &displayio_sprite_type);
+ native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type);
}
if (native_layer == MP_OBJ_NULL) {
- mp_raise_ValueError(translate("Layer must be a Group or Sprite subclass."));
+ mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass."));
}
self->children[self->size] = layer;
self->size++;
@@ -77,8 +77,8 @@ bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, ui
y /= self->scale;
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 (displayio_sprite_get_pixel(layer, x, y, pixel)) {
+ if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
+ if (displayio_tilegrid_get_pixel(layer, x, y, pixel)) {
return true;
}
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
@@ -97,12 +97,15 @@ 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 (displayio_sprite_needs_refresh(layer)) {
+ 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;
}
}
- // TODO: Tiled layer
}
return false;
}
@@ -111,9 +114,10 @@ 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)) {
- displayio_sprite_finish_refresh(layer);
+ 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);
}
- // TODO: Tiled layer
}
}
diff --git a/shared-module/displayio/Sprite.c b/shared-module/displayio/TileGrid.c
index da6eff896..b90603afe 100644
--- a/shared-module/displayio/Sprite.c
+++ b/shared-module/displayio/TileGrid.c
@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
-#include "shared-bindings/displayio/Sprite.h"
+#include "shared-bindings/displayio/TileGrid.h"
#include "shared-bindings/displayio/Bitmap.h"
#include "shared-bindings/displayio/ColorConverter.h"
@@ -32,50 +32,78 @@
#include "shared-bindings/displayio/Palette.h"
#include "shared-bindings/displayio/Shape.h"
-void common_hal_displayio_sprite_construct(displayio_sprite_t *self, mp_obj_t bitmap,
- mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t x, uint16_t y) {
- self->width = width;
- self->height = height;
+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;
+ // Sprites will only have one tile so save a little memory by inlining values in the pointer.
+ uint8_t inline_tiles = sizeof(uint8_t*);
+ if (total_tiles <= inline_tiles) {
+ self->inline_tiles = true;
+ } else {
+ 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 = height;
+ self->total_width = width * tile_width;
+ self->total_height = height * tile_height;
+ self->tile_width = tile_width;
+ self->tile_height = tile_height;
self->bitmap = bitmap;
self->pixel_shader = pixel_shader;
self->x = x;
self->y = y;
}
-void common_hal_displayio_sprite_get_position(displayio_sprite_t *self, int16_t* x, int16_t* y) {
+void common_hal_displayio_tilegrid_get_position(displayio_tilegrid_t *self, int16_t* x, int16_t* y) {
*x = self->x;
*y = self->y;
}
-void common_hal_displayio_sprite_set_position(displayio_sprite_t *self, int16_t x, int16_t y) {
+void common_hal_displayio_tilegrid_set_position(displayio_tilegrid_t *self, int16_t x, int16_t y) {
self->x = x;
self->y = y;
self->needs_refresh = true;
}
-
-mp_obj_t common_hal_displayio_sprite_get_pixel_shader(displayio_sprite_t *self) {
+mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self) {
return self->pixel_shader;
}
-void common_hal_displayio_sprite_set_pixel_shader(displayio_sprite_t *self, mp_obj_t pixel_shader) {
+void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader) {
self->pixel_shader = pixel_shader;
self->needs_refresh = true;
}
-bool displayio_sprite_get_pixel(displayio_sprite_t *self, int16_t x, int16_t y, uint16_t* pixel) {
+bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t y, uint16_t* pixel) {
x -= self->x;
y -= self->y;
- if (y < 0 || y >= self->height || x >= self->width || x < 0) {
+ if (y < 0 || y >= self->total_height || x >= self->total_width || x < 0) {
+ return false;
+ }
+
+ uint8_t* tiles = self->tiles;
+ if (self->inline_tiles) {
+ tiles = (uint8_t*) &self->tiles;
+ }
+ if (tiles == NULL) {
return false;
}
+ uint16_t tile_location = ((y / self->tile_height + self->top_left_y) % self->height_in_tiles) * self->width_in_tiles + (x / self->tile_width + self->top_left_x) % self->width_in_tiles;
+ uint8_t tile = tiles[tile_location];
+ 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)) {
- value = common_hal_displayio_bitmap_get_pixel(self->bitmap, x, y);
+ value = common_hal_displayio_bitmap_get_pixel(self->bitmap, tile_x, tile_y);
} else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) {
- value = common_hal_displayio_shape_get_pixel(self->bitmap, x, y);
+ value = common_hal_displayio_shape_get_pixel(self->bitmap, tile_x, tile_y);
} else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) {
- value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, x, y);
+ value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, tile_x, tile_y);
}
if (self->pixel_shader == mp_const_none) {
@@ -90,11 +118,29 @@ bool displayio_sprite_get_pixel(displayio_sprite_t *self, int16_t x, int16_t y,
return false;
}
-bool displayio_sprite_needs_refresh(displayio_sprite_t *self) {
+void common_hal_displayio_textgrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) {
+ uint8_t* tiles = self->tiles;
+ 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;
+}
+
+
+void common_hal_displayio_textgrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y) {
+ self->top_left_x = x;
+ self->top_left_y = y;
+}
+
+bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self) {
return self->needs_refresh || displayio_palette_needs_refresh(self->pixel_shader);
}
-void displayio_sprite_finish_refresh(displayio_sprite_t *self) {
+void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) {
self->needs_refresh = false;
displayio_palette_finish_refresh(self->pixel_shader);
// TODO(tannewt): We could double buffer changes to position and move them over here.
diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h
new file mode 100644
index 000000000..59645553d
--- /dev/null
+++ b/shared-module/displayio/TileGrid.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_TILEGRID_H
+#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_TILEGRID_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ mp_obj_t bitmap;
+ 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;
+ uint16_t total_height;
+ uint16_t tile_width;
+ uint16_t tile_height;
+ uint16_t top_left_x;
+ uint16_t top_left_y;
+ uint8_t* tiles;
+ bool needs_refresh;
+ bool inline_tiles;
+} displayio_tilegrid_t;
+
+bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t y, uint16_t *pixel);
+bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self);
+void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_TILEGRID_H
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index c86e48a12..f09e4e791 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -6,7 +6,8 @@
#include "shared-bindings/displayio/Display.h"
#include "shared-bindings/displayio/Group.h"
#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];
@@ -17,6 +18,7 @@ void displayio_refresh_displays(void) {
continue;
}
displayio_display_obj_t* display = &displays[i].display;
+ displayio_display_update_backlight(display);
if (!displayio_display_frame_queued(display)) {
return;
@@ -66,78 +68,28 @@ 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++) {
+ release_display(&displays[i].display);
+ 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) {
+ #if CIRCUITPY_DISPLAYIO
// The SPI buses used by FourWires may be allocated on the heap so we need to move them inline.
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].fourwire_bus.base.type != &displayio_fourwire_type) {
@@ -166,23 +118,8 @@ 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;
+ display->auto_brightness = true;
+ common_hal_displayio_display_show(display, &circuitpython_splash);
}
+ #endif
}
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
new file mode 100644
index 000000000..6734fa30e
--- /dev/null
+++ b/shared-module/terminalio/Terminal.c
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-module/terminalio/Terminal.h"
+
+#include "shared-module/displayio/__init__.h"
+#include "shared-bindings/displayio/TileGrid.h"
+
+void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, const uint8_t* unicode_characters, size_t unicode_characters_len) {
+ self->cursor_x = 0;
+ self->cursor_y = 0;
+ self->tilegrid = tilegrid;
+ self->unicode_characters = unicode_characters;
+ self->unicode_characters_len = unicode_characters_len;
+ self->first_row = 0;
+}
+
+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);
+ // Always handle ASCII.
+ if (c < 128) {
+ if (c >= 0x20 && c <= 0x7e) {
+ common_hal_displayio_textgrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, c - 0x20);
+ self->cursor_x++;
+ }
+ if (c == '\r') {
+ 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.
+ const byte* j = self->unicode_characters;
+ uint8_t k = 0;
+ while (j < self->unicode_characters + self->unicode_characters_len) {
+ unichar potential_c = utf8_get_char(j);
+ j = utf8_next_char(j);
+ if (c == potential_c) {
+ common_hal_displayio_textgrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, 0x7f - 0x20 + k);
+ self->cursor_x++;
+ break;
+ }
+ }
+ }
+ if (self->cursor_x >= self->tilegrid->width_in_tiles) {
+ self->cursor_y++;
+ self->cursor_x %= self->tilegrid->width_in_tiles;
+ }
+ 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;
+ }
+ common_hal_displayio_textgrid_set_top_left(self->tilegrid, 0, (start_y + self->tilegrid->height_in_tiles + 1) % self->tilegrid->height_in_tiles);
+ }
+ }
+ return i - data;
+}
+
+bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self) {
+ return true;
+}
diff --git a/shared-module/displayio/Sprite.h b/shared-module/terminalio/Terminal.h
index dc368c4b7..fe9dcf0c4 100644
--- a/shared-module/displayio/Sprite.h
+++ b/shared-module/terminalio/Terminal.h
@@ -1,5 +1,5 @@
/*
- * This file is part of the Micro Python project, http://micropython.org/
+ * This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
@@ -24,27 +24,23 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SPRITE_H
-#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SPRITE_H
+#ifndef SHARED_MODULE_TERMINALIO_TERMINAL_H
+#define SHARED_MODULE_TERMINALIO_TERMINAL_H
-#include <stdbool.h>
#include <stdint.h>
+#include <stdbool.h>
#include "py/obj.h"
+#include "shared-module/displayio/TileGrid.h"
-typedef struct {
+typedef struct {
mp_obj_base_t base;
- mp_obj_t bitmap;
- mp_obj_t pixel_shader;
- uint16_t x;
- uint16_t y;
- uint16_t width;
- uint16_t height;
- bool needs_refresh;
-} displayio_sprite_t;
-
-bool displayio_sprite_get_pixel(displayio_sprite_t *sprite, int16_t x, int16_t y, uint16_t *pixel);
-bool displayio_sprite_needs_refresh(displayio_sprite_t *self);
-void displayio_sprite_finish_refresh(displayio_sprite_t *self);
+ uint16_t cursor_x;
+ uint16_t cursor_y;
+ displayio_tilegrid_t* tilegrid;
+ const byte* unicode_characters;
+ uint16_t unicode_characters_len;
+ uint16_t first_row;
+} terminalio_terminal_obj_t;
-#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SPRITE_H
+#endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */
diff --git a/shared-module/terminalio/__init__.c b/shared-module/terminalio/__init__.c
new file mode 100644
index 000000000..3f61f4823
--- /dev/null
+++ b/shared-module/terminalio/__init__.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/terminalio/__init__.h"
diff --git a/shared-module/terminalio/__init__.h b/shared-module/terminalio/__init__.h
new file mode 100644
index 000000000..e925dd429
--- /dev/null
+++ b/shared-module/terminalio/__init__.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SHARED_MODULE_TERMINALIO___INIT___H
+#define SHARED_MODULE_TERMINALIO___INIT___H
+
+#endif /* SHARED_MODULE_TERMINALIO___INIT___H */