From 2bfd2585a9cfb8541047a3f5eedbfd05fe36f9f9 Mon Sep 17 00:00:00 2001 From: Miika Pekkarinen Date: Sat, 18 Jun 2005 12:53:57 +0000 Subject: Initial support for iriver backlight dimming. Unfortunately dimming remote control's EL-backlight is not possible. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6747 a1c6a512-1295-4272-9138-f99709370657 --- firmware/backlight.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++ firmware/system.c | 7 +- 2 files changed, 217 insertions(+), 3 deletions(-) diff --git a/firmware/backlight.c b/firmware/backlight.c index e006d3aeb5..84d3f1a31e 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c @@ -59,6 +59,218 @@ static int remote_backlight_timer; static unsigned int remote_backlight_timeout = 5; #endif +#if CONFIG_BACKLIGHT == BL_IRIVER +#define BL_PWM_COUNT 100 +/* Cycle interval in ms */ +#define BL_PWM_INTERVAL 5000 +#define BL_PWM_INTERVAL_IDLE 500000 +#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 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; + +void backlight_start_timer(void) +{ + unsigned int count; + + if (bl_timer_active) + return ; + + count = 1; + bl_timer_active = true; + + /* We are using timer 1 */ + TRR1 = count; /* The reference count */ + TCN1 = 0; /* reset the timer */ + TMR1 = 0x011d; /* prescaler=2, restart, CLK/16, enabled */ + + TER1 = 0xff; /* Clear all events */ + + /* ICR2 (Timer2) */ + ICR0 = (ICR0 & 0xffff00ff) | 0x00009000; /* Interrupt on level 4.0 */ + IMR &= ~(1<<10); +} + +void TIMER1(void) __attribute__ ((interrupt_handler)); +void TIMER1(void) +{ + int timer_period; +#ifdef HAVE_REMOTE_LCD_DIMMABLE + int new_timer_period; +#endif + + timer_period = FREQ/20000 * BL_PWM_INTERVAL / 100 / 32; + switch (bl_dim_state) { + /* New cycle */ + case DIM_STATE_START: + bl_pwm_counter = 0; + bl_cycle_counter++; + + 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 { + if (bl_dim_current) + GPIO1_OUT &= ~0x00020000; + else + GPIO1_OUT |= 0x00020000; + } + +#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) { + 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: + 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) { + bool idle = true; + 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 + bl_cycle_counter = 0; + + /* Save CPU & battery when idle, stop timer */ + if (idle) { + bl_timer_active = false; + TMR1 = 0; + } + } + + TRR1 = timer_period; + TCN1 = 0; + TER1 = 0xff; /* Clear all events */ +} + +static void __backlight_dim(int value) +{ + bl_dim_target = value; + backlight_start_timer(); +} + +static void __backlight_fade_in(void) +{ + __backlight_dim(BL_PWM_COUNT); +} + +static void __backlight_fade_out(void) +{ + __backlight_dim(0); +} + +#ifdef HAVE_REMOTE_LCD_DIMMABLE +static void __backlight_dim_remote(int value) +{ + 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); +} +#endif + +#else static void __backlight_off(void) { #if CONFIG_BACKLIGHT == BL_IRIVER @@ -91,6 +303,7 @@ static void __backlight_on(void) P1 |= 0x10; #endif } +#endif void backlight_thread(void) { diff --git a/firmware/system.c b/firmware/system.c index d095e1574a..66bd90f71b 100644 --- a/firmware/system.c +++ b/firmware/system.c @@ -432,12 +432,13 @@ void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = UIE,UIE,UIE,UIE,UIE,UIE, UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, - UIE,UIE,UIE,TIMER0,UIE,UIE,UIE,UIE, - + UIE,UIE,UIE,TIMER0,TIMER1,UIE,UIE,UIE, + /* lvl 3 lvl 4 */ + TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, - SWT,UIE,TIMER1,I2C,UART1,UART2,DMA0,DMA1, + SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1, DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE, PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY, IIS1TXEMPTY,PDIR3FULL,PDIR3RESYN,UQ2CHANERR, -- cgit v1.2.3