summaryrefslogtreecommitdiff
path: root/shared-module/displayio
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2019-02-01 00:32:03 -0800
committerScott Shawcroft <scott@tannewt.org>2019-02-01 00:32:03 -0800
commit448ae64d8e2eb0cce9c5bd9dabd7f2354bb48682 (patch)
tree9f156429c3638e7149fe3e0d7e585bf1fd2462e9 /shared-module/displayio
parentd72cd5b2d6cbc95665c41a43d6d914e71ac58017 (diff)
Add support for display rotation and raw commands
Display rotation is relative to the scan order of the display. The scan order can be found by scrolling the display with command 0x37 `display_bus.send(0x37, struct.pack(">H", i % 128))` Fixes #1504
Diffstat (limited to 'shared-module/displayio')
-rw-r--r--shared-module/displayio/Display.c26
-rw-r--r--shared-module/displayio/Display.h3
-rw-r--r--shared-module/displayio/__init__.c59
3 files changed, 76 insertions, 12 deletions
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index ef0334d10..f14a27b78 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -41,12 +41,10 @@
#define DELAY 0x80
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,
+ mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t rotation,
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 set_vertical_scroll, 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;
@@ -100,6 +98,26 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
self->refresh = true;
self->current_group = &circuitpython_splash;
+ self->width = width;
+ self->height = height;
+ rotation = rotation % 360;
+ self->mirror_x = false;
+ self->mirror_y = false;
+ self->transpose_xy = false;
+ if (rotation == 0 || rotation == 180) {
+ if (rotation == 180) {
+ self->mirror_x = true;
+ self->mirror_y = true;
+ }
+ } else {
+ self->transpose_xy = true;
+ if (rotation == 90) {
+ self->mirror_y = true;
+ } else {
+ self->mirror_x = true;
+ }
+ }
+
// 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)) {
diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h
index 0d7393aff..04da68b63 100644
--- a/shared-module/displayio/Display.h
+++ b/shared-module/displayio/Display.h
@@ -59,6 +59,9 @@ typedef struct {
uint64_t last_backlight_refresh;
bool auto_brightness:1;
bool updating_backlight:1;
+ bool mirror_x;
+ bool mirror_y;
+ bool transpose_xy;
} displayio_display_obj_t;
void displayio_display_update_backlight(displayio_display_obj_t* self);
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index f09e4e791..c4f9cbeb7 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -12,6 +12,12 @@
primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
+static inline void swap(uint16_t* a, uint16_t* b) {
+ uint16_t temp = *a;
+ *a = *b;
+ *b = temp;
+}
+
void displayio_refresh_displays(void) {
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].display.base.type == NULL || displays[i].display.base.type == &mp_type_NoneType) {
@@ -24,23 +30,60 @@ void displayio_refresh_displays(void) {
return;
}
if (displayio_display_refresh_queued(display)) {
- // We compute the pixels
+ // We compute the pixels. r and c are row and column to match the display memory
+ // structure. x and y match location within the groups.
+ uint16_t c0 = 0;
+ uint16_t r0 = 0;
+ uint16_t c1 = display->width;
+ uint16_t r1 = display->height;
+ if (display->transpose_xy) {
+ swap(&c1, &r1);
+ }
+ displayio_display_start_region_update(display, c0, r0, c1, r1);
+
uint16_t x0 = 0;
+ uint16_t x1 = display->width - 1;
+ uint16_t startx = 0;
+ int8_t dx = 1;
+ if (display->mirror_x) {
+ dx = -1;
+ startx = x1;
+ }
uint16_t y0 = 0;
- uint16_t x1 = display->width;
- uint16_t y1 = display->height;
+ uint16_t y1 = display->height - 1;
+ uint16_t starty = 0;
+ int8_t dy = 1;
+ if (display->mirror_y) {
+ dy = -1;
+ starty = y1;
+ }
+
+ bool transpose = false;
+ if (display->transpose_xy) {
+ transpose = true;
+ int8_t temp_dx = dx;
+ dx = dy;
+ dy = temp_dx;
+
+ swap(&starty, &startx);
+ swap(&x0, &y0);
+ swap(&x1, &y1);
+ }
+
size_t index = 0;
- //size_t row_size = (x1 - x0);
uint16_t buffer_size = 256;
uint32_t buffer[buffer_size / 2];
- displayio_display_start_region_update(display, x0, y0, x1, y1);
- for (uint16_t y = y0; y < y1; ++y) {
- for (uint16_t x = x0; x < x1; ++x) {
+ for (uint16_t y = starty; y0 <= y && y <= y1; y += dy) {
+ for (uint16_t x = startx; x0 <= x && x <= x1; x += dx) {
uint16_t* pixel = &(((uint16_t*)buffer)[index]);
*pixel = 0;
if (display->current_group != NULL) {
- displayio_group_get_pixel(display->current_group, x, y, pixel);
+ if (transpose) {
+ displayio_group_get_pixel(display->current_group, y, x, pixel);
+ } else {
+ displayio_group_get_pixel(display->current_group, x, y, pixel);
+ }
}
index += 1;