Răsfoiți Sursa

Version 1.2.8

- improved transfer speed for the bigger displays (3.71" and up)
ZinggJM 6 ani în urmă
părinte
comite
a7a74ba290

+ 3 - 1
README.md

@@ -80,7 +80,9 @@
 - promotion panels from suppliers are welcome, to add support to GxEPD2
 - donation panels from users are welcome, to add support to GxEPD2
 
-### Version 1.2.7
+### Version 1.2.8
+- improved transfer speed for the bigger displays (3.71" and up)
+#### Version 1.2.7
 - fix paged drawing of initial screen on GDEH029A1
 - sometimes true is false, if applied the wrong way round
 #### Version 1.2.6

+ 12 - 12
extras/sw_spi/src/GxEPD2_EPD.cpp

@@ -154,7 +154,7 @@ void GxEPD2_EPD::_writeCommand(uint8_t c)
   _beginTransaction(_spi_settings);
   if (_dc >= 0) digitalWrite(_dc, LOW);
   if (_cs >= 0) digitalWrite(_cs, LOW);
-  _transfer(c);
+  _spi_write(c);
   if (_cs >= 0) digitalWrite(_cs, HIGH);
   if (_dc >= 0) digitalWrite(_dc, HIGH);
   _endTransaction();
@@ -164,7 +164,7 @@ void GxEPD2_EPD::_writeData(uint8_t d)
 {
   _beginTransaction(_spi_settings);
   if (_cs >= 0) digitalWrite(_cs, LOW);
-  _transfer(d);
+  _spi_write(d);
   if (_cs >= 0) digitalWrite(_cs, HIGH);
   _endTransaction();
 }
@@ -175,7 +175,7 @@ void GxEPD2_EPD::_writeData(const uint8_t* data, uint16_t n)
   if (_cs >= 0) digitalWrite(_cs, LOW);
   for (uint8_t i = 0; i < n; i++)
   {
-    _transfer(*data++);
+    _spi_write(*data++);
   }
   if (_cs >= 0) digitalWrite(_cs, HIGH);
   _endTransaction();
@@ -187,11 +187,11 @@ void GxEPD2_EPD::_writeDataPGM(const uint8_t* data, uint16_t n, int16_t fill_wit
   if (_cs >= 0) digitalWrite(_cs, LOW);
   for (uint8_t i = 0; i < n; i++)
   {
-    _transfer(pgm_read_byte(&*data++));
+    _spi_write(pgm_read_byte(&*data++));
   }
   while (fill_with_zeroes > 0)
   {
-    _transfer(0x00);
+    _spi_write(0x00);
     fill_with_zeroes--;
   }
   if (_cs >= 0) digitalWrite(_cs, HIGH);
@@ -204,13 +204,13 @@ void GxEPD2_EPD::_writeDataPGM_sCS(const uint8_t* data, uint16_t n, int16_t fill
   for (uint8_t i = 0; i < n; i++)
   {
     if (_cs >= 0) digitalWrite(_cs, LOW);
-    _transfer(pgm_read_byte(&*data++));
+    _spi_write(pgm_read_byte(&*data++));
     if (_cs >= 0) digitalWrite(_cs, HIGH);
   }
   while (fill_with_zeroes > 0)
   {
     if (_cs >= 0) digitalWrite(_cs, LOW);
-    _transfer(0x00);
+    _spi_write(0x00);
     fill_with_zeroes--;
     if (_cs >= 0) digitalWrite(_cs, HIGH);
   }
@@ -222,11 +222,11 @@ void GxEPD2_EPD::_writeCommandData(const uint8_t* pCommandData, uint8_t datalen)
   _beginTransaction(_spi_settings);
   if (_dc >= 0) digitalWrite(_dc, LOW);
   if (_cs >= 0) digitalWrite(_cs, LOW);
-  _transfer(*pCommandData++);
+  _spi_write(*pCommandData++);
   if (_dc >= 0) digitalWrite(_dc, HIGH);
   for (uint8_t i = 0; i < datalen - 1; i++)  // sub the command
   {
-    _transfer(*pCommandData++);
+    _spi_write(*pCommandData++);
   }
   if (_cs >= 0) digitalWrite(_cs, HIGH);
   _endTransaction();
@@ -237,11 +237,11 @@ void GxEPD2_EPD::_writeCommandDataPGM(const uint8_t* pCommandData, uint8_t datal
   _beginTransaction(_spi_settings);
   if (_dc >= 0) digitalWrite(_dc, LOW);
   if (_cs >= 0) digitalWrite(_cs, LOW);
-  _transfer(pgm_read_byte(&*pCommandData++));
+  _spi_write(pgm_read_byte(&*pCommandData++));
   if (_dc >= 0) digitalWrite(_dc, HIGH);
   for (uint8_t i = 0; i < datalen - 1; i++)  // sub the command
   {
-    _transfer(pgm_read_byte(&*pCommandData++));
+    _spi_write(pgm_read_byte(&*pCommandData++));
   }
   if (_cs >= 0) digitalWrite(_cs, HIGH);
   _endTransaction();
@@ -252,7 +252,7 @@ void GxEPD2_EPD::_beginTransaction(const SPISettings& settings)
   if (_sck < 0) SPI.beginTransaction(settings);
 }
 
-void GxEPD2_EPD::_transfer(uint8_t data)
+void GxEPD2_EPD::_spi_write(uint8_t data)
 {
   if (_sck < 0) SPI.transfer(data);
   else

+ 4 - 1
extras/sw_spi/src/GxEPD2_EPD.h

@@ -97,8 +97,11 @@ class GxEPD2_EPD
     void _writeCommandData(const uint8_t* pCommandData, uint8_t datalen);
     void _writeCommandDataPGM(const uint8_t* pCommandData, uint8_t datalen);
     void _beginTransaction(const SPISettings& settings);
-    void _transfer(uint8_t data);
+    void _spi_write(uint8_t data);
     void _endTransaction();
+    void _startTransfer() {};
+    void _transfer(uint8_t value) {_writeData(value);};
+    void _endTransfer() {};
   public:
     void _waitWhileBusy(const char* comment = 0, uint16_t busy_time = 5000);
     void _writeCommand(uint8_t c);

+ 1 - 1
library.properties

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

+ 17 - 0
src/GxEPD2_EPD.cpp

@@ -222,3 +222,20 @@ void GxEPD2_EPD::_writeCommandDataPGM(const uint8_t* pCommandData, uint8_t datal
   if (_cs >= 0) digitalWrite(_cs, HIGH);
   SPI.endTransaction();
 }
+
+void GxEPD2_EPD::_startTransfer()
+{
+  SPI.beginTransaction(_spi_settings);
+  if (_cs >= 0) digitalWrite(_cs, LOW);
+}
+
+void GxEPD2_EPD::_transfer(uint8_t value)
+{
+  SPI.transfer(value);
+}
+
+void GxEPD2_EPD::_endTransfer()
+{
+  if (_cs >= 0) digitalWrite(_cs, HIGH);
+  SPI.endTransaction();
+}

+ 3 - 0
src/GxEPD2_EPD.h

@@ -95,6 +95,9 @@ class GxEPD2_EPD
     void _writeDataPGM_sCS(const uint8_t* data, uint16_t n, int16_t fill_with_zeroes = 0);
     void _writeCommandData(const uint8_t* pCommandData, uint8_t datalen);
     void _writeCommandDataPGM(const uint8_t* pCommandData, uint8_t datalen);
+    void _startTransfer();
+    void _transfer(uint8_t value);
+    void _endTransfer();
   protected:
     int8_t _cs, _dc, _rst, _busy, _busy_level;
     uint32_t _busy_timeout;

+ 20 - 1
src/epd/GxEPD2_1248.cpp

@@ -745,6 +745,7 @@ void GxEPD2_1248::ScreenPart::writeImagePart(uint8_t command, const uint8_t bitm
   delay(1);
   _setPartialRamArea(x1, y1, w1, h1);
   writeCommand(command);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -765,9 +766,10 @@ void GxEPD2_1248::ScreenPart::writeImagePart(uint8_t command, const uint8_t bitm
         data = bitmap[idx];
       }
       if (invert) data = ~data;
-      writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -809,3 +811,20 @@ void GxEPD2_1248::ScreenPart::_setPartialRamArea(uint16_t x, uint16_t y, uint16_
   writeData(ye % 256);
   writeData(0x01);
 }
+
+void GxEPD2_1248::ScreenPart::_startTransfer()
+{
+  SPI.beginTransaction(_spi_settings);
+  if (_cs >= 0) digitalWrite(_cs, LOW);
+}
+
+void GxEPD2_1248::ScreenPart::_transfer(uint8_t value)
+{
+  SPI.transfer(value);
+}
+
+void GxEPD2_1248::ScreenPart::_endTransfer()
+{
+  if (_cs >= 0) digitalWrite(_cs, HIGH);
+  SPI.endTransaction();
+}

+ 3 - 0
src/epd/GxEPD2_1248.h

@@ -121,6 +121,9 @@ class GxEPD2_1248 : public GxEPD2_EPD
         void writeData(uint8_t d);
       private:
         void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
+        void _startTransfer();
+        void _transfer(uint8_t value);
+        void _endTransfer();
       public:
         const uint16_t WIDTH, HEIGHT;
       private:

+ 12 - 4
src/epd/GxEPD2_371.cpp

@@ -30,17 +30,21 @@ void GxEPD2_371::writeScreenBuffer(uint8_t value)
   _initial_write = false; // initial full screen buffer clean done
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x13); // set current
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
   if (_initial_refresh)
   {
     _writeCommand(0x10); // preset previous
+    _startTransfer();
     for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
     {
-      _writeData(0xFF); // 0xFF is white
+      _transfer(0xFF); // 0xFF is white
     }
+    _endTransfer();
   }
 }
 
@@ -64,6 +68,7 @@ void GxEPD2_371::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -84,9 +89,10 @@ void GxEPD2_371::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
         data = bitmap[idx];
       }
       if (invert) data = ~data;
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -118,6 +124,7 @@ void GxEPD2_371::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -138,9 +145,10 @@ void GxEPD2_371::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
         data = bitmap[idx];
       }
       if (invert) data = ~data;
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }

+ 14 - 4
src/epd/GxEPD2_420.cpp

@@ -31,16 +31,20 @@ void GxEPD2_420::writeScreenBuffer(uint8_t value)
   if (_initial_refresh)
   {
     _writeCommand(0x10); // init old data
+    _startTransfer();
     for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
     {
-      _writeData(value);
+      _transfer(value);
     }
+    _endTransfer();
   }
   _writeCommand(0x13);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
 }
 
 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)
