1 // Copyright 2013 Pervasive Displays, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, 10 // software distributed under the License is distributed on an 11 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 // express or implied. See the License for the specific language 13 // governing permissions and limitations under the License. 14 15 /****************************************************************************** 16 * Includes 17 *****************************************************************************/ 18 //#include "driver_config.h" 19 //#include "target_config.h" 20 //#include "type.h" 21 //#include "gpio.h" 22 #include "Display_COG_Process.h" 23 #include "Display_Hardware_Driver.h" 24 #include "Display_Controller.h" 25 #include <stdio.h> 26 27 28 /****************************************************************************** 29 * Defines and typedefs 30 *****************************************************************************/ 31 #define _GaugeFrameTimeMark 0 32 33 const COG_Parameters_t COG_Parameters[3]= { 34 { //for 1.44" 35 {0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0x00}, 36 0x03, 37 (128/8), 38 96, 39 (((128+96)*2)/8), 40 (43), 41 480 42 }, 43 { //for 2.0" 44 {0x00,0x00,0x00,0x00,0x01,0xFF,0xE0,0x00}, 45 0x03, 46 (200/8), 47 96, 48 (((200+96)*2)/8)+1, 49 (53), 50 480 51 }, 52 { //for 2.7" 53 {0x00,0x00,0x00,0x7F,0xFF,0xFE,0x00,0x00}, 54 0x00, 55 (264/8), 56 176, 57 (((264+176)*2)/8)+1, 58 105, 59 630 60 }, 61 }; 62 63 const uint8_t ScanTable[4] = {0xC0, 0x30, 0x0C, 0x03}; 64 65 66 /****************************************************************************** 67 * Local variables 68 *****************************************************************************/ 69 static uint32_t StageTime = 480; 70 static COG_LineDataPacket_t COG_Line; 71 static uint16_t EPD_Type_Index = 0; 72 static uint16_t cnt = 0; 73 static uint32_t Currentframe; 74 static uint8_t *DataLineEven; 75 static uint8_t *DataLineOdd; 76 static uint8_t *DataLineScan; 77 static uint8_t *DisplayOrgPtr; 78 79 80 /****************************************************************************** 81 * Local functions 82 *****************************************************************************/ 83 static void SetTemperature_Factor(uint8_t EPD_Type_Index) 84 { 85 int16_t Temperature; 86 87 //Get current temperature 88 Temperature = epd_get_temperature(); 89 90 if (Temperature < -10) 91 { 92 StageTime = COG_Parameters[EPD_Type_Index].StageTime * 17; 93 } 94 else if (Temperature < -5) 95 { 96 StageTime = COG_Parameters[EPD_Type_Index].StageTime * 12; 97 } 98 else if (Temperature < 5) 99 { 100 StageTime = COG_Parameters[EPD_Type_Index].StageTime * 8; 101 } 102 else if (Temperature < 10) 103 { 104 StageTime = COG_Parameters[EPD_Type_Index].StageTime * 4; 105 } 106 else if (Temperature < 15) 107 { 108 StageTime = COG_Parameters[EPD_Type_Index].StageTime * 3; 109 } 110 else if (Temperature < 20) 111 { 112 StageTime = COG_Parameters[EPD_Type_Index].StageTime * 2; 113 } 114 else if (Temperature < 40) 115 { 116 StageTime = COG_Parameters[EPD_Type_Index].StageTime * 1; 117 } 118 else 119 { 120 StageTime = (COG_Parameters[EPD_Type_Index].StageTime * 7)/10; 121 } 122 } 123 124 static void Driver_TypeSelect(uint8_t typeIndex) 125 { 126 switch(typeIndex) 127 { 128 case EPDType_144: 129 DataLineEven=&COG_Line.LineDatas.COG_144LineData.Even[0]; 130 DataLineOdd=&COG_Line.LineDatas.COG_144LineData.Odd[0]; 131 DataLineScan=&COG_Line.LineDatas.COG_144LineData.Scan[0]; 132 break; 133 case EPDType_200: 134 DataLineEven=&COG_Line.LineDatas.COG_20LineData.Even[0]; 135 DataLineOdd=&COG_Line.LineDatas.COG_20LineData.Odd[0]; 136 DataLineScan=&COG_Line.LineDatas.COG_20LineData.Scan[0]; 137 break; 138 case EPDType_270: 139 DataLineEven=&COG_Line.LineDatas.COG_27LineData.Even[0]; 140 DataLineOdd=&COG_Line.LineDatas.COG_27LineData.Odd[0]; 141 DataLineScan=&COG_Line.LineDatas.COG_27LineData.Scan[0]; 142 break; 143 } 144 } 145 146 //#pragma GCC optimize ("-O3") 147 static void Display_Stage_1 (uint8_t *PreviousPicture) 148 { 149 uint16_t i,j,k; // general counters 150 uint8_t TempByte; // Temporary storage for image data check 151 uint16_t StartClock; 152 #ifdef DISPLAY_180_DEGREE 153 uint8_t *DataLinePrt; 154 DisplayOrgPtr = (PreviousPicture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); 155 #else 156 DisplayOrgPtr = PreviousPicture; 157 #endif 158 Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; 159 //TestPinTrigger(); 160 cnt = 0; 161 StartClock = epd_GetCurrentTimeTick(); 162 do 163 { 164 // TestPin2Trigger(); 165 PreviousPicture = DisplayOrgPtr; 166 #ifdef DISPLAY_180_DEGREE 167 DataLinePrt = PreviousPicture; 168 #endif 169 for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line 170 { 171 // SPI (0x04, ...) 172 epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); 173 k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; 174 for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line 175 { 176 TempByte = (*PreviousPicture++); 177 #ifdef DISPLAY_180_DEGREE 178 DataLineEven[j] = ((TempByte & 0x80) ? BLACK3 : WHITE3) 179 | ((TempByte & 0x20) ? BLACK2 : WHITE2) 180 | ((TempByte & 0x08) ? BLACK1 : WHITE1) 181 | ((TempByte & 0x02) ? BLACK0 : WHITE0); 182 183 DataLineOdd[k--] = ((TempByte & 0x01) ? BLACK3 : WHITE3) 184 | ((TempByte & 0x04) ? BLACK2 : WHITE2) 185 | ((TempByte & 0x10) ? BLACK1 : WHITE1) 186 | ((TempByte & 0x40) ? BLACK0 : WHITE0); 187 DataLinePrt--; 188 #else 189 DataLineOdd[j] = ((TempByte & 0x80) ? BLACK3 : WHITE3) 190 | ((TempByte & 0x20) ? BLACK2 : WHITE2) 191 | ((TempByte & 0x08) ? BLACK1 : WHITE1) 192 | ((TempByte & 0x02) ? BLACK0 : WHITE0); 193 194 DataLineEven[k--] = ((TempByte & 0x01) ? BLACK3 : WHITE3) 195 | ((TempByte & 0x04) ? BLACK2 : WHITE2) 196 | ((TempByte & 0x10) ? BLACK1 : WHITE1) 197 | ((TempByte & 0x40) ? BLACK0 : WHITE0); 198 #endif 199 } 200 #ifdef DISPLAY_180_DEGREE 201 PreviousPicture = DataLinePrt; 202 #endif 203 DataLineScan[(i>>2)] = ScanTable[(i%4)]; 204 // SPI (0x0a, line data....) 205 epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); 206 207 // SPI (0x02, 0x25) 208 epd_SPI_Send_Byte(0x02, 0x2F); 209 210 DataLineScan[(i>>2)] = 0; 211 } 212 #if(!_GaugeFrameTimeMark) 213 if(COG_Parameters[EPD_Type_Index].FrameTime>0) 214 { 215 while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); 216 } 217 #endif 218 //TestPin2Trigger(); 219 Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; 220 cnt++; 221 }while (StageTime>Currentframe); 222 // TestPin2Trigger(); 223 while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); 224 // TestPin2Trigger(); 225 // TestPinTrigger(); 226 } 227 228 //#pragma GCC optimize ("-O3") 229 static void Display_Stage_2 (uint8_t *PreviousPicture) 230 { 231 uint16_t i, j, k; // general counters 232 uint8_t TempByte; // Temporary storage for image data check 233 uint16_t StartClock; 234 #ifdef DISPLAY_180_DEGREE 235 uint8_t *DataLinePrt; 236 DisplayOrgPtr = (PreviousPicture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); 237 #else 238 DisplayOrgPtr = PreviousPicture; 239 #endif 240 241 // TestPinTrigger(); 242 cnt = 0; 243 Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; 244 StartClock = epd_GetCurrentTimeTick(); 245 do 246 { 247 // TestPin2Trigger(); 248 PreviousPicture = DisplayOrgPtr; 249 #ifdef DISPLAY_180_DEGREE 250 DataLinePrt = PreviousPicture; 251 #endif 252 for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line 253 { 254 // SPI (0x04, ...) 255 epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); 256 k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; 257 for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // make every bit in the line black 258 { 259 TempByte =(*PreviousPicture++); 260 #ifdef DISPLAY_180_DEGREE 261 DataLineEven[j] = ((TempByte & 0x80) ? WHITE3 : NOTHING) 262 | ((TempByte & 0x20) ? WHITE2 : NOTHING) 263 | ((TempByte & 0x08) ? WHITE1 : NOTHING) 264 | ((TempByte & 0x02) ? WHITE0 : NOTHING); 265 DataLineOdd[k--] = ((TempByte & 0x01) ? WHITE3 : NOTHING) 266 | ((TempByte & 0x04) ? WHITE2 : NOTHING) 267 | ((TempByte & 0x10) ? WHITE1 : NOTHING) 268 | ((TempByte & 0x40) ? WHITE0 : NOTHING); 269 DataLinePrt--; 270 #else 271 DataLineOdd[j] = ((TempByte & 0x80) ? WHITE3 : NOTHING) 272 | ((TempByte & 0x20) ? WHITE2 : NOTHING) 273 | ((TempByte & 0x08) ? WHITE1 : NOTHING) 274 | ((TempByte & 0x02) ? WHITE0 : NOTHING); 275 DataLineEven[k--] = ((TempByte & 0x01) ? WHITE3 : NOTHING) 276 | ((TempByte & 0x04) ? WHITE2 : NOTHING) 277 | ((TempByte & 0x10) ? WHITE1 : NOTHING) 278 | ((TempByte & 0x40) ? WHITE0 : NOTHING); 279 #endif 280 } 281 282 #ifdef DISPLAY_180_DEGREE 283 PreviousPicture = DataLinePrt; 284 #endif 285 DataLineScan[(i>>2)] = ScanTable[(i%4)]; 286 // SPI (0x0a, line data....) 287 epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); 288 289 epd_SPI_Send_Byte(0x02, 0x25); 290 291 DataLineScan[(i>>2)] = 0; 292 } 293 #if(!_GaugeFrameTimeMark) 294 if(COG_Parameters[EPD_Type_Index].FrameTime>0) 295 { 296 while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); 297 } 298 #endif 299 //TestPin2Trigger(); 300 Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; 301 cnt++; 302 }while (StageTime>Currentframe); 303 // TestPin2Trigger(); 304 while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); 305 // TestPin2Trigger(); 306 // TestPinTrigger(); 307 } 308 309 310 //#pragma GCC optimize ("-O3") 311 static void Display_Stage_3 (uint8_t *Picture) 312 { 313 uint16_t i, j,k; // general counters 314 uint8_t TempByte; // Temporary storage for image data check 315 uint16_t StartClock; 316 #ifdef DISPLAY_180_DEGREE 317 uint8_t *DataLinePrt; 318 DisplayOrgPtr = (Picture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); 319 #else 320 DisplayOrgPtr = Picture; 321 #endif 322 Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; 323 cnt = 0; 324 // TestPinTrigger(); 325 StartClock = epd_GetCurrentTimeTick(); 326 do 327 { 328 // TestPin2Trigger(); 329 Picture = DisplayOrgPtr; 330 #ifdef DISPLAY_180_DEGREE 331 DataLinePrt = Picture; 332 #endif 333 for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line 334 { 335 // SPI (0x04, 0x03) 336 epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); 337 k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; 338 for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line 339 { 340 TempByte = (*Picture++); 341 #ifdef DISPLAY_180_DEGREE 342 DataLineEven[j] = ((TempByte & 0x80) ? BLACK3 : NOTHING) 343 | ((TempByte & 0x20) ? BLACK2 : NOTHING ) 344 | ((TempByte & 0x08) ? BLACK1 : NOTHING ) 345 | ((TempByte & 0x02) ? BLACK0 : NOTHING ); 346 347 DataLineOdd[k--] = ((TempByte & 0x01) ? BLACK3 : NOTHING) 348 | ((TempByte & 0x04) ? BLACK2 : NOTHING ) 349 | ((TempByte & 0x10) ? BLACK1 : NOTHING ) 350 | ((TempByte & 0x40) ? BLACK0 : NOTHING ); 351 DataLinePrt--; 352 #else 353 DataLineOdd[j] = ((TempByte & 0x80) ? BLACK3 : NOTHING) 354 | ((TempByte & 0x20) ? BLACK2 : NOTHING ) 355 | ((TempByte & 0x08) ? BLACK1 : NOTHING ) 356 | ((TempByte & 0x02) ? BLACK0 : NOTHING ); 357 358 DataLineEven[k--] = ((TempByte & 0x01) ? BLACK3 : NOTHING) 359 | ((TempByte & 0x04) ? BLACK2 : NOTHING ) 360 | ((TempByte & 0x10) ? BLACK1 : NOTHING ) 361 | ((TempByte & 0x40) ? BLACK0 : NOTHING ); 362 #endif 363 } 364 #ifdef DISPLAY_180_DEGREE 365 Picture = DataLinePrt; 366 #endif 367 DataLineScan[(i>>2)] = ScanTable[(i%4)]; 368 // SPI (0x0a, line data....) 369 epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); 370 371 epd_SPI_Send_Byte(0x02, 0x2F); 372 373 DataLineScan[(i>>2)] = 0; 374 } 375 #if(!_GaugeFrameTimeMark) 376 if(COG_Parameters[EPD_Type_Index].FrameTime>0) 377 { 378 while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); 379 } 380 #endif 381 //TestPin2Trigger(); 382 Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; 383 cnt++; 384 }while (StageTime>Currentframe); 385 // TestPin2Trigger(); 386 while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); 387 // TestPin2Trigger(); 388 // TestPinTrigger(); 389 } 390 391 //#pragma GCC optimize ("-O3") 392 static void Display_Stage_4 (uint8_t *Picture) 393 { 394 uint16_t i, j,k; // general counters 395 uint8_t TempByte; // Temporary storage for image data check 396 uint16_t StartClock; 397 #ifdef DISPLAY_180_DEGREE 398 uint8_t *DataLinePrt; 399 DisplayOrgPtr = (Picture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); 400 #else 401 DisplayOrgPtr = Picture; 402 #endif 403 Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; 404 cnt = 0; 405 // TestPinTrigger(); 406 407 StartClock = epd_GetCurrentTimeTick(); 408 do 409 { 410 // TestPin2Trigger(); 411 Picture = DisplayOrgPtr; 412 #ifdef DISPLAY_180_DEGREE 413 DataLinePrt = Picture; 414 #endif 415 for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line 416 { 417 // SPI (0x04, ...) 418 epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); 419 k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; 420 for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line 421 { 422 TempByte =(*Picture++); 423 #ifdef DISPLAY_180_DEGREE 424 DataLineEven[j] = ((TempByte & 0x80) ? WHITE3 : BLACK3 ) 425 | ((TempByte & 0x20) ? WHITE2 : BLACK2 ) 426 | ((TempByte & 0x08) ? WHITE1 : BLACK1 ) 427 | ((TempByte & 0x02) ? WHITE0 : BLACK0 ); 428 429 DataLineOdd[k--] = ((TempByte & 0x01) ? WHITE3 : BLACK3 ) 430 | ((TempByte & 0x04) ? WHITE2 : BLACK2 ) 431 | ((TempByte & 0x10) ? WHITE1 : BLACK1 ) 432 | ((TempByte & 0x40) ? WHITE0 : BLACK0 ); 433 DataLinePrt--; 434 #else 435 DataLineOdd[j] = ((TempByte & 0x80) ? WHITE3 : BLACK3 ) 436 | ((TempByte & 0x20) ? WHITE2 : BLACK2 ) 437 | ((TempByte & 0x08) ? WHITE1 : BLACK1 ) 438 | ((TempByte & 0x02) ? WHITE0 : BLACK0 ); 439 440 DataLineEven[k--] = ((TempByte & 0x01) ? WHITE3 : BLACK3 ) 441 | ((TempByte & 0x04) ? WHITE2 : BLACK2 ) 442 | ((TempByte & 0x10) ? WHITE1 : BLACK1 ) 443 | ((TempByte & 0x40) ? WHITE0 : BLACK0 ); 444 #endif 445 } 446 #ifdef DISPLAY_180_DEGREE 447 Picture = DataLinePrt; 448 #endif 449 DataLineScan[(i>>2)] = ScanTable[(i%4)]; 450 // SPI (0x0a, line data....) 451 epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); 452 453 epd_SPI_Send_Byte(0x02, 0x2F); 454 455 DataLineScan[(i>>2)] = 0; 456 } 457 #if(!_GaugeFrameTimeMark) 458 if(COG_Parameters[EPD_Type_Index].FrameTime>0) 459 { 460 while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); 461 } 462 #endif 463 //TestPin2Trigger(); 464 Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; 465 cnt++; 466 }while (StageTime>Currentframe); 467 468 // TestPin2Trigger(); 469 while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); 470 // TestPin2Trigger(); 471 // TestPinTrigger(); 472 } 473 474 static void Display_Nothing (void) 475 { 476 uint16_t i; // general counters 477 478 for (i = 0; i < COG_Parameters[EPD_Type_Index].HORIZONTAL; i++) // make every bit in the line white 479 { 480 DataLineEven[i] = 0x00; 481 DataLineOdd[i] = 0x00; 482 } 483 484 for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line 485 { 486 epd_SPI_Send_Byte(0x04, 0x03); 487 DataLineScan[(i>>2)] = ScanTable[(i%4)]; 488 // SPI (0x0a, line data....) 489 epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); 490 491 epd_SPI_Send_Byte(0x02, 0x2F); 492 } 493 } 494 495 static void Dummy_line(void) 496 { 497 uint16_t i; 498 499 for (i = 0; i < COG_Parameters[EPD_Type_Index].DataLineSize; i++) 500 { 501 COG_Line.uint8[i] = 0x00; 502 } 503 504 epd_SPI_Send_Byte(0x04, 0x03); 505 506 // SPI (0x0a, line data....) 507 epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); 508 509 epd_SPI_Send_Byte(0x02, 0x2F); 510 } 511 512 513 /****************************************************************************** 514 * Public functions 515 *****************************************************************************/ 516 void epd_HwInit(void) 517 { 518 epd_InitDisplayHardware(); 519 } 520 521 void epd_PowerOn(void) 522 { 523 epd_discharge_low(); 524 epd_rst_low(); 525 epd_cs_low(); 526 epd_spi_init(); 527 528 epd_pwm_active(5); 529 530 epd_panelon_on(); 531 532 epd_pwm_active(10); 533 534 epd_cs_high(); 535 536 //epd_border_high(); 537 538 epd_rst_high(); 539 540 epd_pwm_active(5); 541 542 epd_rst_low(); 543 544 epd_pwm_active(5); 545 546 epd_rst_high(); 547 548 epd_pwm_active(5); 549 } 550 551 void epd_InitializeDriver(uint8_t EPDIndex) 552 { 553 uint8_t SendBuffer[2]; 554 uint16_t k; 555 556 EPD_Type_Index = EPDIndex; 557 558 //Data Line Clear 559 for (k = 0; k <= __LineDataSize; k ++) 560 { 561 COG_Line.uint8[k] = 0x00; 562 } 563 Driver_TypeSelect(EPDIndex); 564 k = 0; 565 566 SetTemperature_Factor(EPDIndex); 567 568 /*while (DRIVERBUSY_Get()) 569 { 570 delayT32B0Us(500); 571 if((k++)>=1000) return;//wait 500 ms 572 } 573 */ 574 575 // SPI (0x01, 0x0000, 0x0000, 0x01ff, 0xe000) 576 epd_SPI_Send(0x01, (uint8_t *)&COG_Parameters[EPDIndex].ChannelSelect, 8); 577 578 epd_SPI_Send_Byte(0x06, 0xff); 579 epd_SPI_Send_Byte(0x07, 0x9d); 580 epd_SPI_Send_Byte(0x08, 0x00); 581 582 // SPI (0x09, 0xd000) 583 SendBuffer[0] = 0xd0; 584 SendBuffer[1] = 0x00; 585 epd_SPI_Send(0x09, SendBuffer, 2); 586 587 epd_SPI_Send_Byte(0x04,COG_Parameters[EPDIndex].VoltageLevel); 588 589 epd_SPI_Send_Byte(0x03, 0x01); 590 epd_SPI_Send_Byte(0x03, 0x00); 591 592 epd_pwm_active(5); 593 594 epd_SPI_Send_Byte(0x05, 0x01); 595 596 epd_pwm_active(30); 597 598 epd_SPI_Send_Byte(0x05, 0x03); 599 epd_delay_ms(30); 600 epd_SPI_Send_Byte(0x05, 0x0f); 601 epd_delay_ms(30); 602 epd_SPI_Send_Byte(0x02, 0x24); 603 printf("Done initialisation.\n"); 604 } 605 606 void epd_Display (uint8_t *pNewImg, uint8_t *pPrevImg) 607 { 608 //COG Process - update display in four steps 609 Display_Stage_1(pPrevImg); 610 Display_Stage_2(pPrevImg); 611 Display_Stage_3(pNewImg); 612 Display_Stage_4(pNewImg); 613 } 614 615 void epd_PowerOff (void) 616 { 617 Display_Nothing(); 618 Dummy_line(); 619 epd_delay_ms(25); 620 621 //border_low(); 622 //epd_delay_ms(_30ms); 623 //border_high(); 624 625 epd_SPI_Send_Byte(0x03, 0x01); 626 epd_SPI_Send_Byte(0x02, 0x05); 627 epd_SPI_Send_Byte(0x05, 0x0E); 628 epd_SPI_Send_Byte(0x05, 0x02); 629 epd_SPI_Send_Byte(0x04, 0x0C); 630 epd_delay_ms(120); 631 epd_SPI_Send_Byte(0x05, 0x00); 632 epd_SPI_Send_Byte(0x07, 0x0D); 633 epd_SPI_Send_Byte(0x04, 0x50); 634 epd_delay_ms(40); 635 epd_SPI_Send_Byte(0x04, 0xA0); 636 epd_delay_ms(40); 637 epd_SPI_Send_Byte(0x04, 0x00); 638 639 epd_rst_low(); 640 epd_cs_low(); 641 epd_spi_detach(); 642 epd_panelon_off(); 643 644 //epd_border_low(); 645 646 epd_discharge_high(); 647 epd_delay_ms(150); 648 epd_discharge_low(); 649 }