1
0
Fork 0
forked from len0rd/rockbox

Hot-plug support for iriver remote.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6625 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2005-06-08 22:48:23 +00:00
parent 969b246f76
commit 23797afb0b
3 changed files with 130 additions and 56 deletions

View file

@ -29,12 +29,9 @@
#include "system.h" #include "system.h"
#include "font.h" #include "font.h"
/* All zeros and ones bitmaps for area filling */ /* All zeros and ones bitmaps for area filling */
static const unsigned char zeros[16] = { static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 static const unsigned char ones[8] = {
};
static const unsigned char ones[16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
}; };
@ -66,6 +63,16 @@ struct scrollinfo {
static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
#ifndef SIMULATOR #ifndef SIMULATOR
static int countdown; /* for remote plugging debounce */
static bool last_remote_status = false;
static bool init_remote = false; /* scroll thread should init lcd */
static bool remote_initialized = false;
/* cached settings values, for hotplug init */
static bool cached_invert = false;
static int cached_contrast = 32;
static int cached_roll = 0;
static void scroll_thread(void); static void scroll_thread(void);
static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)];
#endif #endif
@ -209,18 +216,25 @@ void lcd_remote_write_command_ex(int cmd, int data)
void lcd_remote_powersave(bool on) void lcd_remote_powersave(bool on)
{ {
lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | (on ? 0 : 1)); if (remote_initialized)
lcd_remote_write_command(LCD_REMOTE_CNTL_ENTIRE_ON_OFF | (on ? 1 : 0)); {
lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | (on ? 0 : 1));
lcd_remote_write_command(LCD_REMOTE_CNTL_ENTIRE_ON_OFF | (on ? 1 : 0));
}
} }
void lcd_remote_set_contrast(int val) void lcd_remote_set_contrast(int val)
{ {
lcd_remote_write_command_ex(LCD_REMOTE_CNTL_SELECT_VOLTAGE, val); cached_contrast = val;
if (remote_initialized)
lcd_remote_write_command_ex(LCD_REMOTE_CNTL_SELECT_VOLTAGE, val);
} }
void lcd_remote_set_invert_display(bool yesno) void lcd_remote_set_invert_display(bool yesno)
{ {
lcd_remote_write_command(LCD_REMOTE_CNTL_REVERSE_ON_OFF | yesno); cached_invert = yesno;
if (remote_initialized)
lcd_remote_write_command(LCD_REMOTE_CNTL_REVERSE_ON_OFF | yesno);
} }
int lcd_remote_default_contrast(void) int lcd_remote_default_contrast(void)
@ -377,21 +391,67 @@ void lcd_remote_clear_display(void)
} }
#ifndef SIMULATOR #ifndef SIMULATOR
/*
* Update the display.
* This must be called after all other LCD functions that change the display.
*/
void lcd_remote_update (void) __attribute__ ((section (".icode")));
void lcd_remote_update (void)
{
int y;
/* Copy display bitmap to hardware */ static void remote_lcd_init(void)
for (y = 0; y < LCD_REMOTE_HEIGHT / 8; y++) {
lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_REVERSE);
lcd_remote_write_command(LCD_REMOTE_CNTL_SHL_REVERSE);
lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0);
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x5);
sleep(1);
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x6);
sleep(1);
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x7);
lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_REGULATOR | 0x4); // 0x4 Select regulator @ 5.0 (default);
sleep(1);
lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | 0x0); // page address
lcd_remote_write_command_ex(0x10, 0x00); // Column MSB + LSB
lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | 1);
remote_initialized = true;
lcd_remote_set_contrast(cached_contrast);
lcd_remote_set_invert_display(cached_invert);
lcd_remote_roll(cached_roll);
}
static void remote_tick(void)
{
bool current_status;
current_status = ((GPIO_READ & 0x40000000) == 0);
/* Only report when the status has changed */
if (current_status != last_remote_status)
{ {
lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | y); last_remote_status = current_status;
lcd_remote_write_command_ex(0x10, 0x04); countdown = current_status ? HZ : 1;
lcd_remote_write_data(lcd_remote_framebuffer[y], LCD_REMOTE_WIDTH); }
else
{
/* Count down until it gets negative */
if (countdown >= 0)
countdown--;
if (countdown == 0)
{
if (current_status)
{
init_remote = true;
/* request init in scroll_thread */
}
else
{
CLK_LO;
CS_HI;
remote_initialized = false;
}
}
} }
} }
@ -406,37 +466,35 @@ void lcd_remote_init(void)
GPIO_ENABLE |= 0x10010800; GPIO_ENABLE |= 0x10010800;
GPIO1_ENABLE |= 0x00040004; GPIO1_ENABLE |= 0x00040004;
CLK_LO;
CS_HI;
lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_REVERSE);
lcd_remote_write_command(LCD_REMOTE_CNTL_SHL_REVERSE);
lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0);
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x5);
sleep(1);
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x6);
sleep(1);
lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x7);
lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_REGULATOR | 0x4); // 0x4 Select regulator @ 5.0 (default);
sleep(1);
lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | 0x0); // page address
lcd_remote_write_command_ex(0x10, 0x00); // Column MSB + LSB
lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | 1);
lcd_remote_clear_display(); lcd_remote_clear_display();
lcd_remote_update();
tick_add_task(remote_tick);
create_thread(scroll_thread, scroll_stack, create_thread(scroll_thread, scroll_stack,
sizeof(scroll_stack), scroll_name); sizeof(scroll_stack), scroll_name);
} }
/*
* Update the display.
* This must be called after all other LCD functions that change the display.
*/
void lcd_remote_update (void) __attribute__ ((section (".icode")));
void lcd_remote_update (void)
{
int y;
if (!remote_initialized)
return;
/* Copy display bitmap to hardware */
for (y = 0; y < LCD_REMOTE_HEIGHT / 8; y++)
{
lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | y);
lcd_remote_write_command_ex(0x10, 0x04);
lcd_remote_write_data(lcd_remote_framebuffer[y], LCD_REMOTE_WIDTH);
}
}
/* /*
* Update a fraction of the display. * Update a fraction of the display.
*/ */
@ -445,6 +503,9 @@ void lcd_remote_update_rect (int x_start, int y,
int width, int height) int width, int height)
{ {
int ymax; int ymax;
if (!remote_initialized)
return;
/* The Y coordinates have to work on even 8 pixel rows */ /* The Y coordinates have to work on even 8 pixel rows */
ymax = (y + height-1)/8; ymax = (y + height-1)/8;
@ -478,13 +539,18 @@ void lcd_remote_update_rect (int x_start, int y,
void lcd_remote_roll(int lines) void lcd_remote_roll(int lines)
{ {
char data[2]; char data[2];
lines &= LCD_REMOTE_HEIGHT-1;
data[0] = lines & 0xff;
data[1] = lines >> 8;
lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line cached_roll = lines;
lcd_remote_write_data(data, 2);
if (remote_initialized)
{
lines &= LCD_REMOTE_HEIGHT-1;
data[0] = lines & 0xff;
data[1] = lines >> 8;
lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
lcd_remote_write_data(data, 2);
}
} }
#endif #endif
@ -925,6 +991,14 @@ static void scroll_thread(void)
scrolling_lines = 0; scrolling_lines = 0;
while ( 1 ) { while ( 1 ) {
if (init_remote) /* request to initialize the remote lcd */
{
init_remote = false; /* clear request */
remote_lcd_init();
lcd_remote_update();
}
for ( index = 0; index < SCROLLABLE_LINES; index++ ) { for ( index = 0; index < SCROLLABLE_LINES; index++ ) {
/* really scroll? */ /* really scroll? */
if ( !(scrolling_lines&(1<<index)) ) if ( !(scrolling_lines&(1<<index)) )

View file

@ -27,7 +27,7 @@
#define HZ 100 /* number of ticks per second */ #define HZ 100 /* number of ticks per second */
#define MAX_NUM_TICK_TASKS 4 #define MAX_NUM_TICK_TASKS 5
#define QUEUE_LENGTH 16 /* MUST be a power of 2 */ #define QUEUE_LENGTH 16 /* MUST be a power of 2 */
#define QUEUE_LENGTH_MASK (QUEUE_LENGTH - 1) #define QUEUE_LENGTH_MASK (QUEUE_LENGTH - 1)

View file

@ -77,7 +77,7 @@ extern void lcd_remote_clearline( int x1, int y1, int x2, int y2 );
extern void lcd_remote_drawpixel(int x, int y); extern void lcd_remote_drawpixel(int x, int y);
extern void lcd_remote_clearpixel(int x, int y); extern void lcd_remote_clearpixel(int x, int y);
extern void lcd_remote_invertpixel(int x, int y); extern void lcd_remote_invertpixel(int x, int y);
//extern void lcd_roll(int pixels); extern void lcd_remote_roll(int pixels);
extern void lcd_remote_set_invert_display(bool yesno); extern void lcd_remote_set_invert_display(bool yesno);
//extern void lcd_set_flip(bool yesno); //extern void lcd_set_flip(bool yesno);
extern void lcd_remote_bidir_scroll(int threshold); extern void lcd_remote_bidir_scroll(int threshold);