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 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);
}
}

View File

@ -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.

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) {
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;
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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) {