iriver: LCD flip for H1x0 remote, some code cleanup.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6739 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/settings.c b/apps/settings.c
index ea664a1..6588a6e 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -264,6 +264,7 @@
     {1, S_O(remote_invert), false, "remote invert", off_on },
     {5, S_O(remote_backlight_timeout), 5, "remote backlight timeout",
         "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90" },
+    {1, S_O(remote_flip_display), false, "remote flip display", off_on },
 #endif
 
     /* Current sum of bits: 259 (worst case) */
@@ -394,7 +395,7 @@
 #endif
     
     /* new stuff to be added at the end */
-		    
+            
     /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */
 };
 
@@ -757,10 +758,11 @@
     lcd_set_contrast(global_settings.contrast);
     lcd_scroll_speed(global_settings.scroll_speed);
 #ifdef HAVE_REMOTE_LCD
-	lcd_remote_set_contrast(global_settings.remote_contrast);
-	lcd_remote_set_invert_display(global_settings.remote_invert);
+    lcd_remote_set_contrast(global_settings.remote_contrast);
+    lcd_remote_set_invert_display(global_settings.remote_invert);
+    lcd_remote_set_flip(global_settings.remote_flip_display);
     remote_backlight_set_timeout(global_settings.remote_backlight_timeout);
-#endif 
+#endif
     backlight_set_timeout(global_settings.backlight_timeout);
     backlight_set_on_when_charging(global_settings.backlight_on_when_charging);
     ata_spindown(global_settings.disk_spindown);
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index 9826058..d8f440c 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -101,6 +101,17 @@
                                 lcd_remote_set_invert_display);
      return rc;
 }
+
+static bool remote_flip_display(void)
+{
+    bool rc = set_bool( str(LANG_FLIP_DISPLAY),
+                        &global_settings.remote_flip_display);
+    
+    lcd_remote_set_flip(global_settings.remote_flip_display);
+    lcd_remote_update();
+
+    return rc;
+}
 #endif
 
 #ifdef CONFIG_BACKLIGHT
@@ -1262,8 +1273,8 @@
         { ID2P(LANG_BACKLIGHT),       remote_backlight_timer },
         { ID2P(LANG_CONTRAST),        remote_contrast },
         { ID2P(LANG_INVERT),          remote_invert },
-/*        { ID2P(LANG_FLIP_DISPLAY),    remote_flip_display },
-        { ID2P(LANG_INVERT_CURSOR),   invert_cursor },*/
+        { ID2P(LANG_FLIP_DISPLAY),    remote_flip_display },
+/*        { ID2P(LANG_INVERT_CURSOR),   invert_cursor },*/
     };
 
     m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c
index 2850712..04a4b7f 100644
--- a/firmware/drivers/lcd-h100-remote.c
+++ b/firmware/drivers/lcd-h100-remote.c
@@ -38,6 +38,9 @@
 static int curfont = FONT_SYSFIXED;
 static int xmargin = 0;
 static int ymargin = 0;
+#ifndef SIMULATOR
+static int xoffset; /* needed for flip */
+#endif
 
 unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]
 #ifndef SIMULATOR
@@ -70,6 +73,7 @@
 
 /* cached settings values, for hotplug init */
 static bool cached_invert = false;
+static bool cached_flip = false;
 static int cached_contrast = 32;
 static int cached_roll = 0;
 
@@ -206,7 +210,7 @@
 #define LCD_REMOTE_CNTL_DISPLAY_ON_OFF      0xae
 #define LCD_REMOTE_CNTL_ENTIRE_ON_OFF       0xa4
 #define LCD_REMOTE_CNTL_REVERSE_ON_OFF      0xa6
-#define LCD_REMOTE_CTNL_NOP                 0xe3
+#define LCD_REMOTE_CNTL_NOP                 0xe3
 #define LCD_REMOTE_CNTL_POWER_CONTROL       0x2b
 #define LCD_REMOTE_CNTL_SELECT_REGULATOR    0x20
 #define LCD_REMOTE_CNTL_SELECT_BIAS         0xa2
