From ffb50d07af533bd2010672faecbaa3f206401d56 Mon Sep 17 00:00:00 2001 From: Greg White Date: Thu, 11 Jan 2007 10:24:21 +0000 Subject: 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 --- .../target/arm/gigabeat/meg-fx/backlight-meg-fx.c | 140 +++++++++++---------- firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | 69 ++++++---- 2 files changed, 121 insertions(+), 88 deletions(-) (limited to 'firmware/target/arm/gigabeat/meg-fx') 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; static unsigned short backlight_target; static unsigned short time_til_fade; static unsigned short fade_interval; -static unsigned char backlight_leds; - +static unsigned short initial_tick_delay; +static unsigned char backlight_leds; static enum backlight_states { @@ -79,7 +79,7 @@ enum buttonlight_states BUTTONLIGHT_MODE_CHARGING_ENTRY, BUTTONLIGHT_MODE_CHARGING, BUTTONLIGHT_MODE_CHARGING_WAIT, - + /* internal use only */ BUTTONLIGHT_HELPER_SET, BUTTONLIGHT_HELPER_SET_FINAL, @@ -92,7 +92,7 @@ enum buttonlight_states -static char buttonlight_leds; +static char buttonlight_leds; static unsigned short buttonlight_setting; static unsigned short buttonlight_current; static unsigned char buttonlight_selected; @@ -122,7 +122,9 @@ void __backlight_init(void) buttonlight_state = BUTTONLIGHT_MODE_OFF; buttonlight_selected = 0x04; - + + /* delay 5 seconds before any fading */ + initial_tick_delay = 5000; /* put the led control on the tick list */ tick_add_task(led_control_service); } @@ -167,24 +169,24 @@ void __buttonlight_trigger(void) buttonlight_trigger_now = 1; } - + /* map the mode from the command into the state machine entries */ -void __buttonlight_mode(enum buttonlight_mode mode, +void __buttonlight_mode(enum buttonlight_mode mode, enum buttonlight_selection selection, unsigned short brightness) { /* choose stop to setup mode */ buttonlight_state = BUTTONLIGHT_MODE_STOP; - + /* clip brightness */ if (brightness > MAX_BRIGHTNESS_SETTING) { brightness = MAX_BRIGHTNESS_SETTING; } - + brightness++; /* Select which LEDs to use */ @@ -193,7 +195,7 @@ void __buttonlight_mode(enum buttonlight_mode mode, case BUTTONLIGHT_LED_ALL: buttonlight_selected = BUTTONLIGHT_ALL; break; - + case BUTTONLIGHT_LED_MENU: buttonlight_selected = BUTTONLIGHT_MENU; break; @@ -216,7 +218,7 @@ void __buttonlight_mode(enum buttonlight_mode mode, buttonlight_trigger_brightness = 1; buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY; break; - + case BUTTONLIGHT_FLICKER: buttonlight_trigger_brightness = brightness; buttonlight_state = BUTTONLIGHT_MODE_FLICKER_ENTRY; @@ -239,21 +241,21 @@ void __buttonlight_mode(enum buttonlight_mode mode, return; /* unknown mode */ } - + } -/* +/* * The button lights have 'modes' of operation. Each mode must setup and * execute its own operation - taking care that this is all done in an ISR. - * + * */ -/* led_control_service runs in interrupt context - be brief! - * This service is called once per interrupt timer tick - 100 times a second. +/* led_control_service runs in interrupt context - be brief! + * This service is called once per interrupt timer tick - 100 times a second. * * There should be at most only one i2c operation per call - if more are need * the calls should be spread across calls. @@ -268,25 +270,29 @@ void __buttonlight_mode(enum buttonlight_mode mode, */ static void led_control_service(void) { + if(initial_tick_delay) { + initial_tick_delay--; + return; + } switch (backlight_control) { - case BACKLIGHT_CONTROL_IDLE: + case BACKLIGHT_CONTROL_IDLE: switch (buttonlight_state) { case BUTTONLIGHT_MODE_STOP: break; - + /* Buttonlight mode: OFF */ - case BUTTONLIGHT_MODE_OFF_ENTRY: + case BUTTONLIGHT_MODE_OFF_ENTRY: if (buttonlight_current) { buttonlight_leds = 0x00; sc606_write(SC606_REG_CONF, backlight_leds); buttonlight_current = 0; - } + } buttonlight_state = BUTTONLIGHT_MODE_OFF; break; - case BUTTONLIGHT_MODE_OFF: + case BUTTONLIGHT_MODE_OFF: break; @@ -301,8 +307,8 @@ static void led_control_service(void) buttonlight_setting = DEFAULT_BRIGHTNESS_SETTING; buttonlight_saved_state = BUTTONLIGHT_MODE_CHARGING_WAIT; buttonlight_state = BUTTONLIGHT_HELPER_SET; - break; - + break; + case BUTTONLIGHT_MODE_CHARGING: if (--buttonlight_charging_counter == 0) @@ -318,7 +324,7 @@ static void led_control_service(void) sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); buttonlight_charging_counter = CHARGING_LED_COUNT; } - else + else { buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY; } @@ -334,11 +340,11 @@ static void led_control_service(void) buttonlight_state = BUTTONLIGHT_MODE_CHARGING; } break; - - - /* Buttonlight mode: FOLLOW - try to stay current with backlight + + + /* Buttonlight mode: FOLLOW - try to stay current with backlight * since this runs in the idle of the backlight it will not really - * follow in real time + * follow in real time */ case BUTTONLIGHT_MODE_FOLLOW_ENTRY: /* case 1 - backlight on, but buttonlight is off */ @@ -347,23 +353,23 @@ static void led_control_service(void) /* Turn the buttonlights on */ buttonlight_leds = buttonlight_selected; sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - + /* temporary save for the next mode - then to do settings */ buttonlight_setting = backlight_current; buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; buttonlight_state = BUTTONLIGHT_HELPER_SET; } /* case 2 - backlight off, but buttonlight is on */ - else + else { buttonlight_current = 0; buttonlight_leds = 0x00; sc606_write(SC606_REG_CONF, backlight_leds); buttonlight_state = BUTTONLIGHT_MODE_FOLLOW; } - break; + break; - case BUTTONLIGHT_MODE_FOLLOW: + case BUTTONLIGHT_MODE_FOLLOW: if (buttonlight_current != backlight_current) { /* case 1 - backlight on, but buttonlight is off */ @@ -375,27 +381,27 @@ static void led_control_service(void) buttonlight_leds = buttonlight_selected; sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); } - + /* temporary save for the next mode - then to do settings */ buttonlight_setting = backlight_current; buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; buttonlight_state = BUTTONLIGHT_HELPER_SET; } - + /* case 2 - backlight off, but buttonlight is on */ - else + else { buttonlight_current = 0; buttonlight_leds = 0x00; sc606_write(SC606_REG_CONF, backlight_leds); } - + } - break; + break; - /* Buttonlight mode: ON - stays at the set brightness */ + /* Buttonlight mode: ON - stays at the set brightness */ case BUTTONLIGHT_MODE_ON_ENTRY: buttonlight_leds = buttonlight_selected; sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); @@ -406,22 +412,22 @@ static void led_control_service(void) buttonlight_state = BUTTONLIGHT_HELPER_SET; break; - case BUTTONLIGHT_MODE_ON: + case BUTTONLIGHT_MODE_ON: break; - /* Buttonlight mode: FLICKER */ + /* Buttonlight mode: FLICKER */ case BUTTONLIGHT_MODE_FLICKER_ENTRY: /* already on? turn it off */ - if (buttonlight_current) + if (buttonlight_current) { buttonlight_leds = 0x00; sc606_write(SC606_REG_CONF, backlight_leds); buttonlight_current = 0; - } + } - /* set the brightness if not already set */ + /* set the brightness if not already set */ if (buttonlight_current != buttonlight_trigger_brightness) { /* temporary save for the next mode - then to do settings */ @@ -448,7 +454,7 @@ static void led_control_service(void) buttonlight_state = BUTTONLIGHT_MODE_FLICKERING; } break; - + case BUTTONLIGHT_MODE_FLICKERING: /* flicker the LEDs for as long as we get triggered */ @@ -477,7 +483,7 @@ static void led_control_service(void) /* reset flickering */ buttonlight_trigger_now = 0; buttonlight_flickering = FLICKER_PERIOD; - + /* turn buttonlights on */ buttonlight_leds = buttonlight_selected; buttonlight_current = buttonlight_setting; @@ -487,17 +493,17 @@ static void led_control_service(void) break; - /* Buttonlight mode: SIGNAL / SOLID */ + /* Buttonlight mode: SIGNAL / SOLID */ case BUTTONLIGHT_MODE_SOLID_ENTRY: /* already on? turn it off */ - if (buttonlight_current) + if (buttonlight_current) { buttonlight_leds = 0x00; sc606_write(SC606_REG_CONF, backlight_leds); buttonlight_current = 0; - } - - /* set the brightness if not already set */ + } + + /* set the brightness if not already set */ /* temporary save for the next mode - then to do settings */ buttonlight_setting = buttonlight_trigger_brightness; buttonlight_saved_state = BUTTONLIGHT_MODE_SOLID; @@ -527,10 +533,10 @@ static void led_control_service(void) buttonlight_leds = 0x00; sc606_write(SC606_REG_CONF, backlight_leds); buttonlight_current = 0; - } + } } break; - + /* set the brightness for the buttonlights - takes 2 passes */ case BUTTONLIGHT_HELPER_SET: @@ -546,7 +552,7 @@ static void led_control_service(void) default: break; - + } break; @@ -568,7 +574,7 @@ static void led_control_service(void) lcd_enable(false); break; - + case BACKLIGHT_CONTROL_ON: backlight_leds = 0x03; sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds); @@ -582,7 +588,7 @@ static void led_control_service(void) sc606_write(SC606_REG_A, backlight_brightness-1); /* if we were turned off - turn the backlight on */ - if (backlight_current) + if (backlight_current) { backlight_current = backlight_brightness; backlight_control = BACKLIGHT_CONTROL_IDLE; @@ -592,11 +598,11 @@ static void led_control_service(void) backlight_control = BACKLIGHT_CONTROL_ON; } break; - + case BACKLIGHT_CONTROL_FADE_ON: if (--time_til_fade) return; - + /* The SC606 LED driver can set the brightness in 64 steps */ sc606_write(SC606_REG_A, backlight_current++); @@ -610,11 +616,11 @@ static void led_control_service(void) time_til_fade = fade_interval; } break; - + case BACKLIGHT_CONTROL_FADE_OFF: if (--time_til_fade) return; - + /* The SC606 LED driver can set the brightness in 64 steps */ sc606_write(SC606_REG_A, --backlight_current); @@ -629,7 +635,7 @@ static void led_control_service(void) { backlight_control = BACKLIGHT_CONTROL_OFF; } - + } else { @@ -638,6 +644,10 @@ static void led_control_service(void) break; } + if(backlight_current) + lcd_enable(true); + else + lcd_enable(false); } @@ -647,18 +657,18 @@ static void led_control_service(void) void __backlight_dim(bool dim_now) { unsigned short target; - + /* dont let the interrupt tick happen */ backlight_control = BACKLIGHT_CONTROL_IDLE; target = (dim_now == true) ? 0 : backlight_brightness; - + /* only try and fade if the target is different */ if (backlight_current != target) { backlight_target = target; - - if (backlight_current > backlight_target) + + if (backlight_current > backlight_target) { time_til_fade = fade_interval = 4; backlight_control = BACKLIGHT_CONTROL_FADE_OFF; @@ -676,7 +686,7 @@ void __backlight_dim(bool dim_now) } } } - + } 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]; unsigned long bg_pattern_blit[4]; volatile bool use_dma_blit = false; -volatile bool lcd_on = true; -volatile bool lcd_poweroff = true; +static volatile bool lcd_on = true; +volatile bool lcd_poweroff = false; /* ** These are imported from lcd-16bit.c */ extern unsigned fg_pattern; extern unsigned bg_pattern; -extern volatile bool lcd_on; +static struct mutex lcd_update_mtx; +static struct mutex lcd_clear_mtx; +static struct mutex lcd_enable_mtx; + + +bool lcd_enabled() +{ + return lcd_on; +} /* LCD init */ void lcd_init_device(void) { + mutex_init(&lcd_update_mtx); + mutex_init(&lcd_clear_mtx); + mutex_init(&lcd_enable_mtx); + memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); - /* Switch from 555I mode to 565 mode */ - LCDCON5 |= 1 << 11; + LCDSADDR1 = 0x18F00000; /* These values are pulled from an F40 */ + LCDSADDR2 = 0x00112C00; /* They should move FRAME to the correct location */ + LCDSADDR3 = 0x000000F0; /* TODO: Move FRAME to where we want it */ + + LCDCON5 |= 1 << 11; /* Switch from 555I mode to 565 mode */ #if !defined(BOOTLOADER) use_dma_blit = true; + lcd_poweroff = true; #endif } @@ -52,15 +68,16 @@ void lcd_update_rect(int x, int y, int width, int height) if(!lcd_on) { - for(x=0; x < 2; x++) - yield(); + sleep(200); return; } if (use_dma_blit) { +// mutex_lock(&lcd_update_mtx); + /* Wait for this controller to stop pending transfer */ while((DSTAT1 & 0x000fffff)) - yield(); + CLKCON |= (1 << 2); /* set IDLE bit */ /* Flush DCache */ 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) /* Wait for transfer to complete */ while((DSTAT1 & 0x000fffff)) - yield(); + CLKCON |= (1 << 2); /* set IDLE bit */ +// mutex_unlock(&lcd_update_mtx); } else 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) void lcd_enable(bool state) { + if(!lcd_poweroff) + return; + mutex_lock(&lcd_enable_mtx); if(state) { - if(lcd_poweroff && !lcd_on) { - memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); + if(!lcd_on) { lcd_on = true; + memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); LCDCON1 |= 1; } } else { - if(lcd_poweroff && lcd_on) { + if(lcd_on) { lcd_on = false; LCDCON1 &= ~1; } } + mutex_unlock(&lcd_enable_mtx); } void lcd_set_foreground(unsigned color) @@ -115,19 +137,19 @@ void lcd_set_foreground(unsigned color) fg_pattern = color; memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); - clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); + invalidate_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); } void lcd_set_background(unsigned color) { bg_pattern = color; memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); - clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); + invalidate_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); } void lcd_device_prepare_backdrop(fb_data* backdrop) { - clean_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); + invalidate_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); } void lcd_clear_display_dma(void) @@ -136,10 +158,8 @@ void lcd_clear_display_dma(void) bool inc = false; if(!lcd_on) { - yield(); - yield(); + sleep(200); } - if (lcd_get_drawmode() & DRMODE_INVERSEVID) src = fg_pattern_blit; else @@ -154,9 +174,10 @@ void lcd_clear_display_dma(void) inc = true; } } +// mutex_lock(&lcd_clear_mtx); /* Wait for any pending transfer to complete */ while((DSTAT3 & 0x000fffff)) - yield(); + CLKCON |= (1 << 2); /* set IDLE bit */ DMASKTRIG3 |= 0x4; /* Stop controller */ DIDST3 = ((int) lcd_framebuffer) + 0x30000000; /* set DMA dest, physical address */ DIDSTC3 = 0; /* Dest on AHB, increment */ @@ -165,10 +186,10 @@ void lcd_clear_display_dma(void) DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */ /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */ - DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH) >> 4); + DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | (sizeof(lcd_framebuffer) >> 4); /* Dump DCache for dest, we are about to overwrite it with DMA */ - dump_dcache_range((void *)lcd_framebuffer, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); + invalidate_dcache_range((void *)lcd_framebuffer, sizeof(lcd_framebuffer)); /* Activate the channel */ DMASKTRIG3 = 2; /* Start DMA */ @@ -176,11 +197,14 @@ void lcd_clear_display_dma(void) /* Wait for transfer to complete */ while((DSTAT3 & 0x000fffff)) - yield(); + CLKCON |= (1 << 2); /* set IDLE bit */ +// mutex_unlock(&lcd_update_mtx); } void lcd_clear_display(void) { + lcd_stop_scroll(); + if(use_dma_blit) { lcd_clear_display_dma(); @@ -201,7 +225,6 @@ void lcd_clear_display(void) else memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); } - lcd_stop_scroll(); } -- cgit v1.2.3