EPD_2in13_V2.c (13510B)
1 /***************************************************************************** 2 * | File : EPD_2in13_V2.c 3 * | Author : Waveshare team 4 * | Function : 2.13inch e-paper V2 5 * | Info : 6 *---------------- 7 * | This version: V3.0 8 * | Date : 2019-06-13 9 * | Info : 10 * ----------------------------------------------------------------------------- 11 * V3.0(2019-06-13): 12 * 1.Change name: 13 * EPD_Reset() => EPD_2IN13_V2_Reset() 14 * EPD_SendCommand() => EPD_2IN13_V2_SendCommand() 15 * EPD_SendData() => EPD_2IN13_V2_SendData() 16 * EPD_WaitUntilIdle() => EPD_2IN13_V2_ReadBusy() 17 * EPD_Init() => EPD_2IN13_V2_Init() 18 * EPD_Clear() => EPD_2IN13_V2_Clear() 19 * EPD_Display() => EPD_2IN13_V2_Display() 20 * EPD_Sleep() => EPD_2IN13_V2_Sleep() 21 * 2.add: 22 * EPD_2IN13_V2_DisplayPartBaseImage() 23 * ----------------------------------------------------------------------------- 24 * V2.0(2018-11-14): 25 * 1.Remove:ImageBuff[EPD_HEIGHT * EPD_WIDTH / 8] 26 * 2.Change:EPD_2IN13_V2_Display(UBYTE *Image) 27 * Need to pass parameters: pointer to cached data 28 * 3.Change: 29 * EPD_RST -> EPD_RST_PIN 30 * EPD_DC -> EPD_DC_PIN 31 * EPD_CS -> EPD_CS_PIN 32 * EPD_BUSY -> EPD_BUSY_PIN 33 # 34 # Permission is hereby granted, free of charge, to any person obtaining a copy 35 # of this software and associated documnetation files (the "Software"), to deal 36 # in the Software without restriction, including without limitation the rights 37 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 38 # copies of the Software, and to permit persons to whom the Software is 39 # furished to do so, subject to the following conditions: 40 # 41 # The above copyright notice and this permission notice shall be included in 42 # all copies or substantial portions of the Software. 43 # 44 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 48 # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 49 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 50 # THE SOFTWARE. 51 # 52 ******************************************************************************/ 53 #include "EPD_2in13_V2.h" 54 #include "Debug.h" 55 56 const unsigned char EPD_2IN13_V2_lut_full_update[]= { 57 0x80,0x60,0x40,0x00,0x00,0x00,0x00, //LUT0: BB: VS 0 ~7 58 0x10,0x60,0x20,0x00,0x00,0x00,0x00, //LUT1: BW: VS 0 ~7 59 0x80,0x60,0x40,0x00,0x00,0x00,0x00, //LUT2: WB: VS 0 ~7 60 0x10,0x60,0x20,0x00,0x00,0x00,0x00, //LUT3: WW: VS 0 ~7 61 0x00,0x00,0x00,0x00,0x00,0x00,0x00, //LUT4: VCOM: VS 0 ~7 62 63 0x03,0x03,0x00,0x00,0x02, // TP0 A~D RP0 64 0x09,0x09,0x00,0x00,0x02, // TP1 A~D RP1 65 0x03,0x03,0x00,0x00,0x02, // TP2 A~D RP2 66 0x00,0x00,0x00,0x00,0x00, // TP3 A~D RP3 67 0x00,0x00,0x00,0x00,0x00, // TP4 A~D RP4 68 0x00,0x00,0x00,0x00,0x00, // TP5 A~D RP5 69 0x00,0x00,0x00,0x00,0x00, // TP6 A~D RP6 70 71 0x15,0x41,0xA8,0x32,0x30,0x0A, 72 }; 73 74 const unsigned char EPD_2IN13_V2_lut_partial_update[]= { //20 bytes 75 0x00,0x00,0x00,0x00,0x00,0x00,0x00, //LUT0: BB: VS 0 ~7 76 0x80,0x00,0x00,0x00,0x00,0x00,0x00, //LUT1: BW: VS 0 ~7 77 0x40,0x00,0x00,0x00,0x00,0x00,0x00, //LUT2: WB: VS 0 ~7 78 0x00,0x00,0x00,0x00,0x00,0x00,0x00, //LUT3: WW: VS 0 ~7 79 0x00,0x00,0x00,0x00,0x00,0x00,0x00, //LUT4: VCOM: VS 0 ~7 80 81 0x0A,0x00,0x00,0x00,0x00, // TP0 A~D RP0 82 0x00,0x00,0x00,0x00,0x00, // TP1 A~D RP1 83 0x00,0x00,0x00,0x00,0x00, // TP2 A~D RP2 84 0x00,0x00,0x00,0x00,0x00, // TP3 A~D RP3 85 0x00,0x00,0x00,0x00,0x00, // TP4 A~D RP4 86 0x00,0x00,0x00,0x00,0x00, // TP5 A~D RP5 87 0x00,0x00,0x00,0x00,0x00, // TP6 A~D RP6 88 89 0x15,0x41,0xA8,0x32,0x30,0x0A, 90 }; 91 /****************************************************************************** 92 function : Software reset 93 parameter: 94 ******************************************************************************/ 95 static void EPD_2IN13_V2_Reset(void) 96 { 97 DEV_Digital_Write(EPD_RST_PIN, 1); 98 DEV_Delay_ms(200); 99 DEV_Digital_Write(EPD_RST_PIN, 0); 100 DEV_Delay_ms(10); 101 DEV_Digital_Write(EPD_RST_PIN, 1); 102 DEV_Delay_ms(200); 103 } 104 105 /****************************************************************************** 106 function : send command 107 parameter: 108 Reg : Command register 109 ******************************************************************************/ 110 static void EPD_2IN13_V2_SendCommand(UBYTE Reg) 111 { 112 DEV_Digital_Write(EPD_DC_PIN, 0); 113 DEV_Digital_Write(EPD_CS_PIN, 0); 114 DEV_SPI_WriteByte(Reg); 115 DEV_Digital_Write(EPD_CS_PIN, 1); 116 } 117 118 /****************************************************************************** 119 function : send data 120 parameter: 121 Data : Write data 122 ******************************************************************************/ 123 static void EPD_2IN13_V2_SendData(UBYTE Data) 124 { 125 DEV_Digital_Write(EPD_DC_PIN, 1); 126 DEV_Digital_Write(EPD_CS_PIN, 0); 127 DEV_SPI_WriteByte(Data); 128 DEV_Digital_Write(EPD_CS_PIN, 1); 129 } 130 131 /****************************************************************************** 132 function : Wait until the busy_pin goes LOW 133 parameter: 134 ******************************************************************************/ 135 void EPD_2IN13_V2_ReadBusy(void) 136 { 137 Debug("e-Paper busy\r\n"); 138 while(DEV_Digital_Read(EPD_BUSY_PIN) == 1) { //LOW: idle, HIGH: busy 139 DEV_Delay_ms(100); 140 } 141 Debug("e-Paper busy release\r\n"); 142 } 143 144 /****************************************************************************** 145 function : Turn On Display 146 parameter: 147 ******************************************************************************/ 148 static void EPD_2IN13_V2_TurnOnDisplay(void) 149 { 150 EPD_2IN13_V2_SendCommand(0x22); 151 EPD_2IN13_V2_SendData(0xC7); 152 EPD_2IN13_V2_SendCommand(0x20); 153 EPD_2IN13_V2_ReadBusy(); 154 } 155 156 /****************************************************************************** 157 function : Turn On Display 158 parameter: 159 ******************************************************************************/ 160 static void EPD_2IN13_V2_TurnOnDisplayPart(void) 161 { 162 EPD_2IN13_V2_SendCommand(0x22); 163 EPD_2IN13_V2_SendData(0x0C); 164 EPD_2IN13_V2_SendCommand(0x20); 165 EPD_2IN13_V2_ReadBusy(); 166 } 167 /****************************************************************************** 168 function : Initialize the e-Paper register 169 parameter: 170 ******************************************************************************/ 171 void EPD_2IN13_V2_Init(UBYTE Mode) 172 { 173 UBYTE count; 174 EPD_2IN13_V2_Reset(); 175 176 if(Mode == EPD_2IN13_V2_FULL) { 177 EPD_2IN13_V2_ReadBusy(); 178 EPD_2IN13_V2_SendCommand(0x12); // soft reset 179 EPD_2IN13_V2_ReadBusy(); 180 181 EPD_2IN13_V2_SendCommand(0x74); //set analog block control 182 EPD_2IN13_V2_SendData(0x54); 183 EPD_2IN13_V2_SendCommand(0x7E); //set digital block control 184 EPD_2IN13_V2_SendData(0x3B); 185 186 EPD_2IN13_V2_SendCommand(0x01); //Driver output control 187 EPD_2IN13_V2_SendData(0xF9); 188 EPD_2IN13_V2_SendData(0x00); 189 EPD_2IN13_V2_SendData(0x00); 190 191 EPD_2IN13_V2_SendCommand(0x11); //data entry mode 192 EPD_2IN13_V2_SendData(0x01); 193 194 EPD_2IN13_V2_SendCommand(0x44); //set Ram-X address start/end position 195 EPD_2IN13_V2_SendData(0x00); 196 EPD_2IN13_V2_SendData(0x0F); //0x0C-->(15+1)*8=128 197 198 EPD_2IN13_V2_SendCommand(0x45); //set Ram-Y address start/end position 199 EPD_2IN13_V2_SendData(0xF9); //0xF9-->(249+1)=250 200 EPD_2IN13_V2_SendData(0x00); 201 EPD_2IN13_V2_SendData(0x00); 202 EPD_2IN13_V2_SendData(0x00); 203 204 EPD_2IN13_V2_SendCommand(0x3C); //BorderWavefrom 205 EPD_2IN13_V2_SendData(0x03); 206 207 EPD_2IN13_V2_SendCommand(0x2C); //VCOM Voltage 208 EPD_2IN13_V2_SendData(0x55); // 209 210 EPD_2IN13_V2_SendCommand(0x03); 211 EPD_2IN13_V2_SendData(EPD_2IN13_V2_lut_full_update[70]); 212 213 EPD_2IN13_V2_SendCommand(0x04); // 214 EPD_2IN13_V2_SendData(EPD_2IN13_V2_lut_full_update[71]); 215 EPD_2IN13_V2_SendData(EPD_2IN13_V2_lut_full_update[72]); 216 EPD_2IN13_V2_SendData(EPD_2IN13_V2_lut_full_update[73]); 217 218 EPD_2IN13_V2_SendCommand(0x3A); //Dummy Line 219 EPD_2IN13_V2_SendData(EPD_2IN13_V2_lut_full_update[74]); 220 EPD_2IN13_V2_SendCommand(0x3B); //Gate time 221 EPD_2IN13_V2_SendData(EPD_2IN13_V2_lut_full_update[75]); 222 223 EPD_2IN13_V2_SendCommand(0x32); 224 for(count = 0; count < 70; count++) { 225 EPD_2IN13_V2_SendData(EPD_2IN13_V2_lut_full_update[count]); 226 } 227 228 EPD_2IN13_V2_SendCommand(0x4E); // set RAM x address count to 0; 229 EPD_2IN13_V2_SendData(0x00); 230 EPD_2IN13_V2_SendCommand(0x4F); // set RAM y address count to 0X127; 231 EPD_2IN13_V2_SendData(0xF9); 232 EPD_2IN13_V2_SendData(0x00); 233 EPD_2IN13_V2_ReadBusy(); 234 } else if(Mode == EPD_2IN13_V2_PART) { 235 EPD_2IN13_V2_SendCommand(0x2C); //VCOM Voltage 236 EPD_2IN13_V2_SendData(0x26); 237 238 EPD_2IN13_V2_ReadBusy(); 239 240 EPD_2IN13_V2_SendCommand(0x32); 241 for(count = 0; count < 70; count++) { 242 EPD_2IN13_V2_SendData(EPD_2IN13_V2_lut_partial_update[count]); 243 } 244 245 EPD_2IN13_V2_SendCommand(0x37); 246 EPD_2IN13_V2_SendData(0x00); 247 EPD_2IN13_V2_SendData(0x00); 248 EPD_2IN13_V2_SendData(0x00); 249 EPD_2IN13_V2_SendData(0x00); 250 EPD_2IN13_V2_SendData(0x40); 251 EPD_2IN13_V2_SendData(0x00); 252 EPD_2IN13_V2_SendData(0x00); 253 254 EPD_2IN13_V2_SendCommand(0x22); 255 EPD_2IN13_V2_SendData(0xC0); 256 257 EPD_2IN13_V2_SendCommand(0x20); 258 EPD_2IN13_V2_ReadBusy(); 259 260 EPD_2IN13_V2_SendCommand(0x3C); //BorderWavefrom 261 EPD_2IN13_V2_SendData(0x01); 262 } else { 263 Debug("error, the Mode is EPD_2IN13_FULL or EPD_2IN13_PART"); 264 } 265 } 266 267 /****************************************************************************** 268 function : Clear screen 269 parameter: 270 ******************************************************************************/ 271 void EPD_2IN13_V2_Clear(void) 272 { 273 UWORD Width, Height; 274 Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1); 275 Height = EPD_2IN13_V2_HEIGHT; 276 277 EPD_2IN13_V2_SendCommand(0x24); 278 for (UWORD j = 0; j < Height; j++) { 279 for (UWORD i = 0; i < Width; i++) { 280 EPD_2IN13_V2_SendData(0XFF); 281 } 282 } 283 284 EPD_2IN13_V2_TurnOnDisplay(); 285 } 286 287 /****************************************************************************** 288 function : Sends the image buffer in RAM to e-Paper and displays 289 parameter: 290 ******************************************************************************/ 291 void EPD_2IN13_V2_Display(UBYTE *Image) 292 { 293 UWORD Width, Height; 294 Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1); 295 Height = EPD_2IN13_V2_HEIGHT; 296 297 EPD_2IN13_V2_SendCommand(0x24); 298 for (UWORD j = 0; j < Height; j++) { 299 for (UWORD i = 0; i < Width; i++) { 300 EPD_2IN13_V2_SendData(Image[i + j * Width]); 301 } 302 } 303 EPD_2IN13_V2_TurnOnDisplay(); 304 } 305 306 /****************************************************************************** 307 function : The image of the previous frame must be uploaded, otherwise the 308 first few seconds will display an exception. 309 parameter: 310 ******************************************************************************/ 311 void EPD_2IN13_V2_DisplayPartBaseImage(UBYTE *Image) 312 { 313 UWORD Width, Height; 314 Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1); 315 Height = EPD_2IN13_V2_HEIGHT; 316 317 UDOUBLE Addr = 0; 318 EPD_2IN13_V2_SendCommand(0x24); 319 for (UWORD j = 0; j < Height; j++) { 320 for (UWORD i = 0; i < Width; i++) { 321 Addr = i + j * Width; 322 EPD_2IN13_V2_SendData(Image[Addr]); 323 } 324 } 325 EPD_2IN13_V2_SendCommand(0x26); 326 for (UWORD j = 0; j < Height; j++) { 327 for (UWORD i = 0; i < Width; i++) { 328 Addr = i + j * Width; 329 EPD_2IN13_V2_SendData(Image[Addr]); 330 } 331 } 332 EPD_2IN13_V2_TurnOnDisplay(); 333 } 334 335 336 void EPD_2IN13_V2_DisplayPart(UBYTE *Image) 337 { 338 UWORD Width, Height; 339 Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1); 340 Height = EPD_2IN13_V2_HEIGHT; 341 EPD_2IN13_V2_SendCommand(0x24); 342 for (UWORD j = 0; j < Height; j++) { 343 for (UWORD i = 0; i < Width; i++) { 344 EPD_2IN13_V2_SendData(Image[i + j * Width]); 345 } 346 } 347 348 EPD_2IN13_V2_TurnOnDisplayPart(); 349 } 350 351 /****************************************************************************** 352 function : Enter sleep mode 353 parameter: 354 ******************************************************************************/ 355 void EPD_2IN13_V2_Sleep(void) 356 { 357 EPD_2IN13_V2_SendCommand(0x22); //POWER OFF 358 EPD_2IN13_V2_SendData(0xC3); 359 EPD_2IN13_V2_SendCommand(0x20); 360 361 EPD_2IN13_V2_SendCommand(0x10); //enter deep sleep 362 EPD_2IN13_V2_SendData(0x01); 363 DEV_Delay_ms(100); 364 }