diff --git a/apps/lang/deutsch.lang b/apps/lang/deutsch.lang index c721c3cf96..4fbee51013 100644 --- a/apps/lang/deutsch.lang +++ b/apps/lang/deutsch.lang @@ -3099,3 +3099,15 @@ desc: in playback settings eng: "Crossfade" voice: "Überblenden" new: "Überblenden" + +id: LANG_BACKLIGHT_FADE_IN +desc: in settings_menu +eng: "Backlight fade in" +voice: "Beleuchtung einblenden" +new: "Beleuchtung einblenden" + +id: LANG_BACKLIGHT_FADE_OUT +desc: in settings_menu +eng: "Backlight fade out" +voice: "Beleuchtung ausblenden" +new: "Beleuchtung ausblenden" diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 2c54a9c77b..4549d6c041 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -3093,3 +3093,15 @@ desc: in playback settings eng: "Crossfade" voice: "Crossfade" new: + +id: LANG_BACKLIGHT_FADE_IN +desc: in settings_menu +eng: "Backlight fade in" +voice: "Backlight fade in" +new: + +id: LANG_BACKLIGHT_FADE_OUT +desc: in settings_menu +eng: "Backlight fade out" +voice: "Backlight fade out" +new: diff --git a/apps/plugin.c b/apps/plugin.c index a44482d411..726a518508 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -547,6 +547,8 @@ int plugin_register_timer(int cycles, int prio, void (*timer_callback)(void)) if (prescale > 8 || cycles == 0 || prio < 1 || prio > 15) return 0; /* error, we can't do such period, bad argument */ + + backlight_allow_timer(false); /* stop backlight from messing with the timer */ #if CONFIG_CPU == SH7034 and_b(~0x10, &TSTR); /* Stop the timer 4 */ and_b(~0x10, &TSNC); /* No synchronization */ @@ -575,6 +577,7 @@ void plugin_unregister_timer(void) IPRD = (IPRD & 0xFF0F); /* disable interrupt */ pfn_timer = NULL; #endif + backlight_allow_timer(true); } #if CONFIG_CPU == SH7034 diff --git a/apps/settings.c b/apps/settings.c index 6588a6efd5..c462ea0fcc 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -393,7 +393,14 @@ static const struct bit_entry hd_bits[] = #if CONFIG_HWCODEC == MASNONE {1, S_O(crossfade), false, "crossfade", off_on}, #endif - + +#if CONFIG_BACKLIGHT == BL_IRIVER + /* backlight fading */ + {2, S_O(backlight_fade_in), 1, "backlight fade in", "off,500ms,1s,2s"}, + {3, S_O(backlight_fade_out), 3, "backlight fade out", + "off,500ms,1s,2s,3s,4s,5s,10s"}, +#endif + /* new stuff to be added at the end */ /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */ @@ -765,6 +772,10 @@ void settings_apply(void) #endif backlight_set_timeout(global_settings.backlight_timeout); backlight_set_on_when_charging(global_settings.backlight_on_when_charging); +#if CONFIG_BACKLIGHT == BL_IRIVER + backlight_set_fade_in(global_settings.backlight_fade_in); + backlight_set_fade_out(global_settings.backlight_fade_out); +#endif ata_spindown(global_settings.disk_spindown); #if CONFIG_HWCODEC == MAS3507D dac_line_in(global_settings.line_in); diff --git a/apps/settings.h b/apps/settings.h index 2d4017c9e3..7e0be44c41 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -202,6 +202,10 @@ struct user_settings 1=always, then according to timeout_values[] */ bool backlight_on_when_charging; +#if CONFIG_BACKLIGHT == BL_IRIVER + int backlight_fade_in; /* backlight fade in timing: 0..3 */ + int backlight_fade_out; /* backlight fade in timing: 0..7 */ +#endif int battery_capacity; /* in mAh */ int battery_type; /* for units which can take multiple types (Ondio). */ diff --git a/apps/settings_menu.c b/apps/settings_menu.c index d8f440c25c..efca1a85fb 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -75,12 +75,12 @@ static bool car_adapter_mode(void) } #endif -static bool contrast(void) +/** + * Menu to set icon visibility + */ +static bool show_icons(void) { - return set_int( str(LANG_CONTRAST), "", UNIT_INT, - &global_settings.contrast, - lcd_set_contrast, 1, MIN_CONTRAST_SETTING, - MAX_CONTRAST_SETTING ); + return set_bool( str(LANG_SHOW_ICONS), &global_settings.show_icons ); } #ifdef HAVE_REMOTE_LCD @@ -122,14 +122,114 @@ static bool caption_backlight(void) return rc; } + +#ifdef HAVE_CHARGING +static bool backlight_on_when_charging(void) +{ + bool result = set_bool(str(LANG_BACKLIGHT_ON_WHEN_CHARGING), + &global_settings.backlight_on_when_charging); + backlight_set_on_when_charging(global_settings.backlight_on_when_charging); + return result; +} #endif -/** - * Menu to set icon visibility - */ -static bool show_icons(void) +static bool backlight_timer(void) { - return set_bool( str(LANG_SHOW_ICONS), &global_settings.show_icons ); + static const struct opt_items names[] = { + { STR(LANG_OFF) }, + { STR(LANG_ON) }, + { "1s ", TALK_ID(1, UNIT_SEC) }, + { "2s ", TALK_ID(2, UNIT_SEC) }, + { "3s ", TALK_ID(3, UNIT_SEC) }, + { "4s ", TALK_ID(4, UNIT_SEC) }, + { "5s ", TALK_ID(5, UNIT_SEC) }, + { "6s ", TALK_ID(6, UNIT_SEC) }, + { "7s ", TALK_ID(7, UNIT_SEC) }, + { "8s ", TALK_ID(8, UNIT_SEC) }, + { "9s ", TALK_ID(9, UNIT_SEC) }, + { "10s", TALK_ID(10, UNIT_SEC) }, + { "15s", TALK_ID(15, UNIT_SEC) }, + { "20s", TALK_ID(20, UNIT_SEC) }, + { "25s", TALK_ID(25, UNIT_SEC) }, + { "30s", TALK_ID(30, UNIT_SEC) }, + { "45s", TALK_ID(45, UNIT_SEC) }, + { "60s", TALK_ID(60, UNIT_SEC) }, + { "90s", TALK_ID(90, UNIT_SEC) } + }; + return set_option(str(LANG_BACKLIGHT), &global_settings.backlight_timeout, + INT, names, 19, backlight_set_timeout ); +} + +#if CONFIG_BACKLIGHT == BL_IRIVER +static bool backlight_fade_in(void) +{ + static const struct opt_items names[] = { + { STR(LANG_OFF) }, + { "500ms", TALK_ID(500, UNIT_MS) }, + { "1s", TALK_ID(1, UNIT_SEC) }, + { "2s", TALK_ID(2, UNIT_SEC) }, + }; + return set_option(str(LANG_BACKLIGHT_FADE_IN), + &global_settings.backlight_fade_in, + INT, names, 4, backlight_set_fade_in ); +} + +static bool backlight_fade_out(void) +{ + static const struct opt_items names[] = { + { STR(LANG_OFF) }, + { "500ms", TALK_ID(500, UNIT_MS) }, + { "1s", TALK_ID(1, UNIT_SEC) }, + { "2s", TALK_ID(2, UNIT_SEC) }, + { "3s", TALK_ID(3, UNIT_SEC) }, + { "4s", TALK_ID(4, UNIT_SEC) }, + { "5s", TALK_ID(5, UNIT_SEC) }, + { "10s", TALK_ID(10, UNIT_SEC) }, + }; + return set_option(str(LANG_BACKLIGHT_FADE_OUT), + &global_settings.backlight_fade_out, + INT, names, 8, backlight_set_fade_out ); +} +#endif +#endif /* CONFIG_BACKLIGHT */ + +#ifdef HAVE_REMOTE_LCD + +static bool remote_backlight_timer(void) +{ + static const struct opt_items names[] = { + { STR(LANG_OFF) }, + { STR(LANG_ON) }, + { "1s ", TALK_ID(1, UNIT_SEC) }, + { "2s ", TALK_ID(2, UNIT_SEC) }, + { "3s ", TALK_ID(3, UNIT_SEC) }, + { "4s ", TALK_ID(4, UNIT_SEC) }, + { "5s ", TALK_ID(5, UNIT_SEC) }, + { "6s ", TALK_ID(6, UNIT_SEC) }, + { "7s ", TALK_ID(7, UNIT_SEC) }, + { "8s ", TALK_ID(8, UNIT_SEC) }, + { "9s ", TALK_ID(9, UNIT_SEC) }, + { "10s", TALK_ID(10, UNIT_SEC) }, + { "15s", TALK_ID(15, UNIT_SEC) }, + { "20s", TALK_ID(20, UNIT_SEC) }, + { "25s", TALK_ID(25, UNIT_SEC) }, + { "30s", TALK_ID(30, UNIT_SEC) }, + { "45s", TALK_ID(45, UNIT_SEC) }, + { "60s", TALK_ID(60, UNIT_SEC) }, + { "90s", TALK_ID(90, UNIT_SEC) } + }; + return set_option(str(LANG_BACKLIGHT), &global_settings.remote_backlight_timeout, + INT, names, 19, remote_backlight_set_timeout ); +} + +#endif /* HAVE_REMOTE_LCD */ + +static bool contrast(void) +{ + return set_int( str(LANG_CONTRAST), "", UNIT_INT, + &global_settings.contrast, + lcd_set_contrast, 1, MIN_CONTRAST_SETTING, + MAX_CONTRAST_SETTING ); } #ifdef HAVE_LCD_BITMAP @@ -147,6 +247,20 @@ static bool invert(void) return rc; } +/** + * Menu to turn the display+buttons by 180 degrees + */ +static bool flip_display(void) +{ + bool rc = set_bool( str(LANG_FLIP_DISPLAY), + &global_settings.flip_display); + + button_set_flip(global_settings.flip_display); + lcd_set_flip(global_settings.flip_display); + + return rc; +} + /** * Menu to set Line Selector Type (Pointer/Bar) */ @@ -159,20 +273,6 @@ static bool invert_cursor(void) NULL); } -/** - * Menu to turn the display+buttons by 180 degrees - */ -static bool flip_display(void) -{ - bool rc = set_bool( str(LANG_FLIP_DISPLAY), - &global_settings.flip_display); - - button_set_flip(global_settings.flip_display); - lcd_set_flip(global_settings.flip_display); - - return rc; -} - /** * Menu to configure the battery display on status bar */ @@ -613,76 +713,6 @@ static bool useMRB(void) names, 3, NULL ); } -#ifdef CONFIG_BACKLIGHT -#ifdef HAVE_CHARGING -static bool backlight_on_when_charging(void) -{ - bool result = set_bool(str(LANG_BACKLIGHT_ON_WHEN_CHARGING), - &global_settings.backlight_on_when_charging); - backlight_set_on_when_charging(global_settings.backlight_on_when_charging); - return result; -} -#endif - -static bool backlight_timer(void) -{ - static const struct opt_items names[] = { - { STR(LANG_OFF) }, - { STR(LANG_ON) }, - { "1s ", TALK_ID(1, UNIT_SEC) }, - { "2s ", TALK_ID(2, UNIT_SEC) }, - { "3s ", TALK_ID(3, UNIT_SEC) }, - { "4s ", TALK_ID(4, UNIT_SEC) }, - { "5s ", TALK_ID(5, UNIT_SEC) }, - { "6s ", TALK_ID(6, UNIT_SEC) }, - { "7s ", TALK_ID(7, UNIT_SEC) }, - { "8s ", TALK_ID(8, UNIT_SEC) }, - { "9s ", TALK_ID(9, UNIT_SEC) }, - { "10s", TALK_ID(10, UNIT_SEC) }, - { "15s", TALK_ID(15, UNIT_SEC) }, - { "20s", TALK_ID(20, UNIT_SEC) }, - { "25s", TALK_ID(25, UNIT_SEC) }, - { "30s", TALK_ID(30, UNIT_SEC) }, - { "45s", TALK_ID(45, UNIT_SEC) }, - { "60s", TALK_ID(60, UNIT_SEC) }, - { "90s", TALK_ID(90, UNIT_SEC) } - }; - return set_option(str(LANG_BACKLIGHT), &global_settings.backlight_timeout, - INT, names, 19, backlight_set_timeout ); -} -#endif /* CONFIG_BACKLIGHT */ - -#ifdef HAVE_REMOTE_LCD - -static bool remote_backlight_timer(void) -{ - static const struct opt_items names[] = { - { STR(LANG_OFF) }, - { STR(LANG_ON) }, - { "1s ", TALK_ID(1, UNIT_SEC) }, - { "2s ", TALK_ID(2, UNIT_SEC) }, - { "3s ", TALK_ID(3, UNIT_SEC) }, - { "4s ", TALK_ID(4, UNIT_SEC) }, - { "5s ", TALK_ID(5, UNIT_SEC) }, - { "6s ", TALK_ID(6, UNIT_SEC) }, - { "7s ", TALK_ID(7, UNIT_SEC) }, - { "8s ", TALK_ID(8, UNIT_SEC) }, - { "9s ", TALK_ID(9, UNIT_SEC) }, - { "10s", TALK_ID(10, UNIT_SEC) }, - { "15s", TALK_ID(15, UNIT_SEC) }, - { "20s", TALK_ID(20, UNIT_SEC) }, - { "25s", TALK_ID(25, UNIT_SEC) }, - { "30s", TALK_ID(30, UNIT_SEC) }, - { "45s", TALK_ID(45, UNIT_SEC) }, - { "60s", TALK_ID(60, UNIT_SEC) }, - { "90s", TALK_ID(90, UNIT_SEC) } - }; - return set_option(str(LANG_BACKLIGHT), &global_settings.remote_backlight_timeout, - INT, names, 19, remote_backlight_set_timeout ); -} - -#endif /* HAVE_REMOTE_LCD */ - static bool poweroff_idle_timer(void) { static const struct opt_items names[] = { @@ -1247,6 +1277,10 @@ static bool lcd_settings_menu(void) { ID2P(LANG_BACKLIGHT_ON_WHEN_CHARGING), backlight_on_when_charging }, #endif { ID2P(LANG_CAPTION_BACKLIGHT), caption_backlight }, +#if CONFIG_BACKLIGHT == BL_IRIVER + { ID2P(LANG_BACKLIGHT_FADE_IN), backlight_fade_in }, + { ID2P(LANG_BACKLIGHT_FADE_OUT), backlight_fade_out }, +#endif #endif /* CONFIG_BACKLIGHT */ { ID2P(LANG_CONTRAST), contrast }, #ifdef HAVE_LCD_BITMAP diff --git a/firmware/backlight.c b/firmware/backlight.c index 699b3bffa5..e169209717 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c @@ -60,34 +60,20 @@ static unsigned int remote_backlight_timeout = 5; #endif #if CONFIG_BACKLIGHT == BL_IRIVER +/* backlight fading */ +#define BL_PWM_INTERVAL 5000 /* Cycle interval in µs */ #define BL_PWM_COUNT 100 -/* Cycle interval in ms */ -#define BL_PWM_INTERVAL 5000 -#define BL_DIM_SPEED 4 -#define __backlight_on __backlight_fade_in -#define __backlight_off __backlight_fade_out - -#define DIM_STATE_START 0 -#define DIM_STATE_MAIN 1 -#define DIM_STATE_REMOTE 2 +static const char backlight_fade_value[8] = { 0, 1, 2, 4, 6, 8, 10, 20 }; +static int fade_in_count = 1; +static int fade_out_count = 4; +static bool timer_allowed = true; static bool bl_timer_active = false; static int bl_dim_current = BL_PWM_COUNT; static int bl_dim_target = BL_PWM_COUNT; static int bl_pwm_counter = 0; static volatile int bl_cycle_counter = 0; - -/* Unfortunately we can't dim H1xx remote lcd :/ */ -#ifdef HAVE_REMOTE_LCD_DIMMABLE -#define lcd_remote_backlight_on __backlight_fade_remote_in -#define lcd_remote_backlight_off __backlight_fade_remote_out -static int bl_dim_remote_current = BL_PWM_COUNT; -static int bl_dim_remote_target = BL_PWM_COUNT; -static int bl_pwm_remote_counter = 0; -static bool bl_dim_next_interval; -#endif - -static int bl_dim_state = 0; +static enum {DIM_STATE_START, DIM_STATE_MAIN} bl_dim_state = DIM_STATE_START; void backlight_start_timer(void) { @@ -116,123 +102,60 @@ void TIMER1(void) { int timer_period; bool idle = false; -#ifdef HAVE_REMOTE_LCD_DIMMABLE - int new_timer_period; -#endif - timer_period = FREQ/20000 * BL_PWM_INTERVAL / 100 / 32; + timer_period = FREQ / 2000 * BL_PWM_INTERVAL / 1000 / 32; switch (bl_dim_state) { - /* New cycle */ - case DIM_STATE_START: + /* New cycle */ + case DIM_STATE_START: bl_pwm_counter = 0; bl_cycle_counter++; - if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT) { + if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT) + { GPIO1_OUT &= ~0x00020000; bl_pwm_counter = bl_dim_current; timer_period = timer_period * bl_pwm_counter / BL_PWM_COUNT; bl_dim_state = DIM_STATE_MAIN; - } else { - idle = true; + } + else + { if (bl_dim_current) GPIO1_OUT &= ~0x00020000; else GPIO1_OUT |= 0x00020000; + if (bl_dim_current == bl_dim_target) + idle = true; } -#ifdef HAVE_REMOTE_LCD_DIMMABLE - bl_dim_next_interval = 0; - bl_pwm_remote_counter = 0; - if (bl_dim_remote_current > 0 && - bl_dim_remote_current < BL_PWM_COUNT) { - idle = false; - GPIO_OUT &= ~0x00000800; - bl_pwm_remote_counter = bl_dim_remote_current; - if (bl_dim_state == DIM_STATE_START) { - timer_period = timer_period * bl_pwm_remote_counter - / BL_PWM_COUNT; - bl_dim_state = DIM_STATE_REMOTE; - break ; - } - - new_timer_period = timer_period * bl_pwm_remote_counter - / BL_PWM_COUNT; - if (new_timer_period < timer_period) { - bl_dim_next_interval = timer_period - new_timer_period; - timer_period = new_timer_period; - bl_dim_state = DIM_STATE_REMOTE; - } else { - bl_dim_next_interval = new_timer_period - timer_period; - } - } else { - if (bl_dim_remote_current) - GPIO_OUT &= ~0x00000800; - else - GPIO_OUT |= 0x00000800; - } -#endif break ; - /* Dim main screen */ - case DIM_STATE_MAIN: + /* Dim main screen */ + case DIM_STATE_MAIN: GPIO1_OUT |= 0x00020000; -#ifdef HAVE_REMOTE_LCD_DIMMABLE - if (bl_dim_next_interval) { - timer_period = bl_dim_next_interval; - bl_dim_next_interval = 0; - bl_dim_state = DIM_STATE_REMOTE; - break ; - } -#endif bl_dim_state = DIM_STATE_START; timer_period = timer_period * (BL_PWM_COUNT - bl_pwm_counter) / BL_PWM_COUNT; break ; -#ifdef HAVE_REMOTE_LCD_DIMMABLE - /* Dim remote lcd */ - case DIM_STATE_REMOTE: - GPIO_OUT |= 0x00000800; - if (bl_dim_next_interval) { - timer_period = bl_dim_next_interval; - bl_dim_next_interval = 0; - bl_dim_state = DIM_STATE_MAIN; - break ; - } - - bl_dim_state = DIM_STATE_START; - timer_period = timer_period * (BL_PWM_COUNT - bl_pwm_remote_counter) / BL_PWM_COUNT; - break ; -#endif } - if (bl_cycle_counter >= BL_DIM_SPEED) { - if (bl_dim_target > bl_dim_current) { - bl_dim_current++; - idle = false; - } - else if (bl_dim_target < bl_dim_current) { - bl_dim_current--; - idle = false; - } -#ifdef HAVE_REMOTE_LCD_DIMMABLE - if (bl_dim_remote_target > bl_dim_remote_current) { - bl_dim_remote_current++; - idle = false; - } - else if (bl_dim_remote_target < bl_dim_remote_current) { - bl_dim_remote_current--; - idle = false; - } -#endif + if ((bl_dim_target > bl_dim_current) && (bl_cycle_counter >= fade_in_count)) + { + bl_dim_current++; bl_cycle_counter = 0; - - /* Save CPU & battery when idle, stop timer */ - if (idle) { - bl_timer_active = false; - TMR1 = 0; - } } - + + if ((bl_dim_target < bl_dim_current) && (bl_cycle_counter >= fade_out_count)) + { + bl_dim_current--; + bl_cycle_counter = 0; + } + + if (idle) + { + bl_timer_active = false; + TMR1 = 0; + } + TRR1 = timer_period; TCN1 = 0; TER1 = 0xff; /* Clear all events */ @@ -244,38 +167,44 @@ static void __backlight_dim(int value) backlight_start_timer(); } -static void __backlight_fade_in(void) +void backlight_allow_timer(bool on) { - __backlight_dim(BL_PWM_COUNT); + timer_allowed = on; + + if (!timer_allowed && bl_timer_active) + { + bl_dim_current = bl_dim_target; + bl_timer_active = false; + TMR1 = 0; + + if (bl_dim_current) + GPIO1_OUT &= ~0x00020000; + else + GPIO1_OUT |= 0x00020000; + } } -static void __backlight_fade_out(void) +void backlight_set_fade_in(int index) { - __backlight_dim(0); + fade_in_count = backlight_fade_value[index]; } -#ifdef HAVE_REMOTE_LCD_DIMMABLE -static void __backlight_dim_remote(int value) +void backlight_set_fade_out(int index) { - bl_dim_remote_target = value; -} - -static void __backlight_fade_remote_in(void) -{ - __backlight_dim_remote(BL_PWM_COUNT); -} - -static void __backlight_fade_remote_out(void) -{ - __backlight_dim_remote(0); + fade_out_count = backlight_fade_value[index]; } #endif -#else static void __backlight_off(void) { #if CONFIG_BACKLIGHT == BL_IRIVER - GPIO1_OUT |= 0x00020000; + if (timer_allowed && (fade_out_count > 0)) + __backlight_dim(0); + else + { + bl_dim_target = bl_dim_current = 0; + GPIO1_OUT |= 0x00020000; + } #elif CONFIG_BACKLIGHT == BL_RTC /* Disable square wave */ rtc_write(0x0a, rtc_read(0x0a) & ~0x40); @@ -291,7 +220,13 @@ static void __backlight_off(void) static void __backlight_on(void) { #if CONFIG_BACKLIGHT == BL_IRIVER - GPIO1_OUT &= ~0x00020000; + if (timer_allowed && (fade_in_count > 0)) + __backlight_dim(BL_PWM_COUNT); + else + { + bl_dim_target = bl_dim_current = BL_PWM_COUNT; + GPIO1_OUT &= ~0x00020000; + } #elif CONFIG_BACKLIGHT == BL_RTC /* Enable square wave */ rtc_write(0x0a, rtc_read(0x0a) | 0x40); @@ -304,7 +239,6 @@ static void __backlight_on(void) P1 |= 0x10; #endif } -#endif void backlight_thread(void) { diff --git a/firmware/export/backlight.h b/firmware/export/backlight.h index ab1f9059b2..8d1b56c695 100644 --- a/firmware/export/backlight.h +++ b/firmware/export/backlight.h @@ -27,6 +27,13 @@ void backlight_off(void); void backlight_tick(void); int backlight_get_timeout(void); void backlight_set_timeout(int index); +#if CONFIG_BACKLIGHT == BL_IRIVER +void backlight_set_fade_in(int index); +void backlight_set_fade_out(int index); +void backlight_allow_timer(bool on); +#else +#define backlight_allow_timer(on) +#endif bool backlight_get_on_when_charging(void); void backlight_set_on_when_charging(bool yesno); void remote_backlight_on(void);