@@ -60,9 +64,11 @@ void GxEPD2_420::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   h1 -= dy;
   if ((w1 <= 0) || (h1 <= 0)) return;
   if (!_using_partial_mode) _Init_Part();
+  //uint32_t start = micros();
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -83,10 +89,12 @@ void GxEPD2_420::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
         data = bitmap[idx];
       }
       if (invert) data = ~data;
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
+  //Serial.print("GxEPD2_420::writeImage took "); Serial.println(micros() - start);
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
 
@@ -117,6 +125,7 @@ void GxEPD2_420::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -137,9 +146,10 @@ void GxEPD2_420::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
         data = bitmap[idx];
       }
       if (invert) data = ~data;
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }

+ 11 - 3
src/epd/GxEPD2_583.cpp

@@ -29,10 +29,12 @@ void GxEPD2_583::writeScreenBuffer(uint8_t value)
   if (!_using_partial_mode) _Init_Part();
   if (value == 0xFF) value = 0x33; // white value for this controller
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 2; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
 }
 
 void GxEPD2_583::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
@@ -55,6 +57,7 @@ void GxEPD2_583::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -78,6 +81,7 @@ void GxEPD2_583::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
       _send8pixel(~data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -109,6 +113,7 @@ void GxEPD2_583::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -132,6 +137,7 @@ void GxEPD2_583::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
       _send8pixel(~data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -175,6 +181,7 @@ void GxEPD2_583::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t
     _writeCommand(0x91); // partial in
     _setPartialRamArea(x1, y1, w1, h1);
     _writeCommand(0x10);
+    _startTransfer();
     for (int16_t i = 0; i < h1; i++)
     {
       for (int16_t j = 0; j < w1 / 2; j++)
@@ -195,9 +202,10 @@ void GxEPD2_583::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t
           data = data1[idx];
         }
         if (invert) data = ~data;
-        _writeData(data);
+        _transfer(data);
       }
     }