@@ -214,6 +218,9 @@
 #define LCD_REMOTE_CNTL_INIT_LINE           0x40
 #define LCD_REMOTE_CNTL_SET_PAGE_ADDRESS    0xB0
 
+#define LCD_REMOTE_CNTL_HIGHCOL             0x10    /* Upper column address */
+#define LCD_REMOTE_CNTL_LOWCOL              0x00    /* Lower column address */
+
 void lcd_remote_powersave(bool on)
 {
     if (remote_initialized)
@@ -237,6 +244,30 @@
         lcd_remote_write_command(LCD_REMOTE_CNTL_REVERSE_ON_OFF | yesno);
 }
 
+/* turn the display upside down (call lcd_remote_update() afterwards) */
+void lcd_remote_set_flip(bool yesno)
+{
+    cached_flip = yesno;
+    if (yesno)
+    {
+        xoffset = 0;
+        if (remote_initialized)
+        {
+            lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_NORMAL);
+            lcd_remote_write_command(LCD_REMOTE_CNTL_SHL_NORMAL);
+        }
+    }
+    else
+    {
+        xoffset = 132 - LCD_REMOTE_WIDTH;
+        if (remote_initialized)
+        {
+            lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_REVERSE);
+            lcd_remote_write_command(LCD_REMOTE_CNTL_SHL_REVERSE);
+        }
+    }
+}
+
 int lcd_remote_default_contrast(void)
 {
     return 32;
@@ -394,8 +425,6 @@
 
 static void remote_lcd_init(void)
 {
-    lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_REVERSE);
-    lcd_remote_write_command(LCD_REMOTE_CNTL_SHL_REVERSE);
     lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0);
 
     lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x5);
@@ -416,6 +445,7 @@
     
     remote_initialized = true;
 
+    lcd_remote_set_flip(cached_flip);
     lcd_remote_set_contrast(cached_contrast);
     lcd_remote_set_invert_display(cached_invert);
     lcd_remote_roll(cached_roll);
@@ -490,7 +520,8 @@
     for (y = 0; y < LCD_REMOTE_HEIGHT / 8; y++)
     {
         lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | y);
-        lcd_remote_write_command_ex(0x10, 0x04);
+        lcd_remote_write_command(LCD_REMOTE_CNTL_HIGHCOL | ((xoffset>>4) & 0xf));
+        lcd_remote_write_command(LCD_REMOTE_CNTL_LOWCOL | (xoffset & 0xf));
         lcd_remote_write_data(lcd_remote_framebuffer[y], LCD_REMOTE_WIDTH);
     }
 }
@@ -522,8 +553,11 @@
     for (; y <= ymax; y++)
     {        
         lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | y);
-        lcd_remote_write_command_ex(0x10, 0x00);
-        lcd_remote_write_data(&lcd_remote_framebuffer[y][x_start], width);        
+        lcd_remote_write_command(LCD_REMOTE_CNTL_HIGHCOL
+                                 | (((x_start+xoffset)>>4) & 0xf));
+        lcd_remote_write_command(LCD_REMOTE_CNTL_LOWCOL 
+                                 | ((x_start+xoffset) & 0xf));
+        lcd_remote_write_data(&lcd_remote_framebuffer[y][x_start], width);
     }
 }
 
diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h
index f57a6ee..88b185c 100644
--- a/firmware/export/lcd-remote.h
+++ b/firmware/export/lcd-remote.h
@@ -79,7 +79,7 @@
 extern void lcd_remote_invertpixel(int x, int y);
 extern void lcd_remote_roll(int pixels);
 extern void lcd_remote_set_invert_display(bool yesno);
-//extern void lcd_set_flip(bool yesno);
+extern void lcd_remote_set_flip(bool yesno);
 extern void lcd_remote_bidir_scroll(int threshold);
 extern void lcd_remote_scroll_step(int pixels);
 extern void lcd_remote_setfont(int font);