ESPHome  2024.11.0
waveshare_epaper.cpp
Go to the documentation of this file.
1 #include "waveshare_epaper.h"
2 #include "esphome/core/log.h"
4 #include "esphome/core/helpers.h"
5 #include <cinttypes>
6 
7 namespace esphome {
8 namespace waveshare_epaper {
9 
10 static const char *const TAG = "waveshare_epaper";
11 
12 static const uint8_t LUT_SIZE_WAVESHARE = 30;
13 
14 static const uint8_t FULL_UPDATE_LUT[LUT_SIZE_WAVESHARE] = {0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, 0x66, 0x69,
15  0x69, 0x59, 0x58, 0x99, 0x99, 0x88, 0x00, 0x00, 0x00, 0x00,
16  0xF8, 0xB4, 0x13, 0x51, 0x35, 0x51, 0x51, 0x19, 0x01, 0x00};
17 
18 static const uint8_t PARTIAL_UPDATE_LUT[LUT_SIZE_WAVESHARE] = {
19  0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20  0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
21 
22 static const uint8_t LUT_SIZE_TTGO = 70;
23 
24 static const uint8_t FULL_UPDATE_LUT_TTGO[LUT_SIZE_TTGO] = {
25  0x80, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, // LUT0: BB: VS 0 ~7
26  0x10, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, // LUT1: BW: VS 0 ~7
27  0x80, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, // LUT2: WB: VS 0 ~7
28  0x10, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, // LUT3: WW: VS 0 ~7
29  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUT4: VCOM: VS 0 ~7
30  0x03, 0x03, 0x00, 0x00, 0x02, // TP0 A~D RP0
31  0x09, 0x09, 0x00, 0x00, 0x02, // TP1 A~D RP1
32  0x03, 0x03, 0x00, 0x00, 0x02, // TP2 A~D RP2
33  0x00, 0x00, 0x00, 0x00, 0x00, // TP3 A~D RP3
34  0x00, 0x00, 0x00, 0x00, 0x00, // TP4 A~D RP4
35  0x00, 0x00, 0x00, 0x00, 0x00, // TP5 A~D RP5
36  0x00, 0x00, 0x00, 0x00, 0x00, // TP6 A~D RP6
37 };
38 
39 static const uint8_t PARTIAL_UPDATE_LUT_TTGO[LUT_SIZE_TTGO] = {
40  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUT0: BB: VS 0 ~7
41  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUT1: BW: VS 0 ~7
42  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUT2: WB: VS 0 ~7
43  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUT3: WW: VS 0 ~7
44  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUT4: VCOM: VS 0 ~7
45  0x0A, 0x00, 0x00, 0x00, 0x00, // TP0 A~D RP0
46  0x00, 0x00, 0x00, 0x00, 0x00, // TP1 A~D RP1
47  0x00, 0x00, 0x00, 0x00, 0x00, // TP2 A~D RP2
48  0x00, 0x00, 0x00, 0x00, 0x00, // TP3 A~D RP3
49  0x00, 0x00, 0x00, 0x00, 0x00, // TP4 A~D RP4
50  0x00, 0x00, 0x00, 0x00, 0x00, // TP5 A~D RP5
51  0x00, 0x00, 0x00, 0x00, 0x00, // TP6 A~D RP6
52 };
53 
54 static const uint8_t LUT_SIZE_TTGO_B73 = 100;
55 
56 static const uint8_t FULL_UPDATE_LUT_TTGO_B73[LUT_SIZE_TTGO_B73] = {
57  0xA0, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x00,
58  0x00, 0x00, 0x00, 0xA0, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x90, 0xA0, 0x00,
59  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 
61  0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
62  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 };
65 
66 static const uint8_t PARTIAL_UPDATE_LUT_TTGO_B73[LUT_SIZE_TTGO_B73] = {
67  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68  0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
69  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 
71  0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 };
75 
76 static const uint8_t LUT_SIZE_TTGO_B1 = 29;
77 
78 static const uint8_t FULL_UPDATE_LUT_TTGO_B1[LUT_SIZE_TTGO_B1] = {
79  0x22, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80  0x00, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x01, 0x00, 0x00, 0x00, 0x00};
81 
82 static const uint8_t PARTIAL_UPDATE_LUT_TTGO_B1[LUT_SIZE_TTGO_B1] = {
83  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84  0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
85 
86 // clang-format off
87 // Disable formatting to preserve the same look as in Waveshare examples
88 static const uint8_t PARTIAL_UPD_2IN9_LUT_SIZE = 159;
89 static const uint8_t PARTIAL_UPD_2IN9_LUT[PARTIAL_UPD_2IN9_LUT_SIZE] =
90 {
91  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92  0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93  0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96  0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
97  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
109  0x22, 0x17, 0x41, 0xB0, 0x32, 0x36,
110 };
111 // clang-format on
112 
114  this->init_internal_(this->get_buffer_length_());
115  this->dc_pin_->setup(); // OUTPUT
116  this->dc_pin_->digital_write(false);
117  if (this->reset_pin_ != nullptr) {
118  this->reset_pin_->setup(); // OUTPUT
119  this->reset_pin_->digital_write(true);
120  }
121  if (this->busy_pin_ != nullptr) {
122  this->busy_pin_->setup(); // INPUT
123  }
124  this->spi_setup();
125 
126  this->reset_();
127 }
129 void WaveshareEPaperBase::command(uint8_t value) {
130  this->start_command_();
131  this->write_byte(value);
132  this->end_command_();
133 }
134 void WaveshareEPaperBase::data(uint8_t value) {
135  this->start_data_();
136  this->write_byte(value);
137  this->end_data_();
138 }
139 
140 // write a command followed by one or more bytes of data.
141 // The command is the first byte, length is the total including cmd.
142 void WaveshareEPaperBase::cmd_data(const uint8_t *c_data, size_t length) {
143  this->dc_pin_->digital_write(false);
144  this->enable();
145  this->write_byte(c_data[0]);
146  this->dc_pin_->digital_write(true);
147  this->write_array(c_data + 1, length - 1);
148  this->disable();
149 }
150 
152  if (this->busy_pin_ == nullptr || !this->busy_pin_->digital_read()) {
153  return true;
154  }
155 
156  const uint32_t start = millis();
157  while (this->busy_pin_->digital_read()) {
158  if (millis() - start > this->idle_timeout_()) {
159  ESP_LOGE(TAG, "Timeout while displaying image!");
160  return false;
161  }
162  delay(1);
163  }
164  return true;
165 }
167  this->do_update_();
168  this->display();
169 }
171  // flip logic
172  const uint8_t fill = color.is_on() ? 0x00 : 0xFF;
173  for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
174  this->buffer_[i] = fill;
175 }
177  if (x >= this->get_width_internal() || y >= this->get_height_internal() || x < 0 || y < 0)
178  return;
179 
180  const uint32_t pos = (x + y * this->get_width_controller()) / 8u;
181  const uint8_t subpos = x & 0x07;
182  // flip logic
183  if (!color.is_on()) {
184  this->buffer_[pos] |= 0x80 >> subpos;
185  } else {
186  this->buffer_[pos] &= ~(0x80 >> subpos);
187  }
188 }
189 
191  return this->get_width_controller() * this->get_height_internal() / 8u;
192 } // just a black buffer
194  return this->get_width_controller() * this->get_height_internal() / 4u;
195 } // black and red buffer
196 
198  this->filled_rectangle(0, 0, this->get_width(), this->get_height(), color);
199 }
201  if (x >= this->get_width_internal() || y >= this->get_height_internal() || x < 0 || y < 0)
202  return;
203 
204  const uint32_t buf_half_len = this->get_buffer_length_() / 2u;
205 
206  const uint32_t pos = (x + y * this->get_width_internal()) / 8u;
207  const uint8_t subpos = x & 0x07;
208  // flip logic
209  if (color.is_on()) {
210  this->buffer_[pos] |= 0x80 >> subpos;
211  } else {
212  this->buffer_[pos] &= ~(0x80 >> subpos);
213  }
214 
215  // draw red pixels only, if the color contains red only
216  if (((color.red > 0) && (color.green == 0) && (color.blue == 0))) {
217  this->buffer_[pos + buf_half_len] |= 0x80 >> subpos;
218  } else {
219  this->buffer_[pos + buf_half_len] &= ~(0x80 >> subpos);
220  }
221 }
222 
224  this->dc_pin_->digital_write(false);
225  this->enable();
226 }
229  this->dc_pin_->digital_write(true);
230  this->enable();
231 }
234 
235 // ========================================================
236 // Type A
237 // ========================================================
238 
240  // Achieve display intialization
241  this->init_display_();
242  // If a reset pin is configured, eligible displays can be set to deep sleep
243  // between updates, as recommended by the hardware provider
244  if (this->reset_pin_ != nullptr) {
245  switch (this->model_) {
246  // More models can be added here to enable deep sleep if eligible
249  this->deep_sleep_between_updates_ = true;
250  ESP_LOGI(TAG, "Set the display to deep sleep");
251  this->deep_sleep();
252  break;
253  default:
254  break;
255  }
256  }
257 }
259  if (this->model_ == TTGO_EPAPER_2_13_IN_B74 || this->model_ == WAVESHARE_EPAPER_2_13_IN_V2) {
260  if (this->reset_pin_ != nullptr) {
261  this->reset_pin_->digital_write(false);
262  delay(10);
263  this->reset_pin_->digital_write(true);
264  delay(10);
265  this->wait_until_idle_();
266  }
267 
268  this->command(0x12); // SWRESET
269  this->wait_until_idle_();
270  }
271 
272  // COMMAND DRIVER OUTPUT CONTROL
273  this->command(0x01);
274  this->data(this->get_height_internal() - 1);
275  this->data((this->get_height_internal() - 1) >> 8);
276  this->data(0x00); // ? GD = 0, SM = 0, TB = 0
277 
278  // COMMAND BOOSTER SOFT START CONTROL
279  this->command(0x0C);
280  this->data(0xD7);
281  this->data(0xD6);
282  this->data(0x9D);
283 
284  // COMMAND WRITE VCOM REGISTER
285  this->command(0x2C);
286  this->data(0xA8);
287 
288  // COMMAND SET DUMMY LINE PERIOD
289  this->command(0x3A);
290  this->data(0x1A);
291 
292  // COMMAND SET GATE TIME
293  this->command(0x3B);
294  this->data(0x08); // 2µs per row
295 
296  // COMMAND DATA ENTRY MODE SETTING
297  this->command(0x11);
298  switch (this->model_) {
300  this->data(0x01); // x increase, y decrease : as in demo code
301  break;
304  this->data(0x03); // from top left to bottom right
305  // RAM content option for Display Update
306  this->command(0x21);
307  this->data(0x00);
308  this->data(0x80);
309  break;
310  default:
311  this->data(0x03); // from top left to bottom right
312  }
313 }
315  LOG_DISPLAY("", "Waveshare E-Paper", this);
316  switch (this->model_) {
318  ESP_LOGCONFIG(TAG, " Model: 1.54in");
319  break;
321  ESP_LOGCONFIG(TAG, " Model: 1.54inV2");
322  break;
324  ESP_LOGCONFIG(TAG, " Model: 2.13in");
325  break;
327  ESP_LOGCONFIG(TAG, " Model: 2.13inV2");
328  break;
329  case TTGO_EPAPER_2_13_IN:
330  ESP_LOGCONFIG(TAG, " Model: 2.13in (TTGO)");
331  break;
333  ESP_LOGCONFIG(TAG, " Model: 2.13in (TTGO B73)");
334  break;
336  ESP_LOGCONFIG(TAG, " Model: 2.13in (TTGO B74)");
337  break;
339  ESP_LOGCONFIG(TAG, " Model: 2.13in (TTGO B1)");
340  break;
342  ESP_LOGCONFIG(TAG, " Model: 2.9in");
343  break;
345  ESP_LOGCONFIG(TAG, " Model: 2.9inV2");
346  break;
347  }
348  ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_);
349  LOG_PIN(" Reset Pin: ", this->reset_pin_);
350  LOG_PIN(" DC Pin: ", this->dc_pin_);
351  LOG_PIN(" Busy Pin: ", this->busy_pin_);
352  LOG_UPDATE_INTERVAL(this);
353 }
355  bool full_update = this->at_update_ == 0;
356  bool prev_full_update = this->at_update_ == 1;
357 
358  if (this->deep_sleep_between_updates_) {
359  ESP_LOGI(TAG, "Wake up the display");
360  this->reset_();
361  this->wait_until_idle_();
362  this->init_display_();
363  }
364 
365  if (!this->wait_until_idle_()) {
366  this->status_set_warning();
367  return;
368  }
369 
370  if (this->full_update_every_ >= 1) {
371  if (full_update != prev_full_update) {
372  switch (this->model_) {
373  case TTGO_EPAPER_2_13_IN:
375  // Waveshare 2.13" V2 uses the same LUTs as TTGO
376  this->write_lut_(full_update ? FULL_UPDATE_LUT_TTGO : PARTIAL_UPDATE_LUT_TTGO, LUT_SIZE_TTGO);
377  break;
379  this->write_lut_(full_update ? FULL_UPDATE_LUT_TTGO_B73 : PARTIAL_UPDATE_LUT_TTGO_B73, LUT_SIZE_TTGO_B73);
380  break;
382  // there is no LUT
383  break;
385  this->write_lut_(full_update ? FULL_UPDATE_LUT_TTGO_B1 : PARTIAL_UPDATE_LUT_TTGO_B1, LUT_SIZE_TTGO_B1);
386  break;
387  default:
388  this->write_lut_(full_update ? FULL_UPDATE_LUT : PARTIAL_UPDATE_LUT, LUT_SIZE_WAVESHARE);
389  }
390  }
391  this->at_update_ = (this->at_update_ + 1) % this->full_update_every_;
392  }
393 
394  if (this->model_ == WAVESHARE_EPAPER_2_13_IN_V2) {
395  // Set VCOM for full or partial update
396  this->command(0x2C);
397  this->data(full_update ? 0x55 : 0x26);
398 
399  if (!full_update) {
400  // Enable "ping-pong"
401  this->command(0x37);
402  this->data(0x00);
403  this->data(0x00);
404  this->data(0x00);
405  this->data(0x00);
406  this->data(0x40);
407  this->data(0x00);
408  this->data(0x00);
409  this->command(0x22);
410  this->data(0xc0);
411  this->command(0x20);
412  }
413  }
414 
415  // Border waveform
416  switch (this->model_) {
418  this->command(0x3C);
419  this->data(full_update ? 0x05 : 0x80);
420  break;
422  this->command(0x3C);
423  this->data(full_update ? 0x03 : 0x01);
424  break;
425  default:
426  break;
427  }
428 
429  // Set x & y regions we want to write to (full)
430  switch (this->model_) {
432  // COMMAND SET RAM X ADDRESS START END POSITION
433  this->command(0x44);
434  this->data(0x00);
435  this->data((this->get_width_controller() - 1) >> 3);
436  // COMMAND SET RAM Y ADDRESS START END POSITION
437  this->command(0x45);
438  this->data(this->get_height_internal() - 1);
439  this->data((this->get_height_internal() - 1) >> 8);
440  this->data(0x00);
441  this->data(0x00);
442 
443  // COMMAND SET RAM X ADDRESS COUNTER
444  this->command(0x4E);
445  this->data(0x00);
446  // COMMAND SET RAM Y ADDRESS COUNTER
447  this->command(0x4F);
448  this->data(this->get_height_internal() - 1);
449  this->data((this->get_height_internal() - 1) >> 8);
450 
451  break;
452  default:
453  // COMMAND SET RAM X ADDRESS START END POSITION
454  this->command(0x44);
455  this->data(0x00);
456  this->data((this->get_width_internal() - 1) >> 3);
457  // COMMAND SET RAM Y ADDRESS START END POSITION
458  this->command(0x45);
459  this->data(0x00);
460  this->data(0x00);
461  this->data(this->get_height_internal() - 1);
462  this->data((this->get_height_internal() - 1) >> 8);
463 
464  // COMMAND SET RAM X ADDRESS COUNTER
465  this->command(0x4E);
466  this->data(0x00);
467  // COMMAND SET RAM Y ADDRESS COUNTER
468  this->command(0x4F);
469  this->data(0x00);
470  this->data(0x00);
471  }
472 
473  if (!this->wait_until_idle_()) {
474  this->status_set_warning();
475  return;
476  }
477 
478  // COMMAND WRITE RAM
479  this->command(0x24);
480  this->start_data_();
481  switch (this->model_) {
482  case TTGO_EPAPER_2_13_IN_B1: { // block needed because of variable initializations
483  int16_t wb = ((this->get_width_controller()) >> 3);
484  for (int i = 0; i < this->get_height_internal(); i++) {
485  for (int j = 0; j < wb; j++) {
486  int idx = j + (this->get_height_internal() - 1 - i) * wb;
487  this->write_byte(this->buffer_[idx]);
488  }
489  }
490  break;
491  }
492  default:
493  this->write_array(this->buffer_, this->get_buffer_length_());
494  }
495  this->end_data_();
496 
497  if (this->model_ == WAVESHARE_EPAPER_2_13_IN_V2 && full_update) {
498  // Write base image again on full refresh
499  this->command(0x26);
500  this->start_data_();
501  this->write_array(this->buffer_, this->get_buffer_length_());
502  this->end_data_();
503  }
504 
505  // COMMAND DISPLAY UPDATE CONTROL 2
506  this->command(0x22);
507  switch (this->model_) {
511  this->data(full_update ? 0xF7 : 0xFF);
512  break;
514  this->data(0xC7);
515  break;
517  this->data(full_update ? 0xC7 : 0x0C);
518  break;
519  default:
520  this->data(0xC4);
521  break;
522  }
523 
524  // COMMAND MASTER ACTIVATION
525  this->command(0x20);
526  // COMMAND TERMINATE FRAME READ WRITE
527  this->command(0xFF);
528 
529  this->status_clear_warning();
530 
531  if (this->deep_sleep_between_updates_) {
532  ESP_LOGI(TAG, "Set the display back to deep sleep");
533  this->deep_sleep();
534  }
535 }
537  switch (this->model_) {
540  return 200;
543  case TTGO_EPAPER_2_13_IN:
547  return 122;
550  return 128;
551  }
552  return 0;
553 }
554 // The controller of the 2.13" displays has a buffer larger than screen size
556  switch (this->model_) {
559  case TTGO_EPAPER_2_13_IN:
563  return 128;
564  default:
565  return this->get_width_internal();
566  }
567 }
569  switch (this->model_) {
572  return 200;
575  case TTGO_EPAPER_2_13_IN:
579  return 250;
582  return 296;
583  }
584  return 0;
585 }
586 void WaveshareEPaperTypeA::write_lut_(const uint8_t *lut, const uint8_t size) {
587  // COMMAND WRITE LUT REGISTER
588  this->command(0x32);
589  for (uint8_t i = 0; i < size; i++)
590  this->data(lut[i]);
591 }
593 void WaveshareEPaperTypeA::set_full_update_every(uint32_t full_update_every) {
594  this->full_update_every_ = full_update_every;
595 }
596 
598  switch (this->model_) {
603  return 2500;
604  default:
606  }
607 }
608 
609 // ========================================================
610 // Type B
611 // ========================================================
612 // Datasheet:
613 // - https://www.waveshare.com/w/upload/7/7f/4.2inch-e-paper-b-specification.pdf
614 // - https://github.com/soonuse/epd-library-arduino/blob/master/4.2inch_e-paper/epd4in2/
615 
616 static const uint8_t LUT_VCOM_DC_2_7[44] = {
617  0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x05, 0x00, 0x32, 0x32, 0x00, 0x00, 0x02, 0x00,
618  0x0F, 0x0F, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 };
621 
622 static const uint8_t LUT_WHITE_TO_WHITE_2_7[42] = {
623  0x50, 0x0F, 0x0F, 0x00, 0x00, 0x05, 0x60, 0x32, 0x32, 0x00, 0x00, 0x02, 0xA0, 0x0F,
624  0x0F, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 };
627 
628 static const uint8_t LUT_BLACK_TO_WHITE_2_7[42] = {
629  0x50, 0x0F, 0x0F, 0x00, 0x00, 0x05, 0x60, 0x32, 0x32, 0x00, 0x00, 0x02, 0xA0, 0x0F,
630  0x0F, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 };
633 
634 static const uint8_t LUT_WHITE_TO_BLACK_2_7[] = {
635  0xA0, 0x0F, 0x0F, 0x00, 0x00, 0x05, 0x60, 0x32, 0x32, 0x00, 0x00, 0x02, 0x50, 0x0F,
636  0x0F, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 };
639 
640 static const uint8_t LUT_BLACK_TO_BLACK_2_7[42] = {
641  0xA0, 0x0F, 0x0F, 0x00, 0x00, 0x05, 0x60, 0x32, 0x32, 0x00, 0x00, 0x02, 0x50, 0x0F,
642  0x0F, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 };
645 
647  // command power setting
648  this->command(0x01);
649  this->data(0x03); // VDS_EN, VDG_EN
650  this->data(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
651  this->data(0x2B); // VDH
652  this->data(0x2B); // VDL
653  this->data(0x09); // VDHR
654 
655  // command booster soft start
656  this->command(0x06);
657  this->data(0x07);
658  this->data(0x07);
659  this->data(0x17);
660 
661  // Power optimization - ???
662  this->command(0xF8);
663  this->data(0x60);
664  this->data(0xA5);
665  this->command(0xF8);
666  this->data(0x89);
667  this->data(0xA5);
668  this->command(0xF8);
669  this->data(0x90);
670  this->data(0x00);
671  this->command(0xF8);
672  this->data(0x93);
673  this->data(0x2A);
674  this->command(0xF8);
675  this->data(0xA0);
676  this->data(0xA5);
677  this->command(0xF8);
678  this->data(0xA1);
679  this->data(0x00);
680  this->command(0xF8);
681  this->data(0x73);
682  this->data(0x41);
683 
684  // command partial display refresh
685  this->command(0x16);
686  this->data(0x00);
687 
688  // command power on
689  this->command(0x04);
690  this->wait_until_idle_();
691  delay(10);
692 
693  // Command panel setting
694  this->command(0x00);
695  this->data(0xAF); // KW-BF KWR-AF BWROTP 0f
696  // command pll control
697  this->command(0x30);
698  this->data(0x3A); // 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
699  // COMMAND VCM DC SETTING
700  this->command(0x82);
701  this->data(0x12);
702 
703  delay(2);
704  // COMMAND LUT FOR VCOM
705  this->command(0x20);
706  for (uint8_t i : LUT_VCOM_DC_2_7)
707  this->data(i);
708 
709  // COMMAND LUT WHITE TO WHITE
710  this->command(0x21);
711  for (uint8_t i : LUT_WHITE_TO_WHITE_2_7)
712  this->data(i);
713  // COMMAND LUT BLACK TO WHITE
714  this->command(0x22);
715  for (uint8_t i : LUT_BLACK_TO_WHITE_2_7)
716  this->data(i);
717  // COMMAND LUT WHITE TO BLACK
718  this->command(0x23);
719  for (uint8_t i : LUT_WHITE_TO_BLACK_2_7)
720  this->data(i);
721  // COMMAND LUT BLACK TO BLACK
722  this->command(0x24);
723  for (uint8_t i : LUT_BLACK_TO_BLACK_2_7)
724  this->data(i);
725 }
727  uint32_t buf_len = this->get_buffer_length_();
728 
729  // COMMAND DATA START TRANSMISSION 1
730  this->command(0x10);
731  delay(2);
732  for (uint32_t i = 0; i < buf_len; i++) {
733  this->data(this->buffer_[i]);
734  }
735  delay(2);
736 
737  // COMMAND DATA START TRANSMISSION 2
738  this->command(0x13);
739  delay(2);
740  for (uint32_t i = 0; i < buf_len; i++) {
741  this->data(this->buffer_[i]);
742  }
743 
744  // COMMAND DISPLAY REFRESH
745  this->command(0x12);
746 }
750  LOG_DISPLAY("", "Waveshare E-Paper", this);
751  ESP_LOGCONFIG(TAG, " Model: 2.7in");
752  LOG_PIN(" Reset Pin: ", this->reset_pin_);
753  LOG_PIN(" DC Pin: ", this->dc_pin_);
754  LOG_PIN(" Busy Pin: ", this->busy_pin_);
755  LOG_UPDATE_INTERVAL(this);
756 }
757 
759  this->reset_();
760  this->wait_until_idle_();
761 
762  this->command(0x12); // SWRESET
763  this->wait_until_idle_();
764 
765  // SET WINDOWS
766  // XRAM_START_AND_END_POSITION
767  this->command(0x44);
768  this->data(0x00);
769  this->data(((this->get_width_controller() - 1) >> 3) & 0xFF);
770  // YRAM_START_AND_END_POSITION
771  this->command(0x45);
772  this->data(0x00);
773  this->data(0x00);
774  this->data((get_height_internal() - 1) & 0xFF);
775  this->data(((get_height_internal() - 1) >> 8) & 0xFF);
776 
777  // SET CURSOR
778  // XRAM_ADDRESS
779  this->command(0x4E);
780  this->data(0x00);
781  // YRAM_ADDRESS
782  this->command(0x4F);
783  this->data(0x00);
784  this->data(0x00);
785 
786  this->command(0x11); // data entry mode
787  this->data(0x03);
788 }
790  this->command(0x24);
791  this->start_data_();
792  this->write_array(this->buffer_, this->get_buffer_length_());
793  this->end_data_();
794 
795  // COMMAND DISPLAY REFRESH
796  this->command(0x22);
797  this->data(0xF7);
798  this->command(0x20);
799 }
803  LOG_DISPLAY("", "Waveshare E-Paper", this);
804  ESP_LOGCONFIG(TAG, " Model: 2.7in V2");
805  LOG_PIN(" Reset Pin: ", this->reset_pin_);
806  LOG_PIN(" DC Pin: ", this->dc_pin_);
807  LOG_PIN(" Busy Pin: ", this->busy_pin_);
808  LOG_UPDATE_INTERVAL(this);
809 }
810 
811 // ========================================================
812 // 2.7inch_e-paper_b
813 // ========================================================
814 // Datasheet:
815 // - https://www.waveshare.com/w/upload/d/d8/2.7inch-e-paper-b-specification.pdf
816 // - https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_2in7b.c
817 
818 static const uint8_t LUT_VCOM_DC_2_7B[44] = {0x00, 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x0A,
819  0x00, 0x00, 0x08, 0x00, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x00, 0x0A,
820  0x0A, 0x00, 0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00,
821  0x03, 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
822 
823 static const uint8_t LUT_WHITE_TO_WHITE_2_7B[42] = {0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x0A, 0x00, 0x00,
824  0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x80, 0x0A, 0x0A, 0x00,
825  0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
826  0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
827 
828 static const uint8_t LUT_BLACK_TO_WHITE_2_7B[42] = {0xA0, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x0A, 0x00, 0x00,
829  0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x90, 0x0A, 0x0A, 0x00,
830  0x00, 0x08, 0xB0, 0x04, 0x10, 0x00, 0x00, 0x05, 0xB0, 0x03, 0x0E,
831  0x00, 0x00, 0x0A, 0xC0, 0x23, 0x00, 0x00, 0x00, 0x01};
832 
833 static const uint8_t LUT_WHITE_TO_BLACK_2_7B[] = {0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x20, 0x0A, 0x0A, 0x00, 0x00,
834  0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x10, 0x0A, 0x0A, 0x00,
835  0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
836  0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
837 
838 static const uint8_t LUT_BLACK_TO_BLACK_2_7B[42] = {0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x0A, 0x00, 0x00,
839  0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x80, 0x0A, 0x0A, 0x00,
840  0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
841  0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
842 
844  this->reset_();
845 
846  // command power on
847  this->command(0x04);
848  this->wait_until_idle_();
849  delay(10);
850 
851  // Command panel setting
852  this->command(0x00);
853  this->data(0xAF); // KW-BF KWR-AF BWROTP 0f
854  // command pll control
855  this->command(0x30);
856  this->data(0x3A); // 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
857 
858  // command power setting
859  this->command(0x01);
860  this->data(0x03); // VDS_EN, VDG_EN
861  this->data(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
862  this->data(0x2B); // VDH
863  this->data(0x2B); // VDL
864  this->data(0x09); // VDHR
865 
866  // command booster soft start
867  this->command(0x06);
868  this->data(0x07);
869  this->data(0x07);
870  this->data(0x17);
871 
872  // Power optimization - ???
873  this->command(0xF8);
874  this->data(0x60);
875  this->data(0xA5);
876  this->command(0xF8);
877  this->data(0x89);
878  this->data(0xA5);
879  this->command(0xF8);
880  this->data(0x90);
881  this->data(0x00);
882  this->command(0xF8);
883  this->data(0x93);
884  this->data(0x2A);
885  this->command(0xF8);
886  this->data(0x73);
887  this->data(0x41);
888 
889  // COMMAND VCM DC SETTING
890  this->command(0x82);
891  this->data(0x12);
892 
893  // VCOM_AND_DATA_INTERVAL_SETTING
894  this->command(0x50);
895  this->data(0x87); // define by OTP
896 
897  delay(2);
898  // COMMAND LUT FOR VCOM
899  this->command(0x20);
900  for (uint8_t i : LUT_VCOM_DC_2_7B)
901  this->data(i);
902  // COMMAND LUT WHITE TO WHITE
903  this->command(0x21);
904  for (uint8_t i : LUT_WHITE_TO_WHITE_2_7B)
905  this->data(i);
906  // COMMAND LUT BLACK TO WHITE
907  this->command(0x22);
908  for (uint8_t i : LUT_BLACK_TO_WHITE_2_7B)
909  this->data(i);
910  // COMMAND LUT WHITE TO BLACK
911  this->command(0x23);
912  for (uint8_t i : LUT_WHITE_TO_BLACK_2_7B) {
913  this->data(i);
914  }
915  // COMMAND LUT BLACK TO BLACK
916  this->command(0x24);
917 
918  for (uint8_t i : LUT_BLACK_TO_BLACK_2_7B) {
919  this->data(i);
920  }
921 
922  delay(2);
923 }
924 
926  uint32_t buf_len_half = this->get_buffer_length_() >> 1;
927  this->initialize();
928 
929  // TCON_RESOLUTION
930  this->command(0x61);
931  this->data(this->get_width_controller() >> 8);
932  this->data(this->get_width_controller() & 0xff); // 176
933  this->data(this->get_height_internal() >> 8);
934  this->data(this->get_height_internal() & 0xff); // 264
935 
936  // COMMAND DATA START TRANSMISSION 1 (BLACK)
937  this->command(0x10);
938  delay(2);
939  for (uint32_t i = 0; i < buf_len_half; i++) {
940  this->data(this->buffer_[i]);
941  }
942  this->command(0x11);
943  delay(2);
944 
945  // COMMAND DATA START TRANSMISSION 2 (RED)
946  this->command(0x13);
947  delay(2);
948  for (uint32_t i = buf_len_half; i < buf_len_half * 2u; i++) {
949  this->data(this->buffer_[i]);
950  }
951  this->command(0x11);
952 
953  delay(2);
954 
955  // COMMAND DISPLAY REFRESH
956  this->command(0x12);
957  this->wait_until_idle_();
958 
959  this->deep_sleep();
960 }
964  LOG_DISPLAY("", "Waveshare E-Paper", this);
965  ESP_LOGCONFIG(TAG, " Model: 2.7in B");
966  LOG_PIN(" Reset Pin: ", this->reset_pin_);
967  LOG_PIN(" DC Pin: ", this->dc_pin_);
968  LOG_PIN(" Busy Pin: ", this->busy_pin_);
969  LOG_UPDATE_INTERVAL(this);
970 }
971 
972 // ========================================================
973 // 2.7inch_e-paper_b_v2
974 // ========================================================
975 // Datasheet:
976 // - https://www.waveshare.com/w/upload/7/7b/2.7inch-e-paper-b-v2-specification.pdf
977 // - https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_2in7b_V2.c
978 
980  this->reset_();
981 
982  this->wait_until_idle_();
983  this->command(0x12);
984  this->wait_until_idle_();
985 
986  this->command(0x00);
987  this->data(0x27);
988  this->data(0x01);
989  this->data(0x00);
990 
991  this->command(0x11);
992  this->data(0x03);
993 
994  // self.SetWindows(0, 0, self.width-1, self.height-1)
995  // SetWindows(self, Xstart, Ystart, Xend, Yend):
996 
997  uint32_t xend = this->get_width_controller() - 1;
998  uint32_t yend = this->get_height_internal() - 1;
999  this->command(0x44);
1000  this->data(0x00);
1001  this->data((xend >> 3) & 0xff);
1002 
1003  this->command(0x45);
1004  this->data(0x00);
1005  this->data(0x00);
1006  this->data(yend & 0xff);
1007  this->data((yend >> 8) & 0xff);
1008 
1009  // SetCursor(self, Xstart, Ystart):
1010  this->command(0x4E);
1011  this->data(0x00);
1012  this->command(0x4F);
1013  this->data(0x00);
1014  this->data(0x00);
1015 }
1016 
1018  uint32_t buf_len = this->get_buffer_length_();
1019  // COMMAND DATA START TRANSMISSION 1 (BLACK)
1020  this->command(0x24);
1021  delay(2);
1022  for (uint32_t i = 0; i < buf_len; i++) {
1023  this->data(this->buffer_[i]);
1024  }
1025  delay(2);
1026 
1027  // COMMAND DATA START TRANSMISSION 2 (RED)
1028  this->command(0x26);
1029  delay(2);
1030  for (uint32_t i = 0; i < buf_len; i++) {
1031  this->data(this->buffer_[i]);
1032  }
1033 
1034  delay(2);
1035 
1036  this->command(0x20);
1037 
1038  this->wait_until_idle_();
1039 }
1043  LOG_DISPLAY("", "Waveshare E-Paper", this);
1044  ESP_LOGCONFIG(TAG, " Model: 2.7in B V2");
1045  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1046  LOG_PIN(" DC Pin: ", this->dc_pin_);
1047  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1048  LOG_UPDATE_INTERVAL(this);
1049 }
1050 
1051 // ========================================================
1052 // 2.90in Type B (LUT from OTP)
1053 // Datasheet:
1054 // - https://www.waveshare.com/w/upload/b/bb/2.9inch-e-paper-b-specification.pdf
1055 // - https://github.com/soonuse/epd-library-arduino/blob/master/2.9inch_e-paper_b/epd2in9b/epd2in9b.cpp
1056 // ========================================================
1057 
1059  // from https://www.waveshare.com/w/upload/b/bb/2.9inch-e-paper-b-specification.pdf, page 37
1060  // EPD hardware init start
1061  this->reset_();
1062 
1063  // COMMAND BOOSTER SOFT START
1064  this->command(0x06);
1065  this->data(0x17);
1066  this->data(0x17);
1067  this->data(0x17);
1068 
1069  // COMMAND POWER ON
1070  this->command(0x04);
1071  this->wait_until_idle_();
1072 
1073  // COMMAND PANEL SETTING
1074  this->command(0x00);
1075  // 128x296 resolution: 10
1076  // LUT from OTP: 0
1077  // B/W mode (doesn't work): 1
1078  // scan-up: 1
1079  // shift-right: 1
1080  // booster ON: 1
1081  // no soft reset: 1
1082  this->data(0x9F);
1083 
1084  // COMMAND RESOLUTION SETTING
1085  // set to 128x296 by COMMAND PANEL SETTING
1086 
1087  // COMMAND VCOM AND DATA INTERVAL SETTING
1088  // use defaults for white border and ESPHome image polarity
1089 
1090  // EPD hardware init end
1091 }
1093  // COMMAND DATA START TRANSMISSION 1 (B/W data)
1094  this->command(0x10);
1095  delay(2);
1096  this->start_data_();
1097  this->write_array(this->buffer_, this->get_buffer_length_());
1098  this->end_data_();
1099  delay(2);
1100 
1101  // COMMAND DATA START TRANSMISSION 2 (RED data)
1102  this->command(0x13);
1103  delay(2);
1104  this->start_data_();
1105  for (size_t i = 0; i < this->get_buffer_length_(); i++)
1106  this->write_byte(0x00);
1107  this->end_data_();
1108  delay(2);
1109 
1110  // COMMAND DISPLAY REFRESH
1111  this->command(0x12);
1112  delay(2);
1113  this->wait_until_idle_();
1114 
1115  // COMMAND POWER OFF
1116  // NOTE: power off < deep sleep
1117  this->command(0x02);
1118 }
1122  LOG_DISPLAY("", "Waveshare E-Paper", this);
1123  ESP_LOGCONFIG(TAG, " Model: 2.9in (B)");
1124  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1125  LOG_PIN(" DC Pin: ", this->dc_pin_);
1126  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1127  LOG_UPDATE_INTERVAL(this);
1128 }
1129 
1130 // DKE 2.9
1131 // https://www.badge.team/docs/badges/sha2017/hardware/#e-ink-display-the-dke-group-depg0290b1
1132 // https://www.badge.team/docs/badges/sha2017/hardware/DEPG0290B01V3.0.pdf
1133 static const uint8_t LUT_SIZE_DKE = 70;
1134 static const uint8_t UPDATE_LUT_DKE[LUT_SIZE_DKE] = {
1135  0xA0, 0x90, 0x50, 0x0, 0x0, 0x0, 0x0, 0x50, 0x90, 0xA0, 0x0, 0x0, 0x0, 0x0, 0xA0, 0x90, 0x50, 0x0,
1136  0x0, 0x0, 0x0, 0x50, 0x90, 0xA0, 0x0, 0x0, 0x0, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0xF,
1137  0xF, 0x0, 0x0, 0x0, 0xF, 0xF, 0x0, 0x0, 0x02, 0xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1138  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1139 };
1140 static const uint8_t PART_UPDATE_LUT_DKE[LUT_SIZE_DKE] = {
1141  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x50, 0x10, 0x00, 0x00,
1142  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
1143  0x05, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1144  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1145 static const uint8_t FULL_UPDATE_LUT_DKE[LUT_SIZE_DKE] = {
1146  0x90, 0x50, 0xa0, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0xa0, 0x80, 0x00, 0x90, 0x50, 0xa0, 0x50,
1147  0x50, 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
1148  0x04, 0x00, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00,
1149  0x00, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1150 
1152  // Hardware reset
1153  delay(10);
1154  this->reset_pin_->digital_write(false);
1155  delayMicroseconds(200);
1156  this->reset_pin_->digital_write(true);
1157  delayMicroseconds(200);
1158  // Wait for busy low
1159  this->wait_until_idle_();
1160  // Software reset
1161  this->command(0x12);
1162  // Wait for busy low
1163  this->wait_until_idle_();
1164  // Set Analog Block Control
1165  this->command(0x74);
1166  this->data(0x54);
1167  // Set Digital Block Control
1168  this->command(0x7E);
1169  this->data(0x3B);
1170  // Set display size and driver output control
1171  this->command(0x01);
1172  // this->data(0x27);
1173  // this->data(0x01);
1174  // this->data(0x00);
1175  this->data(this->get_height_internal() - 1);
1176  this->data((this->get_height_internal() - 1) >> 8);
1177  this->data(0x00); // ? GD = 0, SM = 0, TB = 0
1178  // Ram data entry mode
1179  this->command(0x11);
1180  this->data(0x03);
1181  // Set Ram X address
1182  this->command(0x44);
1183  this->data(0x00);
1184  this->data(0x0F);
1185  // Set Ram Y address
1186  this->command(0x45);
1187  this->data(0x00);
1188  this->data(0x00);
1189  this->data(0x27);
1190  this->data(0x01);
1191  // Set border
1192  this->command(0x3C);
1193  // this->data(0x80);
1194  this->data(0x01);
1195  // Set VCOM value
1196  this->command(0x2C);
1197  this->data(0x26);
1198  // Gate voltage setting
1199  this->command(0x03);
1200  this->data(0x17);
1201  // Source voltage setting
1202  this->command(0x04);
1203  this->data(0x41);
1204  this->data(0x00);
1205  this->data(0x32);
1206  // Frame setting 50hz
1207  this->command(0x3A);
1208  this->data(0x30);
1209  this->command(0x3B);
1210  this->data(0x0A);
1211  // Load LUT
1212  this->command(0x32);
1213  for (uint8_t v : FULL_UPDATE_LUT_DKE)
1214  this->data(v);
1215 }
1216 
1218  ESP_LOGI(TAG, "Performing e-paper update.");
1219  // Set Ram X address counter
1220  this->command(0x4e);
1221  this->data(0);
1222  // Set Ram Y address counter
1223  this->command(0x4f);
1224  this->data(0);
1225  this->data(0);
1226  // Load image (128/8*296)
1227  this->command(0x24);
1228  this->start_data_();
1229  this->write_array(this->buffer_, this->get_buffer_length_());
1230  this->end_data_();
1231  // Image update
1232  this->command(0x22);
1233  this->data(0xC7);
1234  this->command(0x20);
1235  // Wait for busy low
1236  this->wait_until_idle_();
1237  // Enter deep sleep mode
1238  this->command(0x10);
1239  this->data(0x01);
1240 }
1244  LOG_DISPLAY("", "Waveshare E-Paper", this);
1245  ESP_LOGCONFIG(TAG, " Model: 2.9in DKE");
1246  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1247  LOG_PIN(" DC Pin: ", this->dc_pin_);
1248  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1249  LOG_UPDATE_INTERVAL(this);
1250 }
1251 void WaveshareEPaper2P9InDKE::set_full_update_every(uint32_t full_update_every) {
1252  this->full_update_every_ = full_update_every;
1253 }
1254 
1255 // ========================================================
1256 // 2.90in Type B (LUT from OTP)
1257 // Datasheet:
1258 // - https://files.waveshare.com/upload/a/af/2.9inch-e-paper-b-v3-specification.pdf
1259 // ========================================================
1260 
1262  // from https://github.com/waveshareteam/e-Paper/blob/master/Arduino/epd2in9b_V3/epd2in9b_V3.cpp
1263  this->reset_();
1264 
1265  // COMMAND POWER ON
1266  this->command(0x04);
1267  this->wait_until_idle_();
1268 
1269  // COMMAND PANEL SETTING
1270  this->command(0x00);
1271  this->data(0x0F);
1272  this->data(0x89);
1273 
1274  // COMMAND RESOLUTION SETTING
1275  this->command(0x61);
1276  this->data(0x80);
1277  this->data(0x01);
1278  this->data(0x28);
1279 
1280  // COMMAND VCOM AND DATA INTERVAL SETTING
1281  this->command(0x50);
1282  this->data(0x77);
1283 }
1285  // COMMAND DATA START TRANSMISSION 1 (B/W data)
1286  this->command(0x10);
1287  delay(2);
1288  this->start_data_();
1289  this->write_array(this->buffer_, this->get_buffer_length_());
1290  this->end_data_();
1291  this->command(0x92);
1292  delay(2);
1293 
1294  // COMMAND DATA START TRANSMISSION 2 (RED data)
1295  this->command(0x13);
1296  delay(2);
1297  this->start_data_();
1298  for (size_t i = 0; i < this->get_buffer_length_(); i++)
1299  this->write_byte(0xFF);
1300  this->end_data_();
1301  this->command(0x92);
1302  delay(2);
1303 
1304  // COMMAND DISPLAY REFRESH
1305  this->command(0x12);
1306  delay(2);
1307  this->wait_until_idle_();
1308 
1309  // COMMAND POWER OFF
1310  // NOTE: power off < deep sleep
1311  this->command(0x02);
1312 }
1316  LOG_DISPLAY("", "Waveshare E-Paper", this);
1317  ESP_LOGCONFIG(TAG, " Model: 2.9in (B) V3");
1318  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1319  LOG_PIN(" DC Pin: ", this->dc_pin_);
1320  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1321  LOG_UPDATE_INTERVAL(this);
1322 }
1323 
1324 // ========================================================
1325 // 2.90in v2 rev2
1326 // based on SDK and examples in ZIP file from:
1327 // https://www.waveshare.com/pico-epaper-2.9.htm
1328 // ========================================================
1329 
1331  this->reset_();
1332  this->wait_until_idle_();
1333 
1334  this->command(0x12); // SWRESET
1335  this->wait_until_idle_();
1336 
1337  this->command(0x01);
1338  this->data(0x27);
1339  this->data(0x01);
1340  this->data(0x00);
1341 
1342  this->command(0x11);
1343  this->data(0x03);
1344 
1345  // SetWindows(0, 0, w, h)
1346  this->command(0x44);
1347  this->data(0x00);
1348  this->data(((this->get_width_controller() - 1) >> 3) & 0xFF);
1349 
1350  this->command(0x45);
1351  this->data(0x00);
1352  this->data(0x00);
1353  this->data((this->get_height_internal() - 1) & 0xFF);
1354  this->data(((this->get_height_internal() - 1) >> 8) & 0xFF);
1355 
1356  this->command(0x21);
1357  this->data(0x00);
1358  this->data(0x80);
1359 
1360  // SetCursor(0, 0)
1361  this->command(0x4E);
1362  this->data(0x00);
1363  this->command(0x4f);
1364  this->data(0x00);
1365  this->data(0x00);
1366 
1367  this->wait_until_idle_();
1368 }
1369 
1371 
1372 void WaveshareEPaper2P9InV2R2::reset_() {
1373  if (this->reset_pin_ != nullptr) {
1374  this->reset_pin_->digital_write(false);
1375  delay(reset_duration_); // NOLINT
1376  this->reset_pin_->digital_write(true);
1377  delay(reset_duration_); // NOLINT
1378  }
1379 }
1380 
1382  if (!this->wait_until_idle_()) {
1383  this->status_set_warning();
1384  ESP_LOGE(TAG, "fail idle 1");
1385  return;
1386  }
1387 
1388  if (this->full_update_every_ == 1) {
1389  // do single full update
1390  this->command(0x24);
1391  this->start_data_();
1392  this->write_array(this->buffer_, this->get_buffer_length_());
1393  this->end_data_();
1394 
1395  // TurnOnDisplay
1396  this->command(0x22);
1397  this->data(0xF7);
1398  this->command(0x20);
1399  return;
1400  }
1401 
1402  // if (this->full_update_every_ == 1 ||
1403  if (this->at_update_ == 0) {
1404  // do base update
1405  this->command(0x24);
1406  this->start_data_();
1407  this->write_array(this->buffer_, this->get_buffer_length_());
1408  this->end_data_();
1409 
1410  this->command(0x26);
1411  this->start_data_();
1412  this->write_array(this->buffer_, this->get_buffer_length_());
1413  this->end_data_();
1414 
1415  // TurnOnDisplay
1416  this->command(0x22);
1417  this->data(0xF7);
1418  this->command(0x20);
1419  } else {
1420  // do partial update
1421  this->reset_();
1422 
1423  this->write_lut_(PARTIAL_UPD_2IN9_LUT, PARTIAL_UPD_2IN9_LUT_SIZE);
1424 
1425  this->command(0x37);
1426  this->data(0x00);
1427  this->data(0x00);
1428  this->data(0x00);
1429  this->data(0x00);
1430  this->data(0x00);
1431  this->data(0x40);
1432  this->data(0x00);
1433  this->data(0x00);
1434  this->data(0x00);
1435  this->data(0x00);
1436 
1437  this->command(0x3C);
1438  this->data(0x80);
1439 
1440  this->command(0x22);
1441  this->data(0xC0);
1442  this->command(0x20);
1443 
1444  if (!this->wait_until_idle_()) {
1445  ESP_LOGE(TAG, "fail idle 2");
1446  }
1447 
1448  // SetWindows(0, 0, w, h)
1449  this->command(0x44);
1450  this->data(0x00);
1451  this->data(((this->get_width_controller() - 1) >> 3) & 0xFF);
1452 
1453  this->command(0x45);
1454  this->data(0x00);
1455  this->data(0x00);
1456  this->data((this->get_height_internal() - 1) & 0xFF);
1457  this->data(((this->get_height_internal() - 1) >> 8) & 0xFF);
1458 
1459  // SetCursor(0, 0)
1460  this->command(0x4E);
1461  this->data(0x00);
1462  this->command(0x4f);
1463  this->data(0x00);
1464  this->data(0x00);
1465 
1466  // write b/w
1467  this->command(0x24);
1468  this->start_data_();
1469  this->write_array(this->buffer_, this->get_buffer_length_());
1470  this->end_data_();
1471 
1472  // TurnOnDisplayPartial
1473  this->command(0x22);
1474  this->data(0x0F);
1475  this->command(0x20);
1476  }
1477 
1478  this->at_update_ = (this->at_update_ + 1) % this->full_update_every_;
1479 }
1480 
1481 void WaveshareEPaper2P9InV2R2::write_lut_(const uint8_t *lut, const uint8_t size) {
1482  // COMMAND WRITE LUT REGISTER
1483  this->command(0x32);
1484  for (uint8_t i = 0; i < size; i++)
1485  this->data(lut[i]);
1486 }
1487 
1489  LOG_DISPLAY("", "Waveshare E-Paper", this);
1490  ESP_LOGCONFIG(TAG, " Model: 2.9inV2R2");
1491  ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_);
1492  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1493  LOG_PIN(" DC Pin: ", this->dc_pin_);
1494  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1495  LOG_UPDATE_INTERVAL(this);
1496 }
1497 
1499  this->command(0x10);
1500  this->data(0x01);
1501 }
1502 
1506 void WaveshareEPaper2P9InV2R2::set_full_update_every(uint32_t full_update_every) {
1507  this->full_update_every_ = full_update_every;
1508 }
1509 
1510 // ========================================================
1511 // Good Display 2.9in black/white/grey
1512 // Datasheet:
1513 // - https://v4.cecdn.yun300.cn/100001_1909185148/SSD1680.pdf
1514 // - https://github.com/adafruit/Adafruit_EPD/blob/master/src/panels/ThinkInk_290_Grayscale4_T5.h
1515 // ========================================================
1516 
1518  // from https://www.waveshare.com/w/upload/b/bb/2.9inch-e-paper-b-specification.pdf, page 37
1519  // EPD hardware init start
1520  this->reset_();
1521 
1522  // COMMAND POWER SETTINGS
1523  this->command(0x00);
1524  this->data(0x03);
1525  this->data(0x00);
1526  this->data(0x2b);
1527  this->data(0x2b);
1528  this->data(0x03); /* for b/w */
1529 
1530  // COMMAND BOOSTER SOFT START
1531  this->command(0x06);
1532  this->data(0x17);
1533  this->data(0x17);
1534  this->data(0x17);
1535 
1536  // COMMAND POWER ON
1537  this->command(0x04);
1538  this->wait_until_idle_();
1539 
1540  // Not sure what this does but it's in the Adafruit EPD library
1541  this->command(0xFF);
1542  this->wait_until_idle_();
1543 
1544  // COMMAND PANEL SETTING
1545  this->command(0x00);
1546  // 128x296 resolution: 10
1547  // LUT from OTP: 0
1548  // B/W mode (doesn't work): 1
1549  // scan-up: 1
1550  // shift-right: 1
1551  // booster ON: 1
1552  // no soft reset: 1
1553  this->data(0b10011111);
1554 
1555  // COMMAND RESOLUTION SETTING
1556  // set to 128x296 by COMMAND PANEL SETTING
1557 
1558  // COMMAND VCOM AND DATA INTERVAL SETTING
1559  // use defaults for white border and ESPHome image polarity
1560 
1561  // EPD hardware init end
1562 }
1564  // COMMAND DATA START TRANSMISSION 2 (B/W only)
1565  this->command(0x13);
1566  delay(2);
1567  this->start_data_();
1568  for (size_t i = 0; i < this->get_buffer_length_(); i++) {
1569  this->write_byte(this->buffer_[i]);
1570  }
1571  this->end_data_();
1572  delay(2);
1573 
1574  // COMMAND DISPLAY REFRESH
1575  this->command(0x12);
1576  delay(2);
1577  this->wait_until_idle_();
1578 
1579  // COMMAND POWER OFF
1580  // NOTE: power off < deep sleep
1581  this->command(0x02);
1582 }
1583 int GDEW029T5::get_width_internal() { return 128; }
1584 int GDEW029T5::get_height_internal() { return 296; }
1586  LOG_DISPLAY("", "Waveshare E-Paper (Good Display)", this);
1587  ESP_LOGCONFIG(TAG, " Model: 2.9in Greyscale GDEW029T5");
1588  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1589  LOG_PIN(" DC Pin: ", this->dc_pin_);
1590  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1591  LOG_UPDATE_INTERVAL(this);
1592 }
1593 
1594 // ========================================================
1595 // Good Display 1.54in black/white/grey GDEW0154M09
1596 // As used in M5Stack Core Ink
1597 // Datasheet:
1598 // - https://v4.cecdn.yun300.cn/100001_1909185148/GDEW0154M09-200709.pdf
1599 // - https://github.com/m5stack/M5Core-Ink
1600 // Reference code from GoodDisplay:
1601 // - https://github.com/GoodDisplay/E-paper-Display-Library-of-GoodDisplay/
1602 // -> /Monochrome_E-paper-Display/1.54inch_JD79653_GDEW0154M09_200x200/ESP32-Arduino%20IDE/GDEW0154M09_Arduino.ino
1603 // M5Stack Core Ink spec:
1604 // - https://docs.m5stack.com/en/core/coreink
1605 // ========================================================
1606 
1608  this->init_internal_();
1610  this->lastbuff_ = allocator.allocate(this->get_buffer_length_());
1611  if (this->lastbuff_ != nullptr) {
1612  memset(this->lastbuff_, 0xff, sizeof(uint8_t) * this->get_buffer_length_());
1613  }
1614  this->clear_();
1615 }
1616 
1617 void GDEW0154M09::reset_() {
1618  // RST is inverse from other einks in this project
1619  if (this->reset_pin_ != nullptr) {
1620  this->reset_pin_->digital_write(false);
1621  delay(10);
1622  this->reset_pin_->digital_write(true);
1623  delay(10);
1624  }
1625 }
1626 
1627 void GDEW0154M09::init_internal_() {
1628  this->reset_();
1629 
1630  // clang-format off
1631  // 200x200 resolution: 11
1632  // LUT from OTP: 0
1633  // B/W mode (doesn't work): 1
1634  // scan-up: 1
1635  // shift-right: 1
1636  // booster ON: 1
1637  // no soft reset: 1
1638  const uint8_t panel_setting_1 = 0b11011111;
1639 
1640  // VCOM status off 0
1641  // Temp sensing default 1
1642  // VGL Power Off Floating 1
1643  // NORG expect refresh 1
1644  // VCOM Off on displ off 0
1645  const uint8_t panel_setting_2 = 0b01110;
1646 
1647  const uint8_t wf_t0154_cz_b3_list[] = {
1648  11, // 11 commands in list
1649  CMD_PSR_PANEL_SETTING, 2, panel_setting_1, panel_setting_2,
1650  CMD_UNDOCUMENTED_0x4D, 1, 0x55,
1651  CMD_UNDOCUMENTED_0xAA, 1, 0x0f,
1652  CMD_UNDOCUMENTED_0xE9, 1, 0x02,
1653  CMD_UNDOCUMENTED_0xB6, 1, 0x11,
1654  CMD_UNDOCUMENTED_0xF3, 1, 0x0a,
1655  CMD_TRES_RESOLUTION_SETTING, 3, 0xc8, 0x00, 0xc8,
1656  CMD_TCON_TCONSETTING, 1, 0x00,
1657  CMD_CDI_VCOM_DATA_INTERVAL, 1, 0xd7,
1658  CMD_PWS_POWER_SAVING, 1, 0x00,
1659  CMD_PON_POWER_ON, 0
1660  };
1661  // clang-format on
1662 
1663  this->write_init_list_(wf_t0154_cz_b3_list);
1664  delay(100); // NOLINT
1665  this->wait_until_idle_();
1666 }
1667 
1668 void GDEW0154M09::write_init_list_(const uint8_t *list) {
1669  uint8_t list_limit = list[0];
1670  uint8_t *start_ptr = ((uint8_t *) list + 1);
1671  for (uint8_t i = 0; i < list_limit; i++) {
1672  this->command(*(start_ptr + 0));
1673  for (uint8_t dnum = 0; dnum < *(start_ptr + 1); dnum++) {
1674  this->data(*(start_ptr + 2 + dnum));
1675  }
1676  start_ptr += (*(start_ptr + 1) + 2);
1677  }
1678 }
1679 
1680 void GDEW0154M09::clear_() {
1681  uint32_t pixsize = this->get_buffer_length_();
1682  for (uint8_t j = 0; j < 2; j++) {
1683  this->command(CMD_DTM1_DATA_START_TRANS);
1684  for (int count = 0; count < pixsize; count++) {
1685  this->data(0x00);
1686  }
1687  this->command(CMD_DTM2_DATA_START_TRANS2);
1688  for (int count = 0; count < pixsize; count++) {
1689  this->data(0xff);
1690  }
1691  this->command(CMD_DISPLAY_REFRESH);
1692  delay(10);
1693  this->wait_until_idle_();
1694  }
1695 }
1696 
1698  this->init_internal_();
1699  // "Mode 0 display" for now
1700  this->command(CMD_DTM1_DATA_START_TRANS);
1701  for (int i = 0; i < this->get_buffer_length_(); i++) {
1702  this->data(0xff);
1703  }
1704  this->command(CMD_DTM2_DATA_START_TRANS2); // write 'new' data to SRAM
1705  for (int i = 0; i < this->get_buffer_length_(); i++) {
1706  this->data(this->buffer_[i]);
1707  }
1708  this->command(CMD_DISPLAY_REFRESH);
1709  delay(10);
1710  this->wait_until_idle_();
1711  this->deep_sleep();
1712 }
1713 
1715  // COMMAND DEEP SLEEP
1716  this->command(CMD_POF_POWER_OFF);
1717  this->wait_until_idle_();
1718  delay(1000); // NOLINT
1719  this->command(CMD_DSLP_DEEP_SLEEP);
1720  this->data(DATA_DSLP_DEEP_SLEEP);
1721 }
1722 
1723 int GDEW0154M09::get_width_internal() { return 200; }
1726  LOG_DISPLAY("", "M5Stack CoreInk E-Paper (Good Display)", this);
1727  ESP_LOGCONFIG(TAG, " Model: 1.54in Greyscale GDEW0154M09");
1728  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1729  LOG_PIN(" DC Pin: ", this->dc_pin_);
1730  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1731  LOG_UPDATE_INTERVAL(this);
1732 }
1733 
1734 static const uint8_t LUT_VCOM_DC_4_2[] = {
1735  0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x17, 0x17, 0x00, 0x00, 0x02, 0x00, 0x0A, 0x01,
1736  0x00, 0x00, 0x01, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1737  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1738 };
1739 static const uint8_t LUT_WHITE_TO_WHITE_4_2[] = {
1740  0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
1741  0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
1742  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1743 };
1744 static const uint8_t LUT_BLACK_TO_WHITE_4_2[] = {
1745  0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
1746  0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
1747  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1748 };
1749 
1750 static const uint8_t LUT_BLACK_TO_BLACK_4_2[] = {
1751  0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
1752  0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
1753  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1754 };
1755 
1756 static const uint8_t LUT_WHITE_TO_BLACK_4_2[] = {
1757  0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
1758  0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
1759  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760 };
1761 
1763  // https://www.waveshare.com/w/upload/7/7f/4.2inch-e-paper-b-specification.pdf - page 8
1764 
1765  // COMMAND POWER SETTING
1766  this->command(0x01);
1767  this->data(0x03); // VDS_EN, VDG_EN
1768  this->data(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
1769  this->data(0x2B); // VDH
1770  this->data(0x2B); // VDL
1771  this->data(0xFF); // VDHR
1772 
1773  // COMMAND BOOSTER SOFT START
1774  this->command(0x06);
1775  this->data(0x17); // PHA
1776  this->data(0x17); // PHB
1777  this->data(0x17); // PHC
1778 
1779  // COMMAND POWER ON
1780  this->command(0x04);
1781  this->wait_until_idle_();
1782  delay(10);
1783  // COMMAND PANEL SETTING
1784  this->command(0x00);
1785  this->data(0xBF); // KW-BF KWR-AF BWROTP 0f
1786  this->data(0x0B);
1787  // COMMAND PLL CONTROL
1788  this->command(0x30);
1789  this->data(0x3C); // 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
1790 
1791  delay(2);
1792  // COMMAND LUT FOR VCOM
1793  this->command(0x20);
1794  for (uint8_t i : LUT_VCOM_DC_4_2)
1795  this->data(i);
1796  // COMMAND LUT WHITE TO WHITE
1797  this->command(0x21);
1798  for (uint8_t i : LUT_WHITE_TO_WHITE_4_2)
1799  this->data(i);
1800  // COMMAND LUT BLACK TO WHITE
1801  this->command(0x22);
1802  for (uint8_t i : LUT_BLACK_TO_WHITE_4_2)
1803  this->data(i);
1804  // COMMAND LUT WHITE TO BLACK
1805  this->command(0x23);
1806  for (uint8_t i : LUT_WHITE_TO_BLACK_4_2)
1807  this->data(i);
1808  // COMMAND LUT BLACK TO BLACK
1809  this->command(0x24);
1810  for (uint8_t i : LUT_BLACK_TO_BLACK_4_2)
1811  this->data(i);
1812 }
1814  // COMMAND RESOLUTION SETTING
1815  this->command(0x61);
1816  this->data(0x01);
1817  this->data(0x90);
1818  this->data(0x01);
1819  this->data(0x2C);
1820 
1821  // COMMAND VCM DC SETTING REGISTER
1822  this->command(0x82);
1823  this->data(0x12);
1824 
1825  // COMMAND VCOM AND DATA INTERVAL SETTING
1826  this->command(0x50);
1827  this->data(0x97);
1828 
1829  // COMMAND DATA START TRANSMISSION 1
1830  this->command(0x10);
1831  delay(2);
1832  this->start_data_();
1833  this->write_array(this->buffer_, this->get_buffer_length_());
1834  this->end_data_();
1835  delay(2);
1836  // COMMAND DATA START TRANSMISSION 2
1837  this->command(0x13);
1838  delay(2);
1839  this->start_data_();
1840  this->write_array(this->buffer_, this->get_buffer_length_());
1841  this->end_data_();
1842  // COMMAND DISPLAY REFRESH
1843  this->command(0x12);
1844 }
1848  LOG_DISPLAY("", "Waveshare E-Paper", this);
1849  ESP_LOGCONFIG(TAG, " Model: 4.2in");
1850  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1851  LOG_PIN(" DC Pin: ", this->dc_pin_);
1852  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1853  LOG_UPDATE_INTERVAL(this);
1854 }
1855 
1856 // ========================================================
1857 // 4.20in Type B (LUT from OTP)
1858 // Datasheet:
1859 // - https://www.waveshare.com/w/upload/2/20/4.2inch-e-paper-module-user-manual-en.pdf
1860 // - https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_4in2b_V2.c
1861 // ========================================================
1863  // these exact timings are required for a proper reset/init
1864  this->reset_pin_->digital_write(false);
1865  delay(2);
1866  this->reset_pin_->digital_write(true);
1867  delay(200); // NOLINT
1868 
1869  // COMMAND POWER ON
1870  this->command(0x04);
1871  this->wait_until_idle_();
1872 
1873  // COMMAND PANEL SETTING
1874  this->command(0x00);
1875  this->data(0x0f); // LUT from OTP
1876 }
1877 
1879  // COMMAND DATA START TRANSMISSION 1 (B/W data)
1880  this->command(0x10);
1881  this->start_data_();
1882  this->write_array(this->buffer_, this->get_buffer_length_());
1883  this->end_data_();
1884 
1885  // COMMAND DATA START TRANSMISSION 2 (RED data)
1886  this->command(0x13);
1887  this->start_data_();
1888  for (size_t i = 0; i < this->get_buffer_length_(); i++)
1889  this->write_byte(0xFF);
1890  this->end_data_();
1891  delay(2);
1892 
1893  // COMMAND DISPLAY REFRESH
1894  this->command(0x12);
1895  this->wait_until_idle_();
1896 
1897  // COMMAND POWER OFF
1898  // NOTE: power off < deep sleep
1899  this->command(0x02);
1900 }
1904  LOG_DISPLAY("", "Waveshare E-Paper", this);
1905  ESP_LOGCONFIG(TAG, " Model: 4.2in (B V2)");
1906  LOG_PIN(" Reset Pin: ", this->reset_pin_);
1907  LOG_PIN(" DC Pin: ", this->dc_pin_);
1908  LOG_PIN(" Busy Pin: ", this->busy_pin_);
1909  LOG_UPDATE_INTERVAL(this);
1910 }
1911 
1913  // COMMAND POWER SETTING
1914  this->command(0x01);
1915  this->data(0x37);
1916  this->data(0x00);
1917 
1918  // COMMAND PANEL SETTING
1919  this->command(0x00);
1920  this->data(0xCF);
1921  this->data(0x0B);
1922 
1923  // COMMAND BOOSTER SOFT START
1924  this->command(0x06);
1925  this->data(0xC7);
1926  this->data(0xCC);
1927  this->data(0x28);
1928 
1929  // COMMAND POWER ON
1930  this->command(0x04);
1931  this->wait_until_idle_();
1932  delay(10);
1933 
1934  // COMMAND PLL CONTROL
1935  this->command(0x30);
1936  this->data(0x3C);
1937 
1938  // COMMAND TEMPERATURE SENSOR CALIBRATION
1939  this->command(0x41);
1940  this->data(0x00);
1941 
1942  // COMMAND VCOM AND DATA INTERVAL SETTING
1943  this->command(0x50);
1944  this->data(0x77);
1945 
1946  // COMMAND TCON SETTING
1947  this->command(0x60);
1948  this->data(0x22);
1949 
1950  // COMMAND RESOLUTION SETTING
1951  this->command(0x61);
1952  this->data(0x02);
1953  this->data(0x58);
1954  this->data(0x01);
1955  this->data(0xC0);
1956 
1957  // COMMAND VCM DC SETTING REGISTER
1958  this->command(0x82);
1959  this->data(0x1E);
1960 
1961  this->command(0xE5);
1962  this->data(0x03);
1963 }
1965  // COMMAND DATA START TRANSMISSION 1
1966  this->command(0x10);
1967 
1968  this->start_data_();
1969  for (size_t i = 0; i < this->get_buffer_length_(); i++) {
1970  uint8_t temp1 = this->buffer_[i];
1971  for (uint8_t j = 0; j < 8; j++) {
1972  uint8_t temp2;
1973  if (temp1 & 0x80) {
1974  temp2 = 0x03;
1975  } else {
1976  temp2 = 0x00;
1977  }
1978 
1979  temp2 <<= 4;
1980  temp1 <<= 1;
1981  j++;
1982  if (temp1 & 0x80) {
1983  temp2 |= 0x03;
1984  } else {
1985  temp2 |= 0x00;
1986  }
1987  temp1 <<= 1;
1988  this->write_byte(temp2);
1989  }
1990 
1991  App.feed_wdt();
1992  }
1993  this->end_data_();
1994 
1995  // COMMAND DISPLAY REFRESH
1996  this->command(0x12);
1997 }
2001  LOG_DISPLAY("", "Waveshare E-Paper", this);
2002  ESP_LOGCONFIG(TAG, " Model: 5.83in");
2003  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2004  LOG_PIN(" DC Pin: ", this->dc_pin_);
2005  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2006  LOG_UPDATE_INTERVAL(this);
2007 }
2008 
2009 // ========================================================
2010 // 5.83in V2
2011 // Datasheet/Specification/Reference:
2012 // - https://www.waveshare.com/w/upload/3/37/5.83inch_e-Paper_V2_Specification.pdf
2013 // - https://github.com/waveshare/e-Paper/blob/master/Arduino/epd5in83_V2/epd5in83_V2.cpp
2014 // ========================================================
2016  // COMMAND POWER SETTING
2017  this->command(0x01);
2018  this->data(0x07);
2019  this->data(0x07);
2020  this->data(0x3f);
2021  this->data(0x3f);
2022 
2023  // COMMAND POWER ON
2024  this->command(0x04);
2025  delay(10);
2026  this->wait_until_idle_();
2027 
2028  // PANNEL SETTING
2029  this->command(0x00);
2030  this->data(0x1F);
2031 
2032  // COMMAND RESOLUTION SETTING
2033  this->command(0x61);
2034  this->data(0x02);
2035  this->data(0x88);
2036  this->data(0x01);
2037  this->data(0xE0);
2038 
2039  this->command(0x15);
2040  this->data(0x00);
2041 
2042  // COMMAND TCON SETTING
2043  this->command(0x60);
2044  this->data(0x22);
2045 
2046  // Do we need this?
2047  // COMMAND PLL CONTROL
2048  this->command(0x30);
2049  this->data(0x3C); // 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
2050 }
2052  // Reuse the code from WaveshareEPaper4P2In::display()
2053  // COMMAND VCM DC SETTING REGISTER
2054  this->command(0x82);
2055  this->data(0x12);
2056 
2057  // COMMAND VCOM AND DATA INTERVAL SETTING
2058  this->command(0x50);
2059  this->data(0x97);
2060 
2061  // COMMAND DATA START TRANSMISSION 1
2062  this->command(0x10);
2063  delay(2);
2064  this->start_data_();
2065  this->write_array(this->buffer_, this->get_buffer_length_());
2066  this->end_data_();
2067  delay(2);
2068 
2069  // COMMAND DATA START TRANSMISSION 2
2070  this->command(0x13);
2071  delay(2);
2072  this->start_data_();
2073  this->write_array(this->buffer_, this->get_buffer_length_());
2074  this->end_data_();
2075 
2076  // COMMAND DISPLAY REFRESH
2077  this->command(0x12);
2078 }
2082  LOG_DISPLAY("", "Waveshare E-Paper", this);
2083  ESP_LOGCONFIG(TAG, " Model: 5.83inv2");
2084  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2085  LOG_PIN(" DC Pin: ", this->dc_pin_);
2086  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2087  LOG_UPDATE_INTERVAL(this);
2088 }
2089 
2091  // COMMAND POWER SETTING
2092  this->command(0x01);
2093  this->data(0x07);
2094  this->data(0x07); // VGH=20V,VGL=-20V
2095  this->data(0x3f); // VDH=15V
2096  this->data(0x3f); // VDL=-15V
2097  // COMMAND POWER ON
2098  this->command(0x04);
2099  delay(100); // NOLINT
2100  this->wait_until_idle_();
2101  // COMMAND PANEL SETTING
2102  this->command(0x00);
2103  this->data(0x0F); // KW3f, KWR-2F, BWROTP 0f, BWOTP 1f
2104  this->command(0x61); // tres
2105  this->data(0x03); // 800px
2106  this->data(0x20);
2107  this->data(0x01); // 400px
2108  this->data(0xE0);
2109  this->command(0x15);
2110  this->data(0x00);
2111  // COMMAND VCOM AND DATA INTERVAL SETTING
2112  this->command(0x50);
2113  this->data(0x11);
2114  this->data(0x07);
2115  // COMMAND TCON SETTING
2116  this->command(0x60);
2117  this->data(0x22);
2118 
2119  this->command(0x82);
2120  this->data(0x08);
2121  this->command(0x30);
2122  this->data(0x06);
2123 
2124  // COMMAND RESOLUTION SETTING
2125  this->command(0x65);
2126  this->data(0x00);
2127  this->data(0x00); // 800*480
2128  this->data(0x00);
2129  this->data(0x00);
2130 }
2132  // COMMAND DATA START TRANSMISSION 1 (B/W data)
2133  this->command(0x10);
2134  delay(2);
2135  this->start_data_();
2136  this->write_array(this->buffer_, this->get_buffer_length_());
2137  this->end_data_();
2138  delay(2);
2139 
2140  // COMMAND DATA START TRANSMISSION 2 (RED data)
2141  this->command(0x13);
2142  delay(2);
2143  this->start_data_();
2144  for (size_t i = 0; i < this->get_buffer_length_(); i++)
2145  this->write_byte(0x00);
2146  this->end_data_();
2147  delay(2);
2148 
2149  // COMMAND DISPLAY REFRESH
2150  this->command(0x12);
2151  delay(100); // NOLINT
2152  this->wait_until_idle_();
2153  this->deep_sleep();
2154 }
2158  LOG_DISPLAY("", "Waveshare E-Paper", this);
2159  ESP_LOGCONFIG(TAG, " Model: 7.5in-bv2");
2160  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2161  LOG_PIN(" DC Pin: ", this->dc_pin_);
2162  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2163  LOG_UPDATE_INTERVAL(this);
2164 }
2165 
2168  if (this->busy_pin_ == nullptr) {
2169  return true;
2170  }
2171 
2172  const uint32_t start = millis();
2173  while (this->busy_pin_->digital_read()) {
2174  this->command(0x71);
2175  if (millis() - start > this->idle_timeout_()) {
2176  ESP_LOGI(TAG, "Timeout while displaying image!");
2177  return false;
2178  }
2179  App.feed_wdt();
2180  delay(10);
2181  }
2182  delay(200); // NOLINT
2183  return true;
2184 };
2186  this->reset_();
2187 
2188  // COMMAND POWER SETTING
2189  this->command(0x01);
2190 
2191  // 1-0=11: internal power
2192  this->data(0x07);
2193  this->data(0x17); // VGH&VGL
2194  this->data(0x3F); // VSH
2195  this->data(0x26); // VSL
2196  this->data(0x11); // VSHR
2197 
2198  // VCOM DC Setting
2199  this->command(0x82);
2200  this->data(0x24); // VCOM
2201 
2202  // Booster Setting
2203  this->command(0x06);
2204  this->data(0x27);
2205  this->data(0x27);
2206  this->data(0x2F);
2207  this->data(0x17);
2208 
2209  // POWER ON
2210  this->command(0x04);
2211 
2212  delay(100); // NOLINT
2213  this->wait_until_idle_();
2214  // COMMAND PANEL SETTING
2215  this->command(0x00);
2216  this->data(0x3F); // KW-3f KWR-2F BWROTP 0f BWOTP 1f
2217 
2218  // COMMAND RESOLUTION SETTING
2219  this->command(0x61);
2220  this->data(0x03); // source 800
2221  this->data(0x20);
2222  this->data(0x01); // gate 480
2223  this->data(0xE0);
2224  // COMMAND ...?
2225  this->command(0x15);
2226  this->data(0x00);
2227  // COMMAND VCOM AND DATA INTERVAL SETTING
2228  this->command(0x50);
2229  this->data(0x10);
2230  this->data(0x00);
2231  // COMMAND TCON SETTING
2232  this->command(0x60);
2233  this->data(0x22);
2234  // Resolution setting
2235  this->command(0x65);
2236  this->data(0x00);
2237  this->data(0x00); // 800*480
2238  this->data(0x00);
2239  this->data(0x00);
2240 
2241  uint8_t lut_vcom_7_i_n5_v2[] = {
2242  0x0, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0xF, 0x1, 0xF, 0x1, 0x2, 0x0, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
2243  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2244  };
2245 
2246  uint8_t lut_ww_7_i_n5_v2[] = {
2247  0x10, 0xF, 0xF, 0x0, 0x0, 0x1, 0x84, 0xF, 0x1, 0xF, 0x1, 0x2, 0x20, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
2248  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2249  };
2250 
2251  uint8_t lut_bw_7_i_n5_v2[] = {
2252  0x10, 0xF, 0xF, 0x0, 0x0, 0x1, 0x84, 0xF, 0x1, 0xF, 0x1, 0x2, 0x20, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
2253  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2254  };
2255 
2256  uint8_t lut_wb_7_i_n5_v2[] = {
2257  0x80, 0xF, 0xF, 0x0, 0x0, 0x3, 0x84, 0xF, 0x1, 0xF, 0x1, 0x4, 0x40, 0xF, 0xF, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0,
2258  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2259  };
2260 
2261  uint8_t lut_bb_7_i_n5_v2[] = {
2262  0x80, 0xF, 0xF, 0x0, 0x0, 0x1, 0x84, 0xF, 0x1, 0xF, 0x1, 0x2, 0x40, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
2263  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2264  };
2265 
2266  uint8_t count;
2267  this->command(0x20); // VCOM
2268  for (count = 0; count < 42; count++)
2269  this->data(lut_vcom_7_i_n5_v2[count]);
2270 
2271  this->command(0x21); // LUTBW
2272  for (count = 0; count < 42; count++)
2273  this->data(lut_ww_7_i_n5_v2[count]);
2274 
2275  this->command(0x22); // LUTBW
2276  for (count = 0; count < 42; count++)
2277  this->data(lut_bw_7_i_n5_v2[count]);
2278 
2279  this->command(0x23); // LUTWB
2280  for (count = 0; count < 42; count++)
2281  this->data(lut_wb_7_i_n5_v2[count]);
2282 
2283  this->command(0x24); // LUTBB
2284  for (count = 0; count < 42; count++)
2285  this->data(lut_bb_7_i_n5_v2[count]);
2286 };
2288  this->init_display_();
2289  uint32_t buf_len = this->get_buffer_length_();
2290 
2291  this->command(0x10);
2292  for (uint32_t i = 0; i < buf_len; i++) {
2293  this->data(0xFF);
2294  }
2295 
2296  this->command(0x13); // Start Transmission
2297  delay(2);
2298  for (uint32_t i = 0; i < buf_len; i++) {
2299  this->data(~this->buffer_[i]);
2300  }
2301 
2302  this->command(0x12); // Display Refresh
2303  delay(100); // NOLINT
2304  this->wait_until_idle_();
2305  this->deep_sleep();
2306 }
2310  LOG_DISPLAY("", "Waveshare E-Paper", this);
2311  ESP_LOGCONFIG(TAG, " Model: 7.5in-bv3");
2312  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2313  LOG_PIN(" DC Pin: ", this->dc_pin_);
2314  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2315  LOG_UPDATE_INTERVAL(this);
2316 }
2317 
2319  // COMMAND POWER SETTING
2320  this->command(0x01);
2321  this->data(0x37);
2322  this->data(0x00);
2323  // COMMAND PANEL SETTING
2324  this->command(0x00);
2325  this->data(0xCF);
2326  this->data(0x0B);
2327  // COMMAND BOOSTER SOFT START
2328  this->command(0x06);
2329  this->data(0xC7);
2330  this->data(0xCC);
2331  this->data(0x28);
2332  // COMMAND POWER ON
2333  this->command(0x04);
2334  this->wait_until_idle_();
2335  delay(10);
2336  // COMMAND PLL CONTROL
2337  this->command(0x30);
2338  this->data(0x3C);
2339  // COMMAND TEMPERATURE SENSOR CALIBRATION
2340  this->command(0x41);
2341  this->data(0x00);
2342  // COMMAND VCOM AND DATA INTERVAL SETTING
2343  this->command(0x50);
2344  this->data(0x77);
2345  // COMMAND TCON SETTING
2346  this->command(0x60);
2347  this->data(0x22);
2348  // COMMAND RESOLUTION SETTING
2349  this->command(0x61);
2350  this->data(0x02);
2351  this->data(0x80);
2352  this->data(0x01);
2353  this->data(0x80);
2354  // COMMAND VCM DC SETTING REGISTER
2355  this->command(0x82);
2356  this->data(0x1E);
2357  this->command(0xE5);
2358  this->data(0x03);
2359 }
2361  // COMMAND DATA START TRANSMISSION 1
2362  this->command(0x10);
2363  this->start_data_();
2364  for (size_t i = 0; i < this->get_buffer_length_(); i++) {
2365  uint8_t temp1 = this->buffer_[i];
2366  for (uint8_t j = 0; j < 8; j++) {
2367  uint8_t temp2;
2368  if (temp1 & 0x80) {
2369  temp2 = 0x03;
2370  } else {
2371  temp2 = 0x00;
2372  }
2373  temp2 <<= 4;
2374  temp1 <<= 1;
2375  j++;
2376  if (temp1 & 0x80) {
2377  temp2 |= 0x03;
2378  } else {
2379  temp2 |= 0x00;
2380  }
2381  temp1 <<= 1;
2382  this->write_byte(temp2);
2383  }
2384  App.feed_wdt();
2385  }
2386  this->end_data_();
2387  // COMMAND DISPLAY REFRESH
2388  this->command(0x12);
2389 }
2393  LOG_DISPLAY("", "Waveshare E-Paper", this);
2394  ESP_LOGCONFIG(TAG, " Model: 7.5in");
2395  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2396  LOG_PIN(" DC Pin: ", this->dc_pin_);
2397  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2398  LOG_UPDATE_INTERVAL(this);
2399 }
2401  if (this->busy_pin_ == nullptr) {
2402  return true;
2403  }
2404 
2405  const uint32_t start = millis();
2406  while (this->busy_pin_->digital_read()) {
2407  this->command(0x71);
2408  if (millis() - start > this->idle_timeout_()) {
2409  ESP_LOGE(TAG, "Timeout while displaying image!");
2410  return false;
2411  }
2412  App.feed_wdt();
2413  delay(10);
2414  }
2415  return true;
2416 }
2418  // COMMAND POWER SETTING
2419  this->command(0x01);
2420  this->data(0x07);
2421  this->data(0x07);
2422  this->data(0x3f);
2423  this->data(0x3f);
2424 
2425  // We don't want the display to be powered at this point
2426 
2427  delay(100); // NOLINT
2428  this->wait_until_idle_();
2429 
2430  // COMMAND VCOM AND DATA INTERVAL SETTING
2431  this->command(0x50);
2432  this->data(0x10);
2433  this->data(0x07);
2434 
2435  // COMMAND TCON SETTING
2436  this->command(0x60);
2437  this->data(0x22);
2438 
2439  // COMMAND PANEL SETTING
2440  this->command(0x00);
2441  this->data(0x1F);
2442 
2443  // COMMAND RESOLUTION SETTING
2444  this->command(0x61);
2445  this->data(0x03);
2446  this->data(0x20);
2447  this->data(0x01);
2448  this->data(0xE0);
2449 
2450  // COMMAND DUAL SPI MM_EN, DUSPI_EN
2451  this->command(0x15);
2452  this->data(0x00);
2453 
2454  // COMMAND POWER DRIVER HAT DOWN
2455  // This command will turn off booster, controller, source driver, gate driver, VCOM, and
2456  // temperature sensor, but register data will be kept until VDD turned OFF or Deep Sleep Mode.
2457  // Source/Gate/Border/VCOM will be released to floating.
2458  this->command(0x02);
2459 }
2461  uint32_t buf_len = this->get_buffer_length_();
2462 
2463  // COMMAND POWER ON
2464  ESP_LOGI(TAG, "Power on the display and hat");
2465 
2466  // This command will turn on booster, controller, regulators, and temperature sensor will be
2467  // activated for one-time sensing before enabling booster. When all voltages are ready, the
2468  // BUSY_N signal will return to high.
2469  this->command(0x04);
2470  delay(200); // NOLINT
2471  this->wait_until_idle_();
2472 
2473  // COMMAND DATA START TRANSMISSION NEW DATA
2474  this->command(0x13);
2475  delay(2);
2476  for (uint32_t i = 0; i < buf_len; i++) {
2477  this->data(~(this->buffer_[i]));
2478  }
2479 
2480  delay(100); // NOLINT
2481  this->wait_until_idle_();
2482 
2483  // COMMAND DISPLAY REFRESH
2484  this->command(0x12);
2485  delay(100); // NOLINT
2486  this->wait_until_idle_();
2487 
2488  ESP_LOGV(TAG, "Before command(0x02) (>> power off)");
2489  this->command(0x02);
2490  this->wait_until_idle_();
2491  ESP_LOGV(TAG, "After command(0x02) (>> power off)");
2492 }
2493 
2496 uint32_t WaveshareEPaper7P5InV2::idle_timeout_() { return 10000; }
2498  LOG_DISPLAY("", "Waveshare E-Paper", this);
2499  ESP_LOGCONFIG(TAG, " Model: 7.5inV2rev2");
2500  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2501  LOG_PIN(" DC Pin: ", this->dc_pin_);
2502  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2503  LOG_UPDATE_INTERVAL(this);
2504 }
2505 
2506 /* 7.50inV2alt */
2508  if (this->busy_pin_ == nullptr) {
2509  return true;
2510  }
2511 
2512  const uint32_t start = millis();
2513  while (this->busy_pin_->digital_read()) {
2514  this->command(0x71);
2515  if (millis() - start > this->idle_timeout_()) {
2516  ESP_LOGI(TAG, "Timeout while displaying image!");
2517  return false;
2518  }
2519  delay(10);
2520  }
2521  return true;
2522 }
2523 
2525  this->reset_();
2526 
2527  // COMMAND POWER SETTING
2528  this->command(0x01);
2529 
2530  // 1-0=11: internal power
2531  this->data(0x07);
2532  this->data(0x17); // VGH&VGL
2533  this->data(0x3F); // VSH
2534  this->data(0x26); // VSL
2535  this->data(0x11); // VSHR
2536 
2537  // VCOM DC Setting
2538  this->command(0x82);
2539  this->data(0x24); // VCOM
2540 
2541  // Booster Setting
2542  this->command(0x06);
2543  this->data(0x27);
2544  this->data(0x27);
2545  this->data(0x2F);
2546  this->data(0x17);
2547 
2548  // POWER ON
2549  this->command(0x04);
2550 
2551  delay(100); // NOLINT
2552  this->wait_until_idle_();
2553  // COMMAND PANEL SETTING
2554  this->command(0x00);
2555  this->data(0x3F); // KW-3f KWR-2F BWROTP 0f BWOTP 1f
2556 
2557  // COMMAND RESOLUTION SETTING
2558  this->command(0x61);
2559  this->data(0x03); // source 800
2560  this->data(0x20);
2561  this->data(0x01); // gate 480
2562  this->data(0xE0);
2563  // COMMAND ...?
2564  this->command(0x15);
2565  this->data(0x00);
2566  // COMMAND VCOM AND DATA INTERVAL SETTING
2567  this->command(0x50);
2568  this->data(0x10);
2569  this->data(0x00);
2570  // COMMAND TCON SETTING
2571  this->command(0x60);
2572  this->data(0x22);
2573  // Resolution setting
2574  this->command(0x65);
2575  this->data(0x00);
2576  this->data(0x00); // 800*480
2577  this->data(0x00);
2578  this->data(0x00);
2579 
2580  this->wait_until_idle_();
2581 
2582  uint8_t lut_vcom_7_i_n5_v2[] = {
2583  0x0, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0xF, 0x1, 0xF, 0x1, 0x2, 0x0, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
2584  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2585  };
2586 
2587  uint8_t lut_ww_7_i_n5_v2[] = {
2588  0x10, 0xF, 0xF, 0x0, 0x0, 0x1, 0x84, 0xF, 0x1, 0xF, 0x1, 0x2, 0x20, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
2589  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2590  };
2591 
2592  uint8_t lut_bw_7_i_n5_v2[] = {
2593  0x10, 0xF, 0xF, 0x0, 0x0, 0x1, 0x84, 0xF, 0x1, 0xF, 0x1, 0x2, 0x20, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
2594  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2595  };
2596 
2597  uint8_t lut_wb_7_i_n5_v2[] = {
2598  0x80, 0xF, 0xF, 0x0, 0x0, 0x3, 0x84, 0xF, 0x1, 0xF, 0x1, 0x4, 0x40, 0xF, 0xF, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0,
2599  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2600  };
2601 
2602  uint8_t lut_bb_7_i_n5_v2[] = {
2603  0x80, 0xF, 0xF, 0x0, 0x0, 0x1, 0x84, 0xF, 0x1, 0xF, 0x1, 0x2, 0x40, 0xF, 0xF, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
2604  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2605  };
2606 
2607  uint8_t count;
2608  this->command(0x20); // VCOM
2609  for (count = 0; count < 42; count++)
2610  this->data(lut_vcom_7_i_n5_v2[count]);
2611 
2612  this->command(0x21); // LUTBW
2613  for (count = 0; count < 42; count++)
2614  this->data(lut_ww_7_i_n5_v2[count]);
2615 
2616  this->command(0x22); // LUTBW
2617  for (count = 0; count < 42; count++)
2618  this->data(lut_bw_7_i_n5_v2[count]);
2619 
2620  this->command(0x23); // LUTWB
2621  for (count = 0; count < 42; count++)
2622  this->data(lut_wb_7_i_n5_v2[count]);
2623 
2624  this->command(0x24); // LUTBB
2625  for (count = 0; count < 42; count++)
2626  this->data(lut_bb_7_i_n5_v2[count]);
2627 }
2628 
2630  LOG_DISPLAY("", "Waveshare E-Paper", this);
2631  ESP_LOGCONFIG(TAG, " Model: 7.5inV2");
2632  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2633  LOG_PIN(" DC Pin: ", this->dc_pin_);
2634  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2635  LOG_UPDATE_INTERVAL(this);
2636 }
2637 
2638 /* 7.50in-bc */
2640  /* The command sequence is similar to the 7P5In display but differs in subtle ways
2641  to allow for faster updates. */
2642  // COMMAND POWER SETTING
2643  this->command(0x01);
2644  this->data(0x37);
2645  this->data(0x00);
2646 
2647  // COMMAND PANEL SETTING
2648  this->command(0x00);
2649  this->data(0xCF);
2650  this->data(0x08);
2651 
2652  // COMMAND PLL CONTROL
2653  this->command(0x30);
2654  this->data(0x3A);
2655 
2656  // COMMAND VCM_DC_SETTING: all temperature range
2657  this->command(0x82);
2658  this->data(0x28);
2659 
2660  // COMMAND BOOSTER SOFT START
2661  this->command(0x06);
2662  this->data(0xC7);
2663  this->data(0xCC);
2664  this->data(0x15);
2665 
2666  // COMMAND VCOM AND DATA INTERVAL SETTING
2667  this->command(0x50);
2668  this->data(0x77);
2669 
2670  // COMMAND TCON SETTING
2671  this->command(0x60);
2672  this->data(0x22);
2673 
2674  // COMMAND FLASH CONTROL
2675  this->command(0x65);
2676  this->data(0x00);
2677 
2678  // COMMAND RESOLUTION SETTING
2679  this->command(0x61);
2680  this->data(0x02); // 640 >> 8
2681  this->data(0x80);
2682  this->data(0x01); // 384 >> 8
2683  this->data(0x80);
2684 
2685  // COMMAND FLASH MODE
2686  this->command(0xE5);
2687  this->data(0x03);
2688 }
2689 
2691  // COMMAND DATA START TRANSMISSION 1
2692  this->command(0x10);
2693  this->start_data_();
2694 
2695  for (size_t i = 0; i < this->get_buffer_length_(); i++) {
2696  // A line of eight source pixels (each a bit in this byte)
2697  uint8_t eight_pixels = this->buffer_[i];
2698 
2699  for (uint8_t j = 0; j < 8; j += 2) {
2700  /* For bichromatic displays, each byte represents two pixels. Each nibble encodes a pixel: 0=white, 3=black,
2701  4=color. Therefore, e.g. 0x44 = two adjacent color pixels, 0x33 is two adjacent black pixels, etc. If you want
2702  to draw using the color pixels, change '0x30' with '0x40' and '0x03' with '0x04' below. */
2703  uint8_t left_nibble = (eight_pixels & 0x80) ? 0x30 : 0x00;
2704  eight_pixels <<= 1;
2705  uint8_t right_nibble = (eight_pixels & 0x80) ? 0x03 : 0x00;
2706  eight_pixels <<= 1;
2707  this->write_byte(left_nibble | right_nibble);
2708  }
2709  App.feed_wdt();
2710  }
2711  this->end_data_();
2712 
2713  // Unlike the 7P5In display, we send the "power on" command here rather than during initialization
2714  // COMMAND POWER ON
2715  this->command(0x04);
2716 
2717  // COMMAND DISPLAY REFRESH
2718  this->command(0x12);
2719 }
2720 
2722 
2724 
2726  LOG_DISPLAY("", "Waveshare E-Paper", this);
2727  ESP_LOGCONFIG(TAG, " Model: 7.5in-bc");
2728  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2729  LOG_PIN(" DC Pin: ", this->dc_pin_);
2730  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2731  LOG_UPDATE_INTERVAL(this);
2732 }
2733 
2735  this->command(0x12); // SWRESET
2736 
2737  this->wait_until_idle_(); // waiting for the electronic paper IC to release the idle signal
2738 
2739  this->command(0x46); // Auto Write RAM
2740  this->data(0xF7);
2741 
2742  this->wait_until_idle_(); // waiting for the electronic paper IC to release the idle signal
2743 
2744  this->command(0x47); // Auto Write RAM
2745  this->data(0xF7);
2746 
2747  this->wait_until_idle_(); // waiting for the electronic paper IC to release the idle signal
2748 
2749  this->command(0x0C); // Soft start setting
2750  this->data(0xAE);
2751  this->data(0xC7);
2752  this->data(0xC3);
2753  this->data(0xC0);
2754  this->data(0x40);
2755 
2756  this->command(0x01); // Set MUX as 527
2757  this->data(0xAF);
2758  this->data(0x02);
2759  this->data(0x01);
2760 
2761  this->command(0x11); // Data entry mode
2762  this->data(0x01);
2763 
2764  this->command(0x44);
2765  this->data(0x00); // RAM x address start at 0
2766  this->data(0x00);
2767  this->data(0x6F); // RAM x address end at 36Fh -> 879
2768  this->data(0x03);
2769 
2770  this->command(0x45);
2771  this->data(0xAF); // RAM y address start at 20Fh;
2772  this->data(0x02);
2773  this->data(0x00); // RAM y address end at 00h;
2774  this->data(0x00);
2775 
2776  this->command(0x3C); // VBD
2777  this->data(0x01); // LUT1, for white
2778 
2779  this->command(0x18);
2780  this->data(0X80);
2781 
2782  this->command(0x22);
2783  this->data(0XB1); // Load Temperature and waveform setting.
2784 
2785  this->command(0x20);
2786 
2787  this->wait_until_idle_(); // waiting for the electronic paper IC to release the idle signal
2788 
2789  this->command(0x4E);
2790  this->data(0x00);
2791  this->data(0x00);
2792 
2793  this->command(0x4F);
2794  this->data(0xAF);
2795  this->data(0x02);
2796 }
2797 
2799  this->command(0x4F);
2800  this->data(0xAf);
2801  this->data(0x02);
2802 
2803  // BLACK
2804  this->command(0x24);
2805  this->start_data_();
2806  this->write_array(this->buffer_, this->get_buffer_length_());
2807  this->end_data_();
2808 
2809  // RED
2810  this->command(0x26);
2811  this->start_data_();
2812  for (size_t i = 0; i < this->get_buffer_length_(); i++)
2813  this->write_byte(0x00);
2814  this->end_data_();
2815 
2816  this->command(0x22);
2817  this->data(0xC7);
2818  this->command(0x20);
2819  delay(100); // NOLINT
2820 }
2821 
2823 
2825 
2827  LOG_DISPLAY("", "Waveshare E-Paper", this);
2828  ESP_LOGCONFIG(TAG, " Model: 7.5in-HD-b");
2829  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2830  LOG_PIN(" DC Pin: ", this->dc_pin_);
2831  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2832  LOG_UPDATE_INTERVAL(this);
2833 }
2834 
2835 static const uint8_t LUT_SIZE_TTGO_DKE_PART = 153;
2836 
2837 static const uint8_t PART_UPDATE_LUT_TTGO_DKE[LUT_SIZE_TTGO_DKE_PART] = {
2838  0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2839  0x0, 0x0, 0x0, 0x0, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0,
2840  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2841  0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2842  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2843  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2844  0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
2845  0x0, 0x0, 0x0, 0x0, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
2846  // 0x22, 0x17, 0x41, 0x0, 0x32, 0x32
2847 };
2848 
2851  bool partial = this->at_update_ != 0;
2852  this->at_update_ = (this->at_update_ + 1) % this->full_update_every_;
2853 
2854  if (partial) {
2855  ESP_LOGI(TAG, "Performing partial e-paper update.");
2856  } else {
2857  ESP_LOGI(TAG, "Performing full e-paper update.");
2858  }
2859 
2860  // start and set up data format
2861  this->command(0x12);
2862  this->wait_until_idle_();
2863 
2864  this->command(0x11);
2865  this->data(0x03);
2866  this->command(0x44);
2867  this->data(1);
2868  this->data(this->get_width_internal() / 8);
2869  this->command(0x45);
2870  this->data(0);
2871  this->data(0);
2872  this->data(this->get_height_internal());
2873  this->data(0);
2874  this->command(0x4e);
2875  this->data(1);
2876  this->command(0x4f);
2877  this->data(0);
2878  this->data(0);
2879 
2880  if (!partial) {
2881  // send data
2882  this->command(0x24);
2883  this->start_data_();
2884  this->write_array(this->buffer_, this->get_buffer_length_());
2885  this->end_data_();
2886 
2887  // commit
2888  this->command(0x20);
2889  this->wait_until_idle_();
2890  } else {
2891  // set up partial update
2892  this->command(0x32);
2893  this->start_data_();
2894  this->write_array(PART_UPDATE_LUT_TTGO_DKE, sizeof(PART_UPDATE_LUT_TTGO_DKE));
2895  this->end_data_();
2896  this->command(0x3F);
2897  this->data(0x22);
2898 
2899  this->command(0x03);
2900  this->data(0x17);
2901  this->command(0x04);
2902  this->data(0x41);
2903  this->data(0x00);
2904  this->data(0x32);
2905  this->command(0x2C);
2906  this->data(0x32);
2907 
2908  this->command(0x37);
2909  this->data(0x00);
2910  this->data(0x00);
2911  this->data(0x00);
2912  this->data(0x00);
2913  this->data(0x00);
2914  this->data(0x40);
2915  this->data(0x00);
2916  this->data(0x00);
2917  this->data(0x00);
2918  this->data(0x00);
2919 
2920  this->command(0x3C);
2921  this->data(0x80);
2922  this->command(0x22);
2923  this->data(0xC0);
2924  this->command(0x20);
2925  this->wait_until_idle_();
2926 
2927  // send data
2928  this->command(0x24);
2929  this->start_data_();
2930  this->write_array(this->buffer_, this->get_buffer_length_());
2931  this->end_data_();
2932 
2933  // commit as partial
2934  this->command(0x22);
2935  this->data(0xCF);
2936  this->command(0x20);
2937  this->wait_until_idle_();
2938 
2939  // data must be sent again on partial update
2940  this->command(0x24);
2941  this->start_data_();
2942  this->write_array(this->buffer_, this->get_buffer_length_());
2943  this->end_data_();
2944  }
2945 
2946  ESP_LOGI(TAG, "Completed e-paper update.");
2947 }
2948 
2951 uint32_t WaveshareEPaper2P13InDKE::idle_timeout_() { return 5000; }
2953  LOG_DISPLAY("", "Waveshare E-Paper", this);
2954  ESP_LOGCONFIG(TAG, " Model: 2.13inDKE");
2955  LOG_PIN(" CS Pin: ", this->cs_);
2956  LOG_PIN(" Reset Pin: ", this->reset_pin_);
2957  LOG_PIN(" DC Pin: ", this->dc_pin_);
2958  LOG_PIN(" Busy Pin: ", this->busy_pin_);
2959  LOG_UPDATE_INTERVAL(this);
2960 }
2961 
2962 void WaveshareEPaper2P13InDKE::set_full_update_every(uint32_t full_update_every) {
2963  this->full_update_every_ = full_update_every;
2964 }
2965 
2966 // ========================================================
2967 // 13.3in (K version)
2968 // Datasheet/Specification/Reference:
2969 // - https://files.waveshare.com/wiki/13.3inch-e-Paper-HAT-(K)/13.3-inch-e-Paper-(K)-user-manual.pdf
2970 // - https://github.com/waveshareteam/e-Paper/tree/master/Arduino/epd13in3k
2971 // ========================================================
2972 
2973 // using default wait_until_idle_() function
2975  this->wait_until_idle_();
2976  this->command(0x12); // SWRESET
2977  this->wait_until_idle_();
2978 
2979  this->command(0x0c); // set soft start
2980  this->data(0xae);
2981  this->data(0xc7);
2982  this->data(0xc3);
2983  this->data(0xc0);
2984  this->data(0x80);
2985 
2986  this->command(0x01); // driver output control
2987  this->data((get_height_internal() - 1) % 256); // Y
2988  this->data((get_height_internal() - 1) / 256); // Y
2989  this->data(0x00);
2990 
2991  this->command(0x11); // data entry mode
2992  this->data(0x03);
2993 
2994  // SET WINDOWS
2995  // XRAM_START_AND_END_POSITION
2996  this->command(0x44);
2997  this->data(0 & 0xFF);
2998  this->data((0 >> 8) & 0x03);
2999  this->data((get_width_internal() - 1) & 0xFF);
3000  this->data(((get_width_internal() - 1) >> 8) & 0x03);
3001  // YRAM_START_AND_END_POSITION
3002  this->command(0x45);
3003  this->data(0 & 0xFF);
3004  this->data((0 >> 8) & 0x03);
3005  this->data((get_height_internal() - 1) & 0xFF);
3006  this->data(((get_height_internal() - 1) >> 8) & 0x03);
3007 
3008  this->command(0x3C); // Border setting
3009  this->data(0x01);
3010 
3011  this->command(0x18); // use the internal temperature sensor
3012  this->data(0x80);
3013 
3014  // SET CURSOR
3015  // XRAM_ADDRESS
3016  this->command(0x4E);
3017  this->data(0 & 0xFF);
3018  this->data((0 >> 8) & 0x03);
3019  // YRAM_ADDRESS
3020  this->command(0x4F);
3021  this->data(0 & 0xFF);
3022  this->data((0 >> 8) & 0x03);
3023 }
3025  // do single full update
3026  this->command(0x24);
3027  this->start_data_();
3028  this->write_array(this->buffer_, this->get_buffer_length_());
3029  this->end_data_();
3030 
3031  // COMMAND DISPLAY REFRESH
3032  this->command(0x22);
3033  this->data(0xF7);
3034  this->command(0x20);
3035 }
3036 
3039 uint32_t WaveshareEPaper13P3InK::idle_timeout_() { return 10000; }
3041  LOG_DISPLAY("", "Waveshare E-Paper", this);
3042  ESP_LOGCONFIG(TAG, " Model: 13.3inK");
3043  LOG_PIN(" Reset Pin: ", this->reset_pin_);
3044  LOG_PIN(" DC Pin: ", this->dc_pin_);
3045  LOG_PIN(" Busy Pin: ", this->busy_pin_);
3046  LOG_UPDATE_INTERVAL(this);
3047 }
3048 
3049 } // namespace waveshare_epaper
3050 } // namespace esphome
virtual void digital_write(bool value)=0
void set_full_update_every(uint32_t full_update_every)
int get_width() override
Get the width of the image in pixels with rotation applied.
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
void draw_absolute_pixel_internal(int x, int y, Color color) override
void write_lut_(const uint8_t *lut, uint8_t size)
uint16_t x
Definition: tt21100.cpp:17
void draw_absolute_pixel_internal(int x, int y, Color color) override
T * allocate(size_t n)
Definition: helpers.h:681
void set_full_update_every(uint32_t full_update_every)
void filled_rectangle(int x1, int y1, int width, int height, Color color=COLOR_ON)
Fill a rectangle with the top left point at [x1,y1] and the bottom right point at [x1+width...
Definition: display.cpp:104
GPIOPin * cs_
Definition: spi.h:378
WaveshareEPaperTypeA(WaveshareEPaperTypeAModel model)
virtual void fill(Color color)
Fill the entire screen with the given color.
Definition: display.cpp:15
virtual void setup()=0
bool is_on() ESPHOME_ALWAYS_INLINE
Definition: color.h:46
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
uint16_t y
Definition: tt21100.cpp:18
void init_internal_(uint32_t buffer_length)
virtual int get_height_internal()=0
const char *const TAG
Definition: spi.cpp:8
int get_height() override
Get the height of the image in pixels with rotation applied.
void status_clear_warning()
Definition: component.cpp:166
virtual int get_width_internal()=0
uint8_t green
Definition: color.h:19
const float PROCESSOR
For components that use data from sensors like displays.
Definition: component.cpp:20
Application App
Global storage of Application pointer - only one Application can exist.
virtual bool digital_read()=0
void write_lut_(const uint8_t *lut, uint8_t size)
uint8_t blue
Definition: color.h:23
uint16_t length
Definition: tt21100.cpp:12
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Definition: core.cpp:28
void set_full_update_every(uint32_t full_update_every)
An STL allocator that uses SPI or internal RAM.
Definition: helpers.h:666
void set_full_update_every(uint32_t full_update_every)
void cmd_data(const uint8_t *data, size_t length)
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26
uint8_t red
Definition: color.h:15