+    _endTransfer();
     _writeCommand(0x92); // partial out
     delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   }
@@ -289,7 +297,7 @@ void GxEPD2_583::_send8pixel(uint8_t data)
     j++;
     t |= data & 0x80 ? 0x00 : 0x03;
     data <<= 1;
-    _writeData(t);
+    _transfer(t);
   }
 }
 

+ 11 - 3
src/epd/GxEPD2_750.cpp

@@ -29,10 +29,12 @@ void GxEPD2_750::writeScreenBuffer(uint8_t value)
   if (!_using_partial_mode) _Init_Part();
   if (value == 0xFF) value = 0x33; // white value for this controller
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 2; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
 }
 
 void GxEPD2_750::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
@@ -55,6 +57,7 @@ void GxEPD2_750::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -78,6 +81,7 @@ void GxEPD2_750::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_
       _send8pixel(~data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -109,6 +113,7 @@ void GxEPD2_750::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -132,6 +137,7 @@ void GxEPD2_750::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t
       _send8pixel(~data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -175,6 +181,7 @@ void GxEPD2_750::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t
     _writeCommand(0x91); // partial in
     _setPartialRamArea(x1, y1, w1, h1);
     _writeCommand(0x10);
+    _startTransfer();
     for (int16_t i = 0; i < h1; i++)
     {
       for (int16_t j = 0; j < w1 / 2; j++)
@@ -195,9 +202,10 @@ void GxEPD2_750::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t
           data = data1[idx];
         }
         if (invert) data = ~data;
-        _writeData(data);
+        _transfer(data);
       }
     }
