16 GxEPD2_EPD(cs, dc, rst, busy, LOW, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
18 _refresh_mode = full_refresh;
31 if (_refresh_mode == full_refresh) _Init_Part();
36 for (uint32_t i = 0; i < uint32_t(
WIDTH) * uint32_t(
HEIGHT) / 8; i++)
44 for (uint32_t i = 0; i < uint32_t(
WIDTH) * uint32_t(
HEIGHT) / 8; i++)
51void 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)
105void GxEPD2_420::writeImage_4G(
const uint8_t bitmap[], uint8_t bpp, int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
107 uint16_t ppb = (bpp == 2 ? 4 : (bpp == 4 ? 2 : (bpp == 8 ? 1 : 0)));
108 uint8_t mask = (bpp == 2 ? 0xC0 : (bpp == 4 ? 0xF0 : 0xFF));
109 uint8_t grey1 = (bpp == 2 ? 0x80 : 0xA0);
110 if (ppb == 0)
return;
113 int16_t wbc = (w + 7) / 8;
116 int16_t wb = (w + ppb - 1) / ppb;
117 int16_t x1 = x < 0 ? 0 : x;
118 int16_t y1 = y < 0 ? 0 : y;
119 uint16_t w1 = x + w < int16_t(
WIDTH) ? w : int16_t(
WIDTH) - x;
120 uint16_t h1 = y + h < int16_t(
HEIGHT) ? h : int16_t(
HEIGHT) - y;
125 if ((w1 <= 0) || (h1 <= 0))
return;
128 _setPartialRamArea(x1, y1, w1, h1);
130 for (uint16_t i = 0; i < h1; i++)
132 for (uint16_t j = 0; j < w1 / ppb; j += bpp)
134 uint8_t out_byte = 0;
135 for (uint16_t k = 0; k < bpp; k++)
139 uint32_t idx = mirror_y ? j + k + dx / ppb + uint32_t((h - 1 - (i + dy))) * wb : j + k + dx / ppb + uint32_t(i + dy) * wb;
142#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
143 in_byte = pgm_read_byte(&bitmap[idx]);
145 in_byte = bitmap[idx];
150 in_byte = bitmap[idx];
152 if (invert) in_byte = ~in_byte;
153 for (uint16_t n = 0; n < ppb; n++)
156 uint8_t nibble = in_byte & mask;
157 if (nibble == mask) out_byte |= 0x01;
158 else if (nibble == 0x00) out_byte |= 0x00;
159 else if (nibble >= grey1) out_byte |= 0x01;
160 else out_byte |= 0x00;
168 for (uint16_t i = 0; i < h1; i++)
170 for (uint16_t j = 0; j < w1 / ppb; j += bpp)
172 uint8_t out_byte = 0;
173 for (uint16_t k = 0; k < bpp; k++)
177 uint32_t idx = mirror_y ? j + k + dx / ppb + uint32_t((h - 1 - (i + dy))) * wb : j + k + dx / ppb + uint32_t(i + dy) * wb;
180#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
181 in_byte = pgm_read_byte(&bitmap[idx]);
183 in_byte = bitmap[idx];
188 in_byte = bitmap[idx];
190 if (invert) in_byte = ~in_byte;
191 for (uint16_t n = 0; n < ppb; n++)
194 uint8_t nibble = in_byte & mask;
195 if (nibble == mask) out_byte |= 0x01;
196 else if (nibble == 0x00) out_byte |= 0x00;
197 else if (nibble >= grey1) out_byte |= 0x00;
198 else out_byte |= 0x01;
210 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
212 writeImagePart_4G(bitmap,
GxEPD_BPP, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
268 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
270 uint16_t ppb = (bpp == 2 ? 4 : (bpp == 4 ? 2 : (bpp == 8 ? 1 : 0)));
271 uint8_t mask = (bpp == 2 ? 0xC0 : (bpp == 4 ? 0xF0 : 0xFF));
272 uint8_t grey1 = (bpp == 2 ? 0x80 : 0xA0);
273 if (ppb == 0)
return;
276 if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0))
return;
277 if ((x_part < 0) || (x_part >= w_bitmap))
return;
278 if ((y_part < 0) || (y_part >= h_bitmap))
return;
279 int16_t wb_bitmap = (w_bitmap + ppb - 1) / ppb;
280 x_part -= x_part % ppb;
281 w = w_bitmap - x_part < w ? w_bitmap - x_part : w;
282 h = h_bitmap - y_part < h ? h_bitmap - y_part : h;
283 int16_t wbc = (w + 7) / 8;
286 int16_t x1 = x < 0 ? 0 : x;
287 int16_t y1 = y < 0 ? 0 : y;
288 uint16_t w1 = x + w < int16_t(
WIDTH) ? w : int16_t(
WIDTH) - x;
289 uint16_t h1 = y + h < int16_t(
HEIGHT) ? h : int16_t(
HEIGHT) - y;
294 if ((w1 <= 0) || (h1 <= 0))
return;
297 _setPartialRamArea(x1, y1, w1, h1);
299 for (uint16_t i = 0; i < h1; i++)
301 for (uint16_t j = 0; j < w1 / ppb; j += bpp)
303 uint8_t out_byte = 0;
304 for (uint16_t k = 0; k < bpp; k++)
308 uint32_t idx = mirror_y ? x_part / ppb + j + k + dx / ppb + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / ppb + j + k + dx / ppb + uint32_t(y_part + i + dy) * wb_bitmap;
311#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
312 in_byte = pgm_read_byte(&bitmap[idx]);
314 in_byte = bitmap[idx];
319 in_byte = bitmap[idx];
321 if (invert) in_byte = ~in_byte;
322 for (uint16_t n = 0; n < ppb; n++)
325 uint8_t nibble = in_byte & mask;
326 if (nibble == mask) out_byte |= 0x01;
327 else if (nibble == 0x00) out_byte |= 0x00;
328 else if (nibble >= grey1) out_byte |= 0x01;
329 else out_byte |= 0x00;
337 for (uint16_t i = 0; i < h1; i++)
339 for (uint16_t j = 0; j < w1 / ppb; j += bpp)
341 uint8_t out_byte = 0;
342 for (uint16_t k = 0; k < bpp; k++)
346 uint32_t idx = mirror_y ? x_part / ppb + j + k + dx / ppb + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / ppb + j + k + dx / ppb + uint32_t(y_part + i + dy) * wb_bitmap;
349#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
350 in_byte = pgm_read_byte(&bitmap[idx]);
352 in_byte = bitmap[idx];
357 in_byte = bitmap[idx];
359 if (invert) in_byte = ~in_byte;
360 for (uint16_t n = 0; n < ppb; n++)
363 uint8_t nibble = in_byte & mask;
364 if (nibble == mask) out_byte |= 0x01;
365 else if (nibble == 0x00) out_byte |= 0x00;
366 else if (nibble >= grey1) out_byte |= 0x00;
367 else out_byte |= 0x01;
378void GxEPD2_420::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)
382 writeImage(black, x, y, w, h, invert, mirror_y, pgm);
386void GxEPD2_420::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,
387 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
391 writeImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
395void GxEPD2_420::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)
399 writeImage(data1, x, y, w, h, invert, mirror_y, pgm);
403void GxEPD2_420::drawImage(
const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
405 writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm);
407 writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm);
411 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
413 writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
415 writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
418void GxEPD2_420::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)
420 writeImage(black, color, x, y, w, h, invert, mirror_y, pgm);
422 writeImage(black, color, x, y, w, h, invert, mirror_y, pgm);
425void GxEPD2_420::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,
426 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
428 writeImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
430 writeImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
433void GxEPD2_420::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)
435 writeNative(data1, data2, x, y, w, h, invert, mirror_y, pgm);
437 writeNative(data1, data2, x, y, w, h, invert, mirror_y, pgm);
445 if (_refresh_mode == forced_full_refresh) _refresh_mode = full_refresh;
446 if (_refresh_mode == fast_refresh) _Init_Full();
447 if (_refresh_mode == grey_refresh) _Update_4G();
456 if (_refresh_mode == forced_full_refresh)
return refresh(
false);
458 int16_t w1 = x < 0 ? w + x : w;
459 int16_t h1 = y < 0 ? h + y : h;
460 int16_t x1 = x < 0 ? 0 : x;
461 int16_t y1 = y < 0 ? 0 : y;
462 w1 = x1 + w1 < int16_t(
WIDTH) ? w1 : int16_t(
WIDTH) - x1;
463 h1 = y1 + h1 < int16_t(
HEIGHT) ? h1 : int16_t(
HEIGHT) - y1;
464 if ((w1 <= 0) || (h1 <= 0))
return;
467 if (w1 % 8 > 0) w1 += 8 - w1 % 8;
469 if (_refresh_mode == full_refresh) _Init_Part();
471 _setPartialRamArea(x1, y1, w1, h1);
472 if (_refresh_mode == grey_refresh) _Update_4G();
493void GxEPD2_420::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
495 uint16_t xe = (x + w - 1) | 0x0007;
496 uint16_t ye = y + h - 1;
511void GxEPD2_420::_PowerOn()
521void GxEPD2_420::_PowerOff()
526 _refresh_mode = full_refresh;
529void GxEPD2_420::_InitDisplay()
559const unsigned char GxEPD2_420::lut_20_vcom0_full[]
PROGMEM =
561 0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
562 0x60, 0x28, 0x28, 0x00, 0x00, 0x01,
563 0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
564 0x00, 0x12, 0x12, 0x00, 0x00, 0x01,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571const unsigned char GxEPD2_420::lut_21_ww_full[]
PROGMEM =
573 0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
574 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
575 0x40, 0x14, 0x00, 0x00, 0x00, 0x01,
576 0xA0, 0x12, 0x12, 0x00, 0x00, 0x01,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
582const unsigned char GxEPD2_420::lut_22_bw_full[]
PROGMEM =
584 0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
585 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
586 0x40, 0x14, 0x00, 0x00, 0x00, 0x01,
587 0xA0, 0x12, 0x12, 0x00, 0x00, 0x01,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
593const unsigned char GxEPD2_420::lut_23_wb_full[]
PROGMEM =
595 0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
596 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
597 0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
598 0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
604const unsigned char GxEPD2_420::lut_24_bb_full[]
PROGMEM =
606 0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
607 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
608 0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
609 0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
616const unsigned char GxEPD2_420::lut_20_vcom0_4G[]
PROGMEM =
618 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01,
619 0x60, 0x14, 0x14, 0x00, 0x00, 0x01,
620 0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
621 0x00, 0x13, 0x0A, 0x01, 0x00, 0x01,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628const unsigned char GxEPD2_420::lut_21_ww_4G[]
PROGMEM =
630 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
631 0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
632 0x10, 0x14, 0x0A, 0x00, 0x00, 0x01,
633 0xA0, 0x13, 0x01, 0x00, 0x00, 0x01,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639const unsigned char GxEPD2_420::lut_22_bw_4G[]
PROGMEM =
641 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
642 0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
643 0x00, 0x14, 0x0A, 0x00, 0x00, 0x01,
644 0x99, 0x0C, 0x01, 0x03, 0x04, 0x01,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650const unsigned char GxEPD2_420::lut_23_wb_4G[]
PROGMEM =
652 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
653 0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
654 0x00, 0x14, 0x0A, 0x00, 0x00, 0x01,
655 0x99, 0x0B, 0x04, 0x04, 0x01, 0x01,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661const unsigned char GxEPD2_420::lut_24_bb_4G[]
PROGMEM =
663 0x80, 0x0A, 0x00, 0x00, 0x00, 0x01,
664 0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
665 0x20, 0x14, 0x0A, 0x00, 0x00, 0x01,
666 0x50, 0x13, 0x01, 0x00, 0x00, 0x01,
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696const unsigned char GxEPD2_420::lut_20_vcom0_partial[]
PROGMEM =
702const unsigned char GxEPD2_420::lut_21_ww_partial[]
PROGMEM =
708const unsigned char GxEPD2_420::lut_22_bw_partial[]
PROGMEM =
714const unsigned char GxEPD2_420::lut_23_wb_partial[]
PROGMEM =
720const unsigned char GxEPD2_420::lut_24_bb_partial[]
PROGMEM =
726void GxEPD2_420::_Force_Init_Full()
729 _refresh_mode = forced_full_refresh;
732void GxEPD2_420::_Init_Full()
746 _refresh_mode = full_refresh;
749void GxEPD2_420::_Init_4G()
751 Serial.println(
"_Init_4G");
764 _refresh_mode = grey_refresh;
767void GxEPD2_420::_Init_Part()
769 Serial.println(
"_Init_Part");
772 _writeDataPGM(lut_20_vcom0_partial,
sizeof(lut_20_vcom0_partial), 44 -
sizeof(lut_20_vcom0_partial));
774 _writeDataPGM(lut_21_ww_partial,
sizeof(lut_21_ww_partial), 42 -
sizeof(lut_21_ww_partial));
776 _writeDataPGM(lut_22_bw_partial,
sizeof(lut_22_bw_partial), 42 -
sizeof(lut_22_bw_partial));
778 _writeDataPGM(lut_23_wb_partial,
sizeof(lut_23_wb_partial), 42 -
sizeof(lut_23_wb_partial));
780 _writeDataPGM(lut_24_bb_partial,
sizeof(lut_24_bb_partial), 42 -
sizeof(lut_24_bb_partial));
782 _refresh_mode = fast_refresh;
785void GxEPD2_420::_Update_Full()
791void GxEPD2_420::_Update_4G()
797void GxEPD2_420::_Update_Part()
const unsigned char GxEPD2_420::lut_20_vcom0_full[] PROGMEM
static const bool usePartialUpdateWindow
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)
GxEPD2_420(int16_t cs, int16_t dc, int16_t rst, int16_t busy)
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)
void 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=false, bool mirror_y=false, bool pgm=false)
void writeImagePart_4G(const uint8_t bitmap[], uint8_t bpp, int16_t x_part, int16_t 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 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)
void writeScreenBuffer(uint8_t value=0xFF)
void clearScreen(uint8_t value=0xFF)
static const uint16_t WIDTH
static const uint16_t partial_refresh_time
void refresh(bool partial_update_mode=false)
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)
static const uint16_t full_refresh_time
void writeImage_4G(const uint8_t bitmap[], uint8_t bpp, 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)
static const uint16_t power_on_time
static const uint16_t power_off_time
static const uint16_t HEIGHT
void _writeCommand(uint8_t c)
void _writeData(uint8_t d)
void _waitWhileBusy(const char *comment=0, uint16_t busy_time=5000)
void _transfer(uint8_t value)
void _writeDataPGM(const uint8_t *data, uint16_t n, int16_t fill_with_zeroes=0)