summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2019-08-20 21:35:42 -0700
committerScott Shawcroft <scott@tannewt.org>2019-08-22 14:23:32 -0700
commit24b30965c41ae32b82c56b166f3287cf2c14f419 (patch)
tree444132721268c10331daced2ae62f4c5e0219497
parent36a23e0fe3914b43645e51bf23a4d8bfec2db2c9 (diff)
Refresh ePaper displays once code.py is done running
-rwxr-xr-xmain.c8
-rw-r--r--shared-bindings/displayio/__init__.c2
-rw-r--r--shared-module/displayio/EPaperDisplay.c27
-rw-r--r--shared-module/displayio/EPaperDisplay.h1
-rw-r--r--shared-module/displayio/__init__.c24
-rw-r--r--shared-module/displayio/display_core.c3
6 files changed, 52 insertions, 13 deletions
diff --git a/main.c b/main.c
index 6ab50fc3c..076674c44 100755
--- a/main.c
+++ b/main.c
@@ -253,6 +253,7 @@ bool run_code_py(safe_mode_t safe_mode) {
}
bool serial_connected_before_animation = false;
+ bool refreshed_epaper_display = false;
rgb_status_animation_t animation;
prep_rgb_status_animation(&result, found_main, safe_mode, &animation);
while (true) {
@@ -290,6 +291,13 @@ bool run_code_py(safe_mode_t safe_mode) {
}
serial_connected_before_animation = serial_connected();
+ // Refresh the ePaper display if we have one. That way it'll show an error message.
+ #if CIRCUITPY_DISPLAYIO
+ if (!refreshed_epaper_display) {
+ refreshed_epaper_display = maybe_refresh_epaperdisplay();
+ }
+ #endif
+
tick_rgb_status_animation(&animation);
}
}
diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c
index 8c5d1f228..f78325593 100644
--- a/shared-bindings/displayio/__init__.c
+++ b/shared-bindings/displayio/__init__.c
@@ -77,7 +77,7 @@
//|
//| Releases any actively used displays so their busses and pins can be used again. This will also
//| release the builtin display on boards that have one. You will need to reinitialize it yourself
-//| afterwards.
+//| afterwards. This may take seconds to complete if an active EPaperDisplay is refreshing.
//|
//| Use this once in your code.py if you initialize a display. Place it right before the
//| initialization so the display is active as long as possible.
diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c
index 6ff060a6a..7e65502d4 100644
--- a/shared-module/displayio/EPaperDisplay.c
+++ b/shared-module/displayio/EPaperDisplay.c
@@ -170,6 +170,9 @@ void displayio_epaperdisplay_start_refresh(displayio_epaperdisplay_obj_t* self)
}
uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaperdisplay_obj_t* self) {
+ if (self->core.last_refresh == 0) {
+ return 0;
+ }
// Refresh at seconds per frame rate.
uint32_t elapsed_time = ticks_ms - self->core.last_refresh;
if (elapsed_time > self->milliseconds_per_frame) {
@@ -343,6 +346,13 @@ void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self) {
}
void release_epaperdisplay(displayio_epaperdisplay_obj_t* self) {
+ if (self->refreshing) {
+ wait_for_busy(self);
+ self->refreshing = false;
+ // Run stop sequence but don't wait for busy because busy is set when sleeping.
+ send_command_sequence(self, false, self->stop_sequence, self->stop_sequence_len);
+ }
+
release_display_core(&self->core);
if (self->busy.base.type == &digitalio_digitalinout_type) {
common_hal_digitalio_digitalinout_deinit(&self->busy);
@@ -352,3 +362,20 @@ void release_epaperdisplay(displayio_epaperdisplay_obj_t* self) {
void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self) {
displayio_display_core_collect_ptrs(&self->core);
}
+
+bool maybe_refresh_epaperdisplay(void) {
+ for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+ if (displays[i].epaper_display.base.type != &displayio_epaperdisplay_type ||
+ displays[i].epaper_display.core.current_group != &circuitpython_splash) {
+ // Skip regular displays and those not showing the splash.
+ continue;
+ }
+ displayio_epaperdisplay_obj_t* display = &displays[i].epaper_display;
+ if (common_hal_displayio_epaperdisplay_get_time_to_refresh(display) != 0) {
+ return false;
+ }
+ return common_hal_displayio_epaperdisplay_refresh(display);
+ }
+ // Return true if no ePaper displays are available to pretend it was updated.
+ return true;
+}
diff --git a/shared-module/displayio/EPaperDisplay.h b/shared-module/displayio/EPaperDisplay.h
index 88b5ebfaf..2be2add4b 100644
--- a/shared-module/displayio/EPaperDisplay.h
+++ b/shared-module/displayio/EPaperDisplay.h
@@ -60,6 +60,7 @@ typedef struct {
void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self);
void release_epaperdisplay(displayio_epaperdisplay_obj_t* self);
+bool maybe_refresh_epaperdisplay(void);
void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self);
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index 0a3b1fd10..a41884c78 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -54,6 +54,19 @@ void displayio_background(void) {
}
void common_hal_displayio_release_displays(void) {
+ // Release displays before busses so that they can send any final commands to turn the display
+ // off properly.
+ for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+ mp_const_obj_t display_type = displays[i].display.base.type;
+ if (display_type == NULL || display_type == &mp_type_NoneType) {
+ continue;
+ } else if (display_type == &displayio_display_type) {
+ release_display(&displays[i].display);
+ } else if (display_type == &displayio_epaperdisplay_type) {
+ release_epaperdisplay(&displays[i].epaper_display);
+ }
+ displays[i].display.base.type = &mp_type_NoneType;
+ }
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 || bus_type == &mp_type_NoneType) {
@@ -67,17 +80,6 @@ void common_hal_displayio_release_displays(void) {
}
displays[i].fourwire_bus.base.type = &mp_type_NoneType;
}
- for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
- mp_const_obj_t display_type = displays[i].display.base.type;
- if (display_type == NULL || display_type == &mp_type_NoneType) {
- continue;
- } else if (display_type == &displayio_display_type) {
- release_display(&displays[i].display);
- } else if (display_type == &displayio_epaperdisplay_type) {
- release_epaperdisplay(&displays[i].epaper_display);
- }
- displays[i].display.base.type = &mp_type_NoneType;
- }
supervisor_stop_terminal();
}
diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c
index f8a8d8fea..24d8ab51f 100644
--- a/shared-module/displayio/display_core.c
+++ b/shared-module/displayio/display_core.c
@@ -52,6 +52,7 @@ void displayio_display_core_construct(displayio_display_core_t* self,
self->current_group = NULL;
self->colstart = colstart;
self->rowstart = rowstart;
+ self->last_refresh = 0;
if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) {
self->bus_reset = common_hal_displayio_parallelbus_reset;
@@ -140,7 +141,7 @@ bool displayio_display_core_show(displayio_display_core_t* self, displayio_group
if (!circuitpython_splash.in_group) {
root_group = &circuitpython_splash;
} else if (self->current_group == &circuitpython_splash) {
- return false;
+ return true;
}
}
if (root_group == self->current_group) {