Paperd.Ink Library 0.0.5
Library for interacting with Paperd.Ink devices.
Loading...
Searching...
No Matches
GxEPD2_it103_1872x1404.cpp
Go to the documentation of this file.
1// Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
2// Requires HW SPI and Adafruit_GFX. Caution: these e-papers require 3.3V supply AND data lines!
3//
4// GxEPD2_it103_1872x1404 class is based on Demo Example from Waveshare for Raspberry PI https://github.com/waveshare/IT8951/archive/master.zip
5// Controller: IT8951 : https://www.waveshare.com/w/upload/1/18/IT8951_D_V0.2.4.3_20170728.pdf
6//
7// The GxEPD2_it103_1872x1404 driver class supports the Waveshare e-Paper IT8951 Driver HAT connected with SPI for the ES103TC1 10.3" e-paper panel (parallel IF)
8// https://www.waveshare.com/product/displays/e-paper/epaper-1/10.3inch-e-paper-d.htm
9// This Driver HAT requires 5V power supply but works with 3.3V data lines; requires both MOSI and MISO SPI lines.
10//
11// Author: Jean-Marc Zingg
12//
13// Version: see library.properties
14//
15// Library: https://github.com/ZinggJM/GxEPD2
16
18
19//#define VCOM 1500 //mV e.g. -1.53 = 1530 = 0x5FA
20#define VCOM 2330 //mV -2.33V as of sticker on my panel
21
22//Built in I80 Command Code
23#define IT8951_TCON_SYS_RUN 0x0001
24#define IT8951_TCON_STANDBY 0x0002
25#define IT8951_TCON_SLEEP 0x0003
26#define IT8951_TCON_REG_RD 0x0010
27#define IT8951_TCON_REG_WR 0x0011
28#define IT8951_TCON_LD_IMG 0x0020
29#define IT8951_TCON_LD_IMG_AREA 0x0021
30#define IT8951_TCON_LD_IMG_END 0x0022
31
32//I80 User defined command code
33#define USDEF_I80_CMD_DPY_AREA 0x0034
34#define USDEF_I80_CMD_GET_DEV_INFO 0x0302
35#define USDEF_I80_CMD_DPY_BUF_AREA 0x0037
36#define USDEF_I80_CMD_VCOM 0x0039
37
38//Rotate mode
39#define IT8951_ROTATE_0 0
40#define IT8951_ROTATE_90 1
41#define IT8951_ROTATE_180 2
42#define IT8951_ROTATE_270 3
43
44//Pixel mode , BPP - Bit per Pixel
45#define IT8951_2BPP 0
46#define IT8951_3BPP 1
47#define IT8951_4BPP 2
48#define IT8951_8BPP 3
49
50//Endian Type
51#define IT8951_LDIMG_L_ENDIAN 0
52#define IT8951_LDIMG_B_ENDIAN 1
53
54#define SYS_REG_BASE 0x0000
55#define I80CPCR (SYS_REG_BASE + 0x04)
56#define MCSR_BASE_ADDR 0x0200
57#define LISAR (MCSR_BASE_ADDR + 0x0008)
58
59GxEPD2_it103_1872x1404::GxEPD2_it103_1872x1404(int16_t cs, int16_t dc, int16_t rst, int16_t busy) :
60 GxEPD2_EPD(cs, dc, rst, busy, LOW, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate),
61 _spi_settings(24000000, MSBFIRST, SPI_MODE0),
62 _spi_settings_for_read(1000000, MSBFIRST, SPI_MODE0)
63{
64}
65
66void GxEPD2_it103_1872x1404::init(uint32_t serial_diag_bitrate)
67{
68 init(serial_diag_bitrate, true, 20, false);
69}
70
71void GxEPD2_it103_1872x1404::init(uint32_t serial_diag_bitrate, bool initial, uint16_t reset_duration, bool pulldown_rst_mode)
72{
73 GxEPD2_EPD::init(serial_diag_bitrate, initial, reset_duration, pulldown_rst_mode);
74
75 // we need a long reset pulse
76 if (_rst >= 0)
77 {
78 digitalWrite(_rst, LOW);
79 delay(200);
80 digitalWrite(_rst, HIGH);
81 delay(200);
82 _waitWhileBusy("init reset_to_ready", reset_to_ready_time);
83 }
84
85 _writeCommand16(USDEF_I80_CMD_GET_DEV_INFO);
86 _waitWhileBusy("GetIT8951SystemInfo", power_on_time);
87 _readData16((uint16_t*)&IT8951DevInfo, sizeof(IT8951DevInfo) / 2);
88 if (_diag_enabled)
89 {
90 //Show Device information of IT8951
91 printf("Panel(W,H) = (%d,%d)\r\n",
92 IT8951DevInfo.usPanelW, IT8951DevInfo.usPanelH );
93 printf("Image Buffer Address = %lX\r\n",
94 uint32_t(IT8951DevInfo.usImgBufAddrL) | (uint32_t(IT8951DevInfo.usImgBufAddrH) << 16));
95 //Show Firmware and LUT Version
96 printf("FW Version = %s\r\n", (uint8_t*)IT8951DevInfo.usFWVersion);
97 printf("LUT Version = %s\r\n", (uint8_t*)IT8951DevInfo.usLUTVersion);
98 }
99 //Set to Enable I80 Packed mode
100 _IT8951WriteReg(I80CPCR, 0x0001);
101 if (VCOM != _IT8951GetVCOM())
102 {
103 _IT8951SetVCOM(VCOM);
104 printf("VCOM = -%.02fV\n", (double)_IT8951GetVCOM() / 1000);
105 }
106 printf("VCOM = -%.02fV\n", (double)_IT8951GetVCOM() / 1000);
107}
108
110{
111 _initial_write = false; // initial full screen buffer clean done
112 if (_initial_refresh) _Init_Full();
113 else _Init_Part();
114 _initial_refresh = false;
115 _setPartialRamArea(0, 0, WIDTH, HEIGHT);
116 SPI.beginTransaction(_spi_settings);
117 if (_cs >= 0) digitalWrite(_cs, LOW);
118 _transfer16(0x0000); // preamble for write data
119 _waitWhileBusy2("clearScreen preamble", default_wait_time);
120 for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT); i++)
121 {
122 SPI.transfer(value);
123#if defined(ESP8266) || defined(ESP32)
124 if (0 == i % 10000) yield();
125#endif
126 }
127 if (_cs >= 0) digitalWrite(_cs, HIGH);
128 SPI.endTransaction();
129 _writeCommand16(IT8951_TCON_LD_IMG_END);
130 _waitWhileBusy2("clearScreen load end", default_wait_time);
131 _refresh(0, 0, WIDTH, HEIGHT, false);
132}
133
135{
136 if (_initial_refresh) clearScreen(value);
137 else _writeScreenBuffer(value);
138}
139
140void GxEPD2_it103_1872x1404::_writeScreenBuffer(uint8_t value)
141{
142 _initial_write = false; // initial full screen buffer clean done
143 if (!_using_partial_mode) _Init_Part();
144 _setPartialRamArea(0, 0, WIDTH, HEIGHT);
145 SPI.beginTransaction(_spi_settings);
146 if (_cs >= 0) digitalWrite(_cs, LOW);
147 _transfer16(0x0000); // preamble for write data
148 _waitWhileBusy2("clearScreen preamble", default_wait_time);
149 for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT); i++)
150 {
151 SPI.transfer(value);
152#if defined(ESP8266) || defined(ESP32)
153 if (0 == i % 10000) yield();
154#endif
155 }
156 if (_cs >= 0) digitalWrite(_cs, HIGH);
157 SPI.endTransaction();
158 _writeCommand16(IT8951_TCON_LD_IMG_END);
159 _waitWhileBusy2("_writeScreenBuffer load end", default_wait_time);
160}
161
162void GxEPD2_it103_1872x1404::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
163{
164 if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
165 delay(1); // yield() to avoid WDT on ESP8266 and ESP32
166 int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
167 x -= x % 8; // byte boundary
168 w = wb * 8; // byte boundary
169 int16_t x1 = x < 0 ? 0 : x; // limit
170 int16_t y1 = y < 0 ? 0 : y; // limit
171 int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
172 int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
173 int16_t dx = x1 - x;
174 int16_t dy = y1 - y;
175 w1 -= dx;
176 h1 -= dy;
177 if ((w1 <= 0) || (h1 <= 0)) return;
178 if (!_using_partial_mode) _Init_Part();
179 _setPartialRamArea(x1, y1, w1, h1);
180 SPI.beginTransaction(_spi_settings);
181 if (_cs >= 0) digitalWrite(_cs, LOW);
182 _transfer16(0x0000); // preamble for write data
183 _waitWhileBusy2("writeImage preamble", default_wait_time);
184 for (int16_t i = 0; i < h1; i++)
185 {
186 for (int16_t j = 0; j < w1 / 8; j++)
187 {
188 uint8_t data;
189 // use wb, h of bitmap for index!
190 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);
191 if (pgm)
192 {
193#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
194 data = pgm_read_byte(&bitmap[idx]);
195#else
196 data = bitmap[idx];
197#endif
198 }
199 else
200 {
201 data = bitmap[idx];
202 }
203 if (invert) data = ~data;
204 _send8pixel(~data);
205 }
206#if defined(ESP8266) || defined(ESP32)
207 yield();
208#endif
209 }
210 if (_cs >= 0) digitalWrite(_cs, HIGH);
211 SPI.endTransaction();
212 _writeCommand16(IT8951_TCON_LD_IMG_END);
213 _waitWhileBusy2("writeImage load end", default_wait_time);
214 delay(1); // yield() to avoid WDT on ESP8266 and ESP32
215}
216
217void GxEPD2_it103_1872x1404::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
218 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
219{
220 if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
221 delay(1); // yield() to avoid WDT on ESP8266 and ESP32
222 if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return;
223 if ((x_part < 0) || (x_part >= w_bitmap)) return;
224 if ((y_part < 0) || (y_part >= h_bitmap)) return;
225 int16_t wb_bitmap = (w_bitmap + 7) / 8; // width bytes, bitmaps are padded
226 x_part -= x_part % 8; // byte boundary
227 w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit
228 h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit
229 x -= x % 8; // byte boundary
230 w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded
231 int16_t x1 = x < 0 ? 0 : x; // limit
232 int16_t y1 = y < 0 ? 0 : y; // limit
233 int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
234 int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
235 int16_t dx = x1 - x;
236 int16_t dy = y1 - y;
237 w1 -= dx;
238 h1 -= dy;
239 if ((w1 <= 0) || (h1 <= 0)) return;
240 if (!_using_partial_mode) _Init_Part();
241 _setPartialRamArea(x1, y1, w1, h1);
242 SPI.beginTransaction(_spi_settings);
243 if (_cs >= 0) digitalWrite(_cs, LOW);
244 _transfer16(0x0000); // preamble for write data
245 _waitWhileBusy2("writeImage preamble", default_wait_time);
246 for (int16_t i = 0; i < h1; i++)
247 {
248 for (int16_t j = 0; j < w1 / 8; j++)
249 {
250 uint8_t data;
251 // use wb_bitmap, h_bitmap of bitmap for index!
252 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);
253 if (pgm)
254 {
255#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
256 data = pgm_read_byte(&bitmap[idx]);
257#else
258 data = bitmap[idx];
259#endif
260 }
261 else
262 {
263 data = bitmap[idx];
264 }
265 if (invert) data = ~data;
266 _send8pixel(~data);
267 }
268 }
269 if (_cs >= 0) digitalWrite(_cs, HIGH);
270 SPI.endTransaction();
271 _writeCommand16(IT8951_TCON_LD_IMG_END);
272 _waitWhileBusy2("writeImage load end", default_wait_time);
273 delay(1); // yield() to avoid WDT on ESP8266 and ESP32
274}
275
276void GxEPD2_it103_1872x1404::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)
277{
278 if (black)
279 {
280 writeImage(black, x, y, w, h, invert, mirror_y, pgm);
281 }
282}
283
284void GxEPD2_it103_1872x1404::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,
285 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
286{
287 if (black)
288 {
289 writeImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
290 }
291}
292
293void GxEPD2_it103_1872x1404::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)
294{
295 if (data1)
296 {
297 if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean
298 delay(1); // yield() to avoid WDT on ESP8266 and ESP32
299 int16_t x1 = x < 0 ? 0 : x; // limit
300 int16_t y1 = y < 0 ? 0 : y; // limit
301 int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
302 int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
303 int16_t dx = x1 - x;
304 int16_t dy = y1 - y;
305 w1 -= dx;
306 h1 -= dy;
307 if ((w1 <= 0) || (h1 <= 0)) return;
308 if (!_using_partial_mode) _Init_Part();
309 _setPartialRamArea(x1, y1, w1, h1);
310 SPI.beginTransaction(_spi_settings);
311 if (_cs >= 0) digitalWrite(_cs, LOW);
312 _transfer16(0x0000); // preamble for write data
313 _waitWhileBusy2("writeNative preamble", default_wait_time);
314 for (int16_t i = 0; i < h1; i++)
315 {
316 for (int16_t j = 0; j < w1; j++)
317 {
318 uint8_t data;
319 // use w, h of bitmap for index!
320 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);
321 if (pgm)
322 {
323#if defined(__AVR) || defined(ESP8266) || defined(ESP32)
324 data = pgm_read_byte(&data1[idx]);
325#else
326 data = data1[idx];
327#endif
328 }
329 else
330 {
331 data = data1[idx];
332 }
333 if (invert) data = ~data;
334 SPI.transfer(data);
335 }
336#if defined(ESP8266) || defined(ESP32)
337 yield();
338#endif
339 }
340 if (_cs >= 0) digitalWrite(_cs, HIGH);
341 SPI.endTransaction();
342 _writeCommand16(IT8951_TCON_LD_IMG_END);
343 _waitWhileBusy2("writeNative load end", default_wait_time);
344 delay(1); // yield() to avoid WDT on ESP8266 and ESP32
345 }
346}
347
348void GxEPD2_it103_1872x1404::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{
350 writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm);
351 _refresh(x, y, w, h, true);
352}
353
354void GxEPD2_it103_1872x1404::drawImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap,
355 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
356{
357 writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
358 _refresh(x, y, w, h, true);
359}
360
361void GxEPD2_it103_1872x1404::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{
363 writeImage(black, color, x, y, w, h, invert, mirror_y, pgm);
364 _refresh(x, y, w, h, true);
365}
366
367void GxEPD2_it103_1872x1404::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,
368 int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm)
369{
370 writeImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm);
371 _refresh(x, y, w, h, true);
372}
373
374void GxEPD2_it103_1872x1404::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{
376 writeNative(data1, data2, x, y, w, h, invert, mirror_y, pgm);
377 _refresh(x, y, w, h, false);
378}
379
380void GxEPD2_it103_1872x1404::refresh(bool partial_update_mode)
381{
382 _refresh(0, 0, WIDTH, HEIGHT, partial_update_mode);
383}
384
385void GxEPD2_it103_1872x1404::refresh(int16_t x, int16_t y, int16_t w, int16_t h)
386{
387 _refresh(x, y, w, h, true);
388}
389
390void GxEPD2_it103_1872x1404::_refresh(int16_t x, int16_t y, int16_t w, int16_t h, bool partial_update_mode)
391{
392 //x -= x % 8; // byte boundary
393 //w -= x % 8; // byte boundary
394 int16_t x1 = x < 0 ? 0 : x; // limit
395 int16_t y1 = y < 0 ? 0 : y; // limit
396 int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit
397 int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit
398 w1 -= x1 - x;
399 h1 -= y1 - y;
400 //Send I80 Display Command (User defined command of IT8951)
401 _writeCommand16(USDEF_I80_CMD_DPY_AREA); //0x0034
402 _waitWhileBusy2("refresh cmd", refresh_cmd_time);
403 //Write arguments
404 _writeData16(x1);
405 _waitWhileBusy2("refresh x", refresh_par_time);
406 _writeData16(y1);
407 _waitWhileBusy2("refresh y", refresh_par_time);
408 _writeData16(w1);
409 _waitWhileBusy2("refresh w", refresh_par_time);
410 _writeData16(h1);
411 _waitWhileBusy2("refresh h", refresh_par_time);
412 _writeData16(partial_update_mode ? 1 : 2); // mode
414}
415
417{
418 _PowerOff();
419}
420
422{
423 if (_power_is_on) _PowerOff();
424 if (_rst >= 0)
425 {
426 // this does not work, does not reduce power, uses more than in stand by mode
427 //delay(1000);
428 //_IT8951Sleep();
429 //delay(1000);
430 //_hibernating = true;
431 }
432}
433
434void GxEPD2_it103_1872x1404::_send8pixel(uint8_t data)
435{
436 for (uint8_t j = 0; j < 8; j++)
437 {
438 SPI.transfer(data & 0x80 ? 0x00 : 0xFF);
439 data <<= 1;
440 }
441}
442
443void GxEPD2_it103_1872x1404::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
444{
445 //_IT8951WriteReg(LISAR + 2 , IT8951DevInfo.usImgBufAddrH);
446 //_IT8951WriteReg(LISAR , IT8951DevInfo.usImgBufAddrL);
447 uint16_t usArg[5];
448 //usArg[0] = (IT8951_LDIMG_L_ENDIAN << 8 ) | (IT8951_8BPP << 4) | (IT8951_ROTATE_0);
449 usArg[0] = (IT8951_LDIMG_B_ENDIAN << 8 ) | (IT8951_8BPP << 4) | (IT8951_ROTATE_0);
450 usArg[1] = x;
451 usArg[2] = y;
452 usArg[3] = w;
453 usArg[4] = h;
454 _writeCommandData16(IT8951_TCON_LD_IMG_AREA , usArg , 5);
455}
456
457void GxEPD2_it103_1872x1404::_PowerOn()
458{
459 if (!_power_is_on)
460 {
461 _IT8951SystemRun();
462 _waitWhileBusy("_PowerOn", power_on_time);
463 }
464 _power_is_on = true;
465}
466
467void GxEPD2_it103_1872x1404::_PowerOff()
468{
469 _IT8951StandBy();
470 _waitWhileBusy("_PowerOff", power_off_time);
471 _power_is_on = false;
472 _using_partial_mode = false;
473}
474
475void GxEPD2_it103_1872x1404::_InitDisplay()
476{
477 // we need a long reset pulse
478 if (_hibernating && (_rst >= 0))
479 {
480 digitalWrite(_rst, LOW);
481 delay(200);
482 digitalWrite(_rst, HIGH);
483 delay(200);
484 }
485}
486
487void GxEPD2_it103_1872x1404::_Init_Full()
488{
489 _InitDisplay();
490 _PowerOn();
491 _using_partial_mode = false;
492}
493
494void GxEPD2_it103_1872x1404::_Init_Part()
495{
496 _InitDisplay();
497 _PowerOn();
498 _using_partial_mode = true;
499}
500
501void GxEPD2_it103_1872x1404::_waitWhileBusy2(const char* comment, uint16_t busy_time)
502{
503 if (_busy >= 0)
504 {
505 unsigned long start = micros();
506 while (1)
507 {
508 if (digitalRead(_busy) != _busy_level) break;
509 delay(1);
510 if (micros() - start > _busy_timeout)
511 {
512 Serial.println("Busy Timeout!");
513 break;
514 }
515 }
516 if (comment)
517 {
518#if !defined(DISABLE_DIAGNOSTIC_OUTPUT)
519 if (_diag_enabled)
520 {
521 unsigned long elapsed = micros() - start;
522 if (elapsed > diag_min_time * 1000)
523 {
524 Serial.print(comment);
525 Serial.print(" : ");
526 Serial.println(elapsed);
527 }
528 }
529#endif
530 }
531 (void) start;
532 }
533 else delay(busy_time);
534}
535
536uint16_t GxEPD2_it103_1872x1404::_transfer16(uint16_t value)
537{
538 uint16_t rv = SPI.transfer(value >> 8) << 8;
539 return (rv | SPI.transfer(value));
540}
541
542void GxEPD2_it103_1872x1404::_writeCommand16(uint16_t c)
543{
544 String s = String("_writeCommand16(0x") + String(c, HEX) + String(")");
545 _waitWhileBusy2(s.c_str(), default_wait_time);
546 SPI.beginTransaction(_spi_settings);
547 if (_cs >= 0) digitalWrite(_cs, LOW);
548 _transfer16(0x6000); // preamble for write command
549 _waitWhileBusy2("_writeCommand16 preamble", default_wait_time);
550 _transfer16(c);
551 if (_cs >= 0) digitalWrite(_cs, HIGH);
552 SPI.endTransaction();
553 //_waitWhileBusy(s.c_str(), default_wait_time);
554}
555
556void GxEPD2_it103_1872x1404::_writeData16(uint16_t d)
557{
558 _waitWhileBusy2("_writeData16", default_wait_time);
559 SPI.beginTransaction(_spi_settings);
560 if (_cs >= 0) digitalWrite(_cs, LOW);
561 _transfer16(0x0000); // preamble for write data
562 _waitWhileBusy2("_writeData16 preamble", default_wait_time);
563 _transfer16(d);
564 if (_cs >= 0) digitalWrite(_cs, HIGH);
565 SPI.endTransaction();
566}
567
568void GxEPD2_it103_1872x1404::_writeData16(const uint16_t* d, uint32_t n)
569{
570 _waitWhileBusy2("_writeData16", default_wait_time);
571 SPI.beginTransaction(_spi_settings);
572 if (_cs >= 0) digitalWrite(_cs, LOW);
573 _transfer16(0x0000); // preamble for write data
574 _waitWhileBusy2("_writeData16 preamble", default_wait_time);
575 for (uint32_t i = 0; i < n; i++)
576 {
577 _transfer16(*d++);
578 }
579 if (_cs >= 0) digitalWrite(_cs, HIGH);
580 SPI.endTransaction();
581}
582
583uint16_t GxEPD2_it103_1872x1404::_readData16()
584{
585 _waitWhileBusy2("_readData16", default_wait_time);
586 SPI.beginTransaction(_spi_settings);
587 if (_cs >= 0) digitalWrite(_cs, LOW);
588 _transfer16(0x1000); // preamble for read data
589 _waitWhileBusy2("_readData16 preamble", default_wait_time);
590 _transfer16(0); // dummy
591 _waitWhileBusy2("_readData16 dummy", default_wait_time);
592 uint16_t rv = _transfer16(0);
593 if (_cs >= 0) digitalWrite(_cs, HIGH);
594 SPI.endTransaction();
595 return rv;
596}
597
598void GxEPD2_it103_1872x1404::_readData16(uint16_t* d, uint32_t n)
599{
600 _waitWhileBusy2("_readData16", default_wait_time);
601 SPI.beginTransaction(_spi_settings);
602 if (_cs >= 0) digitalWrite(_cs, LOW);
603 _transfer16(0x1000); // preamble for read data
604 _waitWhileBusy2("_readData16 preamble", default_wait_time);
605 _transfer16(0); // dummy
606 _waitWhileBusy2("_readData16 dummy", default_wait_time);
607 for (uint32_t i = 0; i < n; i++)
608 {
609 *d++ = _transfer16(0);
610 //_waitWhileBusy("_readData16 data", default_wait_time);
611 }
612 if (_cs >= 0) digitalWrite(_cs, HIGH);
613 SPI.endTransaction();
614}
615
616void GxEPD2_it103_1872x1404::_writeCommandData16(uint16_t c, const uint16_t* d, uint16_t n)
617{
618 _writeCommand16(c);
619 for (uint16_t i = 0; i < n; i++)
620 {
621 _writeData16(d[i]);
622 }
623}
624
625void GxEPD2_it103_1872x1404::_IT8951SystemRun()
626{
627 _writeCommand16(IT8951_TCON_SYS_RUN);
628}
629
630void GxEPD2_it103_1872x1404::_IT8951StandBy()
631{
632 _writeCommand16(IT8951_TCON_STANDBY);
633}
634
635void GxEPD2_it103_1872x1404::_IT8951Sleep()
636{
637 _writeCommand16(IT8951_TCON_SLEEP);
638}
639
640uint16_t GxEPD2_it103_1872x1404::_IT8951ReadReg(uint16_t usRegAddr)
641{
642 uint16_t usData;
643
644 //Send Cmd and Register Address
645 _writeCommand16(IT8951_TCON_REG_RD);
646 _writeData16(usRegAddr);
647 //Read data from Host Data bus
648 usData = _readData16();
649 return usData;
650}
651
652void GxEPD2_it103_1872x1404::_IT8951WriteReg(uint16_t usRegAddr, uint16_t usValue)
653{
654 //Send Cmd , Register Address and Write Value
655 _writeCommand16(IT8951_TCON_REG_WR);
656 _writeData16(usRegAddr);
657 _writeData16(usValue);
658}
659
660uint16_t GxEPD2_it103_1872x1404::_IT8951GetVCOM(void)
661{
662 uint16_t vcom;
663
664 _writeCommand16(USDEF_I80_CMD_VCOM);
665 _waitWhileBusy2("_IT8951GetVCOM", default_wait_time);
666 _writeData16(0);
667 //Read data from Host Data bus
668 vcom = _readData16();
669 return vcom;
670}
671
672void GxEPD2_it103_1872x1404::_IT8951SetVCOM(uint16_t vcom)
673{
674 _writeCommand16(USDEF_I80_CMD_VCOM);
675 _waitWhileBusy2("_IT8951SetVCOM", default_wait_time);
676 _writeData16(1);
677 //Read data from Host Data bus
678 _writeData16(vcom);
679 _waitWhileBusy2("_IT8951SetVCOM", set_vcom_time);
680}
#define IT8951_TCON_SYS_RUN
#define IT8951_8BPP
#define IT8951_TCON_LD_IMG_AREA
#define IT8951_TCON_LD_IMG_END
#define I80CPCR
#define IT8951_TCON_REG_RD
#define IT8951_ROTATE_0
#define USDEF_I80_CMD_DPY_AREA
#define USDEF_I80_CMD_VCOM
#define IT8951_TCON_REG_WR
#define IT8951_LDIMG_B_ENDIAN
#define VCOM
#define IT8951_TCON_SLEEP
#define IT8951_TCON_STANDBY
#define USDEF_I80_CMD_GET_DEV_INFO
bool _diag_enabled
Definition GxEPD2_EPD.h:114
int16_t _busy_level
Definition GxEPD2_EPD.h:112
bool _using_partial_mode
Definition GxEPD2_EPD.h:118
virtual void init(uint32_t serial_diag_bitrate=0)
void _waitWhileBusy(const char *comment=0, uint16_t busy_time=5000)
bool _power_is_on
Definition GxEPD2_EPD.h:118
bool _initial_refresh
Definition GxEPD2_EPD.h:117
bool _initial_write
Definition GxEPD2_EPD.h:117
uint32_t _busy_timeout
Definition GxEPD2_EPD.h:113
int16_t _rst
Definition GxEPD2_EPD.h:112
int16_t _busy
Definition GxEPD2_EPD.h:112
bool _hibernating
Definition GxEPD2_EPD.h:118
int16_t _cs
Definition GxEPD2_EPD.h:112
static const uint16_t refresh_par_time
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 full_refresh_time
static const uint16_t reset_to_ready_time
static const uint16_t default_wait_time
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 diag_min_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)
static const uint16_t WIDTH
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 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 refresh(bool partial_update_mode=false)
static const uint16_t power_on_time
void init(uint32_t serial_diag_bitrate=0)
void clearScreen(uint8_t value=0x33)
static const uint16_t set_vcom_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 refresh_cmd_time
void writeScreenBuffer(uint8_t value=0x33)
static const uint16_t power_off_time
GxEPD2_it103_1872x1404(int16_t cs, int16_t dc, int16_t rst, int16_t busy)
static const uint16_t HEIGHT