00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "board.h"
00043
00044 #include <stdint.h>
00045 #include <string.h>
00046 #include <assert.h>
00047
00048
00049
00050
00051 COMPILER_ALIGNED(32) static void *gpCanvasBuffer = NULL;
00052 static uint32_t gwCanvasBufferSize;
00053 static uint32_t gwCanvasMaxWidth, gwCanvasMaxHeight;
00054 extern uint8_t ili9488_lcdMode;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 static void LCDD_SetPixelColor(uint32_t x, uint32_t y, uint32_t color)
00066 {
00067 ILI9488_SetPixelColor(x, y, color);
00068 }
00069
00070
00071
00072
00073
00074
00075
00076 static void LCDD_FillSolidRect(uint16_t *pCanvasBuffer, rect rc,
00077 uint32_t dwColor)
00078 {
00079 uint32_t row, col;
00080 uint32_t w, h;
00081
00082
00083 w = rc.x + rc.width;
00084 w = w > gwCanvasMaxWidth ? gwCanvasMaxWidth : w;
00085 h = rc.y + rc.height;
00086 h = h > gwCanvasMaxHeight ? gwCanvasMaxHeight : h;
00087
00088 if (ili9488_lcdMode == ILI9488_SPIMODE) {
00089 sBGR *p_buf = gpCanvasBuffer;
00090
00091 if (pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t *)pCanvasBuffer);
00092
00093 if (NULL == p_buf) {
00094 for (row = rc.y; row < h; row++) {
00095 for (col = rc.x; col < w; col++)
00096 LCDD_SetPixelColor(col, row, dwColor);
00097 }
00098
00099 return;
00100 }
00101
00102
00103 for (row = rc.y; row < h; row++) {
00104 for (col = rc.x; col < w; col++) {
00105
00106 p_buf[row * gwCanvasMaxWidth + col].b = dwColor & 0xFF;
00107 p_buf[row * gwCanvasMaxWidth + col].g = dwColor >> 8;
00108 p_buf[row * gwCanvasMaxWidth + col].r = dwColor >> 16;
00109 }
00110 }
00111 } else {
00112 uint16_t *p_buf = gpCanvasBuffer;
00113
00114 if (pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00115
00116
00117 for (row = rc.y; row < h; row++) {
00118 for (col = rc.x; col < w; col++)
00119 p_buf[row * gwCanvasMaxWidth + col] = (uint16_t)dwColor;
00120 }
00121 }
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131 void LCDD_SetUpdateWindowSize(rect rc)
00132 {
00133 gwCanvasMaxWidth = rc.width + 1;
00134 gwCanvasMaxHeight = rc.height + 1;
00135
00136 if (ili9488_lcdMode == ILI9488_SPIMODE)
00137 ILI9488_SpiSetWindow(rc.x, rc.y, rc.width, rc.height);
00138 else
00139 ILI9488_EbiSetWindow(rc.x, rc.y, rc.width, rc.height);
00140 }
00141
00142
00143
00144
00145 void LCDD_UpdateWindow(void)
00146 {
00147 uint32_t size = 0;
00148
00149 if (ili9488_lcdMode == ILI9488_SPIMODE) {
00150 size = gwCanvasBufferSize / (sizeof(sBGR)) * 3;
00151 ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_WRITE,
00152 (uint8_t *)gpCanvasBuffer, 0, AccessWrite, size);
00153 } else {
00154 size = gwCanvasBufferSize / sizeof(uint16_t);
00155 ILI9488_EbiSendCommand(ILI9488_CMD_MEMORY_WRITE,
00156 (uint16_t *)gpCanvasBuffer, 0, AccessWrite, size);
00157 }
00158 }
00159
00160
00161
00162
00163
00164
00165 void LCDD_UpdatePartialWindow(uint8_t *pCanvasBuffer, uint32_t size)
00166 {
00167 uint32_t cnt = 0;
00168
00169 if (ili9488_lcdMode == ILI9488_SPIMODE) {
00170 cnt = size / sizeof(sBGR) * 3;
00171 ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_WRITE,
00172 (uint8_t *)pCanvasBuffer, 0, AccessWrite, cnt);
00173 } else {
00174 cnt = size / sizeof(uint16_t);
00175 ILI9488_EbiSendCommand(ILI9488_CMD_MEMORY_WRITE,
00176 (uint16_t *)pCanvasBuffer, 0, AccessWrite, cnt);
00177 }
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 void LCDD_DrawRectangleWithFill(uint16_t *pCanvasBuffer, uint32_t dwX,
00190 uint32_t dwY, uint32_t dwWidth,
00191 uint32_t dwHeight, uint32_t dwColor)
00192 {
00193 rect rc;
00194 rc.x = dwX;
00195 rc.y = dwY;
00196 rc.width = dwWidth + 1;
00197 rc.height = dwHeight + 1;
00198 LCDD_FillSolidRect(pCanvasBuffer, rc , dwColor);
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 uint32_t LCDD_DrawCircle(uint16_t *pCanvasBuffer, uint32_t x, uint32_t y,
00211 uint32_t r, uint32_t color)
00212 {
00213 signed int d;
00214 uint32_t curX;
00215 uint32_t curY;
00216
00217 d = 3 - (r << 1);
00218 curX = 0;
00219 curY = r;
00220
00221 while (curX <= curY) {
00222 LCDD_DrawPixel(pCanvasBuffer, x + curX, y + curY, color);
00223 LCDD_DrawPixel(pCanvasBuffer, x + curX, y - curY, color);
00224 LCDD_DrawPixel(pCanvasBuffer, x - curX, y + curY, color);
00225 LCDD_DrawPixel(pCanvasBuffer, x - curX, y - curY, color);
00226 LCDD_DrawPixel(pCanvasBuffer, x + curY, y + curX, color);
00227 LCDD_DrawPixel(pCanvasBuffer, x + curY, y - curX, color);
00228 LCDD_DrawPixel(pCanvasBuffer, x - curY, y + curX, color);
00229 LCDD_DrawPixel(pCanvasBuffer, x - curY, y - curX, color);
00230
00231 if (d < 0)
00232 d += (curX << 2) + 6;
00233 else {
00234 d += ((curX - curY) << 2) + 10;
00235 curY--;
00236 }
00237
00238 curX++;
00239 }
00240
00241 return 0;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 uint32_t LCD_DrawFilledCircle(uint16_t *pCanvasBuffer, uint32_t dwX,
00254 uint32_t dwY,
00255 uint32_t dwRadius, uint32_t color)
00256 {
00257 signed int d;
00258 uint32_t dwCurX;
00259 uint32_t dwCurY;
00260 uint32_t dwXmin, dwYmin;
00261
00262 if (dwRadius == 0)
00263 return 0;
00264
00265 d = 3 - (dwRadius << 1);
00266 dwCurX = 0;
00267 dwCurY = dwRadius;
00268
00269 while (dwCurX <= dwCurY) {
00270 dwXmin = (dwCurX > dwX) ? 0 : dwX - dwCurX;
00271 dwYmin = (dwCurY > dwY) ? 0 : dwY - dwCurY;
00272 LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, dwYmin,
00273 dwX + dwCurX - dwXmin, 1 , color);
00274 LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin,
00275 dwY + dwCurY, dwX + dwCurX - dwXmin, 1,
00276 color);
00277 dwXmin = (dwCurY > dwX) ? 0 : dwX - dwCurY;
00278 dwYmin = (dwCurX > dwY) ? 0 : dwY - dwCurX;
00279 LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, dwYmin,
00280 dwX + dwCurY - dwXmin , 1, color);
00281 LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin,
00282 dwY + dwCurX, dwX + dwCurY - dwXmin, 1,
00283 color);
00284
00285 if (d < 0)
00286 d += (dwCurX << 2) + 6;
00287 else {
00288 d += ((dwCurX - dwCurY) << 2) + 10;
00289 dwCurY--;
00290 }
00291
00292 dwCurX++;
00293 }
00294
00295 return 0;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 void LCDD_DrawString(uint16_t *pCanvasBuffer, uint32_t x, uint32_t y,
00308 const uint8_t *pString, uint32_t color)
00309 {
00310 uint32_t xorg = x;
00311
00312 while (*pString != 0) {
00313 if (*pString == '\n') {
00314 y += gFont.height + 2;
00315 x = xorg;
00316 } else {
00317 LCDD_DrawChar(pCanvasBuffer, x, y, *pString, color);
00318 x += gFont.width + 2;
00319 }
00320
00321 pString++;
00322 }
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void LCDD_GetStringSize(const uint8_t *pString, uint32_t *pWidth,
00336 uint32_t *pHeight)
00337 {
00338 uint32_t width = 0;
00339 uint32_t height = gFont.height;
00340
00341 while (*pString != 0) {
00342 if (*pString == '\n')
00343 height += gFont.height + 2;
00344 else
00345 width += gFont.width + 2;
00346
00347 pString++;
00348 }
00349
00350 if (width > 0)
00351 width -= 2;
00352
00353 if (pWidth != NULL)
00354 *pWidth = width;
00355
00356 if (pHeight != NULL)
00357 *pHeight = height;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 void LCDD_BitBlt(uint16_t *pCanvasBuffer, uint32_t dst_x, uint32_t dst_y,
00377 uint32_t dst_w, uint32_t dst_h,
00378 const LcdColor_t *src,
00379 uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h)
00380 {
00381 uint32_t row, col;
00382 uint32_t src_row, src_col;
00383
00384
00385 src_h = src_h;
00386
00387 if (ili9488_lcdMode == ILI9488_SPIMODE) {
00388 sBGR *p_buf = gpCanvasBuffer;
00389
00390 if (pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t *)pCanvasBuffer);
00391
00392
00393 for (src_row = src_y, row = dst_y; row < dst_h; row++, src_row++) {
00394 for (src_col = src_x, col = dst_x; col < dst_w; col++, src_col++) {
00395 p_buf[row * gwCanvasMaxWidth + col].r = src[src_row * src_w + src_col] & 0xFF;
00396 p_buf[row * gwCanvasMaxWidth + col].g = src[src_row * src_w + src_col] >> 8;
00397 p_buf[row * gwCanvasMaxWidth + col].b = src[src_row * src_w + src_col] >> 16;
00398 }
00399
00400 memory_barrier()
00401 }
00402
00403 memory_barrier()
00404 } else {
00405 uint16_t *p_buf = gpCanvasBuffer;
00406
00407 if (pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00408
00409
00410 for (src_row = src_y, row = dst_y; row < (dst_y + dst_h); row++, src_row++) {
00411 for (src_col = src_x, col = dst_x; col < (dst_x + dst_w); col++, src_col++)
00412 p_buf[row * gwCanvasMaxWidth + col] = src[src_row * src_w + src_col];
00413 }
00414
00415 memory_barrier()
00416 }
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 void LCDD_BitBltAlphaBlend(uint16_t *pCanvasBuffer,
00437 uint32_t dst_x,
00438 uint32_t dst_y,
00439 uint32_t dst_w,
00440 uint32_t dst_h,
00441 const LcdColor_t *src,
00442 uint32_t src_x,
00443 uint32_t src_y,
00444 uint32_t src_w,
00445 uint32_t src_h,
00446 uint32_t alpha)
00447 {
00448 uint32_t row, col;
00449 uint32_t src_row, src_col;
00450 uint32_t w, h;
00451 uint32_t dst_row;
00452 uint32_t r, g, b;
00453
00454 if (ili9488_lcdMode == ILI9488_SPIMODE) {
00455 sBGR *p_buf = gpCanvasBuffer;
00456
00457 if (pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t *)pCanvasBuffer);
00458
00459
00460 for (src_row = src_y, row = dst_y; row < dst_h; row++, src_row++) {
00461 for (src_col = src_x, col = dst_x; col < dst_w; col++, src_col++) {
00462 p_buf[row * dst_w + col].r = src[src_row * src_w + src_col] & 0xFF;
00463 p_buf[row * dst_w + col].g = src[src_row * src_w + src_col] >> 8;
00464 p_buf[row * dst_w + col].b = src[src_row * src_w + src_col] >> 16;
00465 }
00466 }
00467
00468 memory_barrier()
00469 } else {
00470 uint16_t *p_buf = gpCanvasBuffer;
00471
00472 if (pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00473
00474 w = src_x + src_w;
00475 h = src_y + src_h;
00476 dst_row = dst_y;
00477 p_buf += (dst_row * dst_w + dst_x);
00478 src += src_y * w + src_x;
00479
00480 for (src_row = src_y; src_row < h; src_row++, dst_row++) {
00481 for (src_col = src_x; src_col < w; src_col++) {
00482 r = (p_buf[src_col] >> 11) * (255 - alpha) / 255 +
00483 (src[src_col] >> 11) * alpha / 255;
00484
00485 if (r > 0x1F) r = 0x1F;
00486
00487 g = ((p_buf[src_col] >> 5) & 0x3F) * (255 - alpha) / 255 +
00488 ((src[src_col] >> 5) & 0x3f) * alpha / 255;
00489
00490 if (g > 0x3F) g = 0x3F;
00491
00492 b = ((p_buf[src_col]) & 0x1F) * (255 - alpha) / 255
00493 + ((src[src_col]) & 0x1f) * alpha / 255;
00494
00495 if (b > 0x1F) b = 0x1F;
00496
00497 p_buf[src_col] = ((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F);
00498 }
00499
00500 p_buf += dst_w;
00501 src += w;
00502 }
00503
00504 memory_barrier()
00505 }
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 void LCDD_DrawImage(uint16_t *pCanvasBuffer, uint32_t dwX, uint32_t dwY,
00519 const LcdColor_t *pImage, uint32_t dwWidth, uint32_t dwHeight)
00520 {
00521
00522
00523
00524
00525 LCDD_BitBlt(pCanvasBuffer, dwX, dwY, dwWidth, dwHeight,
00526 pImage, 0, 0, dwWidth - dwX, dwHeight - dwY);
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 void LCDD_DrawPixel(uint16_t *pCanvasBuffer, uint32_t x, uint32_t y,
00538 uint32_t color)
00539 {
00540
00541 if (ili9488_lcdMode == ILI9488_SPIMODE) {
00542 sBGR *p_buf = gpCanvasBuffer;
00543
00544 if (pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t *)pCanvasBuffer);
00545
00546 if (NULL == p_buf) {
00547 LCDD_SetPixelColor(x, y, color);
00548 return;
00549 }
00550
00551 p_buf += y * gwCanvasMaxWidth;
00552 p_buf += x;
00553 p_buf->b = color & 0xFF;
00554 p_buf->g = color >> 8;
00555 p_buf->r = color >> 16;
00556 p_buf++;
00557 memory_barrier()
00558 } else {
00559 uint16_t *p_buf = gpCanvasBuffer;
00560
00561 if (pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00562
00563 p_buf += y * gwCanvasMaxWidth;
00564 p_buf += x;
00565 *p_buf = (uint16_t)color;
00566 }
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 void LCDD_DrawLine(uint16_t *pCanvasBuffer, uint32_t dwX1, uint32_t dwY1,
00580 uint32_t dwX2, uint32_t dwY2 , uint32_t color)
00581 {
00582 if ((dwY1 == dwY2) || (dwX1 == dwX2)) {
00583
00584 LCDD_DrawStraightLine(pCanvasBuffer, dwX1, dwY1, dwX2, dwY2, color);
00585 } else
00586 LCDD_DrawLineBresenham(pCanvasBuffer, dwX1, dwY1, dwX2, dwY2 , color);
00587 }
00588
00589 void LCDD_DrawStraightLine(uint16_t *pCanvasBuffer, uint32_t dwX1,
00590 uint32_t dwY1,
00591 uint32_t dwX2, uint32_t dwY2 , uint32_t color)
00592 {
00593 uint32_t x, y;
00594 uint32_t tmp;
00595
00596 if (dwY1 > dwY2) {
00597 tmp = dwY1;
00598 dwY1 = dwY2;
00599 dwY2 = tmp;
00600 }
00601
00602 if (dwX1 > dwX2) {
00603 tmp = dwX1;
00604 dwX1 = dwX2;
00605 dwX2 = tmp;
00606 }
00607
00608 for (y = dwY1; y <= dwY2; y++) {
00609 for (x = dwX1; x <= dwX2; x++)
00610 LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00611 }
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 uint32_t LCDD_DrawLineBresenham(uint16_t *pCanvasBuffer, uint32_t dwX1,
00625 uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 , uint32_t color)
00626 {
00627 int dx, dy;
00628 int i;
00629 int xinc, yinc, cumul;
00630 int x, y;
00631
00632 x = dwX1;
00633 y = dwY1;
00634 dx = dwX2 - dwX1;
00635 dy = dwY2 - dwY1;
00636
00637 xinc = (dx > 0) ? 1 : -1;
00638 yinc = (dy > 0) ? 1 : -1;
00639 dx = (dx > 0) ? dx : -dx;
00640 dy = (dy > 0) ? dy : -dy;
00641
00642 LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00643
00644 if (dx > dy) {
00645 cumul = dx / 2;
00646
00647 for (i = 1; i <= dx; i++) {
00648 x += xinc;
00649 cumul += dy;
00650
00651 if (cumul >= dx) {
00652 cumul -= dx;
00653 y += yinc;
00654 }
00655
00656 LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00657 }
00658 } else {
00659 cumul = dy / 2;
00660
00661 for (i = 1; i <= dy; i++) {
00662 y += yinc;
00663 cumul += dx;
00664
00665 if (cumul >= dy) {
00666 cumul -= dy;
00667 x += xinc;
00668 }
00669
00670 LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00671 }
00672 }
00673
00674 return 0;
00675 }
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 void LCDD_DrawRectangle(uint16_t *pCanvasBuffer, uint32_t x, uint32_t y,
00688 uint32_t width, uint32_t height, uint32_t color)
00689 {
00690 LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y, width, 1, color);
00691 LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y, 1, height, color);
00692
00693 LCDD_DrawRectangleWithFill(pCanvasBuffer, x + width , y, 1, height, color);
00694 LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y + height, width, 1, color);
00695 }
00696
00697
00698
00699
00700
00701
00702
00703 void LCDD_SetCavasBuffer(void *pCanvasBuffer, uint32_t wBufferSize)
00704 {
00705 if (ili9488_lcdMode == ILI9488_SPIMODE) {
00706 gpCanvasBuffer = (sBGR *)pCanvasBuffer;
00707 gwCanvasBufferSize = wBufferSize;
00708 } else {
00709 gpCanvasBuffer = (uint16_t *)pCanvasBuffer;
00710 gwCanvasBufferSize = wBufferSize;
00711 }
00712 }
00713
00714