Просмотр исходного кода

Version 1.1.0

- added  support for GDEW0213I5F for 2.13" b/w 104x212 flexible display
- updated GxEPD2_WiFi_Example and GxEPD2_Spiffs_Loader to use BearSSL on ESP8266, for large bitmap downloads
ZinggJM 8 лет назад
Родитель
Сommit
75175344dd

+ 11 - 6
README.md

@@ -1,12 +1,14 @@
 # GxEPD2
 # GxEPD2
-New Simplified Version of GxEPD for Arduino
+## Arduino Display Library for SPI E-Paper Displays
 
 
-## for SPI e-paper displays from Dalian Good Display 
-## and SPI e-paper boards from Waveshare
+- With full Graphics and Text support using Adafruit_GFX
+
+- For SPI e-paper displays from Dalian Good Display 
+- and SPI e-paper boards from Waveshare
 
 
 ### important note :
 ### important note :
-### - these displays are for 3.3V supply and 3.3V data lines.
-### - never connect data lines directly to 5V data pins.
+ - these displays are for 3.3V supply and 3.3V data lines.
+ - never connect data lines directly to 5V data pins.
 
 
 ### Paged Drawing, Picture Loop
 ### Paged Drawing, Picture Loop
  - This library uses paged drawing to limit RAM use and cope with missing single pixel update support
  - This library uses paged drawing to limit RAM use and cope with missing single pixel update support
@@ -33,7 +35,10 @@ New Simplified Version of GxEPD for Arduino
 - Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
 - Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
 - Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
 - Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
 
 
-### Version 1.0.9
+### Version 1.1.0
+- added  support for GDEW0213I5F for 2.13" b/w 104x212 flexible display
+- updated GxEPD2_WiFi_Example and GxEPD2_Spiffs_Loader to use BearSSL on ESP8266, for large bitmap downloads
+#### Version 1.0.9
 - add GxEPD2_U8G2_Fonts_Example, e.g. for use of Umlauts ÄÖÜäéöü
 - add GxEPD2_U8G2_Fonts_Example, e.g. for use of Umlauts ÄÖÜäéöü
 - NOTE: you need to SAVE the modified example to a saveable location for UTF-8 characters to work
 - NOTE: you need to SAVE the modified example to a saveable location for UTF-8 characters to work
 #### Version 1.0.8
 #### Version 1.0.8

+ 5 - 0
examples/GxEPD2_Example/GxEPD2_Example.ino

@@ -44,6 +44,7 @@
 // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
 // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
+//GxEPD2_BW<GxEPD2_213_flex, GxEPD2_213_flex::HEIGHT> display(GxEPD2_213_flex(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
@@ -65,6 +66,7 @@
 // select one , can use full buffer size (full HEIGHT)
 // select one , can use full buffer size (full HEIGHT)
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
+//GxEPD2_BW<GxEPD2_213_flex, GxEPD2_213_flex::HEIGHT> display(GxEPD2_213_flex(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
@@ -87,6 +89,7 @@
 // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
 // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
+//GxEPD2_BW<GxEPD2_213_flex, GxEPD2_213_flex::HEIGHT> display(GxEPD2_213_flex(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
@@ -106,6 +109,7 @@
 // select one and adapt to your mapping
 // select one and adapt to your mapping
 //GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
+//GxEPD2_BW<GxEPD2_213_flex, MAX_HEIGHT(GxEPD2_213_flex)> display(GxEPD2_213_flex(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> display(GxEPD2_290(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> display(GxEPD2_290(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_270, MAX_HEIGHT(GxEPD2_270)> display(GxEPD2_270(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_270, MAX_HEIGHT(GxEPD2_270)> display(GxEPD2_270(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_420, MAX_HEIGHT(GxEPD2_420)> display(GxEPD2_420(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
 //GxEPD2_BW<GxEPD2_420, MAX_HEIGHT(GxEPD2_420)> display(GxEPD2_420(/*CS=4*/ SS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
@@ -128,6 +132,7 @@
 // select one and adapt to your mapping
 // select one and adapt to your mapping
 //GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
+//GxEPD2_BW<GxEPD2_213_flex, MAX_HEIGHT(GxEPD2_213_flex)> display(GxEPD2_213_flex(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> display(GxEPD2_290(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> display(GxEPD2_290(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_270, MAX_HEIGHT(GxEPD2_270)> display(GxEPD2_270(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_270, MAX_HEIGHT(GxEPD2_270)> display(GxEPD2_270(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_420, MAX_HEIGHT(GxEPD2_420)> display(GxEPD2_420(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_420, MAX_HEIGHT(GxEPD2_420)> display(GxEPD2_420(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));

+ 4 - 2
examples/GxEPD2_Example/GxEPD2_boards_added.h

@@ -23,7 +23,8 @@
 #define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8))
 #define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8))
 // select one and adapt to your mapping
 // select one and adapt to your mapping
 //GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
-GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
+//GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
+//GxEPD2_BW<GxEPD2_213_flex, MAX_HEIGHT(GxEPD2_213_flex)> display(GxEPD2_213_flex(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> display(GxEPD2_290(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> display(GxEPD2_290(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_270, MAX_HEIGHT(GxEPD2_270)> display(GxEPD2_270(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_270, MAX_HEIGHT(GxEPD2_270)> display(GxEPD2_270(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_420, MAX_HEIGHT(GxEPD2_420)> display(GxEPD2_420(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
 //GxEPD2_BW<GxEPD2_420, MAX_HEIGHT(GxEPD2_420)> display(GxEPD2_420(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
@@ -51,7 +52,8 @@ GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=10*/ SS, /
 #define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8))
 #define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8))
 // select one and adapt to your mapping
 // select one and adapt to your mapping
 //GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
 //GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
-GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
+//GxEPD2_BW<GxEPD2_213, MAX_HEIGHT(GxEPD2_213)> display(GxEPD2_213(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
+//GxEPD2_BW<GxEPD2_213_flex, MAX_HEIGHT(GxEPD2_213_flex)> display(GxEPD2_213_flex(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
 //GxEPD2_BW<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> display(GxEPD2_290(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
 //GxEPD2_BW<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> display(GxEPD2_290(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
 //GxEPD2_BW<GxEPD2_270, MAX_HEIGHT(GxEPD2_270)> display(GxEPD2_270(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
 //GxEPD2_BW<GxEPD2_270, MAX_HEIGHT(GxEPD2_270)> display(GxEPD2_270(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
 //GxEPD2_BW<GxEPD2_420, MAX_HEIGHT(GxEPD2_420)> display(GxEPD2_420(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
 //GxEPD2_BW<GxEPD2_420, MAX_HEIGHT(GxEPD2_420)> display(GxEPD2_420(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));

+ 14 - 4
examples/GxEPD2_Spiffs_Loader/GxEPD2_Spiffs_Loader.ino

@@ -23,7 +23,9 @@ const bool formatOnFail = false;
 
 
 #if defined (ESP8266)
 #if defined (ESP8266)
 #include <ESP8266WiFi.h>
 #include <ESP8266WiFi.h>
+#define USE_BearSSL true
 #endif
 #endif
+
 #include <WiFiClient.h>
 #include <WiFiClient.h>
 #include <WiFiClientSecure.h>
 #include <WiFiClientSecure.h>
 
 
@@ -33,7 +35,11 @@ const int httpPort  = 80;
 const int httpsPort = 443;
 const int httpsPort = 443;
 const char* fp_api_github_com = "35 85 74 EF 67 35 A7 CE 40 69 50 F3 C0 F6 80 CF 80 3B 2E 19";
 const char* fp_api_github_com = "35 85 74 EF 67 35 A7 CE 40 69 50 F3 C0 F6 80 CF 80 3B 2E 19";
 const char* fp_github_com     = "ca 06 f5 6b 25 8b 7a 0d 4f 2b 05 47 09 39 47 86 51 15 19 84";
 const char* fp_github_com     = "ca 06 f5 6b 25 8b 7a 0d 4f 2b 05 47 09 39 47 86 51 15 19 84";
+#if USE_BearSSL
+const char fp_rawcontent[20]  = {0xcc, 0xaa, 0x48, 0x48, 0x66, 0x46, 0x0e, 0x91, 0x53, 0x2c, 0x9c, 0x7c, 0x23, 0x2a, 0xb1, 0x74, 0x4d, 0x29, 0x9d, 0x33};
+#else
 const char* fp_rawcontent     = "cc aa 48 48 66 46 0e 91 53 2c 9c 7c 23 2a b1 74 4d 29 9d 33";
 const char* fp_rawcontent     = "cc aa 48 48 66 46 0e 91 53 2c 9c 7c 23 2a b1 74 4d 29 9d 33";
+#endif
 const char* host_rawcontent   = "raw.githubusercontent.com";
 const char* host_rawcontent   = "raw.githubusercontent.com";
 const char* path_rawcontent   = "/ZinggJM/GxEPD2/master/extras/bitmaps/";
 const char* path_rawcontent   = "/ZinggJM/GxEPD2/master/extras/bitmaps/";
 const char* path_prenticedavid   = "/prenticedavid/MCUFRIEND_kbv/master/extras/bitmaps/";
 const char* path_prenticedavid   = "/prenticedavid/MCUFRIEND_kbv/master/extras/bitmaps/";