+    _endTransfer();
     _writeCommand(0x92); // partial out
     delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   }
@@ -289,7 +297,7 @@ void GxEPD2_750::_send8pixel(uint8_t data)
     j++;
     t |= data & 0x80 ? 0x00 : 0x03;
     data <<= 1;
-    _writeData(t);
+    _transfer(t);
   }
 }
 

+ 12 - 4
src/epd/GxEPD2_750_T7.cpp

@@ -30,17 +30,21 @@ void GxEPD2_750_T7::writeScreenBuffer(uint8_t value)
   _initial_write = false; // initial full screen buffer clean done
   if (!_using_partial_mode) _Init_Part();
   _writeCommand(0x13); // set current
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
   if (_initial_refresh)
   {
     _writeCommand(0x10); // preset previous
+    _startTransfer();
     for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
     {
-      _writeData(0xFF); // 0xFF is white
+      _transfer(0xFF); // 0xFF is white
     }
+    _endTransfer();
   }
 }
 
@@ -64,6 +68,7 @@ void GxEPD2_750_T7::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -84,9 +89,10 @@ void GxEPD2_750_T7::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int
         data = bitmap[idx];
       }
       if (invert) data = ~data;
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -118,6 +124,7 @@ void GxEPD2_750_T7::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -138,9 +145,10 @@ void GxEPD2_750_T7::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16
         data = bitmap[idx];
       }
       if (invert) data = ~data;
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }

+ 24 - 8
src/epd3c/GxEPD2_420c.cpp

@@ -29,15 +29,19 @@ void GxEPD2_420c::clearScreen(uint8_t black_value, uint8_t color_value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(black_value);
+    _transfer(black_value);
   }
+  _endTransfer();
   _writeCommand(0x13);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(color_value);
+    _transfer(color_value);
   }
+  _endTransfer();
   _Update_Part();
   _writeCommand(0x92); // partial out
 }
@@ -54,15 +58,19 @@ void GxEPD2_420c::writeScreenBuffer(uint8_t black_value, uint8_t color_value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint16_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(black_value);
+    _transfer(black_value);
   }
+  _endTransfer();
   _writeCommand(0x13);
+  _startTransfer();
   for (uint16_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(color_value);
+    _transfer(color_value);
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
 }
 
