Index: firmware/export/config-c200.h =================================================================== --- firmware/export/config-c200.h (Revision 19036) +++ firmware/export/config-c200.h (Arbeitskopie) @@ -32,6 +32,9 @@ /* define this if you have a light associated with the buttons */ #define HAVE_BUTTON_LIGHT +/* define this if the backlight thread is used for fade */ +#define HAVE_BACKLIGHT_THREAD_FADING + /* define this if you have access to the quickscreen */ #define HAVE_QUICKSCREEN Index: firmware/export/config-e200.h =================================================================== --- firmware/export/config-e200.h (Revision 19036) +++ firmware/export/config-e200.h (Arbeitskopie) @@ -32,6 +32,9 @@ /* define this if you have a light associated with the buttons */ #define HAVE_BUTTON_LIGHT +/* define this if the backlight thread is used for fade */ +#define HAVE_BACKLIGHT_THREAD_FADING + /* define this if you have access to the quickscreen */ #define HAVE_QUICKSCREEN Index: firmware/export/config-gigabeat-s.h =================================================================== --- firmware/export/config-gigabeat-s.h (Revision 19036) +++ firmware/export/config-gigabeat-s.h (Arbeitskopie) @@ -77,10 +77,11 @@ #ifndef BOOTLOADER /* Not for bootloader */ -#define HAVE_LCD_ENABLE +//#define HAVE_LCD_ENABLE #define HAVE_BACKLIGHT_BRIGHTNESS +#define HAVE_BACKLIGHT_THREAD_FADING /* Main LCD backlight brightness range and defaults */ #define MIN_BRIGHTNESS_SETTING 0 #define MAX_BRIGHTNESS_SETTING 24 Index: firmware/backlight.c =================================================================== --- firmware/backlight.c (Revision 19036) +++ firmware/backlight.c (Arbeitskopie) @@ -114,6 +114,9 @@ #ifdef BACKLIGHT_DRIVER_CLOSE BACKLIGHT_QUIT, #endif +#if defined(HAVE_BACKLIGHT_THREAD_FADING) && !defined(SIMULATOR) + BACKLIGHT_FADE, +#endif }; static void backlight_thread(void); @@ -397,6 +400,38 @@ } #endif /* defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR) */ +#if defined(HAVE_BACKLIGHT_THREAD_FADING) && !defined(SIMULATOR) +static enum { + NOT_FADING = 0, + FADING_UP, + FADING_DOWN, +} backlight_fading_state = NOT_FADING; + +static unsigned int backlight_fade_counter = 0; + +static void _backlight_on(void) +{ +#ifdef HAVE_LCD_SLEEP + backlight_lcd_sleep_countdown(false); +#endif + if (backlight_fading_state == NOT_FADING) + { +#ifdef HAVE_LCD_ENABLE + lcd_enable(true); /* power on lcd, this takes some time */ +#endif + backlight_fade_counter = 0; + } + backlight_fading_state = FADING_UP; +} + +static void _backlight_off(void) +{ + if (backlight_fading_state == NOT_FADING) + backlight_fade_counter = 0; + backlight_fading_state = FADING_DOWN; +} +#endif + /* Update state of backlight according to timeout setting */ static void backlight_update_state(void) { @@ -560,7 +595,20 @@ backlight_timer = 0; /* Disable the timeout */ _backlight_off(); break; - +#if defined(HAVE_BACKLIGHT_THREAD_FADING) && !defined(SIMULATOR) + case BACKLIGHT_FADE: + if (backlight_fading_state == FADING_UP) + { + if (_backlight_fade_up()) + backlight_fading_state = NOT_FADING; + } + else if (backlight_fading_state == FADING_DOWN) + { + if (_backlight_fade_down()) + backlight_fading_state = NOT_FADING; + } + break; +#endif /* defined(HAVE_BACKLIGHT_THREAD_FADING) && !defined(SIMULATOR) */ #ifdef HAVE_LCD_SLEEP case LCD_SLEEP: lcd_sleep(); @@ -614,7 +662,11 @@ } } #endif /* HAVE_LCD_SLEEP */ - +#if defined(HAVE_BACKLIGHT_THREAD_FADING) && !defined(SIMULATOR) + if (backlight_fading_state && (++backlight_fade_counter % + (HZ/25) == 0)) + queue_post(&backlight_queue, BACKLIGHT_FADE, 0); +#endif #ifdef HAVE_REMOTE_LCD if(remote_backlight_timer) { Index: firmware/target/arm/sandisk/backlight-c200_e200.c =================================================================== --- firmware/target/arm/sandisk/backlight-c200_e200.c (Revision 19036) +++ firmware/target/arm/sandisk/backlight-c200_e200.c (Arbeitskopie) @@ -27,36 +27,116 @@ #include "as3514.h" static unsigned short backlight_brightness = DEFAULT_BRIGHTNESS_SETTING; +static unsigned short current_brightness = DEFAULT_BRIGHTNESS_SETTING; +static bool _is_backlight_on = false; -void _backlight_set_brightness(int brightness) -{ - backlight_brightness = brightness; - if (brightness > 0) - _backlight_on(); - else - _backlight_off(); -} +/* _backlight_on / _off is static when HAVE_BACKLIGHT_THREAD_FADING, since + * it'll then only be used with in this file. firmware/backlight.c implements + * his own _backlight_on / _off functions, which call _backlight_fade_up and _down + * from this file + * + * in the case of e200/c200 _backlight_on / _off basically only do lcd_enable + * and have a slightly different purpse, they won't change the backlight + * brightness level, that'll be done in _backlight_set_brightness_helper */ -void _backlight_on(void) +#ifdef HAVE_BACKLIGHT_THREAD_FADING +static +#endif /* HAVE_BACKLIGHT_THREAD_FADING */ + void _backlight_on(void) { + _is_backlight_on = true; + #ifdef HAVE_LCD_SLEEP backlight_lcd_sleep_countdown(false); /* stop counter */ #endif + #ifdef HAVE_LCD_ENABLE lcd_enable(true); /* power on lcd + visible display */ #endif - ascodec_write(AS3514_DCDC15, backlight_brightness); + +#ifndef HAVE_BACKLIGHT_THREAD_FADING + current_brightness = backlight_brightness; + ascodec_write(AS3514_DCDC15, current_brightness); +#endif /* !HAVE_BACKLIGHT_THREAD_FADING */ } -void _backlight_off(void) +#ifdef HAVE_BACKLIGHT_THREAD_FADING +static +#endif /* HAVE_BACKLIGHT_THREAD_FADING */ + void _backlight_off(void) { - ascodec_write(AS3514_DCDC15, 0x0); + _is_backlight_on = false; + + current_brightness = 0; +#ifndef HAVE_BACKLIGHT_THREAD_FADING + ascodec_write(AS3514_DCDC15, current_brightness); +#endif /* !HAVE_BACKLIGHT_THREAD_FADING */ + +#ifdef HAVE_LCD_SLEEP + backlight_lcd_sleep_countdown(true); /* start countdown */ +#endif #ifdef HAVE_LCD_ENABLE lcd_enable(false); /* power off visible display */ #endif -#ifdef HAVE_LCD_SLEEP - backlight_lcd_sleep_countdown(true); /* start countdown */ +} + + +#ifdef HAVE_BACKLIGHT_THREAD_FADING + +static void _backlight_set_brightness_helper(int brightness) +{ + if (brightness <= 0 && _is_backlight_on) + { + ascodec_write(AS3514_DCDC15, 0); + _backlight_off(); + return; + } + else if (!_is_backlight_on) + { + _backlight_on(); + } + ascodec_write(AS3514_DCDC15, brightness); +} + +/* returns true if fade is finished */ +bool _backlight_fade_up(void) +{ + if (current_brightness < backlight_brightness) + { + _backlight_set_brightness_helper(++current_brightness); + } + return (current_brightness >= backlight_brightness); +} + +/* returns true if fade is finished */ +bool _backlight_fade_down(void) +{ + if (current_brightness > 0) + { + _backlight_set_brightness_helper(--current_brightness); + } + else /* current_brightness <= 0 --> fading done */ + { + return true; + } + return false; +} + +#endif /* HAVE_BACKLIGHT_THREAD_FADING */ + +void _backlight_set_brightness(int brightness) +{ + backlight_brightness = brightness; + current_brightness = brightness; + +#ifdef HAVE_BACKLIGHT_THREAD_FADING + _backlight_set_brightness_helper(brightness); +#else + if (brightness > 0) + _backlight_on(); + else + _backlight_off(); #endif } Index: firmware/target/arm/sandisk/backlight-target.h =================================================================== --- firmware/target/arm/sandisk/backlight-target.h (Revision 19036) +++ firmware/target/arm/sandisk/backlight-target.h (Arbeitskopie) @@ -20,13 +20,21 @@ ****************************************************************************/ #ifndef BACKLIGHT_TARGET_H #define BACKLIGHT_TARGET_H +#include "stdbool.h" #define _backlight_init() true + +#ifndef HAVE_BACKLIGHT_THREAD_FADING void _backlight_on(void); void _backlight_off(void); +#else +/* these both return true if the fade is finished */ +bool _backlight_fade_up(void); +bool _backlight_fade_down(void); +#endif void _backlight_set_brightness(int brightness); -int __backlight_is_on(void); + void _buttonlight_on(void); void _buttonlight_off(void); #endif Index: firmware/target/arm/imx31/gigabeat-s/backlight-target.h =================================================================== --- firmware/target/arm/imx31/gigabeat-s/backlight-target.h (Revision 19036) +++ firmware/target/arm/imx31/gigabeat-s/backlight-target.h (Arbeitskopie) @@ -21,6 +21,8 @@ #ifndef BACKLIGHT_TARGET_H #define BACKLIGHT_TARGET_H +#include "stdbool.h" + #ifdef BOOTLOADER #define BACKLIGHT_DRIVER_CLOSE /* Force the whole driver to be built */ @@ -28,8 +30,14 @@ #endif bool _backlight_init(void); +#ifndef HAVE_BACKLIGHT_THREAD_FADING void _backlight_on(void); void _backlight_off(void); +#else +/* these both return true if the fade is finished */ +bool _backlight_fade_up(void); +bool _backlight_fade_down(void); +#endif void _backlight_set_brightness(int brightness); #endif /* BACKLIGHT_TARGET_H */ Index: firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c =================================================================== --- firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c (Revision 19036) +++ firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c (Arbeitskopie) @@ -20,11 +20,16 @@ ****************************************************************************/ #include "config.h" #include "system.h" +#include "lcd.h" #include "backlight.h" #include "mc13783.h" #include "backlight-target.h" #ifdef HAVE_BACKLIGHT_BRIGHTNESS +static unsigned short backlight_brightness = DEFAULT_BRIGHTNESS_SETTING; +static unsigned short current_brightness = DEFAULT_BRIGHTNESS_SETTING; +static bool _is_backlight_on = true; +static void _backlight_set_brightness_helper(int brightness); /* Table that uses combinations of current level and pwm fraction to get * as many uniquely-visible brightness levels as possible. The lowest current * level for any average current is used even though many combinations give @@ -39,28 +44,28 @@ { 0, 0 }, /* 0 0 0.0 */ { 1, 1 }, /* 3 1 0.2 */ { 1, 2 }, /* 3 2 0.4 */ - { 1, 3 }, /* 3 3 0.6 */ - { 1, 4 }, /* 3 4 0.8 */ - { 1, 5 }, /* 3 5 1.0 */ - { 1, 6 }, /* 3 6 1.2 */ - { 1, 7 }, /* 3 7 1.4 */ - { 1, 8 }, /* 3 8 1.6 */ - { 1, 9 }, /* 3 9 1.8 */ - { 1, 10 }, /* 3 10 2.0 */ - { 1, 11 }, /* 3 11 2.2 */ + { 1, 3 }, /* 3 3 0.6 */ + { 1, 4 }, /* 3 4 0.8 */ + { 1, 5 }, /* 3 5 1.0 */ + { 1, 6 }, /* 3 6 1.2 */ + { 1, 7 }, /* 3 7 1.4 */ + { 1, 8 }, /* 3 8 1.6 */ + { 1, 9 }, /* 3 9 1.8 */ + { 1, 10 }, /* 3 10 2.0 */ + { 1, 11 }, /* 3 11 2.2 */ { 1, 12 }, /* 3 12 2.4 */ /* default */ - { 1, 13 }, /* 3 13 2.6 */ - { 1, 14 }, /* 3 14 2.8 */ - { 1, 15 }, /* 3 15 3.0 */ - { 2, 9 }, /* 6 9 3.6 */ - { 2, 10 }, /* 6 10 4.0 */ - { 2, 11 }, /* 6 11 4.4 */ - { 2, 12 }, /* 6 12 4.8 */ - { 2, 13 }, /* 6 13 5.2 */ - { 2, 14 }, /* 6 14 5.6 */ - { 2, 15 }, /* 6 15 6.0 */ - { 3, 11 }, /* 9 11 6.6 */ - { 3, 12 }, /* 9 12 7.2 */ + { 1, 13 }, /* 3 13 2.6 */ + { 1, 14 }, /* 3 14 2.8 */ + { 1, 15 }, /* 3 15 3.0 */ + { 2, 9 }, /* 6 9 3.6 */ + { 2, 10 }, /* 6 10 4.0 */ + { 2, 11 }, /* 6 11 4.4 */ + { 2, 12 }, /* 6 12 4.8 */ + { 2, 13 }, /* 6 13 5.2 */ + { 2, 14 }, /* 6 14 5.6 */ + { 2, 15 }, /* 6 15 6.0 */ + { 3, 11 }, /* 9 11 6.6 */ + { 3, 12 }, /* 9 12 7.2 */ /* Anything higher is just too much */ }; #endif /* HAVE_BACKLIGHT_BRIGHTNESS */ @@ -69,32 +74,97 @@ { mc13783_write(MC13783_LED_CONTROL0, MC13783_LEDEN | +#ifndef HAVE_BACKLIGHT_THREAD_FADING +/* disable hw backlight fading when using "software" fade */ MC13783_LEDMDRAMPUP | MC13783_LEDMDRAMPDOWN | +#endif MC13783_BOOSTEN | MC13783_ABMODE_MONCH_LEDMD1234 | MC13783_ABREF_400MV); return true; } -void _backlight_on(void) +/* _backlight_on / _off is static when HAVE_BACKLIGHT_THREAD_FADING, since + * it'll then only be used with in this file. firmware/backlight.c implements + * his own _backlight_on / _off functions, which call _backlight_fade_up and _down + * from this file */ + +#ifdef HAVE_BACKLIGHT_THREAD_FADING +static +#endif + void _backlight_on(void) { +#ifdef HAVE_LCD_SLEEP + backlight_lcd_sleep_countdown(false); /* stop counter */ +#endif +#ifdef HAVE_LCD_ENABLE + lcd_enable(true) +#endif /* LEDEN=1 */ mc13783_set(MC13783_LED_CONTROL0, MC13783_LEDEN); + _is_backlight_on = true; } -void _backlight_off(void) +#ifdef HAVE_BACKLIGHT_THREAD_FADING +static +#endif + void _backlight_off(void) { + current_brightness = 0; /* LEDEN=0 */ mc13783_clear(MC13783_LED_CONTROL0, MC13783_LEDEN); +#ifdef HAVE_LCD_ENABLE + lcd_enable(true) +#endif +#ifdef HAVE_LCD_SLEEP + backlight_lcd_sleep_countdown(true); /* start countdown */ +#endif + _is_backlight_on = false; } +#ifdef HAVE_BACKLIGHT_THREAD_FADING +/* returns true if fade is finished */ +bool _backlight_fade_up(void) +{ + if (current_brightness < backlight_brightness) + { + _backlight_set_brightness_helper(++current_brightness); + } + return (current_brightness >= backlight_brightness); +} -#ifdef HAVE_BACKLIGHT_BRIGHTNESS +/* returns true if fade is finished */ +bool _backlight_fade_down(void) +{ + if (current_brightness > 0) + { + _backlight_set_brightness_helper(--current_brightness); + } + else /* current_brightness <= 0 --> fading done */ + { + return true; + } + return false; +} +#endif /* HAVE_BACKLIGHT_THREAD_FADING */ /* Assumes that the backlight has been initialized */ + void _backlight_set_brightness(int brightness) { + backlight_brightness = brightness; + current_brightness = brightness; + + _backlight_set_brightness_helper(brightness); +} + +static void _backlight_set_brightness_helper(int brightness) +{ + if (!_is_backlight_on && brightness > 0) + _backlight_on(); + uint32_t data, md, pwm; + /* invalid brightness, restore default */ if ((unsigned)brightness >= ARRAYLEN(led_md_pwm_table)) brightness = DEFAULT_BRIGHTNESS_SETTING; @@ -110,5 +180,7 @@ data |= MC13783_LEDMDw(md) | MC13783_LEDMDDCw(pwm); mc13783_write(MC13783_LED_CONTROL2, data); + + if (brightness <= 0 && _is_backlight_on) + _backlight_off(); } -#endif /* HAVE_BACKLIGHT_BRIGHTNESS */