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 #include "EPD.h" 17 18 typedef enum { 19 LOW=0, 20 HIGH=1 21 } EPD_pinstate; 22 23 static void EPD_line(uint16_t line, const uint8_t *data, uint8_t fixed_value, uint8_t read_progmem, EPD_stage stage); 24 static void SPI_send(const uint8_t *buffer, uint16_t length); 25 static void SPI_put(uint8_t c); 26 static void SPI_put_wait(uint8_t c); 27 28 static void EPD_Pin_init(); 29 static void EPD_Pin_EPD_CS(EPD_pinstate pin); 30 static void EPD_Pin_RESET(EPD_pinstate pin); 31 static void EPD_Pin_PANEL_ON(EPD_pinstate pin); 32 static void EPD_Pin_DISCHARGE(EPD_pinstate pin); 33 static void EPD_Pin_BORDER(EPD_pinstate pin); 34 static EPD_pinstate epd_get_busy(void); 35 36 static void epd_pwm_active(uint16_t delayInMs); 37 38 39 // inline arrays 40 #define ARRAY(type, ...) ((type[]){__VA_ARGS__}) 41 #define CU8(...) (ARRAY(const uint8_t, __VA_ARGS__)) 42 43 static COG_Parameters_t epd; 44 45 /****************************************************************************** 46 * Local functions 47 *****************************************************************************/ 48 49 50 // convert a temperature in Celcius to 51 // the scale factor for frame_*_repeat methods 52 static int16_t EPD_temperature_to_factor_10x(int16_t temperature) { 53 if (temperature <= -10) { 54 return 170; 55 } else if (temperature <= -5) { 56 return 120; 57 } else if (temperature <= 5) { 58 return 80; 59 } else if (temperature <= 10) { 60 return 40; 61 } else if (temperature <= 15) { 62 return 30; 63 } else if (temperature <= 20) { 64 return 20; 65 } else if (temperature <= 40) { 66 return 10; 67 } 68 return 7; 69 } 70 71 72 // One frame of data is the number of lines * rows. For example: 73 // The 1.44??? frame of data is 96 lines * 128 dots. 74 // The 2??? frame of data is 96 lines * 200 dots. 75 // The 2.7??? frame of data is 176 lines * 264 dots. 76 77 // the image is arranged by line which matches the display size 78 // so smallest would have 96 * 32 bytes 79 80 static void EPD_frame_fixed(uint8_t fixed_value, EPD_stage stage) { 81 uint8_t line; 82 for (line = 0; line < epd.lines_per_display ; ++line) { 83 EPD_line(line, 0, fixed_value, FALSE, stage); 84 } 85 } 86 87 static void EPD_frame_data(PROGMEM const uint8_t *image, EPD_stage stage){ 88 uint8_t line; 89 for (line = 0; line < epd.lines_per_display ; ++line) { 90 EPD_line(line, &image[line * epd.bytes_per_line], 0, TRUE, stage); 91 } 92 } 93 94 95 #if defined(EPD_ENABLE_EXTRA_SRAM) 96 static void EPD_frame_sram(const uint8_t *image, EPD_stage stage){ 97 uint8_t line; 98 for (line = 0; line < epd.lines_per_display ; ++line) { 99 EPD_line(line, &image[line * epd.bytes_per_line], 0, FALSE, stage); 100 } 101 } 102 #endif 103 104 105 static void EPD_frame_fixed_repeat(uint8_t fixed_value, EPD_stage stage) { 106 int32_t stage_time = epd.factored_stage_time; 107 do { 108 uint32_t t_start = bsp_getMsTicks(); 109 EPD_frame_fixed(fixed_value, stage); 110 uint32_t t_end = bsp_getMsTicks(); 111 if (t_end > t_start) { 112 stage_time -= t_end - t_start; 113 } else { 114 stage_time -= t_start - t_end + 1 + 0xffffffffU; 115 } 116 } while (stage_time > 0); 117 } 118 119 120 static void EPD_frame_data_repeat(PROGMEM const uint8_t *image, EPD_stage stage) { 121 int32_t stage_time = epd.factored_stage_time; 122 do { 123 uint32_t t_start = bsp_getMsTicks(); 124 EPD_frame_data(image, stage); 125 uint32_t t_end = bsp_getMsTicks(); 126 if (t_end > t_start) { 127 stage_time -= t_end - t_start; 128 } else { 129 stage_time -= t_start - t_end + 1 + 0xffffffffU; 130 } 131 } while (stage_time > 0); 132 } 133 134 #include <limits.h> 135 #if defined(EPD_ENABLE_EXTRA_SRAM) 136 static void EPD_frame_sram_repeat(const uint8_t *image, EPD_stage stage) { 137 int32_t stage_time = epd.factored_stage_time; 138 do { 139 uint32_t t_start = bsp_getMsTicks(); 140 EPD_frame_sram(image, stage); 141 uint32_t t_end = bsp_getMsTicks(); 142 if (t_end > t_start) { 143 stage_time -= t_end - t_start; 144 } else { 145 stage_time -= t_start - t_end + 1 + 0xffffffffU; 146 } 147 } while (stage_time > 0); 148 } 149 #endif 150 151 #if 0 152 typedef void EPD_reader(void *buffer, uint32_t address, uint16_t length); 153 154 static void EPD_frame_cb(uint32_t address, EPD_reader *reader, EPD_stage stage) { 155 static uint8_t buffer[264 / 8]; 156 uint8_t line; 157 for (line = 0; line < epd.lines_per_display; ++line) { 158 reader(buffer, address + line * epd.bytes_per_line, epd.bytes_per_line); 159 EPD_line(line, buffer, 0, FALSE, stage); 160 } 161 } 162 163 static void EPD_frame_cb_repeat(uint32_t address, EPD_reader *reader, EPD_stage stage) { 164 int32_t stage_time = epd.factored_stage_time; 165 do { 166 uint32_t t_start = bsp_getMsTicks(); 167 EPD_frame_cb(address, reader, stage); 168 uint32_t t_end = bsp_getMsTicks(); 169 if (t_end > t_start) { 170 stage_time -= t_end - t_start; 171 } else { 172 stage_time -= t_start - t_end + 1 + 0xffffffffU; 173 } 174 } while (stage_time > 0); 175 } 176 #endif 177 178 static void EPD_line(uint16_t line, const uint8_t *data, uint8_t fixed_value, uint8_t read_progmem, EPD_stage stage) { 179 // charge pump voltage levels 180 bsp_delayUs(10); 181 SPI_send(CU8(0x70, 0x04), 2); 182 bsp_delayUs(10); 183 SPI_send(epd.gate_source, epd.gate_source_length); 184 185 // send data 186 bsp_delayUs(10); 187 SPI_send(CU8(0x70, 0x0a), 2); 188 bsp_delayUs(10); 189 190 // CS low 191 EPD_Pin_EPD_CS(LOW); 192 SPI_put_wait(0x72); 193 194 // even pixels 195 uint16_t b; 196 for (b = epd.bytes_per_line; b > 0; --b) { 197 if (0 != data) { 198 uint8_t pixels = data[b - 1] & 0xaa; 199 switch(stage) { 200 case EPD_compensate: // B -> W, W -> B (Current Image) 201 pixels = 0xaa | ((pixels ^ 0xaa) >> 1); 202 break; 203 case EPD_white: // B -> N, W -> W (Current Image) 204 pixels = 0x55 + ((pixels ^ 0xaa) >> 1); 205 break; 206 case EPD_inverse: // B -> N, W -> B (New Image) 207 pixels = 0x55 | (pixels ^ 0xaa); 208 break; 209 case EPD_normal: // B -> B, W -> W (New Image) 210 pixels = 0xaa | (pixels >> 1); 211 break; 212 } 213 SPI_put_wait(pixels); 214 } else { 215 SPI_put_wait(fixed_value); 216 } } 217 218 // scan line 219 for (b = 0; b < epd.bytes_per_scan; ++b) { 220 if (line / 4 == b) { 221 SPI_put_wait(0xc0 >> (2 * (line & 0x03))); 222 } else { 223 SPI_put_wait(0x00); 224 } 225 } 226 227 // odd pixels 228 for (b = 0; b < epd.bytes_per_line; ++b) { 229 if (0 != data) { 230 uint8_t pixels = data[b] & 0x55; 231 switch(stage) { 232 case EPD_compensate: // B -> W, W -> B (Current Image) 233 pixels = 0xaa | (pixels ^ 0x55); 234 break; 235 case EPD_white: // B -> N, W -> W (Current Image) 236 pixels = 0x55 + (pixels ^ 0x55); 237 break; 238 case EPD_inverse: // B -> N, W -> B (New Image) 239 pixels = 0x55 | ((pixels ^ 0x55) << 1); 240 break; 241 case EPD_normal: // B -> B, W -> W (New Image) 242 pixels = 0xaa | pixels; 243 break; 244 } 245 uint8_t p1 = (pixels >> 6) & 0x03; 246 uint8_t p2 = (pixels >> 4) & 0x03; 247 uint8_t p3 = (pixels >> 2) & 0x03; 248 uint8_t p4 = (pixels >> 0) & 0x03; 249 pixels = (p1 << 0) | (p2 << 2) | (p3 << 4) | (p4 << 6); 250 SPI_put_wait(pixels); 251 } else { 252 SPI_put_wait(fixed_value); 253 } 254 } 255 256 if (epd.filler == TRUE) { 257 SPI_put_wait(0x00); 258 } 259 260 // CS high 261 EPD_Pin_EPD_CS(HIGH); 262 263 // output data to panel 264 bsp_delayUs(10); 265 SPI_send(CU8(0x70, 0x02), 2); 266 bsp_delayUs(10); 267 SPI_send(CU8(0x72, 0x2f), 2); 268 } 269 270 271 /****************************************************************************** 272 * Public functions 273 *****************************************************************************/ 274 275 276 void EPD_init(EPD_size size) { 277 static uint8_t cs[] = {0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00}; 278 static uint8_t gs[] = {0x72, 0x03}; 279 280 EPD_Pin_init(); 281 282 epd.size = size; 283 epd.stage_time = 480; // milliseconds 284 epd.lines_per_display = 96; 285 epd.dots_per_line = 128; 286 epd.bytes_per_line = 128 / 8; 287 epd.bytes_per_scan = 96 / 4; 288 epd.filler = FALSE; 289 epd.channel_select = cs; 290 epd.channel_select_length = sizeof(cs); 291 epd.gate_source = gs; 292 epd.gate_source_length = sizeof(gs); 293 294 // set up size structure 295 switch (size) { 296 default: 297 case EPD_1_44: // default so no change 298 break; 299 300 case EPD_2_0: { 301 epd.lines_per_display = 96; 302 epd.dots_per_line = 200; 303 epd.bytes_per_line = 200 / 8; 304 epd.bytes_per_scan = 96 / 4; 305 epd.filler = TRUE; 306 cs[0] = 0x72; 307 cs[1] = 0x00; 308 cs[2] = 0x00; 309 cs[3] = 0x00; 310 cs[4] = 0x00; 311 cs[5] = 0x01; 312 cs[6] = 0xff; 313 cs[7] = 0xe0; 314 cs[8] = 0x00; 315 gs[0] = 0x72; 316 gs[1] = 0x03; 317 break; 318 } 319 320 case EPD_2_7: { 321 epd.stage_time = 630; // milliseconds 322 epd.lines_per_display = 176; 323 epd.dots_per_line = 264; 324 epd.bytes_per_line = 264 / 8; 325 epd.bytes_per_scan = 176 / 4; 326 epd.filler = TRUE; 327 cs[0] = 0x72; 328 cs[1] = 0x00; 329 cs[2] = 0x00; 330 cs[3] = 0x00; 331 cs[4] = 0x7f; 332 cs[5] = 0xff; 333 cs[6] = 0xfe; 334 cs[7] = 0x00; 335 cs[8] = 0x00; 336 gs[0] = 0x72; 337 gs[1] = 0x00; 338 break; 339 } 340 } 341 342 epd.factored_stage_time = epd.stage_time; 343 } 344 345 346 void EPD_begin(void) 347 { 348 // power up sequence 349 SPI_put(0x00); 350 351 EPD_Pin_RESET(LOW); 352 EPD_Pin_PANEL_ON(LOW); 353 EPD_Pin_DISCHARGE(LOW); 354 EPD_Pin_BORDER(LOW); 355 EPD_Pin_EPD_CS(LOW); 356 357 // PWM_start(this->EPD_Pin_PWM); 358 // Delay_ms(5); 359 epd_pwm_active(5); 360 EPD_Pin_PANEL_ON(HIGH); 361 // Delay_ms(10); 362 epd_pwm_active(10); 363 364 EPD_Pin_RESET(HIGH); 365 EPD_Pin_BORDER(HIGH); 366 EPD_Pin_EPD_CS(HIGH); 367 // Delay_ms(5); 368 epd_pwm_active(5); 369 370 EPD_Pin_RESET(LOW); 371 // Delay_ms(5); 372 epd_pwm_active(5); 373 374 EPD_Pin_RESET(HIGH); 375 // Delay_ms(5); 376 epd_pwm_active(5); 377 378 // wait for COG to become ready 379 while (HIGH == epd_get_busy()) { 380 epd_pwm_active(10); 381 } 382 383 // channel select 384 bsp_delayUs(10); 385 SPI_send(CU8(0x70, 0x01), 2); 386 bsp_delayUs(10); 387 SPI_send(epd.channel_select, epd.channel_select_length); 388 389 // DC/DC frequency 390 bsp_delayUs(10); 391 SPI_send(CU8(0x70, 0x06), 2); 392 bsp_delayUs(10); 393 SPI_send(CU8(0x72, 0xff), 2); 394 395 // high power mode osc 396 bsp_delayUs(10); 397 SPI_send(CU8(0x70, 0x07), 2); 398 bsp_delayUs(10); 399 SPI_send(CU8(0x72, 0x9d), 2); 400 401 402 // disable ADC 403 bsp_delayUs(10); 404 SPI_send(CU8(0x70, 0x08), 2); 405 bsp_delayUs(10); 406 SPI_send(CU8(0x72, 0x00), 2); 407 408 // Vcom level 409 bsp_delayUs(10); 410 SPI_send(CU8(0x70, 0x09), 2); 411 bsp_delayUs(10); 412 SPI_send(CU8(0x72, 0xd0, 0x00), 3); 413 414 // gate and source voltage levels 415 bsp_delayUs(10); 416 SPI_send(CU8(0x70, 0x04), 2); 417 bsp_delayUs(10); 418 SPI_send(epd.gate_source, epd.gate_source_length); 419 420 // Delay_ms(5); //??? 421 epd_pwm_active(5); 422 423 // driver latch on 424 bsp_delayUs(10); 425 SPI_send(CU8(0x70, 0x03), 2); 426 bsp_delayUs(10); 427 SPI_send(CU8(0x72, 0x01), 2); 428 429 // driver latch off 430 bsp_delayUs(10); 431 SPI_send(CU8(0x70, 0x03), 2); 432 bsp_delayUs(10); 433 SPI_send(CU8(0x72, 0x00), 2); 434 435 // Delay_ms(5); 436 epd_pwm_active(5); 437 438 // charge pump positive voltage on 439 bsp_delayUs(10); 440 SPI_send(CU8(0x70, 0x05), 2); 441 bsp_delayUs(10); 442 SPI_send(CU8(0x72, 0x01), 2); 443 444 // final delay before PWM off 445 // Delay_ms(30); 446 // PWM_stop(this->EPD_Pin_PWM); 447 epd_pwm_active(30); 448 449 // charge pump negative voltage on 450 bsp_delayUs(10); 451 SPI_send(CU8(0x70, 0x05), 2); 452 bsp_delayUs(10); 453 SPI_send(CU8(0x72, 0x03), 2); 454 455 bsp_delayMs(30); 456 457 // Vcom driver on 458 bsp_delayUs(10); 459 SPI_send(CU8(0x70, 0x05), 2); 460 bsp_delayUs(10); 461 SPI_send(CU8(0x72, 0x0f), 2); 462 463 bsp_delayMs(30); 464 465 // output enable to disable 466 bsp_delayUs(10); 467 SPI_send(CU8(0x70, 0x02), 2); 468 bsp_delayUs(10); 469 SPI_send(CU8(0x72, 0x24), 2); 470 } 471 472 473 void EPD_end(void) { 474 475 EPD_frame_fixed(0x55, EPD_normal); // dummy frame 476 EPD_line(0x7fffu, 0, 0x55, FALSE, EPD_normal); // dummy_line 477 478 bsp_delayMs(25); 479 480 EPD_Pin_BORDER(LOW); 481 bsp_delayMs(30); 482 483 EPD_Pin_BORDER(HIGH); 484 485 // latch reset turn on 486 bsp_delayUs(10); 487 SPI_send(CU8(0x70, 0x03), 2); 488 bsp_delayUs(10); 489 SPI_send(CU8(0x72, 0x01), 2); 490 491 // output enable off 492 bsp_delayUs(10); 493 SPI_send(CU8(0x70, 0x02), 2); 494 bsp_delayUs(10); 495 SPI_send(CU8(0x72, 0x05), 2); 496 497 // Vcom power off 498 bsp_delayUs(10); 499 SPI_send(CU8(0x70, 0x05), 2); 500 bsp_delayUs(10); 501 SPI_send(CU8(0x72, 0x0e), 2); 502 503 // power off negative charge pump 504 bsp_delayUs(10); 505 SPI_send(CU8(0x70, 0x05), 2); 506 bsp_delayUs(10); 507 SPI_send(CU8(0x72, 0x02), 2); 508 509 // discharge 510 bsp_delayUs(10); 511 SPI_send(CU8(0x70, 0x04), 2); 512 bsp_delayUs(10); 513 SPI_send(CU8(0x72, 0x0c), 2); 514 515 bsp_delayMs(120); 516 517 // all charge pumps off 518 bsp_delayUs(10); 519 SPI_send(CU8(0x70, 0x05), 2); 520 bsp_delayUs(10); 521 SPI_send(CU8(0x72, 0x00), 2); 522 523 // turn of osc 524 bsp_delayUs(10); 525 SPI_send(CU8(0x70, 0x07), 2); 526 bsp_delayUs(10); 527 SPI_send(CU8(0x72, 0x0d), 2); 528 529 // discharge internal - 1 530 bsp_delayUs(10); 531 SPI_send(CU8(0x70, 0x04), 2); 532 bsp_delayUs(10); 533 SPI_send(CU8(0x72, 0x50), 2); 534 535 bsp_delayMs(40); 536 537 // discharge internal - 2 538 bsp_delayUs(10); 539 SPI_send(CU8(0x70, 0x04), 2); 540 bsp_delayUs(10); 541 SPI_send(CU8(0x72, 0xA0), 2); 542 543 bsp_delayMs(40); 544 545 // discharge internal - 3 546 bsp_delayUs(10); 547 SPI_send(CU8(0x70, 0x04), 2); 548 bsp_delayUs(10); 549 SPI_send(CU8(0x72, 0x00), 2); 550 551 // turn of power and all signals 552 EPD_Pin_RESET(LOW); 553 EPD_Pin_PANEL_ON(LOW); 554 EPD_Pin_BORDER(LOW); 555 EPD_Pin_EPD_CS(LOW); 556 557 EPD_Pin_DISCHARGE(HIGH); 558 559 SPI_put(0x00); 560 561 bsp_delayMs(150); 562 563 EPD_Pin_DISCHARGE(LOW); 564 } 565 566 567 void EPD_setFactor(int16_t temperature) { 568 epd.factored_stage_time = epd.stage_time * EPD_temperature_to_factor_10x(temperature) / 10; 569 } 570 571 // clear display (anything -> white) 572 void EPD_clear() { 573 EPD_frame_fixed_repeat(0xff, EPD_compensate); 574 EPD_frame_fixed_repeat(0xff, EPD_white); 575 EPD_frame_fixed_repeat(0xaa, EPD_inverse); 576 EPD_frame_fixed_repeat(0xaa, EPD_normal); 577 } 578 579 // assuming a clear (white) screen output an image (PROGMEM data) 580 void EPD_image(PROGMEM const uint8_t *image) { 581 EPD_frame_fixed_repeat(0xaa, EPD_compensate); 582 EPD_frame_fixed_repeat(0xaa, EPD_white); 583 EPD_frame_data_repeat(image, EPD_inverse); 584 EPD_frame_data_repeat(image, EPD_normal); 585 } 586 587 // change from old image to new image (PROGMEM data) 588 void EPD_image_progmem(PROGMEM const uint8_t *old_image, PROGMEM const uint8_t *new_image) { 589 EPD_frame_data_repeat(old_image, EPD_compensate); 590 EPD_frame_data_repeat(old_image, EPD_white); 591 EPD_frame_data_repeat(new_image, EPD_inverse); 592 EPD_frame_data_repeat(new_image, EPD_normal); 593 } 594 595 #if defined(EPD_ENABLE_EXTRA_SRAM) 596 // change from old image to new image (SRAM version) 597 void EPD_image_sram(const uint8_t *old_image, const uint8_t *new_image) { 598 EPD_frame_sram_repeat(old_image, EPD_compensate); 599 EPD_frame_sram_repeat(old_image, EPD_white); 600 EPD_frame_sram_repeat(new_image, EPD_inverse); 601 EPD_frame_sram_repeat(new_image, EPD_normal); 602 } 603 #endif 604 605 606 static void SPI_put(uint8_t c) { 607 uint8_t placeholder = c; 608 bsp_spiWrite(&placeholder, 1); 609 } 610 611 612 static void SPI_put_wait(uint8_t c) { 613 614 SPI_put(c); 615 616 // wait for COG ready 617 while (HIGH == epd_get_busy()) { 618 } 619 } 620 621 622 static void SPI_send(const uint8_t *buffer, uint16_t length) { 623 // CS low 624 EPD_Pin_EPD_CS(LOW); 625 626 bsp_spiWrite((uint8_t*)buffer, length); 627 628 // CS high 629 EPD_Pin_EPD_CS(HIGH); 630 } 631 632 static void EPD_Pin_init() 633 { 634 bsp_pinDir(6, 1); // CS 635 bsp_pinDir(7, 0); // Driver Busy 636 bsp_pinDir(8, 1); // Border 637 bsp_pinDir(11, 1); // Pwm 638 bsp_pinDir(12, 1); // Reset 639 bsp_pinDir(13, 1); // Panel On 640 bsp_pinDir(14, 1); // Discharge 641 } 642 643 static void EPD_Pin_EPD_CS(EPD_pinstate pin) 644 { 645 if (HIGH == pin) { 646 bsp_pinSet(6); 647 } 648 else { 649 bsp_pinClr(6); 650 } 651 } 652 653 static void EPD_Pin_RESET(EPD_pinstate pin) 654 { 655 if (HIGH == pin) { 656 bsp_pinSet(12); 657 } 658 else { 659 bsp_pinClr(12); 660 } 661 } 662 663 static void EPD_Pin_PANEL_ON(EPD_pinstate pin) 664 { 665 if (HIGH == pin) { 666 bsp_pinSet(13); 667 } 668 else { 669 bsp_pinClr(13); 670 } 671 } 672 673 static void EPD_Pin_DISCHARGE(EPD_pinstate pin) 674 { 675 if (HIGH == pin) { 676 bsp_pinSet(14); 677 } 678 else { 679 bsp_pinClr(14); 680 } 681 } 682 683 static void EPD_Pin_BORDER(EPD_pinstate pin) 684 { 685 if (HIGH == pin) { 686 bsp_pinSet(8); 687 } 688 else { 689 bsp_pinClr(8); 690 } 691 } 692 693 static EPD_pinstate epd_get_busy(void) 694 { 695 if (bsp_pinState(7)) 696 return HIGH; 697 else 698 return LOW; 699 } 700 701 static void epd_pwm_active(uint16_t delayInMs) 702 { 703 uint16_t numOfIterations; 704 705 numOfIterations = delayInMs * 100; 706 707 for(; numOfIterations > 0; numOfIterations--) 708 { 709 bsp_pinSet(11); 710 bsp_delayUs(5); //100kHz 711 bsp_pinClr(11); 712 bsp_delayUs(5); 713 } 714 }