@@ -91,6 +99,7 @@ void GxEPD2_420c::writeImage(const uint8_t* black, const uint8_t* color, int16_t
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -114,10 +123,12 @@ void GxEPD2_420c::writeImage(const uint8_t* black, const uint8_t* color, int16_t
         }
         if (invert) data = ~data;
       }
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -141,9 +152,10 @@ void GxEPD2_420c::writeImage(const uint8_t* black, const uint8_t* color, int16_t
         }
         if (invert) data = ~data;
       }
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -181,6 +193,7 @@ void GxEPD2_420c::writeImagePart(const uint8_t* black, const uint8_t* color, int
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -201,10 +214,12 @@ void GxEPD2_420c::writeImagePart(const uint8_t* black, const uint8_t* color, int
         data = black[idx];
       }
       if (invert) data = ~data;
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -228,9 +243,10 @@ void GxEPD2_420c::writeImagePart(const uint8_t* black, const uint8_t* color, int
         }
         if (invert) data = ~data;
       }
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }

+ 18 - 4
src/epd3c/GxEPD2_583c.cpp

@@ -25,10 +25,12 @@ void GxEPD2_583c::clearScreen(uint8_t value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 2; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
   _Update_Part();
   _writeCommand(0x92); // partial out
 }
@@ -40,10 +42,12 @@ void GxEPD2_583c::clearScreen(uint8_t black_value, uint8_t color_value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
     _send8pixel(~black_value, ~color_value);
   }
+  _endTransfer();
   _Update_Part();
   _writeCommand(0x92); // partial out
 }
@@ -56,10 +60,12 @@ void GxEPD2_583c::writeScreenBuffer(uint8_t value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 2; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
 }
 
@@ -70,10 +76,12 @@ void GxEPD2_583c::writeScreenBuffer(uint8_t black_value, uint8_t color_value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
     _send8pixel(~black_value, ~color_value);
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
 }
 
@@ -102,6 +110,7 @@ void GxEPD2_583c::writeImage(const uint8_t* black, const uint8_t* color, int16_t
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -150,6 +159,7 @@ void GxEPD2_583c::writeImage(const uint8_t* black, const uint8_t* color, int16_t
     yield();
 #endif
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -187,6 +197,7 @@ void GxEPD2_583c::writeImagePart(const uint8_t* black, const uint8_t* color, int
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -233,6 +244,7 @@ void GxEPD2_583c::writeImagePart(const uint8_t* black, const uint8_t* color, int
     yield();
 #endif
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -259,6 +271,7 @@ void GxEPD2_583c::writeNative(const uint8_t* data1, const uint8_t* data2, int16_
     _writeCommand(0x91); // partial in
     _setPartialRamArea(x1, y1, w1, h1);
     _writeCommand(0x10);
+    _startTransfer();
     for (int16_t i = 0; i < h1; i++)
     {
       for (int16_t j = 0; j < w1 / 2; j++)
@@ -279,9 +292,10 @@ void GxEPD2_583c::writeNative(const uint8_t* data1, const uint8_t* data2, int16_
           data = data1[idx];
         }
         if (invert) data = ~data;
-        _writeData(data);
+        _transfer(data);
       }
     }
+    _endTransfer();
     _writeCommand(0x92); // partial out
     delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   }
@@ -374,7 +388,7 @@ void GxEPD2_583c::_send8pixel(uint8_t black_data, uint8_t color_data)
     else t |= 0x03; // white
     black_data <<= 1;
     color_data <<= 1;
-    _writeData(t);
+    _transfer(t);
   }
 }
 

+ 18 - 4
src/epd3c/GxEPD2_750c.cpp

@@ -25,10 +25,12 @@ void GxEPD2_750c::clearScreen(uint8_t value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 2; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
   _Update_Part();
   _writeCommand(0x92); // partial out
 }
@@ -40,10 +42,12 @@ void GxEPD2_750c::clearScreen(uint8_t black_value, uint8_t color_value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
     _send8pixel(~black_value, ~color_value);
   }
+  _endTransfer();
   _Update_Part();
   _writeCommand(0x92); // partial out
 }
@@ -56,10 +60,12 @@ void GxEPD2_750c::writeScreenBuffer(uint8_t value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 2; i++)
   {
-    _writeData(value);
+    _transfer(value);
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
 }
 
@@ -70,10 +76,12 @@ void GxEPD2_750c::writeScreenBuffer(uint8_t black_value, uint8_t color_value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
     _send8pixel(~black_value, ~color_value);
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
 }
 
