2
0

epd2in9_V2.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  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. Epd::~Epd() {
  73. };
  74. Epd::Epd() {
  75. reset_pin = RST_PIN;
  76. dc_pin = DC_PIN;
  77. cs_pin = CS_PIN;
  78. busy_pin = BUSY_PIN;
  79. width = EPD_WIDTH;
  80. height = EPD_HEIGHT;
  81. };
  82. int Epd::Init() {
  83. /* this calls the peripheral hardware interface, see epdif */
  84. if (IfInit() != 0) {
  85. return -1;
  86. }
  87. Reset();
  88. /* EPD hardware init start */
  89. WaitUntilIdle();
  90. SendCommand(0x12); //SWRESET
  91. WaitUntilIdle();
  92. SendCommand(0x01); //Driver output control
  93. SendData(0x27);
  94. SendData(0x01);
  95. SendData(0x00);
  96. SendCommand(0x11); //data entry mode
  97. SendData(0x03);
  98. SetMemoryArea(0, 0, width-1, height-1);
  99. SendCommand(0x21); // Display update control
  100. SendData(0x00);
  101. SendData(0x80);
  102. SetMemoryPointer(0, 0);
  103. WaitUntilIdle();
  104. SetLut_by_host(WS_20_30);
  105. /* EPD hardware init end */
  106. return 0;
  107. }
  108. /**
  109. * @brief: basic function for sending commands
  110. */
  111. void Epd::SendCommand(unsigned char command) {
  112. DigitalWrite(dc_pin, LOW);
  113. DigitalWrite(cs_pin, LOW);
  114. SpiTransfer(command);
  115. DigitalWrite(cs_pin, HIGH);
  116. }
  117. /**
  118. * @brief: basic function for sending data
  119. */
  120. void Epd::SendData(unsigned char data) {
  121. DigitalWrite(dc_pin, HIGH);
  122. DigitalWrite(cs_pin, LOW);
  123. SpiTransfer(data);
  124. DigitalWrite(cs_pin, HIGH);
  125. }
  126. /**
  127. * @brief: Wait until the busy_pin goes LOW
  128. */
  129. void Epd::WaitUntilIdle(void) {
  130. while(1) { //=1 BUSY
  131. if(DigitalRead(busy_pin)==LOW)
  132. break;
  133. DelayMs(5);
  134. }
  135. DelayMs(5);
  136. }
  137. /**
  138. * @brief: module reset.
  139. * often used to awaken the module in deep sleep,
  140. * see Epd::Sleep();
  141. */
  142. void Epd::Reset(void) {
  143. DigitalWrite(reset_pin, HIGH);
  144. DelayMs(20);
  145. DigitalWrite(reset_pin, LOW); //module reset
  146. DelayMs(5);
  147. DigitalWrite(reset_pin, HIGH);
  148. DelayMs(20);
  149. }
  150. /**
  151. * @brief: put an image buffer to the frame memory.
  152. * this won't update the display.
  153. */
  154. void Epd::SetFrameMemory(
  155. const unsigned char* image_buffer,
  156. int x,
  157. int y,
  158. int image_width,
  159. int image_height
  160. ) {
  161. int x_end;
  162. int y_end;
  163. if (
  164. image_buffer == NULL ||
  165. x < 0 || image_width < 0 ||
  166. y < 0 || image_height < 0
  167. ) {
  168. return;
  169. }
  170. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  171. x &= 0xF8;
  172. image_width &= 0xF8;
  173. if (x + image_width >= this->width) {
  174. x_end = this->width - 1;
  175. } else {
  176. x_end = x + image_width - 1;
  177. }
  178. if (y + image_height >= this->height) {
  179. y_end = this->height - 1;
  180. } else {
  181. y_end = y + image_height - 1;
  182. }
  183. SetMemoryArea(x, y, x_end, y_end);
  184. SetMemoryPointer(x, y);
  185. SendCommand(0x24);
  186. /* send the image data */
  187. for (int j = 0; j < y_end - y + 1; j++) {
  188. for (int i = 0; i < (x_end - x + 1) / 8; i++) {
  189. SendData(image_buffer[i + j * (image_width / 8)]);
  190. }
  191. }
  192. }
  193. void Epd::SetFrameMemory_Partial(
  194. const unsigned char* image_buffer,
  195. int x,
  196. int y,
  197. int image_width,
  198. int image_height
  199. ) {
  200. int x_end;
  201. int y_end;
  202. if (
  203. image_buffer == NULL ||
  204. x < 0 || image_width < 0 ||
  205. y < 0 || image_height < 0
  206. ) {
  207. return;
  208. }
  209. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  210. x &= 0xF8;
  211. image_width &= 0xF8;
  212. if (x + image_width >= this->width) {
  213. x_end = this->width - 1;
  214. } else {
  215. x_end = x + image_width - 1;
  216. }
  217. if (y + image_height >= this->height) {
  218. y_end = this->height - 1;
  219. } else {
  220. y_end = y + image_height - 1;
  221. }
  222. DigitalWrite(reset_pin, LOW);
  223. DelayMs(2);
  224. DigitalWrite(reset_pin, HIGH);
  225. DelayMs(2);
  226. SetLut(_WF_PARTIAL_2IN9);
  227. SendCommand(0x37);
  228. SendData(0x00);
  229. SendData(0x00);
  230. SendData(0x00);
  231. SendData(0x00);
  232. SendData(0x00);
  233. SendData(0x40);
  234. SendData(0x00);
  235. SendData(0x00);
  236. SendData(0x00);
  237. SendData(0x00);
  238. SendCommand(0x3C); //BorderWavefrom
  239. SendData(0x80);
  240. SendCommand(0x22);
  241. SendData(0xC0);
  242. SendCommand(0x20);
  243. WaitUntilIdle();
  244. SetMemoryArea(x, y, x_end, y_end);
  245. SetMemoryPointer(x, y);
  246. SendCommand(0x24);
  247. /* send the image data */
  248. for (int j = 0; j < y_end - y + 1; j++) {
  249. for (int i = 0; i < (x_end - x + 1) / 8; i++) {
  250. SendData(image_buffer[i + j * (image_width / 8)]);
  251. }
  252. }
  253. }
  254. /**
  255. * @brief: put an image buffer to the frame memory.
  256. * this won't update the display.
  257. *
  258. * Question: When do you use this function instead of
  259. * void SetFrameMemory(
  260. * const unsigned char* image_buffer,
  261. * int x,
  262. * int y,
  263. * int image_width,
  264. * int image_height
  265. * );
  266. * Answer: SetFrameMemory with parameters only reads image data
  267. * from the RAM but not from the flash in AVR chips (for AVR chips,
  268. * you have to use the function pgm_read_byte to read buffers
  269. * from the flash).
  270. */
  271. void Epd::SetFrameMemory(const unsigned char* image_buffer) {
  272. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  273. SetMemoryPointer(0, 0);
  274. SendCommand(0x24);
  275. /* send the image data */
  276. for (int i = 0; i < this->width / 8 * this->height; i++) {
  277. SendData(pgm_read_byte(&image_buffer[i]));
  278. }
  279. }
  280. void Epd::SetFrameMemory_Base(const unsigned char* image_buffer) {
  281. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  282. SetMemoryPointer(0, 0);
  283. SendCommand(0x24);
  284. /* send the image data */
  285. for (int i = 0; i < this->width / 8 * this->height; i++) {
  286. SendData(pgm_read_byte(&image_buffer[i]));
  287. }
  288. SendCommand(0x26);
  289. /* send the image data */
  290. for (int i = 0; i < this->width / 8 * this->height; i++) {
  291. SendData(pgm_read_byte(&image_buffer[i]));
  292. }
  293. }
  294. /**
  295. * @brief: clear the frame memory with the specified color.
  296. * this won't update the display.
  297. */
  298. void Epd::ClearFrameMemory(unsigned char color) {
  299. SetMemoryArea(0, 0, this->width - 1, this->height - 1);
  300. SetMemoryPointer(0, 0);
  301. SendCommand(0x24);
  302. /* send the color data */
  303. for (int i = 0; i < this->width / 8 * this->height; i++) {
  304. SendData(color);
  305. }
  306. }
  307. /**
  308. * @brief: update the display
  309. * there are 2 memory areas embedded in the e-paper display
  310. * but once this function is called,
  311. * the the next action of SetFrameMemory or ClearFrame will
  312. * set the other memory area.
  313. */
  314. void Epd::DisplayFrame(void) {
  315. SendCommand(0x22);
  316. SendData(0xc7);
  317. SendCommand(0x20);
  318. WaitUntilIdle();
  319. }
  320. void Epd::DisplayFrame_Partial(void) {
  321. SendCommand(0x22);
  322. SendData(0x0F);
  323. SendCommand(0x20);
  324. WaitUntilIdle();
  325. }
  326. void Epd::SetLut(unsigned char *lut) {
  327. unsigned char count;
  328. SendCommand(0x32);
  329. for(count=0; count<153; count++)
  330. SendData(lut[count]);
  331. WaitUntilIdle();
  332. }
  333. void Epd::SetLut_by_host(unsigned char *lut) {
  334. SetLut((unsigned char *)lut);
  335. SendCommand(0x3f);
  336. SendData(*(lut+153));
  337. SendCommand(0x03); // gate voltage
  338. SendData(*(lut+154));
  339. SendCommand(0x04); // source voltage
  340. SendData(*(lut+155)); // VSH
  341. SendData(*(lut+156)); // VSH2
  342. SendData(*(lut+157)); // VSL
  343. SendCommand(0x2c); // VCOM
  344. SendData(*(lut+158));
  345. }
  346. /**
  347. * @brief: private function to specify the memory area for data R/W
  348. */
  349. void Epd::SetMemoryArea(int x_start, int y_start, int x_end, int y_end) {
  350. SendCommand(0x44);
  351. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  352. SendData((x_start >> 3) & 0xFF);
  353. SendData((x_end >> 3) & 0xFF);
  354. SendCommand(0x45);
  355. SendData(y_start & 0xFF);
  356. SendData((y_start >> 8) & 0xFF);
  357. SendData(y_end & 0xFF);
  358. SendData((y_end >> 8) & 0xFF);
  359. }
  360. /**
  361. * @brief: private function to specify the start point for data R/W
  362. */
  363. void Epd::SetMemoryPointer(int x, int y) {
  364. SendCommand(0x4E);
  365. /* x point must be the multiple of 8 or the last 3 bits will be ignored */
  366. SendData((x >> 3) & 0xFF);
  367. SendCommand(0x4F);
  368. SendData(y & 0xFF);
  369. SendData((y >> 8) & 0xFF);
  370. WaitUntilIdle();
  371. }
  372. /**
  373. * @brief: After this command is transmitted, the chip would enter the
  374. * deep-sleep mode to save power.
  375. * The deep sleep mode would return to standby by hardware reset.
  376. * You can use Epd::Init() to awaken
  377. */
  378. void Epd::Sleep() {
  379. SendCommand(0x10);
  380. SendData(0x01);
  381. // WaitUntilIdle();
  382. }
  383. /* END OF FILE */