Skip to content

Rework displayio display bus transaction handling during refresh #1620

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ LONGINT_IMPL = MPZ
CHIP_VARIANT = SAMD21G18A
CHIP_FAMILY = samd21

CFLAGS_INLINE_LIMIT = 70

CIRCUITPY_NETWORK = 1
MICROPY_PY_WIZNET5K = 5500

Expand Down
8 changes: 5 additions & 3 deletions shared-bindings/displayio/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_

void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self);

void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void displayio_display_finish_region_update(displayio_display_obj_t* self);
bool displayio_display_begin_transaction(displayio_display_obj_t* self);
void displayio_display_end_transaction(displayio_display_obj_t* self);

void displayio_display_set_region_to_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
bool displayio_display_frame_queued(displayio_display_obj_t* self);

bool displayio_display_refresh_queued(displayio_display_obj_t* self);
void displayio_display_finish_refresh(displayio_display_obj_t* self);
bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length);
void displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length);

bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self);
void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness);
Expand Down
7 changes: 6 additions & 1 deletion shared-bindings/displayio/FourWire.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ STATIC mp_obj_t displayio_fourwire_obj_send(mp_obj_t self, mp_obj_t command_obj,
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ);

common_hal_displayio_fourwire_begin_transaction(self);
// Wait for display bus to be available.
while (!common_hal_displayio_fourwire_begin_transaction(self)) {
#ifdef MICROPY_VM_HOOK_LOOP
MICROPY_VM_HOOK_LOOP ;
#endif
}
common_hal_displayio_fourwire_send(self, true, &command, 1);
common_hal_displayio_fourwire_send(self, false, ((uint8_t*) bufinfo.buf), bufinfo.len);
common_hal_displayio_fourwire_end_transaction(self);
Expand Down
7 changes: 6 additions & 1 deletion shared-bindings/displayio/ParallelBus.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,12 @@ STATIC mp_obj_t displayio_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_o
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ);

common_hal_displayio_parallelbus_begin_transaction(self);
// Wait for display bus to be available.
while (!common_hal_displayio_parallelbus_begin_transaction(self)) {
#ifdef MICROPY_VM_HOOK_LOOP
MICROPY_VM_HOOK_LOOP ;
#endif
}
common_hal_displayio_parallelbus_send(self, true, &command, 1);
common_hal_displayio_parallelbus_send(self, false, ((uint8_t*) bufinfo.buf), bufinfo.len);
common_hal_displayio_parallelbus_end_transaction(self);
Expand Down
24 changes: 15 additions & 9 deletions shared-module/displayio/Display.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
self->bus = bus;

uint32_t i = 0;
self->begin_transaction(self->bus);
while (!self->begin_transaction(self->bus)) {
#ifdef MICROPY_VM_HOOK_LOOP
MICROPY_VM_HOOK_LOOP ;
#endif
}
while (i < init_sequence_len) {
uint8_t *cmd = init_sequence + i;
uint8_t data_size = *(cmd + 1);
Expand Down Expand Up @@ -198,9 +202,16 @@ bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self,
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) {
bool displayio_display_begin_transaction(displayio_display_obj_t* self) {
return self->begin_transaction(self->bus);
}

void displayio_display_end_transaction(displayio_display_obj_t* self) {
self->end_transaction(self->bus);
}

void displayio_display_set_region_to_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);
uint16_t data[2];
self->send(self->bus, true, &self->set_column_command, 1);
data[0] = __builtin_bswap16(x0 + self->colstart);
Expand All @@ -213,10 +224,6 @@ void displayio_display_start_region_update(displayio_display_obj_t* self, uint16
self->send(self->bus, true, &self->write_ram_command, 1);
}

void displayio_display_finish_region_update(displayio_display_obj_t* self) {
self->end_transaction(self->bus);
}

bool displayio_display_frame_queued(displayio_display_obj_t* self) {
// Refresh at ~30 fps.
return (ticks_ms - self->last_refresh) > 32;
Expand All @@ -234,9 +241,8 @@ void displayio_display_finish_refresh(displayio_display_obj_t* self) {
self->last_refresh = ticks_ms;
}

bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length) {
void displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length) {
self->send(self->bus, false, (uint8_t*) pixels, length * 4);
return true;
}

void displayio_display_update_backlight(displayio_display_obj_t* self) {
Expand Down
58 changes: 42 additions & 16 deletions shared-module/displayio/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ static inline void swap(uint16_t* a, uint16_t* b) {
*b = temp;
}

bool refreshing_displays = false;
// Check for recursive calls to displayio_refresh_displays.
bool refresh_displays_in_progress = false;

void displayio_refresh_displays(void) {
if (mp_hal_is_interrupted()) {
Expand All @@ -35,20 +36,25 @@ void displayio_refresh_displays(void) {
return;
}

if (refreshing_displays) {
if (refresh_displays_in_progress) {
// Don't allow recursive calls to this routine.
return;
}
refreshing_displays = true;

refresh_displays_in_progress = true;

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) {
// Skip null display.
continue;
}
displayio_display_obj_t* display = &displays[i].display;
displayio_display_update_backlight(display);

// Time to refresh at specified frame rate?
if (!displayio_display_frame_queued(display)) {
refreshing_displays = false;
return;
// Too soon. Try next display.
continue;
}
if (displayio_display_refresh_queued(display)) {
// We compute the pixels. r and c are row and column to match the display memory
Expand All @@ -60,7 +66,13 @@ void displayio_refresh_displays(void) {
if (display->transpose_xy) {
swap(&c1, &r1);
}
displayio_display_start_region_update(display, c0, r0, c1, r1);

if (!displayio_display_begin_transaction(display)) {
// Can't acquire display bus; skip updating this display. Try next display.
continue;
}
displayio_display_set_region_to_update(display, c0, r0, c1, r1);
displayio_display_end_transaction(display);

uint16_t x0 = 0;
uint16_t x1 = display->width - 1;
Expand Down Expand Up @@ -94,6 +106,8 @@ void displayio_refresh_displays(void) {
size_t index = 0;
uint16_t buffer_size = 256;
uint32_t buffer[buffer_size / 2];
bool skip_this_display = false;

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]);
Expand All @@ -110,29 +124,41 @@ void displayio_refresh_displays(void) {
index += 1;
// The buffer is full, send it.
if (index >= buffer_size) {
if (!displayio_display_send_pixels(display, buffer, buffer_size / 2) || reload_requested) {
displayio_display_finish_region_update(display);
refreshing_displays = false;
return;
if (!displayio_display_begin_transaction(display)) {
// Can't acquire display bus; skip the rest of the data. Try next display.
index = 0;
skip_this_display = true;
break;
}
displayio_display_send_pixels(display, buffer, buffer_size / 2);
displayio_display_end_transaction(display);
// TODO(tannewt): Make refresh displays faster so we don't starve other
// background tasks.
usb_background();
index = 0;
}
}
}

if (skip_this_display) {
// Go on to next display.
continue;
}
// Send the remaining data.
if (index && !displayio_display_send_pixels(display, buffer, index * 2)) {
displayio_display_finish_region_update(display);
refreshing_displays = false;
return;
if (index) {
if (!displayio_display_begin_transaction(display)) {
// Can't get display bus. Skip the rest of the data. Try next display.
continue;
}
displayio_display_send_pixels(display, buffer, index * 2);
}
displayio_display_finish_region_update(display);
displayio_display_end_transaction(display);
}
displayio_display_finish_refresh(display);
}
refreshing_displays = false;

// All done.
refresh_displays_in_progress = false;
}

void common_hal_displayio_release_displays(void) {
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy