Преглед изворни кода

Merge pull request #187 from ZinggJM/work_in_progress

Version 1.6.8
ZinggJM пре 7 месеци
родитељ
комит
1ae66efc01
100 измењених фајлова са 1521 додато и 651 уклоњено
  1. 5 1
      README.md
  2. 47 1
      examples/GxEPD2_Example/GxEPD2_Example.ino
  3. 1 1
      library.properties
  4. 6 6
      src/GxEPD2_7C.h
  5. 11 0
      src/epd/GxEPD2_102.cpp
  6. 3 0
      src/epd/GxEPD2_102.h
  7. 11 0
      src/epd/GxEPD2_1160_T91.cpp
  8. 3 0
      src/epd/GxEPD2_1160_T91.h
  9. 30 8
      src/epd/GxEPD2_1248.cpp
  10. 6 0
      src/epd/GxEPD2_1248.h
  11. 36 25
      src/epd/GxEPD2_150_BN.cpp
  12. 3 0
      src/epd/GxEPD2_150_BN.h
  13. 24 2
      src/epd/GxEPD2_154.cpp
  14. 6 0
      src/epd/GxEPD2_154.h
  15. 11 0
      src/epd/GxEPD2_154_D67.cpp
  16. 3 0
      src/epd/GxEPD2_154_D67.h
  17. 11 0
      src/epd/GxEPD2_154_M09.cpp
  18. 3 0
      src/epd/GxEPD2_154_M09.h
  19. 11 0
      src/epd/GxEPD2_154_M10.cpp
  20. 3 0
      src/epd/GxEPD2_154_M10.h
  21. 24 2
      src/epd/GxEPD2_154_T8.cpp
  22. 6 0
      src/epd/GxEPD2_154_T8.h
  23. 24 2
      src/epd/GxEPD2_213.cpp
  24. 6 0
      src/epd/GxEPD2_213.h
  25. 11 0
      src/epd/GxEPD2_213_B72.cpp
  26. 3 0
      src/epd/GxEPD2_213_B72.h
  27. 11 0
      src/epd/GxEPD2_213_B73.cpp
  28. 3 0
      src/epd/GxEPD2_213_B73.h
  29. 11 0
      src/epd/GxEPD2_213_B74.cpp
  30. 3 0
      src/epd/GxEPD2_213_B74.h
  31. 11 0
      src/epd/GxEPD2_213_BN.cpp
  32. 3 0
      src/epd/GxEPD2_213_BN.h
  33. 24 2
      src/epd/GxEPD2_213_M21.cpp
  34. 6 0
      src/epd/GxEPD2_213_M21.h
  35. 11 0
      src/epd/GxEPD2_213_T5D.cpp
  36. 3 0
      src/epd/GxEPD2_213_T5D.h
  37. 24 2
      src/epd/GxEPD2_213_flex.cpp
  38. 6 0
      src/epd/GxEPD2_213_flex.h
  39. 24 2
      src/epd/GxEPD2_260.cpp
  40. 6 0
      src/epd/GxEPD2_260.h
  41. 24 2
      src/epd/GxEPD2_260_M01.cpp
  42. 6 0
      src/epd/GxEPD2_260_M01.h
  43. 11 0
      src/epd/GxEPD2_266_BN.cpp
  44. 3 0
      src/epd/GxEPD2_266_BN.h
  45. 11 0
      src/epd/GxEPD2_270.cpp
  46. 3 0
      src/epd/GxEPD2_270.h
  47. 24 2
      src/epd/GxEPD2_290.cpp
  48. 6 0
      src/epd/GxEPD2_290.h
  49. 11 0
      src/epd/GxEPD2_290_BS.cpp
  50. 3 0
      src/epd/GxEPD2_290_BS.h
  51. 11 0
      src/epd/GxEPD2_290_I6FD.cpp
  52. 3 0
      src/epd/GxEPD2_290_I6FD.h
  53. 24 2
      src/epd/GxEPD2_290_M06.cpp
  54. 6 0
      src/epd/GxEPD2_290_M06.h
  55. 24 2
      src/epd/GxEPD2_290_T5.cpp
  56. 6 0
      src/epd/GxEPD2_290_T5.h
  57. 11 0
      src/epd/GxEPD2_290_T5D.cpp
  58. 3 0
      src/epd/GxEPD2_290_T5D.h
  59. 11 0
      src/epd/GxEPD2_290_T94.cpp
  60. 3 0
      src/epd/GxEPD2_290_T94.h
  61. 11 0
      src/epd/GxEPD2_290_T94_V2.cpp
  62. 3 0
      src/epd/GxEPD2_290_T94_V2.h
  63. 11 0
      src/epd/GxEPD2_370_TC1.cpp
  64. 3 0
      src/epd/GxEPD2_370_TC1.h
  65. 24 2
      src/epd/GxEPD2_371.cpp
  66. 6 0
      src/epd/GxEPD2_371.h
  67. 24 2
      src/epd/GxEPD2_420.cpp
  68. 6 0
      src/epd/GxEPD2_420.h
  69. 24 2
      src/epd/GxEPD2_420_M01.cpp
  70. 6 0
      src/epd/GxEPD2_420_M01.h
  71. 24 2
      src/epd/GxEPD2_583_T8.cpp
  72. 6 0
      src/epd/GxEPD2_583_T8.h
  73. 24 2
      src/epd/GxEPD2_750_T7.cpp
  74. 6 0
      src/epd/GxEPD2_750_T7.h
  75. 258 284
      src/epd7c/GxEPD2_730c_GDEP073E01.cpp
  76. 3 2
      src/epd7c/GxEPD2_730c_GDEP073E01.h
  77. 266 288
      src/epd7c/GxEPD2_730c_GDEY073D46.cpp
  78. 4 5
      src/epd7c/GxEPD2_730c_GDEY073D46.h
  79. 11 0
      src/gdem/GxEPD2_1020_GDEM102T91.cpp
  80. 3 0
      src/gdem/GxEPD2_1020_GDEM102T91.h
  81. 11 0
      src/gdem/GxEPD2_1085_GDEM1085T51.cpp
  82. 3 0
      src/gdem/GxEPD2_1085_GDEM1085T51.h
  83. 11 0
      src/gdem/GxEPD2_1330_GDEM133T91.cpp
  84. 3 0
      src/gdem/GxEPD2_1330_GDEM133T91.h
  85. 11 0
      src/gdem/GxEPD2_397_GDEM0397T81.cpp
  86. 3 0
      src/gdem/GxEPD2_397_GDEM0397T81.h
  87. 11 0
      src/gdeq/GxEPD2_310_GDEQ031T10.cpp
  88. 3 0
      src/gdeq/GxEPD2_310_GDEQ031T10.h
  89. 11 0
      src/gdeq/GxEPD2_426_GDEQ0426T82.cpp
  90. 3 0
      src/gdeq/GxEPD2_426_GDEQ0426T82.h
  91. 11 0
      src/gdeq/GxEPD2_583_GDEQ0583T31.cpp
  92. 3 0
      src/gdeq/GxEPD2_583_GDEQ0583T31.h
  93. 11 0
      src/gdey/GxEPD2_154_GDEY0154D67.cpp
  94. 3 0
      src/gdey/GxEPD2_154_GDEY0154D67.h
  95. 11 0
      src/gdey/GxEPD2_213_GDEY0213B74.cpp
  96. 3 0
      src/gdey/GxEPD2_213_GDEY0213B74.h
  97. 11 0
      src/gdey/GxEPD2_266_GDEY0266T90.cpp
  98. 3 0
      src/gdey/GxEPD2_266_GDEY0266T90.h
  99. 11 0
      src/gdey/GxEPD2_270_GDEY027T91.cpp
  100. 3 0
      src/gdey/GxEPD2_270_GDEY027T91.h

+ 5 - 1
README.md

@@ -173,7 +173,11 @@
 - Let me know about interesting panels that fall into this category.
 - Let me know about interesting panels that fall into this category.
 - I occasionally buy new panels, but adding support will take as much time as needed.
 - I occasionally buy new panels, but adding support will take as much time as needed.
 
 
-### Version 1.6.7
+### Version 1.6.8
+- added methods writeImageToPrevious and writeImagePartToPrevious to b/w driver classes
+- added partial update support to GDEP073E01
+- added partial window addressing to GDEY073D46, partial refresh not usable
+#### Version 1.6.7
 - added support for GDEW075Z08 fast b/w refresh in new class GxEPD2_750c_GDEW075Z08
 - added support for GDEW075Z08 fast b/w refresh in new class GxEPD2_750c_GDEW075Z08
 - GxEPD2_750c_GDEW075Z08 uses a b/w waveform written to registers, none available in OTP
 - GxEPD2_750c_GDEW075Z08 uses a b/w waveform written to registers, none available in OTP
 - added support for GDEY075Z08 fast b/w refresh in new class GxEPD2_750c_GDEY075Z08
 - added support for GDEY075Z08 fast b/w refresh in new class GxEPD2_750c_GDEY075Z08

+ 47 - 1
examples/GxEPD2_Example/GxEPD2_Example.ino

@@ -248,7 +248,7 @@ void setup()
     draw7colors();
     draw7colors();
     delay(4000);
     delay(4000);
     display.epd2.drawNativeColors(); delay(2000);
     display.epd2.drawNativeColors(); delay(2000);
-    //return;
+    //display.powerOff(); return;
   }
   }
 #endif
 #endif
   if (display.epd2.hasPartialUpdate)
   if (display.epd2.hasPartialUpdate)
@@ -1619,6 +1619,30 @@ void drawBitmaps800x480()
       display.refresh(false); // full update
       display.refresh(false); // full update
     }
     }
   }
   }
+#if defined(ESP32) && false
+  if (display.epd2.panel == GxEPD2::GDEP073E01)
+  {
+    int16_t wp = display.epd2.WIDTH / 5;
+    int16_t hp = display.epd2.HEIGHT / 5;
+    int16_t n = 0;
+    for (int16_t k = 0; k < 3; k++)
+    {
+      display.writeScreenBuffer();
+      for (int16_t i = 0; i < 5; i++)
+      {
+        for (int16_t j = 0; j < 5; j++)
+        {
+          if ((n++ % 2) || (k == 2))
+          {
+            display.epd2.writeImagePart(Bitmap800x480_1, 0, i * wp, j * hp, 800, 480, i * wp, j * hp, wp, hp, false, false, true);
+          }
+        }
+      }
+      display.refresh(false);
+      delay(2000);
+    }
+  }
+#endif
 }
 }
 #endif
 #endif
 
 
@@ -2080,6 +2104,28 @@ void drawBitmaps3c800x480()
       delay(2000);
       delay(2000);
     }
     }
   }
   }
+  if ((display.epd2.panel == GxEPD2::GDEP073E01) && false)
+  {
+    int16_t wp = display.epd2.WIDTH / 5;
+    int16_t hp = display.epd2.HEIGHT / 5;
+    int16_t n = 0;
+    for (int16_t k = 0; k < 3; k++)
+    {
+      display.writeScreenBuffer();
+      for (int16_t i = 0; i < 5; i++)
+      {
+        for (int16_t j = 0; j < 5; j++)
+        {
+          if ((n++ % 2) || (k == 2))
+          {
+            display.epd2.writeImagePart(Bitmap3c800x480_1_black, Bitmap3c800x480_1_red, i * wp, j * hp, 800, 480, i * wp, j * hp, wp, hp, true, false, true);
+          }
+        }
+      }
+      display.refresh(false);
+      delay(2000);
+    }
+  }
 }
 }
 #endif
 #endif
 
 

+ 1 - 1
library.properties

@@ -1,5 +1,5 @@
 name=GxEPD2
 name=GxEPD2
-version=1.6.7
+version=1.6.8
 author=Jean-Marc Zingg
 author=Jean-Marc Zingg
 maintainer=Jean-Marc Zingg
 maintainer=Jean-Marc Zingg
 sentence=Arduino Display Library for SPI E-Paper displays from Dalian Good Display and Waveshare. 
 sentence=Arduino Display Library for SPI E-Paper displays from Dalian Good Display and Waveshare. 

+ 6 - 6
src/GxEPD2_7C.h

@@ -218,8 +218,8 @@ class GxEPD2_7C : public GxEPD2_GFX_BASE_CLASS
     }
     }
 
 
     // setPartialWindow, use parameters according to actual rotation.
     // setPartialWindow, use parameters according to actual rotation.
-    // x and w should be multiple of 8, for rotation 0 or 2,
-    // y and h should be multiple of 8, for rotation 1 or 3,
+    // x and w should be multiple of 4, for rotation 0 or 2,
+    // y and h should be multiple of 4, for rotation 1 or 3,
     // else window is increased as needed,
     // else window is increased as needed,
     // this is an addressing limitation of the e-paper controllers
     // this is an addressing limitation of the e-paper controllers
     void setPartialWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
     void setPartialWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
@@ -231,10 +231,10 @@ class GxEPD2_7C : public GxEPD2_GFX_BASE_CLASS
       _pw_h = gx_uint16_min(h, height() - _pw_y);
       _pw_h = gx_uint16_min(h, height() - _pw_y);
       _rotate(_pw_x, _pw_y, _pw_w, _pw_h);
       _rotate(_pw_x, _pw_y, _pw_w, _pw_h);
       _using_partial_mode = true;
       _using_partial_mode = true;
-      // make _pw_x, _pw_w multiple of 2
-      _pw_w += _pw_x % 2;
-      if (_pw_w % 2 > 0) _pw_w += 2 - _pw_w % 2;
-      _pw_x -= _pw_x % 2;
+      // make _pw_x, _pw_w multiple of 4, required by Spectra6 controller
+      _pw_w += _pw_x % 4;
+      if (_pw_w % 4 > 0) _pw_w += 4 - _pw_w % 4;
+      _pw_x -= _pw_x % 4;
     }
     }
 
 
     void firstPage()
     void firstPage()

+ 11 - 0
src/epd/GxEPD2_102.cpp

@@ -59,6 +59,11 @@ void GxEPD2_102::writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_102::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_102::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_102::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -116,6 +121,12 @@ void GxEPD2_102::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_102::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_102::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_102::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                  int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                  int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_102.h

@@ -42,8 +42,11 @@ class GxEPD2_102 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_1160_T91.cpp

@@ -70,6 +70,11 @@ void GxEPD2_1160_T91::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_1160_T91::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_1160_T91::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_1160_T91::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -130,6 +135,12 @@ void GxEPD2_1160_T91::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_1160_T91::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_1160_T91::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_1160_T91::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                       int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                       int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_1160_T91.h

@@ -41,8 +41,11 @@ class GxEPD2_1160_T91 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 30 - 8
src/epd/GxEPD2_1248.cpp

@@ -134,24 +134,46 @@ void GxEPD2_1248::writeScreenBufferAgain(uint8_t value)
 }
 }
 
 
 void GxEPD2_1248::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_1248::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_1248::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_1248::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
-  S2.writeImagePart(0x13, bitmap, 0, 0, w, h, x, y, w, h, invert, mirror_y, pgm);
-  M2.writeImagePart(0x13, bitmap, 0, 0, w, h, x - S2.WIDTH, y, w, h, invert, mirror_y, pgm);
-  M1.writeImagePart(0x13, bitmap, 0, 0, w, h, x, y - S2.HEIGHT, w, h, invert, mirror_y, pgm);
-  S1.writeImagePart(0x13, bitmap, 0, 0, w, h, x - M1.WIDTH, y - M2.HEIGHT, w, h, invert, mirror_y, pgm);
+  S2.writeImagePart(command, bitmap, 0, 0, w, h, x, y, w, h, invert, mirror_y, pgm);
+  M2.writeImagePart(command, bitmap, 0, 0, w, h, x - S2.WIDTH, y, w, h, invert, mirror_y, pgm);
+  M1.writeImagePart(command, bitmap, 0, 0, w, h, x, y - S2.HEIGHT, w, h, invert, mirror_y, pgm);
+  S1.writeImagePart(command, bitmap, 0, 0, w, h, x - M1.WIDTH, y - M2.HEIGHT, w, h, invert, mirror_y, pgm);
 }
 }
 
 
 void GxEPD2_1248::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_1248::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_1248::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_1248::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                  int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                  int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
-  S2.writeImagePart(0x13, bitmap, x_part, y_part, w, h, x, y, w, h, invert, mirror_y, pgm);
-  M2.writeImagePart(0x13, bitmap, x_part, y_part, w, h, x - S2.WIDTH, y, w, h, invert, mirror_y, pgm);
-  M1.writeImagePart(0x13, bitmap, x_part, y_part, w, h, x, y - S2.HEIGHT, w, h, invert, mirror_y, pgm);
-  S1.writeImagePart(0x13, bitmap, x_part, y_part, w, h, x - M1.WIDTH, y - M2.HEIGHT, w, h, invert, mirror_y, pgm);
+  S2.writeImagePart(command, bitmap, x_part, y_part, w, h, x, y, w, h, invert, mirror_y, pgm);
+  M2.writeImagePart(command, bitmap, x_part, y_part, w, h, x - S2.WIDTH, y, w, h, invert, mirror_y, pgm);
+  M1.writeImagePart(command, bitmap, x_part, y_part, w, h, x, y - S2.HEIGHT, w, h, invert, mirror_y, pgm);
+  S1.writeImagePart(command, bitmap, x_part, y_part, w, h, x - M1.WIDTH, y - M2.HEIGHT, w, h, invert, mirror_y, pgm);
 }
 }
 
 
 void GxEPD2_1248::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_1248::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)

+ 6 - 0
src/epd/GxEPD2_1248.h

@@ -54,8 +54,11 @@ class GxEPD2_1248 : public GxEPD2_EPD
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -79,6 +82,9 @@ class GxEPD2_1248 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _reset();
     void _reset();
     void _initSPI();
     void _initSPI();
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);

+ 36 - 25
src/epd/GxEPD2_150_BN.cpp

@@ -70,6 +70,11 @@ void GxEPD2_150_BN::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_150_BN::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_150_BN::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_150_BN::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -118,20 +123,26 @@ void GxEPD2_150_BN::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t
 }
 }
 
 
 void GxEPD2_150_BN::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_150_BN::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
-                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+                                   int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
 void GxEPD2_150_BN::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_150_BN::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
-    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+                                        int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set previous
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set previous
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_150_BN::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_150_BN::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_150_BN::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
-                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
@@ -193,7 +204,7 @@ void GxEPD2_150_BN::writeImage(const uint8_t* black, const uint8_t* color, int16
 }
 }
 
 
 void GxEPD2_150_BN::writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_150_BN::writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
-                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+                                   int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (black)
   if (black)
   {
   {
@@ -217,7 +228,7 @@ void GxEPD2_150_BN::drawImage(const uint8_t bitmap[], int16_t x, int16_t y, int1
 }
 }
 
 
 void GxEPD2_150_BN::drawImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_150_BN::drawImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
-                                   int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+                                  int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   refresh(x, y, w, h);
   refresh(x, y, w, h);
@@ -233,7 +244,7 @@ void GxEPD2_150_BN::drawImage(const uint8_t* black, const uint8_t* color, int16_
 }
 }
 
 
 void GxEPD2_150_BN::drawImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_150_BN::drawImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
-                                   int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+                                  int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (black)
   if (black)
   {
   {
@@ -269,7 +280,7 @@ void GxEPD2_150_BN::refresh(int16_t x, int16_t y, int16_t w, int16_t h)
   int16_t y1 = y < 0 ? 0 : y; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
   w1 = x1 + w1 < int16_t(WIDTH) ? w1 : int16_t(WIDTH) - x1; // limit
   w1 = x1 + w1 < int16_t(WIDTH) ? w1 : int16_t(WIDTH) - x1; // limit
   h1 = y1 + h1 < int16_t(HEIGHT) ? h1 : int16_t(HEIGHT) - y1; // limit
   h1 = y1 + h1 < int16_t(HEIGHT) ? h1 : int16_t(HEIGHT) - y1; // limit
-  if ((w1 <= 0) || (h1 <= 0)) return; 
+  if ((w1 <= 0) || (h1 <= 0)) return;
   // make x1, w1 multiple of 8
   // make x1, w1 multiple of 8
   w1 += x1 % 8;
   w1 += x1 % 8;
   if (w1 % 8 > 0) w1 += 8 - w1 % 8;
   if (w1 % 8 > 0) w1 += 8 - w1 % 8;
@@ -360,24 +371,24 @@ void GxEPD2_150_BN::_InitDisplay()
 
 
 const unsigned char GxEPD2_150_BN::lut_partial[] PROGMEM =
 const unsigned char GxEPD2_150_BN::lut_partial[] PROGMEM =
 {
 {
-    0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
 };
 };
 
 
 void GxEPD2_150_BN::_Init_Part()
 void GxEPD2_150_BN::_Init_Part()

+ 3 - 0
src/epd/GxEPD2_150_BN.h

@@ -42,8 +42,11 @@ class GxEPD2_150_BN : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 24 - 2
src/epd/GxEPD2_154.cpp

@@ -81,6 +81,16 @@ void GxEPD2_154::_writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_154::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_154::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_154::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_154::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -98,7 +108,7 @@ void GxEPD2_154::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x24);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -128,6 +138,18 @@ void GxEPD2_154::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
 }
 }
 
 
 void GxEPD2_154::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_154::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                   int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_154::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_154::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -152,7 +174,7 @@ void GxEPD2_154::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x24);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_154.h

@@ -38,8 +38,11 @@ class GxEPD2_154 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -60,6 +63,9 @@ class GxEPD2_154 : public GxEPD2_EPD
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
     void _writeScreenBuffer(uint8_t value);
     void _writeScreenBuffer(uint8_t value);
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 11 - 0
src/epd/GxEPD2_154_D67.cpp

@@ -69,6 +69,11 @@ void GxEPD2_154_D67::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_154_D67::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_154_D67::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_154_D67::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -129,6 +134,12 @@ void GxEPD2_154_D67::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_154_D67::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_154_D67::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_154_D67::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_154_D67.h

@@ -41,8 +41,11 @@ class GxEPD2_154_D67 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_154_M09.cpp

@@ -60,6 +60,11 @@ void GxEPD2_154_M09::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_154_M09::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_154_M09::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_154_M09::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -121,6 +126,12 @@ void GxEPD2_154_M09::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_154_M09::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_154_M09::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_154_M09::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_154_M09.h

@@ -40,8 +40,11 @@ class GxEPD2_154_M09 : public GxEPD2_EPD
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_154_M10.cpp

@@ -55,6 +55,11 @@ void GxEPD2_154_M10::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_154_M10::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_154_M10::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_154_M10::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -110,6 +115,12 @@ void GxEPD2_154_M10::writeImagePart(const uint8_t bitmap[], int16_t x_part, int1
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_154_M10::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_154_M10::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_154_M10::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_154_M10.h

@@ -40,8 +40,11 @@ class GxEPD2_154_M10 : public GxEPD2_EPD
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 24 - 2
src/epd/GxEPD2_154_T8.cpp

@@ -45,6 +45,16 @@ void GxEPD2_154_T8::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_154_T8::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_154_T8::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_154_T8::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_154_T8::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -63,7 +73,7 @@ void GxEPD2_154_T8::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -94,6 +104,18 @@ void GxEPD2_154_T8::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
 }
 }
 
 
 void GxEPD2_154_T8::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_154_T8::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_154_T8::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_154_T8::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -119,7 +141,7 @@ void GxEPD2_154_T8::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_154_T8.h

@@ -39,8 +39,11 @@ class GxEPD2_154_T8 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -61,6 +64,9 @@ class GxEPD2_154_T8 : public GxEPD2_EPD
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();
     void _InitDisplay();
     void _InitDisplay();

+ 24 - 2
src/epd/GxEPD2_213.cpp

@@ -81,6 +81,16 @@ void GxEPD2_213::_writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_213::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -98,7 +108,7 @@ void GxEPD2_213::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x24);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -128,6 +138,18 @@ void GxEPD2_213::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
 }
 }
 
 
 void GxEPD2_213::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -152,7 +174,7 @@ void GxEPD2_213::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x24);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_213.h

@@ -38,8 +38,11 @@ class GxEPD2_213 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -60,6 +63,9 @@ class GxEPD2_213 : public GxEPD2_EPD
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
     void _writeScreenBuffer(uint8_t value);
     void _writeScreenBuffer(uint8_t value);
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setRamEntryWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setRamEntryWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setRamArea(uint16_t xs, uint16_t xe, uint16_t ys, uint16_t ye);
     void _setRamArea(uint16_t xs, uint16_t xe, uint16_t ys, uint16_t ye);

+ 11 - 0
src/epd/GxEPD2_213_B72.cpp

@@ -58,6 +58,11 @@ void GxEPD2_213_B72::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_213_B72::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_B72::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213_B72::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -117,6 +122,12 @@ void GxEPD2_213_B72::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_213_B72::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_B72::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213_B72::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_213_B72.h

@@ -39,8 +39,11 @@ class GxEPD2_213_B72 : public GxEPD2_EPD
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_213_B73.cpp

@@ -59,6 +59,11 @@ void GxEPD2_213_B73::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_213_B73::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_B73::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213_B73::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -118,6 +123,12 @@ void GxEPD2_213_B73::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_213_B73::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_B73::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213_B73::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_213_B73.h

@@ -40,8 +40,11 @@ class GxEPD2_213_B73 : public GxEPD2_EPD
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_213_B74.cpp

@@ -70,6 +70,11 @@ void GxEPD2_213_B74::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_213_B74::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_B74::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213_B74::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -130,6 +135,12 @@ void GxEPD2_213_B74::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_213_B74::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_B74::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213_B74::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_213_B74.h

@@ -41,8 +41,11 @@ class GxEPD2_213_B74 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_213_BN.cpp

@@ -69,6 +69,11 @@ void GxEPD2_213_BN::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_213_BN::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_BN::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213_BN::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -129,6 +134,12 @@ void GxEPD2_213_BN::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_213_BN::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_BN::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213_BN::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_213_BN.h

@@ -41,8 +41,11 @@ class GxEPD2_213_BN : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 24 - 2
src/epd/GxEPD2_213_M21.cpp

@@ -45,6 +45,16 @@ void GxEPD2_213_M21::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_213_M21::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213_M21::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213_M21::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213_M21::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -63,7 +73,7 @@ void GxEPD2_213_M21::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -94,6 +104,18 @@ void GxEPD2_213_M21::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
 }
 }
 
 
 void GxEPD2_213_M21::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213_M21::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213_M21::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213_M21::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -119,7 +141,7 @@ void GxEPD2_213_M21::writeImagePart(const uint8_t bitmap[], int16_t x_part, int1
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_213_M21.h

@@ -39,8 +39,11 @@ class GxEPD2_213_M21 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -60,6 +63,9 @@ class GxEPD2_213_M21 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 11 - 0
src/epd/GxEPD2_213_T5D.cpp

@@ -65,6 +65,11 @@ void GxEPD2_213_T5D::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_213_T5D::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_T5D::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213_T5D::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -126,6 +131,12 @@ void GxEPD2_213_T5D::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_213_T5D::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_T5D::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213_T5D::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_213_T5D.h

@@ -40,8 +40,11 @@ class GxEPD2_213_T5D : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 24 - 2
src/epd/GxEPD2_213_flex.cpp

@@ -44,6 +44,16 @@ void GxEPD2_213_flex::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_213_flex::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213_flex::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213_flex::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213_flex::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -62,7 +72,7 @@ void GxEPD2_213_flex::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, i
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -93,6 +103,18 @@ void GxEPD2_213_flex::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, i
 }
 }
 
 
 void GxEPD2_213_flex::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213_flex::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213_flex::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_213_flex::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -118,7 +140,7 @@ void GxEPD2_213_flex::writeImagePart(const uint8_t bitmap[], int16_t x_part, int
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_213_flex.h

@@ -38,8 +38,11 @@ class GxEPD2_213_flex : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -59,6 +62,9 @@ class GxEPD2_213_flex : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 24 - 2
src/epd/GxEPD2_260.cpp

@@ -45,6 +45,16 @@ void GxEPD2_260::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_260::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_260::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_260::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_260::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -63,7 +73,7 @@ void GxEPD2_260::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -95,6 +105,18 @@ void GxEPD2_260::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
 
 
 void GxEPD2_260::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_260::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_260::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_260::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -119,7 +141,7 @@ void GxEPD2_260::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_260.h

@@ -40,8 +40,11 @@ class GxEPD2_260 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -61,6 +64,9 @@ class GxEPD2_260 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 24 - 2
src/epd/GxEPD2_260_M01.cpp

@@ -45,6 +45,16 @@ void GxEPD2_260_M01::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_260_M01::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_260_M01::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_260_M01::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_260_M01::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -63,7 +73,7 @@ void GxEPD2_260_M01::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -94,6 +104,18 @@ void GxEPD2_260_M01::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
 }
 }
 
 
 void GxEPD2_260_M01::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_260_M01::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_260_M01::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_260_M01::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -119,7 +141,7 @@ void GxEPD2_260_M01::writeImagePart(const uint8_t bitmap[], int16_t x_part, int1
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_260_M01.h

@@ -39,8 +39,11 @@ class GxEPD2_260_M01 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -60,6 +63,9 @@ class GxEPD2_260_M01 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 11 - 0
src/epd/GxEPD2_266_BN.cpp

@@ -73,6 +73,11 @@ void GxEPD2_266_BN::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_266_BN::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_266_BN::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_266_BN::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -133,6 +138,12 @@ void GxEPD2_266_BN::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_266_BN::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_266_BN::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_266_BN::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_266_BN.h

@@ -42,8 +42,11 @@ class GxEPD2_266_BN : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_270.cpp

@@ -56,6 +56,11 @@ void GxEPD2_270::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y, i
   _writeImage(0x14, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x14, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_270::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x14, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_270::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_270::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -112,6 +117,12 @@ void GxEPD2_270::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part, int
   _writeImagePart(0x14, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x14, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_270::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x14, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_270::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_270::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                  int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                  int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_270.h

@@ -39,8 +39,11 @@ class GxEPD2_270 : public GxEPD2_EPD
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 24 - 2
src/epd/GxEPD2_290.cpp

@@ -75,6 +75,16 @@ void GxEPD2_290::_writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_290::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_290::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -92,7 +102,7 @@ void GxEPD2_290::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x24);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -122,6 +132,18 @@ void GxEPD2_290::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
 }
 }
 
 
 void GxEPD2_290::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_290::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -146,7 +168,7 @@ void GxEPD2_290::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x24);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_290.h

@@ -38,8 +38,11 @@ class GxEPD2_290 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -59,6 +62,9 @@ class GxEPD2_290 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _writeScreenBuffer(uint8_t value);
     void _writeScreenBuffer(uint8_t value);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();

+ 11 - 0
src/epd/GxEPD2_290_BS.cpp

@@ -73,6 +73,11 @@ void GxEPD2_290_BS::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_290_BS::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_BS::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_290_BS::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -133,6 +138,12 @@ void GxEPD2_290_BS::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_290_BS::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_BS::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_290_BS::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_290_BS.h

@@ -42,8 +42,11 @@ class GxEPD2_290_BS : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_290_I6FD.cpp

@@ -66,6 +66,11 @@ void GxEPD2_290_I6FD::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_290_I6FD::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_I6FD::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_290_I6FD::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -127,6 +132,12 @@ void GxEPD2_290_I6FD::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_290_I6FD::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_I6FD::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_290_I6FD::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_290_I6FD.h

@@ -41,8 +41,11 @@ class GxEPD2_290_I6FD : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 24 - 2
src/epd/GxEPD2_290_M06.cpp

@@ -44,6 +44,16 @@ void GxEPD2_290_M06::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_290_M06::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_290_M06::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290_M06::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290_M06::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -62,7 +72,7 @@ void GxEPD2_290_M06::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -93,6 +103,18 @@ void GxEPD2_290_M06::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
 }
 }
 
 
 void GxEPD2_290_M06::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_290_M06::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290_M06::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290_M06::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -118,7 +140,7 @@ void GxEPD2_290_M06::writeImagePart(const uint8_t bitmap[], int16_t x_part, int1
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_290_M06.h

@@ -38,8 +38,11 @@ class GxEPD2_290_M06 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -59,6 +62,9 @@ class GxEPD2_290_M06 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 24 - 2
src/epd/GxEPD2_290_T5.cpp

@@ -44,6 +44,16 @@ void GxEPD2_290_T5::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_290_T5::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_290_T5::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290_T5::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290_T5::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -62,7 +72,7 @@ void GxEPD2_290_T5::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -93,6 +103,18 @@ void GxEPD2_290_T5::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
 }
 }
 
 
 void GxEPD2_290_T5::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_290_T5::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290_T5::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_290_T5::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -118,7 +140,7 @@ void GxEPD2_290_T5::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_290_T5.h

@@ -38,8 +38,11 @@ class GxEPD2_290_T5 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -59,6 +62,9 @@ class GxEPD2_290_T5 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 11 - 0
src/epd/GxEPD2_290_T5D.cpp

@@ -65,6 +65,11 @@ void GxEPD2_290_T5D::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_290_T5D::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_T5D::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_290_T5D::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -126,6 +131,12 @@ void GxEPD2_290_T5D::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_290_T5D::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_T5D::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_290_T5D::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_290_T5D.h

@@ -40,8 +40,11 @@ class GxEPD2_290_T5D : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_290_T94.cpp

@@ -70,6 +70,11 @@ void GxEPD2_290_T94::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_290_T94::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_T94::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_290_T94::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -130,6 +135,12 @@ void GxEPD2_290_T94::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_290_T94::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_T94::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_290_T94::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_290_T94.h

@@ -41,8 +41,11 @@ class GxEPD2_290_T94 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_290_T94_V2.cpp

@@ -73,6 +73,11 @@ void GxEPD2_290_T94_V2::writeImageAgain(const uint8_t bitmap[], int16_t x, int16
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_290_T94_V2::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_T94_V2::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_290_T94_V2::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -133,6 +138,12 @@ void GxEPD2_290_T94_V2::writeImagePartAgain(const uint8_t bitmap[], int16_t x_pa
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_290_T94_V2::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_290_T94_V2::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_290_T94_V2::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_290_T94_V2.h

@@ -44,8 +44,11 @@ class GxEPD2_290_T94_V2 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/epd/GxEPD2_370_TC1.cpp

@@ -71,6 +71,11 @@ void GxEPD2_370_TC1::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_370_TC1::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_370_TC1::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_370_TC1::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -131,6 +136,12 @@ void GxEPD2_370_TC1::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part,
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_370_TC1::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_370_TC1::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_370_TC1::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/epd/GxEPD2_370_TC1.h

@@ -42,8 +42,11 @@ class GxEPD2_370_TC1 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 24 - 2
src/epd/GxEPD2_371.cpp

@@ -49,6 +49,16 @@ void GxEPD2_371::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_371::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_371::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_371::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_371::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -67,7 +77,7 @@ void GxEPD2_371::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -98,6 +108,18 @@ void GxEPD2_371::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
 }
 }
 
 
 void GxEPD2_371::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_371::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_371::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_371::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -123,7 +145,7 @@ void GxEPD2_371::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_371.h

@@ -40,8 +40,11 @@ class GxEPD2_371 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -66,6 +69,9 @@ class GxEPD2_371 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 24 - 2
src/epd/GxEPD2_420.cpp

@@ -48,6 +48,16 @@ void GxEPD2_420::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_420::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_420::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_420::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_420::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -67,7 +77,7 @@ void GxEPD2_420::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   //uint32_t start = micros();
   //uint32_t start = micros();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -99,6 +109,18 @@ void GxEPD2_420::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
 }
 }
 
 
 void GxEPD2_420::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_420::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_420::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_420::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -124,7 +146,7 @@ void GxEPD2_420::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_420.h

@@ -39,8 +39,11 @@ class GxEPD2_420 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -60,6 +63,9 @@ class GxEPD2_420 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 24 - 2
src/epd/GxEPD2_420_M01.cpp

@@ -49,6 +49,16 @@ void GxEPD2_420_M01::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_420_M01::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_420_M01::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_420_M01::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_420_M01::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -68,7 +78,7 @@ void GxEPD2_420_M01::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
   //uint32_t start = micros();
   //uint32_t start = micros();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -100,6 +110,18 @@ void GxEPD2_420_M01::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, in
 }
 }
 
 
 void GxEPD2_420_M01::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_420_M01::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_420_M01::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_420_M01::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -125,7 +147,7 @@ void GxEPD2_420_M01::writeImagePart(const uint8_t bitmap[], int16_t x_part, int1
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_420_M01.h

@@ -40,8 +40,11 @@ class GxEPD2_420_M01 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -61,6 +64,9 @@ class GxEPD2_420_M01 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 24 - 2
src/epd/GxEPD2_583_T8.cpp

@@ -49,6 +49,16 @@ void GxEPD2_583_T8::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_583_T8::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_583_T8::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_583_T8::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_583_T8::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -67,7 +77,7 @@ void GxEPD2_583_T8::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -98,6 +108,18 @@ void GxEPD2_583_T8::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
 }
 }
 
 
 void GxEPD2_583_T8::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_583_T8::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_583_T8::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_583_T8::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -123,7 +145,7 @@ void GxEPD2_583_T8::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_583_T8.h

@@ -40,8 +40,11 @@ class GxEPD2_583_T8 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -66,6 +69,9 @@ class GxEPD2_583_T8 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 24 - 2
src/epd/GxEPD2_750_T7.cpp

@@ -49,6 +49,16 @@ void GxEPD2_750_T7::writeScreenBuffer(uint8_t value)
 }
 }
 
 
 void GxEPD2_750_T7::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_750_T7::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_750_T7::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_750_T7::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -67,7 +77,7 @@ void GxEPD2_750_T7::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {
@@ -98,6 +108,18 @@ void GxEPD2_750_T7::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
 }
 }
 
 
 void GxEPD2_750_T7::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_750_T7::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_750_T7::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
