diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2009-08-24 17:37:53 +0000 |
---|---|---|
committer | Bertrik Sikken <bertrik@sikken.nl> | 2009-08-24 17:37:53 +0000 |
commit | 400cd026f3267cff8b67d0bf0ab5f4645732cc5e (patch) | |
tree | b1422baebf25c072d5308bba44995ba87ce62eb7 /firmware/target | |
parent | 1747a33fcc9ceb8b78012d662086aeac51490812 (diff) | |
download | rockbox-400cd026f3267cff8b67d0bf0ab5f4645732cc5e.tar.gz rockbox-400cd026f3267cff8b67d0bf0ab5f4645732cc5e.zip |
Meizu M6SP: initial LCD driver (compiles but is untested)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22500 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c | 514 |
1 files changed, 413 insertions, 101 deletions
diff --git a/firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c b/firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c index 1affab3b01..b6330406f2 100644 --- a/firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c +++ b/firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2002 by Alan Korr | 10 | * Copyright (C) 2009 Bertrik Sikken |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 13 | * modify it under the terms of the GNU General Public License |
@@ -18,118 +18,430 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include "config.h" | 21 | |
22 | #include <inttypes.h> | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "s5l8700.h" | ||
26 | #include "lcd.h" | ||
27 | |||
28 | /* LCD driver for the Meizu M6 SP using the CLCD controller in the S5L8700 | ||
22 | 29 | ||
23 | #include "hwcompat.h" | 30 | The Meizu M6 SP can have two different LCDs, the S6D0139 and another |
24 | #include "kernel.h" | 31 | (yet unknown) type, the exact type is detected at run-time. |
25 | #include "lcd.h" | ||
26 | #include "system.h" | ||
27 | #include "cpu.h" | ||
28 | 32 | ||
29 | /*** definitions ***/ | 33 | Open issues: |
34 | * untested on actual hardware | ||
35 | * use 16-bit pixel format, currently pixels are converted to a 32-bit pixel | ||
36 | format in lcd_update_rect, that is not natively supported yet in Rockbox. | ||
37 | |||
38 | */ | ||
30 | 39 | ||
40 | /* LCD SPI connections */ | ||
41 | #define LCD_SPI_SSn (1<<1) /* on PDAT7 */ | ||
42 | #define LCD_SPI_MISO (1<<2) /* on PDAT3 */ | ||
43 | #define LCD_SPI_MOSI (1<<6) /* on PDAT3 */ | ||
44 | #define LCD_SPI_SCLK (1<<7) /* on PDAT3 */ | ||
45 | |||
46 | #define LCD_TYPE1_ID 0x139 /* id for LCD type S6D0139 */ | ||
47 | |||
48 | static int lcd_type = 0; | ||
31 | 49 | ||
32 | /** globals **/ | 50 | /* local frame buffer, keeps pixels in 32-bit words in format 0x00RRGGBB */ |
33 | 51 | static uint32_t lcd_local_fb[LCD_HEIGHT][LCD_WIDTH]; | |
34 | static int xoffset; /* needed for flip */ | 52 | |
35 | 53 | ||
36 | /*** hardware configuration ***/ | 54 | /* simple and crude delay */ |
37 | 55 | static void lcd_delay(int count) | |
38 | int lcd_default_contrast(void) | 56 | { |
39 | { | 57 | volatile int i; |
40 | return 0x1f; | 58 | for (i = 0; i < count; i++); |
41 | } | 59 | } |
42 | 60 | ||
43 | void lcd_set_contrast(int val) | 61 | /* write 'data_out' of length 'bits' over SPI and return received data */ |
44 | { | 62 | static unsigned int lcd_spi_transfer(int bits, unsigned int data_out) |
45 | } | 63 | { |
46 | 64 | unsigned int data_in = 0; | |
47 | void lcd_set_invert_display(bool yesno) | 65 | |
48 | { | 66 | /* SSn active */ |
49 | } | 67 | PDAT7 &= ~LCD_SPI_SSn; |
50 | 68 | lcd_delay(10); | |
51 | /* turn the display upside down (call lcd_update() afterwards) */ | 69 | |
52 | void lcd_set_flip(bool yesno) | 70 | /* send and receive data */ |
53 | { | 71 | while (bits--) { |
54 | /* TODO: flip mode isn't working. The commands in the else part of | 72 | /* CLK low */ |
55 | this function are how the original firmware inits the LCD */ | 73 | PDAT3 &= ~LCD_SPI_SCLK; |
56 | 74 | ||
57 | if (yesno) | 75 | /* set MOSI */ |
58 | { | 76 | if (data_out & (1 << bits)) { |
59 | xoffset = 132 - LCD_WIDTH; /* 132 colums minus the 128 we have */ | 77 | PDAT3 |= LCD_SPI_MOSI; |
60 | } | 78 | } |
61 | else | 79 | else { |
62 | { | 80 | PDAT3 &= ~LCD_SPI_MOSI; |
63 | xoffset = 0; | 81 | } |
64 | } | 82 | |
65 | } | 83 | /* delay */ |
66 | 84 | lcd_delay(10); | |
67 | 85 | ||
68 | /* LCD init */ | 86 | /* sample MISO */ |
69 | void lcd_init_device(void) | 87 | data_in <<= 1; |
88 | if (PDAT3 & LCD_SPI_MISO) { | ||
89 | data_in |= 1; | ||
90 | } | ||
91 | |||
92 | /* CLK high */ | ||
93 | PDAT3 |= LCD_SPI_SCLK; | ||
94 | |||
95 | /* delay */ | ||
96 | lcd_delay(10); | ||
97 | } | ||
98 | |||
99 | /* SSn inactive */ | ||
100 | PDAT7 |= LCD_SPI_SSn; | ||
101 | lcd_delay(10); | ||
102 | |||
103 | return data_in; | ||
104 | } | ||
105 | |||
106 | /* initialize the lcd SPI port interface */ | ||
107 | static void lcd_spi_init(void) | ||
108 | { | ||
109 | /* configure SSn (P7.1) as output */ | ||
110 | PCON7 = (PCON7 & ~0x000000F0) | 0x00000010; | ||
111 | |||
112 | /* configure MISO (P3.2) input, MOSI (P3.6) output, SCLK (P3.7) output */ | ||
113 | PCON3 = (PCON3 & ~0xFF000F00) | 0x11000000; | ||
114 | |||
115 | /* set all outputs high */ | ||
116 | PDAT7 |= LCD_SPI_SSn; | ||
117 | PDAT3 |= (LCD_SPI_MOSI | LCD_SPI_SCLK); | ||
118 | } | ||
119 | |||
120 | /* read LCD identification word over SPI */ | ||
121 | static unsigned int lcd_read_reg(unsigned reg) | ||
122 | { | ||
123 | unsigned int data; | ||
124 | |||
125 | lcd_spi_transfer(24, (0x74 << 16) | reg); //0111.0100 | ||
126 | data = lcd_spi_transfer(24, (0x77 << 16)); //0111.0111 | ||
127 | return data & 0xFFFF; | ||
128 | } | ||
129 | |||
130 | /* write LCD register over SPI */ | ||
131 | static void lcd_write_reg(unsigned char reg, unsigned int data) | ||
132 | { | ||
133 | lcd_spi_transfer(24, (0x74 << 16) | reg); //0111.0100 | ||
134 | lcd_spi_transfer(24, (0x76 << 16) | data); //0111.0110 | ||
135 | } | ||
136 | |||
137 | /* enable/disable clock signals towards the lcd */ | ||
138 | static void lcd_controller_power(bool on) | ||
70 | { | 139 | { |
71 | } | 140 | if (on) { |
141 | LCDCON1 |= 0x80003; | ||
142 | } | ||
143 | else { | ||
144 | LCDCON1 &= ~0x80003; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | /* lcd init configuration for lcd type 1 */ | ||
149 | static void lcd_init1(void) | ||
150 | { | ||
151 | lcd_write_reg(0x07, 0x0000); /* display control */ | ||
152 | lcd_write_reg(0x13, 0x0000); /* power control 3 */ | ||
153 | lcd_delay(166670); | ||
154 | |||
155 | lcd_write_reg(0x11, 0x3304); /* power control 2 */ | ||
156 | lcd_write_reg(0x14, 0x1300); /* power control 4 */ | ||
157 | lcd_write_reg(0x10, 0x1A20); /* power control 1 */ | ||
158 | lcd_write_reg(0x13, 0x0040); /* power control 3 */ | ||
159 | lcd_delay(833350); | ||
160 | |||
161 | lcd_write_reg(0x13, 0x0060); /* power control 3 */ | ||
162 | lcd_write_reg(0x13, 0x0070); /* power control 3 */ | ||
163 | lcd_delay(3333400); | ||
164 | |||
165 | lcd_write_reg(0x01, 0x0127); /* driver output control */ | ||
166 | lcd_write_reg(0x02, 0x0700); /* lcd driving waveform control */ | ||
167 | lcd_write_reg(0x03, 0x1030); /* entry mode */ | ||
168 | lcd_write_reg(0x08, 0x0208); /* blank period control 1 */ | ||
169 | lcd_write_reg(0x0B, 0x0620); /* frame cycle control */ | ||
170 | lcd_write_reg(0x0C, 0x0110); /* external interface control */ | ||
171 | lcd_write_reg(0x30, 0x0120); /* gamma control 1 */ | ||
172 | lcd_write_reg(0x31, 0x0117); /* gamma control 2 */ | ||
173 | lcd_write_reg(0x32, 0x0000); /* gamma control 3 */ | ||
174 | lcd_write_reg(0x33, 0x0305); /* gamma control 4 */ | ||
175 | lcd_write_reg(0x34, 0x0717); /* gamma control 5 */ | ||
176 | lcd_write_reg(0x35, 0x0124); /* gamma control 6 */ | ||
177 | lcd_write_reg(0x36, 0x0706); /* gamma control 7 */ | ||
178 | lcd_write_reg(0x37, 0x0503); /* gamma control 8 */ | ||
179 | lcd_write_reg(0x38, 0x1F03); /* gamma control 9 */ | ||
180 | lcd_write_reg(0x39, 0x0009); /* gamma control 10 */ | ||
181 | lcd_write_reg(0x40, 0x0000); /* gate scan position */ | ||
182 | lcd_write_reg(0x41, 0x0000); /* vertical scroll control */ | ||
183 | lcd_write_reg(0x42, 0x013F); /* 1st screen driving position (end) */ | ||
184 | lcd_write_reg(0x43, 0x0000); /* 1st screen driving position (start) */ | ||
185 | lcd_write_reg(0x44, 0x013F); /* 2nd screen driving position (end) */ | ||
186 | lcd_write_reg(0x45, 0x0000); /* 2nd screen driving position (start) */ | ||
187 | lcd_write_reg(0x46, 0xEF00); /* horizontal window address */ | ||
188 | lcd_write_reg(0x47, 0x013F); /* vertical window address (end) */ | ||
189 | lcd_write_reg(0x48, 0x0000); /* vertical window address (start) */ | ||
190 | |||
191 | lcd_write_reg(0x07, 0x0015); /* display control */ | ||
192 | lcd_delay(500000); | ||
193 | lcd_write_reg(0x07, 0x0017); /* display control */ | ||
194 | |||
195 | lcd_write_reg(0x20, 0x0000); /* RAM address set (low part) */ | ||
196 | lcd_write_reg(0x21, 0x0000); /* RAM address set (high part) */ | ||
197 | lcd_write_reg(0x22, 0x0000); /* write data to GRAM */ | ||
198 | } | ||
199 | |||
200 | /* lcd init configuration for lcd type 2 */ | ||
201 | static void lcd_init2(void) | ||
202 | { | ||
203 | lcd_write_reg(0x07, 0x0000); | ||
204 | lcd_write_reg(0x12, 0x0000); | ||
205 | lcd_delay(166670); | ||
206 | |||
207 | lcd_write_reg(0x11, 0x000C); | ||
208 | lcd_write_reg(0x12, 0x0A1C); | ||
209 | lcd_write_reg(0x13, 0x0022); | ||
210 | lcd_write_reg(0x14, 0x0000); | ||
211 | |||
212 | lcd_write_reg(0x10, 0x7404); | ||
213 | lcd_write_reg(0x11, 0x0738); | ||
214 | lcd_write_reg(0x10, 0x7404); | ||
215 | lcd_delay(833350); | ||
216 | |||
217 | lcd_write_reg(0x07, 0x0009); | ||
218 | lcd_write_reg(0x12, 0x065C); | ||
219 | lcd_delay(3333400); | ||
220 | |||
221 | lcd_write_reg(0x01, 0xE127); | ||
222 | lcd_write_reg(0x02, 0x0300); | ||
223 | lcd_write_reg(0x03, 0x1100); | ||
224 | lcd_write_reg(0x08, 0x0008); | ||
225 | lcd_write_reg(0x0B, 0x0000); | ||
226 | lcd_write_reg(0x0C, 0x0000); | ||
227 | lcd_write_reg(0x0D, 0x0007); | ||
228 | lcd_write_reg(0x15, 0x0003); | ||
229 | |||
230 | lcd_write_reg(0x16, 0x0014); | ||
231 | lcd_write_reg(0x17, 0x0000); | ||
232 | lcd_write_reg(0x30, 0x0503); | ||
233 | lcd_write_reg(0x31, 0x0303); | ||
234 | lcd_write_reg(0x32, 0x0305); | ||
235 | lcd_write_reg(0x33, 0x0202); | ||
236 | lcd_write_reg(0x34, 0x0204); | ||
237 | lcd_write_reg(0x35, 0x0404); | ||
238 | lcd_write_reg(0x36, 0x0402); | ||
239 | lcd_write_reg(0x37, 0x0202); | ||
240 | lcd_write_reg(0x38, 0x1000); | ||
241 | lcd_write_reg(0x39, 0x1000); | ||
242 | |||
243 | lcd_write_reg(0x07, 0x0009); | ||
244 | lcd_delay(666680); | ||
245 | |||
246 | lcd_write_reg(0x07, 0x0109); | ||
247 | lcd_delay(666680); | ||
248 | |||
249 | lcd_write_reg(0x07, 0x010B); | ||
250 | } | ||
251 | |||
252 | /* lcd enable for lcd type 1 */ | ||
253 | static void lcd_enable1(bool on) | ||
254 | { | ||
255 | if (on) { | ||
256 | lcd_write_reg(0x00, 0x0001); /* start oscillation */ | ||
257 | lcd_delay(166670); | ||
258 | lcd_write_reg(0x10, 0x0000); /* power control 1 */ | ||
259 | lcd_delay(166670); | ||
260 | |||
261 | lcd_write_reg(0x11, 0x3304); /* power control 2 */ | ||
262 | lcd_write_reg(0x14, 0x1300); /* power control 4 */ | ||
263 | lcd_write_reg(0x10, 0x1A20); /* power control 1 */ | ||
264 | lcd_write_reg(0x07, 0x0015); /* display control */ | ||
265 | lcd_delay(500000); | ||
266 | |||
267 | lcd_write_reg(0x20, 0x0000); /* RAM address set (low part) */ | ||
268 | lcd_write_reg(0x21, 0x0000); /* RAM address set (high part) */ | ||
269 | lcd_write_reg(0x22, 0x0000); /* write data to GRAM */ | ||
270 | } | ||
271 | else { | ||
272 | lcd_write_reg(0x07, 0x0016); /* display control */ | ||
273 | lcd_delay(166670 * 4); | ||
274 | lcd_write_reg(0x07, 0x0004); /* display control */ | ||
275 | lcd_delay(166670 * 4); | ||
276 | |||
277 | lcd_write_reg(0x10, 0x1E21); /* power control 1 */ | ||
278 | lcd_delay(166670); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | /* lcd enable for lcd type 2 */ | ||
283 | static void lcd_enable2(bool on) | ||
284 | { | ||
285 | if (on) { | ||
286 | lcd_write_reg(0x10, 0x0400); | ||
287 | lcd_delay(666680); | ||
288 | |||
289 | lcd_write_reg(0x07, 0x0000); | ||
290 | lcd_write_reg(0x12, 0x0000); | ||
291 | lcd_delay(166670); | ||
292 | |||
293 | lcd_write_reg(0x11, 0x000C); | ||
294 | lcd_write_reg(0x12, 0x0A1C); | ||
295 | lcd_write_reg(0x13, 0x0022); | ||
296 | lcd_write_reg(0x14, 0x0000); | ||
297 | lcd_write_reg(0x10, 0x7404); | ||
298 | lcd_delay(833350); | ||
299 | |||
300 | lcd_write_reg(0x07, 0x0009); | ||
301 | lcd_write_reg(0x12, 0x065C); | ||
302 | lcd_delay(3333400); | ||
303 | |||
304 | lcd_write_reg(0x0B, 0x0000); | ||
305 | lcd_write_reg(0x07, 0x0009); | ||
306 | lcd_delay(666680); | ||
307 | |||
308 | lcd_write_reg(0x07, 0x0109); | ||
309 | lcd_delay(666680); | ||
310 | |||
311 | lcd_write_reg(0x07, 0x010B); | ||
312 | } | ||
313 | else { | ||
314 | lcd_write_reg(0x0B, 0x0000); | ||
315 | lcd_write_reg(0x07, 0x0009); | ||
316 | lcd_delay(666680); | ||
317 | |||
318 | lcd_write_reg(0x07, 0x0008); | ||
319 | lcd_delay(666680); | ||
320 | |||
321 | lcd_write_reg(0x10, 0x0400); | ||
322 | lcd_write_reg(0x10, 0x0401); | ||
323 | lcd_delay(166670); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | /* turn both the lcd controller and the lcd itself on or off */ | ||
328 | void lcd_enable(bool on) | ||
329 | { | ||
330 | if (on) { | ||
331 | /* enable controller clock */ | ||
332 | PWRCON &= ~(1 << 18); | ||
333 | |||
334 | lcd_controller_power(true); | ||
335 | lcd_delay(166670); | ||
336 | } | ||
337 | |||
338 | /* call type specific power function */ | ||
339 | if (lcd_type == 1) { | ||
340 | lcd_enable1(on); | ||
341 | } | ||
342 | else { | ||
343 | lcd_enable2(on); | ||
344 | } | ||
345 | |||
346 | if (!on) { | ||
347 | lcd_controller_power(false); | ||
348 | |||
349 | /* disable controller clock */ | ||
350 | PWRCON |= (1 << 18); | ||
351 | } | ||
352 | } | ||
72 | 353 | ||
73 | /*** Update functions ***/ | 354 | /* initialise the lcd controller inside the s5l8700 */ |
355 | static void lcd_controller_init(void) | ||
356 | { | ||
357 | PWRCON &= ~(1 << 18); | ||
358 | |||
359 | LCDCON1 = 0x991DC; | ||
360 | LCDCON2 = 0xE8; | ||
361 | LCDTCON1 = (lcd_type == 1) ? 0x70103 : 0x30303; | ||
362 | LCDTCON2 = (lcd_type == 1) ? 0x70103 : 0x30703; | ||
363 | LCDTCON3 = 0x9F8EF; | ||
364 | LCDOSD1 = 0; | ||
365 | LCDOSD2 = 0; | ||
366 | LCDOSD3 = 0; | ||
367 | LCDB1SADDR1 = 0; | ||
368 | LCDB2SADDR1 = 0; | ||
369 | LCDF1SADDR1 = 0; | ||
370 | LCDF2SADDR1 = 0; | ||
371 | LCDB1SADDR2 = 0; | ||
372 | LCDB2SADDR2 = 0; | ||
373 | LCDF1SADDR2 = 0; | ||
374 | LCDF2SADDR2 = 0; | ||
375 | LCDB1SADDR3 = 0; | ||
376 | LCDB2SADDR3 = 0; | ||
377 | LCDF1SADDR3 = 0; | ||
378 | LCDF2SADDR3 = 0; | ||
379 | LCDKEYCON = 0; | ||
380 | LCDCOLVAL = 0; | ||
381 | LCDBGCON = 0; | ||
382 | LCDFGCON = 0; | ||
383 | LCDDITHMODE = 0; | ||
384 | |||
385 | LCDINTCON = 0; | ||
386 | } | ||
387 | |||
388 | void lcd_init_device(void) | ||
389 | { | ||
390 | unsigned int lcd_id; | ||
391 | |||
392 | /* configure LCD SPI pins */ | ||
393 | lcd_spi_init(); | ||
394 | |||
395 | /* identify display through SPI */ | ||
396 | lcd_id = lcd_read_reg(0); | ||
397 | lcd_type = (lcd_id == LCD_TYPE1_ID) ? 1 : 2; | ||
398 | |||
399 | /* configure LCD pins */ | ||
400 | PCON_ASRAM = 1; | ||
401 | |||
402 | /* init LCD controller */ | ||
403 | lcd_controller_init(); | ||
404 | |||
405 | /* display specific init sequence */ | ||
406 | if (lcd_type == 1) { | ||
407 | lcd_init1(); | ||
408 | } | ||
409 | else { | ||
410 | lcd_init2(); | ||
411 | } | ||
412 | |||
413 | /* set active background buffer */ | ||
414 | LCDCON1 &= ~(1 << 21); /* clear BDBCON */ | ||
415 | |||
416 | /* set background buffer address */ | ||
417 | LCDB1SADDR1 = (uint32_t) &lcd_local_fb[0][0]; | ||
418 | LCDB1SADDR2 = (uint32_t) &lcd_local_fb[LCD_HEIGHT][0]; | ||
419 | |||
420 | lcd_enable(true); | ||
421 | } | ||
74 | 422 | ||
75 | /* Performance function that works with an external buffer | 423 | void lcd_update_rect(int x, int y, int width, int height) |
76 | note that by and bheight are in 8-pixel units! */ | ||
77 | void lcd_blit_mono(const unsigned char *data, int x, int by, int width, | ||
78 | int bheight, int stride) | ||
79 | { | 424 | { |
80 | /* Copy display bitmap to hardware */ | 425 | fb_data *src; |
81 | while (bheight--) | 426 | uint32_t *dst; |
82 | { | 427 | fb_data pixel; |
428 | int h, w; | ||
429 | |||
430 | for (h = 0; h < height; h++) { | ||
431 | src = &lcd_framebuffer[y][x]; | ||
432 | dst = &lcd_local_fb[y][x]; | ||
433 | for (w = 0; w < width; w++) { | ||
434 | pixel = src[w]; | ||
435 | dst[w] = (RGB_UNPACK_RED(pixel) << 16) | | ||
436 | (RGB_UNPACK_GREEN(pixel) << 8) | | ||
437 | (RGB_UNPACK_BLUE(pixel) << 0); | ||
438 | } | ||
439 | y++; | ||
83 | } | 440 | } |
84 | } | 441 | } |
85 | 442 | ||
86 | |||
87 | /* Performance function that works with an external buffer | ||
88 | note that by and bheight are in 8-pixel units! */ | ||
89 | void lcd_blit_grey_phase_blit(unsigned char *values, unsigned char *phases, | ||
90 | int x, int by, int width, int bheight, int stride) | ||
91 | { | ||
92 | (void)values; | ||
93 | (void)phases; | ||
94 | (void)x; | ||
95 | (void)by; | ||
96 | (void)width; | ||
97 | (void)bheight; | ||
98 | (void)stride; | ||
99 | } | ||
100 | |||
101 | /* Update the display. | ||
102 | This must be called after all other LCD functions that change the display. */ | ||
103 | void lcd_update(void) ICODE_ATTR; | ||
104 | void lcd_update(void) | 443 | void lcd_update(void) |
105 | { | 444 | { |
106 | int y; | 445 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); |
107 | |||
108 | /* Copy display bitmap to hardware */ | ||
109 | for (y = 0; y < LCD_FBHEIGHT; y++) | ||
110 | { | ||
111 | } | ||
112 | } | 446 | } |
113 | 447 | ||
114 | /* Update a fraction of the display. */ | ||
115 | void lcd_update_rect(int, int, int, int) ICODE_ATTR; | ||
116 | void lcd_update_rect(int x, int y, int width, int height) | ||
117 | { | ||
118 | int ymax; | ||
119 | |||
120 | /* The Y coordinates have to work on even 8 pixel rows */ | ||
121 | ymax = (y + height-1) >> 3; | ||
122 | y >>= 3; | ||
123 | |||
124 | if(x + width > LCD_WIDTH) | ||
125 | width = LCD_WIDTH - x; | ||
126 | if (width <= 0) | ||
127 | return; /* nothing left to do, 0 is harmful to lcd_write_data() */ | ||
128 | if(ymax >= LCD_FBHEIGHT) | ||
129 | ymax = LCD_FBHEIGHT-1; | ||
130 | |||
131 | /* Copy specified rectange bitmap to hardware */ | ||
132 | for (; y <= ymax; y++) | ||
133 | { | ||
134 | } | ||
135 | } | ||