Refresh ePaper displays once code.py is done running

This commit is contained in:
Scott Shawcroft 2019-08-20 21:35:42 -07:00
parent 36a23e0fe3
commit 24b30965c4
No known key found for this signature in database
GPG Key ID: 9349BC7E64B1921E
6 changed files with 52 additions and 13 deletions

8
main.c
View File

@ -253,6 +253,7 @@ bool run_code_py(safe_mode_t safe_mode) {
} }
bool serial_connected_before_animation = false; bool serial_connected_before_animation = false;
bool refreshed_epaper_display = false;
rgb_status_animation_t animation; rgb_status_animation_t animation;
prep_rgb_status_animation(&result, found_main, safe_mode, &animation); prep_rgb_status_animation(&result, found_main, safe_mode, &animation);
while (true) { while (true) {
@ -290,6 +291,13 @@ bool run_code_py(safe_mode_t safe_mode) {
} }
serial_connected_before_animation = serial_connected(); 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); tick_rgb_status_animation(&animation);
} }
} }

View File

@ -77,7 +77,7 @@
//| //|
//| Releases any actively used displays so their busses and pins can be used again. This will also //| 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 //| 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 //| 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. //| initialization so the display is active as long as possible.

View File

@ -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) { 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. // Refresh at seconds per frame rate.
uint32_t elapsed_time = ticks_ms - self->core.last_refresh; uint32_t elapsed_time = ticks_ms - self->core.last_refresh;
if (elapsed_time > self->milliseconds_per_frame) { 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) { 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); release_display_core(&self->core);
if (self->busy.base.type == &digitalio_digitalinout_type) { if (self->busy.base.type == &digitalio_digitalinout_type) {
common_hal_digitalio_digitalinout_deinit(&self->busy); 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) { void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self) {
displayio_display_core_collect_ptrs(&self->core); 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;
}

View File

@ -60,6 +60,7 @@ typedef struct {
void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self); void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self);
void release_epaperdisplay(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); void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self);

View File

@ -54,6 +54,19 @@ void displayio_background(void) {
} }
void common_hal_displayio_release_displays(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++) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type;
if (bus_type == NULL || bus_type == &mp_type_NoneType) { 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; 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(); supervisor_stop_terminal();
} }

View File

@ -52,6 +52,7 @@ void displayio_display_core_construct(displayio_display_core_t* self,
self->current_group = NULL; self->current_group = NULL;
self->colstart = colstart; self->colstart = colstart;
self->rowstart = rowstart; self->rowstart = rowstart;
self->last_refresh = 0;
if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) {
self->bus_reset = common_hal_displayio_parallelbus_reset; 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) { if (!circuitpython_splash.in_group) {
root_group = &circuitpython_splash; root_group = &circuitpython_splash;
} else if (self->current_group == &circuitpython_splash) { } else if (self->current_group == &circuitpython_splash) {
return false; return true;
} }
} }
if (root_group == self->current_group) { if (root_group == self->current_group) {