epd2in13b_V4.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /**
  2. * @filename : epd2in13b_V4.cpp
  3. * @brief : Implements for Three-color e-paper library
  4. * @author : Yehui from Waveshare
  5. *
  6. * Copyright (C) Waveshare April 25 2022
  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 "epd2in13b_V4.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. bufwidth = 128/8;
  37. height = EPD_HEIGHT;
  38. bufheight = 63;
  39. };
  40. int Epd::Init(void) {
  41. /* this calls the peripheral hardware interface, see epdif */
  42. if (IfInit() != 0) {
  43. return -1;
  44. }
  45. /* EPD hardware init start */
  46. Reset();
  47. WaitUntilIdle();
  48. SendCommand(0x12); // SWRESET
  49. WaitUntilIdle();
  50. SendCommand(0x01); //Driver output control
  51. SendData(0xf9);
  52. SendData(0x00);
  53. SendData(0x00);
  54. SendCommand(0x11); //data entry mode
  55. SendData(0x03);
  56. SetWindows(0, 0, width-1, height-1);
  57. SetCursor(0, 0);
  58. SendCommand(0x3C); //BorderWavefrom
  59. SendData(0x05);
  60. SendCommand(0x18); //Read built-in temperature sensor
  61. SendData(0x80);
  62. SendCommand(0x21); // Display update control
  63. SendData(0x80);
  64. SendData(0x80);
  65. WaitUntilIdle();
  66. return 0;
  67. }
  68. /**
  69. * @brief: basic function for sending commands
  70. */
  71. void Epd::SendCommand(unsigned char command) {
  72. DigitalWrite(dc_pin, LOW);
  73. SpiTransfer(command);
  74. }
  75. /**
  76. * @brief: basic function for sending data
  77. */
  78. void Epd::SendData(unsigned char data) {
  79. DigitalWrite(dc_pin, HIGH);
  80. SpiTransfer(data);
  81. }
  82. /**
  83. * @brief: Wait until the busy_pin goes HIGH
  84. */
  85. void Epd::WaitUntilIdle(void) {
  86. while(DigitalRead(busy_pin) == 1) { //1: busy, 0: idle
  87. DelayMs(10);
  88. }
  89. DelayMs(10);
  90. }
  91. /**
  92. * @brief: module reset.
  93. * often used to awaken the module in deep sleep,
  94. * see Epd::Sleep();
  95. */
  96. void Epd::Reset(void) {
  97. DigitalWrite(reset_pin, HIGH);
  98. DelayMs(20);
  99. DigitalWrite(reset_pin, LOW);
  100. DelayMs(2);
  101. DigitalWrite(reset_pin, HIGH);
  102. DelayMs(20);
  103. this->count = 0;
  104. }
  105. // Setting the display window
  106. void Epd::SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend) {
  107. SendCommand(0x44); // SET_RAM_X_ADDRESS_START_END_POSITION
  108. SendData((Xstart>>3) & 0xFF);
  109. SendData((Xend>>3) & 0xFF);
  110. SendCommand(0x45); // SET_RAM_Y_ADDRESS_START_END_POSITION
  111. SendData(Ystart & 0xFF);
  112. SendData((Ystart >> 8) & 0xFF);
  113. SendData(Yend & 0xFF);
  114. SendData((Yend >> 8) & 0xFF);
  115. }
  116. // Set Cursor
  117. void Epd::SetCursor(UWORD Xstart, UWORD Ystart) {
  118. SendCommand(0x4E); // SET_RAM_X_ADDRESS_COUNTER
  119. SendData(Xstart & 0xFF);
  120. SendCommand(0x4F); // SET_RAM_Y_ADDRESS_COUNTER
  121. SendData(Ystart & 0xFF);
  122. SendData((Ystart >> 8) & 0xFF);
  123. }
  124. /**
  125. * @brief: refresh and displays the frame
  126. */
  127. void Epd::DisplayFrame(const unsigned char* frame_buffer_black, const unsigned char* frame_buffer_red) {
  128. if (frame_buffer_black != NULL) {
  129. SendCommand(0x24);
  130. for (int i = 0; i < this->bufwidth * this->height; i++) {
  131. SendData(pgm_read_byte(&frame_buffer_black[i]));
  132. }
  133. DelayMs(2);
  134. }
  135. if (frame_buffer_red != NULL) {
  136. SendCommand(0x26);
  137. for (int i = 0; i < this->bufwidth * this->height; i++) {
  138. SendData(pgm_read_byte(&frame_buffer_red[i]));
  139. }
  140. }
  141. SendCommand(0x20);
  142. WaitUntilIdle();
  143. this->count = 0;
  144. }
  145. void Epd::Display(const unsigned char* frame_buffer) {
  146. if(this->count == 0){
  147. SendCommand(0x24);
  148. this->count++;
  149. }else if(this->count > 0 && this->count < 4 ){
  150. this->count++;
  151. }else if(this->count == 4){
  152. SendCommand(0x26);
  153. this->count++;
  154. }else if(this->count > 4 && this->count < 8 ){
  155. this->count++;
  156. }
  157. for(int i = 0; i < this->bufwidth * this->bufheight; i++){
  158. SendData(frame_buffer[i]);
  159. }
  160. if(this->count == 8){
  161. SendCommand(0x20);
  162. WaitUntilIdle();
  163. this->count = 0;
  164. }
  165. }
  166. /**
  167. * @brief: clear the frame data from the SRAM, this won't refresh the display
  168. */
  169. void Epd::ClearFrame(void) {
  170. SendCommand(0x24);
  171. for(int i = 0; i < bufwidth * height; i++) {
  172. SendData(0xFF);
  173. }
  174. SendCommand(0x26);
  175. for(int i = 0; i < bufwidth * height; i++) {
  176. SendData(0xFF);
  177. }
  178. SendCommand(0x20);
  179. WaitUntilIdle();
  180. this->count = 0;
  181. }
  182. /**
  183. * @brief: This displays the frame data from SRAM
  184. */
  185. void Epd::DisplayFrame(void) {
  186. this->count = 0;
  187. SendCommand(0x20); // Activate Display Update Sequence
  188. WaitUntilIdle();
  189. }
  190. /**
  191. * @brief: After this command is transmitted, the chip would enter the deep-sleep mode to save power.
  192. * The deep sleep mode would return to standby by hardware reset. The only one parameter is a
  193. * check code, the command would be executed if check code = 0xA5.
  194. * You can use Epd::Reset() to awaken and use Epd::Init() to initialize.
  195. */
  196. void Epd::Sleep() {
  197. SendCommand(0x10); //enter deep sleep
  198. SendData(0x01);
  199. DelayMs(100);
  200. this->count = 0;
  201. }
  202. /* END OF FILE */