Skip to content

Commit

Permalink
Support async full refresh in meshtastic/firmware
Browse files Browse the repository at this point in the history
  • Loading branch information
todd-herbert committed Mar 6, 2024
1 parent f27cf38 commit 8234d19
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/GxEPD2_BW.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
#ifndef _GxEPD2_BW_H_
#define _GxEPD2_BW_H_

// This version of meshtastic/GxEPD2 has been modified (defiled) to allow nextPage() to run full refreshes asynchronously
// This macro ensures that the relevant modifications to meshtastic/firmware will only run with a correctly modified version of GxEPD2
// Note: this async behavior is unrelated to the callback system implemented in newer versions of ZinggJM/GxEPD2
#define HAS_EINK_ASYNCFULL

// uncomment next line to use class GFX of library GFX_Root instead of Adafruit_GFX
//#include <GFX.h>

Expand Down Expand Up @@ -239,6 +244,16 @@ class GxEPD2_BW : public GxEPD2_GFX_BASE_CLASS
_second_phase = false;
}

// Transplanted from nextPage(), non-paged, full refresh
// This is the code which runs after the refresh() call
// Method is called by meshtastic/firmware, once polling GxEPD2_BW::isBusy() reports that the physical refresh is complete
void endAsyncFull() {
if (epd2.hasFastPartialUpdate) {
epd2.writeImageAgain(_buffer, 0, 0, WIDTH, HEIGHT);
}
epd2.powerOff();
}

bool nextPage()
{
if (1 == _pages)
Expand All @@ -258,12 +273,16 @@ class GxEPD2_BW : public GxEPD2_GFX_BASE_CLASS
{
epd2.writeImageForFullRefresh(_buffer, 0, 0, WIDTH, HEIGHT);
epd2.refresh(false);
#if defined(USE_EINK_DYNAMICDISPLAY) // This macro defined in meshtastic/firmware
// -- meshtastic: moved to endAsyncFull() --
#else
if (epd2.hasFastPartialUpdate)
{
epd2.writeImageAgain(_buffer, 0, 0, WIDTH, HEIGHT);
//epd2.refresh(true); // not needed
}
epd2.powerOff();
#endif
}
return false;
}
Expand Down
20 changes: 20 additions & 0 deletions src/GxEPD2_EPD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ void GxEPD2_EPD::_reset()

void GxEPD2_EPD::_waitWhileBusy(const char* comment, uint16_t busy_time)
{
// For full refreshes, meshtastic/firmare will poll GxEPD2_EPD::isBusy() instead of waiting here
if (_isUpdatingFull(comment))
return;

if (_busy >= 0)
{
delay(1); // add some margin to become active
Expand Down Expand Up @@ -241,3 +245,19 @@ void GxEPD2_EPD::_endTransfer()
if (_cs >= 0) digitalWrite(_cs, HIGH);
_spi.endTransaction();
}

// Polled by meshtastic/firmware, during async full-refresh
bool GxEPD2_EPD::isBusy() {
return (digitalRead(_busy) == _busy_level);
}

// Used to skip _waitWhileBusy(), for meshtastic async
bool GxEPD2_EPD::_isUpdatingFull(const char* comment) {
// On first update, a fast-refresh might also clear screen using a full-refresh
// If meshtastic/firmware asked for fast-refresh, it will expect this full-refresh to block. So: force that to happen
if (_initial_refresh)
return false;

// True if comment matches
return ( strcmp(comment, "_Update_Full") == 0 );
}
2 changes: 2 additions & 0 deletions src/GxEPD2_EPD.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class GxEPD2_EPD
{
return (a > b ? a : b);
};
bool isBusy(); // Used in meshtastic/firmware, to poll after nextPage(), for async full refresh
protected:
void _reset();
void _waitWhileBusy(const char* comment = 0, uint16_t busy_time = 5000);
Expand All @@ -104,6 +105,7 @@ class GxEPD2_EPD
void _startTransfer();
void _transfer(uint8_t value);
void _endTransfer();
bool _isUpdatingFull(const char* comment); // Meshtastic: Determine if _waitWhileBusy() should be skipped (for async), by comparing the comment string..
protected:
int8_t _cs, _dc, _rst, _busy, _busy_level;
uint32_t _busy_timeout;
Expand Down
1 change: 1 addition & 0 deletions src/epd/GxEPD2_213_FC1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void GxEPD2_213_FC1::clearScreen(uint8_t value)
_writeScreenBuffer(0x13, value); // Clear "NEW" (red) mem
_writeScreenBuffer(0x10, value); // Clear "OLD" (black) mem
refresh(false); // Full refresh
_PowerOff();
_initial_write = false;
_initial_refresh = false;
}
Expand Down

0 comments on commit 8234d19

Please sign in to comment.