00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00023 #ifdef __arm__
00024 #include <linux/fb.h>
00025 #include <unistd.h>
00026 #include <stdio.h>
00027 #include <sys/ioctl.h>
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030 #include <fcntl.h>
00031 #include <string.h>
00032 #include <stdlib.h>
00033 #else
00034 #include <stdio.h>
00035 #include <unistd.h>
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #endif
00039
00040 #include <sys/time.h>
00041 #define MILLION 1000000
00042 #include <sys/socket.h>
00043 #include <netinet/in.h>
00044 #include <arpa/inet.h>
00045 #include <errno.h>
00046
00047 #include "liberdm/erdm.h"
00048 #include "liberdm/erdmServer.h"
00049 #include "liberdm/erdminternal.h"
00050
00051 #include "config.h"
00052 #include "displayEinkTypes.h"
00053 #include "liberdm/display.h"
00054 #include <liberipc/eripc.h>
00055 #include <liberipc/eripcbusyd.h>
00056 #include <liberipc/eripccontentlister.h>
00057
00058 #define N_FILENAME 1024
00059 #define UD_FBSIZE 786432 // 768*1024*2*4/8 // H x V x bit_per_pixel x upscale_factor_to_fit_X / bits_in_a_byte
00060
00061 #define BUFFERSIZE 1024
00062
00063 #define ERDMG_LOGGING_ON 0
00064 #define ERDMG_WARNING_ON 1
00065 #define ERDMG_ERROR_ON 1
00066
00067 #if (ERDMG_LOGGING_ON)
00068 #define ERDMG_LOGPRINTF(x, args...) fprintf(stderr, "(L)" __FILE__ ":%d,%s() " x "\n", __LINE__, __func__ , ##args)
00069 #else
00070 #define ERDMG_LOGPRINTF(x, args...) do {} while (0)
00071 #endif
00072
00073 #if (ERDMG_WARNING_ON)
00074 #define ERDMG_WARNPRINTF(x, args...) fprintf(stderr, "(W)" __FILE__ ":%d,%s() " x "\n", __LINE__, __func__ , ##args)
00075 #else
00076 #define ERDMG_WARNPRINTF(x, args...) do {} while (0)
00077 #endif
00078
00079 #if (ERDMG_ERROR_ON)
00080 #define ERDMG_ERRORPRINTF(x, args...) fprintf(stderr, "(E)" __FILE__ ":%d,%s() " x "\n", __LINE__, __func__ , ##args)
00081 #else
00082 #define ERDMG_ERRORPRINTF(x, args...) do {} while (0)
00083 #endif
00084
00085 #define min(x,y) (((x)<(y))?(x):(y))
00086 #define max(x,y) (((x)>(y))?(x):(y))
00087
00088
00089 #define WAVEFORM_SIZE (128*1024)
00090
00091 #define FBIO_IOCTL_BASE 'v'
00092 #define FBIO_DISPLAY _IOW(FBIO_IOCTL_BASE, 1, struct display_update_info)
00093 #define FBIO_ERASE_WHITE _IOW(FBIO_IOCTL_BASE, 2, struct display_update_info)
00094 #define FBIO_DRAWPIXELS _IOW(FBIO_IOCTL_BASE, 3, struct transfer_buffer)
00095 #define FBIO_DRAW_BRUSH _IOW(FBIO_IOCTL_BASE, 4, struct brush_draw_info)
00096 #define FBIO_REDRAW _IOW(FBIO_IOCTL_BASE, 5, struct display_update_info)
00097 #define FBIO_UPLOAD_WAVEFORM _IOC(_IOC_WRITE, FBIO_IOCTL_BASE, 6, WAVEFORM_SIZE)
00098
00099
00100 #define FBIO_DISPLAYPARTIAL 0xfff
00101
00102
00103 typedef struct _dmWaveforms
00104 {
00105 eDmQuality quality;
00106 unsigned long einkElapsedTime;
00107 } dmWaveforms_t;
00108
00109
00110 static dmWaveforms_t waveforms[] = {
00111 {dmQFull, 1 * MILLION },
00112 {dmQBW, 100000 },
00113 {dmQTyping, 1 * MILLION }
00114 };
00115
00116 void displayHelp()
00117 {
00118 printf("Usage: displayMgr -<option> <argument>\n");
00119 printf(" no arguments : start server process (local access only)\n");
00120 printf(" -a : allow messages to be sent from any host (starts server process)\n");
00121 printf(" -h : display this message\n");
00122
00123 printf(" -p : disable partial update\n");
00124 printf(" -w <filename> : load waveform from filename\n");
00125 }
00126
00127 int uploadWaveform(int fbDev, char *szFilename)
00128 {
00129 FILE *file = NULL;
00130 unsigned char *buffer = NULL;
00131 int ret = 0;
00132
00133 file = fopen(szFilename, "rb");
00134 if (!file)
00135 {
00136 ERDMG_ERRORPRINTF("Error opening file %s", szFilename);
00137 ret = -1;
00138 goto end;
00139 }
00140
00141 buffer = (unsigned char *) malloc(WAVEFORM_SIZE);
00142 if (!buffer)
00143 {
00144 ERDMG_ERRORPRINTF("Out of memory");
00145 ret = -2;
00146 goto end;
00147 }
00148
00149 if (fread(buffer, 1, WAVEFORM_SIZE, file) != WAVEFORM_SIZE)
00150 {
00151 ERDMG_ERRORPRINTF("Error reading file");
00152 ret = -3;
00153 goto end;
00154 }
00155
00156 if ((ret = ioctl(fbDev, FBIO_UPLOAD_WAVEFORM, buffer)))
00157 {
00158 ERDMG_ERRORPRINTF("Error uploading waveform (err=0x%x)", ret);
00159 ret = -4;
00160 goto end;
00161 }
00162
00163 end:
00164 if (buffer)
00165 free(buffer);
00166 if (file)
00167 fclose(file);
00168 return ret;
00169 }
00170
00171
00172 int main(int argc, char **argv)
00173 {
00174 int fDump = 0;
00175 int fLocal = 1;
00176 int fDisablePartialUpdate = 0;
00177 int fWaveFile = 0;
00178 int nArg = 1;
00179 char szDumpFile[N_FILENAME];
00180 char szWaveFile[N_FILENAME];
00181 int nRet;
00182
00183
00184 int ret;
00185 int fbDev;
00186
00187 int sockfd;
00188 struct sockaddr_in clientAdr;
00189 socklen_t len;
00190 int n;
00191
00192 char buffer[BUFFERSIZE];
00193 uDmCommand dmCommand;
00194 unsigned long sleepTimeUSeconds = 0;
00195
00196 erClientChannel_t contentListerChannel;
00197 int first_update = 1;
00198
00199
00200
00201
00202 while (nArg < argc)
00203 {
00204 if (argv[nArg][0] == '-')
00205 {
00206 switch (argv[nArg][1])
00207 {
00208 case 'h':
00209 displayHelp();
00210 return 0;
00211 break;
00212
00213 case 'a':
00214 fLocal = 0;
00215 nArg++;
00216 break;
00217
00218 case 'd':
00219 fDump = 1;
00220
00221 if (++nArg >= argc)
00222 {
00223
00224 ERDMG_ERRORPRINTF("Supply a filename after option -d");
00225 displayHelp();
00226 return -1;
00227 }
00228 else
00229 {
00230 strncpy(szDumpFile, argv[nArg], N_FILENAME);
00231 nArg++;
00232 }
00233 break;
00234
00235 case 'p':
00236 fDisablePartialUpdate = 1;
00237 nArg++;
00238 break;
00239
00240 case 'w':
00241 fWaveFile = 1;
00242
00243 if (++nArg >= argc)
00244 {
00245
00246 ERDMG_ERRORPRINTF("Supply a filename after option -w");
00247 displayHelp();
00248 return -1;
00249 }
00250 else
00251 {
00252 strncpy(szWaveFile, argv[nArg], N_FILENAME);
00253 nArg++;
00254 }
00255 break;
00256
00257 default:
00258 ERDMG_ERRORPRINTF("Option %s not known.", argv[nArg]);
00259 displayHelp();
00260 return -1;
00261 }
00262 }
00263 else
00264 {
00265 ERDMG_ERRORPRINTF("Argument supplied not proceded by option.");
00266 displayHelp();
00267 return -1;
00268 }
00269 }
00270
00271
00272 ERDMG_WARNPRINTF("ePaper daemon (%s)", PACKAGE_STRING);
00273
00274 if (fDump == 1)
00275 ERDMG_WARNPRINTF("File dumping set to file %s", szDumpFile);
00276 if (fLocal == 1)
00277 ERDMG_WARNPRINTF("Display Manager is accessible to local processes only.");
00278 if (fWaveFile == 1)
00279 ERDMG_WARNPRINTF("Loading waveforms from file %s", szWaveFile);
00280
00281 #ifdef __arm__
00282 fbDev = open("/dev/fb0", O_RDWR);
00283 if (fbDev == -1)
00284 {
00285 ERDMG_ERRORPRINTF("Error opening framebufferdevice. # mknod /dev/fb0 c 29 0");
00286 return -1;
00287 }
00288
00289
00290 if (fWaveFile == 1)
00291 {
00292 nRet = uploadWaveform(fbDev, szWaveFile);
00293 if (nRet != 0)
00294 {
00295 ERDMG_ERRORPRINTF("Failed to upload waveform, continuing anyway");
00296 }
00297 }
00298 #endif
00299
00300 initServer(&sockfd, fLocal);
00301
00302 ret = erIpcStartClient(ER_CONTENTLISTER_CHANNEL, &contentListerChannel);
00303 if (ret != 0)
00304 ERDMG_ERRORPRINTF("erIpcStartClient returned %d", ret);
00305 while (1)
00306 {
00307 fd_set readset;
00308 struct timeval timeout;
00309 char szClientIP[INET_ADDRSTRLEN + 1];
00310 struct timeval tvStart;
00311 struct timeval tvEnd;
00312 long timediff;
00313 uDmCommand dmCmdDpy;
00314 uDmCommand dmCmdDpyPartial;
00315 eDmCommandCode commandCode;
00316 struct coordinates coordFinal;
00317 int nx1, ny1, nx2, ny2;
00318 int x1, y1, x2, y2;
00319 struct display_update_info displayUpdateInfo;
00320 struct partial_display_update_info partialDisplayUpdateInfo;
00321
00322 if (sleepTimeUSeconds > 0)
00323 {
00324
00325 ERDMG_LOGPRINTF("Going to sleep for %ld micro seconds", sleepTimeUSeconds);
00326 usleep(sleepTimeUSeconds);
00327 sleepTimeUSeconds = 0;
00328 }
00329
00330
00331 len = sizeof(clientAdr);
00332 n = recvfrom(sockfd, buffer, BUFFERSIZE, 0, (struct sockaddr *) &clientAdr, &len);
00333 buffer[n] = '\0';
00334 if (inet_ntop(AF_INET, &clientAdr.sin_addr, szClientIP, sizeof(szClientIP)))
00335 {
00336 ERDMG_LOGPRINTF("Message %s received from %s.", buffer, szClientIP);
00337 }
00338 nRet = dmMessageParser(buffer, &dmCommand);
00339 if (nRet != 0)
00340 {
00341 ERDMG_ERRORPRINTF("Skipping an invalid command");
00342 continue;
00343 }
00344
00345
00346
00347 if (first_update)
00348 {
00349 first_update = 0;
00350
00351 ERDMG_LOGPRINTF("Erase to white for first update");
00352 displayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00353 displayUpdateInfo.sequence = 0;
00354 #ifdef __arm__
00355 if ((ret = ioctl(fbDev, FBIO_ERASE_WHITE, &displayUpdateInfo)))
00356 {
00357 ERDMG_ERRORPRINTF("Error sending FBIO_ERASE_WHITE: %x", ret);
00358 }
00359 #else
00360 ERDMG_LOGPRINTF("(Dummy) ioctl(fbdev, FBIO_ERASE_WHITE)");
00361 #endif
00362 }
00363
00364 commandCode = dmCommand.dmCmdGeneric.cmd;
00365 switch (commandCode)
00366 {
00367 case dmCcDisplay:
00368 dmCmdDpy = dmCommand;
00369 break;
00370
00371 case dmCcDisplayPartial:
00372 dmCmdDpyPartial = dmCommand;
00373 break;
00374
00375 default:
00376 ;
00377 }
00378
00379
00380
00381 switch (dmCommand.dmCmdGeneric.priority)
00382 {
00383 case dmCmdPriorLow:
00384 timediff = 1500 * 1000;
00385 break;
00386
00387 case dmCmdPriorHigh:
00388 timediff = 100 * 1000;
00389 break;
00390
00391 case dmCmdPriorUrgent:
00392 timediff = 0;
00393 break;
00394
00395 case dmCmdPriorNormal:
00396 default:
00397 timediff = 500 * 1000;
00398 break;
00399 }
00400
00401
00402 gettimeofday(&tvEnd, NULL);
00403 tvEnd.tv_usec += timediff;
00404 if (tvEnd.tv_usec > MILLION)
00405 {
00406 tvEnd.tv_usec -= MILLION;
00407 tvEnd.tv_sec += 1;
00408 }
00409
00410 while (1)
00411 {
00412 FD_ZERO(&readset);
00413 FD_SET(sockfd, &readset);
00414
00415 gettimeofday(&tvStart, NULL);
00416 if (tvEnd.tv_usec < tvStart.tv_usec)
00417 {
00418 tvEnd.tv_usec += MILLION;
00419 tvEnd.tv_sec -= 1;
00420 }
00421 if (tvEnd.tv_sec < tvStart.tv_sec)
00422 {
00423 timeout.tv_usec = 0;
00424 timeout.tv_sec = 0;
00425 }
00426 else
00427 {
00428 timeout.tv_usec = tvEnd.tv_usec - tvStart.tv_usec;
00429 timeout.tv_sec = tvEnd.tv_sec - tvStart.tv_sec;
00430 }
00431 ERDMG_LOGPRINTF("timeout [%ld:%06ld]", timeout.tv_sec, timeout.tv_usec);
00432
00433 if ((select(sockfd + 1, &readset, NULL, NULL, &timeout) == -1) && (errno != EINTR))
00434 {
00435 perror("Select Failed");
00436 }
00437 else
00438 {
00439 if (FD_ISSET(sockfd, &readset))
00440 {
00441 len = sizeof(clientAdr);
00442 n = recvfrom(sockfd, buffer, BUFFERSIZE, 0, (struct sockaddr *) &clientAdr, &len);
00443 buffer[n] = '\0';
00444 if (inet_ntop(AF_INET, &clientAdr.sin_addr, szClientIP, sizeof(szClientIP)))
00445 {
00446 ERDMG_LOGPRINTF("Message %s received from %s.", buffer, szClientIP);
00447 }
00448 nRet = dmMessageParser(buffer, &dmCommand);
00449 if (nRet != 0)
00450 {
00451 ERDMG_ERRORPRINTF("Skipping an invalid command");
00452 continue;
00453 }
00454
00455 if (commandCode == dmCcDisplay)
00456 {
00457
00458
00459 if ((int) dmCmdDpy.dmCmdDisplay.priority < (int) dmCommand.dmCmdDisplay.priority)
00460 {
00461 dmCmdDpy.dmCmdDisplay.priority = dmCommand.dmCmdDisplay.priority;
00462 }
00463
00464
00465 if ((int) dmCmdDpy.dmCmdDisplay.qual > (int) dmCommand.dmCmdDisplay.qual)
00466 {
00467 dmCmdDpy.dmCmdDisplay.qual = dmCommand.dmCmdDisplay.qual;
00468 }
00469 }
00470 else if (commandCode == dmCcDisplayPartial)
00471 {
00472 if (dmCommand.dmCmdGeneric.cmd == dmCcDisplay)
00473 {
00474
00475 commandCode = dmCcDisplay;
00476 dmCmdDpy = dmCommand;
00477 }
00478 else if (dmCommand.dmCmdGeneric.cmd == dmCcDisplayPartial)
00479 {
00480
00481 int x1Up, y1Up;
00482 int x1Down, y1Down;
00483 int x2Up, y2Up;
00484 int x2Down, y2Down;
00485
00486 x1Down = dmCmdDpyPartial.dmCmdDisplayPartial.xDown;
00487 y1Down = dmCmdDpyPartial.dmCmdDisplayPartial.yDown;
00488 x1Up = dmCmdDpyPartial.dmCmdDisplayPartial.xUp;
00489 y1Up = dmCmdDpyPartial.dmCmdDisplayPartial.yUp;
00490
00491 x1Up = min(x1Up, x1Down);
00492 y1Up = min(y1Up, y1Down);
00493 x1Down = max(x1Up, x1Down);
00494 y1Down = max(y1Up, y1Down);
00495
00496 x2Down = dmCommand.dmCmdDisplayPartial.xDown;
00497 y2Down = dmCommand.dmCmdDisplayPartial.yDown;
00498 x2Up = dmCommand.dmCmdDisplayPartial.xUp;
00499 y2Up = dmCommand.dmCmdDisplayPartial.yUp;
00500
00501 x2Up = min(x2Up, x2Down);
00502 y2Up = min(y2Up, y2Down);
00503 x2Down = max(x2Up, x2Down);
00504 y2Down = max(y2Up, y2Down);
00505
00506
00507 commandCode = dmCcDisplayPartial;
00508 dmCmdDpyPartial.dmCmdDisplay.cmd = commandCode;
00509 dmCmdDpyPartial.dmCmdDisplay.priority = dmCmdPriorNormal;
00510 dmCmdDpyPartial.dmCmdDisplay.qual = dmQFull;
00511 dmCmdDpyPartial.dmCmdDisplayPartial.xUp = min(x1Up, x2Up);
00512 dmCmdDpyPartial.dmCmdDisplayPartial.yUp = min(y1Up, y2Up);
00513 dmCmdDpyPartial.dmCmdDisplayPartial.xDown = max(x1Down, x2Down);
00514 dmCmdDpyPartial.dmCmdDisplayPartial.yDown = max(y1Down, y2Down);
00515 }
00516 }
00517 else
00518 {
00519 commandCode = dmCommand.dmCmdGeneric.cmd;
00520 switch (commandCode)
00521 {
00522 case dmCcDisplay:
00523 dmCmdDpy = dmCommand;
00524 break;
00525
00526 case dmCcDisplayPartial:
00527 dmCmdDpyPartial = dmCommand;
00528 break;
00529 default:
00530 ;
00531 }
00532 }
00533 }
00534 else
00535 {
00536 ERDMG_LOGPRINTF("Nothing more pending.");
00537 break;
00538 }
00539 }
00540 }
00541
00542 switch (commandCode)
00543 {
00544 case dmCcDisplay:
00545 dmCommand = dmCmdDpy;
00546 break;
00547
00548 case dmCcDisplayPartial:
00549 dmCommand = dmCmdDpyPartial;
00550 break;
00551
00552 default:
00553 ;
00554 }
00555
00556 switch (dmCommand.dmCmdGeneric.cmd)
00557 {
00558 case dmCcDisplay:
00559 displayUpdateInfo.sequence = 0;
00560 switch (dmCommand.dmCmdDisplay.qual)
00561 {
00562 case dmQFull:
00563 displayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00564 break;
00565 case dmQBW:
00566 displayUpdateInfo.waveform = WAVEFORM_FAST_BLACK_WHITE;
00567 ERDMG_LOGPRINTF("Selected BW waveform");
00568 break;
00569 case dmQTyping:
00570 displayUpdateInfo.waveform = WAVEFORM_TYPING;
00571 ERDMG_LOGPRINTF("Selected Typing waveform");
00572 break;
00573 default:
00574 ;
00575 }
00576 ERDMG_LOGPRINTF("Before ioctl");
00577 gettimeofday(&tvStart, NULL);
00578 #ifdef __arm__
00579
00580 if ((ret = ioctl(fbDev, FBIO_DISPLAY, &displayUpdateInfo)))
00581 {
00582 ERDMG_ERRORPRINTF("Error sending FBIO_DISPLAY: %x", ret);
00583 }
00584 #else
00585 ERDMG_LOGPRINTF("(Dummy) ioctl(fbDev, FBIO_DISPLAY, NULL)");
00586 #endif
00587 gettimeofday(&tvEnd, NULL);
00588 timediff = MILLION * (tvEnd.tv_sec - tvStart.tv_sec) + (tvEnd.tv_usec - tvStart.tv_usec);
00589 ERDMG_LOGPRINTF("ioctl executed for %ld usec", timediff);
00590 sleepTimeUSeconds = waveforms[(int) dmCommand.dmCmdDisplay.qual].einkElapsedTime;
00591
00592 clDisplayUpdated(contentListerChannel);
00593 break;
00594
00595 case dmCcDisplayPartial:
00596
00597
00598
00599
00600
00601
00602
00603
00604 if (fDisablePartialUpdate == 1)
00605 {
00606 ERDMG_LOGPRINTF("Before ioctl (PARTIAL UPDATE DISABLED: FULL UPDATE INSTEAD)");
00607 displayUpdateInfo.sequence = 0;
00608 displayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00609 gettimeofday(&tvStart, NULL);
00610 #ifdef __arm__
00611
00612 if ((ret = ioctl(fbDev, FBIO_DISPLAY, &displayUpdateInfo)))
00613 {
00614 ERDMG_ERRORPRINTF("Error sending FBIO_DISPLAY: %x", ret);
00615 }
00616 #else
00617 ERDMG_LOGPRINTF("(Dummy) ioctl(fbDev, FBIO_DISPLAY, NULL)");
00618 #endif
00619 gettimeofday(&tvEnd, NULL);
00620 timediff = MILLION * (tvEnd.tv_sec - tvStart.tv_sec) + (tvEnd.tv_usec - tvStart.tv_usec);
00621 ERDMG_LOGPRINTF("ioctl executed for %ld usec", timediff);
00622 sleepTimeUSeconds = waveforms[(int) dmCommand.dmCmdDisplay.qual].einkElapsedTime;
00623 }
00624 else
00625 {
00626 partialDisplayUpdateInfo.sequence = 0;
00627 partialDisplayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00628
00629 nx1 = dmCommand.dmCmdDisplayPartial.yUp;
00630 ny1 = SCREEN_WIDTH - dmCommand.dmCmdDisplayPartial.xUp;
00631 nx2 = dmCommand.dmCmdDisplayPartial.yDown;
00632 ny2 = SCREEN_WIDTH - dmCommand.dmCmdDisplayPartial.xDown;
00633
00634
00635
00636
00637 x1 = min(nx1, nx2);
00638 y1 = min(ny1, ny2);
00639 x2 = max(nx1, nx2);
00640 y2 = max(ny1, ny2);
00641
00642
00643
00644 x2 += 4;
00645 y2 += 4;
00646
00647 x1 = (x1 < 4) ? 4 : (x1 - (x1 % 4));
00648 y1 = (y1 < 4) ? 4 : (y1 - (y1 % 4));
00649 x2 = (x2 > (SCREEN_HEIGHT - 4)) ? (SCREEN_HEIGHT - 4) : (x2 - (x2 % 4));
00650 y2 = (y2 > (SCREEN_WIDTH - 4)) ? (SCREEN_WIDTH - 4) : (y2 - (y2 % 4));
00651
00652
00653 coordFinal.x1 = x1;
00654 coordFinal.y1 = y1;
00655 coordFinal.x2 = x2;
00656 coordFinal.y2 = y2;
00657
00658 partialDisplayUpdateInfo.coord = coordFinal;
00659
00660 ERDMG_LOGPRINTF("Before ioctl. PartialUpdate((%d,%d):(%d,%d))", coordFinal.x1, coordFinal.y1, coordFinal.x2, coordFinal.y2);
00661 gettimeofday(&tvStart, NULL);
00662 #ifdef __arm__
00663
00664 if ((ret = ioctl(fbDev, FBIO_DISPLAYPARTIAL, &partialDisplayUpdateInfo)))
00665 {
00666 ERDMG_ERRORPRINTF("Error sending FBIO_DISPLAYPARTIAL: %x", ret);
00667 }
00668 #else
00669 ERDMG_LOGPRINTF("(Dummy) ioctl(fbdev, FBIO_DISPLAYPARTIAL, &coordFinal)");
00670 #endif
00671 gettimeofday(&tvEnd, NULL);
00672 timediff = MILLION * (tvEnd.tv_sec - tvStart.tv_sec) + (tvEnd.tv_usec - tvStart.tv_usec);
00673 ERDMG_LOGPRINTF("ioctl executed for %ld usec", timediff);
00674 sleepTimeUSeconds = waveforms[(int) dmCommand.dmCmdDisplay.qual].einkElapsedTime;
00675 }
00676 break;
00677
00678 case dmCcDump:
00679 ERDMG_ERRORPRINTF("%d not implemented.", (int) dmCommand.dmCmdGeneric.cmd);
00680 sleepTimeUSeconds = 0;
00681 break;
00682
00683 case dmCcEraseToWhite:
00684 displayUpdateInfo.waveform = WAVEFORM_4BPP_IMAGE;
00685 displayUpdateInfo.sequence = 0;
00686 ERDMG_LOGPRINTF("erase to white");
00687 #ifdef __arm__
00688 if ((ret = ioctl(fbDev, FBIO_ERASE_WHITE, &displayUpdateInfo)))
00689 {
00690 ERDMG_ERRORPRINTF("Error sending FBIO_ERASE_WHITE: %x", ret);
00691 }
00692 #else
00693 ERDMG_LOGPRINTF("(Dummy) ioctl(fbdev, FBIO_ERASE_WHITE)");
00694 #endif
00695 sleepTimeUSeconds = 0;
00696 break;
00697
00698 default:
00699 ;
00700 }
00701 }
00702
00703 return 0;
00704 }