From 3a3304fa31c081cfd41e125b814eab58f83422c0 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Sat, 1 Apr 2006 23:48:03 +0000 Subject: greyscale iPod LCD: Working display flip. * Correct register definitions for HD66753. * Correct 1/3 and 2/3 greylevels. * Some tweaks. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9414 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/button.c | 23 +++++---- firmware/drivers/lcd-2bit-horz.c | 6 ++- firmware/drivers/lcd-ipod.c | 99 ++++++++++++++++++++++++++----------- firmware/export/config-ipod3g.h | 3 ++ firmware/export/config-ipod4g.h | 3 ++ firmware/export/config-ipodmini.h | 3 ++ firmware/export/config-ipodmini2g.h | 3 ++ 7 files changed, 97 insertions(+), 43 deletions(-) diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index 99b5b06c69..6a95932763 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c @@ -694,30 +694,33 @@ void button_init(void) } #ifdef HAVE_LCD_BITMAP /* only bitmap displays can be flipped */ -#if (CONFIG_KEYPAD != IPOD_3G_PAD) && (CONFIG_KEYPAD != IPOD_4G_PAD) /* - * helper function to swap UP/DOWN, LEFT/RIGHT (and F1/F3 for Recorder) + * helper function to swap LEFT/RIGHT, UP/DOWN (if present), and F1/F3 (Recorder) */ static int button_flip(int button) { int newbutton; newbutton = button & - ~(BUTTON_UP | BUTTON_DOWN - | BUTTON_LEFT | BUTTON_RIGHT + ~(BUTTON_LEFT | BUTTON_RIGHT +#if defined(BUTTON_UP) && defined(BUTTON_DOWN) + | BUTTON_UP | BUTTON_DOWN +#endif #if CONFIG_KEYPAD == RECORDER_PAD | BUTTON_F1 | BUTTON_F3 #endif ); - if (button & BUTTON_UP) - newbutton |= BUTTON_DOWN; - if (button & BUTTON_DOWN) - newbutton |= BUTTON_UP; if (button & BUTTON_LEFT) newbutton |= BUTTON_RIGHT; if (button & BUTTON_RIGHT) newbutton |= BUTTON_LEFT; +#if defined(BUTTON_UP) && defined(BUTTON_DOWN) + if (button & BUTTON_UP) + newbutton |= BUTTON_DOWN; + if (button & BUTTON_DOWN) + newbutton |= BUTTON_UP; +#endif #if CONFIG_KEYPAD == RECORDER_PAD if (button & BUTTON_F1) newbutton |= BUTTON_F3; @@ -727,10 +730,6 @@ static int button_flip(int button) return newbutton; } -#else -/* We don't flip the iPod's keypad yet*/ -#define button_flip(x) (x) -#endif /* * set the flip attribute diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index bfb69da33b..826f68a06a 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c @@ -86,7 +86,11 @@ void lcd_init(void) int lcd_default_contrast(void) { - return 40; +#if defined(IPOD_MINI) || defined(IPOD_MINI2G) + return 42; +#else + return 35; +#endif } /*** parameter handling ***/ diff --git a/firmware/drivers/lcd-ipod.c b/firmware/drivers/lcd-ipod.c index d9b0df5b3c..3f777cf7a9 100644 --- a/firmware/drivers/lcd-ipod.c +++ b/firmware/drivers/lcd-ipod.c @@ -36,7 +36,6 @@ static inline bool timer_check(int clock_start, int usecs) return ((int)(USEC_TIMER - clock_start)) >= usecs; } - #if (CONFIG_LCD == LCD_IPOD2BPP) /*** hardware configuration ***/ @@ -63,16 +62,19 @@ static inline bool timer_check(int clock_start, int usecs) #define R_ROTATION 0x06 #define R_DISPLAY_CONTROL 0x07 #define R_CURSOR_CONTROL 0x08 -#define R_DOUBLE_HEIGHT_POS 0x09 -#define R_VERTICAL_SCROLL 0x0a -#define R_VERTICAL_CURSOR_POS 0x0b -#define R_HORIZONTAL_CURSOR_POS 0x0c +#define R_HORIZONTAL_CURSOR_POS 0x0b +#define R_VERTICAL_CURSOR_POS 0x0c +#define R_1ST_SCR_DRV_POS 0x0d +#define R_2ND_SCR_DRV_POS 0x0e #define R_RAM_WRITE_MASK 0x10 #define R_RAM_ADDR_SET 0x11 #define R_RAM_DATA 0x12 -static unsigned int lcd_contrast = 0x2a; - +/* needed for flip */ +static int addr_offset = 0; +#if defined(IPOD_MINI) || defined(IPOD_MINI2G) +static int pix_offset = 0; +#endif /* wait for LCD with timeout */ static void lcd_wait_write(void) @@ -86,7 +88,7 @@ static void lcd_wait_write(void) /* send LCD data */ -static void lcd_send_data(int data) +static void lcd_send_data(unsigned data) { lcd_wait_write(); #ifdef IPOD_MINI2G @@ -100,7 +102,7 @@ static void lcd_send_data(int data) } /* send LCD command */ -static void lcd_prepare_cmd(int cmd) +static void lcd_prepare_cmd(unsigned cmd) { lcd_wait_write(); #ifdef IPOD_MINI2G @@ -114,22 +116,17 @@ static void lcd_prepare_cmd(int cmd) } /* send LCD command and data */ -static void lcd_cmd_and_data(int cmd, int data) +static void lcd_cmd_and_data(unsigned cmd, unsigned data) { lcd_prepare_cmd(cmd); lcd_send_data(data); } /* LCD init */ -void lcd_init_device(void){ -#if defined(IPOD_MINI) || defined(IPOD_MINI2G) - /* driver output control - 160x112 (ipod mini) */ - lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000d); -#else - /* driver output control - 160x128 */ - lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010f); -#endif - +void lcd_init_device(void) +{ + lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015); + lcd_set_flip(false); lcd_cmd_and_data(R_ENTRY_MODE, 0x0010); #ifdef APPLE_IPOD4G @@ -168,22 +165,46 @@ void lcd_set_contrast(int val) else if (val > 63) val = 63; lcd_cmd_and_data(R_CONTRAST_CONTROL, 0x400 | (val + 64)); - lcd_contrast = val; } void lcd_set_invert_display(bool yesno) { if (yesno) - lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0003); + lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0017); else - lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0001); + lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015); } /* turn the display upside down (call lcd_update() afterwards) */ void lcd_set_flip(bool yesno) { - /* TODO: Implement lcd_set_flip() */ - (void)yesno; +#if defined(IPOD_MINI) || defined(IPOD_MINI2G) + if (yesno) { + /* 160x112, inverse SEG & COM order */ + lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030d); + lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */ + addr_offset = (22 << 5) | 3; + pix_offset = 6; + } else { + /* 160x112 */ + lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000d); + lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */ + addr_offset = 0; + pix_offset = 0; + } +#else + if (yesno) { + /* 160x128, inverse COM order */ + lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020f); + lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 0..127 */ + addr_offset = (4 << 5) | 1; + } else { + /* 160x128, inverse SEG order */ + lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010f); + lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 4..131 */ + addr_offset = 0; + } +#endif } void lcd_update_rect(int x, int y, int width, int height) @@ -199,6 +220,9 @@ void lcd_update_rect(int x, int y, int width, int height) if (ymax >= LCD_HEIGHT) ymax = LCD_HEIGHT - 1; +#if defined(IPOD_MINI) || defined(IPOD_MINI2G) + x += pix_offset; +#endif /* writing is done in 16-bit units (8 pixels) */ xmax = (x + width - 1) >> 3; x >>= 3; @@ -206,17 +230,32 @@ void lcd_update_rect(int x, int y, int width, int height) for (; y <= ymax; y++) { unsigned char *data, *data_end; - int ram_addr = x | (y << 5); + int ram_addr = (x | (y << 5)) + addr_offset; lcd_cmd_and_data(R_RAM_ADDR_SET, ram_addr); lcd_prepare_cmd(R_RAM_DATA); - + data = &lcd_framebuffer[y][2*x]; data_end = data + 2 * width; - do { - int lowbyte = *data++; - lcd_send_data((*data++ << 8) | lowbyte); - } while (data < data_end); +#if defined(IPOD_MINI) || defined(IPOD_MINI2G) + if (pix_offset == 6) { + data -= 2; + data_end -= 1; + unsigned cur_word = *data++ >> 4; + do { + cur_word |= *data++ << 4; + cur_word |= *data++ << 12; + lcd_send_data(cur_word & 0xffff); + cur_word >>= 16; + } while (data < data_end); + } else +#endif + { + do { + unsigned lowbyte = *data++; + lcd_send_data(lowbyte | (*data++ << 8)); + } while (data < data_end); + } } } diff --git a/firmware/export/config-ipod3g.h b/firmware/export/config-ipod3g.h index 072d6027fc..8cca000961 100644 --- a/firmware/export/config-ipod3g.h +++ b/firmware/export/config-ipod3g.h @@ -21,6 +21,9 @@ #define LCD_PIXELFORMAT HORIZONTAL_PACKING +/* define this if you can flip your LCD */ +#define HAVE_LCD_FLIP + #define CONFIG_KEYPAD IPOD_3G_PAD /* Define this if you do software codec */ diff --git a/firmware/export/config-ipod4g.h b/firmware/export/config-ipod4g.h index 7195f207e1..7e428de68f 100644 --- a/firmware/export/config-ipod4g.h +++ b/firmware/export/config-ipod4g.h @@ -21,6 +21,9 @@ #define LCD_PIXELFORMAT HORIZONTAL_PACKING +/* define this if you can flip your LCD */ +#define HAVE_LCD_FLIP + #define CONFIG_KEYPAD IPOD_4G_PAD /* Define this if you do software codec */ diff --git a/firmware/export/config-ipodmini.h b/firmware/export/config-ipodmini.h index b4e909ce07..4514bcb471 100644 --- a/firmware/export/config-ipodmini.h +++ b/firmware/export/config-ipodmini.h @@ -21,6 +21,9 @@ #define LCD_PIXELFORMAT HORIZONTAL_PACKING +/* define this if you can flip your LCD */ +#define HAVE_LCD_FLIP + #define CONFIG_KEYPAD IPOD_4G_PAD /* Define this if you do software codec */ diff --git a/firmware/export/config-ipodmini2g.h b/firmware/export/config-ipodmini2g.h index 0f9011c437..8cea14470b 100755 --- a/firmware/export/config-ipodmini2g.h +++ b/firmware/export/config-ipodmini2g.h @@ -21,6 +21,9 @@ #define LCD_PIXELFORMAT HORIZONTAL_PACKING +/* define this if you can flip your LCD */ +#define HAVE_LCD_FLIP + #define CONFIG_KEYPAD IPOD_4G_PAD /* Define this if you do software codec */ -- cgit v1.2.3