@@ -225,15 +231,22 @@ void downloadFile_HTTP(const char* host, const char* path, const char* filename,
 void downloadFile_HTTPS(const char* host, const char* path, const char* filename, const char* fingerprint, const char* target)
 void downloadFile_HTTPS(const char* host, const char* path, const char* filename, const char* fingerprint, const char* target)
 {
 {
   // Use WiFiClientSecure class to create TLS connection
   // Use WiFiClientSecure class to create TLS connection
+#if USE_BearSSL
+  BearSSL::WiFiClientSecure client;
+#else
   WiFiClientSecure client;
   WiFiClientSecure client;
+#endif
   Serial.println(); Serial.print("downloading file \""); Serial.print(filename);  Serial.println("\"");
   Serial.println(); Serial.print("downloading file \""); Serial.print(filename);  Serial.println("\"");
   Serial.print("connecting to "); Serial.println(host);
   Serial.print("connecting to "); Serial.println(host);
+#if USE_BearSSL
+  if (fingerprint) client.setFingerprint((uint8_t*)fingerprint);
+#endif
   if (!client.connect(host, httpsPort))
   if (!client.connect(host, httpsPort))
   {
   {
     Serial.println("connection failed");
     Serial.println("connection failed");
     return;
     return;
   }
   }
-#if defined (ESP8266)
+#if defined (ESP8266) && !USE_BearSSL
   if (fingerprint)
   if (fingerprint)
   {
   {
     if (client.verify(fingerprint, host))
     if (client.verify(fingerprint, host))
@@ -324,6 +337,3 @@ void downloadFile_HTTPS(const char* host, const char* path, const char* filename
   file.close();
   file.close();
   Serial.print("done, "); Serial.print(total); Serial.println(" bytes transferred");
   Serial.print("done, "); Serial.print(total); Serial.println(" bytes transferred");
 }
 }
-
-
-

+ 90 - 65
examples/GxEPD2_WiFi_Example/GxEPD2_WiFi_Example.ino

@@ -44,6 +44,7 @@
 // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
 // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
+//GxEPD2_BW<GxEPD2_213_flex, GxEPD2_213_flex::HEIGHT> display(GxEPD2_213_flex(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
@@ -65,6 +66,7 @@
 // select one , can use full buffer size (full HEIGHT)
 // select one , can use full buffer size (full HEIGHT)
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
+//GxEPD2_BW<GxEPD2_213_flex, GxEPD2_213_flex::HEIGHT> display(GxEPD2_213_flex(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=15*/ SS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
@@ -87,6 +89,7 @@
 // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
 // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display(GxEPD2_213(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
+//GxEPD2_BW<GxEPD2_213_flex, GxEPD2_213_flex::HEIGHT> display(GxEPD2_213_flex(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display(GxEPD2_290(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
 //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
@@ -102,7 +105,9 @@
 
 
 #if defined (ESP8266)
 #if defined (ESP8266)
 #include <ESP8266WiFi.h>
 #include <ESP8266WiFi.h>
+#define USE_BearSSL true
 #endif
 #endif
+
 #include <WiFiClient.h>
 #include <WiFiClient.h>
 #include <WiFiClientSecure.h>
 #include <WiFiClientSecure.h>
 
 
@@ -112,7 +117,11 @@ const int httpPort  = 80;
 const int httpsPort = 443;
 const int httpsPort = 443;
 const char* fp_api_github_com = "35 85 74 EF 67 35 A7 CE 40 69 50 F3 C0 F6 80 CF 80 3B 2E 19";
 const char* fp_api_github_com = "35 85 74 EF 67 35 A7 CE 40 69 50 F3 C0 F6 80 CF 80 3B 2E 19";
 const char* fp_github_com     = "ca 06 f5 6b 25 8b 7a 0d 4f 2b 05 47 09 39 47 86 51 15 19 84";
 const char* fp_github_com     = "ca 06 f5 6b 25 8b 7a 0d 4f 2b 05 47 09 39 47 86 51 15 19 84";
+#if USE_BearSSL
+const char fp_rawcontent[20]  = {0xcc, 0xaa, 0x48, 0x48, 0x66, 0x46, 0x0e, 0x91, 0x53, 0x2c, 0x9c, 0x7c, 0x23, 0x2a, 0xb1, 0x74, 0x4d, 0x29, 0x9d, 0x33};
+#else
 const char* fp_rawcontent     = "cc aa 48 48 66 46 0e 91 53 2c 9c 7c 23 2a b1 74 4d 29 9d 33";
 const char* fp_rawcontent     = "cc aa 48 48 66 46 0e 91 53 2c 9c 7c 23 2a b1 74 4d 29 9d 33";
+#endif
 const char* host_rawcontent   = "raw.githubusercontent.com";
 const char* host_rawcontent   = "raw.githubusercontent.com";
 const char* path_rawcontent   = "/ZinggJM/GxEPD2/master/extras/bitmaps/";
 const char* path_rawcontent   = "/ZinggJM/GxEPD2/master/extras/bitmaps/";
 const char* path_prenticedavid   = "/prenticedavid/MCUFRIEND_kbv/master/extras/bitmaps/";
 const char* path_prenticedavid   = "/prenticedavid/MCUFRIEND_kbv/master/extras/bitmaps/";
@@ -452,17 +461,11 @@ void showBitmapFrom_HTTP(const char* host, const char* path, const char* filenam
             if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
             if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
             {
             {
               uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
               uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
-              //if (get > client.available()) delay(200); // does improve? yes, if >= 200
-              // there seems an issue with long downloads on ESP8266
-              tryToWaitForAvailable(client, get);
-              uint32_t got = client.read(input_buffer, get);
+              uint32_t got = read(client, input_buffer, get);
               while ((got < get) && connection_ok)
               while ((got < get) && connection_ok)
               {
               {
                 //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
                 //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
-                //if ((get - got) > client.available()) delay(200); // does improve? yes, if >= 200
-                // there seems an issue with long downloads on ESP8266
-                tryToWaitForAvailable(client, get - got);
-                uint32_t gotmore = client.read(input_buffer + got, get - got);
+                uint32_t gotmore = read(client, input_buffer + got, get - got);
                 got += gotmore;
                 got += gotmore;
                 connection_ok = gotmore > 0;
                 connection_ok = gotmore > 0;
               }
               }
@@ -684,17 +687,11 @@ void drawBitmapFrom_HTTP_ToBuffer(const char* host, const char* path, const char
             if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
             if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
             {
             {
               uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
               uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
-              //if (get > client.available()) delay(200); // does improve? yes, if >= 200
-              // there seems an issue with long downloads on ESP8266
-              tryToWaitForAvailable(client, get);
-              uint32_t got = client.read(input_buffer, get);
+              uint32_t got = read(client, input_buffer, get);
               while ((got < get) && connection_ok)
               while ((got < get) && connection_ok)
               {
               {
                 //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
                 //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
-                //if ((get - got) > client.available()) delay(200); // does improve? yes, if >= 200
-                // there seems an issue with long downloads on ESP8266
-                tryToWaitForAvailable(client, get - got);
-                uint32_t gotmore = client.read(input_buffer + got, get - got);
+                uint32_t gotmore = read(client, input_buffer + got, get - got);
                 got += gotmore;
                 got += gotmore;
                 connection_ok = gotmore > 0;
                 connection_ok = gotmore > 0;
               }
               }
@@ -795,7 +792,11 @@ void showBitmapFrom_HTTP_Buffered(const char* host, const char* path, const char
 void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color)
 void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color)
 {
 {
   // Use WiFiClientSecure class to create TLS connection
   // Use WiFiClientSecure class to create TLS connection
+#if USE_BearSSL
+  BearSSL::WiFiClientSecure client;
+#else
   WiFiClientSecure client;
   WiFiClientSecure client;
+#endif
   bool connection_ok = false;
   bool connection_ok = false;
   bool valid = false; // valid format to be handled
   bool valid = false; // valid format to be handled
   bool flip = true; // bitmap is stored bottom-to-top
   bool flip = true; // bitmap is stored bottom-to-top
@@ -803,12 +804,15 @@ void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filena
   if ((x >= display.width()) || (y >= display.height())) return;
   if ((x >= display.width()) || (y >= display.height())) return;
   Serial.println(); Serial.print("downloading file \""); Serial.print(filename);  Serial.println("\"");
   Serial.println(); Serial.print("downloading file \""); Serial.print(filename);  Serial.println("\"");
   Serial.print("connecting to "); Serial.println(host);
   Serial.print("connecting to "); Serial.println(host);
+#if USE_BearSSL
+  if (fingerprint) client.setFingerprint((uint8_t*)fingerprint);
+#endif
   if (!client.connect(host, httpsPort))
   if (!client.connect(host, httpsPort))
   {
   {
     Serial.println("connection failed");
     Serial.println("connection failed");
     return;
     return;
   }
   }
-#if defined (ESP8266)
+#if defined (ESP8266) && !USE_BearSSL
   if (fingerprint)
   if (fingerprint)
   {
   {
     if (client.verify(fingerprint, host))
     if (client.verify(fingerprint, host))
@@ -933,17 +937,12 @@ void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filena
             if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
             if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
             {
             {
               uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
               uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
-              //if (get > client.available()) delay(200); // does improve? yes, if >= 200
-              // there seems an issue with long downloads on ESP8266
-              tryToWaitForAvailable(client, get);
-              uint32_t got = client.read(input_buffer, get);
+              uint32_t got = read(client, input_buffer, get);
               while ((got < get) && connection_ok)
               while ((got < get) && connection_ok)
               {
               {
                 //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
                 //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
                 //if ((get - got) > client.available()) delay(200); // does improve? yes, if >= 200
                 //if ((get - got) > client.available()) delay(200); // does improve? yes, if >= 200
-                // there seems an issue with long downloads on ESP8266
-                tryToWaitForAvailable(client, get - got);
-                uint32_t gotmore = client.read(input_buffer + got, get - got);
+                uint32_t gotmore = read(client, input_buffer + got, get - got);
                 got += gotmore;
                 got += gotmore;
                 connection_ok = gotmore > 0;
                 connection_ok = gotmore > 0;
               }
               }
@@ -1040,7 +1039,11 @@ void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filena
 void drawBitmapFrom_HTTPS_ToBuffer(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color)
 void drawBitmapFrom_HTTPS_ToBuffer(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color)
 {
 {
   // Use WiFiClientSecure class to create TLS connection
   // Use WiFiClientSecure class to create TLS connection
+#if USE_BearSSL
+  BearSSL::WiFiClientSecure client;
+#else
   WiFiClientSecure client;
   WiFiClientSecure client;
+#endif
   bool connection_ok = false;
   bool connection_ok = false;
   bool valid = false; // valid format to be handled
   bool valid = false; // valid format to be handled
   bool flip = true; // bitmap is stored bottom-to-top
   bool flip = true; // bitmap is stored bottom-to-top
@@ -1048,12 +1051,15 @@ void drawBitmapFrom_HTTPS_ToBuffer(const char* host, const char* path, const cha
   if ((x >= display.width()) || (y >= display.height())) return;
   if ((x >= display.width()) || (y >= display.height())) return;
   display.fillScreen(GxEPD_WHITE);
   display.fillScreen(GxEPD_WHITE);
   Serial.print("connecting to "); Serial.println(host);
   Serial.print("connecting to "); Serial.println(host);
+#if USE_BearSSL
+  if (fingerprint) client.setFingerprint((uint8_t*)fingerprint);
+#endif
   if (!client.connect(host, httpsPort))
   if (!client.connect(host, httpsPort))
   {
   {
     Serial.println("connection failed");
     Serial.println("connection failed");
     return;
     return;
   }
   }
-#if defined (ESP8266)
+#if defined (ESP8266) && !USE_BearSSL
   if (fingerprint)
   if (fingerprint)
   {
   {
     if (client.verify(fingerprint, host))
     if (client.verify(fingerprint, host))
@@ -1178,17 +1184,11 @@ void drawBitmapFrom_HTTPS_ToBuffer(const char* host, const char* path, const cha
             if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
             if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
             {
             {
               uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
               uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
-              //if (get > client.available()) delay(200); // does improve? yes, if >= 200
-              // there seems an issue with long downloads on ESP8266
-              tryToWaitForAvailable(client, get);
-              uint32_t got = client.read(input_buffer, get);
+              uint32_t got = read(client, input_buffer, get);
               while ((got < get) && connection_ok)
               while ((got < get) && connection_ok)
               {
               {
                 //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
                 //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
-                //if ((get - got) > client.available()) delay(200); // does improve? yes, if >= 200
-                // there seems an issue with long downloads on ESP8266
-                tryToWaitForAvailable(client, get - got);
-                uint32_t gotmore = client.read(input_buffer + got, get - got);
+                uint32_t gotmore = read(client, input_buffer + got, get - got);
                 got += gotmore;
                 got += gotmore;
                 connection_ok = gotmore > 0;
                 connection_ok = gotmore > 0;
               }
               }
@@ -1306,51 +1306,76 @@ uint32_t read32(WiFiClient& client)
   return result;
   return result;
 }
 }
 
 
-uint32_t skip(WiFiClient& client, int32_t bytes)
+#if USE_BearSSL
+
+uint32_t skip(BearSSL::WiFiClientSecure& client, int32_t bytes)
 {
 {
   int32_t remain = bytes;
   int32_t remain = bytes;
-  int16_t retries = 3;
-  uint32_t chunk = 1024;
-  if (chunk > sizeof(input_buffer)) chunk = sizeof(input_buffer);
-  while (client.connected() && (remain > chunk))
+  uint32_t start = millis();
+  while (client.connected() && (remain > 0))
   {
   {
-    // there seems an issue with long downloads on ESP8266
-    tryToWaitForAvailable(client, chunk);
-    uint32_t got = client.read(input_buffer, chunk);
-    //Serial.print("skipped "); Serial.println(got);
-    remain -= got;
-    if ((0 == got) && (0 == --retries))
+    if (client.available())
     {
     {
-      Serial.print("Error on skip, got 0, skipped "); Serial.print(bytes - remain); Serial.print(" of "); Serial.println(bytes);
-      break; // don't hang forever (retries don't help)
+      int16_t v = client.read();
+      remain--;
     }
     }
+    else delay(1);
+    if (millis() - start > 2000) break; // don't hang forever
   }
   }
-  if (client.connected() && (remain > 0) && (remain <= chunk))
-  {
-    remain -= client.read(input_buffer, remain);
-  }
-  return bytes - remain; // bytes read and skipped
+  return bytes - remain;
 }
 }
 
 
-void tryToWaitForAvailable(WiFiClient& client, int32_t amount)
+uint32_t read(BearSSL::WiFiClientSecure& client, uint8_t* buffer, int32_t bytes)
 {
 {
-  // this doesn't work as expected, but it helps for long downloads
-  int32_t start = millis();
-  for (int16_t t = 0, dly = 50; t < 20; t++, dly += 50)
+  int32_t remain = bytes;
+  uint32_t start = millis();
+  while (client.connected() && (remain > 0))
   {
   {
-    if (client.available()) break; // read would not recover after having returned 0
-    delay(dly);
+    if (client.available())
+    {
+      int16_t v = client.read();
+      *buffer++ = uint8_t(v);
+      remain--;
+    }
+    else delay(1);
+    if (millis() - start > 2000) break; // don't hang forever
   }
   }
-  for (int16_t t = 0, dly = 50; t < 3; t++, dly += 25)
+  return bytes - remain;
+}
+
+#endif
+
+uint32_t skip(WiFiClient& client, int32_t bytes)
+{
+  int32_t remain = bytes;
+  uint32_t start = millis();
+  while (client.connected() && (remain > 0))
   {
   {
-    if (amount <= client.available()) break;
-    delay(dly);
-    //Serial.print("available "); Serial.println(client.available()); // stays constant
+    if (client.available())
+    {
+      int16_t v = client.read();
+      remain--;
+    }
+    else delay(1);
+    if (millis() - start > 2000) break; // don't hang forever
   }
   }
-  int32_t elapsed = millis() - start;
-  if (elapsed > 250)
+  return bytes - remain;
+}
+
+uint32_t read(WiFiClient& client, uint8_t* buffer, int32_t bytes)
+{
+  int32_t remain = bytes;
+  uint32_t start = millis();
+  while (client.connected() && (remain > 0))
   {
   {
-    Serial.print("waited for available "); Serial.print(millis() - start); Serial.println(" ms"); // usually 0 or 225ms
+    if (client.available())
+    {
+      int16_t v = client.read();
+      *buffer++ = uint8_t(v);
+      remain--;
+    }
+    else delay(1);
+    if (millis() - start > 2000) break; // don't hang forever
   }
   }
+  return bytes - remain;
 }
 }
-

+ 2 - 2
library.properties

@@ -1,8 +1,8 @@
 name=GxEPD2
 name=GxEPD2
-version=1.0.9
+version=1.1.0
 author=Jean-Marc Zingg
 author=Jean-Marc Zingg
 maintainer=Jean-Marc Zingg
 maintainer=Jean-Marc Zingg
-sentence=Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
+sentence=Arduino Display Library for SPI E-Paper displays from Dalian Good Display and Waveshare. 
 paragraph=Requires HW SPI and Adafruit_GFX. Caution: these e-papers require 3.3V supply AND data lines!
 paragraph=Requires HW SPI and Adafruit_GFX. Caution: these e-papers require 3.3V supply AND data lines!
 category=Display
 category=Display
 url=https://github.com/ZinggJM/GxEPD2
 url=https://github.com/ZinggJM/GxEPD2

+ 1 - 0
src/GxEPD2_BW.h

@@ -16,6 +16,7 @@
 #include "GxEPD2_EPD.h"
 #include "GxEPD2_EPD.h"
 #include "epd/GxEPD2_154.h"
 #include "epd/GxEPD2_154.h"
 #include "epd/GxEPD2_213.h"
 #include "epd/GxEPD2_213.h"
+#include "epd/GxEPD2_213_flex.h"
 #include "epd/GxEPD2_290.h"
 #include "epd/GxEPD2_290.h"
 #include "epd/GxEPD2_270.h"
 #include "epd/GxEPD2_270.h"
 #include "epd/GxEPD2_420.h"
 #include "epd/GxEPD2_420.h"

+ 1 - 0
src/GxEPD2_EPD.h

@@ -31,6 +31,7 @@ class GxEPD2
     {
     {
       GDEP015OC1, Waveshare_1_54_bw = GDEP015OC1,
       GDEP015OC1, Waveshare_1_54_bw = GDEP015OC1,
       GDE0213B1,  Waveshare_2_13_bw = GDE0213B1,
       GDE0213B1,  Waveshare_2_13_bw = GDE0213B1,
+      GDEW0213I5F, Waveshare_2_13_flex = GDEW0213I5F,
       GDEH029A1,  Waveshare_2_9_bw = GDEH029A1,
       GDEH029A1,  Waveshare_2_9_bw = GDEH029A1,
       GDEW027W3,  Waveshare_2_7_bw = GDEW027W3,
       GDEW027W3,  Waveshare_2_7_bw = GDEW027W3,
       GDEW042T2,  Waveshare_4_2_bw = GDEW042T2,
       GDEW042T2,  Waveshare_4_2_bw = GDEW042T2,

+ 313 - 0
src/epd/GxEPD2_213_flex.cpp

@@ -0,0 +1,313 @@
+// Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
+// Requires HW SPI and Adafruit_GFX. Caution: these e-papers require 3.3V supply AND data lines!
+//
+// based on Demo Example from Good Display: http://www.good-display.com/download_list/downloadcategoryid=34&isMode=false.html
+//
+// Author: Jean-Marc Zingg
+//
+// Version: see library.properties
+//
+// Library: https://github.com/ZinggJM/GxEPD2
+
+#include "GxEPD2_213_flex.h"
+#include "WaveTables.h"
+
+GxEPD2_213_flex::GxEPD2_213_flex(int8_t cs, int8_t dc, int8_t rst, int8_t busy) :
+  GxEPD2_EPD(cs, dc, rst, busy, LOW, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
+{
+  _initial = true;
+  _power_is_on = false;
+  _using_partial_mode = false;
+}
+
+void GxEPD2_213_flex::init(uint32_t serial_diag_bitrate)
+{
+  GxEPD2_EPD::init(serial_diag_bitrate);
+  _initial = true;
+  _power_is_on = false;
+  _using_partial_mode = false;
+}
+
+void GxEPD2_213_flex::clearScreen(uint8_t value)
+{
+  if (_initial)
+  {
+    _Init_Full();
+    _writeCommand(0x10); // preset previous
+    for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
+    {
+      _writeData(0xFF); // 0xFF is white
+    }
+    _writeCommand(0x13); // set current
+    for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
+    {
+      _writeData(value);
+    }
+    _Update_Full();
+    _initial = false;
+  }
+  if (!_using_partial_mode) _Init_Part();
+  _writeCommand(0x91); // partial in
+  _setPartialRamArea(0, 0, WIDTH, HEIGHT);
+  _writeCommand(0x13);
+  for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
+  {
+    _writeData(value);
+  }
+  _Update_Part();
+  _setPartialRamArea(0, 0, WIDTH, HEIGHT);
+  _writeCommand(0x13);
+  for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
+  {
+    _writeData(value);
+  }
+  _Update_Part();
+  _writeCommand(0x92); // partial out
+  _initial = false;
+}
+
+void GxEPD2_213_flex::writeScreenBuffer(uint8_t value)
+{
+  if (_initial) clearScreen(value);
+  else _writeScreenBuffer(value);
+}
+
+void GxEPD2_213_flex::_writeScreenBuffer(uint8_t value)
+{
+  if (!_using_partial_mode) _Init_Part();
+  _writeCommand(0x91); // partial in
+  _setPartialRamArea(0, 0, WIDTH, HEIGHT);
+  _writeCommand(0x13);
+  for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
+  {
+    _writeData(value);
+  }
+  _writeCommand(0x92); // partial out
+}
+
+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)
+{
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+  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;
+  if (!_using_partial_mode) _Init_Part();
+  _writeCommand(0x91); // partial in
+  _setPartialRamArea(x1, y1, w1, h1);
+  _writeCommand(0x13);
+  for (int16_t i = 0; i < h1; i++)
+  {
+    for (int16_t j = 0; j < w1 / 8; j++)
+    {
+      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];
+      }
+      if (invert) data = ~data;
+      _writeData(data);
+    }
+  }
+  _writeCommand(0x92); // partial out
+  delay(1); // yield() to avoid WDT on ESP8266 and ESP32
+}
+
+void GxEPD2_213_flex::writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  if (black)
+  {
+    writeImage(black, x, y, w, h, invert, mirror_y, pgm);
+  }
+}
+
+void GxEPD2_213_flex::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)
+  {
+    writeImage(data1, x, y, w, h, invert, mirror_y, pgm);
+  }
+}
+
+void GxEPD2_213_flex::drawImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm);
+  refresh(x, y, w, h);
+}
+
+void GxEPD2_213_flex::drawImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
+{
+  writeImage(black, color, x, y, w, h, invert, mirror_y, pgm);
+  refresh(x, y, w, h);
+}
+
+void GxEPD2_213_flex::drawNative(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)
+{
+  writeNative(data1, data2, x, y, w, h, invert, mirror_y, pgm);
+  refresh(x, y, w, h);
+}
+
+void GxEPD2_213_flex::refresh(bool partial_update_mode)
+{
+  if (partial_update_mode) refresh(0, 0, WIDTH, HEIGHT);
+  else
+  {
+    if (_using_partial_mode) _Init_Full();
+    _Update_Full();
+  }
+}
+
+void GxEPD2_213_flex::refresh(int16_t x, int16_t y, int16_t w, int16_t h)
+{
+  x -= x % 8; // byte boundary
+  w -= x % 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
+  w1 -= x1 - x;
+  h1 -= y1 - y;
+  if (!_using_partial_mode) _Init_Part();
+  _writeCommand(0x91); // partial in
+  _setPartialRamArea(x1, y1, w1, h1);
+  _Update_Part();
+  _writeCommand(0x92); // partial out
+}
+
+void GxEPD2_213_flex::powerOff(void)
+{
+  _PowerOff();
+}
+
+void GxEPD2_213_flex::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
+{
+  uint16_t xe = (x + w - 1) | 0x0007; // byte boundary inclusive (last byte)
+  uint16_t ye = y + h - 1;
+  x &= 0xFFF8; // byte boundary
+  _writeCommand(0x90); // 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); // don't see any difference
+  //_writeData(0x00); // don't see any difference
+}
+
+void GxEPD2_213_flex::_PowerOn()
+{
+  if (!_power_is_on)
+  {
+    _writeCommand(0x04);
+    _waitWhileBusy("_PowerOn", power_on_time);
+  }
+  _power_is_on = true;
+}
+
+void GxEPD2_213_flex::_PowerOff()
+{
+  _writeCommand(0x02); // power off
+  _waitWhileBusy("_PowerOff", power_off_time);
+  _power_is_on = false;
+  _using_partial_mode = false;
+}
+
+void GxEPD2_213_flex::_InitDisplay()
+{
+  _writeCommand(0x01); //POWER SETTING
+  _writeData (0x03);
+  _writeData (0x00);
+  _writeData (0x2b);
+  _writeData (0x2b);
+  _writeData (0x03);
+  _writeCommand(0x06); //boost soft start
+  _writeData (0x17);   //A
+  _writeData (0x17);   //B
+  _writeData (0x17);   //C
+  _writeCommand(0x00); //panel setting
+  _writeData(0xbf);    //LUT from register, 128x296
+  _writeData(0x0d);    //VCOM to 0V fast
+  _writeCommand(0x30); //PLL setting
+  _writeData (0x3a);   // 3a 100HZ   29 150Hz 39 200HZ 31 171HZ
+  _writeCommand(0x61); //resolution setting
+  _writeData (WIDTH);
+  _writeData (HEIGHT >> 8);
+  _writeData (HEIGHT & 0xFF);
+}
+
+void GxEPD2_213_flex::_Init_Full()
+{
+  _InitDisplay();
+  _writeCommand(0x82); //vcom_DC setting
+  _writeData (0x08);
+  _writeCommand(0X50); //VCOM AND DATA INTERVAL SETTING
+  _writeData(0x97);    //WBmode:VBDF 17|D7 VBDW 97 VBDB 57   WBRmode:VBDF F7 VBDW 77 VBDB 37  VBDR B7
+  _writeCommand(0x20);
+  _writeDataPGM(GxGDEW0213I5F_lut_20_vcomDC, sizeof(GxGDEW0213I5F_lut_20_vcomDC));
+  _writeCommand(0x21);
+  _writeDataPGM(GxGDEW0213I5F_lut_21_ww, sizeof(GxGDEW0213I5F_lut_21_ww));
+  _writeCommand(0x22);
+  _writeDataPGM(GxGDEW0213I5F_lut_22_bw, sizeof(GxGDEW0213I5F_lut_22_bw));
+  _writeCommand(0x23);
+  _writeDataPGM(GxGDEW0213I5F_lut_23_wb, sizeof(GxGDEW0213I5F_lut_23_wb));
+  _writeCommand(0x24);
+  _writeDataPGM(GxGDEW0213I5F_lut_24_bb, sizeof(GxGDEW0213I5F_lut_24_bb));
+  _PowerOn();
+  _using_partial_mode = false;
+}
+
+void GxEPD2_213_flex::_Init_Part()
+{
+  _InitDisplay();
+  _writeCommand(0x82); //vcom_DC setting
+  _writeData (0x08);
+  _writeCommand(0X50);
+  _writeData(0x17);    //WBmode:VBDF 17|D7 VBDW 97 VBDB 57   WBRmode:VBDF F7 VBDW 77 VBDB 37  VBDR B7
+  _writeCommand(0x20);
+  _writeDataPGM(GxGDEW0213I5F_lut_20_vcomDC_partial, sizeof(GxGDEW0213I5F_lut_20_vcomDC_partial));
+  _writeCommand(0x21);
+  _writeDataPGM(GxGDEW0213I5F_lut_21_ww_partial, sizeof(GxGDEW0213I5F_lut_21_ww_partial));
+  _writeCommand(0x22);
+  _writeDataPGM(GxGDEW0213I5F_lut_22_bw_partial, sizeof(GxGDEW0213I5F_lut_22_bw_partial));
+  _writeCommand(0x23);
+  _writeDataPGM(GxGDEW0213I5F_lut_23_wb_partial, sizeof(GxGDEW0213I5F_lut_23_wb_partial));
+  _writeCommand(0x24);
+  _writeDataPGM(GxGDEW0213I5F_lut_24_bb_partial, sizeof(GxGDEW0213I5F_lut_24_bb_partial));
+  _PowerOn();
+  _using_partial_mode = true;
+}
+
+void GxEPD2_213_flex::_Update_Full()
+{
+  _writeCommand(0x12); //display refresh
+  _waitWhileBusy("_Update_Full", full_refresh_time);
+}
+
+void GxEPD2_213_flex::_Update_Part()
+{
+  _writeCommand(0x12); //display refresh
+  _waitWhileBusy("_Update_Part", partial_refresh_time);
+}
+
+

+ 66 - 0
src/epd/GxEPD2_213_flex.h

@@ -0,0 +1,66 @@
+// Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
+// Requires HW SPI and Adafruit_GFX. Caution: these e-papers require 3.3V supply AND data lines!
+//
+// based on Demo Example from Good Display: http://www.good-display.com/download_list/downloadcategoryid=34&isMode=false.html
+//
+// Author: Jean-Marc Zingg
+//
+// Version: see library.properties
+//
+// Library: https://github.com/ZinggJM/GxEPD2
+
+#ifndef _GxEPD2_213_flex_H_
+#define _GxEPD2_213_flex_H_
+
+#include "../GxEPD2_EPD.h"
+
+class GxEPD2_213_flex : public GxEPD2_EPD
+{
+  public:
+    // attributes
+    static const uint16_t WIDTH = 104;
+    static const uint16_t HEIGHT = 212;
+    static const GxEPD2::Panel panel = GxEPD2::GDEW0213I5F;
+    static const bool hasColor = false;
+    static const bool hasPartialUpdate = true;
+    static const bool hasFastPartialUpdate = true;
+    static const uint16_t power_on_time = 400; // ms, e.g. 36553us
+    static const uint16_t power_off_time = 250; // ms, e.g. 20759us
+    static const uint16_t full_refresh_time = 2100; // ms, e.g. 2056899us
+    static const uint16_t partial_refresh_time = 300; // ms, e.g. 283622us
+    // constructor
+    GxEPD2_213_flex(int8_t cs, int8_t dc, int8_t rst, int8_t busy);
+    // methods (virtual)
+    void init(uint32_t serial_diag_bitrate = 0); // = 0 : disabled
+    //  Support for Bitmaps (Sprites) to Controller Buffer and to Screen
+    void clearScreen(uint8_t value = 0xFF); // init controller memory and screen (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
+    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* 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);
+    // write sprite of native data to controller memory, without screen refresh; x and w should be multiple of 8
+    void writeNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    // write to controller memory, with screen refresh; x and w should be multiple of 8
+    void drawImage(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 drawImage(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);
+    // write sprite of native data to controller memory, with screen refresh; x and w should be multiple of 8
+    void drawNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
+    void refresh(bool partial_update_mode = false); // screen refresh from controller memory to full screen
+    void refresh(int16_t x, int16_t y, int16_t w, int16_t h); // screen refresh from controller memory, partial screen
+    void powerOff();
+  private:
+    void _writeScreenBuffer(uint8_t value);
+    void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
+    void _PowerOn();
+    void _PowerOff();
+    void _InitDisplay();
+    void _Init_Full();
+    void _Init_Part();
+    void _Update_Full();
+    void _Update_Part();
+  protected:
+    bool _initial, _power_is_on, _using_partial_mode;
+};
+
+#endif
+

+ 106 - 0
src/epd/WaveTables.h

@@ -49,6 +49,112 @@ const uint8_t GxGDEH029A1_LUTDefault_part[] PROGMEM =
   0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 };
 
 
+//full screen update LUT
+const unsigned char GxGDEW0213I5F_lut_20_vcomDC[] PROGMEM = 
+{
+  0x00  , 0x08 , 0x00 , 0x00 , 0x00 , 0x02,
+  0x60  , 0x28 , 0x28 , 0x00 , 0x00 , 0x01,
+  0x00  , 0x14 , 0x00 , 0x00 , 0x00 , 0x01,
+  0x00  , 0x12 , 0x12 , 0x00 , 0x00 , 0x01,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
+  , 0x00 , 0x00,
+};
+const unsigned char GxGDEW0213I5F_lut_21_ww[] PROGMEM = 
+{
+  0x40  , 0x08 , 0x00 , 0x00 , 0x00 , 0x02,
+  0x90  , 0x28 , 0x28 , 0x00 , 0x00 , 0x01,
+  0x40  , 0x14 , 0x00 , 0x00 , 0x00 , 0x01,
+  0xA0  , 0x12 , 0x12 , 0x00 , 0x00 , 0x01,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+};
+const unsigned char GxGDEW0213I5F_lut_22_bw[] PROGMEM = 
+{
+  0x40  , 0x17 , 0x00 , 0x00 , 0x00 , 0x02 ,
+  0x90  , 0x0F , 0x0F , 0x00 , 0x00 , 0x03 ,
+  0x40  , 0x0A , 0x01 , 0x00 , 0x00 , 0x01 ,
+  0xA0  , 0x0E , 0x0E , 0x00 , 0x00 , 0x02 ,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
+};
+const unsigned char GxGDEW0213I5F_lut_23_wb[] PROGMEM = 
+{
+  0x80  , 0x08 , 0x00 , 0x00 , 0x00 , 0x02,
+  0x90  , 0x28 , 0x28 , 0x00 , 0x00 , 0x01,
+  0x80  , 0x14 , 0x00 , 0x00 , 0x00 , 0x01,
+  0x50  , 0x12 , 0x12 , 0x00 , 0x00 , 0x01,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+};
+const unsigned char GxGDEW0213I5F_lut_24_bb[] PROGMEM = 
+{
+  0x80  , 0x08 , 0x00 , 0x00 , 0x00 , 0x02,
+  0x90  , 0x28 , 0x28 , 0x00 , 0x00 , 0x01,
+  0x80  , 0x14 , 0x00 , 0x00 , 0x00 , 0x01,
+  0x50  , 0x12 , 0x12 , 0x00 , 0x00 , 0x01,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+  0x00  , 0x00 , 0x00 , 0x00 , 0x00 , 0x00,
+};
+
+//partial screen update LUT
+const unsigned char GxGDEW0213I5F_lut_20_vcomDC_partial[] PROGMEM = 
+{
+  0x00  , 0x19 , 0x01 , 0x00 , 0x00 , 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,
+};
+const unsigned char GxGDEW0213I5F_lut_21_ww_partial[] PROGMEM = 
+{
+  0x00  , 0x19 , 0x01 , 0x00 , 0x00 , 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,
+};
+const unsigned char GxGDEW0213I5F_lut_22_bw_partial[] PROGMEM = 
+{
+  0x80  , 0x19 , 0x01 , 0x00 , 0x00 , 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,
+};
+const unsigned char GxGDEW0213I5F_lut_23_wb_partial[] PROGMEM = 
+{
+  0x40  , 0x19 , 0x01 , 0x00 , 0x00 , 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,
+};
+const unsigned char GxGDEW0213I5F_lut_24_bb_partial[] PROGMEM = 
+{
+  0x00  , 0x19 , 0x01 , 0x00 , 0x00 , 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,
+};
+
 const uint8_t GxGDEW027W3_lut_20_vcomDC[] PROGMEM =
 const uint8_t GxGDEW027W3_lut_20_vcomDC[] PROGMEM =
 {
 {
 0x00  ,0x00 ,
 0x00  ,0x00 ,