GxEPD2_EPD.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
  2. // Requires HW SPI and Adafruit_GFX. Caution: these e-papers require 3.3V supply AND data lines!
  3. //
  4. // based on Demo Example from Good Display: http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
  5. //
  6. // Author: Jean-Marc Zingg
  7. //
  8. // Version: see library.properties
  9. //
  10. // Library: https://github.com/ZinggJM/GxEPD2
  11. #include "GxEPD2_EPD.h"
  12. #if defined(ESP8266) || defined(ESP32)
  13. #include <pgmspace.h>
  14. #else
  15. #include <avr/pgmspace.h>
  16. #endif
  17. GxEPD2_EPD::GxEPD2_EPD(int8_t cs, int8_t dc, int8_t rst, int8_t busy, int8_t busy_level, uint32_t busy_timeout,
  18. uint16_t w, uint16_t h, GxEPD2::Panel p, bool c, bool pu, bool fpu) :
  19. WIDTH(w), HEIGHT(h), panel(p), hasColor(c), hasPartialUpdate(pu), hasFastPartialUpdate(fpu),
  20. _cs(cs), _dc(dc), _rst(rst), _busy(busy), _busy_level(busy_level), _busy_timeout(busy_timeout), _diag_enabled(false),
  21. _spi_settings(4000000, MSBFIRST, SPI_MODE0)
  22. {
  23. _initial_write = true;
  24. _initial_refresh = true;
  25. _power_is_on = false;
  26. _using_partial_mode = false;
  27. _hibernating = false;
  28. }
  29. void GxEPD2_EPD::init(uint32_t serial_diag_bitrate)
  30. {
  31. init(serial_diag_bitrate, true, false);
  32. }
  33. void GxEPD2_EPD::init(uint32_t serial_diag_bitrate, bool initial, bool pulldown_rst_mode)
  34. {
  35. _initial_write = initial;
  36. _initial_refresh = initial;
  37. _pulldown_rst_mode = pulldown_rst_mode;
  38. _power_is_on = false;
  39. _using_partial_mode = false;
  40. _hibernating = false;
  41. if (serial_diag_bitrate > 0)
  42. {
  43. Serial.begin(serial_diag_bitrate);
  44. _diag_enabled = true;
  45. }
  46. if (_cs >= 0)
  47. {
  48. digitalWrite(_cs, HIGH);
  49. pinMode(_cs, OUTPUT);
  50. }
  51. if (_dc >= 0)
  52. {
  53. digitalWrite(_dc, HIGH);
  54. pinMode(_dc, OUTPUT);
  55. }
  56. _reset();
  57. if (_busy >= 0)
  58. {
  59. pinMode(_busy, INPUT);
  60. }
  61. SPI.begin();
  62. }
  63. void GxEPD2_EPD::_reset()
  64. {
  65. if (_rst >= 0)
  66. {
  67. if (_pulldown_rst_mode)
  68. {
  69. digitalWrite(_rst, LOW);
  70. pinMode(_rst, OUTPUT);
  71. delay(20);
  72. pinMode(_rst, INPUT_PULLUP);
  73. delay(200);
  74. }
  75. else
  76. {
  77. digitalWrite(_rst, HIGH);
  78. pinMode(_rst, OUTPUT);
  79. delay(20);
  80. digitalWrite(_rst, LOW);
  81. delay(20);
  82. digitalWrite(_rst, HIGH);
  83. delay(200);
  84. }
  85. _hibernating = false;
  86. }
  87. }
  88. void GxEPD2_EPD::_waitWhileBusy(const char* comment, uint16_t busy_time)
  89. {
  90. if (_busy >= 0)
  91. {
  92. delay(1); // add some margin to become active
  93. unsigned long start = micros();
  94. while (1)
  95. {
  96. if (digitalRead(_busy) != _busy_level) break;
  97. delay(1);
  98. if (micros() - start > _busy_timeout)
  99. {
  100. Serial.println("Busy Timeout!");
  101. break;
  102. }
  103. }
  104. if (comment)
  105. {
  106. #if !defined(DISABLE_DIAGNOSTIC_OUTPUT)
  107. if (_diag_enabled)
  108. {
  109. unsigned long elapsed = micros() - start;
  110. Serial.print(comment);
  111. Serial.print(" : ");
  112. Serial.println(elapsed);
  113. }
  114. #endif
  115. }
  116. (void) start;
  117. }
  118. else delay(busy_time);
  119. }
  120. void GxEPD2_EPD::_writeCommand(uint8_t c)
  121. {
  122. SPI.beginTransaction(_spi_settings);
  123. if (_dc >= 0) digitalWrite(_dc, LOW);
  124. if (_cs >= 0) digitalWrite(_cs, LOW);
  125. SPI.transfer(c);
  126. if (_cs >= 0) digitalWrite(_cs, HIGH);
  127. if (_dc >= 0) digitalWrite(_dc, HIGH);
  128. SPI.endTransaction();
  129. }
  130. void GxEPD2_EPD::_writeData(uint8_t d)
  131. {
  132. SPI.beginTransaction(_spi_settings);
  133. if (_cs >= 0) digitalWrite(_cs, LOW);
  134. SPI.transfer(d);
  135. if (_cs >= 0) digitalWrite(_cs, HIGH);
  136. SPI.endTransaction();
  137. }
  138. void GxEPD2_EPD::_writeData(const uint8_t* data, uint16_t n)
  139. {
  140. SPI.beginTransaction(_spi_settings);
  141. if (_cs >= 0) digitalWrite(_cs, LOW);
  142. for (uint16_t i = 0; i < n; i++)
  143. {
  144. SPI.transfer(*data++);
  145. }
  146. if (_cs >= 0) digitalWrite(_cs, HIGH);
  147. SPI.endTransaction();
  148. }
  149. void GxEPD2_EPD::_writeDataPGM(const uint8_t* data, uint16_t n, int16_t fill_with_zeroes)
  150. {
  151. SPI.beginTransaction(_spi_settings);
  152. if (_cs >= 0) digitalWrite(_cs, LOW);
  153. for (uint16_t i = 0; i < n; i++)
  154. {
  155. SPI.transfer(pgm_read_byte(&*data++));
  156. }
  157. while (fill_with_zeroes > 0)
  158. {
  159. SPI.transfer(0x00);
  160. fill_with_zeroes--;
  161. }
  162. if (_cs >= 0) digitalWrite(_cs, HIGH);
  163. SPI.endTransaction();
  164. }
  165. void GxEPD2_EPD::_writeDataPGM_sCS(const uint8_t* data, uint16_t n, int16_t fill_with_zeroes)
  166. {
  167. SPI.beginTransaction(_spi_settings);
  168. for (uint8_t i = 0; i < n; i++)
  169. {
  170. if (_cs >= 0) digitalWrite(_cs, LOW);
  171. SPI.transfer(pgm_read_byte(&*data++));
  172. if (_cs >= 0) digitalWrite(_cs, HIGH);
  173. }
  174. while (fill_with_zeroes > 0)
  175. {
  176. if (_cs >= 0) digitalWrite(_cs, LOW);
  177. SPI.transfer(0x00);
  178. fill_with_zeroes--;
  179. if (_cs >= 0) digitalWrite(_cs, HIGH);
  180. }
  181. SPI.endTransaction();
  182. }
  183. void GxEPD2_EPD::_writeCommandData(const uint8_t* pCommandData, uint8_t datalen)
  184. {
  185. SPI.beginTransaction(_spi_settings);
  186. if (_dc >= 0) digitalWrite(_dc, LOW);
  187. if (_cs >= 0) digitalWrite(_cs, LOW);
  188. SPI.transfer(*pCommandData++);
  189. if (_dc >= 0) digitalWrite(_dc, HIGH);
  190. for (uint8_t i = 0; i < datalen - 1; i++) // sub the command
  191. {
  192. SPI.transfer(*pCommandData++);
  193. }
  194. if (_cs >= 0) digitalWrite(_cs, HIGH);
  195. SPI.endTransaction();
  196. }
  197. void GxEPD2_EPD::_writeCommandDataPGM(const uint8_t* pCommandData, uint8_t datalen)
  198. {
  199. SPI.beginTransaction(_spi_settings);
  200. if (_dc >= 0) digitalWrite(_dc, LOW);
  201. if (_cs >= 0) digitalWrite(_cs, LOW);
  202. SPI.transfer(pgm_read_byte(&*pCommandData++));
  203. if (_dc >= 0) digitalWrite(_dc, HIGH);
  204. for (uint8_t i = 0; i < datalen - 1; i++) // sub the command
  205. {
  206. SPI.transfer(pgm_read_byte(&*pCommandData++));
  207. }
  208. if (_cs >= 0) digitalWrite(_cs, HIGH);
  209. SPI.endTransaction();
  210. }
  211. void GxEPD2_EPD::_startTransfer()
  212. {
  213. SPI.beginTransaction(_spi_settings);
  214. if (_cs >= 0) digitalWrite(_cs, LOW);
  215. }
  216. void GxEPD2_EPD::_transfer(uint8_t value)
  217. {
  218. SPI.transfer(value);
  219. }
  220. void GxEPD2_EPD::_endTransfer()
  221. {
  222. if (_cs >= 0) digitalWrite(_cs, HIGH);
  223. SPI.endTransaction();
  224. }