Iriver: Reworked remote detection & init: * Monitor the remote type & try to init the LCD for 20 seconds after plugin. Fixes wrong type detection & non-working LCD when plugging in slowly, and inits much faster if the remote is already plugged at boot (no delayed logo). * Don't try to init the LCD for a non-LCD remote in order to save CPU power. * More precise scroll timing, taking drawing time & other delays into account.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9783 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
e0f7ecbfd8
commit
2aa85a2b6a
1 changed files with 76 additions and 36 deletions
|
@ -87,10 +87,13 @@ static int byte_delay = 172;
|
|||
#endif
|
||||
|
||||
/* remote hotplug */
|
||||
static int countdown; /* for remote plugging debounce */
|
||||
static bool last_remote_status = false;
|
||||
static bool init_remote = false; /* scroll thread should init lcd */
|
||||
static struct event_queue remote_scroll_queue;
|
||||
#define REMOTE_INIT_LCD 1
|
||||
#define REMOTE_DEINIT_LCD 2
|
||||
|
||||
static bool remote_initialized = false;
|
||||
static int _remote_type = 0;
|
||||
|
||||
/* cached settings values */
|
||||
static bool cached_invert = false;
|
||||
static bool cached_flip = false;
|
||||
|
@ -409,6 +412,7 @@ void lcd_remote_set_flip(bool yesno)
|
|||
/* The actual LCD init */
|
||||
static void remote_lcd_init(void)
|
||||
{
|
||||
CS_HI;
|
||||
lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0);
|
||||
|
||||
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x5);
|
||||
|
@ -434,8 +438,6 @@ static void remote_lcd_init(void)
|
|||
lcd_remote_set_invert_display(cached_invert);
|
||||
}
|
||||
|
||||
static int _remote_type = 0;
|
||||
|
||||
int remote_type(void)
|
||||
{
|
||||
return _remote_type;
|
||||
|
@ -444,55 +446,67 @@ int remote_type(void)
|
|||
/* Monitor remote hotswap */
|
||||
static void remote_tick(void)
|
||||
{
|
||||
static bool last_status = false;
|
||||
static int countdown = 0;
|
||||
static int init_delay = 0;
|
||||
bool current_status;
|
||||
int val;
|
||||
int level;
|
||||
|
||||
current_status = ((GPIO_READ & 0x40000000) == 0);
|
||||
/* Only report when the status has changed */
|
||||
if (current_status != last_remote_status)
|
||||
if (current_status != last_status)
|
||||
{
|
||||
last_remote_status = current_status;
|
||||
countdown = current_status ? HZ : 1;
|
||||
last_status = current_status;
|
||||
countdown = current_status ? 20*HZ : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Count down until it gets negative */
|
||||
if (countdown >= 0)
|
||||
countdown--;
|
||||
|
||||
if (countdown == 0)
|
||||
|
||||
if (current_status)
|
||||
{
|
||||
if (current_status)
|
||||
if (!(countdown % 8))
|
||||
{
|
||||
/* Determine which type of remote it is.
|
||||
The number 8 is just a fudge factor. */
|
||||
/* Determine which type of remote it is */
|
||||
level = set_irq_level(HIGHEST_IRQ_LEVEL);
|
||||
val = adc_scan(ADC_REMOTEDETECT);
|
||||
set_irq_level(level);
|
||||
if (val < ADCVAL_H300_LCD_REMOTE_HOLD)
|
||||
if (val < ADCVAL_H300_LCD_REMOTE)
|
||||
_remote_type = REMOTETYPE_H300_LCD; /* hold off */
|
||||
else
|
||||
if (val < ADCVAL_H100_LCD_REMOTE)
|
||||
_remote_type = REMOTETYPE_H100_LCD; /* hold off */
|
||||
|
||||
if (val < ADCVAL_H100_LCD_REMOTE_HOLD)
|
||||
{
|
||||
if (val < ADCVAL_H100_LCD_REMOTE)
|
||||
if (val < ADCVAL_H300_LCD_REMOTE)
|
||||
_remote_type = REMOTETYPE_H300_LCD; /* hold off */
|
||||
else
|
||||
_remote_type = REMOTETYPE_H300_LCD; /* hold on */
|
||||
else
|
||||
if (val < ADCVAL_H100_LCD_REMOTE_HOLD)
|
||||
_remote_type = REMOTETYPE_H100_LCD; /* hold on, or no remote */
|
||||
_remote_type = REMOTETYPE_H100_LCD; /* hold off */
|
||||
else
|
||||
_remote_type = REMOTETYPE_H300_NONLCD; /* hold doesn't matter */
|
||||
if (val < ADCVAL_H300_LCD_REMOTE_HOLD)
|
||||
_remote_type = REMOTETYPE_H300_LCD; /* hold on */
|
||||
else
|
||||
_remote_type = REMOTETYPE_H100_LCD; /* hold on */
|
||||
|
||||
init_remote = true;
|
||||
/* request init in scroll_thread */
|
||||
if (--init_delay <= 0)
|
||||
{
|
||||
queue_post(&remote_scroll_queue, REMOTE_INIT_LCD, 0);
|
||||
init_delay = 6;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_remote_type = REMOTETYPE_H300_NONLCD; /* hold on or off */
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (countdown == 0)
|
||||
{
|
||||
CLK_LO;
|
||||
CS_HI;
|
||||
remote_initialized = false;
|
||||
_remote_type = 0;
|
||||
|
||||
queue_post(&remote_scroll_queue, REMOTE_DEINIT_LCD, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -539,6 +553,7 @@ void lcd_remote_init(void)
|
|||
#endif
|
||||
lcd_remote_clear_display();
|
||||
|
||||
queue_clear(&remote_scroll_queue); /* no queue_init() -- private queue */
|
||||
tick_add_task(remote_tick);
|
||||
create_thread(scroll_thread, scroll_stack,
|
||||
sizeof(scroll_stack), scroll_name);
|
||||
|
@ -1330,22 +1345,41 @@ static void scroll_thread(void)
|
|||
{
|
||||
struct font* pf;
|
||||
struct scrollinfo* s;
|
||||
long next_tick = current_tick;
|
||||
long delay = 0;
|
||||
int index;
|
||||
int xpos, ypos;
|
||||
int lastmode;
|
||||
#ifndef SIMULATOR
|
||||
struct event ev;
|
||||
#endif
|
||||
|
||||
/* initialize scroll struct array */
|
||||
scrolling_lines = 0;
|
||||
|
||||
while ( 1 ) {
|
||||
|
||||
#ifndef SIMULATOR
|
||||
if (init_remote) /* request to initialize the remote lcd */
|
||||
#ifdef SIMULATOR
|
||||
sleep(delay);
|
||||
#else
|
||||
queue_wait_w_tmo(&remote_scroll_queue, &ev, delay);
|
||||
switch (ev.id)
|
||||
{
|
||||
init_remote = false; /* clear request */
|
||||
remote_lcd_init();
|
||||
lcd_remote_update();
|
||||
case REMOTE_INIT_LCD:
|
||||
remote_lcd_init();
|
||||
lcd_remote_update();
|
||||
break;
|
||||
|
||||
case REMOTE_DEINIT_LCD:
|
||||
CLK_LO;
|
||||
CS_HI;
|
||||
remote_initialized = false;
|
||||
break;
|
||||
}
|
||||
|
||||
delay = next_tick - current_tick - 1;
|
||||
if (delay >= 0)
|
||||
continue;
|
||||
#endif
|
||||
for ( index = 0; index < SCROLLABLE_LINES; index++ ) {
|
||||
/* really scroll? */
|
||||
|
@ -1395,7 +1429,13 @@ static void scroll_thread(void)
|
|||
lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height);
|
||||
}
|
||||
|
||||
sleep(scroll_ticks);
|
||||
next_tick += scroll_ticks;
|
||||
delay = next_tick - current_tick - 1;
|
||||
if (delay < 0)
|
||||
{
|
||||
next_tick = current_tick + 1;
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue