summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg White <gwhite@rockbox.org>2007-01-11 10:24:21 +0000
committerGreg White <gwhite@rockbox.org>2007-01-11 10:24:21 +0000
commitffb50d07af533bd2010672faecbaa3f206401d56 (patch)
tree5fd3ed1ecd8f25109ddce3daceecdd035ff66d30
parent991b2eefe95e8f758438051cd6ff829bc985dbac (diff)
downloadrockbox-ffb50d07af533bd2010672faecbaa3f206401d56.tar.gz
rockbox-ffb50d07af533bd2010672faecbaa3f206401d56.zip
Add initial backlight delay to stop backlight from fading during boot; switch to IDLE instead of yield()
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11983 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c140
-rw-r--r--firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c69
2 files changed, 121 insertions, 88 deletions
diff --git a/firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c
index b97e1430b2..9a1c684506 100644
--- a/firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c
+++ b/firmware/target/arm/gigabeat/meg-fx/backlight-meg-fx.c
@@ -36,8 +36,8 @@ static unsigned short backlight_current;
36static unsigned short backlight_target; 36static unsigned short backlight_target;
37static unsigned short time_til_fade; 37static unsigned short time_til_fade;
38static unsigned short fade_interval; 38static unsigned short fade_interval;
39static unsigned char backlight_leds; 39static unsigned short initial_tick_delay;
40 40static unsigned char backlight_leds;
41 41
42static enum backlight_states 42static enum backlight_states
43{ 43{
@@ -79,7 +79,7 @@ enum buttonlight_states
79 BUTTONLIGHT_MODE_CHARGING_ENTRY, 79 BUTTONLIGHT_MODE_CHARGING_ENTRY,
80 BUTTONLIGHT_MODE_CHARGING, 80 BUTTONLIGHT_MODE_CHARGING,
81 BUTTONLIGHT_MODE_CHARGING_WAIT, 81 BUTTONLIGHT_MODE_CHARGING_WAIT,
82 82
83 /* internal use only */ 83 /* internal use only */
84 BUTTONLIGHT_HELPER_SET, 84 BUTTONLIGHT_HELPER_SET,
85 BUTTONLIGHT_HELPER_SET_FINAL, 85 BUTTONLIGHT_HELPER_SET_FINAL,
@@ -92,7 +92,7 @@ enum buttonlight_states
92 92
93 93
94 94
95static char buttonlight_leds; 95static char buttonlight_leds;
96static unsigned short buttonlight_setting; 96static unsigned short buttonlight_setting;
97static unsigned short buttonlight_current; 97static unsigned short buttonlight_current;
98static unsigned char buttonlight_selected; 98static unsigned char buttonlight_selected;
@@ -122,7 +122,9 @@ void __backlight_init(void)
122 buttonlight_state = BUTTONLIGHT_MODE_OFF; 122 buttonlight_state = BUTTONLIGHT_MODE_OFF;
123 123
124 buttonlight_selected = 0x04; 124 buttonlight_selected = 0x04;
125 125
126 /* delay 5 seconds before any fading */
127 initial_tick_delay = 5000;
126 /* put the led control on the tick list */ 128 /* put the led control on the tick list */
127 tick_add_task(led_control_service); 129 tick_add_task(led_control_service);
128} 130}
@@ -167,24 +169,24 @@ void __buttonlight_trigger(void)
167 buttonlight_trigger_now = 1; 169 buttonlight_trigger_now = 1;
168} 170}
169 171
170 172
171 173
172 174
173/* map the mode from the command into the state machine entries */ 175/* map the mode from the command into the state machine entries */
174void __buttonlight_mode(enum buttonlight_mode mode, 176void __buttonlight_mode(enum buttonlight_mode mode,
175 enum buttonlight_selection selection, 177 enum buttonlight_selection selection,
176 unsigned short brightness) 178 unsigned short brightness)
177{ 179{
178 /* choose stop to setup mode */ 180 /* choose stop to setup mode */
179 buttonlight_state = BUTTONLIGHT_MODE_STOP; 181 buttonlight_state = BUTTONLIGHT_MODE_STOP;
180 182
181 183
182 /* clip brightness */ 184 /* clip brightness */
183 if (brightness > MAX_BRIGHTNESS_SETTING) 185 if (brightness > MAX_BRIGHTNESS_SETTING)
184 { 186 {
185 brightness = MAX_BRIGHTNESS_SETTING; 187 brightness = MAX_BRIGHTNESS_SETTING;
186 } 188 }
187 189
188 brightness++; 190 brightness++;
189 191
190 /* Select which LEDs to use */ 192 /* Select which LEDs to use */
@@ -193,7 +195,7 @@ void __buttonlight_mode(enum buttonlight_mode mode,
193 case BUTTONLIGHT_LED_ALL: 195 case BUTTONLIGHT_LED_ALL:
194 buttonlight_selected = BUTTONLIGHT_ALL; 196 buttonlight_selected = BUTTONLIGHT_ALL;
195 break; 197 break;
196 198
197 case BUTTONLIGHT_LED_MENU: 199 case BUTTONLIGHT_LED_MENU:
198 buttonlight_selected = BUTTONLIGHT_MENU; 200 buttonlight_selected = BUTTONLIGHT_MENU;
199 break; 201 break;
@@ -216,7 +218,7 @@ void __buttonlight_mode(enum buttonlight_mode mode,
216 buttonlight_trigger_brightness = 1; 218 buttonlight_trigger_brightness = 1;
217 buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY; 219 buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY;
218 break; 220 break;
219 221
220 case BUTTONLIGHT_FLICKER: 222 case BUTTONLIGHT_FLICKER:
221 buttonlight_trigger_brightness = brightness; 223 buttonlight_trigger_brightness = brightness;
222 buttonlight_state = BUTTONLIGHT_MODE_FLICKER_ENTRY; 224 buttonlight_state = BUTTONLIGHT_MODE_FLICKER_ENTRY;
@@ -239,21 +241,21 @@ void __buttonlight_mode(enum buttonlight_mode mode,
239 return; /* unknown mode */ 241 return; /* unknown mode */
240 } 242 }
241 243
242 244
243} 245}
244 246
245 247
246 248
247/* 249/*
248 * The button lights have 'modes' of operation. Each mode must setup and 250 * The button lights have 'modes' of operation. Each mode must setup and
249 * execute its own operation - taking care that this is all done in an ISR. 251 * execute its own operation - taking care that this is all done in an ISR.
250 * 252 *
251 */ 253 */
252 254
253 255
254 256
255/* led_control_service runs in interrupt context - be brief! 257/* led_control_service runs in interrupt context - be brief!
256 * This service is called once per interrupt timer tick - 100 times a second. 258 * This service is called once per interrupt timer tick - 100 times a second.
257 * 259 *
258 * There should be at most only one i2c operation per call - if more are need 260 * There should be at most only one i2c operation per call - if more are need
259 * the calls should be spread across calls. 261 * the calls should be spread across calls.
@@ -268,25 +270,29 @@ void __buttonlight_mode(enum buttonlight_mode mode,
268 */ 270 */
269static void led_control_service(void) 271static void led_control_service(void)
270{ 272{
273 if(initial_tick_delay) {
274 initial_tick_delay--;
275 return;
276 }
271 switch (backlight_control) 277 switch (backlight_control)
272 { 278 {
273 case BACKLIGHT_CONTROL_IDLE: 279 case BACKLIGHT_CONTROL_IDLE:
274 switch (buttonlight_state) 280 switch (buttonlight_state)
275 { 281 {
276 case BUTTONLIGHT_MODE_STOP: break; 282 case BUTTONLIGHT_MODE_STOP: break;
277 283
278 /* Buttonlight mode: OFF */ 284 /* Buttonlight mode: OFF */
279 case BUTTONLIGHT_MODE_OFF_ENTRY: 285 case BUTTONLIGHT_MODE_OFF_ENTRY:
280 if (buttonlight_current) 286 if (buttonlight_current)
281 { 287 {
282 buttonlight_leds = 0x00; 288 buttonlight_leds = 0x00;
283 sc606_write(SC606_REG_CONF, backlight_leds); 289 sc606_write(SC606_REG_CONF, backlight_leds);
284 buttonlight_current = 0; 290 buttonlight_current = 0;
285 } 291 }
286 buttonlight_state = BUTTONLIGHT_MODE_OFF; 292 buttonlight_state = BUTTONLIGHT_MODE_OFF;
287 break; 293 break;
288 294
289 case BUTTONLIGHT_MODE_OFF: 295 case BUTTONLIGHT_MODE_OFF:
290 break; 296 break;
291 297
292 298
@@ -301,8 +307,8 @@ static void led_control_service(void)
301 buttonlight_setting = DEFAULT_BRIGHTNESS_SETTING; 307 buttonlight_setting = DEFAULT_BRIGHTNESS_SETTING;
302 buttonlight_saved_state = BUTTONLIGHT_MODE_CHARGING_WAIT; 308 buttonlight_saved_state = BUTTONLIGHT_MODE_CHARGING_WAIT;
303 buttonlight_state = BUTTONLIGHT_HELPER_SET; 309 buttonlight_state = BUTTONLIGHT_HELPER_SET;
304 break; 310 break;
305 311
306 312
307 case BUTTONLIGHT_MODE_CHARGING: 313 case BUTTONLIGHT_MODE_CHARGING:
308 if (--buttonlight_charging_counter == 0) 314 if (--buttonlight_charging_counter == 0)
@@ -318,7 +324,7 @@ static void led_control_service(void)
318 sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); 324 sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds);
319 buttonlight_charging_counter = CHARGING_LED_COUNT; 325 buttonlight_charging_counter = CHARGING_LED_COUNT;
320 } 326 }
321 else 327 else
322 { 328 {
323 buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY; 329 buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY;
324 } 330 }
@@ -334,11 +340,11 @@ static void led_control_service(void)
334 buttonlight_state = BUTTONLIGHT_MODE_CHARGING; 340 buttonlight_state = BUTTONLIGHT_MODE_CHARGING;
335 } 341 }
336 break; 342 break;
337 343
338 344
339 /* Buttonlight mode: FOLLOW - try to stay current with backlight 345 /* Buttonlight mode: FOLLOW - try to stay current with backlight
340 * since this runs in the idle of the backlight it will not really 346 * since this runs in the idle of the backlight it will not really
341 * follow in real time 347 * follow in real time
342 */ 348 */
343 case BUTTONLIGHT_MODE_FOLLOW_ENTRY: 349 case BUTTONLIGHT_MODE_FOLLOW_ENTRY:
344 /* case 1 - backlight on, but buttonlight is off */ 350 /* case 1 - backlight on, but buttonlight is off */
@@ -347,23 +353,23 @@ static void led_control_service(void)
347 /* Turn the buttonlights on */ 353 /* Turn the buttonlights on */
348 buttonlight_leds = buttonlight_selected; 354 buttonlight_leds = buttonlight_selected;
349 sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); 355 sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds);
350 356
351 /* temporary save for the next mode - then to do settings */ 357 /* temporary save for the next mode - then to do settings */
352 buttonlight_setting = backlight_current; 358 buttonlight_setting = backlight_current;
353 buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; 359 buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW;
354 buttonlight_state = BUTTONLIGHT_HELPER_SET; 360 buttonlight_state = BUTTONLIGHT_HELPER_SET;
355 } 361 }
356 /* case 2 - backlight off, but buttonlight is on */ 362 /* case 2 - backlight off, but buttonlight is on */
357 else 363 else
358 { 364 {
359 buttonlight_current = 0; 365 buttonlight_current = 0;
360 buttonlight_leds = 0x00; 366 buttonlight_leds = 0x00;
361 sc606_write(SC606_REG_CONF, backlight_leds); 367 sc606_write(SC606_REG_CONF, backlight_leds);
362 buttonlight_state = BUTTONLIGHT_MODE_FOLLOW; 368 buttonlight_state = BUTTONLIGHT_MODE_FOLLOW;
363 } 369 }
364 break; 370 break;
365 371
366 case BUTTONLIGHT_MODE_FOLLOW: 372 case BUTTONLIGHT_MODE_FOLLOW:
367 if (buttonlight_current != backlight_current) 373 if (buttonlight_current != backlight_current)
368 { 374 {
369 /* case 1 - backlight on, but buttonlight is off */ 375 /* case 1 - backlight on, but buttonlight is off */
@@ -375,27 +381,27 @@ static void led_control_service(void)
375 buttonlight_leds = buttonlight_selected; 381 buttonlight_leds = buttonlight_selected;
376 sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); 382 sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds);
377 } 383 }
378 384
379 /* temporary save for the next mode - then to do settings */ 385 /* temporary save for the next mode - then to do settings */
380 buttonlight_setting = backlight_current; 386 buttonlight_setting = backlight_current;
381 buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; 387 buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW;
382 buttonlight_state = BUTTONLIGHT_HELPER_SET; 388 buttonlight_state = BUTTONLIGHT_HELPER_SET;
383 } 389 }
384 390
385 /* case 2 - backlight off, but buttonlight is on */ 391 /* case 2 - backlight off, but buttonlight is on */
386 else 392 else
387 { 393 {
388 buttonlight_current = 0; 394 buttonlight_current = 0;
389 buttonlight_leds = 0x00; 395 buttonlight_leds = 0x00;
390 sc606_write(SC606_REG_CONF, backlight_leds); 396 sc606_write(SC606_REG_CONF, backlight_leds);
391 } 397 }
392 398
393 } 399 }
394 break; 400 break;
395 401
396 402
397 403
398 /* Buttonlight mode: ON - stays at the set brightness */ 404 /* Buttonlight mode: ON - stays at the set brightness */
399 case BUTTONLIGHT_MODE_ON_ENTRY: 405 case BUTTONLIGHT_MODE_ON_ENTRY:
400 buttonlight_leds = buttonlight_selected; 406 buttonlight_leds = buttonlight_selected;
401 sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); 407 sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds);
@@ -406,22 +412,22 @@ static void led_control_service(void)
406 buttonlight_state = BUTTONLIGHT_HELPER_SET; 412 buttonlight_state = BUTTONLIGHT_HELPER_SET;
407 break; 413 break;
408 414
409 case BUTTONLIGHT_MODE_ON: 415 case BUTTONLIGHT_MODE_ON:
410 break; 416 break;
411 417
412 418
413 419
414 /* Buttonlight mode: FLICKER */ 420 /* Buttonlight mode: FLICKER */
415 case BUTTONLIGHT_MODE_FLICKER_ENTRY: 421 case BUTTONLIGHT_MODE_FLICKER_ENTRY:
416 /* already on? turn it off */ 422 /* already on? turn it off */
417 if (buttonlight_current) 423 if (buttonlight_current)
418 { 424 {
419 buttonlight_leds = 0x00; 425 buttonlight_leds = 0x00;
420 sc606_write(SC606_REG_CONF, backlight_leds); 426 sc606_write(SC606_REG_CONF, backlight_leds);
421 buttonlight_current = 0; 427 buttonlight_current = 0;
422 } 428 }
423 429
424 /* set the brightness if not already set */ 430 /* set the brightness if not already set */
425 if (buttonlight_current != buttonlight_trigger_brightness) 431 if (buttonlight_current != buttonlight_trigger_brightness)
426 { 432 {
427 /* temporary save for the next mode - then to do settings */ 433 /* temporary save for the next mode - then to do settings */
@@ -448,7 +454,7 @@ static void led_control_service(void)
448 buttonlight_state = BUTTONLIGHT_MODE_FLICKERING; 454 buttonlight_state = BUTTONLIGHT_MODE_FLICKERING;
449 } 455 }
450 break; 456 break;
451 457
452 458
453 case BUTTONLIGHT_MODE_FLICKERING: 459 case BUTTONLIGHT_MODE_FLICKERING:
454 /* flicker the LEDs for as long as we get triggered */ 460 /* flicker the LEDs for as long as we get triggered */
@@ -477,7 +483,7 @@ static void led_control_service(void)
477 /* reset flickering */ 483 /* reset flickering */
478 buttonlight_trigger_now = 0; 484 buttonlight_trigger_now = 0;
479 buttonlight_flickering = FLICKER_PERIOD; 485 buttonlight_flickering = FLICKER_PERIOD;
480 486
481 /* turn buttonlights on */ 487 /* turn buttonlights on */
482 buttonlight_leds = buttonlight_selected; 488 buttonlight_leds = buttonlight_selected;
483 buttonlight_current = buttonlight_setting; 489 buttonlight_current = buttonlight_setting;
@@ -487,17 +493,17 @@ static void led_control_service(void)
487 break; 493 break;
488 494
489 495
490 /* Buttonlight mode: SIGNAL / SOLID */ 496 /* Buttonlight mode: SIGNAL / SOLID */
491 case BUTTONLIGHT_MODE_SOLID_ENTRY: 497 case BUTTONLIGHT_MODE_SOLID_ENTRY:
492 /* already on? turn it off */ 498 /* already on? turn it off */
493 if (buttonlight_current) 499 if (buttonlight_current)
494 { 500 {
495 buttonlight_leds = 0x00; 501 buttonlight_leds = 0x00;
496 sc606_write(SC606_REG_CONF, backlight_leds); 502 sc606_write(SC606_REG_CONF, backlight_leds);
497 buttonlight_current = 0; 503 buttonlight_current = 0;
498 } 504 }
499 505
500 /* set the brightness if not already set */ 506 /* set the brightness if not already set */
501 /* temporary save for the next mode - then to do settings */ 507 /* temporary save for the next mode - then to do settings */
502 buttonlight_setting = buttonlight_trigger_brightness; 508 buttonlight_setting = buttonlight_trigger_brightness;
503 buttonlight_saved_state = BUTTONLIGHT_MODE_SOLID; 509 buttonlight_saved_state = BUTTONLIGHT_MODE_SOLID;
@@ -527,10 +533,10 @@ static void led_control_service(void)
527 buttonlight_leds = 0x00; 533 buttonlight_leds = 0x00;
528 sc606_write(SC606_REG_CONF, backlight_leds); 534 sc606_write(SC606_REG_CONF, backlight_leds);
529 buttonlight_current = 0; 535 buttonlight_current = 0;
530 } 536 }
531 } 537 }
532 break; 538 break;
533 539
534 540
535 /* set the brightness for the buttonlights - takes 2 passes */ 541 /* set the brightness for the buttonlights - takes 2 passes */
536 case BUTTONLIGHT_HELPER_SET: 542 case BUTTONLIGHT_HELPER_SET:
@@ -546,7 +552,7 @@ static void led_control_service(void)
546 552
547 default: 553 default:
548 break; 554 break;
549 555
550 } 556 }
551 break; 557 break;
552 558
@@ -568,7 +574,7 @@ static void led_control_service(void)
568 lcd_enable(false); 574 lcd_enable(false);
569 break; 575 break;
570 576
571 577
572 case BACKLIGHT_CONTROL_ON: 578 case BACKLIGHT_CONTROL_ON:
573 backlight_leds = 0x03; 579 backlight_leds = 0x03;
574 sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds); 580 sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds);
@@ -582,7 +588,7 @@ static void led_control_service(void)
582 sc606_write(SC606_REG_A, backlight_brightness-1); 588 sc606_write(SC606_REG_A, backlight_brightness-1);
583 589
584 /* if we were turned off - turn the backlight on */ 590 /* if we were turned off - turn the backlight on */
585 if (backlight_current) 591 if (backlight_current)
586 { 592 {
587 backlight_current = backlight_brightness; 593 backlight_current = backlight_brightness;
588 backlight_control = BACKLIGHT_CONTROL_IDLE; 594 backlight_control = BACKLIGHT_CONTROL_IDLE;
@@ -592,11 +598,11 @@ static void led_control_service(void)
592 backlight_control = BACKLIGHT_CONTROL_ON; 598 backlight_control = BACKLIGHT_CONTROL_ON;
593 } 599 }
594 break; 600 break;
595 601
596 602
597 case BACKLIGHT_CONTROL_FADE_ON: 603 case BACKLIGHT_CONTROL_FADE_ON:
598 if (--time_til_fade) return; 604 if (--time_til_fade) return;
599 605
600 /* The SC606 LED driver can set the brightness in 64 steps */ 606 /* The SC606 LED driver can set the brightness in 64 steps */
601 sc606_write(SC606_REG_A, backlight_current++); 607 sc606_write(SC606_REG_A, backlight_current++);
602 608
@@ -610,11 +616,11 @@ static void led_control_service(void)
610 time_til_fade = fade_interval; 616 time_til_fade = fade_interval;
611 } 617 }
612 break; 618 break;
613 619
614 620
615 case BACKLIGHT_CONTROL_FADE_OFF: 621 case BACKLIGHT_CONTROL_FADE_OFF:
616 if (--time_til_fade) return; 622 if (--time_til_fade) return;
617 623
618 /* The SC606 LED driver can set the brightness in 64 steps */ 624 /* The SC606 LED driver can set the brightness in 64 steps */
619 sc606_write(SC606_REG_A, --backlight_current); 625 sc606_write(SC606_REG_A, --backlight_current);
620 626
@@ -629,7 +635,7 @@ static void led_control_service(void)
629 { 635 {
630 backlight_control = BACKLIGHT_CONTROL_OFF; 636 backlight_control = BACKLIGHT_CONTROL_OFF;
631 } 637 }
632 638
633 } 639 }
634 else 640 else
635 { 641 {
@@ -638,6 +644,10 @@ static void led_control_service(void)
638 break; 644 break;
639 } 645 }
640 646
647 if(backlight_current)
648 lcd_enable(true);
649 else
650 lcd_enable(false);
641} 651}
642 652
643 653
@@ -647,18 +657,18 @@ static void led_control_service(void)
647void __backlight_dim(bool dim_now) 657void __backlight_dim(bool dim_now)
648{ 658{
649 unsigned short target; 659 unsigned short target;
650 660
651 /* dont let the interrupt tick happen */ 661 /* dont let the interrupt tick happen */
652 backlight_control = BACKLIGHT_CONTROL_IDLE; 662 backlight_control = BACKLIGHT_CONTROL_IDLE;
653 663
654 target = (dim_now == true) ? 0 : backlight_brightness; 664 target = (dim_now == true) ? 0 : backlight_brightness;
655 665
656 /* only try and fade if the target is different */ 666 /* only try and fade if the target is different */
657 if (backlight_current != target) 667 if (backlight_current != target)
658 { 668 {
659 backlight_target = target; 669 backlight_target = target;
660 670
661 if (backlight_current > backlight_target) 671 if (backlight_current > backlight_target)
662 { 672 {
663 time_til_fade = fade_interval = 4; 673 time_til_fade = fade_interval = 4;
664 backlight_control = BACKLIGHT_CONTROL_FADE_OFF; 674 backlight_control = BACKLIGHT_CONTROL_FADE_OFF;
@@ -676,7 +686,7 @@ void __backlight_dim(bool dim_now)
676 } 686 }
677 } 687 }
678 } 688 }
679 689
680} 690}
681 691
682 692
diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
index 965f4523c8..cbeddc6ee7 100644
--- a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
+++ b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
@@ -16,29 +16,45 @@ unsigned long fg_pattern_blit[4];
16unsigned long bg_pattern_blit[4]; 16unsigned long bg_pattern_blit[4];
17 17
18volatile bool use_dma_blit = false; 18volatile bool use_dma_blit = false;
19volatile bool lcd_on = true; 19static volatile bool lcd_on = true;
20volatile bool lcd_poweroff = true; 20volatile bool lcd_poweroff = false;
21/* 21/*
22** These are imported from lcd-16bit.c 22** These are imported from lcd-16bit.c
23*/ 23*/
24extern unsigned fg_pattern; 24extern unsigned fg_pattern;
25extern unsigned bg_pattern; 25extern unsigned bg_pattern;
26 26
27extern volatile bool lcd_on; 27static struct mutex lcd_update_mtx;
28static struct mutex lcd_clear_mtx;
29static struct mutex lcd_enable_mtx;
30
31
32bool lcd_enabled()
33{
34 return lcd_on;
35}
28 36
29/* LCD init */ 37/* LCD init */
30void lcd_init_device(void) 38void lcd_init_device(void)
31{ 39{
40 mutex_init(&lcd_update_mtx);
41 mutex_init(&lcd_clear_mtx);
42 mutex_init(&lcd_enable_mtx);
43
32 memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); 44 memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2);
33 memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); 45 memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2);
34 clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); 46 clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit));
35 clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); 47 clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit));
36 48
37 /* Switch from 555I mode to 565 mode */ 49 LCDSADDR1 = 0x18F00000; /* These values are pulled from an F40 */
38 LCDCON5 |= 1 << 11; 50 LCDSADDR2 = 0x00112C00; /* They should move FRAME to the correct location */
51 LCDSADDR3 = 0x000000F0; /* TODO: Move FRAME to where we want it */
52
53 LCDCON5 |= 1 << 11; /* Switch from 555I mode to 565 mode */
39 54
40#if !defined(BOOTLOADER) 55#if !defined(BOOTLOADER)
41 use_dma_blit = true; 56 use_dma_blit = true;
57 lcd_poweroff = true;
42#endif 58#endif
43} 59}
44 60
@@ -52,15 +68,16 @@ void lcd_update_rect(int x, int y, int width, int height)
52 68
53 if(!lcd_on) 69 if(!lcd_on)
54 { 70 {
55 for(x=0; x < 2; x++) 71 sleep(200);
56 yield();
57 return; 72 return;
58 } 73 }
59 if (use_dma_blit) 74 if (use_dma_blit)
60 { 75 {
76// mutex_lock(&lcd_update_mtx);
77
61 /* Wait for this controller to stop pending transfer */ 78 /* Wait for this controller to stop pending transfer */
62 while((DSTAT1 & 0x000fffff)) 79 while((DSTAT1 & 0x000fffff))
63 yield(); 80 CLKCON |= (1 << 2); /* set IDLE bit */
64 81
65 /* Flush DCache */ 82 /* Flush DCache */
66 invalidate_dcache_range((void *)(((int) &lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH)), (height * sizeof(fb_data) * LCD_WIDTH)); 83 invalidate_dcache_range((void *)(((int) &lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH)), (height * sizeof(fb_data) * LCD_WIDTH));
@@ -86,7 +103,8 @@ void lcd_update_rect(int x, int y, int width, int height)
86 103
87 /* Wait for transfer to complete */ 104 /* Wait for transfer to complete */
88 while((DSTAT1 & 0x000fffff)) 105 while((DSTAT1 & 0x000fffff))
89 yield(); 106 CLKCON |= (1 << 2); /* set IDLE bit */
107// mutex_unlock(&lcd_update_mtx);
90 } 108 }
91 else 109 else
92 memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); 110 memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH)));
@@ -95,19 +113,23 @@ void lcd_update_rect(int x, int y, int width, int height)
95 113
96void lcd_enable(bool state) 114void lcd_enable(bool state)
97{ 115{
116 if(!lcd_poweroff)
117 return;
118 mutex_lock(&lcd_enable_mtx);
98 if(state) { 119 if(state) {
99 if(lcd_poweroff && !lcd_on) { 120 if(!lcd_on) {
100 memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2);
101 lcd_on = true; 121 lcd_on = true;
122 memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2);
102 LCDCON1 |= 1; 123 LCDCON1 |= 1;
103 } 124 }
104 } 125 }
105 else { 126 else {
106 if(lcd_poweroff && lcd_on) { 127 if(lcd_on) {
107 lcd_on = false; 128 lcd_on = false;
108 LCDCON1 &= ~1; 129 LCDCON1 &= ~1;
109 } 130 }
110 } 131 }
132 mutex_unlock(&lcd_enable_mtx);
111} 133}
112 134
113void lcd_set_foreground(unsigned color) 135void lcd_set_foreground(unsigned color)
@@ -115,19 +137,19 @@ void lcd_set_foreground(unsigned color)
115 fg_pattern = color; 137 fg_pattern = color;
116 138
117 memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); 139 memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2);
118 clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); 140 invalidate_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit));
119} 141}
120 142
121void lcd_set_background(unsigned color) 143void lcd_set_background(unsigned color)
122{ 144{
123 bg_pattern = color; 145 bg_pattern = color;
124 memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); 146 memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2);
125 clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); 147 invalidate_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit));
126} 148}
127 149
128void lcd_device_prepare_backdrop(fb_data* backdrop) 150void lcd_device_prepare_backdrop(fb_data* backdrop)
129{ 151{
130 clean_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); 152 invalidate_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH));
131} 153}
132 154
133void lcd_clear_display_dma(void) 155void lcd_clear_display_dma(void)
@@ -136,10 +158,8 @@ void lcd_clear_display_dma(void)
136 bool inc = false; 158 bool inc = false;
137 159
138 if(!lcd_on) { 160 if(!lcd_on) {
139 yield(); 161 sleep(200);
140 yield();
141 } 162 }
142
143 if (lcd_get_drawmode() & DRMODE_INVERSEVID) 163 if (lcd_get_drawmode() & DRMODE_INVERSEVID)
144 src = fg_pattern_blit; 164 src = fg_pattern_blit;
145 else 165 else
@@ -154,9 +174,10 @@ void lcd_clear_display_dma(void)
154 inc = true; 174 inc = true;
155 } 175 }
156 } 176 }
177// mutex_lock(&lcd_clear_mtx);
157 /* Wait for any pending transfer to complete */ 178 /* Wait for any pending transfer to complete */
158 while((DSTAT3 & 0x000fffff)) 179 while((DSTAT3 & 0x000fffff))
159 yield(); 180 CLKCON |= (1 << 2); /* set IDLE bit */
160 DMASKTRIG3 |= 0x4; /* Stop controller */ 181 DMASKTRIG3 |= 0x4; /* Stop controller */
161 DIDST3 = ((int) lcd_framebuffer) + 0x30000000; /* set DMA dest, physical address */ 182 DIDST3 = ((int) lcd_framebuffer) + 0x30000000; /* set DMA dest, physical address */
162 DIDSTC3 = 0; /* Dest on AHB, increment */ 183 DIDSTC3 = 0; /* Dest on AHB, increment */
@@ -165,10 +186,10 @@ void lcd_clear_display_dma(void)
165 DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */ 186 DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */
166 187
167 /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */ 188 /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */
168 DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH) >> 4); 189 DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | (sizeof(lcd_framebuffer) >> 4);
169 190
170 /* Dump DCache for dest, we are about to overwrite it with DMA */ 191 /* Dump DCache for dest, we are about to overwrite it with DMA */
171 dump_dcache_range((void *)lcd_framebuffer, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); 192 invalidate_dcache_range((void *)lcd_framebuffer, sizeof(lcd_framebuffer));
172 /* Activate the channel */ 193 /* Activate the channel */
173 DMASKTRIG3 = 2; 194 DMASKTRIG3 = 2;
174 /* Start DMA */ 195 /* Start DMA */
@@ -176,11 +197,14 @@ void lcd_clear_display_dma(void)
176 197
177 /* Wait for transfer to complete */ 198 /* Wait for transfer to complete */
178 while((DSTAT3 & 0x000fffff)) 199 while((DSTAT3 & 0x000fffff))
179 yield(); 200 CLKCON |= (1 << 2); /* set IDLE bit */
201// mutex_unlock(&lcd_update_mtx);
180} 202}
181 203
182void lcd_clear_display(void) 204void lcd_clear_display(void)
183{ 205{
206 lcd_stop_scroll();
207
184 if(use_dma_blit) 208 if(use_dma_blit)
185 { 209 {
186 lcd_clear_display_dma(); 210 lcd_clear_display_dma();
@@ -201,7 +225,6 @@ void lcd_clear_display(void)
201 else 225 else
202 memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); 226 memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer));
203 } 227 }
204 lcd_stop_scroll();
205} 228}
206 229
207 230