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);
 
 
   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_1448x1072::_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();
 
  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();
 
 
  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);
 
 
  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();
 
 
  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);
 
 
  362  writeImage(black, color, x, y, w, h, invert, mirror_y, pgm);
 
  363  _refresh(x, y, w, h, 
true);
 
 
  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);
 
 
  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_1448x1072::_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_1448x1072::_send8pixel(uint8_t data)
 
  435  for (uint8_t j = 0; j < 8; j++)
 
  437    SPI.transfer(data & 0x80 ? 0x00 : 0xFF);
 
  442void GxEPD2_it60_1448x1072::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
 
  456void GxEPD2_it60_1448x1072::_PowerOn()
 
  466void GxEPD2_it60_1448x1072::_PowerOff()
 
  474void GxEPD2_it60_1448x1072::_InitDisplay()
 
  479    digitalWrite(
_rst, LOW);
 
  481    digitalWrite(
_rst, HIGH);
 
  486void GxEPD2_it60_1448x1072::_Init_Full()
 
  493void GxEPD2_it60_1448x1072::_Init_Part()
 
  500void GxEPD2_it60_1448x1072::_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_1448x1072::_transfer16(uint16_t value)
 
  537  uint16_t rv = SPI.transfer(value >> 8) << 8;
 
  538  return (rv | SPI.transfer(value));
 
  541void GxEPD2_it60_1448x1072::_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_1448x1072::_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_1448x1072::_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_1448x1072::_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_1448x1072::_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_1448x1072::_writeCommandData16(uint16_t c, 
const uint16_t* d, uint16_t n)
 
  618  for (uint16_t i = 0; i < n; i++)
 
  624void GxEPD2_it60_1448x1072::_IT8951SystemRun()
 
  629void GxEPD2_it60_1448x1072::_IT8951StandBy()
 
  634void GxEPD2_it60_1448x1072::_IT8951Sleep()
 
  639uint16_t GxEPD2_it60_1448x1072::_IT8951ReadReg(uint16_t usRegAddr)
 
  645  _writeData16(usRegAddr);
 
  647  usData = _readData16();
 
  651void GxEPD2_it60_1448x1072::_IT8951WriteReg(uint16_t usRegAddr, uint16_t usValue)
 
  655  _writeData16(usRegAddr);
 
  656  _writeData16(usValue);
 
  659uint16_t GxEPD2_it60_1448x1072::_IT8951GetVCOM(
void)
 
  667  vcom = _readData16();
 
  671void GxEPD2_it60_1448x1072::_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)
 
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 clearScreen(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)
 
static const uint16_t refresh_par_time
 
static const uint16_t power_on_time
 
void writeScreenBuffer(uint8_t value=0x33)
 
GxEPD2_it60_1448x1072(int16_t cs, int16_t dc, int16_t rst, int16_t busy)
 
void refresh(bool partial_update_mode=false)
 
static const uint16_t power_off_time
 
static const uint16_t default_wait_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 init(uint32_t serial_diag_bitrate=0)
 
static const uint16_t reset_to_ready_time
 
static const uint16_t HEIGHT
 
static const uint16_t WIDTH
 
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 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
 
static const uint16_t refresh_cmd_time
 
static const uint16_t set_vcom_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)
 
static const uint16_t diag_min_time