@@ -102,6 +110,7 @@ void GxEPD2_750c::writeImage(const uint8_t* black, const uint8_t* color, int16_t
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -147,6 +156,7 @@ void GxEPD2_750c::writeImage(const uint8_t* black, const uint8_t* color, int16_t
       _send8pixel(~black_data, ~color_data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -184,6 +194,7 @@ void GxEPD2_750c::writeImagePart(const uint8_t* black, const uint8_t* color, int
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -230,6 +241,7 @@ void GxEPD2_750c::writeImagePart(const uint8_t* black, const uint8_t* color, int
     yield();
 #endif
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -256,6 +268,7 @@ void GxEPD2_750c::writeNative(const uint8_t* data1, const uint8_t* data2, int16_
     _writeCommand(0x91); // partial in
     _setPartialRamArea(x1, y1, w1, h1);
     _writeCommand(0x10);
+    _startTransfer();
     for (int16_t i = 0; i < h1; i++)
     {
       for (int16_t j = 0; j < w1 / 2; j++)
@@ -276,9 +289,10 @@ void GxEPD2_750c::writeNative(const uint8_t* data1, const uint8_t* data2, int16_
           data = data1[idx];
         }
         if (invert) data = ~data;
-        _writeData(data);
+        _transfer(data);
       }
     }
+    _endTransfer();
     _writeCommand(0x92); // partial out
     delay(1); // yield() to avoid WDT on ESP8266 and ESP32
   }
@@ -371,7 +385,7 @@ void GxEPD2_750c::_send8pixel(uint8_t black_data, uint8_t color_data)
     else t |= 0x03; // white
     black_data <<= 1;
     color_data <<= 1;
-    _writeData(t);
+    _transfer(t);
   }
 }
 

+ 24 - 8
src/epd3c/GxEPD2_750c_Z08.cpp

@@ -30,15 +30,19 @@ void GxEPD2_750c_Z08::clearScreen(uint8_t black_value, uint8_t color_value)
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(black_value);
+    _transfer(black_value);
   }
+  _endTransfer();
   _writeCommand(0x13);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(~color_value);
+    _transfer(~color_value);
   }
+  _endTransfer();
   _Update_Part();
   _writeCommand(0x92); // partial out
 }
@@ -55,15 +59,19 @@ void GxEPD2_750c_Z08::writeScreenBuffer(uint8_t black_value, uint8_t color_value
   _writeCommand(0x91); // partial in
   _setPartialRamArea(0, 0, WIDTH, HEIGHT);
   _writeCommand(0x10);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(black_value);
+    _transfer(black_value);
   }
+  _endTransfer();
   _writeCommand(0x13);
+  _startTransfer();
   for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
   {
-    _writeData(~color_value);
+    _transfer(~color_value);
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
 }
 
@@ -92,6 +100,7 @@ void GxEPD2_750c_Z08::writeImage(const uint8_t* black, const uint8_t* color, int
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -115,10 +124,12 @@ void GxEPD2_750c_Z08::writeImage(const uint8_t* black, const uint8_t* color, int
         }
         if (invert) data = ~data;
       }
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -142,9 +153,10 @@ void GxEPD2_750c_Z08::writeImage(const uint8_t* black, const uint8_t* color, int
         }
         if (invert) data = ~data;
       }
-      _writeData(~data);
+      _transfer(~data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }
@@ -182,6 +194,7 @@ void GxEPD2_750c_Z08::writeImagePart(const uint8_t* black, const uint8_t* color,
   _writeCommand(0x91); // partial in
   _setPartialRamArea(x1, y1, w1, h1);
   _writeCommand(0x10);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -202,10 +215,12 @@ void GxEPD2_750c_Z08::writeImagePart(const uint8_t* black, const uint8_t* color,
         data = black[idx];
       }
       if (invert) data = ~data;
-      _writeData(data);
+      _transfer(data);
     }
   }
+  _endTransfer();
   _writeCommand(0x13);
+  _startTransfer();
   for (int16_t i = 0; i < h1; i++)
   {
     for (int16_t j = 0; j < w1 / 8; j++)
@@ -229,9 +244,10 @@ void GxEPD2_750c_Z08::writeImagePart(const uint8_t* black, const uint8_t* color,
         }
         if (invert) data = ~data;
       }
-      _writeData(~data);
+      _transfer(~data);
     }
   }
+  _endTransfer();
   _writeCommand(0x92); // partial out
   delay(1); // yield() to avoid WDT on ESP8266 and ESP32
 }