diff options
author | Dave Chapman <dave@dchapman.com> | 2009-07-17 17:58:43 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2009-07-17 17:58:43 +0000 |
commit | 11c3f67a1e056bd6998dc2a17d9f81617708794d (patch) | |
tree | 137f8a45112a49b5aa8d47ae6c0d2b063d657857 /firmware/target/arm/s5l8700 | |
parent | b5f9f6152b92c237b4f7f045c16ec9f3c121dd59 (diff) | |
download | rockbox-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/s5l8700')
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c | 162 |
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 | |||
56 | static int lcd_type; | ||
57 | static int xoffset; /* needed for flip */ | ||
58 | |||
29 | /** hardware access functions */ | 59 | /** hardware access functions */ |
30 | 60 | ||
31 | static void s5l_lcd_write_cmd(unsigned short cmd) | 61 | static 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 | ||
37 | static void s5l_lcd_write_data(int data) | 70 | static 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 **/ | 75 | static inline void s5l_lcd_write_data(int data) |
44 | 76 | { | |
45 | static int lcd_type; | 77 | LCD_WDATA = data >> 8; |
46 | static 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 | ||
55 | void lcd_set_contrast(int val) | 88 | void lcd_set_contrast(int val) |
56 | { | 89 | { |
90 | (void)val; | ||
57 | } | 91 | } |
58 | 92 | ||
59 | void lcd_set_invert_display(bool yesno) | 93 | void 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); |
108 | void 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! */ | ||
120 | void 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 | } |