epd2in9_V2.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  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. Epd::~Epd() {
  95. };
  96. Epd::Epd() {
  97. reset_pin = RST_PIN;
  98. dc_pin = DC_PIN;
  99. cs_pin = CS_PIN;
  100. busy_pin = BUSY_PIN;
  101. width = EPD_WIDTH;
  102. height = EPD_HEIGHT;
  103. };
  104. int Epd::Init() {
  105. /* this calls the peripheral hardware interface, see epdif */
  106. if (IfInit() != 0) {
  107. return -1;
  108. }
  109. Reset();
  110. /* EPD hardware init start */
  111. WaitUntilIdle();
  112. SendCommand(0x12); //SWRESET
  113. WaitUntilIdle();
  114. SendCommand(0x01); //Driver output control
  115. SendData(0x27);
  116. SendData(0x01);
  117. SendData(0x00);
  118. SendCommand(0x11); //data entry mode
  119. SendData(0x03);
  120. SetMemoryArea(0, 0, width-1, height-1);
  121. SendCommand(0x21); // Display update control
  122. SendData(0x00);
  123. SendData(0x80);
  124. SetMemoryPointer(0, 0);
  125. WaitUntilIdle();
  126. SetLut_by_host(WS_20_30);
  127. /* EPD hardware init end */
  128. return 0;
  129. }
  130. int Epd::Init_4Gray() {
  131. /* this calls the peripheral hardware interface, see epdif */
  132. if (IfInit() != 0) {
  133. return -1;
  134. }
  135. Reset();
  136. /* EPD hardware init start */
  137. WaitUntilIdle();
  138. SendCommand(0x12); //SWRESET
  139. WaitUntilIdle();
  140. SendCommand(0x01); //Driver output control
  141. SendData(0x27);
  142. SendData(0x01);
  143. SendData(0x00);
  144. SendCommand(0x11); //data entry mode
  145. SendData(0x03);
  146. SetMemoryArea(8, 0, width, height-1);
  147. SendCommand(0x3C);
  148. SendData(0x04);
  149. SetMemoryPointer(8, 0);
  150. WaitUntilIdle();
  151. SetLut_by_host(Gray4);
  152. /* EPD hardware init end */
  153. return 0;
  154. }
  155. /**
  156. * @brief: basic function for sending commands
  157. */
  158. void Epd::SendCommand(unsigned char command) {
  159. DigitalWrite(dc_pin, LOW);
  160. DigitalWrite(cs_pin, LOW);
  161. SpiTransfer(command);
  162. DigitalWrite(cs_pin, HIGH);
  163. }
  164. /**
  165. * @brief: basic function for sending data
  166. */
  167. void Epd::SendData(unsigned char data) {
  168. DigitalWrite(dc_pin, HIGH);
  169. DigitalWrite(cs_pin, LOW);
  170. SpiTransfer(data);
  171. DigitalWrite(cs_pin, HIGH);
  172. }
  173. /**
  174. * @brief: Wait until the busy_pin goes LOW
  175. */
  176. void Epd::WaitUntilIdle(void) {
  177. while(1) { //=1 BUSY
  178. if(DigitalRead(busy_pin)==LOW)
  179. break;
  180. DelayMs(5);
  181. }
  182. DelayMs(5);
  183. }
  184. /**
  185. * @brief: module reset.
  186. * often used to awaken the module in deep sleep,
  187. * see Epd::Sleep();
  188. */
  189. void Epd::Reset(void) {
  190. DigitalWrite(reset_pin, HIGH);
  191. DelayMs(20);
  192. DigitalWrite(reset_pin, LOW); //module reset
  193. DelayMs(5);
  194. DigitalWrite(reset_pin, HIGH);
  195. DelayMs(20);
  196. }
  197. /**
  198. * @brief: put an image buffer to the frame memory.
  199. * this won't update the display.
  200. */
  201. void Epd::SetFrameMemory(
  202. const unsigned char* image_buffer,
  203. int x,
  204. int y,
  205. int image_width,
  206. int image_height
  207. ) {
  208. int x_end;
  209. int y_end;
  210. if (
  211. image_buffer == NULL ||
  212. x < 0 || image_width < 0 ||
  213. y < 0 || image_height < 0
  214. ) {
  215. return;
  216. }
  217. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  218. x &= 0xF8;
  219. image_width &= 0xF8;
  220. if (x + image_width >= this->width) {
  221. x_end = this->width - 1;
  222. } else {
  223. x_end = x + image_width - 1;
  224. }
  225. if (y + image_height >= this->height) {
  226. y_end = this->height - 1;
  227. } else {
  228. y_end = y + image_height - 1;
  229. }
  230. SetMemoryArea(x, y, x_end, y_end);
  231. SetMemoryPointer(x, y);
  232. SendCommand(0x24);
  233. /* send the image data */
  234. for (int j = 0; j < y_end - y + 1; j++) {
  235. for (int i = 0; i < (x_end - x + 1) / 8; i++) {
  236. SendData(image_buffer[i + j * (image_width / 8)]);
  237. }
  238. }
  239. }
  240. void Epd::SetFrameMemory_Partial(
  241. const unsigned char* image_buffer,
  242. int x,
  243. int y,
  244. int image_width,
  245. int image_height
  246. ) {
  247. int x_end;
  248. int y_end;
  249. if (
  250. image_buffer == NULL ||
  251. x < 0 || image_width < 0 ||
  252. y < 0 || image_height < 0
  253. ) {
  254. return;
  255. }
  256. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  257. x &= 0xF8;
  258. image_width &= 0xF8;
  259. if (x + image_width >= this->width) {
  260. x_end = this->width - 1;
  261. } else {
  262. x_end = x + image_width - 1;
  263. }
  264. if (y + image_height >= this->height) {
  265. y_end = this->height - 1;
  266. } else {
  267. y_end = y + image_height - 1;
  268. }
  269. DigitalWrite(reset_pin, LOW);
  270. DelayMs(2);
  271. DigitalWrite(reset_pin, HIGH);
  272. DelayMs(2);
  273. SetLut(_WF_PARTIAL_2IN9);
  274. SendCommand(0x37);
  275. SendData(0x00);
  276. SendData(0x00);
  277. SendData(0x00);
  278. SendData(0x00);
  279. SendData(0x00);
  280. SendData(0x40);
  281. SendData(0x00);
  282. SendData(0x00);
  283. SendData(0x00);
  284. SendData(0x00);
  285. SendCommand(0x3C); //BorderWavefrom
  286. SendData(0x80);
  287. SendCommand(0x22);
  288. SendData(0xC0);
  289. SendCommand(0x20);
  290. WaitUntilIdle();
  291. SetMemoryArea(x, y, x_end, y_end);
  292. SetMemoryPointer(x, y);
  293. SendCommand(0x24);
  294. /* send the image data */
  295. for (int j = 0; j < y_end - y + 1; j++) {
  296. for (int i = 0; i < (x_end - x + 1) / 8; i++) {
  297. SendData(image_buffer[i + j * (image_width / 8)]);
  298. }
  299. }
  300. }
  301. /**
  302. * @brief: put an image buffer to the frame memory.
  303. * this won't update the display.
  304. *
  305. * Question: When do you use this function instead of
  306. * void SetFrameMemory(
  307. * const unsigned char* image_buffer,
  308. * int x,
  309. * int y,
  310. * int image_width,
  311. * int image_height
  312. * );
  313. * Answer: SetFrameMemory with parameters only reads image data
  314. * from the RAM but not from the flash in AVR chips (for AVR chips,
  315. * you have to use the function pgm_read_byte to read buffers
  316. * from the flash).
  317. */
  318. void Epd::SetFrameMemory(const unsigned char* image_buffer) {
  319. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  320. SetMemoryPointer(0, 0);
  321. SendCommand(0x24);
  322. /* send the image data */
  323. for (int i = 0; i < this->width / 8 * this->height; i++) {
  324. SendData(pgm_read_byte(&image_buffer[i]));
  325. }
  326. }
  327. void Epd::SetFrameMemory_Base(const unsigned char* image_buffer) {
  328. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  329. SetMemoryPointer(0, 0);
  330. SendCommand(0x24);
  331. /* send the image data */
  332. for (int i = 0; i < this->width / 8 * this->height; i++) {
  333. SendData(pgm_read_byte(&image_buffer[i]));
  334. }
  335. SendCommand(0x26);
  336. /* send the image data */
  337. for (int i = 0; i < this->width / 8 * this->height; i++) {
  338. SendData(pgm_read_byte(&image_buffer[i]));
  339. }
  340. }
  341. /**
  342. * @brief: clear the frame memory with the specified color.
  343. * this won't update the display.
  344. */
  345. void Epd::ClearFrameMemory(unsigned char color) {
  346. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  347. SetMemoryPointer(0, 0);
  348. SendCommand(0x24);
  349. /* send the color data */
  350. for (int i = 0; i < this->width / 8 * this->height; i++) {
  351. SendData(color);
  352. }
  353. SendCommand(0x26);
  354. /* send the color data */
  355. for (int i = 0; i < this->width / 8 * this->height; i++) {
  356. SendData(color);
  357. }
  358. }
  359. void Epd::Display4Gray(const unsigned char *Image)
  360. {
  361. int i,j,k;
  362. unsigned char temp1,temp2,temp3;
  363. SendCommand(0x24);
  364. for(i=0;i<4736;i++)
  365. {
  366. temp3=0;
  367. for(j=0;j<2;j++)
  368. {
  369. temp1 = pgm_read_byte(&Image[i*2+j]);
  370. for(k=0;k<2;k++)
  371. {
  372. temp2 = temp1&0xC0 ;
  373. if(temp2 == 0xC0)
  374. temp3 |= 0x00;//white
  375. else if(temp2 == 0x00)
  376. temp3 |= 0x01; //black
  377. else if(temp2 == 0x80)
  378. temp3 |= 0x01; //gray1
  379. else //0x40
  380. temp3 |= 0x00; //gray2
  381. temp3 <<= 1;
  382. temp1 <<= 2;
  383. temp2 = temp1&0xC0 ;
  384. if(temp2 == 0xC0) //white
  385. temp3 |= 0x00;
  386. else if(temp2 == 0x00) //black
  387. temp3 |= 0x01;
  388. else if(temp2 == 0x80)
  389. temp3 |= 0x01; //gray1
  390. else //0x40
  391. temp3 |= 0x00; //gray2
  392. if(j!=1 || k!=1)
  393. temp3 <<= 1;
  394. temp1 <<= 2;
  395. }
  396. }
  397. SendData(temp3);
  398. }
  399. // new data
  400. SendCommand(0x26);
  401. for(i=0;i<4736;i++)
  402. {
  403. temp3=0;
  404. for(j=0;j<2;j++)
  405. {
  406. temp1 = pgm_read_byte(&Image[i*2+j]);
  407. for(k=0;k<2;k++)
  408. {
  409. temp2 = temp1&0xC0 ;
  410. if(temp2 == 0xC0)
  411. temp3 |= 0x00;//white
  412. else if(temp2 == 0x00)
  413. temp3 |= 0x01; //black
  414. else if(temp2 == 0x80)
  415. temp3 |= 0x00; //gray1
  416. else //0x40
  417. temp3 |= 0x01; //gray2
  418. temp3 <<= 1;
  419. temp1 <<= 2;
  420. temp2 = temp1&0xC0 ;
  421. if(temp2 == 0xC0) //white
  422. temp3 |= 0x00;
  423. else if(temp2 == 0x00) //black
  424. temp3 |= 0x01;
  425. else if(temp2 == 0x80)
  426. temp3 |= 0x00; //gray1
  427. else //0x40
  428. temp3 |= 0x01; //gray2
  429. if(j!=1 || k!=1)
  430. temp3 <<= 1;
  431. temp1 <<= 2;
  432. }
  433. }
  434. SendData(temp3);
  435. }
  436. DisplayFrame();
  437. }
  438. /**
  439. * @brief: update the display
  440. * there are 2 memory areas embedded in the e-paper display
  441. * but once this function is called,
  442. * the the next action of SetFrameMemory or ClearFrame will
  443. * set the other memory area.
  444. */
  445. void Epd::DisplayFrame(void) {
  446. SendCommand(0x22);
  447. SendData(0xc7);
  448. SendCommand(0x20);
  449. WaitUntilIdle();
  450. }
  451. void Epd::DisplayFrame_Partial(void) {
  452. SendCommand(0x22);
  453. SendData(0x0F);
  454. SendCommand(0x20);
  455. WaitUntilIdle();
  456. }
  457. void Epd::SetLut(unsigned char *lut) {
  458. unsigned char count;
  459. SendCommand(0x32);
  460. for(count=0; count<153; count++)
  461. SendData(lut[count]);
  462. WaitUntilIdle();
  463. }
  464. void Epd::SetLut_by_host(unsigned char *lut) {
  465. SetLut((unsigned char *)lut);
  466. SendCommand(0x3f);
  467. SendData(*(lut+153));
  468. SendCommand(0x03); // gate voltage
  469. SendData(*(lut+154));
  470. SendCommand(0x04); // source voltage
  471. SendData(*(lut+155)); // VSH
  472. SendData(*(lut+156)); // VSH2
  473. SendData(*(lut+157)); // VSL
  474. SendCommand(0x2c); // VCOM
  475. SendData(*(lut+158));
  476. }
  477. /**
  478. * @brief: private function to specify the memory area for data R/W
  479. */
  480. void Epd::SetMemoryArea(int x_start, int y_start, int x_end, int y_end) {
  481. SendCommand(0x44);
  482. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  483. SendData((x_start >> 3) & 0xFF);
  484. SendData((x_end >> 3) & 0xFF);
  485. SendCommand(0x45);
  486. SendData(y_start & 0xFF);
  487. SendData((y_start >> 8) & 0xFF);
  488. SendData(y_end & 0xFF);
  489. SendData((y_end >> 8) & 0xFF);
  490. }
  491. /**
  492. * @brief: private function to specify the start point for data R/W
  493. */
  494. void Epd::SetMemoryPointer(int x, int y) {
  495. SendCommand(0x4E);
  496. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  497. SendData((x >> 3) & 0xFF);
  498. SendCommand(0x4F);
  499. SendData(y & 0xFF);
  500. SendData((y >> 8) & 0xFF);
  501. WaitUntilIdle();
  502. }
  503. /**
  504. * @brief: After this command is transmitted, the chip would enter the
  505. * deep-sleep mode to save power.
  506. * The deep sleep mode would return to standby by hardware reset.
  507. * You can use Epd::Init() to awaken
  508. */
  509. void Epd::Sleep() {
  510. SendCommand(0x10);
  511. SendData(0x01);
  512. // WaitUntilIdle();
  513. }
  514. /* END OF FILE */