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
This commit is contained in:
Miika Pekkarinen 2005-06-18 12:53:57 +00:00
parent b0287720b1
commit 2bfd2585a9
2 changed files with 217 additions and 3 deletions

View file

@ -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)
{

View file

@ -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,