+void GxEPD2_750_T7::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -123,7 +145,7 @@ void GxEPD2_750_T7::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16
   if (!_using_partial_mode) _Init_Part();
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x91); // partial in
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _setPartialRamArea(x1, y1, w1, h1);
-  _writeCommand(0x13);
+  _writeCommand(command);
   _startTransfer();
   _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   for (int16_t i = 0; i < h1; i++)
   {
   {

+ 6 - 0
src/epd/GxEPD2_750_T7.h

@@ -40,8 +40,11 @@ class GxEPD2_750_T7 : public GxEPD2_EPD
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white)
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
@@ -66,6 +69,9 @@ class GxEPD2_750_T7 : public GxEPD2_EPD
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
   private:
   private:
+    void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 258 - 284
src/epd7c/GxEPD2_730c_GDEP073E01.cpp

@@ -16,7 +16,6 @@
 GxEPD2_730c_GDEP073E01::GxEPD2_730c_GDEP073E01(int16_t cs, int16_t dc, int16_t rst, int16_t busy) :
 GxEPD2_730c_GDEP073E01::GxEPD2_730c_GDEP073E01(int16_t cs, int16_t dc, int16_t rst, int16_t busy) :
   GxEPD2_EPD(cs, dc, rst, busy, LOW, 20000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
   GxEPD2_EPD(cs, dc, rst, busy, LOW, 20000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
 {
 {
-  _paged = false;
 }
 }
 
 
 void GxEPD2_730c_GDEP073E01::clearScreen(uint8_t value)
 void GxEPD2_730c_GDEP073E01::clearScreen(uint8_t value)
@@ -38,6 +37,7 @@ void GxEPD2_730c_GDEP073E01::writeScreenBuffer(uint8_t value)
 void GxEPD2_730c_GDEP073E01::writeScreenBuffer(uint8_t black_value, uint8_t color_value)
 void GxEPD2_730c_GDEP073E01::writeScreenBuffer(uint8_t black_value, uint8_t color_value)
 {
 {
   if (!_init_display_done) _InitDisplay();
   if (!_init_display_done) _InitDisplay();
+  _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
   _writeCommand(0x10);
   _startTransfer();
   _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 2; i++)
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 2; i++)
@@ -54,13 +54,41 @@ void GxEPD2_730c_GDEP073E01::writeImage(const uint8_t bitmap[], int16_t x, int16
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   if (!_init_display_done) _InitDisplay();
   if (!_init_display_done) _InitDisplay();
-  if (_paged && (x == 0) && (w == int16_t(WIDTH)) && (h < int16_t(HEIGHT)))
+  if (_initial_write) writeScreenBuffer();
+  int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
+  x -= x % 8; // byte boundary
+  w = wb * 8; // byte boundary
+  int16_t x1 = x < 0 ? 0 : x; // limit
+  int16_t y1 = y < 0 ? 0 : y; // limit
+  int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
+  int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
+  int16_t dx = x1 - x;
+  int16_t dy = y1 - y;
+  w1 -= dx;
+  h1 -= dy;
+  if ((w1 <= 0) || (h1 <= 0)) return;
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x10);
+  _startTransfer();
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    //Serial.println("paged");
-    _startTransfer();
-    for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(h) / 8; i++)
+    for (int16_t j = 0; j < w1 / 8; j++)
     {
     {
-      uint8_t data = bitmap[i];
+      uint8_t data;
+      // use wb, h of bitmap for index!
+      int16_t idx = mirror_y ? j + dx / 8 + ((h - 1 - (i + dy))) * wb : j + dx / 8 + (i + dy) * wb;
+      if (pgm)
+      {
+#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
+        data = pgm_read_byte(&bitmap[idx]);
+#else
+        data = bitmap[idx];
+#endif
+      }
+      else
+      {
+        data = bitmap[idx];
+      }
       for (int16_t k = 0; k < 4; k++)
       for (int16_t k = 0; k < 4; k++)
       {
       {
         uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
         uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
@@ -68,54 +96,8 @@ void GxEPD2_730c_GDEP073E01::writeImage(const uint8_t bitmap[], int16_t x, int16
         _transfer(data2);
         _transfer(data2);
       }
       }
     }
     }
-    _endTransfer();
-    if (y + h == HEIGHT) // last page
-    {
-      //Serial.println("paged ended");
-      _paged = false;
-    }
-  }
-  else
-  {
-    _paged = false;
-    int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
-    x -= x % 8; // byte boundary
-    w = wb * 8; // byte boundary
-    if ((w <= 0) || (h <= 0)) return;
-    _writeCommand(0x10);
-    _startTransfer();
-    for (int16_t i = 0; i < int16_t(HEIGHT); i++)
-    {
-      for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
-      {
-        uint8_t data = 0xFF;
-        if ((j >= x) && (j <= x + w) && (i >= y) && (i < y + h))
-        {
-          uint32_t idx = mirror_y ? (j - x) / 8 + uint32_t((h - 1 - (i - y))) * wb : (j - x) / 8 + uint32_t(i - y) * wb;
-          if (pgm)
-          {
-#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-            data = pgm_read_byte(&bitmap[idx]);
-#else
-            data = bitmap[idx];
-#endif
-          }
-          else
-          {
-            data = bitmap[idx];
-          }
-          if (invert) data = ~data;
-        }
-        for (int16_t k = 0; k < 4; k++)
-        {
-          uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
-          data <<= 2;
-          _transfer(data2);
-        }
-      }
-    }
-    _endTransfer();
   }
   }
+  _endTransfer();
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 }
 
 
@@ -123,18 +105,53 @@ void GxEPD2_730c_GDEP073E01::writeImage(const uint8_t* black, const uint8_t* col
 {
 {
   if (!black && !color) return;
   if (!black && !color) return;
   if (!color) return writeImage(black, x, y, w, h, invert, mirror_y, pgm);
   if (!color) return writeImage(black, x, y, w, h, invert, mirror_y, pgm);
-  //Serial.print("writeImage("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print("writeImage_3c("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   if (!_init_display_done) _InitDisplay();
   if (!_init_display_done) _InitDisplay();
-  if (_paged && (x == 0) && (w == int16_t(WIDTH)) && (h < int16_t(HEIGHT)))
+  if (_initial_write) writeScreenBuffer();
+  int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
+  x -= x % 8; // byte boundary
+  w = wb * 8; // byte boundary
+  int16_t x1 = x < 0 ? 0 : x; // limit
+  int16_t y1 = y < 0 ? 0 : y; // limit
+  int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
+  int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
+  int16_t dx = x1 - x;
+  int16_t dy = y1 - y;
+  w1 -= dx;
+  h1 -= dy;
+  if ((w1 <= 0) || (h1 <= 0)) return;
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x10);
+  _startTransfer();
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    //Serial.println("paged");
-    _startTransfer();
-    for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(h) / 8; i++)
+    for (int16_t j = 0; j < w1 / 8; j++)
     {
     {
-      uint8_t black_data = black[i];
-      uint8_t color_data = color[i];
+      uint8_t black_data = 0xFF, color_data = 0xFF;
+      // use wb, h of bitmap for index!
+      uint32_t idx = mirror_y ? j + dx / 8 + uint32_t((h - 1 - (i + dy))) * wb : j + dx / 8 + uint32_t(i + dy) * wb;
+      if (pgm)
+      {
+#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
+        black_data = pgm_read_byte(&black[idx]);
+        color_data = pgm_read_byte(&color[idx]);
+#else
+        black_data = black[idx];
+        color_data = color[idx];
+#endif
+      }
+      else
+      {
+        black_data = black[idx];
+        color_data = color[idx];
+      }
+      if (invert)
+      {
+        black_data = ~black_data;
+        color_data = ~color_data;
+      }
       for (int16_t k = 0; k < 4; k++)
       for (int16_t k = 0; k < 4; k++)
       {
       {
         uint8_t out_data = 0x00;
         uint8_t out_data = 0x00;
@@ -149,75 +166,21 @@ void GxEPD2_730c_GDEP073E01::writeImage(const uint8_t* black, const uint8_t* col
         _transfer(out_data);
         _transfer(out_data);
       }
       }
     }
     }
-    _endTransfer();
-    if (y + h == HEIGHT) // last page
-    {
-      //Serial.println("paged ended");
-      _paged = false;
-    }
-  }
-  else
-  {
-    _paged = false;
-    int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
-    x -= x % 8; // byte boundary
-    w = wb * 8; // byte boundary
-    if ((w <= 0) || (h <= 0)) return;
-    _writeCommand(0x10);
-    _startTransfer();
-    for (int16_t i = 0; i < int16_t(HEIGHT); i++)
-    {
-      for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
-      {
-        uint8_t black_data = 0xFF, color_data = 0xFF;
-        if ((j >= x) && (j < x + w) && (i >= y) && (i < y + h))
-        {
-          uint32_t idx = mirror_y ? (j - x) / 8 + uint32_t((h - 1 - (i - y))) * wb : (j - x) / 8 + uint32_t(i - y) * wb;
-          if (pgm)
-          {
-#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-            black_data = pgm_read_byte(&black[idx]);
-            color_data = pgm_read_byte(&color[idx]);
-#else
-            black_data = black[idx];
-            color_data = color[idx];
-#endif
-          }
-          else
-          {
-            black_data = black[idx];
-            color_data = color[idx];
-          }
-          if (invert)
-          {
-            black_data = ~black_data;
-            color_data = ~color_data;
-          }
-        }
-        for (int16_t k = 0; k < 4; k++)
-        {
-          uint8_t out_data = 0x00;
-          for (int16_t l = 0; l < 2; l++)
-          {
-            out_data <<= 4;
-            if (!(color_data & 0x80)) out_data |= 0x04;
-            else out_data |= black_data & 0x80 ? 0x01 : 0x00;
-            black_data <<= 1;
-            color_data <<= 1;
-          }
-          _transfer(out_data);
-        }
-      }
-    }
-    _endTransfer();
   }
   }
+  _endTransfer();
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 }
 
 
 void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
+  //Serial.print("writeImagePart("); Serial.print(x_part); Serial.print(", "); Serial.print(y_part); Serial.print(", ");
+  //Serial.print(w_bitmap); Serial.print(", "); Serial.print(h_bitmap); Serial.print(", ");
+  //Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((y_part < 0) || (y_part >= h_bitmap)) return;
   if ((y_part < 0) || (y_part >= h_bitmap)) return;
@@ -225,7 +188,9 @@ void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t bitmap[], int16_t x_pa
   x_part -= x_part % 8; // byte boundary
   x_part -= x_part % 8; // byte boundary
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
-  x -= x % 8; // byte boundary
+  // make x, w multiple of 8
+  w += x % 8; // adjust for byte boundary of x
+  x -= x % 8; // byte boundary ox
   w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
@@ -236,32 +201,29 @@ void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t bitmap[], int16_t x_pa
   w1 -= dx;
   w1 -= dx;
   h1 -= dy;
   h1 -= dy;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
-  if (!_init_display_done) _InitDisplay();
+  _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
   _writeCommand(0x10);
   _startTransfer();
   _startTransfer();
