epd2in9_V2.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /**
  2. * @filename : epd2in9_V2.cpp
  3. * @brief : Implements for e-paper library
  4. * @author :
  5. *
  6. * Copyright (C) Waveshare Nov 9 2020
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documnetation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdlib.h>
  27. #include "epd2in9_V2.h"
  28. unsigned char _WF_PARTIAL_2IN9[159] =
  29. {
  30. 0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  31. 0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  32. 0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  33. 0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  34. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  35. 0x0A,0x0,0x0,0x0,0x0,0x0,0x2,
  36. 0x1,0x0,0x0,0x0,0x0,0x0,0x0,
  37. 0x1,0x0,0x0,0x0,0x0,0x0,0x0,
  38. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  39. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  40. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  41. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  42. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  43. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  44. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  45. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  46. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  47. 0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
  48. 0x22,0x17,0x41,0xB0,0x32,0x36,
  49. };
  50. unsigned char WS_20_30[159] =
  51. {
  52. 0x80, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0,
  53. 0x10, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0,
  54. 0x80, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0,
  55. 0x10, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0,
  56. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  57. 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x1,
  58. 0xA, 0xA, 0x0, 0xA, 0xA, 0x0, 0x1,
  59. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  60. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  61. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  62. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  63. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  64. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  65. 0x14, 0x8, 0x0, 0x1, 0x0, 0x0, 0x1,
  66. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
  67. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  68. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  69. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x0, 0x0, 0x0,
  70. 0x22, 0x17, 0x41, 0x0, 0x32, 0x36
  71. };
  72. unsigned char Gray4[159] =
  73. {
  74. 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L0 //2.28s
  75. 0x20, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L1
  76. 0x28, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L2
  77. 0x2A, 0x60, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L3
  78. 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L4
  79. 0x00, 0x02, 0x00, 0x05, 0x14, 0x00, 0x00, //TP, SR, RP of Group0
  80. 0x1E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x01, //TP, SR, RP of Group1
  81. 0x00, 0x02, 0x00, 0x05, 0x14, 0x00, 0x00, //TP, SR, RP of Group2
  82. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group3
  83. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group4
  84. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group5
  85. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group6
  86. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group7
  87. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group8
  88. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group9
  89. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group10
  90. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group11
  91. 0x24, 0x22, 0x22, 0x22, 0x23, 0x32, 0x00, 0x00, 0x00, //FR, XON
  92. 0x22, 0x17, 0x41, 0xAE, 0x32, 0x28, //EOPT VGH VSH1 VSH2 VSL VCOM
  93. };
  94. unsigned char WF_FULL[159] =
  95. {
  96. 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L0 1.00S
  97. 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L1
  98. 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L2
  99. 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L3
  100. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //VS L4
  101. 0x19, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group0
  102. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group1
  103. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group2
  104. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group3
  105. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group4
  106. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group5
  107. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group6
  108. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group7
  109. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group8
  110. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group9
  111. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group10
  112. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TP, SR, RP of Group11
  113. 0x24, 0x42, 0x22, 0x22, 0x23, 0x32, 0x00, 0x00, 0x00, //FR, XON
  114. 0x22, 0x17, 0x41, 0xAE, 0x32, 0x38, //EOPT VGH VSH1 VSH2 VSL VCOM
  115. };
  116. Epd::~Epd() {
  117. };
  118. Epd::Epd() {
  119. reset_pin = RST_PIN;
  120. dc_pin = DC_PIN;
  121. cs_pin = CS_PIN;
  122. busy_pin = BUSY_PIN;
  123. width = EPD_WIDTH;
  124. height = EPD_HEIGHT;
  125. };
  126. int Epd::Init() {
  127. /* this calls the peripheral hardware interface, see epdif */
  128. if (IfInit() != 0) {
  129. return -1;
  130. }
  131. Reset();
  132. /* EPD hardware init start */
  133. WaitUntilIdle();
  134. SendCommand(0x12); //SWRESET
  135. WaitUntilIdle();
  136. SendCommand(0x01); //Driver output control
  137. SendData(0x27);
  138. SendData(0x01);
  139. SendData(0x00);
  140. SendCommand(0x11); //data entry mode
  141. SendData(0x03);
  142. SetMemoryArea(0, 0, width-1, height-1);
  143. SendCommand(0x21); // Display update control
  144. SendData(0x00);
  145. SendData(0x80);
  146. SetMemoryPointer(0, 0);
  147. WaitUntilIdle();
  148. SetLut_by_host(WS_20_30);
  149. /* EPD hardware init end */
  150. return 0;
  151. }
  152. int Epd::Init_Fast() {
  153. /* this calls the peripheral hardware interface, see epdif */
  154. if (IfInit() != 0) {
  155. return -1;
  156. }
  157. Reset();
  158. /* EPD hardware init start */
  159. WaitUntilIdle();
  160. SendCommand(0x12); //SWRESET
  161. WaitUntilIdle();
  162. SendCommand(0x01); //Driver output control
  163. SendData(0x27);
  164. SendData(0x01);
  165. SendData(0x00);
  166. SendCommand(0x11); //data entry mode
  167. SendData(0x03);
  168. SetMemoryArea(0, 0, width-1, height-1);
  169. SendCommand(0x3C);
  170. SendData(0x05);
  171. SendCommand(0x21); // Display update control
  172. SendData(0x00);
  173. SendData(0x80);
  174. SetMemoryPointer(0, 0);
  175. WaitUntilIdle();
  176. SetLut_by_host(WF_FULL);
  177. /* EPD hardware init end */
  178. return 0;
  179. }
  180. int Epd::Init_4Gray() {
  181. /* this calls the peripheral hardware interface, see epdif */
  182. if (IfInit() != 0) {
  183. return -1;
  184. }
  185. Reset();
  186. /* EPD hardware init start */
  187. WaitUntilIdle();
  188. SendCommand(0x12); //SWRESET
  189. WaitUntilIdle();
  190. SendCommand(0x01); //Driver output control
  191. SendData(0x27);
  192. SendData(0x01);
  193. SendData(0x00);
  194. SendCommand(0x11); //data entry mode
  195. SendData(0x03);
  196. SetMemoryArea(8, 0, width, height-1);
  197. SendCommand(0x3C);
  198. SendData(0x04);
  199. SetMemoryPointer(8, 0);
  200. WaitUntilIdle();
  201. SetLut_by_host(Gray4);
  202. /* EPD hardware init end */
  203. return 0;
  204. }
  205. /**
  206. * @brief: basic function for sending commands
  207. */
  208. void Epd::SendCommand(unsigned char command) {
  209. DigitalWrite(dc_pin, LOW);
  210. DigitalWrite(cs_pin, LOW);
  211. SpiTransfer(command);
  212. DigitalWrite(cs_pin, HIGH);
  213. }
  214. /**
  215. * @brief: basic function for sending data
  216. */
  217. void Epd::SendData(unsigned char data) {
  218. DigitalWrite(dc_pin, HIGH);
  219. DigitalWrite(cs_pin, LOW);
  220. SpiTransfer(data);
  221. DigitalWrite(cs_pin, HIGH);
  222. }
  223. /**
  224. * @brief: Wait until the busy_pin goes LOW
  225. */
  226. void Epd::WaitUntilIdle(void) {
  227. while(1) { //=1 BUSY
  228. if(DigitalRead(busy_pin)==LOW)
  229. break;
  230. DelayMs(5);
  231. }
  232. DelayMs(5);
  233. }
  234. /**
  235. * @brief: module reset.
  236. * often used to awaken the module in deep sleep,
  237. * see Epd::Sleep();
  238. */
  239. void Epd::Reset(void) {
  240. DigitalWrite(reset_pin, HIGH);
  241. DelayMs(20);
  242. DigitalWrite(reset_pin, LOW); //module reset
  243. DelayMs(5);
  244. DigitalWrite(reset_pin, HIGH);
  245. DelayMs(20);
  246. }
  247. /**
  248. * @brief: put an image buffer to the frame memory.
  249. * this won't update the display.
  250. */
  251. void Epd::SetFrameMemory(
  252. const unsigned char* image_buffer,
  253. int x,
  254. int y,
  255. int image_width,
  256. int image_height
  257. ) {
  258. int x_end;
  259. int y_end;
  260. if (
  261. image_buffer == NULL ||
  262. x < 0 || image_width < 0 ||
  263. y < 0 || image_height < 0
  264. ) {
  265. return;
  266. }
  267. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  268. x &= 0xF8;
  269. image_width &= 0xF8;
  270. if (x + image_width >= this->width) {
  271. x_end = this->width - 1;
  272. } else {
  273. x_end = x + image_width - 1;
  274. }
  275. if (y + image_height >= this->height) {
  276. y_end = this->height - 1;
  277. } else {
  278. y_end = y + image_height - 1;
  279. }
  280. SetMemoryArea(x, y, x_end, y_end);
  281. SetMemoryPointer(x, y);
  282. SendCommand(0x24);
  283. /* send the image data */
  284. for (int j = 0; j < y_end - y + 1; j++) {
  285. for (int i = 0; i < (x_end - x + 1) / 8; i++) {
  286. SendData(image_buffer[i + j * (image_width / 8)]);
  287. }
  288. }
  289. }
  290. void Epd::SetFrameMemory_Partial(
  291. const unsigned char* image_buffer,
  292. int x,
  293. int y,
  294. int image_width,
  295. int image_height
  296. ) {
  297. int x_end;
  298. int y_end;
  299. if (
  300. image_buffer == NULL ||
  301. x < 0 || image_width < 0 ||
  302. y < 0 || image_height < 0
  303. ) {
  304. return;
  305. }
  306. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  307. x &= 0xF8;
  308. image_width &= 0xF8;
  309. if (x + image_width >= this->width) {
  310. x_end = this->width - 1;
  311. } else {
  312. x_end = x + image_width - 1;
  313. }
  314. if (y + image_height >= this->height) {
  315. y_end = this->height - 1;
  316. } else {
  317. y_end = y + image_height - 1;
  318. }
  319. DigitalWrite(reset_pin, LOW);
  320. DelayMs(2);
  321. DigitalWrite(reset_pin, HIGH);
  322. DelayMs(2);
  323. SetLut(_WF_PARTIAL_2IN9);
  324. SendCommand(0x37);
  325. SendData(0x00);
  326. SendData(0x00);
  327. SendData(0x00);
  328. SendData(0x00);
  329. SendData(0x00);
  330. SendData(0x40);
  331. SendData(0x00);
  332. SendData(0x00);
  333. SendData(0x00);
  334. SendData(0x00);
  335. SendCommand(0x3C); //BorderWavefrom
  336. SendData(0x80);
  337. SendCommand(0x22);
  338. SendData(0xC0);
  339. SendCommand(0x20);
  340. WaitUntilIdle();
  341. SetMemoryArea(x, y, x_end, y_end);
  342. SetMemoryPointer(x, y);
  343. SendCommand(0x24);
  344. /* send the image data */
  345. for (int j = 0; j < y_end - y + 1; j++) {
  346. for (int i = 0; i < (x_end - x + 1) / 8; i++) {
  347. SendData(image_buffer[i + j * (image_width / 8)]);
  348. }
  349. }
  350. }
  351. /**
  352. * @brief: put an image buffer to the frame memory.
  353. * this won't update the display.
  354. *
  355. * Question: When do you use this function instead of
  356. * void SetFrameMemory(
  357. * const unsigned char* image_buffer,
  358. * int x,
  359. * int y,
  360. * int image_width,
  361. * int image_height
  362. * );
  363. * Answer: SetFrameMemory with parameters only reads image data
  364. * from the RAM but not from the flash in AVR chips (for AVR chips,
  365. * you have to use the function pgm_read_byte to read buffers
  366. * from the flash).
  367. */
  368. void Epd::SetFrameMemory(const unsigned char* image_buffer) {
  369. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  370. SetMemoryPointer(0, 0);
  371. SendCommand(0x24);
  372. /* send the image data */
  373. for (int i = 0; i < this->width / 8 * this->height; i++) {
  374. SendData(pgm_read_byte(&image_buffer[i]));
  375. }
  376. }
  377. void Epd::SetFrameMemory_Base(const unsigned char* image_buffer) {
  378. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  379. SetMemoryPointer(0, 0);
  380. SendCommand(0x24);
  381. /* send the image data */
  382. for (int i = 0; i < this->width / 8 * this->height; i++) {
  383. SendData(pgm_read_byte(&image_buffer[i]));
  384. }
  385. SendCommand(0x26);
  386. /* send the image data */
  387. for (int i = 0; i < this->width / 8 * this->height; i++) {
  388. SendData(pgm_read_byte(&image_buffer[i]));
  389. }
  390. }
  391. /**
  392. * @brief: clear the frame memory with the specified color.
  393. * this won't update the display.
  394. */
  395. void Epd::ClearFrameMemory(unsigned char color) {
  396. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  397. SetMemoryPointer(0, 0);
  398. SendCommand(0x24);
  399. /* send the color data */
  400. for (int i = 0; i < this->width / 8 * this->height; i++) {
  401. SendData(color);
  402. }
  403. SendCommand(0x26);
  404. /* send the color data */
  405. for (int i = 0; i < this->width / 8 * this->height; i++) {
  406. SendData(color);
  407. }
  408. }
  409. void Epd::Display4Gray(const unsigned char *Image)
  410. {
  411. int i,j,k;
  412. unsigned char temp1,temp2,temp3;
  413. SendCommand(0x24);
  414. for(i=0;i<4736;i++)
  415. {
  416. temp3=0;
  417. for(j=0;j<2;j++)
  418. {
  419. temp1 = pgm_read_byte(&Image[i*2+j]);
  420. for(k=0;k<2;k++)
  421. {
  422. temp2 = temp1&0xC0 ;
  423. if(temp2 == 0xC0)
  424. temp3 |= 0x00;//white
  425. else if(temp2 == 0x00)
  426. temp3 |= 0x01; //black
  427. else if(temp2 == 0x80)
  428. temp3 |= 0x01; //gray1
  429. else //0x40
  430. temp3 |= 0x00; //gray2
  431. temp3 <<= 1;
  432. temp1 <<= 2;
  433. temp2 = temp1&0xC0 ;
  434. if(temp2 == 0xC0) //white
  435. temp3 |= 0x00;
  436. else if(temp2 == 0x00) //black
  437. temp3 |= 0x01;
  438. else if(temp2 == 0x80)
  439. temp3 |= 0x01; //gray1
  440. else //0x40
  441. temp3 |= 0x00; //gray2
  442. if(j!=1 || k!=1)
  443. temp3 <<= 1;
  444. temp1 <<= 2;
  445. }
  446. }
  447. SendData(temp3);
  448. }
  449. // new data
  450. SendCommand(0x26);
  451. for(i=0;i<4736;i++)
  452. {
  453. temp3=0;
  454. for(j=0;j<2;j++)
  455. {
  456. temp1 = pgm_read_byte(&Image[i*2+j]);
  457. for(k=0;k<2;k++)
  458. {
  459. temp2 = temp1&0xC0 ;
  460. if(temp2 == 0xC0)
  461. temp3 |= 0x00;//white
  462. else if(temp2 == 0x00)
  463. temp3 |= 0x01; //black
  464. else if(temp2 == 0x80)
  465. temp3 |= 0x00; //gray1
  466. else //0x40
  467. temp3 |= 0x01; //gray2
  468. temp3 <<= 1;
  469. temp1 <<= 2;
  470. temp2 = temp1&0xC0 ;
  471. if(temp2 == 0xC0) //white
  472. temp3 |= 0x00;
  473. else if(temp2 == 0x00) //black
  474. temp3 |= 0x01;
  475. else if(temp2 == 0x80)
  476. temp3 |= 0x00; //gray1
  477. else //0x40
  478. temp3 |= 0x01; //gray2
  479. if(j!=1 || k!=1)
  480. temp3 <<= 1;
  481. temp1 <<= 2;
  482. }
  483. }
  484. SendData(temp3);
  485. }
  486. DisplayFrame();
  487. }
  488. /**
  489. * @brief: update the display
  490. * there are 2 memory areas embedded in the e-paper display
  491. * but once this function is called,
  492. * the the next action of SetFrameMemory or ClearFrame will
  493. * set the other memory area.
  494. */
  495. void Epd::DisplayFrame(void) {
  496. SendCommand(0x22);
  497. SendData(0xc7);
  498. SendCommand(0x20);
  499. WaitUntilIdle();
  500. }
  501. void Epd::DisplayFrame_Partial(void) {
  502. SendCommand(0x22);
  503. SendData(0x0F);
  504. SendCommand(0x20);
  505. WaitUntilIdle();
  506. }
  507. void Epd::SetLut(unsigned char *lut) {
  508. unsigned char count;
  509. SendCommand(0x32);
  510. for(count=0; count<153; count++)
  511. SendData(lut[count]);
  512. WaitUntilIdle();
  513. }
  514. void Epd::SetLut_by_host(unsigned char *lut) {
  515. SetLut((unsigned char *)lut);
  516. SendCommand(0x3f);
  517. SendData(*(lut+153));
  518. SendCommand(0x03); // gate voltage
  519. SendData(*(lut+154));
  520. SendCommand(0x04); // source voltage
  521. SendData(*(lut+155)); // VSH
  522. SendData(*(lut+156)); // VSH2
  523. SendData(*(lut+157)); // VSL
  524. SendCommand(0x2c); // VCOM
  525. SendData(*(lut+158));
  526. }
  527. /**
  528. * @brief: private function to specify the memory area for data R/W
  529. */
  530. void Epd::SetMemoryArea(int x_start, int y_start, int x_end, int y_end) {
  531. SendCommand(0x44);
  532. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  533. SendData((x_start >> 3) & 0xFF);
  534. SendData((x_end >> 3) & 0xFF);
  535. SendCommand(0x45);
  536. SendData(y_start & 0xFF);
  537. SendData((y_start >> 8) & 0xFF);
  538. SendData(y_end & 0xFF);
  539. SendData((y_end >> 8) & 0xFF);
  540. }
  541. /**
  542. * @brief: private function to specify the start point for data R/W
  543. */
  544. void Epd::SetMemoryPointer(int x, int y) {
  545. SendCommand(0x4E);
  546. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  547. SendData((x >> 3) & 0xFF);
  548. SendCommand(0x4F);
  549. SendData(y & 0xFF);
  550. SendData((y >> 8) & 0xFF);
  551. WaitUntilIdle();
  552. }
  553. /**
  554. * @brief: After this command is transmitted, the chip would enter the
  555. * deep-sleep mode to save power.
  556. * The deep sleep mode would return to standby by hardware reset.
  557. * You can use Epd::Init() to awaken
  558. */
  559. void Epd::Sleep() {
  560. SendCommand(0x10);
  561. SendData(0x01);
  562. // WaitUntilIdle();
  563. }
  564. /* END OF FILE */