epd13in3b.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /**
  2. * @filename : epd13in3b.cpp
  3. * @brief : Implements for e-paper library
  4. * @author : Yehui from Waveshare
  5. *
  6. * Copyright (C) Waveshare 2024 04 08
  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 "epd13in3b.h"
  28. Epd::~Epd() {
  29. };
  30. Epd::Epd() {
  31. reset_pin = RST_PIN;
  32. dc_pin = DC_PIN;
  33. cs_pin = CS_PIN;
  34. busy_pin = BUSY_PIN;
  35. width = EPD_WIDTH;
  36. height = EPD_HEIGHT;
  37. };
  38. int Epd::Init(void) {
  39. if (IfInit() != 0) {
  40. return -1;
  41. }
  42. Reset();
  43. ReadBusy();
  44. SendCommand(0x12);
  45. ReadBusy();
  46. SendCommand(0x0C);
  47. SendData(0xAE);
  48. SendData(0xC7);
  49. SendData(0xC3);
  50. SendData(0xC0);
  51. SendData(0x80);
  52. SendCommand(0x01);
  53. SendData(0xA7);
  54. SendData(0x02);
  55. SendData(0x00);
  56. SendCommand(0x11);
  57. SendData(0x03);
  58. SendCommand(0x44);
  59. SendData(0x00);
  60. SendData(0x00);
  61. SendData(0xBF);
  62. SendData(0x03);
  63. SendCommand(0x45);
  64. SendData(0x00);
  65. SendData(0x00);
  66. SendData(0xA7);
  67. SendData(0x02);
  68. SendCommand(0x3C);
  69. SendData(0x01);
  70. SendCommand(0x18);
  71. SendData(0x80);
  72. SendCommand(0x4E);
  73. SendData(0x00);
  74. SendData(0x00);
  75. SendCommand(0x4F);
  76. SendData(0x00);
  77. SendData(0x00);
  78. ReadBusy();
  79. return 0;
  80. }
  81. /**
  82. * @brief: basic function for sending commands
  83. */
  84. void Epd::SendCommand(unsigned char command) {
  85. DigitalWrite(dc_pin, LOW);
  86. SpiTransfer(command);
  87. }
  88. /**
  89. * @brief: basic function for sending data
  90. */
  91. void Epd::SendData(unsigned char data) {
  92. DigitalWrite(dc_pin, HIGH);
  93. SpiTransfer(data);
  94. }
  95. /**
  96. * @brief: Wait until the busy_pin goes HIGH
  97. */
  98. void Epd::ReadBusy(void) {
  99. unsigned char busy;
  100. Serial.print("e-Paper Busy\r\n ");
  101. do{
  102. DelayMs(20);
  103. busy = DigitalRead(busy_pin);
  104. }while(busy == 1);
  105. Serial.print("e-Paper Busy Release\r\n ");
  106. DelayMs(20);
  107. }
  108. /**
  109. * @brief: Refresh function
  110. */
  111. void Epd::TurnOnDisplay(void) {
  112. SendCommand(0x22);
  113. SendData(0xF7);
  114. SendCommand(0x20);
  115. ReadBusy();
  116. }
  117. void Epd::TurnOnDisplay_Part(void)
  118. {
  119. SendCommand(0x22); //Display Update Control
  120. SendData(0xFF);
  121. SendCommand(0x20); //Activate Display Update Sequence
  122. ReadBusy();
  123. }
  124. /**
  125. * @brief: module reset.
  126. * often used to awaken the module in deep sleep,
  127. * see Epd::Sleep();
  128. */
  129. void Epd::Reset(void) {
  130. DigitalWrite(reset_pin, HIGH);
  131. DelayMs(200);
  132. DigitalWrite(reset_pin, LOW); //module reset
  133. DelayMs(2);
  134. DigitalWrite(reset_pin, HIGH);
  135. DelayMs(200);
  136. }
  137. void Epd::Clear(void) {
  138. SendCommand(0x24);
  139. for(unsigned long i=0; i<height*width/8; i++) {
  140. SendData(0xFF);
  141. }
  142. SendCommand(0x26);
  143. for(unsigned long i=0; i<height*width/8; i++) {
  144. SendData(0x00);
  145. }
  146. TurnOnDisplay();
  147. }
  148. void Epd::Displaypart(const unsigned char* pbuffer, unsigned long xStart, unsigned long yStart, unsigned long Picture_Width, unsigned long Picture_Height, unsigned char Block) {
  149. if(Block == 0){
  150. SendCommand(0x24);
  151. }else{
  152. SendCommand(0x26);
  153. }
  154. for (unsigned long j = 0; j < height; j++) {
  155. for (unsigned long i = 0; i < width/8; i++) {
  156. if( (j>=yStart) && (j<yStart+Picture_Height) && (i*8>=xStart) && (i*8<xStart+Picture_Width)){
  157. if(Block == 0){
  158. SendData((pgm_read_byte(&(pbuffer[i-xStart/8 + (Picture_Width)/8*(j-yStart)]))) );
  159. }else if(Block == 1){
  160. SendData(~(pgm_read_byte(&(pbuffer[i-xStart/8 + (Picture_Width)/8*(j-yStart)]))) );
  161. }
  162. }else {
  163. if(Block == 0){
  164. SendData(0xFF);
  165. }else{
  166. SendData(0x00);
  167. }
  168. }
  169. }
  170. }
  171. if(Block != 0){
  172. TurnOnDisplay();
  173. }
  174. }
  175. void Epd::DisplayFrame(const unsigned char *blackimage, const unsigned char *ryimage) {
  176. SendCommand(0x24);
  177. for (unsigned long j = 0; j < height; j++) {
  178. for (unsigned long i = 0; i < width/8; i++) {
  179. SendData(blackimage[i + j * width/8]);
  180. }
  181. }
  182. SendCommand(0x26);
  183. for (unsigned long j = 0; j < height; j++) {
  184. for (unsigned long i = 0; i < width/8; i++) {
  185. SendData(ryimage[i + j * width/8]);
  186. }
  187. }
  188. TurnOnDisplay();
  189. }
  190. void Epd::Display_Base(const unsigned char *blackimage, const unsigned char *ryimage) {
  191. SendCommand(0x24);
  192. for (unsigned long j = 0; j < height; j++) {
  193. for (unsigned long i = 0; i < width/8; i++) {
  194. SendData(blackimage[i + j * width/8]);
  195. }
  196. }
  197. SendCommand(0x26);
  198. for (unsigned long j = 0; j < height; j++) {
  199. for (unsigned long i = 0; i < width/8; i++) {
  200. SendData(ryimage[i + j * width/8]);
  201. }
  202. }
  203. TurnOnDisplay();
  204. SendCommand(0x26);
  205. for (unsigned long j = 0; j < height; j++) {
  206. for (unsigned long i = 0; i < width/8; i++) {
  207. SendData(blackimage[i + j * width/8]);
  208. }
  209. }
  210. }
  211. void Epd::Display_Part(unsigned char *Image, unsigned long x, unsigned long y, unsigned long w, unsigned long l)
  212. {
  213. unsigned long i;
  214. unsigned long HEIGHT = l;
  215. unsigned long WIDTH = (w % 8 == 0)? (w / 8 ): (w / 8 + 1);
  216. SendCommand(0x3C); // Border Border setting
  217. SendData(0x80);
  218. SendCommand(0x44);
  219. SendData(x & 0xFF);
  220. SendData((x>>8) & 0x03);
  221. SendData((x+w-1) & 0xFF);
  222. SendData(((x+w-1)>>8) & 0x03);
  223. SendCommand(0x45);
  224. SendData(y & 0xFF);
  225. SendData((y>>8) & 0x03);
  226. SendData((y+l-1) & 0xFF);
  227. SendData(((y+l-1)>>8) & 0x03);
  228. SendCommand(0x4E);
  229. SendData(x & 0xFF);
  230. SendData((x>>8) & 0x03);
  231. SendCommand(0x4F);
  232. SendData(y & 0xFF);
  233. SendData((y>>8) & 0x03);
  234. SendCommand(0x24); //write RAM for black(0)/white (1)
  235. for (unsigned long j = 0; j < HEIGHT; j++) {
  236. for (unsigned long i = 0; i < WIDTH; i++) {
  237. SendData(Image[i + j * WIDTH]);
  238. }
  239. }
  240. TurnOnDisplay_Part();
  241. SendCommand(0x26); //write RAM for black(0)/white (1)
  242. for (unsigned long j = 0; j < HEIGHT; j++) {
  243. for (unsigned long i = 0; i < WIDTH; i++) {
  244. SendData(Image[i + j * WIDTH]);
  245. }
  246. }
  247. }
  248. /**
  249. * @brief: After this command is transmitted, the chip would enter the
  250. * deep-sleep mode to save power.
  251. * The deep sleep mode would return to standby by hardware reset.
  252. * The only one parameter is a check code, the command would be
  253. * executed if check code = 0xA5.
  254. * You can use EPD_Reset() to awaken
  255. */
  256. void Epd::Sleep(void) {
  257. SendCommand(0x10);
  258. SendData(0x03);
  259. DelayMs(100);
  260. ReadBusy();
  261. }
  262. /* END OF FILE */