diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2010-01-04 21:35:26 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2010-01-04 21:35:26 +0000 |
commit | 98fa13cb29d9e26d9eac64096c37f8875b347b77 (patch) | |
tree | 1ada74e0da0422dabc9faaed3aff5227eff6575d | |
parent | 2895b659c89077f782bddc5700f1f1cdc0a2ee58 (diff) | |
download | rockbox-98fa13cb29d9e26d9eac64096c37f8875b347b77.tar.gz rockbox-98fa13cb29d9e26d9eac64096c37f8875b347b77.zip |
Sansa Fuze: LCD
- add lcd_set_invert()
- add lcd_set_flip() commented out since not working fine yet:
mpegplayer isn't flipped, and statusbar display is buggy
- use the registers list from e200v2
- cosmetics (indentation fix, comments changes, function names, casts,
function moves, ...) to make the diff with lcd-e200v2.c shorter
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24181 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/export/config/sansafuze.h | 2 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c | 310 |
2 files changed, 198 insertions, 114 deletions
diff --git a/firmware/export/config/sansafuze.h b/firmware/export/config/sansafuze.h index 4370aef42e..f9b4f629af 100644 --- a/firmware/export/config/sansafuze.h +++ b/firmware/export/config/sansafuze.h | |||
@@ -62,7 +62,7 @@ | |||
62 | //#define HAVE_LCD_FLIP | 62 | //#define HAVE_LCD_FLIP |
63 | 63 | ||
64 | /* define this if you can invert the colours on your LCD */ | 64 | /* define this if you can invert the colours on your LCD */ |
65 | //#define HAVE_LCD_INVERT | 65 | #define HAVE_LCD_INVERT |
66 | 66 | ||
67 | 67 | ||
68 | /* define this if you have a real-time clock */ | 68 | /* define this if you have a real-time clock */ |
diff --git a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c index c9dd69d47b..d10396cfd4 100644 --- a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c +++ b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c | |||
@@ -31,22 +31,68 @@ | |||
31 | 31 | ||
32 | /* The controller is unknown, but some registers appear to be the same as the | 32 | /* The controller is unknown, but some registers appear to be the same as the |
33 | HD66789R */ | 33 | HD66789R */ |
34 | static bool display_on = false; /* is the display turned on? */ | ||
34 | 35 | ||
36 | /* register defines */ | ||
37 | #define R_START_OSC 0x00 | ||
38 | #define R_DRV_OUTPUT_CONTROL 0x01 | ||
39 | #define R_DRV_WAVEFORM_CONTROL 0x02 | ||
35 | #define R_ENTRY_MODE 0x03 | 40 | #define R_ENTRY_MODE 0x03 |
36 | #define R_RAM_ADDR_SET 0x21 | 41 | #define R_COMPARE_REG1 0x04 |
37 | #define R_WRITE_DATA_2_GRAM 0x22 | 42 | #define R_COMPARE_REG2 0x05 |
38 | 43 | ||
39 | #define R_ENTRY_MODE_HORZ 0x7030 | 44 | #define R_DISP_CONTROL1 0x07 |
45 | #define R_DISP_CONTROL2 0x08 | ||
46 | #define R_DISP_CONTROL3 0x09 | ||
47 | |||
48 | #define R_FRAME_CYCLE_CONTROL 0x0b | ||
49 | #define R_EXT_DISP_IF_CONTROL 0x0c | ||
50 | |||
51 | #define R_POWER_CONTROL1 0x10 | ||
52 | #define R_POWER_CONTROL2 0x11 | ||
53 | #define R_POWER_CONTROL3 0x12 | ||
54 | #define R_POWER_CONTROL4 0x13 | ||
55 | |||
56 | #define R_RAM_ADDR_SET 0x21 | ||
57 | #define R_WRITE_DATA_2_GRAM 0x22 | ||
58 | |||
59 | #define R_GAMMA_FINE_ADJ_POS1 0x30 | ||
60 | #define R_GAMMA_FINE_ADJ_POS2 0x31 | ||
61 | #define R_GAMMA_FINE_ADJ_POS3 0x32 | ||
62 | #define R_GAMMA_GRAD_ADJ_POS 0x33 | ||
63 | |||
64 | #define R_GAMMA_FINE_ADJ_NEG1 0x34 | ||
65 | #define R_GAMMA_FINE_ADJ_NEG2 0x35 | ||
66 | #define R_GAMMA_FINE_ADJ_NEG3 0x36 | ||
67 | #define R_GAMMA_GRAD_ADJ_NEG 0x37 | ||
68 | |||
69 | #define R_GAMMA_AMP_ADJ_RES_POS 0x38 | ||
70 | #define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 | ||
71 | |||
72 | #define R_GATE_SCAN_POS 0x40 | ||
73 | #define R_VERT_SCROLL_CONTROL 0x41 | ||
74 | #define R_1ST_SCR_DRV_POS 0x42 | ||
75 | #define R_2ND_SCR_DRV_POS 0x43 | ||
76 | #define R_HORIZ_RAM_ADDR_POS 0x44 | ||
77 | #define R_VERT_RAM_ADDR_POS 0x45 | ||
78 | |||
79 | /* Flip Flag */ | ||
80 | #define R_ENTRY_MODE_HORZ_NORMAL 0x7030 | ||
81 | #define R_ENTRY_MODE_HORZ_FLIPPED 0x7000 | ||
82 | static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL; | ||
40 | #define R_ENTRY_MODE_VERT 0x7038 | 83 | #define R_ENTRY_MODE_VERT 0x7038 |
84 | #define R_ENTRY_MODE_SOLID_VERT 0x1038 | ||
85 | /* FIXME */ | ||
86 | #define R_ENTRY_MODE_VIDEO_NORMAL 0x7038 | ||
87 | #define R_ENTRY_MODE_VIDEO_FLIPPED 0x7018 | ||
41 | 88 | ||
42 | static unsigned lcd_yuv_options = 0; | 89 | /* Reverse Flag */ |
43 | static bool display_on = false; /* is the display turned on? */ | 90 | #define R_DISP_CONTROL_NORMAL 0x0004 |
44 | static bool display_flipped = false; | 91 | #define R_DISP_CONTROL_REV 0x0000 |
45 | static int xoffset = 20; /* needed for flip */ | 92 | static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; |
46 | /* we need to write a red pixel for correct button reads | 93 | |
47 | * (see lcd_button_support()),but that must not happen while the lcd is updating | 94 | static const int xoffset = 20; |
48 | * so block lcd_button_support the during updates */ | 95 | static volatile bool lcd_busy = false; |
49 | static volatile int lcd_busy = false; | ||
50 | 96 | ||
51 | static inline void lcd_delay(int x) | 97 | static inline void lcd_delay(int x) |
52 | { | 98 | { |
@@ -54,7 +100,7 @@ static inline void lcd_delay(int x) | |||
54 | asm volatile ("nop\n"); | 100 | asm volatile ("nop\n"); |
55 | } while (x--); | 101 | } while (x--); |
56 | } | 102 | } |
57 | 103 | ||
58 | static void as3525_dbop_init(void) | 104 | static void as3525_dbop_init(void) |
59 | { | 105 | { |
60 | CGU_DBOP = (1<<3) | AS3525_DBOP_DIV; | 106 | CGU_DBOP = (1<<3) | AS3525_DBOP_DIV; |
@@ -69,6 +115,7 @@ static void as3525_dbop_init(void) | |||
69 | GPIOC_AFSEL = 0xff; | 115 | GPIOC_AFSEL = 0xff; |
70 | 116 | ||
71 | DBOP_TIMPOL_23 = 0x6000e; | 117 | DBOP_TIMPOL_23 = 0x6000e; |
118 | |||
72 | /* short count: 16|enable write|output data width: 16|read strobe line */ | 119 | /* short count: 16|enable write|output data width: 16|read strobe line */ |
73 | DBOP_CTRL = (1<<18|1<<16|1<<12|1<<3); | 120 | DBOP_CTRL = (1<<18|1<<16|1<<12|1<<3); |
74 | DBOP_TIMPOL_01 = 0x6e167; | 121 | DBOP_TIMPOL_01 = 0x6e167; |
@@ -94,7 +141,6 @@ static void lcd_write_cmd(int cmd) | |||
94 | /* Wait for fifo to empty */ | 141 | /* Wait for fifo to empty */ |
95 | while ((DBOP_STAT & (1<<10)) == 0); | 142 | while ((DBOP_STAT & (1<<10)) == 0); |
96 | 143 | ||
97 | /* This loop is unique to the Fuze */ | ||
98 | lcd_delay(4); | 144 | lcd_delay(4); |
99 | 145 | ||
100 | DBOP_TIMPOL_23 = 0xa167e06f; | 146 | DBOP_TIMPOL_23 = 0xa167e06f; |
@@ -105,12 +151,12 @@ void lcd_write_data(const fb_data* p_bytes, int count) | |||
105 | const long *data; | 151 | const long *data; |
106 | if ((int)p_bytes & 0x3) | 152 | if ((int)p_bytes & 0x3) |
107 | { /* need to do a single 16bit write beforehand if the address is | 153 | { /* need to do a single 16bit write beforehand if the address is |
108 | * not word aligned*/ | 154 | * not word aligned */ |
109 | lcd_write_value16(*p_bytes); | 155 | lcd_write_value16(*p_bytes); |
110 | count--;p_bytes++; | 156 | count--;p_bytes++; |
111 | } | 157 | } |
112 | /* from here, 32bit transfers are save */ | 158 | /* from here, 32bit transfers are save |
113 | /* set it to transfer 4*(outputwidth) units at a time, | 159 | * set it to transfer 4*(outputwidth) units at a time, |
114 | * if bit 12 is set it only does 2 halfwords though */ | 160 | * if bit 12 is set it only does 2 halfwords though */ |
115 | DBOP_CTRL |= (1<<13|1<<14); | 161 | DBOP_CTRL |= (1<<13|1<<14); |
116 | lcd_delay(10); | 162 | lcd_delay(10); |
@@ -129,92 +175,128 @@ void lcd_write_data(const fb_data* p_bytes, int count) | |||
129 | /* due to the 32bit alignment requirement or uneven count, | 175 | /* due to the 32bit alignment requirement or uneven count, |
130 | * we possibly need to do a 16bit transfer at the end also */ | 176 | * we possibly need to do a 16bit transfer at the end also */ |
131 | if (count > 0) | 177 | if (count > 0) |
132 | lcd_write_value16(*(unsigned short*)data); | 178 | lcd_write_value16(*(fb_data*)data); |
133 | } | 179 | } |
134 | 180 | ||
135 | static void lcd_write_reg(int reg, int value) | 181 | static void lcd_write_reg(int reg, int value) |
136 | { | 182 | { |
137 | unsigned short data = value; | 183 | fb_data data = value; |
138 | 184 | ||
139 | lcd_write_cmd(reg); | 185 | lcd_write_cmd(reg); |
140 | lcd_write_value16(data); | 186 | lcd_write_value16(data); |
141 | } | 187 | } |
142 | 188 | ||
143 | /* turn the display upside down (call lcd_update() afterwards) */ | 189 | /*** hardware configuration ***/ |
190 | |||
191 | void lcd_set_contrast(int val) | ||
192 | { | ||
193 | (void)val; | ||
194 | } | ||
195 | |||
196 | void lcd_set_invert_display(bool yesno) | ||
197 | { | ||
198 | r_disp_control_rev = yesno ? R_DISP_CONTROL_REV : | ||
199 | R_DISP_CONTROL_NORMAL; | ||
200 | |||
201 | if (display_on) | ||
202 | { | ||
203 | lcd_write_reg(R_DISP_CONTROL1, 0x0013 | r_disp_control_rev); | ||
204 | } | ||
205 | |||
206 | } | ||
207 | |||
208 | #ifdef HAVE_LCD_FLIP | ||
209 | static bool display_flipped = false; | ||
210 | |||
211 | /* turn the display upside down */ | ||
144 | void lcd_set_flip(bool yesno) | 212 | void lcd_set_flip(bool yesno) |
145 | { | 213 | { |
146 | display_flipped = yesno; | 214 | display_flipped = yesno; |
147 | xoffset = yesno ? 0 : 20; /* TODO: Implement flipped mode */ | ||
148 | 215 | ||
149 | /* TODO */ | 216 | r_entry_mode = yesno ? R_ENTRY_MODE_HORZ_FLIPPED : |
217 | R_ENTRY_MODE_HORZ_NORMAL; | ||
150 | } | 218 | } |
151 | 219 | #endif | |
152 | 220 | ||
153 | static void _display_on(void) | 221 | static void _display_on(void) |
154 | { | 222 | { |
155 | /* Initialise in the same way as the original firmare */ | 223 | /* Initialise in the same way as the original firmare */ |
156 | 224 | ||
157 | lcd_write_reg(0x07, 0); | 225 | lcd_write_reg(R_DISP_CONTROL1, 0); |
158 | lcd_write_reg(0x13, 0); | 226 | lcd_write_reg(R_POWER_CONTROL4, 0); |
159 | 227 | ||
160 | lcd_write_reg(0x11, 0x3704); | 228 | lcd_write_reg(R_POWER_CONTROL2, 0x3704); |
161 | lcd_write_reg(0x14, 0x1a1b); | 229 | lcd_write_reg(0x14, 0x1a1b); |
162 | lcd_write_reg(0x10, 0x3860); | 230 | lcd_write_reg(R_POWER_CONTROL1, 0x3860); |
163 | lcd_write_reg(0x13, 0x40); | 231 | lcd_write_reg(R_POWER_CONTROL4, 0x40); |
164 | 232 | ||
165 | lcd_write_reg(0x13, 0x60); | 233 | lcd_write_reg(R_POWER_CONTROL4, 0x60); |
166 | 234 | ||
167 | lcd_write_reg(0x13, 0x70); | 235 | lcd_write_reg(R_POWER_CONTROL4, 0x70); |
168 | lcd_write_reg(0x01, 277); | 236 | lcd_write_reg(R_DRV_OUTPUT_CONTROL, 277); |
169 | lcd_write_reg(0x02, (7<<8)); | 237 | lcd_write_reg(R_DRV_WAVEFORM_CONTROL, (7<<8)); |
170 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); | 238 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); |
171 | lcd_write_reg(0x08, 0x01); | 239 | lcd_write_reg(R_DISP_CONTROL2, 0x01); |
172 | lcd_write_reg(0x0b, (1<<10)); | 240 | lcd_write_reg(R_FRAME_CYCLE_CONTROL, (1<<10)); |
173 | lcd_write_reg(0x0c, 0); | 241 | lcd_write_reg(R_EXT_DISP_IF_CONTROL, 0); |
174 | 242 | ||
175 | lcd_write_reg(0x30, 0x40); | 243 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x40); |
176 | lcd_write_reg(0x31, 0x0687); | 244 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0687); |
177 | lcd_write_reg(0x32, 0x0306); | 245 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0306); |
178 | lcd_write_reg(0x33, 0x104); | 246 | lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x104); |
179 | lcd_write_reg(0x34, 0x0585); | 247 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0585); |
180 | lcd_write_reg(0x35, 255+66); | 248 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 255+66); |
181 | lcd_write_reg(0x36, 0x0687+128); | 249 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0687+128); |
182 | lcd_write_reg(0x37, 259); | 250 | lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 259); |
183 | lcd_write_reg(0x38, 0); | 251 | lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0); |
184 | lcd_write_reg(0x39, 0); | 252 | lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0); |
185 | 253 | ||
186 | lcd_write_reg(0x42, (LCD_WIDTH - 1)); | 254 | lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_WIDTH - 1)); |
187 | lcd_write_reg(0x43, 0); | 255 | lcd_write_reg(R_2ND_SCR_DRV_POS, 0); |
188 | lcd_write_reg(0x44, (LCD_WIDTH - 1)); | 256 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_WIDTH - 1)); |
189 | lcd_write_reg(0x45, 0); | 257 | lcd_write_reg(R_VERT_RAM_ADDR_POS, 0); |
190 | lcd_write_reg(0x46, (((LCD_WIDTH - 1) + xoffset) << 8) | xoffset); | 258 | lcd_write_reg(0x46, (((LCD_WIDTH - 1) + xoffset) << 8) | xoffset); |
191 | lcd_write_reg(0x47, (LCD_HEIGHT - 1)); | 259 | lcd_write_reg(0x47, (LCD_HEIGHT - 1)); |
192 | lcd_write_reg(0x48, 0x0); | 260 | lcd_write_reg(0x48, 0x0); |
193 | 261 | ||
194 | lcd_write_reg(0x07, 0x11); | 262 | lcd_write_reg(R_DISP_CONTROL1, 0x11); |
195 | lcd_write_reg(0x07, 0x17); | 263 | lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev); |
196 | 264 | ||
197 | display_on = true; /* must be done before calling lcd_update() */ | 265 | display_on = true; /* must be done before calling lcd_update() */ |
198 | lcd_update(); | 266 | lcd_update(); |
199 | } | 267 | } |
200 | 268 | ||
269 | void lcd_init_device(void) | ||
270 | { | ||
271 | as3525_dbop_init(); | ||
272 | |||
273 | GPIOA_DIR |= (1<<5|1<<4|1<<3); | ||
274 | GPIOA_PIN(5) = 0; | ||
275 | GPIOA_PIN(3) = (1<<3); | ||
276 | GPIOA_PIN(4) = 0; | ||
277 | GPIOA_PIN(5) = (1<<5); | ||
278 | |||
279 | _display_on(); | ||
280 | } | ||
281 | |||
201 | #if defined(HAVE_LCD_ENABLE) | 282 | #if defined(HAVE_LCD_ENABLE) |
202 | void lcd_enable(bool on) | 283 | void lcd_enable(bool on) |
203 | { | 284 | { |
204 | if (display_on == on) | 285 | if (display_on == on) |
205 | return; /* nothing to do */ | 286 | return; |
287 | |||
206 | if(on) | 288 | if(on) |
207 | { | 289 | { |
208 | lcd_write_reg(0, 1); | 290 | lcd_write_reg(R_START_OSC, 1); |
209 | lcd_write_reg(0x10, 0); | 291 | lcd_write_reg(R_POWER_CONTROL1, 0); |
210 | lcd_write_reg(0x11, 0x3704); | 292 | lcd_write_reg(R_POWER_CONTROL2, 0x3704); |
211 | lcd_write_reg(0x14, 0x1a1b); | 293 | lcd_write_reg(0x14, 0x1a1b); |
212 | lcd_write_reg(0x10, 0x3860); | 294 | lcd_write_reg(R_POWER_CONTROL1, 0x3860); |
213 | lcd_write_reg(0x13, 0x40); | 295 | lcd_write_reg(R_POWER_CONTROL4, 0x40); |
214 | lcd_write_reg(0x13, 0x60); | 296 | lcd_write_reg(R_POWER_CONTROL4, 0x60); |
215 | lcd_write_reg(0x13, 112); | 297 | lcd_write_reg(R_POWER_CONTROL4, 112); |
216 | lcd_write_reg(0x07, 0x11); | 298 | lcd_write_reg(R_DISP_CONTROL1, 0x11); |
217 | lcd_write_reg(0x07, 0x17); | 299 | lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev); |
218 | display_on = true; | 300 | display_on = true; |
219 | lcd_update(); /* Resync display */ | 301 | lcd_update(); /* Resync display */ |
220 | send_event(LCD_EVENT_ACTIVATION, NULL); | 302 | send_event(LCD_EVENT_ACTIVATION, NULL); |
@@ -223,9 +305,9 @@ void lcd_enable(bool on) | |||
223 | } | 305 | } |
224 | else | 306 | else |
225 | { | 307 | { |
226 | lcd_write_reg(0x07, 0x22); | 308 | lcd_write_reg(R_DISP_CONTROL1, 0x22); |
227 | lcd_write_reg(0x07, 0); | 309 | lcd_write_reg(R_DISP_CONTROL1, 0); |
228 | lcd_write_reg(0x10, 1); | 310 | lcd_write_reg(R_POWER_CONTROL1, 1); |
229 | display_on = false; | 311 | display_on = false; |
230 | } | 312 | } |
231 | } | 313 | } |
@@ -240,23 +322,28 @@ bool lcd_active(void) | |||
240 | 322 | ||
241 | /*** update functions ***/ | 323 | /*** update functions ***/ |
242 | 324 | ||
325 | /* FIXME : find the datasheet for this RENESAS controller so we identify the | ||
326 | * registers used in windowing code (not present in HD66789R) */ | ||
327 | |||
243 | /* Set horizontal window addresses */ | 328 | /* Set horizontal window addresses */ |
244 | static void lcd_window_x(int xmin, int xmax) | 329 | static void lcd_window_x(int xmin, int xmax) |
245 | { | 330 | { |
246 | xmin += xoffset; | 331 | xmin += xoffset; |
247 | xmax += xoffset; | 332 | xmax += xoffset; |
248 | lcd_write_reg(0x46, (xmax << 8) | xmin); | 333 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS + 2, (xmax << 8) | xmin); |
249 | lcd_write_reg(0x20, xmin); | 334 | lcd_write_reg(R_RAM_ADDR_SET - 1, xmin); |
250 | } | 335 | } |
251 | 336 | ||
252 | /* Set vertical window addresses */ | 337 | /* Set vertical window addresses */ |
253 | static void lcd_window_y(int ymin, int ymax) | 338 | static void lcd_window_y(int ymin, int ymax) |
254 | { | 339 | { |
255 | lcd_write_reg(0x47, ymax); | 340 | lcd_write_reg(R_VERT_RAM_ADDR_POS + 2, ymax); |
256 | lcd_write_reg(0x48, ymin); | 341 | lcd_write_reg(R_VERT_RAM_ADDR_POS + 3, ymin); |
257 | lcd_write_reg(0x21, ymin); | 342 | lcd_write_reg(R_RAM_ADDR_SET, ymin); |
258 | } | 343 | } |
259 | 344 | ||
345 | static unsigned lcd_yuv_options = 0; | ||
346 | |||
260 | void lcd_yuv_set_options(unsigned options) | 347 | void lcd_yuv_set_options(unsigned options) |
261 | { | 348 | { |
262 | lcd_yuv_options = options; | 349 | lcd_yuv_options = options; |
@@ -267,11 +354,15 @@ extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | |||
267 | int width, | 354 | int width, |
268 | int stride); | 355 | int stride); |
269 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | 356 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], |
270 | int width, | 357 | int width, |
271 | int stride, | 358 | int stride, |
272 | int x_screen, /* To align dither */ | 359 | int x_screen, /* To align dither pattern */ |
273 | int y_screen); /* pattern */ | 360 | int y_screen); |
274 | /* Performance function to blit a YUV bitmap directly to the LCD */ | 361 | |
362 | /* Performance function to blit a YUV bitmap directly to the LCD | ||
363 | * src_x, src_y, width and height should be even | ||
364 | * x, y, width and height have to be within LCD bounds | ||
365 | */ | ||
275 | void lcd_blit_yuv(unsigned char * const src[3], | 366 | void lcd_blit_yuv(unsigned char * const src[3], |
276 | int src_x, int src_y, int stride, | 367 | int src_x, int src_y, int stride, |
277 | int x, int y, int width, int height) | 368 | int x, int y, int width, int height) |
@@ -279,10 +370,6 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
279 | unsigned char const * yuv_src[3]; | 370 | unsigned char const * yuv_src[3]; |
280 | off_t z; | 371 | off_t z; |
281 | 372 | ||
282 | lcd_busy = true; | ||
283 | |||
284 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT); | ||
285 | |||
286 | /* Sorry, but width and height must be >= 2 or else */ | 373 | /* Sorry, but width and height must be >= 2 or else */ |
287 | width &= ~1; | 374 | width &= ~1; |
288 | height >>= 1; | 375 | height >>= 1; |
@@ -292,6 +379,16 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
292 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | 379 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); |
293 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | 380 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); |
294 | 381 | ||
382 | lcd_busy = true; | ||
383 | |||
384 | #ifdef HAVE_LCD_FLIP | ||
385 | lcd_write_reg(R_ENTRY_MODE, | ||
386 | display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL | ||
387 | ); | ||
388 | #else | ||
389 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VIDEO_NORMAL); | ||
390 | #endif | ||
391 | |||
295 | lcd_window_x(x, x + width - 1); | 392 | lcd_window_x(x, x + width - 1); |
296 | 393 | ||
297 | if (lcd_yuv_options & LCD_YUV_DITHER) | 394 | if (lcd_yuv_options & LCD_YUV_DITHER) |
@@ -299,7 +396,7 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
299 | do | 396 | do |
300 | { | 397 | { |
301 | lcd_window_y(y, y + 1); | 398 | lcd_window_y(y, y + 1); |
302 | /* Start write to GRAM */ | 399 | |
303 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | 400 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); |
304 | 401 | ||
305 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); | 402 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); |
@@ -308,14 +405,14 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
308 | yuv_src[2] += stride >> 1; | 405 | yuv_src[2] += stride >> 1; |
309 | y += 2; | 406 | y += 2; |
310 | } | 407 | } |
311 | while (--height > 0); | 408 | while (--height > 0); |
312 | } | 409 | } |
313 | else | 410 | else |
314 | { | 411 | { |
315 | do | 412 | do |
316 | { | 413 | { |
317 | lcd_window_y(y, y + 1); | 414 | lcd_window_y(y, y + 1); |
318 | /* Start write to GRAM */ | 415 | |
319 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | 416 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); |
320 | 417 | ||
321 | lcd_write_yuv420_lines(yuv_src, width, stride); | 418 | lcd_write_yuv420_lines(yuv_src, width, stride); |
@@ -324,25 +421,12 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
324 | yuv_src[2] += stride >> 1; | 421 | yuv_src[2] += stride >> 1; |
325 | y += 2; | 422 | y += 2; |
326 | } | 423 | } |
327 | while (--height > 0); | 424 | while (--height > 0); |
328 | } | 425 | } |
329 | 426 | ||
330 | lcd_busy = false; | 427 | lcd_busy = false; |
331 | } | 428 | } |
332 | 429 | ||
333 | void lcd_init_device() | ||
334 | { | ||
335 | as3525_dbop_init(); | ||
336 | |||
337 | GPIOA_DIR |= (1<<5|1<<4|1<<3); | ||
338 | GPIOA_PIN(5) = 0; | ||
339 | GPIOA_PIN(3) = (1<<3); | ||
340 | GPIOA_PIN(4) = 0; | ||
341 | GPIOA_PIN(5) = (1<<5); | ||
342 | |||
343 | _display_on(); | ||
344 | } | ||
345 | |||
346 | /* Update the display. | 430 | /* Update the display. |
347 | This must be called after all other LCD functions that change the display. */ | 431 | This must be called after all other LCD functions that change the display. */ |
348 | void lcd_update(void) | 432 | void lcd_update(void) |
@@ -352,29 +436,27 @@ void lcd_update(void) | |||
352 | 436 | ||
353 | lcd_busy = true; | 437 | lcd_busy = true; |
354 | 438 | ||
355 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); | 439 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); |
356 | 440 | ||
357 | lcd_window_x(0, LCD_WIDTH - 1); | 441 | lcd_window_x(0, LCD_WIDTH - 1); |
358 | lcd_window_y(0, LCD_HEIGHT - 1); | 442 | lcd_window_y(0, LCD_HEIGHT - 1); |
359 | 443 | ||
360 | /* Start write to GRAM */ | ||
361 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | 444 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); |
362 | 445 | ||
363 | /* Write data */ | 446 | lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); |
364 | lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); | 447 | |
365 | lcd_busy = false; | 448 | lcd_busy = false; |
366 | } | 449 | } |
367 | 450 | ||
368 | /* Update a fraction of the display. */ | 451 | /* Update a fraction of the display. */ |
369 | void lcd_update_rect(int x, int y, int width, int height) | 452 | void lcd_update_rect(int x, int y, int width, int height) |
370 | { | 453 | { |
371 | int xmax, ymax; | ||
372 | const fb_data *ptr; | 454 | const fb_data *ptr; |
455 | int xmax, ymax; | ||
373 | 456 | ||
374 | if (!display_on) | 457 | if (!display_on) |
375 | return; | 458 | return; |
376 | 459 | ||
377 | |||
378 | xmax = x + width; | 460 | xmax = x + width; |
379 | if (xmax >= LCD_WIDTH) | 461 | if (xmax >= LCD_WIDTH) |
380 | xmax = LCD_WIDTH - 1; /* Clip right */ | 462 | xmax = LCD_WIDTH - 1; /* Clip right */ |
@@ -395,12 +477,11 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
395 | 477 | ||
396 | lcd_busy = true; | 478 | lcd_busy = true; |
397 | 479 | ||
398 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); | 480 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); |
399 | 481 | ||
400 | lcd_window_x(x, xmax); | 482 | lcd_window_x(x, xmax); |
401 | lcd_window_y(y, ymax); | 483 | lcd_window_y(y, ymax); |
402 | 484 | ||
403 | /* Start write to GRAM */ | ||
404 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | 485 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); |
405 | 486 | ||
406 | ptr = &lcd_framebuffer[y][x]; | 487 | ptr = &lcd_framebuffer[y][x]; |
@@ -412,23 +493,26 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
412 | ptr += LCD_WIDTH; | 493 | ptr += LCD_WIDTH; |
413 | } | 494 | } |
414 | while (--height >= 0); | 495 | while (--height >= 0); |
496 | |||
415 | lcd_busy = false; | 497 | lcd_busy = false; |
416 | } | 498 | } |
417 | 499 | ||
418 | /* writes one read pixel outside the visible area, needed for correct dbop reads */ | 500 | /* writes one red pixel outside the visible area, needed for correct |
501 | * dbop reads */ | ||
419 | bool lcd_button_support(void) | 502 | bool lcd_button_support(void) |
420 | { | 503 | { |
421 | fb_data data = 0xf<<12; | ||
422 | if (lcd_busy) | 504 | if (lcd_busy) |
423 | return false; | 505 | return false; |
424 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); | ||
425 | /* Set start position and window */ | ||
426 | 506 | ||
507 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); | ||
508 | |||
509 | /* Set start position and window */ | ||
427 | lcd_window_x(-1, 0); | 510 | lcd_window_x(-1, 0); |
428 | lcd_window_y(-1, 0); | 511 | lcd_window_y(-1, 0); |
512 | |||
429 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | 513 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); |
430 | 514 | ||
431 | lcd_write_value16(data); | 515 | lcd_write_value16(0xf<<12); |
432 | 516 | ||
433 | return true; | 517 | return true; |
434 | } | 518 | } |