summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2009-07-17 17:58:43 +0000
committerDave Chapman <dave@dchapman.com>2009-07-17 17:58:43 +0000
commit11c3f67a1e056bd6998dc2a17d9f81617708794d (patch)
tree137f8a45112a49b5aa8d47ae6c0d2b063d657857 /firmware/target/arm
parentb5f9f6152b92c237b4f7f045c16ec9f3c121dd59 (diff)
downloadrockbox-11c3f67a1e056bd6998dc2a17d9f81617708794d.tar.gz
rockbox-11c3f67a1e056bd6998dc2a17d9f81617708794d.zip
Improvments to Nano 2G LCD driver. This now works reliably on both LCD types.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21926 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c162
1 files changed, 77 insertions, 85 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
index ad2e356b5e..481e548440 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
@@ -26,24 +26,57 @@
26#include "system.h" 26#include "system.h"
27#include "cpu.h" 27#include "cpu.h"
28 28
29
30/* The Nano 2G has two different LCD types. What we call "type 0"
31 appears to be similar to the ILI9320 and "type 1" is similar to the
32 LDS176.
33*/
34
35/* LCD type 0 register defines */
36
37#define R_ENTRY_MODE 0x03
38#define R_HORIZ_GRAM_ADDR_SET 0x20
39#define R_VERT_GRAM_ADDR_SET 0x21
40#define R_WRITE_DATA_TO_GRAM 0x22
41#define R_HORIZ_ADDR_START_POS 0x50
42#define R_HORIZ_ADDR_END_POS 0x51
43#define R_VERT_ADDR_START_POS 0x52
44#define R_VERT_ADDR_END_POS 0x53
45
46
47/* LCD type 1 register defines */
48
49#define R_COLUMN_ADDR_SET 0x2a
50#define R_ROW_ADDR_SET 0x2b
51#define R_MEMORY_WRITE 0x2c
52
53
54/** globals **/
55
56static int lcd_type;
57static int xoffset; /* needed for flip */
58
29/** hardware access functions */ 59/** hardware access functions */
30 60
31static void s5l_lcd_write_cmd(unsigned short cmd) 61static inline void s5l_lcd_write_cmd_data(int cmd, int data)
32{ 62{
33 while (LCD_STATUS&0x10); 63 LCD_WCMD = cmd >> 8;
34 LCD_WCMD = cmd; 64 LCD_WCMD = cmd & 0xff;
65
66 LCD_WDATA = data >> 8;
67 LCD_WDATA = data & 0xff;
35} 68}
36 69
37static void s5l_lcd_write_data(int data) 70static inline void s5l_lcd_write_cmd(unsigned short cmd)
38{ 71{
39 LCD_WDATA = data; 72 LCD_WCMD = cmd;
40 while (LCD_STATUS&0x10);
41} 73}
42 74
43/** globals **/ 75static inline void s5l_lcd_write_data(int data)
44 76{
45static int lcd_type; 77 LCD_WDATA = data >> 8;
46static int xoffset; /* needed for flip */ 78 LCD_WDATA = data & 0xff;
79}
47 80
48/*** hardware configuration ***/ 81/*** hardware configuration ***/
49 82
@@ -54,10 +87,12 @@ int lcd_default_contrast(void)
54 87
55void lcd_set_contrast(int val) 88void lcd_set_contrast(int val)
56{ 89{
90 (void)val;
57} 91}
58 92
59void lcd_set_invert_display(bool yesno) 93void lcd_set_invert_display(bool yesno)
60{ 94{
95 (void)yesno;
61} 96}
62 97
63/* turn the display upside down (call lcd_update() afterwards) */ 98/* turn the display upside down (call lcd_update() afterwards) */
@@ -95,40 +130,23 @@ void lcd_init_device(void)
95 PCON14 &= ~0xf0; /* Set pin 1 to input */ 130 PCON14 &= ~0xf0; /* Set pin 1 to input */
96 131
97 if (((PDAT13 & 1) == 0) && ((PDAT14 & 2) == 2)) 132 if (((PDAT13 & 1) == 0) && ((PDAT14 & 2) == 2))
98 lcd_type = 0; 133 lcd_type = 0; /* Similar to ILI9320 */
99 else 134 else
100 lcd_type = 1; 135 lcd_type = 1; /* Similar to LDS176 */
101}
102
103 136
104/*** Update functions ***/ 137 /* Now init according to lcd type */
138 if (lcd_type == 0) {
139 /* TODO */
105 140
106/* Performance function that works with an external buffer 141 /* Entry Mode: AM=0, I/D1=1, I/D0=1, ORG=0, HWM=1, BGR=1 */
107 note that by and bheight are in 8-pixel units! */ 142 s5l_lcd_write_cmd_data(R_ENTRY_MODE, 0x1230);
108void lcd_blit_mono(const unsigned char *data, int x, int by, int width, 143 } else {
109 int bheight, int stride) 144 /* TODO */
110{
111 /* Copy display bitmap to hardware */
112 while (bheight--)
113 {
114 } 145 }
115} 146}
116 147
117 148
118/* Performance function that works with an external buffer 149/*** Update functions ***/
119 note that by and bheight are in 8-pixel units! */
120void lcd_blit_grey_phase_blit(unsigned char *values, unsigned char *phases,
121 int x, int by, int width, int bheight, int stride)
122{
123 (void)values;
124 (void)phases;
125 (void)x;
126 (void)by;
127 (void)width;
128 (void)bheight;
129 (void)stride;
130}
131
132 150
133/* Update the display. 151/* Update the display.
134 This must be called after all other LCD functions that change the display. */ 152 This must be called after all other LCD functions that change the display. */
@@ -140,64 +158,37 @@ void lcd_update(void)
140 fb_data pixel; 158 fb_data pixel;
141 159
142 if (lcd_type==0) { 160 if (lcd_type==0) {
143 s5l_lcd_write_cmd(0x50); 161 s5l_lcd_write_cmd_data(R_HORIZ_ADDR_START_POS, 0);
144 s5l_lcd_write_data(0); /* Start column */ 162 s5l_lcd_write_cmd_data(R_HORIZ_ADDR_END_POS, LCD_WIDTH-1);
145 s5l_lcd_write_cmd(0x51); 163 s5l_lcd_write_cmd_data(R_VERT_ADDR_START_POS, 0);
146 s5l_lcd_write_data(LCD_WIDTH-1); /* End column */ 164 s5l_lcd_write_cmd_data(R_VERT_ADDR_END_POS, LCD_HEIGHT-1);
147 s5l_lcd_write_cmd(0x52);
148 s5l_lcd_write_data(0); /* Start row */
149 s5l_lcd_write_cmd(0x53);
150 s5l_lcd_write_data(LCD_HEIGHT-1); /* End row */
151
152 s5l_lcd_write_cmd(0x20);
153 s5l_lcd_write_data(0);
154 s5l_lcd_write_cmd(0x21);
155 s5l_lcd_write_data(0);
156 s5l_lcd_write_cmd(0x22);
157
158 /* Copy display bitmap to hardware */
159 for (y = 0; y < LCD_HEIGHT; y++) {
160 for (x = 0; x < LCD_WIDTH; x++) {
161 pixel = *(p++);
162 165
163 while (LCD_STATUS&0x10); 166 s5l_lcd_write_cmd_data(R_HORIZ_GRAM_ADDR_SET, 0);
167 s5l_lcd_write_cmd_data(R_VERT_GRAM_ADDR_SET, 0);
164 168
165 LCD_WDATA = pixel & 0xff; 169 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM);
166 LCD_WDATA = (pixel & 0xff00) >> 8;
167 }
168 }
169 } else { 170 } else {
170 s5l_lcd_write_cmd(0x3a); 171 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET);
171 s5l_lcd_write_data(0x65); 172 s5l_lcd_write_data(0); /* Start column */
172 173 s5l_lcd_write_data(LCD_WIDTH-1); /* End column */
173 s5l_lcd_write_cmd(0x2a);
174 s5l_lcd_write_data(0); /* Start column, high byte */
175 s5l_lcd_write_data(0); /* Start column. low byte */
176 s5l_lcd_write_data(0); /* End column, high byte */
177 s5l_lcd_write_data(LCD_WIDTH-1); /* End column, low byte */
178 174
179 s5l_lcd_write_cmd(0x2b); 175 s5l_lcd_write_cmd(R_ROW_ADDR_SET);
180 s5l_lcd_write_data(0); /* Start row, high byte */ 176 s5l_lcd_write_data(0); /* Start row */
181 s5l_lcd_write_data(0); /* Start row, low byte */ 177 s5l_lcd_write_data(LCD_HEIGHT-1); /* End row */
182 s5l_lcd_write_data(0); /* End row, high byte */
183 s5l_lcd_write_data(LCD_HEIGHT-1); /* End row, low byte */
184 178
185 s5l_lcd_write_cmd(0x2c); 179 s5l_lcd_write_cmd(R_MEMORY_WRITE);
180 }
186 181
187 /* Copy display bitmap to hardware */
188 for (y = 0; y < LCD_HEIGHT; y++) {
189 for (x = 0; x < LCD_WIDTH; x++) {
190 pixel = *(p++);
191 182
192 while (LCD_STATUS&0x10); 183 /* Copy display bitmap to hardware */
184 for (y = 0; y < LCD_HEIGHT; y++) {
185 for (x = 0; x < LCD_WIDTH; x++) {
186 pixel = *(p++);
193 187
194 LCD_WDATA = (pixel & 0xff00) >> 8; 188 LCD_WDATA = (pixel & 0xff00) >> 8;
195 LCD_WDATA = pixel & 0xff; 189 LCD_WDATA = pixel & 0xff;
196 }
197 } 190 }
198 } 191 }
199
200 s5l_lcd_write_cmd(0x29);
201} 192}
202 193
203/* Update a fraction of the display. */ 194/* Update a fraction of the display. */
@@ -209,5 +200,6 @@ void lcd_update_rect(int x, int y, int width, int height)
209 (void)width; 200 (void)width;
210 (void)height; 201 (void)height;
211 202
203 /* TODO. For now, just do a full-screen update */
212 lcd_update(); 204 lcd_update();
213} 205}