From 93afc71e2e17530e51da924eaeb8332dbc6664fe Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 13 Nov 2020 07:49:01 +0800 Subject: [PATCH] Show "sleeping" on eink while in deep sleep --- src/graphics/Screen.cpp | 46 +++++++++++++++++++++++++++++++++++------ src/graphics/Screen.h | 6 ++++++ src/sleep.cpp | 2 +- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 3e53d130..75aa40ae 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -85,13 +85,16 @@ static uint16_t displayWidth, displayHeight; #define SCREEN_TRANSITION_MSECS 300 #endif -static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +/** + * Draw the icon with extra info printed around the corners + */ +static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { // draw an xbm image. // Please note that everything that should be transitioned // needs to be drawn relative to x and y - // draw centered left to right and centered above the one line of app text + // draw centered icon left to right and centered above the one line of app text display->drawXbm(x + (SCREEN_WIDTH - icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - icon_height) / 2 + 2, icon_width, icon_height, (const uint8_t *)icon_bits); @@ -101,15 +104,31 @@ static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int1 display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title); display->setFont(FONT_SMALL); - const char *region = myRegion ? myRegion->name : NULL; - if (region) - display->drawString(x + 0, y + 0, region); + // Draw region in upper left + if (upperMsg) + display->drawString(x + 0, y + 0, upperMsg); + // Draw version in upper right char buf[16]; snprintf(buf, sizeof(buf), "%s", xstr(APP_VERSION)); // Note: we don't bother printing region or now, it makes the string too long display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf); screen->forceDisplay(); + + // FIXME - draw serial # somewhere? +} + +static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + // Draw region in upper left + const char *region = myRegion ? myRegion->name : NULL; + drawIconScreen(region, display, state, x, y); +} + +/// Used on eink displays while in deep sleep +static void drawSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + drawIconScreen("Sleeping...", display, state, x, y); } static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) @@ -600,6 +619,21 @@ Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue cmdQueue.setReader(this); } +/** + * Prepare the display for the unit going to the lowest power mode possible. Most screens will just + * poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code + */ +void Screen::doDeepSleep() +{ +#ifdef HAS_EINK + static FrameCallback sleepFrames[] = {drawSleepScreen}; + static const int sleepFrameCount = sizeof(sleepFrames) / sizeof(sleepFrames[0]); + ui.setFrames(sleepFrames, sleepFrameCount); + ui.update(); +#endif + setOn(false); +} + void Screen::handleSetOn(bool on) { if (!useDisplay) @@ -636,7 +670,7 @@ void Screen::setup() displayWidth = dispdev.width(); displayHeight = dispdev.height(); - ui.setTimePerTransition(SCREEN_TRANSITION_MSECS); + ui.setTimePerTransition(SCREEN_TRANSITION_MSECS); ui.setIndicatorPosition(BOTTOM); // Defines where the first frame is located in the bar. diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 5539dcc7..d0bf6228 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -99,6 +99,12 @@ class Screen : public concurrency::OSThread enqueueCmd(ScreenCmd{.cmd = on ? Cmd::SET_ON : Cmd::SET_OFF}); } + /** + * Prepare the display for the unit going to the lowest power mode possible. Most screens will just + * poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code + */ + void doDeepSleep(); + /// Handles a button press. void onPress() { enqueueCmd(ScreenCmd{.cmd = Cmd::ON_PRESS}); } diff --git a/src/sleep.cpp b/src/sleep.cpp index e2cafe57..160479d5 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -149,7 +149,7 @@ void doDeepSleep(uint64_t msecToWake) waitEnterSleep(); notifyDeepSleep.notifyObservers(NULL); - screen->setOn(false); // datasheet says this will draw only 10ua + screen->doDeepSleep(); // datasheet says this will draw only 10ua nodeDB.saveToDisk();