summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iaudio/x5/lcd-x5.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iaudio/x5/lcd-x5.c')
-rwxr-xr-xfirmware/target/coldfire/iaudio/x5/lcd-x5.c135
1 files changed, 31 insertions, 104 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
index 240b1db586..e1fe23a442 100755
--- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
@@ -100,25 +100,6 @@ static inline void lcd_begin_write_gram(void)
100 LCD_CMD = R_WRITE_DATA_2_GRAM << 1; 100 LCD_CMD = R_WRITE_DATA_2_GRAM << 1;
101} 101}
102 102
103static inline void lcd_write_one(unsigned short px)
104{
105 unsigned short pxsr = px >> 8;
106 LCD_DATA = pxsr + (pxsr & 0x1F8);
107 LCD_DATA = px << 1;
108}
109
110/* Write two pixels to gram from a long */
111/* called very frequently - inline! */
112static inline void lcd_write_two(unsigned long px2)
113{
114 unsigned short px2sr = px2 >> 24;
115 LCD_DATA = px2sr + (px2sr & 0x1F8);
116 LCD_DATA = px2 >> 15;
117 px2sr = px2 >> 8;
118 LCD_DATA = px2sr + (px2sr & 0x1F8);
119 LCD_DATA = px2 << 1;
120}
121
122/*** hardware configuration ***/ 103/*** hardware configuration ***/
123 104
124int lcd_default_contrast(void) 105int lcd_default_contrast(void)
@@ -423,45 +404,38 @@ void lcd_blit(const fb_data* data, int x, int by, int width,
423 /*if(display_on)*/ 404 /*if(display_on)*/
424} 405}
425 406
426/* Performance function to blit a YUV bitmap directly to the LCD */ 407/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420.
427/* Assumes YCrCb 4:2:0. */ 408 * y should have two lines of Y back to back.
428/* 409 * bu and rv should contain the Cb and Cr data for the two lines of Y.
429 See http://en.wikipedia.org/wiki/YCbCr 410 * Stores bu, guv and rv in repective buffers for use in second line.
430 ITU-R BT.601 (formerly CCIR 601): 411 */
431 |Y'| | 0.299000 0.587000 0.114000| |R| 412extern void lcd_write_yuv420_lines(const unsigned char *y,
432 |Pb| = |-0.168736 -0.331264 0.500000| |G| or 0.564334 * (B - Y') 413 unsigned char *bu, unsigned char *guv, unsigned char *rv,
433 |Pr| | 0.500000 -0.418688 0.081312| |B| or 0.713267 * (R - Y') 414 int width);
434 Scaled, normalized and rounded: 415
435 |Y'| | 65 129 25| |R| + 16 : 16->235 416/* Performance function to blit a YUV bitmap directly to the LCD
436 |Cb| = |-38 -74 112| |G| + 128 : 16->240 417 * src_x, src_y, width and height should be even and within the LCD's
437 |Cr| |112 -94 -18| |B| + 128 : 16->240 418 * boundaries.
438 419 */
439 The inverse:
440 |R| |1.000000 -0.000001 1.402000| |Y'|
441 |G| = |1.000000 -0.334136 -0.714136| |Pb|
442 |B| |1.000000 1.772000 0.000000| |Pr|
443 Scaled, normalized, rounded and tweaked to yield RGB 666:
444 |R| |298 0 409| |Y' - 16| / 1024
445 |G| = |298 -100 -208| |Cb - 128| / 1024
446 |B| |298 516 0| |Cr - 128| / 1024
447*/
448void lcd_yuv_blit(unsigned char * const [3], int, int, int,
449 int, int, int, int) ICODE_ATTR;
450void lcd_yuv_blit(unsigned char * const src[3], 420void lcd_yuv_blit(unsigned char * const src[3],
451 int src_x, int src_y, int stride, 421 int src_x, int src_y, int stride,
452 int x, int y, int width, int height) 422 int x, int y, int width, int height)
453{ 423{
424 /* IRAM Y, Cb/bu, guv and Cb/rv buffers. */
425 unsigned char y_ibuf[LCD_WIDTH*2];
426 unsigned char bu_ibuf[LCD_WIDTH/2];
427 unsigned char guv_ibuf[LCD_WIDTH/2];
428 unsigned char rv_ibuf[LCD_WIDTH/2];
454 const unsigned char *ysrc, *usrc, *vsrc; 429 const unsigned char *ysrc, *usrc, *vsrc;
455 int uv_stepper, uv_step, y_end; 430 const unsigned char *ysrc_max;
456 431
457 if (!display_on) 432 if (!display_on)
458 return; 433 return;
459 434
460 width = (width + 1) & ~1; 435 width = (width + 1) & ~1;
461 height = (height + 1) & ~1; 436 height = (height + 1) & ~1;
462 y_end = y + height;
463 437
464 /* Set start position and window */ 438 /* Set start position and window */
465 lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | 439 lcd_write_reg(R_RAM_ADDR_SET, (x << 8) |
466 (((y + roll_offset) & 127) + y_offset)); 440 (((y + roll_offset) & 127) + y_offset));
467 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); 441 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
@@ -471,72 +445,26 @@ void lcd_yuv_blit(unsigned char * const src[3],
471 ysrc = src[0] + src_y*stride + src_x; 445 ysrc = src[0] + src_y*stride + src_x;
472 usrc = src[1] + (src_y*stride >> 2) + (src_x >> 1); 446 usrc = src[1] + (src_y*stride >> 2) + (src_x >> 1);
473 vsrc = src[2] + (usrc - src[1]); 447 vsrc = src[2] + (usrc - src[1]);
474 448 ysrc_max = ysrc + height*stride;
475 stride = stride - width; /* Use end of current line->start of next */
476 uv_stepper = (stride >> 1) - (width >> 1);
477 uv_step = uv_stepper - (stride >> 1);
478 449
479 do 450 do
480 { 451 {
481 const unsigned char *ysrc_end = ysrc + width; 452 memcpy(y_ibuf, ysrc, width);
482 453 memcpy(&y_ibuf[width], &ysrc[stride], width);
483 do 454 memcpy(bu_ibuf, usrc, width >> 1);
484 { 455 memcpy(rv_ibuf, vsrc, width >> 1);
485 int lum, cb, cr; 456 lcd_write_yuv420_lines(y_ibuf, bu_ibuf, guv_ibuf, rv_ibuf, width);
486 int rv, guv, bu; 457 ysrc += stride << 1;
487 int r, g, b; 458 usrc += stride >> 1;
488 459 vsrc += stride >> 1;
489 lum = 298* *ysrc++ - 4768; /* 298*16 */
490 cb = *usrc++ - 128;
491 cr = *vsrc++ - 128;
492 bu = 516*cb;
493 guv = -100*cb - 208*cr;
494 rv = 409*cr;
495
496 r = (lum + rv) >> 10;
497 g = (lum + guv) >> 10;
498 b = (lum + bu) >> 10;
499
500 if ((unsigned)r > 63)
501 r = (r < 0) ? 0 : 63;
502 if ((unsigned)g > 63)
503 g = (g < 0) ? 0 : 63;
504 if ((unsigned)b > 63)
505 b = (b < 0) ? 0 : 63;
506
507 LCD_DATA = (r << 3) | (g >> 3);
508 LCD_DATA = (g << 6) | b;
509
510 lum = 298* *ysrc++ - 4768; /* 298*16 */
511 r = (lum + rv) >> 10;
512 g = (lum + guv) >> 10;
513 b = (lum + bu) >> 10;
514
515 if ((unsigned)r > 63)
516 r = (r < 0) ? 0 : 63;
517 if ((unsigned)g > 63)
518 g = (g < 0) ? 0 : 63;
519 if ((unsigned)b > 63)
520 b = (b < 0) ? 0 : 63;
521
522 LCD_DATA = (r << 3) | (g >> 3);
523 LCD_DATA = (g << 6) | b;
524 }
525 while (ysrc < ysrc_end);
526
527 usrc += uv_step;
528 vsrc += uv_step;
529 uv_step = uv_stepper - uv_step;
530
531 ysrc += stride;
532 } 460 }
533 while (++y < y_end); 461 while (ysrc < ysrc_max);
534} /* lcd_yuv_blit */ 462} /* lcd_yuv_blit */
535 463
464
536/* Update the display. 465/* Update the display.
537 This must be called after all other LCD functions that change the 466 This must be called after all other LCD functions that change the
538 lcd frame buffer. */ 467 lcd frame buffer. */
539void lcd_update(void) ICODE_ATTR;
540void lcd_update(void) 468void lcd_update(void)
541{ 469{
542 if (!display_on) 470 if (!display_on)
@@ -554,7 +482,6 @@ void lcd_update(void)
554} /* lcd_update */ 482} /* lcd_update */
555 483
556/* Update a fraction of the display. */ 484/* Update a fraction of the display. */
557void lcd_update_rect(int, int, int, int) ICODE_ATTR;
558void lcd_update_rect(int x, int y, int width, int height) 485void lcd_update_rect(int x, int y, int width, int height)
559{ 486{
560 int ymax; 487 int ymax;