22#define IT8951_TCON_SYS_RUN 0x0001
23#define IT8951_TCON_STANDBY 0x0002
24#define IT8951_TCON_SLEEP 0x0003
25#define IT8951_TCON_REG_RD 0x0010
26#define IT8951_TCON_REG_WR 0x0011
27#define IT8951_TCON_LD_IMG 0x0020
28#define IT8951_TCON_LD_IMG_AREA 0x0021
29#define IT8951_TCON_LD_IMG_END 0x0022
32#define USDEF_I80_CMD_DPY_AREA 0x0034
33#define USDEF_I80_CMD_GET_DEV_INFO 0x0302
34#define USDEF_I80_CMD_DPY_BUF_AREA 0x0037
35#define USDEF_I80_CMD_VCOM 0x0039
38#define IT8951_ROTATE_0 0
39#define IT8951_ROTATE_90 1
40#define IT8951_ROTATE_180 2
41#define IT8951_ROTATE_270 3
50#define IT8951_LDIMG_L_ENDIAN 0
51#define IT8951_LDIMG_B_ENDIAN 1
53#define SYS_REG_BASE 0x0000
54#define I80CPCR (SYS_REG_BASE + 0x04)
55#define MCSR_BASE_ADDR 0x0200
56#define LISAR (MCSR_BASE_ADDR + 0x0008)
59 GxEPD2_EPD(cs, dc, rst, busy, LOW, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate),
60 _spi_settings(24000000, MSBFIRST, SPI_MODE0),
61 _spi_settings_for_read(1000000, MSBFIRST, SPI_MODE0)
67 init(serial_diag_bitrate,
true, 20,
false);
70void GxEPD2_it60::init(uint32_t serial_diag_bitrate,
bool initial, uint16_t reset_duration,
bool pulldown_rst_mode)
72 GxEPD2_EPD::init(serial_diag_bitrate, initial, reset_duration, pulldown_rst_mode);
77 digitalWrite(
_rst, LOW);
79 digitalWrite(
_rst, HIGH);
86 _readData16((uint16_t*)&IT8951DevInfo,
sizeof(IT8951DevInfo) / 2);
90 printf(
"Panel(W,H) = (%d,%d)\r\n",
91 IT8951DevInfo.usPanelW, IT8951DevInfo.usPanelH );
92 printf(
"Image Buffer Address = %lX\r\n",
93 uint32_t(IT8951DevInfo.usImgBufAddrL) | (uint32_t(IT8951DevInfo.usImgBufAddrH) << 16));
95 printf(
"FW Version = %s\r\n", (uint8_t*)IT8951DevInfo.usFWVersion);
96 printf(
"LUT Version = %s\r\n", (uint8_t*)IT8951DevInfo.usLUTVersion);
99 _IT8951WriteReg(
I80CPCR, 0x0001);
100 if (
VCOM != _IT8951GetVCOM())
102 _IT8951SetVCOM(
VCOM);
103 printf(
"VCOM = -%.02fV\n", (
double)_IT8951GetVCOM() / 1000);
105 printf(
"VCOM = -%.02fV\n", (
double)_IT8951GetVCOM() / 1000);
115 SPI.beginTransaction(_spi_settings);
116 if (
_cs >= 0) digitalWrite(
_cs, LOW);
119 for (uint32_t i = 0; i < uint32_t(
WIDTH) * uint32_t(
HEIGHT); i++)
122#if defined(ESP8266) || defined(ESP32)
123 if (0 == i % 10000) yield();
126 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
127 SPI.endTransaction();
136 else _writeScreenBuffer(value);
139void GxEPD2_it60::_writeScreenBuffer(uint8_t value)
144 SPI.beginTransaction(_spi_settings);
145 if (
_cs >= 0) digitalWrite(
_cs, LOW);
148 for (uint32_t i = 0; i < uint32_t(
WIDTH) * uint32_t(
HEIGHT); i++)
151#if defined(ESP8266) || defined(ESP32)
152 if (0 == i % 10000) yield();
155 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
156 SPI.endTransaction();
161void GxEPD2_it60::writeImage(
const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
165 int16_t wb = (w + 7) / 8;
168 int16_t x1 = x < 0 ? 0 : x;
169 int16_t y1 = y < 0 ? 0 : y;
170 int16_t w1 = x + w < int16_t(
WIDTH) ? w : int16_t(
WIDTH) - x;
171 int16_t h1 = y + h < int16_t(
HEIGHT) ? h : int16_t(
HEIGHT) - y;
176 if ((w1 <= 0) || (h1 <= 0))
return;
178 _setPartialRamArea(x1, y1, w1, h1);
179 SPI.beginTransaction(_spi_settings);
180 if (
_cs >= 0) digitalWrite(
_cs, LOW);
183 for (int16_t i = 0; i < h1; i++)
185 for (int16_t j = 0; j < w1 / 8; j++)
189 uint32_t idx = mirror_y ? uint32_t(j + dx / 8) + uint32_t((h - 1 - (i + dy))) * uint32_t(wb) : uint32_t(j + dx / 8) + uint32_t(i + dy) * uint32_t(wb);
192#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
193 data = pgm_read_byte(&bitmap[idx]);
202 if (invert) data = ~data;
205#if defined(ESP8266) || defined(ESP32)
209 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
210 SPI.endTransaction();
217 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
221 if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0))
return;
222 if ((x_part < 0) || (x_part >= w_bitmap))
return;
223 if ((y_part < 0) || (y_part >= h_bitmap))
return;
224 int16_t wb_bitmap = (w_bitmap + 7) / 8;
225 x_part -= x_part % 8;
226 w = w_bitmap - x_part < w ? w_bitmap - x_part : w;
227 h = h_bitmap - y_part < h ? h_bitmap - y_part : h;
229 w = 8 * ((w + 7) / 8);
230 int16_t x1 = x < 0 ? 0 : x;
231 int16_t y1 = y < 0 ? 0 : y;
232 int16_t w1 = x + w < int16_t(
WIDTH) ? w : int16_t(
WIDTH) - x;
233 int16_t h1 = y + h < int16_t(
HEIGHT) ? h : int16_t(
HEIGHT) - y;
238 if ((w1 <= 0) || (h1 <= 0))
return;
240 _setPartialRamArea(x1, y1, w1, h1);
241 SPI.beginTransaction(_spi_settings);
242 if (
_cs >= 0) digitalWrite(
_cs, LOW);
245 for (int16_t i = 0; i < h1; i++)
247 for (int16_t j = 0; j < w1 / 8; j++)
251 uint32_t idx = mirror_y ? x_part / 8 + (j + dx / 8) + uint32_t((h_bitmap - 1 - (y_part + i + dy))) * uint32_t(wb_bitmap) : x_part / 8 + j + dx / 8 + uint32_t(y_part + i + dy) * uint32_t(wb_bitmap);
254#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
255 data = pgm_read_byte(&bitmap[idx]);
264 if (invert) data = ~data;
268 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
269 SPI.endTransaction();
275void GxEPD2_it60::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)
279 writeImage(black, x, y, w, h, invert, mirror_y, pgm);
284 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
288 writeImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
292void GxEPD2_it60::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)
298 int16_t x1 = x < 0 ? 0 : x;
299 int16_t y1 = y < 0 ? 0 : y;
300 int16_t w1 = x + w < int16_t(
WIDTH) ? w : int16_t(
WIDTH) - x;
301 int16_t h1 = y + h < int16_t(
HEIGHT) ? h : int16_t(
HEIGHT) - y;
306 if ((w1 <= 0) || (h1 <= 0))
return;
308 _setPartialRamArea(x1, y1, w1, h1);
309 SPI.beginTransaction(_spi_settings);
310 if (
_cs >= 0) digitalWrite(
_cs, LOW);
313 for (int16_t i = 0; i < h1; i++)
315 for (int16_t j = 0; j < w1; j++)
319 uint32_t idx = mirror_y ? uint32_t(j + dx) + uint32_t((h - 1 - (i + dy))) * uint32_t(w) : uint32_t(j + dx) + uint32_t(i + dy) * uint32_t(w);
322#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
323 data = pgm_read_byte(&data1[idx]);
332 if (invert) data = ~data;
335#if defined(ESP8266) || defined(ESP32)
339 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
340 SPI.endTransaction();
347void GxEPD2_it60::drawImage(
const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
349 writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm);
350 _refresh(x, y, w, h,
true);
354 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
356 writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
357 _refresh(x, y, w, h,
true);
360void GxEPD2_it60::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)
362 writeImage(black, color, x, y, w, h, invert, mirror_y, pgm);
363 _refresh(x, y, w, h,
true);
366void GxEPD2_it60::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,
367 int16_t x, int16_t y, int16_t w, int16_t h,
bool invert,
bool mirror_y,
bool pgm)
369 writeImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
370 _refresh(x, y, w, h,
true);
373void GxEPD2_it60::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)
375 writeNative(data1, data2, x, y, w, h, invert, mirror_y, pgm);
376 _refresh(x, y, w, h,
false);
381 _refresh(0, 0,
WIDTH,
HEIGHT, partial_update_mode);
386 _refresh(x, y, w, h,
true);
389void GxEPD2_it60::_refresh(int16_t x, int16_t y, int16_t w, int16_t h,
bool partial_update_mode)
393 int16_t x1 = x < 0 ? 0 : x;
394 int16_t y1 = y < 0 ? 0 : y;
395 int16_t w1 = x + w < int16_t(
WIDTH) ? w : int16_t(
WIDTH) - x;
396 int16_t h1 = y + h < int16_t(
HEIGHT) ? h : int16_t(
HEIGHT) - y;
411 _writeData16(partial_update_mode ? 1 : 2);
433void GxEPD2_it60::_send8pixel(uint8_t data)
435 for (uint8_t j = 0; j < 8; j++)
437 SPI.transfer(data & 0x80 ? 0x00 : 0xFF);
442void GxEPD2_it60::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
456void GxEPD2_it60::_PowerOn()
466void GxEPD2_it60::_PowerOff()
474void GxEPD2_it60::_InitDisplay()
479 digitalWrite(
_rst, LOW);
481 digitalWrite(
_rst, HIGH);
486void GxEPD2_it60::_Init_Full()
493void GxEPD2_it60::_Init_Part()
500void GxEPD2_it60::_waitWhileBusy2(
const char* comment, uint16_t busy_time)
504 unsigned long start = micros();
511 Serial.println(
"Busy Timeout!");
517#if !defined(DISABLE_DIAGNOSTIC_OUTPUT)
520 unsigned long elapsed = micros() - start;
523 Serial.print(comment);
525 Serial.println(elapsed);
532 else delay(busy_time);
535uint16_t GxEPD2_it60::_transfer16(uint16_t value)
537 uint16_t rv = SPI.transfer(value >> 8) << 8;
538 return (rv | SPI.transfer(value));
541void GxEPD2_it60::_writeCommand16(uint16_t c)
543 String s = String(
"_writeCommand16(0x") + String(c, HEX) + String(
")");
545 SPI.beginTransaction(_spi_settings);
546 if (
_cs >= 0) digitalWrite(
_cs, LOW);
550 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
551 SPI.endTransaction();
555void GxEPD2_it60::_writeData16(uint16_t d)
558 SPI.beginTransaction(_spi_settings);
559 if (
_cs >= 0) digitalWrite(
_cs, LOW);
563 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
564 SPI.endTransaction();
567void GxEPD2_it60::_writeData16(
const uint16_t* d, uint32_t n)
570 SPI.beginTransaction(_spi_settings);
571 if (
_cs >= 0) digitalWrite(
_cs, LOW);
574 for (uint32_t i = 0; i < n; i++)
578 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
579 SPI.endTransaction();
582uint16_t GxEPD2_it60::_readData16()
585 SPI.beginTransaction(_spi_settings);
586 if (
_cs >= 0) digitalWrite(
_cs, LOW);
591 uint16_t rv = _transfer16(0);
592 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
593 SPI.endTransaction();
597void GxEPD2_it60::_readData16(uint16_t* d, uint32_t n)
600 SPI.beginTransaction(_spi_settings);
601 if (
_cs >= 0) digitalWrite(
_cs, LOW);
606 for (uint32_t i = 0; i < n; i++)
608 *d++ = _transfer16(0);
611 if (
_cs >= 0) digitalWrite(
_cs, HIGH);
612 SPI.endTransaction();
615void GxEPD2_it60::_writeCommandData16(uint16_t c,
const uint16_t* d, uint16_t n)
618 for (uint16_t i = 0; i < n; i++)
624void GxEPD2_it60::_IT8951SystemRun()
629void GxEPD2_it60::_IT8951StandBy()
634void GxEPD2_it60::_IT8951Sleep()
639uint16_t GxEPD2_it60::_IT8951ReadReg(uint16_t usRegAddr)
645 _writeData16(usRegAddr);
647 usData = _readData16();
651void GxEPD2_it60::_IT8951WriteReg(uint16_t usRegAddr, uint16_t usValue)
655 _writeData16(usRegAddr);
656 _writeData16(usValue);
659uint16_t GxEPD2_it60::_IT8951GetVCOM(
void)
667 vcom = _readData16();
671void GxEPD2_it60::_IT8951SetVCOM(uint16_t vcom)
#define IT8951_TCON_SYS_RUN
#define IT8951_TCON_LD_IMG_AREA
#define IT8951_TCON_LD_IMG_END
#define IT8951_TCON_REG_RD
#define USDEF_I80_CMD_DPY_AREA
#define USDEF_I80_CMD_VCOM
#define IT8951_TCON_REG_WR
#define IT8951_LDIMG_B_ENDIAN
#define IT8951_TCON_SLEEP
#define IT8951_TCON_STANDBY
#define USDEF_I80_CMD_GET_DEV_INFO
virtual void init(uint32_t serial_diag_bitrate=0)
void _waitWhileBusy(const char *comment=0, uint16_t busy_time=5000)
static const uint16_t set_vcom_time
static const uint16_t refresh_par_time
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)
static const uint16_t default_wait_time
static const uint16_t power_on_time
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 init(uint32_t serial_diag_bitrate=0)
GxEPD2_it60(int16_t cs, int16_t dc, int16_t rst, int16_t busy)
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 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 HEIGHT
static const uint16_t diag_min_time
static const uint16_t full_refresh_time
static const uint16_t reset_to_ready_time
void refresh(bool partial_update_mode=false)
void clearScreen(uint8_t value=0x33)
static const uint16_t WIDTH
static const uint16_t power_off_time
void writeScreenBuffer(uint8_t value=0x33)
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 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)
static const uint16_t refresh_cmd_time