-  for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
+    for (int16_t j = 0; j < w1 / 8; j++)
     {
     {
-      uint8_t data = 0xFF;
-      if ((j >= x1) && (j < x1 + w) && (i >= y1) && (i < y1 + h))
+      uint8_t data;
+      // use wb_bitmap, h_bitmap of bitmap for index!
+      uint32_t idx = mirror_y ? x_part / 8 + j + dx / 8 + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / 8 + j + dx / 8 + uint32_t(y_part + i + dy) * wb_bitmap;
+      if (pgm)
       {
       {
-        // use wb_bitmap, h_bitmap of bitmap for index!
-        uint32_t idx = mirror_y ? (x_part + j - x1) / 8 + uint32_t((h_bitmap - 1 - (y_part + i - y1))) * wb_bitmap : (x_part + j - x1) / 8 + uint32_t(y_part + i - y1) * wb_bitmap;
-        if (pgm)
-        {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-          data = pgm_read_byte(&bitmap[idx]);
+        data = pgm_read_byte(&bitmap[idx]);
 #else
 #else
-          data = bitmap[idx];
+        data = bitmap[idx];
 #endif
 #endif
-        }
-        else
-        {
-          data = bitmap[idx];
-        }
-        if (invert) data = ~data;
       }
       }
+      else
+      {
+        data = bitmap[idx];
+      }
+      if (invert) data = ~data;
       for (int16_t k = 0; k < 4; k++)
       for (int16_t k = 0; k < 4; k++)
       {
       {
         uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
         uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
@@ -277,12 +239,14 @@ void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t bitmap[], int16_t x_pa
 void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
-  //Serial.print("writeImagePart("); Serial.print(x_part); Serial.print(", "); Serial.print(y_part); Serial.print(", ");
+  //Serial.print("writeImagePart_3c("); Serial.print(x_part); Serial.print(", "); Serial.print(y_part); Serial.print(", ");
   //Serial.print(w_bitmap); Serial.print(", "); Serial.print(h_bitmap); Serial.print(", ");
   //Serial.print(w_bitmap); Serial.print(", "); Serial.print(h_bitmap); Serial.print(", ");
   //Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
   //Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   if (!black && !color) return;
   if (!black && !color) return;
   if (!color) return writeImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   if (!color) return writeImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
@@ -291,7 +255,9 @@ void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t* black, const uint8_t*
   x_part -= x_part % 8; // byte boundary
   x_part -= x_part % 8; // byte boundary
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
-  x -= x % 8; // byte boundary
+  // make x, w multiple of 8
+  w += x % 8; // adjust for byte boundary of x
+  x -= x % 8; // byte boundary ox
   w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
@@ -302,38 +268,35 @@ void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t* black, const uint8_t*
   w1 -= dx;
   w1 -= dx;
   h1 -= dy;
   h1 -= dy;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
-  if (!_init_display_done) _InitDisplay();
+  _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
   _writeCommand(0x10);
   _startTransfer();
   _startTransfer();
-  for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
+    for (int16_t j = 0; j < w1 / 8; j++)
     {
     {
       uint8_t black_data = 0xFF, color_data = 0xFF;
       uint8_t black_data = 0xFF, color_data = 0xFF;
-      if ((j >= x1) && (j < x1 + w) && (i >= y1) && (i < y1 + h))
+      // use wb_bitmap, h_bitmap of bitmap for index!
+      uint32_t idx = mirror_y ? x_part / 8 + j + dx / 8 + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / 8 + j + dx / 8 + uint32_t(y_part + i + dy) * wb_bitmap;
+      if (pgm)
       {
       {
-        // use wb_bitmap, h_bitmap of bitmap for index!
-        uint32_t idx = mirror_y ? (x_part + j - x1) / 8 + uint32_t((h_bitmap - 1 - (y_part + i - y1))) * wb_bitmap : (x_part + j - x1) / 8 + uint32_t(y_part + i - y1) * wb_bitmap;
-        if (pgm)
-        {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-          black_data = pgm_read_byte(&black[idx]);
-          color_data = pgm_read_byte(&color[idx]);
+        black_data = pgm_read_byte(&black[idx]);
+        color_data = pgm_read_byte(&color[idx]);
 #else
 #else
-          black_data = black[idx];
-          color_data = color[idx];
+        black_data = black[idx];
+        color_data = color[idx];
 #endif
 #endif
-        }
-        else
-        {
-          black_data = black[idx];
-          color_data = color[idx];
-        }
-        if (invert)
-        {
-          black_data = ~black_data;
-          color_data = ~color_data;
-        }
+      }
+      else
+      {
+        black_data = black[idx];
+        color_data = color[idx];
+      }
+      if (invert)
+      {
+        black_data = ~black_data;
+        color_data = ~color_data;
       }
       }
       for (int16_t k = 0; k < 4; k++)
       for (int16_t k = 0; k < 4; k++)
       {
       {
@@ -356,81 +319,61 @@ void GxEPD2_730c_GDEP073E01::writeImagePart(const uint8_t* black, const uint8_t*
 
 
 void GxEPD2_730c_GDEP073E01::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_730c_GDEP073E01::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
-  if (data1)
+  if (!data1) return;
+  //Serial.print("writeNative("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
+  uint32_t wb = (w + 1) / 2; // width bytes, bitmaps are padded
+  x -= x % 2; // byte boundary
+  w = wb * 2; // byte boundary
+  int16_t x1 = x < 0 ? 0 : x; // limit
+  int16_t y1 = y < 0 ? 0 : y; // limit
+  int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
+  int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
+  int16_t dx = x1 - x;
+  int16_t dy = y1 - y;
+  w1 -= dx;
+  h1 -= dy;
+  if ((w1 <= 0) || (h1 <= 0)) return;
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x10);
+  _startTransfer();
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    //Serial.print("writeNative("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
-    //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
-    delay(1); // yield() to avoid WDT on ESP8266 and ESP32
-    if (!_init_display_done) _InitDisplay();
-    if (_paged && (x == 0) && (w == int16_t(WIDTH)) && (h < int16_t(HEIGHT)))
-    {
-      //Serial.println("paged");
-      _startTransfer();
-      for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(h) / 2; i++)
-      {
-        uint8_t data = data1[i];
-        if (!invert) data = _convert_to_native(data);
-        _transfer(data);
-      }
-      _endTransfer();
-      if (y + h == HEIGHT) // last page
-      {
-        //Serial.println("paged ended");
-        _paged = false;
-      }
-    }
-    else
+    for (int16_t j = 0; j < w1 / 2; j++)
     {
     {
-      _paged = false;
-      int16_t wb = (w + 1) / 2; // width bytes, bitmaps are padded
-      x -= x % 2; // byte boundary
-      w = wb * 2; // byte boundary
-      if ((w <= 0) || (h <= 0)) return;
-      _writeCommand(0x10);
-      _startTransfer();
-      for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+      uint8_t data;
+      // use wb, h of bitmap for index!
+      uint32_t idx = mirror_y ? j + dx / 2 + uint32_t((h - 1 - (i + dy))) * wb : j + dx / 2 + uint32_t(i + dy) * wb;
+      if (pgm)
       {
       {
-        for (int16_t j = 0; j < int16_t(WIDTH); j += 2)
-        {
-          uint8_t data = 0x11;
-          if (data1)
-          {
-            if ((j >= x) && (j < x + w) && (i >= y) && (i < y + h))
-            {
-              uint32_t idx = mirror_y ? (j - x) / 2 + uint32_t((h - 1 - (i - y))) * wb : (j - x) / 2 + uint32_t(i - y) * wb;
-              if (pgm)
-              {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-                data = pgm_read_byte(&data1[idx]);
+        data = pgm_read_byte(&data1[idx]);
 #else
 #else
-                data = data1[idx];
+        data = data1[idx];
 #endif
 #endif
-              }
-              else
-              {
-                data = data1[idx];
-              }
-              if (!invert) data = _convert_to_native(data);
-            }
-          }
-          _transfer(data);
-        }
       }
       }
-      _endTransfer();
+      else
+      {
+        data = data1[idx];
+      }
+      if (!invert) data = _convert_to_native(data);
+      _transfer(data);
     }
     }
-    delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   }
   }
+  _endTransfer();
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 }
 
 
 void GxEPD2_730c_GDEP073E01::writeNativePart(const uint8_t* data1, const uint8_t* data2, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_730c_GDEP073E01::writeNativePart(const uint8_t* data1, const uint8_t* data2, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
-  //Serial.print("writeNativePart("); Serial.print(x_part); Serial.print(", "); Serial.print(y_part); Serial.print(", ");
-  //Serial.print(w_bitmap); Serial.print(", "); Serial.print(h_bitmap); Serial.print(", ");
-  //Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
-  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   if (!data1) return;
   if (!data1) return;
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((y_part < 0) || (y_part >= h_bitmap)) return;
   if ((y_part < 0) || (y_part >= h_bitmap)) return;
@@ -438,6 +381,7 @@ void GxEPD2_730c_GDEP073E01::writeNativePart(const uint8_t* data1, const uint8_t
   x_part -= x_part % 2; // byte boundary
   x_part -= x_part % 2; // byte boundary
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
+  w += x % 2; // adjust for byte boundary of x
   x -= x % 2; // byte boundary
   x -= x % 2; // byte boundary
   w = 2 * ((w + 1) / 2); // byte boundary, bitmaps are padded
   w = 2 * ((w + 1) / 2); // byte boundary, bitmaps are padded
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t x1 = x < 0 ? 0 : x; // limit
@@ -449,32 +393,29 @@ void GxEPD2_730c_GDEP073E01::writeNativePart(const uint8_t* data1, const uint8_t
   w1 -= dx;
   w1 -= dx;
   h1 -= dy;
   h1 -= dy;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
-  if (!_init_display_done) _InitDisplay();
+  _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
   _writeCommand(0x10);
   _startTransfer();
   _startTransfer();
-  for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    for (int16_t j = 0; j < int16_t(WIDTH); j += 2)
+    for (int16_t j = 0; j < w1 / 2; j++)
     {
     {
-      uint8_t data = 0x11;
-      if ((j >= x1) && (j < x1 + w) && (i >= y1) && (i < y1 + h))
+      uint8_t data;
+      // use wb_bitmap, h_bitmap of bitmap for index!
+      uint32_t idx = mirror_y ? x_part / 2 + j + dx / 2 + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / 2 + j + dx / 2 + uint32_t(y_part + i + dy) * wb_bitmap;
+      if (pgm)
       {
       {
-        // use wb_bitmap, h_bitmap of bitmap for index!
-        uint32_t idx = mirror_y ? (x_part + j - x1) / 2 + uint32_t((h_bitmap - 1 - (y_part + i - y1))) * wb_bitmap : (x_part + j - x1) / 2 + uint32_t(y_part + i - y1) * wb_bitmap;
-        if (pgm)
-        {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-          data = pgm_read_byte(&data1[idx]);
+        data = pgm_read_byte(&data1[idx]);
 #else
 #else
-          data = data1[idx];
+        data = data1[idx];
 #endif
 #endif
-        }
-        else
-        {
-          data = data1[idx];
-        }
-        if (!invert) data = _convert_to_native(data);
       }
       }
+      else
+      {
+        data = data1[idx];
+      }
+      if (!invert) data = _convert_to_native(data);
       _transfer(data);
       _transfer(data);
     }
     }
   }
   }
@@ -517,6 +458,9 @@ void GxEPD2_730c_GDEP073E01::drawNative(const uint8_t* data1, const uint8_t* dat
 void GxEPD2_730c_GDEP073E01::refresh(bool partial_update_mode)
 void GxEPD2_730c_GDEP073E01::refresh(bool partial_update_mode)
 {
 {
   _PowerOn();
   _PowerOn();
+  _setPartialRamArea(0, 0, WIDTH, HEIGHT);
+  _writeCommand(0x50);
+  _writeData(0x3F);
   _writeCommand(0x12); // Display Refresh
   _writeCommand(0x12); // Display Refresh
   _writeData(0x00);
   _writeData(0x00);
   delay(1);
   delay(1);
@@ -526,6 +470,10 @@ void GxEPD2_730c_GDEP073E01::refresh(bool partial_update_mode)
 void GxEPD2_730c_GDEP073E01::refresh(int16_t x, int16_t y, int16_t w, int16_t h)
 void GxEPD2_730c_GDEP073E01::refresh(int16_t x, int16_t y, int16_t w, int16_t h)
 {
 {
   _PowerOn();
   _PowerOn();
+  if (usePartialUpdate) _setPartialRamArea(x, y, w, h);
+  else _setPartialRamArea(0, 0, WIDTH, HEIGHT);
+  _writeCommand(0x50);
+  _writeData(0xFF); // border floating
   _writeCommand(0x12); // Display Refresh
   _writeCommand(0x12); // Display Refresh
   _writeData(0x00);
   _writeData(0x00);
   delay(1);
   delay(1);
@@ -549,11 +497,22 @@ void GxEPD2_730c_GDEP073E01::hibernate()
   }
   }
 }
 }
 
 
-void GxEPD2_730c_GDEP073E01::setPaged()
+void GxEPD2_730c_GDEP073E01::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
 {
 {
-  _paged = true;
-  if (!_init_display_done) _InitDisplay();
-  _writeCommand(0x10);
+  //Serial.print("_setPartialRamArea("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
+  uint16_t xe = x + w - 1;
+  uint16_t ye = y + h; // controller issue (one more)
+  _writeCommand(0x83); // partial window
+  _writeData(x / 256);
+  _writeData(x % 256);
+  _writeData(xe / 256);
+  _writeData(xe % 256);
+  _writeData(y / 256);
+  _writeData(y % 256);
+  _writeData(ye / 256);
+  _writeData(ye % 256);
+  _writeData(0x01);
 }
 }
 
 
 void GxEPD2_730c_GDEP073E01::_PowerOn()
 void GxEPD2_730c_GDEP073E01::_PowerOn()
@@ -579,6 +538,7 @@ void GxEPD2_730c_GDEP073E01::_PowerOff()
 
 
 void GxEPD2_730c_GDEP073E01::_InitDisplay()
 void GxEPD2_730c_GDEP073E01::_InitDisplay()
 {
 {
+  //Serial.println("_InitDisplay");
   if ((_rst >= 0) && (_hibernating || _initial_write))
   if ((_rst >= 0) && (_hibernating || _initial_write))
   {
   {
     pinMode(_rst, OUTPUT); // just in case
     pinMode(_rst, OUTPUT); // just in case
@@ -587,8 +547,8 @@ void GxEPD2_730c_GDEP073E01::_InitDisplay()
     digitalWrite(_rst, LOW);
     digitalWrite(_rst, LOW);
     delay(20);
     delay(20);
     digitalWrite(_rst, HIGH);
     digitalWrite(_rst, HIGH);
-    delay(10); // 4ms measured
-    //_waitWhileBusy("_InitDisplay reset", power_on_time); // 4000us
+    delay(10); // 6ms measured
+    //_waitWhileBusy("_InitDisplay reset", power_on_time); // 6000us
     _initial_write = false; // used for initial reset done
     _initial_write = false; // used for initial reset done
     _hibernating = false;
     _hibernating = false;
     _power_is_on = false;
     _power_is_on = false;
@@ -710,51 +670,50 @@ uint8_t GxEPD2_730c_GDEP073E01::_colorOfDemoBitmap(uint8_t from, int16_t mode)
 void GxEPD2_730c_GDEP073E01::writeDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode, bool mirror_y, bool pgm)
 void GxEPD2_730c_GDEP073E01::writeDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode, bool mirror_y, bool pgm)
 {
 {
   (void) mode;
   (void) mode;
-  if (data1)
+  if (!data1) return;
+  //Serial.print("writeDemoBitmap("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
+  int16_t x1 = x < 0 ? 0 : x; // limit
+  int16_t y1 = y < 0 ? 0 : y; // limit
+  int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
+  int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
+  int16_t dx = x1 - x;
+  int16_t dy = y1 - y;
+  w1 -= dx;
+  h1 -= dy;
+  if ((w1 <= 0) || (h1 <= 0)) return;
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x10);
+  _startTransfer();
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    //Serial.print("writeNative("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
-    //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
-    if (!_init_display_done) _InitDisplay();
-    delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+    for (int16_t j = 0; j < w1; j += 2)
     {
     {
-      _paged = false;
-      if ((w <= 0) || (h <= 0)) return;
-      _writeCommand(0x10);
-      _startTransfer();
-      for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+      uint8_t data = 0x11;
+      uint32_t idx = mirror_y ? j + dx + uint32_t((h - 1 - (i + dy))) * w : j + dx + uint32_t(i + dy) * w;
+      if (pgm)
       {
       {
-        for (int16_t j = 0; j < int16_t(WIDTH); j += 2)
-        {
-          uint8_t data = 0x11;
-          if (data1)
-          {
-            if ((j >= x) && (j < x + w) && (i >= y) && (i < y + h))
-            {
-              uint32_t idx = mirror_y ? (j - x) + uint32_t((h - 1 - (i - y))) * w : (j - x) + uint32_t(i - y) * w;
-              if (pgm)
-              {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-                data = _colorOfDemoBitmap(pgm_read_byte(&data1[idx++]), mode) << 4;
-                data |= _colorOfDemoBitmap(pgm_read_byte(&data1[idx]), mode);
+        data = _colorOfDemoBitmap(pgm_read_byte(&data1[idx++]), mode) << 4;
+        data |= _colorOfDemoBitmap(pgm_read_byte(&data1[idx]), mode);
 #else
 #else
-                data = _colorOfDemoBitmap(data1[idx++], mode) << 4;
-                data |= _colorOfDemoBitmap(data1[idx], mode);
+        data = _colorOfDemoBitmap(data1[idx++], mode) << 4;
+        data |= _colorOfDemoBitmap(data1[idx], mode);
 #endif
 #endif
-              }
-              else
-              {
-                data = _colorOfDemoBitmap(data1[idx++], mode) << 4;
-                data |= _colorOfDemoBitmap(data1[idx], mode);
-              }
-            }
-          }
-          _transfer(data);
-        }
       }
       }
-      _endTransfer();
+      else
+      {
+        data = _colorOfDemoBitmap(data1[idx++], mode) << 4;
+        data |= _colorOfDemoBitmap(data1[idx], mode);
+      }
+      _transfer(data);
     }
     }
-    delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   }
   }
+  _endTransfer();
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 }
 
 
 void GxEPD2_730c_GDEP073E01::drawDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode, bool mirror_y, bool pgm)
 void GxEPD2_730c_GDEP073E01::drawDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode, bool mirror_y, bool pgm)
@@ -765,9 +724,8 @@ void GxEPD2_730c_GDEP073E01::drawDemoBitmap(const uint8_t* data1, const uint8_t*
 
 
 void GxEPD2_730c_GDEP073E01::drawNativeColors()
 void GxEPD2_730c_GDEP073E01::drawNativeColors()
 {
 {
+#if 0
   const uint16_t colors = 7;
   const uint16_t colors = 7;
-  //const uint16_t colors = 8; // 7 is white
-  //const uint16_t colors = 16; // repeated for 8..15
   const uint16_t h1 = HEIGHT / colors;
   const uint16_t h1 = HEIGHT / colors;
   _writeCommand(0x10);
   _writeCommand(0x10);
   _startTransfer();
   _startTransfer();
@@ -780,6 +738,22 @@ void GxEPD2_730c_GDEP073E01::drawNativeColors()
   }
   }
   _endTransfer();
   _endTransfer();
   refresh();
   refresh();
+#else
+  const uint16_t stripes = 7;
+  const uint16_t h1 = (HEIGHT / stripes) - 1;
+  for (uint16_t s = 0; s < stripes; s++)
+  {
+    _setPartialRamArea(0, s * h1, WIDTH, h1);
+    _writeCommand(0x10);
+    _startTransfer();
+    for (uint16_t hnb = 0; hnb < h1 * WIDTH / 2; hnb++)
+    {
+      _transfer((s << 4) | s);
+    }
+    _endTransfer();
+  }
+  refresh();
+#endif
 }
 }
 
 
 uint8_t GxEPD2_730c_GDEP073E01::_convert_to_native(uint8_t data)
 uint8_t GxEPD2_730c_GDEP073E01::_convert_to_native(uint8_t data)

+ 3 - 2
src/epd7c/GxEPD2_730c_GDEP073E01.h

@@ -25,7 +25,8 @@ class GxEPD2_730c_GDEP073E01 : public GxEPD2_EPD
     static const uint16_t HEIGHT = 480;
     static const uint16_t HEIGHT = 480;
     static const GxEPD2::Panel panel = GxEPD2::GDEP073E01;
     static const GxEPD2::Panel panel = GxEPD2::GDEP073E01;
     static const bool hasColor = true;
     static const bool hasColor = true;
-    static const bool hasPartialUpdate = false;
+    static const bool hasPartialUpdate = true;
+    static const bool usePartialUpdate = true; // set false to force full screen update
     static const bool hasFastPartialUpdate = false;
     static const bool hasFastPartialUpdate = false;
     static const uint16_t power_on_time = 200; // ms, e.g. 172000us
     static const uint16_t power_on_time = 200; // ms, e.g. 172000us
     static const uint16_t power_off_time = 150; // ms, e.g. 145000us
     static const uint16_t power_off_time = 150; // ms, e.g. 145000us
@@ -65,9 +66,9 @@ class GxEPD2_730c_GDEP073E01 : public GxEPD2_EPD
     void refresh(int16_t x, int16_t y, int16_t w, int16_t h); // screen refresh from controller memory, partial screen
     void refresh(int16_t x, int16_t y, int16_t w, int16_t h); // screen refresh from controller memory, partial screen
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
-    void setPaged(); // for GxEPD2_154c and GxEPD2_565c and GxEPD2_730c_GDEP073E01 paged workaround
     void drawNativeColors();
     void drawNativeColors();
   private:
   private:
+    void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
     uint8_t _colorOfDemoBitmap(uint8_t from, int16_t mode = 0);
     uint8_t _colorOfDemoBitmap(uint8_t from, int16_t mode = 0);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();

+ 266 - 288
src/epd7c/GxEPD2_730c_GDEY073D46.cpp

@@ -16,7 +16,6 @@
 GxEPD2_730c_GDEY073D46::GxEPD2_730c_GDEY073D46(int16_t cs, int16_t dc, int16_t rst, int16_t busy) :
 GxEPD2_730c_GDEY073D46::GxEPD2_730c_GDEY073D46(int16_t cs, int16_t dc, int16_t rst, int16_t busy) :
   GxEPD2_EPD(cs, dc, rst, busy, LOW, 60000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
   GxEPD2_EPD(cs, dc, rst, busy, LOW, 60000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
 {
 {
-  _paged = false;
 }
 }
 
 
 void GxEPD2_730c_GDEY073D46::clearScreen(uint8_t value)
 void GxEPD2_730c_GDEY073D46::clearScreen(uint8_t value)
@@ -54,13 +53,41 @@ void GxEPD2_730c_GDEY073D46::writeImage(const uint8_t bitmap[], int16_t x, int16
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   if (!_init_display_done) _InitDisplay();
   if (!_init_display_done) _InitDisplay();
-  if (_paged && (x == 0) && (w == int16_t(WIDTH)) && (h < int16_t(HEIGHT)))
+  if (_initial_write) writeScreenBuffer();
+  int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
+  x -= x % 8; // byte boundary
+  w = wb * 8; // byte boundary
+  int16_t x1 = x < 0 ? 0 : x; // limit
+  int16_t y1 = y < 0 ? 0 : y; // limit
+  int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
+  int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
+  int16_t dx = x1 - x;
+  int16_t dy = y1 - y;
+  w1 -= dx;
+  h1 -= dy;
+  if ((w1 <= 0) || (h1 <= 0)) return;
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x10);
+  _startTransfer();
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    //Serial.println("paged");
-    _startTransfer();
-    for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(h) / 8; i++)
+    for (int16_t j = 0; j < w1 / 8; j++)
     {
     {
-      uint8_t data = bitmap[i];
+      uint8_t data;
+      // use wb, h of bitmap for index!
+      int16_t idx = mirror_y ? j + dx / 8 + ((h - 1 - (i + dy))) * wb : j + dx / 8 + (i + dy) * wb;
+      if (pgm)
+      {
+#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
+        data = pgm_read_byte(&bitmap[idx]);
+#else
+        data = bitmap[idx];
+#endif
+      }
+      else
+      {
+        data = bitmap[idx];
+      }
       for (int16_t k = 0; k < 4; k++)
       for (int16_t k = 0; k < 4; k++)
       {
       {
         uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
         uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
@@ -68,54 +95,8 @@ void GxEPD2_730c_GDEY073D46::writeImage(const uint8_t bitmap[], int16_t x, int16
         _transfer(data2);
         _transfer(data2);
       }
       }
     }
     }
-    _endTransfer();
-    if (y + h == HEIGHT) // last page
-    {
-      //Serial.println("paged ended");
-      _paged = false;
-    }
-  }
-  else
-  {
-    _paged = false;
-    int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
-    x -= x % 8; // byte boundary
-    w = wb * 8; // byte boundary
-    if ((w <= 0) || (h <= 0)) return;
-    _writeCommand(0x10);
-    _startTransfer();
-    for (int16_t i = 0; i < int16_t(HEIGHT); i++)
-    {
-      for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
-      {
-        uint8_t data = 0xFF;
-        if ((j >= x) && (j <= x + w) && (i >= y) && (i < y + h))
-        {
-          uint32_t idx = mirror_y ? (j - x) / 8 + uint32_t((h - 1 - (i - y))) * wb : (j - x) / 8 + uint32_t(i - y) * wb;
-          if (pgm)
-          {
-#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-            data = pgm_read_byte(&bitmap[idx]);
-#else
-            data = bitmap[idx];
-#endif
-          }
-          else
-          {
-            data = bitmap[idx];
-          }
-          if (invert) data = ~data;
-        }
-        for (int16_t k = 0; k < 4; k++)
-        {
-          uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
-          data <<= 2;
-          _transfer(data2);
-        }
-      }
-    }
-    _endTransfer();
   }
   }
+  _endTransfer();
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 }
 
 
@@ -123,18 +104,53 @@ void GxEPD2_730c_GDEY073D46::writeImage(const uint8_t* black, const uint8_t* col
 {
 {
   if (!black && !color) return;
   if (!black && !color) return;
   if (!color) return writeImage(black, x, y, w, h, invert, mirror_y, pgm);
   if (!color) return writeImage(black, x, y, w, h, invert, mirror_y, pgm);
-  //Serial.print("writeImage("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print("writeImage_3c("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   if (!_init_display_done) _InitDisplay();
   if (!_init_display_done) _InitDisplay();
-  if (_paged && (x == 0) && (w == int16_t(WIDTH)) && (h < int16_t(HEIGHT)))
+  if (_initial_write) writeScreenBuffer();
+  int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
+  x -= x % 8; // byte boundary
+  w = wb * 8; // byte boundary
+  int16_t x1 = x < 0 ? 0 : x; // limit
+  int16_t y1 = y < 0 ? 0 : y; // limit
+  int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
+  int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
+  int16_t dx = x1 - x;
+  int16_t dy = y1 - y;
+  w1 -= dx;
+  h1 -= dy;
+  if ((w1 <= 0) || (h1 <= 0)) return;
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x10);
+  _startTransfer();
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    //Serial.println("paged");
-    _startTransfer();
-    for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(h) / 8; i++)
+    for (int16_t j = 0; j < w1 / 8; j++)
     {
     {
-      uint8_t black_data = black[i];
-      uint8_t color_data = color[i];
+      uint8_t black_data = 0xFF, color_data = 0xFF;
+      // use wb, h of bitmap for index!
+      uint32_t idx = mirror_y ? j + dx / 8 + uint32_t((h - 1 - (i + dy))) * wb : j + dx / 8 + uint32_t(i + dy) * wb;
+      if (pgm)
+      {
+#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
+        black_data = pgm_read_byte(&black[idx]);
+        color_data = pgm_read_byte(&color[idx]);
+#else
+        black_data = black[idx];
+        color_data = color[idx];
+#endif
+      }
+      else
+      {
+        black_data = black[idx];
+        color_data = color[idx];
+      }
+      if (invert)
+      {
+        black_data = ~black_data;
+        color_data = ~color_data;
+      }
       for (int16_t k = 0; k < 4; k++)
       for (int16_t k = 0; k < 4; k++)
       {
       {
         uint8_t out_data = 0x00;
         uint8_t out_data = 0x00;
@@ -149,75 +165,21 @@ void GxEPD2_730c_GDEY073D46::writeImage(const uint8_t* black, const uint8_t* col
         _transfer(out_data);
         _transfer(out_data);
       }
       }
     }
     }
-    _endTransfer();
-    if (y + h == HEIGHT) // last page
-    {
-      //Serial.println("paged ended");
-      _paged = false;
-    }
-  }
-  else
-  {
-    _paged = false;
-    int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
-    x -= x % 8; // byte boundary
-    w = wb * 8; // byte boundary
-    if ((w <= 0) || (h <= 0)) return;
-    _writeCommand(0x10);
-    _startTransfer();
-    for (int16_t i = 0; i < int16_t(HEIGHT); i++)
-    {
-      for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
-      {
-        uint8_t black_data = 0xFF, color_data = 0xFF;
-        if ((j >= x) && (j < x + w) && (i >= y) && (i < y + h))
-        {
-          uint32_t idx = mirror_y ? (j - x) / 8 + uint32_t((h - 1 - (i - y))) * wb : (j - x) / 8 + uint32_t(i - y) * wb;
-          if (pgm)
-          {
-#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-            black_data = pgm_read_byte(&black[idx]);
-            color_data = pgm_read_byte(&color[idx]);
-#else
-            black_data = black[idx];
-            color_data = color[idx];
-#endif
-          }
-          else
-          {
-            black_data = black[idx];
-            color_data = color[idx];
-          }
-          if (invert)
-          {
-            black_data = ~black_data;
-            color_data = ~color_data;
-          }
-        }
-        for (int16_t k = 0; k < 4; k++)
-        {
-          uint8_t out_data = 0x00;
-          for (int16_t l = 0; l < 2; l++)
-          {
-            out_data <<= 4;
-            if (!(color_data & 0x80)) out_data |= 0x04;
-            else out_data |= black_data & 0x80 ? 0x01 : 0x00;
-            black_data <<= 1;
-            color_data <<= 1;
-          }
-          _transfer(out_data);
-        }
-      }
-    }
-    _endTransfer();
   }
   }
+  _endTransfer();
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 }
 
 
 void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
+  //Serial.print("writeImagePart("); Serial.print(x_part); Serial.print(", "); Serial.print(y_part); Serial.print(", ");
+  //Serial.print(w_bitmap); Serial.print(", "); Serial.print(h_bitmap); Serial.print(", ");
+  //Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((y_part < 0) || (y_part >= h_bitmap)) return;
   if ((y_part < 0) || (y_part >= h_bitmap)) return;
@@ -225,7 +187,9 @@ void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t bitmap[], int16_t x_pa
   x_part -= x_part % 8; // byte boundary
   x_part -= x_part % 8; // byte boundary
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
-  x -= x % 8; // byte boundary
+  // make x, w multiple of 8
+  w += x % 8; // adjust for byte boundary of x
+  x -= x % 8; // byte boundary ox
   w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
@@ -236,32 +200,29 @@ void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t bitmap[], int16_t x_pa
   w1 -= dx;
   w1 -= dx;
   h1 -= dy;
   h1 -= dy;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
-  if (!_init_display_done) _InitDisplay();
+  _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
   _writeCommand(0x10);
   _startTransfer();
   _startTransfer();
-  for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
+    for (int16_t j = 0; j < w1 / 8; j++)
     {
     {
-      uint8_t data = 0xFF;
-      if ((j >= x1) && (j < x1 + w) && (i >= y1) && (i < y1 + h))
+      uint8_t data;
+      // use wb_bitmap, h_bitmap of bitmap for index!
+      uint32_t idx = mirror_y ? x_part / 8 + j + dx / 8 + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / 8 + j + dx / 8 + uint32_t(y_part + i + dy) * wb_bitmap;
+      if (pgm)
       {
       {
-        // use wb_bitmap, h_bitmap of bitmap for index!
-        uint32_t idx = mirror_y ? (x_part + j - x1) / 8 + uint32_t((h_bitmap - 1 - (y_part + i - y1))) * wb_bitmap : (x_part + j - x1) / 8 + uint32_t(y_part + i - y1) * wb_bitmap;
-        if (pgm)
-        {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-          data = pgm_read_byte(&bitmap[idx]);
+        data = pgm_read_byte(&bitmap[idx]);
 #else
 #else
-          data = bitmap[idx];
+        data = bitmap[idx];
 #endif
 #endif
-        }
-        else
-        {
-          data = bitmap[idx];
-        }
-        if (invert) data = ~data;
       }
       }
+      else
+      {
+        data = bitmap[idx];
+      }
+      if (invert) data = ~data;
       for (int16_t k = 0; k < 4; k++)
       for (int16_t k = 0; k < 4; k++)
       {
       {
         uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
         uint8_t data2 = (data & 0x80 ? 0x10 : 0x00) | (data & 0x40 ? 0x01 : 0x00);
@@ -277,12 +238,14 @@ void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t bitmap[], int16_t x_pa
 void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
-  //Serial.print("writeImagePart("); Serial.print(x_part); Serial.print(", "); Serial.print(y_part); Serial.print(", ");
+  //Serial.print("writeImagePart_3c("); Serial.print(x_part); Serial.print(", "); Serial.print(y_part); Serial.print(", ");
   //Serial.print(w_bitmap); Serial.print(", "); Serial.print(h_bitmap); Serial.print(", ");
   //Serial.print(w_bitmap); Serial.print(", "); Serial.print(h_bitmap); Serial.print(", ");
   //Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
   //Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   if (!black && !color) return;
   if (!black && !color) return;
   if (!color) return writeImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   if (!color) return writeImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
@@ -291,7 +254,9 @@ void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t* black, const uint8_t*
   x_part -= x_part % 8; // byte boundary
   x_part -= x_part % 8; // byte boundary
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
-  x -= x % 8; // byte boundary
+  // make x, w multiple of 8
+  w += x % 8; // adjust for byte boundary of x
+  x -= x % 8; // byte boundary ox
   w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
   int16_t y1 = y < 0 ? 0 : y; // limit
@@ -302,38 +267,35 @@ void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t* black, const uint8_t*
   w1 -= dx;
   w1 -= dx;
   h1 -= dy;
   h1 -= dy;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
-  if (!_init_display_done) _InitDisplay();
+  _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
   _writeCommand(0x10);
   _startTransfer();
   _startTransfer();
-  for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    for (int16_t j = 0; j < int16_t(WIDTH); j += 8)
+    for (int16_t j = 0; j < w1 / 8; j++)
     {
     {
       uint8_t black_data = 0xFF, color_data = 0xFF;
       uint8_t black_data = 0xFF, color_data = 0xFF;
-      if ((j >= x1) && (j < x1 + w) && (i >= y1) && (i < y1 + h))
+      // use wb_bitmap, h_bitmap of bitmap for index!
+      uint32_t idx = mirror_y ? x_part / 8 + j + dx / 8 + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / 8 + j + dx / 8 + uint32_t(y_part + i + dy) * wb_bitmap;
+      if (pgm)
       {
       {
-        // use wb_bitmap, h_bitmap of bitmap for index!
-        uint32_t idx = mirror_y ? (x_part + j - x1) / 8 + uint32_t((h_bitmap - 1 - (y_part + i - y1))) * wb_bitmap : (x_part + j - x1) / 8 + uint32_t(y_part + i - y1) * wb_bitmap;
-        if (pgm)
-        {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-          black_data = pgm_read_byte(&black[idx]);
-          color_data = pgm_read_byte(&color[idx]);
+        black_data = pgm_read_byte(&black[idx]);
+        color_data = pgm_read_byte(&color[idx]);
 #else
 #else
-          black_data = black[idx];
-          color_data = color[idx];
+        black_data = black[idx];
+        color_data = color[idx];
 #endif
 #endif
-        }
-        else
-        {
-          black_data = black[idx];
-          color_data = color[idx];
-        }
-        if (invert)
-        {
-          black_data = ~black_data;
-          color_data = ~color_data;
-        }
+      }
+      else
+      {
+        black_data = black[idx];
+        color_data = color[idx];
+      }
+      if (invert)
+      {
+        black_data = ~black_data;
+        color_data = ~color_data;
       }
       }
       for (int16_t k = 0; k < 4; k++)
       for (int16_t k = 0; k < 4; k++)
       {
       {
@@ -356,80 +318,61 @@ void GxEPD2_730c_GDEY073D46::writeImagePart(const uint8_t* black, const uint8_t*
 
 
 void GxEPD2_730c_GDEY073D46::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_730c_GDEY073D46::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
-  if (data1)
+  if (!data1) return;
+  //Serial.print("writeNative("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
+  uint32_t wb = (w + 1) / 2; // width bytes, bitmaps are padded
+  x -= x % 2; // byte boundary
+  w = wb * 2; // byte boundary
+  int16_t x1 = x < 0 ? 0 : x; // limit
+  int16_t y1 = y < 0 ? 0 : y; // limit
+  int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
+  int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
+  int16_t dx = x1 - x;
+  int16_t dy = y1 - y;
+  w1 -= dx;
+  h1 -= dy;
+  if ((w1 <= 0) || (h1 <= 0)) return;
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x10);
+  _startTransfer();
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    //Serial.print("writeNative("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
-    //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
-    delay(1); // yield() to avoid WDT on ESP8266 and ESP32
-    if (!_init_display_done) _InitDisplay();
-    if (_paged && (x == 0) && (w == int16_t(WIDTH)) && (h < int16_t(HEIGHT)))
-    {
-      //Serial.println("paged");
-      _startTransfer();
-      for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(h) / 2; i++)
-      {
-        uint8_t data = data1[i];
-        _transfer(data);
-      }
-      _endTransfer();
-      if (y + h == HEIGHT) // last page
-      {
-        //Serial.println("paged ended");
-        _paged = false;
-      }
-    }
-    else
+    for (int16_t j = 0; j < w1 / 2; j++)
     {
     {
-      _paged = false;
-      int16_t wb = (w + 1) / 2; // width bytes, bitmaps are padded
-      x -= x % 2; // byte boundary
-      w = wb * 2; // byte boundary
-      if ((w <= 0) || (h <= 0)) return;
-      _writeCommand(0x10);
-      _startTransfer();
-      for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+      uint8_t data;
+      // use wb, h of bitmap for index!
+      uint32_t idx = mirror_y ? j + dx / 2 + uint32_t((h - 1 - (i + dy))) * wb : j + dx / 2 + uint32_t(i + dy) * wb;
+      if (pgm)
       {
       {
-        for (int16_t j = 0; j < int16_t(WIDTH); j += 2)
-        {
-          uint8_t data = 0x11;
-          if (data1)
-          {
-            if ((j >= x) && (j < x + w) && (i >= y) && (i < y + h))
-            {
-              uint32_t idx = mirror_y ? (j - x) / 2 + uint32_t((h - 1 - (i - y))) * wb : (j - x) / 2 + uint32_t(i - y) * wb;
-              if (pgm)
-              {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-                data = pgm_read_byte(&data1[idx]);
+        data = pgm_read_byte(&data1[idx]);
 #else
 #else
-                data = data1[idx];
+        data = data1[idx];
 #endif
 #endif
-              }
-              else
-              {
-                data = data1[idx];
-              }
-              if (invert) data = ~data;
-            }
-          }
-          _transfer(data);
-        }
       }
       }
-      _endTransfer();
+      else
+      {
+        data = data1[idx];
+      }
+      if (invert) data = ~data;
+      _transfer(data);
     }
     }
-    delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   }
   }
+  _endTransfer();
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 }
 
 
 void GxEPD2_730c_GDEY073D46::writeNativePart(const uint8_t* data1, const uint8_t* data2, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_730c_GDEY073D46::writeNativePart(const uint8_t* data1, const uint8_t* data2, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
-  //Serial.print("writeNativePart("); Serial.print(x_part); Serial.print(", "); Serial.print(y_part); Serial.print(", ");
-  //Serial.print(w_bitmap); Serial.print(", "); Serial.print(h_bitmap); Serial.print(", ");
-  //Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
-  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   if (!data1) return;
   if (!data1) return;
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((x_part < 0) || (x_part >= w_bitmap)) return;
   if ((y_part < 0) || (y_part >= h_bitmap)) return;
   if ((y_part < 0) || (y_part >= h_bitmap)) return;
@@ -437,6 +380,7 @@ void GxEPD2_730c_GDEY073D46::writeNativePart(const uint8_t* data1, const uint8_t
   x_part -= x_part % 2; // byte boundary
   x_part -= x_part % 2; // byte boundary
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
   h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
+  w += x % 2; // adjust for byte boundary of x
   x -= x % 2; // byte boundary
   x -= x % 2; // byte boundary
   w = 2 * ((w + 1) / 2); // byte boundary, bitmaps are padded
   w = 2 * ((w + 1) / 2); // byte boundary, bitmaps are padded
   int16_t x1 = x < 0 ? 0 : x; // limit
   int16_t x1 = x < 0 ? 0 : x; // limit
@@ -448,32 +392,29 @@ void GxEPD2_730c_GDEY073D46::writeNativePart(const uint8_t* data1, const uint8_t
   w1 -= dx;
   w1 -= dx;
   h1 -= dy;
   h1 -= dy;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if ((w1 <= 0) || (h1 <= 0)) return;
-  if (!_init_display_done) _InitDisplay();
+  _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
   _writeCommand(0x10);
   _startTransfer();
   _startTransfer();
-  for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    for (int16_t j = 0; j < int16_t(WIDTH); j += 2)
+    for (int16_t j = 0; j < w1 / 2; j++)
     {
     {
-      uint8_t data = 0x11;
-      if ((j >= x1) && (j < x1 + w) && (i >= y1) && (i < y1 + h))
+      uint8_t data;
+      // use wb_bitmap, h_bitmap of bitmap for index!
+      uint32_t idx = mirror_y ? x_part / 2 + j + dx / 2 + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / 2 + j + dx / 2 + uint32_t(y_part + i + dy) * wb_bitmap;
+      if (pgm)
       {
       {
-        // use wb_bitmap, h_bitmap of bitmap for index!
-        uint32_t idx = mirror_y ? (x_part + j - x1) / 2 + uint32_t((h_bitmap - 1 - (y_part + i - y1))) * wb_bitmap : (x_part + j - x1) / 2 + uint32_t(y_part + i - y1) * wb_bitmap;
-        if (pgm)
-        {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-          data = pgm_read_byte(&data1[idx]);
+        data = pgm_read_byte(&data1[idx]);
 #else
 #else
-          data = data1[idx];
+        data = data1[idx];
 #endif
 #endif
-        }
-        else
-        {
-          data = data1[idx];
-        }
-        if (invert) data = ~data;
       }
       }
+      else
+      {
+        data = data1[idx];
+      }
+      if (invert) data = ~data;
       _transfer(data);
       _transfer(data);
     }
     }
   }
   }
@@ -516,6 +457,9 @@ void GxEPD2_730c_GDEY073D46::drawNative(const uint8_t* data1, const uint8_t* dat
 void GxEPD2_730c_GDEY073D46::refresh(bool partial_update_mode)
 void GxEPD2_730c_GDEY073D46::refresh(bool partial_update_mode)
 {
 {
   _PowerOn();
   _PowerOn();
+  _setPartialRamArea(0, 0, WIDTH, HEIGHT);
+  _writeCommand(0x50);
+  _writeData(0x3F);
   _writeCommand(0x12); // Display Refresh
   _writeCommand(0x12); // Display Refresh
   _writeData(0x00);
   _writeData(0x00);
   delay(1);
   delay(1);
@@ -525,6 +469,10 @@ void GxEPD2_730c_GDEY073D46::refresh(bool partial_update_mode)
 void GxEPD2_730c_GDEY073D46::refresh(int16_t x, int16_t y, int16_t w, int16_t h)
 void GxEPD2_730c_GDEY073D46::refresh(int16_t x, int16_t y, int16_t w, int16_t h)
 {
 {
   _PowerOn();
   _PowerOn();
+  if (usePartialUpdate) _setPartialRamArea(x, y, w, h);
+  else _setPartialRamArea(0, 0, WIDTH, HEIGHT);
+  _writeCommand(0x50);
+  _writeData(0x3F); // border white, no floating?
   _writeCommand(0x12); // Display Refresh
   _writeCommand(0x12); // Display Refresh
   _writeData(0x00);
   _writeData(0x00);
   delay(1);
   delay(1);
@@ -548,11 +496,22 @@ void GxEPD2_730c_GDEY073D46::hibernate()
   }
   }
 }
 }
 
 
-void GxEPD2_730c_GDEY073D46::setPaged()
+void GxEPD2_730c_GDEY073D46::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
 {
 {
-  _paged = true;
-  if (!_init_display_done) _InitDisplay();
-  _writeCommand(0x10);
+  //Serial.print("_setPartialRamArea("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
+  uint16_t xe = x + w - 1;
+  uint16_t ye = y + h; // controller issue (one more)
+  _writeCommand(0x83); // partial window
+  _writeData(x / 256);
+  _writeData(x % 256);
+  _writeData(xe / 256);
+  _writeData(xe % 256);
+  _writeData(y / 256);
+  _writeData(y % 256);
+  _writeData(ye / 256);
+  _writeData(ye % 256);
+  _writeData(0x01);
 }
 }
 
 
 void GxEPD2_730c_GDEY073D46::_PowerOn()
 void GxEPD2_730c_GDEY073D46::_PowerOn()
@@ -662,17 +621,37 @@ void GxEPD2_730c_GDEY073D46::_InitDisplay()
   _init_display_done = true;
   _init_display_done = true;
 }
 }
 
 
-uint8_t GxEPD2_730c_GDEY073D46::_colorOfDemoBitmap(uint8_t from)
+uint8_t GxEPD2_730c_GDEY073D46::_colorOfDemoBitmap(uint8_t from, int16_t mode)
 {
 {
-  switch (from)
+  switch (mode)
   {
   {
-    case 0xFF: return (0x01); // white;
-    case 0xFC: return (0x05); // yellow;
-    case 0xF1: return (0x06); // orange;
-    case 0xE5: return (0x04); // red;
-    case 0x4B: return (0x03); // blue;
-    case 0x39: return (0x02); // green;
-    case 0x00: return (0x00); // black;
+    case 0:
+      {
+        switch (from)
+        {
+          case 0xFF: return (0x01); // white;
+          case 0xFC: return (0x05); // yellow;
+          case 0xF1: return (0x06); // orange;
+          case 0xE5: return (0x04); // red;
+          case 0x4B: return (0x03); // blue;
+          case 0x39: return (0x02); // green;
+          case 0x00: return (0x00); // black;
+          default: return (0x01); // white;
+        }
+      }
+    case 1:
+      {
+        switch (from)
+        {
+          case 0x00: return (0x00); // black;
+          case 0xff: return (0x01); // white;
+          case 0xfc: return (0x05); // yellow;
+          case 0xE0: return (0x04); // red;
+          case 0x03: return (0x03); // blue;
+          case 0x1c: return (0x02); // green;
+          default: return (0x01); // white;
+        }
+      }
     default: return (0x01); // white;
     default: return (0x01); // white;
   }
   }
 }
 }
@@ -680,51 +659,50 @@ uint8_t GxEPD2_730c_GDEY073D46::_colorOfDemoBitmap(uint8_t from)
 void GxEPD2_730c_GDEY073D46::writeDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode, bool mirror_y, bool pgm)
 void GxEPD2_730c_GDEY073D46::writeDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode, bool mirror_y, bool pgm)
 {
 {
   (void) mode;
   (void) mode;
-  if (data1)
+  if (!data1) return;
+  //Serial.print("writeDemoBitmap("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
+  //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  if (!_init_display_done) _InitDisplay();
+  if (_initial_write) writeScreenBuffer();
+  int16_t x1 = x < 0 ? 0 : x; // limit
+  int16_t y1 = y < 0 ? 0 : y; // limit
+  int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
+  int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
+  int16_t dx = x1 - x;
+  int16_t dy = y1 - y;
+  w1 -= dx;
+  h1 -= dy;
+  if ((w1 <= 0) || (h1 <= 0)) return;
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x10);
+  _startTransfer();
+  for (int16_t i = 0; i < h1; i++)
   {
   {
-    //Serial.print("writeNative("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", ");
-    //Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
-    if (!_init_display_done) _InitDisplay();
-    delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+    for (int16_t j = 0; j < w1; j += 2)
     {
     {
-      _paged = false;
-      if ((w <= 0) || (h <= 0)) return;
-      _writeCommand(0x10);
-      _startTransfer();
-      for (int16_t i = 0; i < int16_t(HEIGHT); i++)
+      uint8_t data = 0x11;
+      uint32_t idx = mirror_y ? j + dx + uint32_t((h - 1 - (i + dy))) * w : j + dx + uint32_t(i + dy) * w;
+      if (pgm)
       {
       {
-        for (int16_t j = 0; j < int16_t(WIDTH); j += 2)
-        {
-          uint8_t data = 0x11;
-          if (data1)
-          {
-            if ((j >= x) && (j < x + w) && (i >= y) && (i < y + h))
-            {
-              uint32_t idx = mirror_y ? (j - x) + uint32_t((h - 1 - (i - y))) * w : (j - x) + uint32_t(i - y) * w;
-              if (pgm)
-              {
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
 #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
-                data = _colorOfDemoBitmap(pgm_read_byte(&data1[idx++])) << 4;
-                data |= _colorOfDemoBitmap(pgm_read_byte(&data1[idx]));
+        data = _colorOfDemoBitmap(pgm_read_byte(&data1[idx++]), mode) << 4;
+        data |= _colorOfDemoBitmap(pgm_read_byte(&data1[idx]), mode);
 #else
 #else
-                data = _colorOfDemoBitmap(data1[idx++]) << 4;
-                data |= _colorOfDemoBitmap(data1[idx]);
+        data = _colorOfDemoBitmap(data1[idx++], mode) << 4;
+        data |= _colorOfDemoBitmap(data1[idx], mode);
 #endif
 #endif
-              }
-              else
-              {
-                data = _colorOfDemoBitmap(data1[idx++]) << 4;
-                data |= _colorOfDemoBitmap(data1[idx]);
-              }
-            }
-          }
-          _transfer(data);
-        }
       }
       }
-      _endTransfer();
+      else
+      {
+        data = _colorOfDemoBitmap(data1[idx++], mode) << 4;
+        data |= _colorOfDemoBitmap(data1[idx], mode);
+      }
+      _transfer(data);
     }
     }
-    delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   }
   }
+  _endTransfer();
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 }
 
 
 void GxEPD2_730c_GDEY073D46::drawDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode, bool mirror_y, bool pgm)
 void GxEPD2_730c_GDEY073D46::drawDemoBitmap(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, int16_t mode, bool mirror_y, bool pgm)

+ 4 - 5
src/epd7c/GxEPD2_730c_GDEY073D46.h

@@ -25,7 +25,8 @@ class GxEPD2_730c_GDEY073D46 : public GxEPD2_EPD
     static const uint16_t HEIGHT = 480;
     static const uint16_t HEIGHT = 480;
     static const GxEPD2::Panel panel = GxEPD2::GDEY073D46;
     static const GxEPD2::Panel panel = GxEPD2::GDEY073D46;
     static const bool hasColor = true;
     static const bool hasColor = true;
-    static const bool hasPartialUpdate = false;
+    static const bool hasPartialUpdate = true;
+    static const bool usePartialUpdate = false; // force full screen update, else looks horrible
     static const bool hasFastPartialUpdate = false;
     static const bool hasFastPartialUpdate = false;
     static const uint16_t power_on_time = 200; // ms, e.g. 172000us
     static const uint16_t power_on_time = 200; // ms, e.g. 172000us
     static const uint16_t power_off_time = 150; // ms, e.g. 145000us
     static const uint16_t power_off_time = 150; // ms, e.g. 145000us
@@ -65,14 +66,12 @@ class GxEPD2_730c_GDEY073D46 : public GxEPD2_EPD
     void refresh(int16_t x, int16_t y, int16_t w, int16_t h); // screen refresh from controller memory, partial screen
     void refresh(int16_t x, int16_t y, int16_t w, int16_t h); // screen refresh from controller memory, partial screen
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
     void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
-    void setPaged(); // for GxEPD2_154c and GxEPD2_565c and GxEPD2_730c_GDEY073D46 paged workaround
   private:
   private:
-    uint8_t _colorOfDemoBitmap(uint8_t from);
+    void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
+    uint8_t _colorOfDemoBitmap(uint8_t from, int16_t mode = 0);
     void _PowerOn();
     void _PowerOn();
     void _PowerOff();
     void _PowerOff();
     void _InitDisplay();
     void _InitDisplay();
-  private:
-    bool _paged;
 };
 };
 
 
 #endif
 #endif

+ 11 - 0
src/gdem/GxEPD2_1020_GDEM102T91.cpp

@@ -70,6 +70,11 @@ void GxEPD2_1020_GDEM102T91::writeImageAgain(const uint8_t bitmap[], int16_t x,
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_1020_GDEM102T91::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_1020_GDEM102T91::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_1020_GDEM102T91::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -130,6 +135,12 @@ void GxEPD2_1020_GDEM102T91::writeImagePartAgain(const uint8_t bitmap[], int16_t
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_1020_GDEM102T91::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_1020_GDEM102T91::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_1020_GDEM102T91::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdem/GxEPD2_1020_GDEM102T91.h

@@ -41,8 +41,11 @@ class GxEPD2_1020_GDEM102T91 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdem/GxEPD2_1085_GDEM1085T51.cpp

@@ -101,6 +101,11 @@ void GxEPD2_1085_GDEM1085T51::writeImageAgain(const uint8_t bitmap[], int16_t x,
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_1085_GDEM1085T51::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_1085_GDEM1085T51::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_1085_GDEM1085T51::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   //Serial.print("_writeImage("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", "); Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
   //Serial.print("_writeImage("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", "); Serial.print(w); Serial.print(", "); Serial.print(h); Serial.println(")");
@@ -201,6 +206,12 @@ void GxEPD2_1085_GDEM1085T51::writeImagePartAgain(const uint8_t bitmap[], int16_
   _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_1085_GDEM1085T51::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_1085_GDEM1085T51::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_1085_GDEM1085T51::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdem/GxEPD2_1085_GDEM1085T51.h

@@ -43,8 +43,11 @@ class GxEPD2_1085_GDEM1085T51 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     //void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     //void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdem/GxEPD2_1330_GDEM133T91.cpp

@@ -70,6 +70,11 @@ void GxEPD2_1330_GDEM133T91::writeImageAgain(const uint8_t bitmap[], int16_t x,
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_1330_GDEM133T91::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_1330_GDEM133T91::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_1330_GDEM133T91::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -130,6 +135,12 @@ void GxEPD2_1330_GDEM133T91::writeImagePartAgain(const uint8_t bitmap[], int16_t
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_1330_GDEM133T91::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_1330_GDEM133T91::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_1330_GDEM133T91::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdem/GxEPD2_1330_GDEM133T91.h

@@ -41,8 +41,11 @@ class GxEPD2_1330_GDEM133T91 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdem/GxEPD2_397_GDEM0397T81.cpp

@@ -75,6 +75,11 @@ void GxEPD2_397_GDEM0397T81::writeImageAgain(const uint8_t bitmap[], int16_t x,
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_397_GDEM0397T81::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_397_GDEM0397T81::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_397_GDEM0397T81::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -135,6 +140,12 @@ void GxEPD2_397_GDEM0397T81::writeImagePartAgain(const uint8_t bitmap[], int16_t
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_397_GDEM0397T81::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_397_GDEM0397T81::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_397_GDEM0397T81::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdem/GxEPD2_397_GDEM0397T81.h

@@ -42,8 +42,11 @@ class GxEPD2_397_GDEM0397T81 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdeq/GxEPD2_310_GDEQ031T10.cpp

@@ -68,6 +68,11 @@ void GxEPD2_310_GDEQ031T10::writeImageAgain(const uint8_t bitmap[], int16_t x, i
   //_writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current, not needed
   //_writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current, not needed
 }
 }
 
 
+void GxEPD2_310_GDEQ031T10::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_310_GDEQ031T10::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_310_GDEQ031T10::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -130,6 +135,12 @@ void GxEPD2_310_GDEQ031T10::writeImagePartAgain(const uint8_t bitmap[], int16_t
   //_writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current, not needed
   //_writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); // set current, not needed
 }
 }
 
 
+void GxEPD2_310_GDEQ031T10::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_310_GDEQ031T10::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_310_GDEQ031T10::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdeq/GxEPD2_310_GDEQ031T10.h

@@ -43,8 +43,11 @@ class GxEPD2_310_GDEQ031T10 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdeq/GxEPD2_426_GDEQ0426T82.cpp

@@ -69,6 +69,11 @@ void GxEPD2_426_GDEQ0426T82::writeImageAgain(const uint8_t bitmap[], int16_t x,
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_426_GDEQ0426T82::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_426_GDEQ0426T82::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_426_GDEQ0426T82::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -129,6 +134,12 @@ void GxEPD2_426_GDEQ0426T82::writeImagePartAgain(const uint8_t bitmap[], int16_t
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_426_GDEQ0426T82::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_426_GDEQ0426T82::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_426_GDEQ0426T82::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdeq/GxEPD2_426_GDEQ0426T82.h

@@ -42,8 +42,11 @@ class GxEPD2_426_GDEQ0426T82 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdeq/GxEPD2_583_GDEQ0583T31.cpp

@@ -55,6 +55,11 @@ void GxEPD2_583_GDEQ0583T31::writeImageForFullRefresh(const uint8_t bitmap[], in
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImage(0x13, bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_583_GDEQ0583T31::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_583_GDEQ0583T31::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_583_GDEQ0583T31::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
   if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
@@ -110,6 +115,12 @@ void GxEPD2_583_GDEQ0583T31::writeImagePart(const uint8_t bitmap[], int16_t x_pa
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x13, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_583_GDEQ0583T31::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x10, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_583_GDEQ0583T31::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_583_GDEQ0583T31::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
     int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdeq/GxEPD2_583_GDEQ0583T31.h

@@ -42,8 +42,11 @@ class GxEPD2_583_GDEQ0583T31 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdey/GxEPD2_154_GDEY0154D67.cpp

@@ -69,6 +69,11 @@ void GxEPD2_154_GDEY0154D67::writeImageAgain(const uint8_t bitmap[], int16_t x,
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_154_GDEY0154D67::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_154_GDEY0154D67::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_154_GDEY0154D67::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -129,6 +134,12 @@ void GxEPD2_154_GDEY0154D67::writeImagePartAgain(const uint8_t bitmap[], int16_t
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_154_GDEY0154D67::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_154_GDEY0154D67::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_154_GDEY0154D67::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdey/GxEPD2_154_GDEY0154D67.h

@@ -42,8 +42,11 @@ class GxEPD2_154_GDEY0154D67 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdey/GxEPD2_213_GDEY0213B74.cpp

@@ -69,6 +69,11 @@ void GxEPD2_213_GDEY0213B74::writeImageAgain(const uint8_t bitmap[], int16_t x,
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_213_GDEY0213B74::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_GDEY0213B74::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_213_GDEY0213B74::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -128,6 +133,12 @@ void GxEPD2_213_GDEY0213B74::writeImagePartAgain(const uint8_t bitmap[], int16_t
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_213_GDEY0213B74::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_213_GDEY0213B74::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_213_GDEY0213B74::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdey/GxEPD2_213_GDEY0213B74.h

@@ -42,8 +42,11 @@ class GxEPD2_213_GDEY0213B74 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdey/GxEPD2_266_GDEY0266T90.cpp

@@ -69,6 +69,11 @@ void GxEPD2_266_GDEY0266T90::writeImageAgain(const uint8_t bitmap[], int16_t x,
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_266_GDEY0266T90::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_266_GDEY0266T90::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_266_GDEY0266T90::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -128,6 +133,12 @@ void GxEPD2_266_GDEY0266T90::writeImagePartAgain(const uint8_t bitmap[], int16_t
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_266_GDEY0266T90::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_266_GDEY0266T90::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_266_GDEY0266T90::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdey/GxEPD2_266_GDEY0266T90.h

@@ -42,8 +42,11 @@ class GxEPD2_266_GDEY0266T90 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

+ 11 - 0
src/gdey/GxEPD2_270_GDEY027T91.cpp

@@ -69,6 +69,11 @@ void GxEPD2_270_GDEY027T91::writeImageAgain(const uint8_t bitmap[], int16_t x, i
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
   _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); // set current
 }
 }
 
 
+void GxEPD2_270_GDEY027T91::writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_270_GDEY027T91::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 void GxEPD2_270_GDEY027T91::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
@@ -128,6 +133,12 @@ void GxEPD2_270_GDEY027T91::writeImagePartAgain(const uint8_t bitmap[], int16_t
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
   _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
 }
 }
 
 
+void GxEPD2_270_GDEY027T91::writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+    int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  _writeImagePart(0x26, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
+}
+
 void GxEPD2_270_GDEY027T91::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
 void GxEPD2_270_GDEY027T91::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
                                      int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
 {
 {

+ 3 - 0
src/gdey/GxEPD2_270_GDEY027T91.h

@@ -42,8 +42,11 @@ class GxEPD2_270_GDEY027T91 : public GxEPD2_EPD
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     // write to controller memory, without screen refresh; x and w should be multiple of 8
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImageToPrevious(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void writeImagePartToPrevious(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
+                                int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
     void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
                         int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);

Неке датотеке нису приказане због велике количине промена