Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SDFileSystem app epson mbed msp430 pl tests
eink.cpp
00001 // 00002 // Filename: eink.cpp 00003 // 00004 // Flexbook eInk display driver. 00005 // 00006 00007 #include "eink.h" 00008 00009 #include "mbed.h" 00010 00011 #include "ChaN/ff.h" 00012 00013 #include "log.h" 00014 #include "page.h" 00015 00016 #include "pmic-tps65185.h" 00017 #include "vcom.h" 00018 00019 #include <sstream> 00020 00021 const int MAX_INIT_FAILS = 3; 00022 00023 SPI *spi = 0; 00024 00025 #define I2C_PMIC_ADDR_TPS65185 0x68 00026 00027 struct tps65185_info pmic_info; 00028 00029 const char *g_wflib_fatfs_path = "/waveform.dat"; 00030 00031 extern "C" 00032 { 00033 // EPSON drivers. 00034 #include "epson/epson-epdc.h" 00035 #include "epson/epson-s1d135xx.h" 00036 00037 // Plastic Logic drivers. 00038 #include "pl/epdc.h" 00039 #include "pl/dispinfo.h" 00040 #include "pl/platform.h" 00041 #include "pl/types.h" 00042 00043 #include "wflib.h" 00044 00045 void mdelay(uint16_t ms) 00046 { 00047 wait_ms(ms); 00048 } 00049 00050 void msleep(uint16_t ms) 00051 { 00052 mdelay(ms); 00053 } 00054 00055 #define EPSON_RESET p16 00056 #define EPSON_CS_0 p14 00057 #define EPSON_HIRQ p15 00058 #define EPSON_HRDY ~0U 00059 #define EPSON_HDC p24 00060 #define EPSON_CLK_EN 1002 00061 #define EPSON_VCC_EN 1003 00062 00063 enum 00064 { 00065 HVSW_CTRL = p17, /* VCOM switch enable */ 00066 PMIC_EN = p18, /* HV-PMIC enable */ 00067 PMIC_POK = p23, /* HV-PMIC power OK */ 00068 PMIC_FLT = 1006 /* HV-PMIC fault condition */ 00069 }; 00070 00071 static const struct s1d135xx_data g_s1d135xx_data = 00072 { 00073 EPSON_RESET, 00074 EPSON_CS_0, 00075 EPSON_HIRQ, 00076 EPSON_HRDY, 00077 EPSON_HDC, 00078 EPSON_CLK_EN, 00079 EPSON_VCC_EN 00080 }; 00081 00082 void printgpio(unsigned int gpio) 00083 { 00084 switch(gpio) 00085 { 00086 case EPSON_RESET: 00087 printf("EPSON_RESET"); 00088 break; 00089 00090 case EPSON_CS_0: 00091 printf("EPSON_CS_0"); 00092 break; 00093 00094 case EPSON_HIRQ: 00095 printf("EPSON_HIRQ"); 00096 break; 00097 00098 case EPSON_HRDY: 00099 printf("EPSON_HRDY"); 00100 break; 00101 00102 case EPSON_HDC: 00103 printf("EPSON_HDC"); 00104 break; 00105 00106 case EPSON_CLK_EN: 00107 printf("EPSON_CLK_EN"); 00108 break; 00109 00110 case EPSON_VCC_EN: 00111 printf("EPSON_VCC_EN"); 00112 break; 00113 00114 case HVSW_CTRL: 00115 printf("HVSW_CTRL"); 00116 break; 00117 00118 case PMIC_EN: 00119 printf("PMIC_EN"); 00120 break; 00121 00122 case PMIC_POK: 00123 printf("PMIC_POK"); 00124 break; 00125 00126 default: 00127 printf("Unknown GPIO: %u", gpio); 00128 break; 00129 } 00130 } 00131 00132 //#define LOG_GPIO 00133 00134 extern int msp430_gpio_get(unsigned gpio) 00135 { 00136 #ifdef LOG_GPIO 00137 printf("msp430_gpio_get("); 00138 printgpio(gpio); 00139 printf(")\n"); 00140 #endif // LOG_GPIO 00141 00142 int value = 0; 00143 if(gpio != EPSON_CLK_EN && gpio != EPSON_VCC_EN) 00144 { 00145 DigitalIn gpiopin((PinName) gpio); 00146 value = gpiopin; 00147 } else { 00148 #ifdef LOG_GPIO 00149 printf("unused GPIO, ignored\n"); 00150 #endif // LOG_GPIO 00151 } 00152 00153 return value; 00154 } 00155 00156 extern void msp430_gpio_set(unsigned gpio, int value) 00157 { 00158 #ifdef LOG_GPIO 00159 printf("msp430_gpio_set("); 00160 printgpio(gpio); 00161 printf(", %d)\n", value); 00162 #endif // LOG_GPIO 00163 00164 if(gpio != EPSON_CLK_EN && gpio != EPSON_VCC_EN) 00165 { 00166 DigitalOut gpiopin((PinName) gpio); 00167 gpiopin = value; 00168 } else { 00169 #ifdef LOG_GPIO 00170 printf("unused GPIO, ignored\n"); 00171 #endif // LOG_GPIO 00172 } 00173 } 00174 00175 int _swap_bytes(int bytes) 00176 { 00177 uint16_t ubytes = bytes; 00178 ubytes = (ubytes << 8) + (ubytes >> 8); 00179 return ubytes; 00180 } 00181 00182 int parser_read_file_line(FIL *f, char *buffer, int max_length) 00183 { 00184 Log("parser_read_file_line not implemented, returning FR_OK"); 00185 return 0; 00186 } 00187 00188 int parser_read_word(const char *str, const char *sep, unsigned int *out) 00189 { 00190 Log("parser_read_word not implemented, returning 0"); 00191 return 0; 00192 } 00193 00194 //#define LOG_SPI 00195 00196 void spi_read_bytes(uint8_t *buff, size_t size) 00197 { 00198 #ifdef LOG_SPI 00199 printf("spi_read_bytes("); 00200 #endif // LOG_SPI 00201 for(size_t i = 0; i < size; i++) 00202 { 00203 buff[i] = spi->write(0); 00204 00205 #ifdef LOG_SPI 00206 int buffint = buff[i]; 00207 printf("%02x", buffint); 00208 #endif // LOG_SPI 00209 } 00210 00211 #ifdef LOG_SPI 00212 int sizeint = size; 00213 printf(", %02x)\n", sizeint); 00214 #endif // LOG_SPI 00215 } 00216 00217 void spi_write_bytes(uint8_t *buff, size_t size) 00218 { 00219 #ifdef LOG_SPI 00220 int sizeint = size; 00221 printf("spi_write_bytes("); 00222 for(size_t i = 0; i < size; i++) 00223 { 00224 int buffint = buff[i]; 00225 printf("%02x", buffint); 00226 } 00227 printf(", %02x)\n", sizeint); 00228 #endif // LOG_SPI 00229 00230 if(spi) 00231 { 00232 for(size_t i = 0; i < size; i++) 00233 { 00234 spi->write(buff[i]); 00235 } 00236 00237 } else { 00238 00239 printf("ERROR: SPI not set!!!\n"); 00240 } 00241 } 00242 00243 } // End '"C" linking. 00244 00245 struct pl_platform g_plat; 00246 00247 struct pl_dispinfo g_dispinfo; 00248 00249 void WriteColour(pl_epdc &epdc, uint8_t colour) 00250 { 00251 if(epdc.fill(&epdc, NULL, colour)) 00252 Log("fill failed"); 00253 00254 if(epdc.clear_init(&epdc)) 00255 Log("clear_init fail"); 00256 00257 if(g_plat.psu.on(&g_plat.psu)) 00258 Log("PSU on fail"); 00259 00260 int wfid = pl_epdc_get_wfid(&epdc, wf_refresh); 00261 if (wfid < 0) 00262 Log("Bad wfid"); 00263 00264 if(epdc.update(&epdc, wfid, NULL)) 00265 Log("update failed"); 00266 00267 if(epdc.wait_update_end(&epdc)) 00268 Log("wait update end failed"); 00269 00270 if(g_plat.psu.off(&g_plat.psu)) 00271 Log("PSU off fail"); 00272 } 00273 00274 void WritePicture(pl_epdc &epdc, const char *file) 00275 { 00276 //#ifdef VERBOSE 00277 Log("WritePicture"); 00278 //#endif 00279 00280 if(g_plat.epdc.load_image(&g_plat.epdc, file, NULL, 0, 0)) 00281 Log("Image load failed"); 00282 else Log("Image loaded"); 00283 if(g_plat.psu.on(&g_plat.psu)) 00284 Log("PSU on fail"); 00285 else Log ("PSU on"); 00286 int wfid = pl_epdc_get_wfid(&epdc, wf_refresh); 00287 if (wfid < 0) 00288 Log("Bad wfid"); 00289 else Log("Good wfid"); 00290 00291 if(g_plat.epdc.update(&g_plat.epdc, wfid, NULL)) 00292 Log("update failed"); 00293 else Log("update succeeded"); 00294 00295 if(epdc.wait_update_end(&epdc)) 00296 Log("wait update end failed"); 00297 else Log("wait update end succeeded"); 00298 00299 if(g_plat.psu.off(&g_plat.psu)) 00300 Log("PSU off fail"); 00301 else Log("PSU off"); 00302 } 00303 00304 void WriteImage(const char *file) 00305 { 00306 #ifdef VERBOSE 00307 Log("WritePicture"); 00308 #endif 00309 00310 if(g_plat.epdc.load_image(&g_plat.epdc, file, NULL, 0, 0)) 00311 Log("Image load failed"); 00312 } 00313 00314 void WritePartImage(const char *file, int xd, int yd, int xi, int yi, int w, int h) 00315 { 00316 #ifdef VERBOSE 00317 Log("WritePartImage"); 00318 #endif 00319 00320 pl_area area; 00321 00322 area.left = xd; 00323 area.top = yd; 00324 area.width = w; 00325 area.height = h; 00326 00327 if(g_plat.epdc.load_image(&g_plat.epdc, file, &area, xi, yi)) 00328 Log("Image load failed"); 00329 } 00330 00331 void UpdateDisplay() 00332 { 00333 #ifdef VERBOSE 00334 Log("UpdateDisplay"); 00335 #endif 00336 00337 if(g_plat.psu.on(&g_plat.psu)) 00338 Log("PSU on fail"); 00339 00340 int wfid = pl_epdc_get_wfid(&g_plat.epdc, wf_refresh); 00341 if (wfid < 0) 00342 Log("Bad wfid"); 00343 00344 if(g_plat.epdc.update(&g_plat.epdc, wfid, NULL)) 00345 Log("update failed"); 00346 00347 if(g_plat.epdc.wait_update_end(&g_plat.epdc)) 00348 Log("wait update end failed"); 00349 00350 if(g_plat.psu.off(&g_plat.psu)) 00351 Log("PSU off fail"); 00352 } 00353 00354 int pl_i2c_reg_read_8(I2C &i2c, uint8_t i2c_addr, uint8_t reg, uint8_t *data); 00355 00356 int pl_i2c_reg_write_8(I2C &i2c, uint8_t i2c_addr, uint8_t reg, uint8_t data); 00357 00358 void pl_hwinfo_log(const struct pl_hwinfo *info) 00359 { 00360 #if VERBOSE 00361 const struct pl_hw_vcom_info *vcom = &info->vcom; 00362 #endif 00363 const struct pl_hw_board_info *board = &info->board; 00364 00365 #if VERBOSE 00366 printf("Version: %d\n", info->version); 00367 printf("VCOM DAC info: dac[%d]=%d, dac[%d]=%d\n", 00368 vcom->dac_x1, vcom->dac_y1, vcom->dac_x2, vcom->dac_y2); 00369 printf("Gate PSU info: VGPOS=%ld, VGNEG=%ld, swing=%ld\n", 00370 vcom->vgpos_mv, vcom->vgneg_mv, vcom->swing_ideal); 00371 #endif 00372 printf("Board type: %s, version: %d.%d\n", 00373 board->board_type, board->board_ver_maj, board->board_ver_min); 00374 #if VERBOSE 00375 printf("vcom_mode=%d, hv_pmic=%d, vcom_dac=%d, vcom_adc=%d\n", 00376 board->vcom_mode, board->hv_pmic, board->vcom_dac, board->vcom_adc); 00377 printf("io_config=%d, i2c_mode=%d, temp_sensor=%d, frame_buffer=%d\n", 00378 board->io_config, board->i2c_mode, board->temp_sensor, 00379 board->frame_buffer); 00380 printf("epdc_ref=%d, adc_scale_1=%d, adc_scale_2=%d\n", 00381 board->epdc_ref, board->adc_scale_1, board->adc_scale_2); 00382 printf("CRC16: %04X\n", info->crc); 00383 #endif 00384 } 00385 00386 #define CONFIG_DEFAULT_I2C_MODE I2C_MODE_HOST 00387 #define BOARD_MAJ 6 00388 #define BOARD_MIN 3 00389 00390 static const struct pl_hwinfo g_hwinfo_default = { 00391 /* version */ 00392 PL_HWINFO_VERSION, 00393 /* vcom */ 00394 { 127, 4172, 381, 12490, 25080, -32300, 56886 }, 00395 /* board */ 00396 { "HB", BOARD_MAJ, BOARD_MIN, 0, HV_PMIC_TPS65185, 0, 0, 0, 00397 CONFIG_DEFAULT_I2C_MODE, TEMP_SENSOR_NONE, 0, EPDC_S1D13541, 1, 1 }, 00398 /* CRC16 (not used when not reading from actual EEPROM) */ 00399 0xFFFF, 00400 }; 00401 00402 FIL g_wflib_fatfs_file; 00403 00404 static struct pl_epdpsu_gpio g_epdpsu_gpio = { 00405 &g_plat.gpio, PMIC_EN, HVSW_CTRL, PMIC_POK, PMIC_FLT, 300, 5, 100 00406 }; 00407 00408 struct vcom_cal vcom_cal; 00409 00410 pl_epdc &Get_epdc() 00411 { 00412 return g_plat.epdc; 00413 } 00414 00415 std::ostream &operator<<(std::ostream &s, pl_gpio &gpio) 00416 { 00417 s << "pl_gpio\n"; 00418 00419 s << gpio.config << "\n"; 00420 s << gpio.get << "\n"; 00421 s << gpio.set << "\n"; 00422 00423 return s; 00424 } 00425 00426 std::ostream &operator<<(std::ostream &s, pl_epdpsu &epdpsu) 00427 { 00428 s << "pl_epdpsu\n"; 00429 00430 s << epdpsu.on << "\n"; 00431 s << epdpsu.off << "\n"; 00432 s << epdpsu.state << "\n"; 00433 s << epdpsu.data << "\n"; 00434 00435 return s; 00436 }; 00437 00438 std::ostream &operator<<(std::ostream &s, pl_epdc &epdc) 00439 { 00440 s << "pl_epdc\n"; 00441 00442 s << epdc.clear_init << "\n"; 00443 s << epdc.load_wflib << "\n"; 00444 s << epdc.update << "\n"; 00445 s << epdc.wait_update_end << "\n"; 00446 s << epdc.set_power << "\n"; 00447 s << epdc.set_temp_mode << "\n"; 00448 s << epdc.update_temp << "\n"; 00449 s << epdc.fill << "\n"; 00450 s << epdc.pattern_check << "\n"; 00451 s << epdc.load_image << "\n"; 00452 s << epdc.set_epd_power << "\n"; 00453 00454 s << epdc.wf_table << "\n"; 00455 s << epdc.dispinfo << "\n"; 00456 //struct pl_wflib wflib << "\n"; 00457 s << epdc.power_state << "\n"; 00458 s << epdc.temp_mode << "\n"; 00459 s << epdc.manual_temp << "\n"; 00460 s << epdc.xres << "\n"; 00461 s << epdc.yres << "\n"; 00462 s << epdc.data << "\n"; 00463 00464 return s; 00465 }; 00466 00467 std::ostream &operator<<(std::ostream &s, pl_platform &g_plat) 00468 { 00469 s << "pl_platform\n"; 00470 00471 s << g_plat.gpio << "\n"; 00472 s << g_plat.psu << "\n"; 00473 s << g_plat.epdc << "\n"; 00474 s << g_plat.i2c << "\n"; 00475 s << g_plat.sys_gpio << "\n"; 00476 s << g_plat.hwinfo << "\n"; 00477 s << g_plat.dispinfo << "\n"; 00478 00479 return s; 00480 } 00481 00482 void DisplayHardwareSettings() 00483 { 00484 pl_hwinfo_log(g_plat.hwinfo); 00485 00486 #ifdef VERBOSE 00487 printf("Hardware information start\n"): 00488 std::ostringstream info; 00489 info << g_plat << "\n"; 00490 printf(info.str().c_str()); 00491 00492 printf("Hardware information end\n"); 00493 #endif // VERBOSE 00494 } 00495 00496 // Configure the EPSON controller settings. 00497 s1d135xx driver = { &g_s1d135xx_data, NULL }; 00498 00499 00500 void InitDisplay(I2C &i2c, SPI &spi_in, DigitalOut &spics, DigitalOut &hven, DigitalOut &rst, DigitalIn &hvpok) 00501 { 00502 spi = &spi_in; 00503 00504 spi->frequency(1000000); 00505 spi->format(8, 0); 00506 00507 rst = 0; 00508 hven = 0; 00509 spics = 1; 00510 00511 // Initialise the platform settings. 00512 g_plat.i2c = NULL; 00513 g_plat.sys_gpio = NULL; 00514 g_plat.hwinfo = &g_hwinfo_default; 00515 g_plat.dispinfo = &g_dispinfo; 00516 00517 g_plat.psu.on = NULL; 00518 g_plat.psu.off = NULL; 00519 g_plat.psu.state = 0; 00520 g_plat.psu.data = NULL; 00521 00522 // Use a 100Khz I2c clock (the PMIC limits are 100-400KHz). 00523 i2c.frequency(100000); 00524 00525 // COnfigure the VCOM settings. 00526 g_dispinfo.info.vcom = 5124; // Note hardcoded VCOM 00527 00528 int fails = 0; 00529 int initfailed = -1; 00530 while(initfailed && fails < MAX_INIT_FAILS) 00531 { 00532 // Enable the TPS65185 PMIC. 00533 // The I2C is now enabled. 00534 hven = 1; 00535 wait(0.2); 00536 00537 // Hard reset the Epson controller. 00538 rst = 0; 00539 mdelay(4); 00540 rst = 1; 00541 mdelay(10); 00542 00543 // Load the display information. 00544 initfailed = pl_wflib_init_fatfs(&g_plat.epdc.wflib, (int *) &g_wflib_fatfs_file, g_wflib_fatfs_path); 00545 if(initfailed != 0) 00546 { 00547 Log("Failed to load display info"); 00548 fails++; 00549 00550 } else { 00551 00552 pl_epdpsu_gpio_init(&g_plat.psu, &g_epdpsu_gpio); 00553 vcom_init(&vcom_cal, &g_plat.hwinfo->vcom); 00554 initfailed = tps65185_init(&pmic_info, i2c, I2C_PMIC_ADDR_TPS65185, &vcom_cal); 00555 if(initfailed != 0) 00556 { 00557 Log("Error initalizing TPS65185"); 00558 fails++; 00559 00560 } else { 00561 00562 initfailed = tps65185_set_vcom_voltage(&pmic_info, g_plat.dispinfo->info.vcom); 00563 if(initfailed != 0) 00564 { 00565 Log("Error initalizing VCOM"); 00566 fails++; 00567 00568 } else { 00569 00570 if(epson_epdc_init(&g_plat.epdc, g_plat.dispinfo, EPSON_EPDC_S1D13541, &driver) != 0) 00571 { 00572 Log("Error initalizing EPDC"); 00573 00574 } else { 00575 00576 // Display the hardware settings. 00577 DisplayHardwareSettings(); 00578 00579 Log("White screen"); 00580 WriteColour(g_plat.epdc, PL_WHITE); 00581 00582 //wait(4); 00583 00584 Log("Black screen"); 00585 WriteColour(g_plat.epdc, PL_BLACK); 00586 00587 /*wait(4); 00588 00589 Log("White screen"); 00590 WriteColour(g_plat.epdc, PL_WHITE); 00591 00592 wait(4); 00593 Log("Picture"); 00594 WritePicture(g_plat.epdc, "/myfile.pgm");*/ 00595 00596 /*WriteColour(g_plat.epdc, PL_WHITE); 00597 Log("Picture"); 00598 wait(1); 00599 WritePicture(g_plat.epdc, "/logos2.pgm"); 00600 wait(5); 00601 //ShortBeep(); 00602 WritePicture(g_plat.epdc, "/hang00.pgm"); 00603 wait (2); 00604 //ShortBeep(); 00605 WritePicture(g_plat.epdc, "/hang01.pgm"); 00606 wait (2); 00607 //ShortBeep(); 00608 WritePicture(g_plat.epdc, "/hang02.pgm"); 00609 wait (2); 00610 //ShortBeep(); 00611 WritePicture(g_plat.epdc, "/hang03.pgm"); 00612 wait (2); 00613 //ShortBeep(); 00614 WritePicture(g_plat.epdc, "/hang04.pgm"); 00615 wait (2); 00616 //ShortBeep(); 00617 WritePicture(g_plat.epdc, "/hang05.pgm"); 00618 wait (2); 00619 //ShortBeep(); 00620 WritePicture(g_plat.epdc, "/hang06.pgm"); 00621 wait (2); 00622 //ShortBeep(); 00623 WritePicture(g_plat.epdc, "/hang07.pgm"); 00624 wait (2); 00625 //ShortBeep(); 00626 WritePicture(g_plat.epdc, "/hang08.pgm"); 00627 wait(2); 00628 //ShortBeep(); 00629 WritePicture(g_plat.epdc, "/hang09.pgm"); 00630 wait (2); 00631 //ShortBeep(); 00632 WritePicture(g_plat.epdc, "/hang10.pgm"); 00633 wait (2); 00634 //ShortBeep(); 00635 WritePicture(g_plat.epdc, "/hang11.pgm"); 00636 wait (2);*/ 00637 } 00638 } 00639 } 00640 } 00641 } 00642 00643 if(fails < MAX_INIT_FAILS) 00644 printf("Init done, %d retries\n", fails); 00645 else 00646 printf("Init aborted, retry limit of %d exceeded\n", fails); 00647 } 00648 00649 void WriteImage ( const int number) 00650 { 00651 printf("WriteImage in eink.cpp\n"); 00652 switch (number) 00653 { 00654 case 0: 00655 WritePicture(g_plat.epdc, "/hang00.pgm"); 00656 break; 00657 case 1: 00658 WritePicture(g_plat.epdc, "/hang01.pgm"); 00659 break; 00660 case 2: 00661 WritePicture(g_plat.epdc, "/hang02.pgm"); 00662 break; 00663 case 3: 00664 WritePicture(g_plat.epdc, "/hang03.pgm"); 00665 break; 00666 case 4: 00667 WritePicture(g_plat.epdc, "/hang04.pgm"); 00668 break; 00669 case 5: 00670 WritePicture(g_plat.epdc, "/hang05.pgm"); 00671 break; 00672 case 6: 00673 WritePicture(g_plat.epdc, "/hang06.pgm"); 00674 break; 00675 case 7: 00676 WritePicture(g_plat.epdc, "/hang07.pgm"); 00677 break; 00678 case 8: 00679 WritePicture(g_plat.epdc, "/hang08.pgm"); 00680 break; 00681 default: 00682 break; 00683 } 00684 }
Generated on Tue Jul 12 2022 21:14:34 by
