epd1in54_V2.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. /*****************************************************************************
  2. * | File : epd1in54_V2.cpp
  3. * | Author : Waveshare team
  4. * | Function : 1.54inch e-paper V2
  5. * | Info :
  6. *----------------
  7. * | This version: V1.0
  8. * | Date : 2019-06-24
  9. * | Info :
  10. #
  11. # Permission is hereby granted, free of charge, to any person obtaining a copy
  12. # of this software and associated documnetation files (the "Software"), to deal
  13. # in the Software without restriction, including without limitation the rights
  14. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. # copies of the Software, and to permit persons to whom the Software is
  16. # furished to do so, subject to the following conditions:
  17. #
  18. # The above copyright notice and this permission notice shall be included in
  19. # all copies or substantial portions of the Software.
  20. #
  21. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  27. # THE SOFTWARE.
  28. #
  29. ******************************************************************************/
  30. #include <stdlib.h>
  31. #include "epd1in54_V2.h"
  32. // waveform full refresh
  33. unsigned char WF_Full_1IN54[159] =
  34. {
  35. 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  36. 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  37. 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  38. 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  39. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  40. 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  41. 0x8, 0x1, 0x0, 0x8, 0x1, 0x0, 0x2,
  42. 0xA, 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. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  48. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  49. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  50. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  51. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  52. 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
  53. 0x22, 0x17, 0x41, 0x0, 0x32, 0x20
  54. };
  55. // waveform partial refresh(fast)
  56. unsigned char WF_PARTIAL_1IN54_0[159] =
  57. {
  58. 0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  59. 0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  60. 0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  61. 0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  62. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  63. 0xF,0x0,0x0,0x0,0x0,0x0,0x0,
  64. 0x1,0x1,0x0,0x0,0x0,0x0,0x0,
  65. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  66. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  67. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  68. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  69. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  70. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  71. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  72. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  73. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  74. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  75. 0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
  76. 0x02,0x17,0x41,0xB0,0x32,0x28,
  77. };
  78. // waveform partial refresh(quality)
  79. // unsigned char WF_PARTIAL_1IN54_1[159] =
  80. // {
  81. // 0x0,0x00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  82. // 0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  83. // 0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  84. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  85. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  86. // 0xA,0x0,0x0,0x0,0x0,0x0,0x1,
  87. // 0x1,0x0,0x0,0x0,0x0,0x0,0x0,
  88. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  89. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  90. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  91. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  92. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  93. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  94. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  95. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  96. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  97. // 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  98. // 0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
  99. // 0x22,0x17,0x41,0x0,0x32,0x20,
  100. // };
  101. Epd::~Epd()
  102. {
  103. };
  104. Epd::Epd()
  105. {
  106. reset_pin = RST_PIN;
  107. dc_pin = DC_PIN;
  108. cs_pin = CS_PIN;
  109. busy_pin = BUSY_PIN;
  110. width = EPD_WIDTH;
  111. height = EPD_HEIGHT;
  112. };
  113. /**
  114. * @brief: basic function for sending commands
  115. */
  116. void Epd::SendCommand(unsigned char command)
  117. {
  118. DigitalWrite(dc_pin, LOW);
  119. SpiTransfer(command);
  120. }
  121. /**
  122. * @brief: basic function for sending data
  123. */
  124. void Epd::SendData(unsigned char data)
  125. {
  126. DigitalWrite(dc_pin, HIGH);
  127. SpiTransfer(data);
  128. }
  129. /**
  130. * @brief: Wait until the busy_pin goes HIGH
  131. */
  132. void Epd::WaitUntilIdle(void)
  133. {
  134. while(DigitalRead(busy_pin) == 1) { //LOW: idle, HIGH: busy
  135. DelayMs(100);
  136. }
  137. DelayMs(200);
  138. }
  139. void Epd::Lut(unsigned char* lut)
  140. {
  141. SendCommand(0x32);
  142. for(unsigned char i=0; i<153; i++)
  143. SendData(lut[i]);
  144. WaitUntilIdle();
  145. }
  146. void Epd::SetLut(unsigned char* lut)
  147. {
  148. Lut(lut);
  149. SendCommand(0x3f);
  150. SendData(lut[153]);
  151. SendCommand(0x03);
  152. SendData(lut[154]);
  153. SendCommand(0x04);
  154. SendData(lut[155]);
  155. SendData(lut[156]);
  156. SendData(lut[157]);
  157. SendCommand(0x2c);
  158. SendData(lut[158]);
  159. }
  160. // High Direction
  161. int Epd::HDirInit(void)
  162. {
  163. /* this calls the peripheral hardware interface, see epdif */
  164. if (IfInit() != 0) {
  165. return -1;
  166. }
  167. /* EPD hardware init start */
  168. Reset();
  169. WaitUntilIdle();
  170. SendCommand(0x12); //SWRESET
  171. WaitUntilIdle();
  172. SendCommand(0x01); //Driver output control
  173. SendData(0xC7);
  174. SendData(0x00);
  175. SendData(0x01);
  176. SendCommand(0x11); //data entry mode
  177. SendData(0x01);
  178. SendCommand(0x44); //set Ram-X address start/end position
  179. SendData(0x00);
  180. SendData(0x18); //0x0C-->(18+1)*8=200
  181. SendCommand(0x45); //set Ram-Y address start/end position
  182. SendData(0xC7); //0xC7-->(199+1)=200
  183. SendData(0x00);
  184. SendData(0x00);
  185. SendData(0x00);
  186. SendCommand(0x3C); //BorderWavefrom
  187. SendData(0x01);
  188. SendCommand(0x18);
  189. SendData(0x80);
  190. SendCommand(0x22); // //Load Temperature and waveform setting.
  191. SendData(0XB1);
  192. SendCommand(0x20);
  193. SendCommand(0x4E); // set RAM x address count to 0;
  194. SendData(0x00);
  195. SendCommand(0x4F); // set RAM y address count to 0X199;
  196. SendData(0xC7);
  197. SendData(0x00);
  198. WaitUntilIdle();
  199. SetLut(WF_Full_1IN54);
  200. /* EPD hardware init end */
  201. return 0;
  202. }
  203. // Low Direction
  204. int Epd::LDirInit(void)
  205. {
  206. /* this calls the peripheral hardware interface, see epdif */
  207. if (IfInit() != 0) {
  208. return -1;
  209. }
  210. /* EPD hardware init start */
  211. Reset();
  212. WaitUntilIdle();
  213. SendCommand(0x12); //SWRESET
  214. WaitUntilIdle();
  215. SendCommand(0x01); //Driver output control
  216. SendData(0xC7);
  217. SendData(0x00);
  218. SendData(0x00);
  219. SendCommand(0x11); //data entry mode
  220. SendData(0x03);
  221. SendCommand(0x44);
  222. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  223. SendData((0 >> 3) & 0xFF);
  224. SendData((199 >> 3) & 0xFF);
  225. SendCommand(0x45);
  226. SendData(0 & 0xFF);
  227. SendData((0 >> 8) & 0xFF);
  228. SendData(199 & 0xFF);
  229. SendData((199 >> 8) & 0xFF);
  230. SendCommand(0x3C); //BorderWavefrom
  231. SendData(0x01);
  232. SendCommand(0x18);
  233. SendData(0x80);
  234. SendCommand(0x22); // //Load Temperature and waveform setting.
  235. SendData(0XB1);
  236. SendCommand(0x20);
  237. SendCommand(0x4E); // set RAM x address count to 0;
  238. SendData(0x00);
  239. SendCommand(0x4F); // set RAM y address count to 0X199;
  240. SendData(0xC7);
  241. SendData(0x00);
  242. WaitUntilIdle();
  243. SetLut(WF_Full_1IN54);
  244. /* EPD hardware init end */
  245. return 0;
  246. }
  247. /**
  248. * @brief: module reset.
  249. * often used to awaken the module in deep sleep,
  250. * see Epd::Sleep();
  251. */
  252. void Epd::Reset(void)
  253. {
  254. DigitalWrite(reset_pin, HIGH);
  255. DelayMs(20);
  256. DigitalWrite(reset_pin, LOW); //module reset
  257. DelayMs(5);
  258. DigitalWrite(reset_pin, HIGH);
  259. DelayMs(20);
  260. }
  261. void Epd::Clear(void)
  262. {
  263. int w, h;
  264. w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
  265. h = EPD_HEIGHT;
  266. SendCommand(0x24);
  267. for (int j = 0; j < h; j++) {
  268. for (int i = 0; i < w; i++) {
  269. SendData(0xff);
  270. }
  271. }
  272. SendCommand(0x26);
  273. for (int j = 0; j < h; j++) {
  274. for (int i = 0; i < w; i++) {
  275. SendData(0xff);
  276. }
  277. }
  278. //DISPLAY REFRESH
  279. DisplayFrame();
  280. }
  281. void Epd::Display(const unsigned char* frame_buffer)
  282. {
  283. int w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
  284. int h = EPD_HEIGHT;
  285. if (frame_buffer != NULL) {
  286. SendCommand(0x24);
  287. for (int j = 0; j < h; j++) {
  288. for (int i = 0; i < w; i++) {
  289. SendData(pgm_read_byte(&frame_buffer[i + j * w]));
  290. }
  291. }
  292. }
  293. //DISPLAY REFRESH
  294. DisplayFrame();
  295. }
  296. void Epd::DisplayPartBaseImage(const unsigned char* frame_buffer)
  297. {
  298. int w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
  299. int h = EPD_HEIGHT;
  300. if (frame_buffer != NULL) {
  301. SendCommand(0x24);
  302. for (int j = 0; j < h; j++) {
  303. for (int i = 0; i < w; i++) {
  304. SendData(pgm_read_byte(&frame_buffer[i + j * w]));
  305. }
  306. }
  307. SendCommand(0x26);
  308. for (int j = 0; j < h; j++) {
  309. for (int i = 0; i < w; i++) {
  310. SendData(pgm_read_byte(&frame_buffer[i + j * w]));
  311. }
  312. }
  313. }
  314. //DISPLAY REFRESH
  315. DisplayFrame();
  316. }
  317. void Epd::DisplayPartBaseWhiteImage(void)
  318. {
  319. int w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
  320. int h = EPD_HEIGHT;
  321. SendCommand(0x24);
  322. for (int j = 0; j < h; j++) {
  323. for (int i = 0; i < w; i++) {
  324. SendData(0xff);
  325. }
  326. }
  327. SendCommand(0x26);
  328. for (int j = 0; j < h; j++) {
  329. for (int i = 0; i < w; i++) {
  330. SendData(0xff);
  331. }
  332. }
  333. //DISPLAY REFRESH
  334. DisplayFrame();
  335. }
  336. void Epd::DisplayPart(const unsigned char* frame_buffer)
  337. {
  338. int w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
  339. int h = EPD_HEIGHT;
  340. if (frame_buffer != NULL) {
  341. SendCommand(0x24);
  342. for (int j = 0; j < h; j++) {
  343. for (int i = 0; i < w; i++) {
  344. SendData(pgm_read_byte(&frame_buffer[i + j * w]));
  345. }
  346. }
  347. }
  348. //DISPLAY REFRESH
  349. DisplayPartFrame();
  350. }
  351. /**
  352. * @brief: private function to specify the memory area for data R/W
  353. */
  354. void Epd::SetMemoryArea(int x_start, int y_start, int x_end, int y_end)
  355. {
  356. SendCommand(0x44);
  357. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  358. SendData((x_start >> 3) & 0xFF);
  359. SendData((x_end >> 3) & 0xFF);
  360. SendCommand(0x45);
  361. SendData(y_start & 0xFF);
  362. SendData((y_start >> 8) & 0xFF);
  363. SendData(y_end & 0xFF);
  364. SendData((y_end >> 8) & 0xFF);
  365. }
  366. /**
  367. * @brief: private function to specify the start point for data R/W
  368. */
  369. void Epd::SetMemoryPointer(int x, int y)
  370. {
  371. SendCommand(0x4e);
  372. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  373. SendData((x >> 3) & 0xFF);
  374. SendCommand(0x4F);
  375. SendData(y & 0xFF);
  376. SendData((y >> 8) & 0xFF);
  377. WaitUntilIdle();
  378. }
  379. /**
  380. * @brief: update the display
  381. * there are 2 memory areas embedded in the e-paper display
  382. * but once this function is called,
  383. * the the next action of SetFrameMemory or ClearFrame will
  384. * set the other memory area.
  385. */
  386. void Epd::DisplayFrame(void)
  387. {
  388. //DISPLAY REFRESH
  389. SendCommand(0x22);
  390. SendData(0xc7);
  391. SendCommand(0x20);
  392. WaitUntilIdle();
  393. }
  394. void Epd::DisplayPartFrame(void)
  395. {
  396. SendCommand(0x22);
  397. SendData(0xcF);
  398. SendCommand(0x20);
  399. WaitUntilIdle();
  400. }
  401. void Epd::SetFrameMemory(
  402. const unsigned char* image_buffer,
  403. int x,
  404. int y,
  405. int image_width,
  406. int image_height
  407. )
  408. {
  409. int x_end;
  410. int y_end;
  411. DigitalWrite(reset_pin, LOW); //module reset
  412. DelayMs(2);
  413. DigitalWrite(reset_pin, HIGH);
  414. DelayMs(2);
  415. SendCommand(0x3c);
  416. SendData(0x80);
  417. if (
  418. image_buffer == NULL ||
  419. x < 0 || image_width < 0 ||
  420. y < 0 || image_height < 0
  421. ) {
  422. return;
  423. }
  424. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  425. x &= 0xF8;
  426. image_width &= 0xF8;
  427. if (x + image_width >= this->width) {
  428. x_end = this->width - 1;
  429. } else {
  430. x_end = x + image_width - 1;
  431. }
  432. if (y + image_height >= this->height) {
  433. y_end = this->height - 1;
  434. } else {
  435. y_end = y + image_height - 1;
  436. }
  437. SetMemoryArea(x, y, x_end, y_end);
  438. SetMemoryPointer(x, y);
  439. SendCommand(0x24);
  440. /* send the image data */
  441. for (int j = 0; j < y_end - y + 1; j++) {
  442. for (int i = 0; i < (x_end - x + 1) / 8; i++) {
  443. SendData(image_buffer[i + j * (image_width / 8)]);
  444. }
  445. }
  446. }
  447. void Epd::SetFrameMemoryPartial(
  448. const unsigned char* image_buffer,
  449. int x,
  450. int y,
  451. int image_width,
  452. int image_height
  453. )
  454. {
  455. int x_end;
  456. int y_end;
  457. DigitalWrite(reset_pin, LOW); //module reset
  458. DelayMs(2);
  459. DigitalWrite(reset_pin, HIGH);
  460. DelayMs(2);
  461. SetLut(WF_PARTIAL_1IN54_0);
  462. SendCommand(0x37);
  463. SendData(0x00);
  464. SendData(0x00);
  465. SendData(0x00);
  466. SendData(0x00);
  467. SendData(0x00);
  468. SendData(0x40);
  469. SendData(0x00);
  470. SendData(0x00);
  471. SendData(0x00);
  472. SendData(0x00);
  473. SendCommand(0x3c);
  474. SendData(0x80);
  475. SendCommand(0x22);
  476. SendData(0xc0);
  477. SendCommand(0x20);
  478. WaitUntilIdle();
  479. if (
  480. image_buffer == NULL ||
  481. x < 0 || image_width < 0 ||
  482. y < 0 || image_height < 0
  483. ) {
  484. return;
  485. }
  486. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  487. x &= 0xF8;
  488. image_width &= 0xF8;
  489. if (x + image_width >= this->width) {
  490. x_end = this->width - 1;
  491. } else {
  492. x_end = x + image_width - 1;
  493. }
  494. if (y + image_height >= this->height) {
  495. y_end = this->height - 1;
  496. } else {
  497. y_end = y + image_height - 1;
  498. }
  499. SetMemoryArea(x, y, x_end, y_end);
  500. SetMemoryPointer(x, y);
  501. SendCommand(0x24);
  502. /* send the image data */
  503. for (int j = 0; j < y_end - y + 1; j++) {
  504. for (int i = 0; i < (x_end - x + 1) / 8; i++) {
  505. SendData(image_buffer[i + j * (image_width / 8)]);
  506. }
  507. }
  508. }
  509. /**
  510. * @brief: After this command is transmitted, the chip would enter the
  511. * deep-sleep mode to save power.
  512. * The deep sleep mode would return to standby by hardware reset.
  513. * The only one parameter is a check code, the command would be
  514. * executed if check code = 0xA5.
  515. * You can use Epd::Init() to awaken
  516. */
  517. void Epd::Sleep()
  518. {
  519. SendCommand(0x10); //enter deep sleep
  520. SendData(0x01);
  521. DelayMs(200);
  522. DigitalWrite(reset_pin, LOW);
  523. }
  524. /* END OF FILE */