22 int16_t cs_m1, int16_t cs_s1, int16_t cs_m2, int16_t cs_s2,
23 int16_t dc1, int16_t dc2, int16_t rst1, int16_t rst2,
24 int16_t busy_m1, int16_t busy_s1, int16_t busy_m2, int16_t busy_s2) :
25 GxEPD2_EPD(cs_m1, dc1, rst1, busy_m1, LOW, 20000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate),
26 _sck(sck), _miso(miso), _mosi(mosi), _dc1(dc1), _dc2(dc2), _rst1(rst1), _rst2(rst2),
27 _cs_m1(cs_m1), _cs_s1(cs_s1), _cs_m2(cs_m2), _cs_s2(cs_s2),
28 _busy_m1(busy_m1), _busy_s1(busy_s1), _busy_m2(busy_m2), _busy_s2(busy_s2),
30 M1(648, 492, false, cs_m1, dc1),
31 S1(656, 492, false, cs_s1, dc1),
32 M2(656, 492, true, cs_m2, dc2),
33 S2(648, 492, true, cs_s2, dc2)
40 int16_t dc1, int16_t dc2, int16_t rst1, int16_t rst2,
41 int16_t busy_m1, int16_t busy_s1, int16_t busy_m2, int16_t busy_s2) :
42 GxEPD2_EPD(cs_m1, dc1, rst1, busy_m1, LOW, 20000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate),
43 _sck(SCK), _miso(MISO), _mosi(MOSI), _dc1(dc1), _dc2(dc2), _rst1(rst1), _rst2(rst2),
44 _cs_m1(cs_m1), _cs_s1(cs_s1), _cs_m2(cs_m2), _cs_s2(cs_s2),
45 _busy_m1(busy_m1), _busy_s1(busy_s1), _busy_m2(busy_m2), _busy_s2(busy_s2),
47 M1(648, 492, false, cs_m1, dc1),
48 S1(656, 492, false, cs_s1, dc1),
49 M2(656, 492, true, cs_m2, dc2),
50 S2(648, 492, true, cs_s2, dc2)
56 GxEPD2_EPD(23, 25, 33, 32, LOW, 20000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate),
57 _sck(SCK), _miso(MISO), _mosi(MOSI), _dc1(dc), _dc2(dc), _rst1(rst), _rst2(rst),
58 _cs_m1(cs_m1), _cs_s1(cs_s1), _cs_m2(cs_m2), _cs_s2(cs_s2),
59 _busy_m1(busy), _busy_s1(busy), _busy_m2(busy), _busy_s2(busy),
61 M1(648, 492, false, cs_m1, dc),
62 S1(656, 492, false, cs_s1, dc),
63 M2(656, 492, true, cs_m2, dc),
64 S2(648, 492, true, cs_s2, dc)
70 init(serial_diag_bitrate,
true, 20,
false);
73void GxEPD2_1248c::init(uint32_t serial_diag_bitrate,
bool initial, uint16_t reset_duration,
bool pulldown_rst_mode)
78 if (serial_diag_bitrate > 0)
80 Serial.begin(serial_diag_bitrate);
82 Serial.println(); Serial.println(
"GxEPD2_1248c::init()");
84 pinMode(_cs_m1, OUTPUT);
85 pinMode(_cs_s1, OUTPUT);
86 pinMode(_cs_m2, OUTPUT);
87 pinMode(_cs_s2, OUTPUT);
88 pinMode(_dc1, OUTPUT);
89 pinMode(_dc2, OUTPUT);
90 pinMode(_rst1, OUTPUT);
91 pinMode(_rst2, OUTPUT);
92 pinMode(_busy_m1, INPUT);
93 pinMode(_busy_s1, INPUT);
94 pinMode(_busy_m2, INPUT);
95 pinMode(_busy_s2, INPUT);
96 digitalWrite(_cs_m1, HIGH);
97 digitalWrite(_cs_s1, HIGH);
98 digitalWrite(_cs_m2, HIGH);
99 digitalWrite(_cs_s2, HIGH);
103 _getMasterTemperature();
112void GxEPD2_1248c::_writeScreenBuffer(uint8_t command, uint8_t value)
114 M1.writeScreenBuffer(command, value);
115 S1.writeScreenBuffer(command, value);
116 M2.writeScreenBuffer(command, value);
117 S2.writeScreenBuffer(command, value);
123 _writeScreenBuffer(0x10, value);
124 _writeScreenBuffer(0x13, ~value);
131 _writeScreenBuffer(0x10, black_value);
132 _writeScreenBuffer(0x13, color_value);
136void GxEPD2_1248c::_writeImage(uint8_t command,
const uint8_t* bitmap, int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
140 S2.writeImagePart(command, bitmap, 0, 0, w, h, x, y, w, h, invert, mirror_y, pgm);
141 M2.writeImagePart(command, bitmap, 0, 0, w, h, x - S2.WIDTH, y, w, h, invert, mirror_y, pgm);
142 M1.writeImagePart(command, bitmap, 0, 0, w, h, x, y - S2.HEIGHT, w, h, invert, mirror_y, pgm);
143 S1.writeImagePart(command, bitmap, 0, 0, w, h, x - M1.WIDTH, y - M2.HEIGHT, w, h, invert, mirror_y, pgm);
147void GxEPD2_1248c::writeImage(
const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
151 _writeImage(0x10, bitmap, x, y, w, h, invert, mirror_y, pgm);
152 _writeScreenBuffer(0x13, 0x0);
155void GxEPD2_1248c::_writeImagePart(uint8_t command,
const uint8_t* bitmap, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
156 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
160 S2.writeImagePart(command, bitmap, x_part, y_part, w, h, x, y, w, h, invert, mirror_y, pgm);
161 M2.writeImagePart(command, bitmap, x_part, y_part, w, h, x - S2.WIDTH, y, w, h, invert, mirror_y, pgm);
162 M1.writeImagePart(command, bitmap, x_part, y_part, w, h, x, y - S2.HEIGHT, w, h, invert, mirror_y, pgm);
163 S1.writeImagePart(command, bitmap, x_part, y_part, w, h, x - M1.WIDTH, y - M2.HEIGHT, w, h, invert, mirror_y, pgm);
168 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
172 _writeImagePart(0x10, bitmap, x_part, y_part, w, h, x, y, w, h, invert, mirror_y, pgm);
175void GxEPD2_1248c::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)
179 _writeImage(0x10, black, x, y, w, h, invert, mirror_y, pgm);
180 _writeImage(0x13, color, x, y, w, h, !invert, mirror_y, pgm);
184 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
188 _writeImagePart(0x10, black, x_part, y_part, w, h, x, y, w, h, invert, mirror_y, pgm);
189 _writeImagePart(0x13, color, x_part, y_part, w, h, x, y, w, h, !invert, mirror_y, pgm);
192void GxEPD2_1248c::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)
194 writeImage(data1, data2, x, y, w, h, invert, mirror_y, pgm);
197void GxEPD2_1248c::drawImage(
const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
199 writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm);
204 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
206 writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
210void GxEPD2_1248c::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)
212 writeImage(black, color, x, y, w, h, invert, mirror_y, pgm);
217 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
219 writeImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
223void GxEPD2_1248c::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)
225 writeNative(data1, data2, x, y, w, h, invert, mirror_y, pgm);
257 _writeCommandAll(0x07);
263void GxEPD2_1248c::_reset(
void)
265 digitalWrite(_rst1, LOW);
266 digitalWrite(_rst2, LOW);
268 digitalWrite(_rst1, HIGH);
269 digitalWrite(_rst2, HIGH);
274void GxEPD2_1248c::_initSPI()
277 if ((SCK != _sck) || (MISO != _miso) || (MOSI != _mosi))
280 SPI.begin(_sck, _miso, _mosi, _cs_m1);
288void GxEPD2_1248c::_PowerOn()
292 _writeCommandMaster(0x04);
298void GxEPD2_1248c::_PowerOff()
302 _writeCommandMaster(0x02);
309void GxEPD2_1248c::_InitDisplay()
313 M1.writeCommand(0x00);
315 S1.writeCommand(0x00);
317 M2.writeCommand(0x00);
319 S2.writeCommand(0x00);
322 M1.writeCommand(0x06);
327 M2.writeCommand(0x06);
333 M1.writeCommand(0x61);
338 S1.writeCommand(0x61);
343 M2.writeCommand(0x61);
348 S2.writeCommand(0x61);
353 _writeCommandAll(0x15);
355 _writeCommandAll(0x50);
359 _writeCommandAll(0x60);
362 _writeCommandAll(0xE3);
365 _writeCommandAll(0xe0);
368 _writeCommandAll(0xe5);
369 _writeDataAll(_temperature);
372void GxEPD2_1248c::_Init_Full()
374 Serial.println(
"_Init_Full");
377 M1.writeCommand(0x00);
379 S1.writeCommand(0x00);
381 M2.writeCommand(0x00);
383 S2.writeCommand(0x00);
389void GxEPD2_1248c::_Init_Part()
391 Serial.println(
"_Init_Part");
394 M1.writeCommand(0x00);
396 S1.writeCommand(0x00);
398 M2.writeCommand(0x00);
400 S2.writeCommand(0x00);
406void GxEPD2_1248c::_Update_Full()
408 _writeCommandAll(0x12);
412void GxEPD2_1248c::_Update_Part()
414 _writeCommandAll(0x12);
418void GxEPD2_1248c::_writeCommandMaster(uint8_t c)
421 digitalWrite(_dc1, LOW);
422 digitalWrite(_dc2, LOW);
423 digitalWrite(_cs_m1, LOW);
424 digitalWrite(_cs_m2, LOW);
426 digitalWrite(_cs_m1, HIGH);
427 digitalWrite(_cs_m2, HIGH);
428 digitalWrite(_dc1, HIGH);
429 digitalWrite(_dc2, HIGH);
430 SPI.endTransaction();
433void GxEPD2_1248c::_writeDataMaster(uint8_t d)
436 digitalWrite(_cs_m1, LOW);
437 digitalWrite(_cs_m2, LOW);
439 digitalWrite(_cs_m1, HIGH);
440 digitalWrite(_cs_m2, HIGH);
441 SPI.endTransaction();
444void GxEPD2_1248c::_writeCommandAll(uint8_t c)
447 digitalWrite(_dc1, LOW);
448 digitalWrite(_dc2, LOW);
449 digitalWrite(_cs_m1, LOW);
450 digitalWrite(_cs_s1, LOW);
451 digitalWrite(_cs_m2, LOW);
452 digitalWrite(_cs_s2, LOW);
454 digitalWrite(_cs_m1, HIGH);
455 digitalWrite(_cs_s1, HIGH);
456 digitalWrite(_cs_m2, HIGH);
457 digitalWrite(_cs_s2, HIGH);
458 digitalWrite(_dc1, HIGH);
459 digitalWrite(_dc2, HIGH);
460 SPI.endTransaction();
463void GxEPD2_1248c::_writeDataAll(uint8_t d)
466 digitalWrite(_cs_m1, LOW);
467 digitalWrite(_cs_s1, LOW);
468 digitalWrite(_cs_m2, LOW);
469 digitalWrite(_cs_s2, LOW);
471 digitalWrite(_cs_m1, HIGH);
472 digitalWrite(_cs_s1, HIGH);
473 digitalWrite(_cs_m2, HIGH);
474 digitalWrite(_cs_s2, HIGH);
475 SPI.endTransaction();
478void GxEPD2_1248c::_writeDataPGM_All(
const uint8_t* data, uint16_t n, int16_t fill_with_zeroes)
481 digitalWrite(_cs_m1, LOW);
482 digitalWrite(_cs_s1, LOW);
483 digitalWrite(_cs_m2, LOW);
484 digitalWrite(_cs_s2, LOW);
485 for (uint16_t i = 0; i < n; i++)
487 SPI.transfer(pgm_read_byte(&*data++));
489 while (fill_with_zeroes > 0)
494 digitalWrite(_cs_m1, HIGH);
495 digitalWrite(_cs_s1, HIGH);
496 digitalWrite(_cs_m2, HIGH);
497 digitalWrite(_cs_s2, HIGH);
498 SPI.endTransaction();
501void GxEPD2_1248c::_waitWhileAnyBusy(
const char* comment, uint16_t busy_time)
506 unsigned long start = micros();
510 bool nb_m1 = _busy_m1 >= 0 ?
_busy_level != digitalRead(_busy_m1) : true;
511 bool nb_s1 = _busy_m1 >= 0 ?
_busy_level != digitalRead(_busy_s1) : true;
512 bool nb_m2 = _busy_m1 >= 0 ?
_busy_level != digitalRead(_busy_m2) : true;
513 bool nb_s2 = _busy_m1 >= 0 ?
_busy_level != digitalRead(_busy_s2) : true;
514 if (nb_m1 && nb_s1 && nb_m2 && nb_s2)
break;
518 Serial.println(
"Busy Timeout!");
526 unsigned long elapsed = micros() - start;
527 Serial.print(comment);
529 Serial.println(elapsed);
534 else delay(busy_time);
537void GxEPD2_1248c::_getMasterTemperature()
540 M1.writeCommand(0x40);
541 _waitWhileAnyBusy(
"getMasterTemperature", 300);
543 pinMode(_mosi, INPUT);
545 digitalWrite(_sck, HIGH);
546 pinMode(_sck, OUTPUT);
547 digitalWrite(_cs_m1, LOW);
548 pinMode(_mosi, INPUT);
549 for (uint16_t i = 0; i < 8; i++)
551 digitalWrite(_sck, LOW);
553 delayMicroseconds(2);
554 if (digitalRead(_mosi)) value |= 0x01;
555 delayMicroseconds(2);
556 digitalWrite(_sck, HIGH);
557 delayMicroseconds(2);
559 digitalWrite(_cs_m1, HIGH);
560 pinMode(_sck, INPUT);
561 _temperature = value;
565 Serial.print(
"Master Temperature is "); Serial.println(value);
569void GxEPD2_1248c::_readController(uint8_t cmd, uint8_t* data, uint16_t n, int8_t cs, int8_t dc)
571 if (cs < 0) cs = _cs_m1;
572 if (dc < 0) dc = _dc1;
574 digitalWrite(cs, LOW);
575 digitalWrite(dc, LOW);
577 digitalWrite(dc, HIGH);
578 digitalWrite(cs, HIGH);
579 SPI.endTransaction();
580 _waitWhileAnyBusy(
"_readController", 300);
582 pinMode(_mosi, INPUT);
584 digitalWrite(_sck, HIGH);
585 pinMode(_sck, OUTPUT);
586 digitalWrite(cs, LOW);
587 pinMode(_mosi, INPUT);
588 for (uint16_t j = 0; j < n; j++)
591 for (uint16_t i = 0; i < 8; i++)
593 digitalWrite(_sck, LOW);
595 delayMicroseconds(2);
596 if (digitalRead(_mosi)) value |= 0x01;
597 delayMicroseconds(2);
598 digitalWrite(_sck, HIGH);
599 delayMicroseconds(2);
603 digitalWrite(cs, HIGH);
604 pinMode(_sck, INPUT);
608GxEPD2_1248c::ScreenPart::ScreenPart(uint16_t width, uint16_t height,
bool rev_scan, int16_t cs, int16_t dc) :
609 WIDTH(width), HEIGHT(height), _rev_scan(rev_scan),
610 _cs(cs), _dc(dc), _spi_settings(4000000, MSBFIRST, SPI_MODE0)
614void GxEPD2_1248c::ScreenPart::writeScreenBuffer(uint8_t command, uint8_t value)
616 writeCommand(command);
617 for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++)
623void GxEPD2_1248c::ScreenPart::writeImagePart(uint8_t command,
const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
624 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
627 if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0))
return;
628 if ((x_part < 0) || (x_part >= w_bitmap))
return;
629 if ((y_part < 0) || (y_part >= h_bitmap))
return;
630 int32_t wb_bitmap = (w_bitmap + 7) / 8;
631 x_part -= x_part % 8;
632 w = w_bitmap - x_part < w ? w_bitmap - x_part : w;
633 h = h_bitmap - y_part < h ? h_bitmap - y_part : h;
635 w = 8 * ((w + 7) / 8);
636 int16_t x1 = x < 0 ? 0 : x;
637 int16_t y1 = y < 0 ? 0 : y;
638 int16_t w1 = x + w < int16_t(
WIDTH) ? w : int16_t(
WIDTH) - x;
639 int16_t h1 = y + h < int16_t(
HEIGHT) ? h : int16_t(
HEIGHT) - y;
644 if ((w1 <= 0) || (h1 <= 0))
return;
649 _setPartialRamArea(x1, y1, w1, h1);
650 writeCommand(command);
652 for (int16_t i = 0; i < h1; i++)
654 for (int16_t j = 0; j < w1 / 8; j++)
658 int32_t idx = mirror_y ? x_part / 8 + j + dx / 8 + ((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / 8 + j + dx / 8 + (y_part + i + dy) * wb_bitmap;
661#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
662 data = pgm_read_byte(&bitmap[idx]);
671 if (invert) data = ~data;
680void GxEPD2_1248c::ScreenPart::writeCommand(uint8_t c)
683 if (
_dc >= 0) digitalWrite(
_dc, LOW);
684 if (
_cs >= 0) digitalWrite(
_cs, LOW);
686 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
687 if (
_dc >= 0) digitalWrite(
_dc, HIGH);
688 SPI.endTransaction();
691void GxEPD2_1248c::ScreenPart::writeData(uint8_t d)
694 if (
_cs >= 0) digitalWrite(
_cs, LOW);
696 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
697 SPI.endTransaction();
700void GxEPD2_1248c::ScreenPart::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
702 if (_rev_scan) x =
WIDTH - w - x;
703 uint16_t xe = (x + w - 1) | 0x0007;
704 uint16_t ye = y + h - 1;
718void GxEPD2_1248c::ScreenPart::_startTransfer()
721 if (
_cs >= 0) digitalWrite(
_cs, LOW);
724void GxEPD2_1248c::ScreenPart::_transfer(uint8_t value)
729void GxEPD2_1248c::ScreenPart::_endTransfer()
731 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
732 SPI.endTransaction();
void refresh(bool partial_update_mode=false)
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 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)
static const uint16_t power_on_time
static const uint16_t full_refresh_time
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 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)
GxEPD2_1248c(int16_t cs_m1, int16_t cs_s1, int16_t cs_m2, int16_t cs_s2, int16_t dc1, int16_t dc2, int16_t rst1, int16_t rst2, int16_t busy_m1, int16_t busy_s1, int16_t busy_m2, int16_t busy_s2)
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)
static const uint16_t partial_refresh_time
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 clearScreen(uint8_t value=0xFF)
static const uint16_t WIDTH
void init(uint32_t serial_diag_bitrate=0)
static const uint16_t HEIGHT
void writeScreenBuffer(uint8_t value=0xFF)
void _transfer(uint8_t value)
SPISettings _spi_settings