summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-2bit-horz.c33
-rw-r--r--firmware/drivers/lcd-ipod.c47
2 files changed, 38 insertions, 42 deletions
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index 826f68a06a..e15d8ddbc4 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -46,7 +46,7 @@ static const unsigned char dibits[16] ICONST_ATTR = {
46}; 46};
47 47
48static const unsigned char pixmask[4] ICONST_ATTR = { 48static const unsigned char pixmask[4] ICONST_ATTR = {
49 0x03, 0x0C, 0x30, 0xC0 49 0xC0, 0x30, 0x0C, 0x03
50}; 50};
51 51
52static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ 52static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */
@@ -381,8 +381,8 @@ void lcd_hline(int x1, int x2, int y)
381 bfunc = lcd_blockfuncs[drawmode]; 381 bfunc = lcd_blockfuncs[drawmode];
382 dst = &lcd_framebuffer[y][x1>>2]; 382 dst = &lcd_framebuffer[y][x1>>2];
383 nx = x2 - (x1 & ~3); 383 nx = x2 - (x1 & ~3);
384 mask = 0xFFu << (2 * (x1 & 3)); 384 mask = 0xFFu >> (2 * (x1 & 3));
385 mask_right = 0xFFu >> (2 * (~nx & 3)); 385 mask_right = 0xFFu << (2 * (~nx & 3));
386 386
387 for (; nx >= 4; nx -= 4) 387 for (; nx >= 4; nx -= 4)
388 { 388 {
@@ -479,8 +479,8 @@ void lcd_fillrect(int x, int y, int width, int height)
479 bfunc = lcd_blockfuncs[drawmode]; 479 bfunc = lcd_blockfuncs[drawmode];
480 dst = &lcd_framebuffer[y][x>>2]; 480 dst = &lcd_framebuffer[y][x>>2];
481 nx = width - 1 + (x & 3); 481 nx = width - 1 + (x & 3);
482 mask = 0xFFu << (2 * (x & 3)); 482 mask = 0xFFu >> (2 * (x & 3));
483 mask_right = 0xFFu >> (2 * (~nx & 3)); 483 mask_right = 0xFFu << (2 * (~nx & 3));
484 484
485 for (; nx >= 4; nx -= 4) 485 for (; nx >= 4; nx -= 4)
486 { 486 {
@@ -515,9 +515,7 @@ void lcd_fillrect(int x, int y, int width, int height)
515 * at top. 515 * at top.
516 * The bytes are stored in row-major order, with byte 0 being top left, 516 * The bytes are stored in row-major order, with byte 0 being top left,
517 * byte 1 2nd from left etc. The first row of bytes defines pixel row 517 * byte 1 2nd from left etc. The first row of bytes defines pixel row
518 * 0, the second row defines pixel row 1 etc. 518 * 0, the second row defines pixel row 1 etc. */
519 *
520 * This is similar to the internal lcd hw format. */
521 519
522/* Draw a partial monochrome bitmap */ 520/* Draw a partial monochrome bitmap */
523void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 521void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
@@ -602,7 +600,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig
602 * 600 *
603 * A bitmap contains two bits for every pixel. 00 = white, 01 = light grey, 601 * A bitmap contains two bits for every pixel. 00 = white, 01 = light grey,
604 * 10 = dark grey, 11 = black. Bits within a byte are arranged horizontally, 602 * 10 = dark grey, 11 = black. Bits within a byte are arranged horizontally,
605 * LSB at the left. 603 * MSB at the left.
606 * The bytes are stored in row-major order, with byte 0 being top left, 604 * The bytes are stored in row-major order, with byte 0 being top left,
607 * byte 1 2nd from left etc. Each row of bytes defines one pixel row. 605 * byte 1 2nd from left etc. Each row of bytes defines one pixel row.
608 * 606 *
@@ -651,8 +649,8 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
651 shift = x & 3; 649 shift = x & 3;
652 nx = width - 1 + shift + src_x; 650 nx = width - 1 + shift + src_x;
653 651
654 mask = 0xFFu << (2 * (shift + src_x)); 652 mask = 0xFF00u >> (2 * (shift + src_x));
655 mask_right = 0xFFu >> (2 * (~nx & 3)); 653 mask_right = 0xFFu << (2 * (~nx & 3));
656 654
657 shift *= 2; 655 shift *= 2;
658 dst_end = dst + height * LCD_FBWIDTH; 656 dst_end = dst + height * LCD_FBWIDTH;
@@ -660,26 +658,25 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
660 { 658 {
661 const unsigned char *src_row = src; 659 const unsigned char *src_row = src;
662 unsigned char *dst_row = dst; 660 unsigned char *dst_row = dst;
663 unsigned mask_row = mask; 661 unsigned mask_row = mask >> 8;
664 unsigned data = 0; 662 unsigned data = 0;
665 663
666 for (x = nx; x >= 4; x -= 4) 664 for (x = nx; x >= 4; x -= 4)
667 { 665 {
668 data |= *src_row++ << shift; 666 data = (data << 8) | *src_row++;
669 667
670 if (mask_row & 0xFF) 668 if (mask_row & 0xFF)
671 { 669 {
672 setblock(dst_row, mask_row, data); 670 setblock(dst_row, mask_row, data >> shift);
673 mask_row = 0xFF; 671 mask_row = 0xFF;
674 } 672 }
675 else 673 else
676 mask_row >>= 8; 674 mask_row = mask;
677 675
678 dst_row++; 676 dst_row++;
679 data >>= 8;
680 } 677 }
681 data |= *src_row << shift; 678 data = (data << 8) | *src_row;
682 setblock(dst_row, mask_row & mask_right, data); 679 setblock(dst_row, mask_row & mask_right, data >> shift);
683 680
684 src += stride; 681 src += stride;
685 dst += LCD_FBWIDTH; 682 dst += LCD_FBWIDTH;
diff --git a/firmware/drivers/lcd-ipod.c b/firmware/drivers/lcd-ipod.c
index 3f777cf7a9..ab0940d56b 100644
--- a/firmware/drivers/lcd-ipod.c
+++ b/firmware/drivers/lcd-ipod.c
@@ -71,13 +71,13 @@ static inline bool timer_check(int clock_start, int usecs)
71#define R_RAM_DATA 0x12 71#define R_RAM_DATA 0x12
72 72
73/* needed for flip */ 73/* needed for flip */
74static int addr_offset = 0; 74static int addr_offset;
75#if defined(IPOD_MINI) || defined(IPOD_MINI2G) 75#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
76static int pix_offset = 0; 76static int pix_offset;
77#endif 77#endif
78 78
79/* wait for LCD with timeout */ 79/* wait for LCD with timeout */
80static void lcd_wait_write(void) 80static inline void lcd_wait_write(void)
81{ 81{
82 int start = USEC_TIMER; 82 int start = USEC_TIMER;
83 83
@@ -127,7 +127,7 @@ void lcd_init_device(void)
127{ 127{
128 lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015); 128 lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015);
129 lcd_set_flip(false); 129 lcd_set_flip(false);
130 lcd_cmd_and_data(R_ENTRY_MODE, 0x0010); 130 lcd_cmd_and_data(R_ENTRY_MODE, 0x0000);
131 131
132#ifdef APPLE_IPOD4G 132#ifdef APPLE_IPOD4G
133 outl(inl(0x6000d004) | 0x4, 0x6000d004); /* B02 enable */ 133 outl(inl(0x6000d004) | 0x4, 0x6000d004); /* B02 enable */
@@ -180,29 +180,29 @@ void lcd_set_flip(bool yesno)
180{ 180{
181#if defined(IPOD_MINI) || defined(IPOD_MINI2G) 181#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
182 if (yesno) { 182 if (yesno) {
183 /* 160x112, inverse SEG & COM order */ 183 /* 168x112, inverse COM order */
184 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030d); 184 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020d);
185 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */ 185 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */
186 addr_offset = (22 << 5) | 3; 186 addr_offset = (22 << 5) | (20 - 3);
187 pix_offset = 6; 187 pix_offset = 6;
188 } else { 188 } else {
189 /* 160x112 */ 189 /* 168x112, inverse SEG order */
190 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000d); 190 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010d);
191 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */ 191 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */
192 addr_offset = 0; 192 addr_offset = 20;
193 pix_offset = 0; 193 pix_offset = 0;
194 } 194 }
195#else 195#else
196 if (yesno) { 196 if (yesno) {
197 /* 160x128, inverse COM order */ 197 /* 168x128, inverse SEG & COM order */
198 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020f); 198 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030f);
199 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 0..127 */ 199 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 0..127 */
200 addr_offset = (4 << 5) | 1; 200 addr_offset = (4 << 5) | (20 - 1);
201 } else { 201 } else {
202 /* 160x128, inverse SEG order */ 202 /* 168x128 */
203 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010f); 203 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000f);
204 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 4..131 */ 204 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 4..131 */
205 addr_offset = 0; 205 addr_offset = 20;
206 } 206 }
207#endif 207#endif
208} 208}
@@ -230,7 +230,7 @@ void lcd_update_rect(int x, int y, int width, int height)
230 230
231 for (; y <= ymax; y++) { 231 for (; y <= ymax; y++) {
232 unsigned char *data, *data_end; 232 unsigned char *data, *data_end;
233 int ram_addr = (x | (y << 5)) + addr_offset; 233 int ram_addr = (y << 5) + addr_offset - x;
234 234
235 lcd_cmd_and_data(R_RAM_ADDR_SET, ram_addr); 235 lcd_cmd_and_data(R_RAM_ADDR_SET, ram_addr);
236 lcd_prepare_cmd(R_RAM_DATA); 236 lcd_prepare_cmd(R_RAM_DATA);
@@ -241,19 +241,18 @@ void lcd_update_rect(int x, int y, int width, int height)
241 if (pix_offset == 6) { 241 if (pix_offset == 6) {
242 data -= 2; 242 data -= 2;
243 data_end -= 1; 243 data_end -= 1;
244 unsigned cur_word = *data++ >> 4; 244 unsigned cur_word = *data++;
245 do { 245 do {
246 cur_word |= *data++ << 4; 246 cur_word = (cur_word << 8) | *data++;
247 cur_word |= *data++ << 12; 247 cur_word = (cur_word << 8) | *data++;
248 lcd_send_data(cur_word & 0xffff); 248 lcd_send_data((cur_word >> 4) & 0xffff);
249 cur_word >>= 16;
250 } while (data < data_end); 249 } while (data < data_end);
251 } else 250 } else
252#endif 251#endif
253 { 252 {
254 do { 253 do {
255 unsigned lowbyte = *data++; 254 unsigned highbyte = *data++;
256 lcd_send_data(lowbyte | (*data++ << 8)); 255 lcd_send_data((highbyte << 8) | *data++);
257 } while (data < data_end); 256 } while (data < data_end);
258 } 257 }
259 } 258 }