make eink screen look nicer

1.2-legacy
Kevin Hester 2020-10-15 15:56:38 +08:00
rodzic 4db0c4a563
commit 649a120fe0
4 zmienionych plików z 55 dodań i 8 usunięć

Wyświetl plik

@ -54,8 +54,10 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
// FIXME quick hack to limit drawing to a very slow rate
uint32_t lastDrawMsec;
// Write the buffer to the display memory
void EInkDisplay::display(void)
/**
* Force a display update if we haven't drawn within the specified msecLimit
*/
bool EInkDisplay::forceDisplay(uint32_t msecLimit)
{
// No need to grab this lock because we are on our own SPI bus
// concurrency::LockGuard g(spiLock);
@ -63,7 +65,7 @@ void EInkDisplay::display(void)
uint32_t now = millis();
uint32_t sinceLast = now - lastDrawMsec;
if (framePtr && (sinceLast > 60 * 1000 || lastDrawMsec == 0)) {
if (framePtr && (sinceLast > msecLimit || lastDrawMsec == 0)) {
lastDrawMsec = now;
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
@ -86,9 +88,24 @@ void EInkDisplay::display(void)
// Put screen to sleep to save power
ePaper.Sleep();
return true;
} else {
// DEBUG_MSG("Skipping eink display\n");
return false;
}
}
// Write the buffer to the display memory
void EInkDisplay::display(void)
{
// We don't allow regular 'dumb' display() calls to draw on eink until we've shown
// at least one forceDisplay() keyframe. This prevents flashing when we should the critical
// bootscreen (that we want to look nice)
if (lastDrawMsec)
if (forceDisplay(slowUpdateMsec)) // Show the first screen a few seconds after boot, then slower
slowUpdateMsec = 5 * 60 * 1000;
}
// Send a command to the display (low level function)
void EInkDisplay::sendCommand(uint8_t com)
{

Wyświetl plik

@ -14,15 +14,26 @@
*/
class EInkDisplay : public OLEDDisplay
{
/// How often should we update the display, at first we do an update 5 secs after boot,
/// thereafter we do once per 5 minutes
uint32_t slowUpdateMsec = 5 * 1000;
public:
/* constructor
FIXME - the parameters are not used, just a temporary hack to keep working like the old displays
*/
EInkDisplay(uint8_t address, int sda, int scl);
// Write the buffer to the display memory
// Write the buffer to the display memory (for eink we only do this occasionally)
virtual void display(void);
/**
* Force a display update if we haven't drawn within the specified msecLimit
*
* @return true if we did draw the screen
*/
bool forceDisplay(uint32_t msecLimit = 2000);
protected:
// the header size of the buffer used, e.g. for the SPI command header
virtual int getBufferOffset(void) { return 0; }
@ -33,3 +44,5 @@ class EInkDisplay : public OLEDDisplay
// Connect to the display
virtual bool connect();
};

Wyświetl plik

@ -72,7 +72,10 @@ static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int1
// draw an xbm image.
// Please note that everything that should be transitioned
// needs to be drawn relative to x and y
display->drawXbm(x + 32, y, icon_width, icon_height, (const uint8_t *)icon_bits);
// draw centered 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_16 - icon_height) / 2, icon_width,
icon_height, (const uint8_t *)icon_bits);
display->setFont(ArialMT_Plain_16);
display->setTextAlignment(TEXT_ALIGN_CENTER);
@ -85,6 +88,7 @@ static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int1
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(SCREEN_WIDTH - 20, 0, buf);
screen->forceDisplay();
}
static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
@ -570,7 +574,8 @@ void _screen_header()
}
#endif
Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), ui(&dispdev) {
Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), ui(&dispdev)
{
cmdQueue.setReader(this);
}
@ -658,6 +663,14 @@ void Screen::setup()
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
}
void Screen::forceDisplay()
{
// Nasty hack to force epaper updates for 'key' frames. FIXME, cleanup.
#ifdef HAS_EINK
dispdev.forceDisplay();
#endif
}
int32_t Screen::runOnce()
{
// If we don't have a screen, don't ever spend any CPU for us.
@ -722,6 +735,7 @@ int32_t Screen::runOnce()
DEBUG_MSG("Setting idle framerate\n");
targetFramerate = IDLE_FRAMERATE;
ui.setTargetFPS(targetFramerate);
forceDisplay();
}
// While showing the bootscreen or Bluetooth pair screen all of our

Wyświetl plik

@ -180,6 +180,9 @@ class Screen : public concurrency::OSThread
int handleStatusUpdate(const meshtastic::Status *arg);
/// Used to force (super slow) eink displays to draw critical frames
void forceDisplay();
protected:
/// Updates the UI.
//