EPD_2in13d.c (15419B)
1 /***************************************************************************** 2 * | File : EPD_2in13d.c 3 * | Author : Waveshare team 4 * | Function : 2.13inch e-paper d 5 * | Info : 6 *---------------- 7 * | This version: V3.0 8 * | Date : 2019-06-12 9 * | Info : 10 * ----------------------------------------------------------------------------- 11 * V3.0(2019-06-12): 12 * 1.Change: 13 * lut_vcomDC[] => EPD_2IN13D_lut_vcomDC[] 14 * lut_ww[] => EPD_2IN13D_lut_ww[] 15 * lut_bw[] => EPD_2IN13D_lut_bw[] 16 * lut_wb[] => EPD_2IN13D_lut_wb[] 17 * lut_bb[] => EPD_2IN13D_lut_bb[] 18 * lut_vcom1[] => EPD_2IN13D_lut_vcom1[] 19 * lut_ww1[] => EPD_2IN13D_lut_ww1[] 20 * lut_bw1[] => EPD_2IN13D_lut_bw1[] 21 * lut_wb1[] => EPD_2IN13D_lut_wb1[] 22 * lut_bb1[] => EPD_2IN13D_lut_bb1[] 23 * EPD_Reset() => EPD_2IN13D_Reset() 24 * EPD_SendCommand() => EPD_2IN13D_SendCommand() 25 * EPD_SendData() => EPD_2IN13D_SendData() 26 * EPD_WaitUntilIdle() => EPD_2IN13D_ReadBusy() 27 * EPD_SetFullReg() => EPD_2IN13D_SetFullReg() 28 * EPD_SetPartReg() => EPD_2IN13D_SetPartReg() 29 * EPD_TurnOnDisplay() => EPD_2IN13D_TurnOnDisplay() 30 * EPD_Init() => EPD_2IN13D_Init() 31 * EPD_Clear() => EPD_2IN13D_Clear() 32 * EPD_Display() => EPD_2IN13D_Display() 33 * EPD_Sleep() => EPD_2IN13D_Sleep() 34 * V2.0(2018-11-13): 35 * 1.Remove:ImageBuff[EPD_2IN13D_HEIGHT * EPD_2IN13D_WIDTH / 8] 36 * 2.Change:EPD_Display(UBYTE *Image) 37 * Need to pass parameters: pointer to cached data 38 * 3.Change: 39 * EPD_RST -> EPD_RST_PIN 40 * EPD_DC -> EPD_DC_PIN 41 * EPD_CS -> EPD_CS_PIN 42 * EPD_BUSY -> EPD_BUSY_PIN 43 # 44 # Permission is hereby granted, free of charge, to any person obtaining a copy 45 # of this software and associated documnetation files (the "Software"), to deal 46 # in the Software without restriction, including without limitation the rights 47 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 48 # copies of the Software, and to permit persons to whom the Software is 49 # furished to do so, subject to the following conditions: 50 # 51 # The above copyright notice and this permission notice shall be included in 52 # all copies or substantial portions of the Software. 53 # 54 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 55 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 56 # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 57 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 58 # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 59 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 60 # THE SOFTWARE. 61 # 62 ******************************************************************************/ 63 #include "EPD_2in13d.h" 64 #include "Debug.h" 65 66 /** 67 * full screen update LUT 68 **/ 69 static const unsigned char EPD_2IN13D_lut_vcomDC[] = { 70 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 71 0x60, 0x28, 0x28, 0x00, 0x00, 0x01, 72 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 73 0x00, 0x12, 0x12, 0x00, 0x00, 0x01, 74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 0x00, 0x00, 78 }; 79 static const unsigned char EPD_2IN13D_lut_ww[] = { 80 0x40, 0x08, 0x00, 0x00, 0x00, 0x02, 81 0x90, 0x28, 0x28, 0x00, 0x00, 0x01, 82 0x40, 0x14, 0x00, 0x00, 0x00, 0x01, 83 0xA0, 0x12, 0x12, 0x00, 0x00, 0x01, 84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 }; 88 static const unsigned char EPD_2IN13D_lut_bw[] = { 89 0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 90 0x90, 0x0F, 0x0F, 0x00, 0x00, 0x03, 91 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, 92 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 }; 97 static const unsigned char EPD_2IN13D_lut_wb[] = { 98 0x80, 0x08, 0x00, 0x00, 0x00, 0x02, 99 0x90, 0x28, 0x28, 0x00, 0x00, 0x01, 100 0x80, 0x14, 0x00, 0x00, 0x00, 0x01, 101 0x50, 0x12, 0x12, 0x00, 0x00, 0x01, 102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 }; 106 static const unsigned char EPD_2IN13D_lut_bb[] = { 107 0x80, 0x08, 0x00, 0x00, 0x00, 0x02, 108 0x90, 0x28, 0x28, 0x00, 0x00, 0x01, 109 0x80, 0x14, 0x00, 0x00, 0x00, 0x01, 110 0x50, 0x12, 0x12, 0x00, 0x00, 0x01, 111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 114 }; 115 116 117 /** 118 * partial screen update LUT 119 **/ 120 static const unsigned char EPD_2IN13D_lut_vcom1[] = { 121 0x00, 0x19, 0x01, 0x00, 0x00, 0x01, 122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 128 ,0x00, 0x00, 129 }; 130 static const unsigned char EPD_2IN13D_lut_ww1[] = { 131 0x00, 0x19, 0x01, 0x00, 0x00, 0x01, 132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 }; 139 static const unsigned char EPD_2IN13D_lut_bw1[] = { 140 0x80, 0x19, 0x01, 0x00, 0x00, 0x01, 141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 147 }; 148 static const unsigned char EPD_2IN13D_lut_wb1[] = { 149 0x40, 0x19, 0x01, 0x00, 0x00, 0x01, 150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 156 }; 157 static const unsigned char EPD_2IN13D_lut_bb1[] = { 158 0x00, 0x19, 0x01, 0x00, 0x00, 0x01, 159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 165 }; 166 167 168 /****************************************************************************** 169 function : Software reset 170 parameter: 171 ******************************************************************************/ 172 static void EPD_2IN13D_Reset(void) 173 { 174 DEV_Digital_Write(EPD_RST_PIN, 1); 175 DEV_Delay_ms(200); 176 DEV_Digital_Write(EPD_RST_PIN, 0); 177 DEV_Delay_ms(200); 178 DEV_Digital_Write(EPD_RST_PIN, 1); 179 DEV_Delay_ms(200); 180 } 181 182 /****************************************************************************** 183 function : send command 184 parameter: 185 Reg : Command register 186 ******************************************************************************/ 187 static void EPD_2IN13D_SendCommand(UBYTE Reg) 188 { 189 DEV_Digital_Write(EPD_DC_PIN, 0); 190 DEV_Digital_Write(EPD_CS_PIN, 0); 191 DEV_SPI_WriteByte(Reg); 192 DEV_Digital_Write(EPD_CS_PIN, 1); 193 } 194 195 /****************************************************************************** 196 function : send data 197 parameter: 198 Data : Write data 199 ******************************************************************************/ 200 static void EPD_2IN13D_SendData(UBYTE Data) 201 { 202 DEV_Digital_Write(EPD_DC_PIN, 1); 203 DEV_Digital_Write(EPD_CS_PIN, 0); 204 DEV_SPI_WriteByte(Data); 205 DEV_Digital_Write(EPD_CS_PIN, 1); 206 } 207 208 /****************************************************************************** 209 function : Wait until the busy_pin goes LOW 210 parameter: 211 ******************************************************************************/ 212 static void EPD_2IN13D_ReadBusy(void) 213 { 214 Debug("e-Paper busy\r\n"); 215 UBYTE busy; 216 do { 217 EPD_2IN13D_SendCommand(0x71); 218 busy = DEV_Digital_Read(EPD_BUSY_PIN); 219 busy =!(busy & 0x01); 220 } while(busy); 221 DEV_Delay_ms(200); 222 Debug("e-Paper busy release\r\n"); 223 } 224 225 /****************************************************************************** 226 function : LUT download 227 parameter: 228 ******************************************************************************/ 229 static void EPD_2IN13D_SetFullReg(void) 230 { 231 EPD_2IN13D_SendCommand(0X50); //VCOM AND DATA INTERVAL SETTING 232 EPD_2IN13D_SendData(0xb7); //WBmode:VBDF 17|D7 VBDW 97 VBDB 57 WBRmode:VBDF F7 VBDW 77 VBDB 37 VBDR B7 233 234 unsigned int count; 235 EPD_2IN13D_SendCommand(0x20); 236 for(count=0; count<44; count++) { 237 EPD_2IN13D_SendData(EPD_2IN13D_lut_vcomDC[count]); 238 } 239 240 EPD_2IN13D_SendCommand(0x21); 241 for(count=0; count<42; count++) { 242 EPD_2IN13D_SendData(EPD_2IN13D_lut_ww[count]); 243 } 244 245 EPD_2IN13D_SendCommand(0x22); 246 for(count=0; count<42; count++) { 247 EPD_2IN13D_SendData(EPD_2IN13D_lut_bw[count]); 248 } 249 250 EPD_2IN13D_SendCommand(0x23); 251 for(count=0; count<42; count++) { 252 EPD_2IN13D_SendData(EPD_2IN13D_lut_wb[count]); 253 } 254 255 EPD_2IN13D_SendCommand(0x24); 256 for(count=0; count<42; count++) { 257 EPD_2IN13D_SendData(EPD_2IN13D_lut_bb[count]); 258 } 259 } 260 261 /****************************************************************************** 262 function : LUT download 263 parameter: 264 ******************************************************************************/ 265 static void EPD_2IN13D_SetPartReg(void) 266 { 267 EPD_2IN13D_SendCommand(0x82); //vcom_DC setting 268 EPD_2IN13D_SendData(0x00); 269 EPD_2IN13D_SendCommand(0X50); 270 EPD_2IN13D_SendData(0xb7); 271 272 unsigned int count; 273 EPD_2IN13D_SendCommand(0x20); 274 for(count=0; count<44; count++) { 275 EPD_2IN13D_SendData(EPD_2IN13D_lut_vcom1[count]); 276 } 277 278 EPD_2IN13D_SendCommand(0x21); 279 for(count=0; count<42; count++) { 280 EPD_2IN13D_SendData(EPD_2IN13D_lut_ww1[count]); 281 } 282 283 EPD_2IN13D_SendCommand(0x22); 284 for(count=0; count<42; count++) { 285 EPD_2IN13D_SendData(EPD_2IN13D_lut_bw1[count]); 286 } 287 288 EPD_2IN13D_SendCommand(0x23); 289 for(count=0; count<42; count++) { 290 EPD_2IN13D_SendData(EPD_2IN13D_lut_wb1[count]); 291 } 292 293 EPD_2IN13D_SendCommand(0x24); 294 for(count=0; count<42; count++) { 295 EPD_2IN13D_SendData(EPD_2IN13D_lut_bb1[count]); 296 } 297 } 298 299 /****************************************************************************** 300 function : Turn On Display 301 parameter: 302 ******************************************************************************/ 303 static void EPD_2IN13D_TurnOnDisplay(void) 304 { 305 EPD_2IN13D_SendCommand(0x12); //DISPLAY REFRESH 306 DEV_Delay_ms(10); //!!!The delay here is necessary, 200uS at least!!! 307 308 EPD_2IN13D_ReadBusy(); 309 } 310 311 /****************************************************************************** 312 function : Initialize the e-Paper register 313 parameter: 314 ******************************************************************************/ 315 void EPD_2IN13D_Init() 316 { 317 EPD_2IN13D_Reset(); 318 319 EPD_2IN13D_SendCommand(0x01); //POWER SETTING 320 EPD_2IN13D_SendData(0x03); 321 EPD_2IN13D_SendData(0x00); 322 EPD_2IN13D_SendData(0x2b); 323 EPD_2IN13D_SendData(0x2b); 324 EPD_2IN13D_SendData(0x03); 325 326 EPD_2IN13D_SendCommand(0x06); //boost soft start 327 EPD_2IN13D_SendData(0x17); //A 328 EPD_2IN13D_SendData(0x17); //B 329 EPD_2IN13D_SendData(0x17); //C 330 331 EPD_2IN13D_SendCommand(0x04); 332 EPD_2IN13D_ReadBusy(); 333 334 EPD_2IN13D_SendCommand(0x00); //panel setting 335 EPD_2IN13D_SendData(0xbf); //LUT from OTP,128x296 336 EPD_2IN13D_SendData(0x0e); //VCOM to 0V fast 337 338 EPD_2IN13D_SendCommand(0x30); //PLL setting 339 EPD_2IN13D_SendData(0x3a); // 3a 100HZ 29 150Hz 39 200HZ 31 171HZ 340 341 EPD_2IN13D_SendCommand(0x61); //resolution setting 342 EPD_2IN13D_SendData(EPD_2IN13D_WIDTH); 343 EPD_2IN13D_SendData((EPD_2IN13D_HEIGHT >> 8) & 0xff); 344 EPD_2IN13D_SendData(EPD_2IN13D_HEIGHT& 0xff); 345 346 EPD_2IN13D_SendCommand(0x82); //vcom_DC setting 347 EPD_2IN13D_SendData(0x28); 348 } 349 350 /****************************************************************************** 351 function : Clear screen 352 parameter: 353 ******************************************************************************/ 354 void EPD_2IN13D_Clear(void) 355 { 356 UWORD Width, Height; 357 Width = (EPD_2IN13D_WIDTH % 8 == 0)? (EPD_2IN13D_WIDTH / 8 ): (EPD_2IN13D_WIDTH / 8 + 1); 358 Height = EPD_2IN13D_HEIGHT; 359 360 EPD_2IN13D_SendCommand(0x10); 361 for (UWORD j = 0; j < Height; j++) { 362 for (UWORD i = 0; i < Width; i++) { 363 EPD_2IN13D_SendData(0x00); 364 } 365 } 366 367 EPD_2IN13D_SendCommand(0x13); 368 for (UWORD j = 0; j < Height; j++) { 369 for (UWORD i = 0; i < Width; i++) { 370 EPD_2IN13D_SendData(0xFF); 371 } 372 } 373 374 EPD_2IN13D_SetFullReg(); 375 EPD_2IN13D_TurnOnDisplay(); 376 } 377 378 /****************************************************************************** 379 function : Sends the image buffer in RAM to e-Paper and displays 380 parameter: 381 ******************************************************************************/ 382 void EPD_2IN13D_Display(UBYTE *Image) 383 { 384 UWORD Width, Height; 385 Width = (EPD_2IN13D_WIDTH % 8 == 0)? (EPD_2IN13D_WIDTH / 8 ): (EPD_2IN13D_WIDTH / 8 + 1); 386 Height = EPD_2IN13D_HEIGHT; 387 388 EPD_2IN13D_SendCommand(0x10); 389 for (UWORD j = 0; j < Height; j++) { 390 for (UWORD i = 0; i < Width; i++) { 391 EPD_2IN13D_SendData(0x00); 392 } 393 } 394 // Dev_Delay_ms(10); 395 396 EPD_2IN13D_SendCommand(0x13); 397 for (UWORD j = 0; j < Height; j++) { 398 for (UWORD i = 0; i < Width; i++) { 399 EPD_2IN13D_SendData(Image[i + j * Width]); 400 } 401 } 402 // Dev_Delay_ms(10); 403 404 EPD_2IN13D_SetFullReg(); 405 EPD_2IN13D_TurnOnDisplay(); 406 } 407 408 /****************************************************************************** 409 function : Sends the image buffer in RAM to e-Paper and displays 410 parameter: 411 ******************************************************************************/ 412 void EPD_2IN13D_DisplayPart(UBYTE *Image) 413 { 414 /* Set partial Windows */ 415 EPD_2IN13D_SetPartReg(); 416 EPD_2IN13D_SendCommand(0x91); //This command makes the display enter partial mode 417 EPD_2IN13D_SendCommand(0x90); //resolution setting 418 EPD_2IN13D_SendData(0); //x-start 419 EPD_2IN13D_SendData(EPD_2IN13D_WIDTH - 1); //x-end 420 421 EPD_2IN13D_SendData(0); 422 EPD_2IN13D_SendData(0); //y-start 423 EPD_2IN13D_SendData(EPD_2IN13D_HEIGHT / 256); 424 EPD_2IN13D_SendData(EPD_2IN13D_HEIGHT % 256 - 1); //y-end 425 EPD_2IN13D_SendData(0x28); 426 427 UWORD Width; 428 Width = (EPD_2IN13D_WIDTH % 8 == 0)? (EPD_2IN13D_WIDTH / 8 ): (EPD_2IN13D_WIDTH / 8 + 1); 429 430 /* send data */ 431 EPD_2IN13D_SendCommand(0x10); 432 for (UWORD j = 0; j < EPD_2IN13D_HEIGHT; j++) { 433 for (UWORD i = 0; i < Width; i++) { 434 EPD_2IN13D_SendData(~Image[i + j * Width]); 435 } 436 } 437 438 EPD_2IN13D_SendCommand(0x13); 439 for (UWORD j = 0; j < EPD_2IN13D_HEIGHT; j++) { 440 for (UWORD i = 0; i < Width; i++) { 441 EPD_2IN13D_SendData(Image[i + j * Width]); 442 } 443 } 444 445 /* Set partial refresh */ 446 EPD_2IN13D_TurnOnDisplay(); 447 } 448 449 450 /****************************************************************************** 451 function : Enter sleep mode 452 parameter: 453 ******************************************************************************/ 454 void EPD_2IN13D_Sleep(void) 455 { 456 EPD_2IN13D_SendCommand(0X50); 457 EPD_2IN13D_SendData(0xf7); 458 EPD_2IN13D_SendCommand(0X02); //power off 459 EPD_2IN13D_SendCommand(0X07); //deep sleep 460 EPD_2IN13D_SendData(0xA5); 461 }