From c854f6617a0b343333635fe0cc91419daff7cdd5 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 6 Mar 2019 13:45:48 -0500 Subject: [PATCH] check display-bus transaction status and act accordingly --- shared-bindings/displayio/Display.h | 2 +- shared-bindings/displayio/FourWire.c | 7 ++++++- shared-bindings/displayio/ParallelBus.c | 7 ++++++- shared-module/displayio/Display.c | 16 +++++++++++++--- shared-module/displayio/__init__.c | 6 +++++- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index ee9106f778..8c9e7fc137 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -48,7 +48,7 @@ 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); +bool 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_frame_queued(displayio_display_obj_t* self); diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 56baa534b7..70cd427471 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -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); diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index a54a844719..6a499ed069 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -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); diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 95c5cdfeca..2f2ba0665c 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -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); @@ -198,9 +202,14 @@ 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) { +// This routine is meant to be called as a background task. If it cannot acquire the display bus, +// it will return false immediately to indicate it didn't do anything. +bool 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); + if (!self->begin_transaction(self->bus)) { + // Could not acquire the bus; give up. + return false; + } uint16_t data[2]; self->send(self->bus, true, &self->set_column_command, 1); data[0] = __builtin_bswap16(x0 + self->colstart); @@ -211,6 +220,7 @@ void displayio_display_start_region_update(displayio_display_obj_t* self, uint16 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); + return true; } void displayio_display_finish_region_update(displayio_display_obj_t* self) { diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 79014fb5af..58a6ce4714 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -60,7 +60,11 @@ void displayio_refresh_displays(void) { if (display->transpose_xy) { swap(&c1, &r1); } - displayio_display_start_region_update(display, c0, r0, c1, r1); + // Someone else is holding the bus used to talk to the display, + // so skip update for now. + if (!displayio_display_start_region_update(display, c0, r0, c1, r1)) { + return; + } uint16_t x0 = 0; uint16_t x1 = display->width - 1;