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