/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2002 by Alan Korr * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "config.h" #include "hwcompat.h" #ifdef HAVE_LCD_CHARCELLS #include "lcd.h" #include "kernel.h" #include "thread.h" #include #include #include "file.h" #include "debug.h" #include "system.h" #include "font.h" /*** definitions ***/ #define OLD_LCD_CONTRAST_SET ((char)0xA8) #define OLD_LCD_CRAM ((char)0xB0) /* Characters */ #define OLD_LCD_PRAM ((char)0x80) /* Patterns */ #define OLD_LCD_IRAM ((char)0xE0) /* Icons */ #define NEW_LCD_CONTRAST_SET ((char)0x50) #define NEW_LCD_CRAM ((char)0x80) /* Characters */ #define NEW_LCD_PRAM ((char)0xC0) /* Patterns */ #define NEW_LCD_IRAM ((char)0x40) /* Icons */ #define LCD_CURSOR(x,y) ((char)(lcd_cram+((y)*16+(x)))) #define LCD_ICON(i) ((char)(lcd_iram+i)) #define SCROLLABLE_LINES 2 #define SCROLL_MODE_OFF 0 #define SCROLL_MODE_PAUSE 1 #define SCROLL_MODE_RUN 2 /*** generic code ***/ struct scrollinfo { int mode; char text[MAX_PATH]; char line[32]; int textlen; int offset; int startx; int starty; int space; }; static void scroll_thread(void); static char scroll_stack[DEFAULT_STACK_SIZE]; static char scroll_name[] = "scroll"; static char scroll_speed = 8; /* updates per second */ static char scroll_spacing = 3; /* spaces between end and start of text */ static long scroll_start_tick; static struct scrollinfo scroll[SCROLLABLE_LINES]; static const unsigned char new_lcd_ascii[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, 0x10,0x11,0x05,0x13,0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67, 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7, 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7, 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, 0x41,0x41,0x41,0x41,0x41,0x41,0x20,0x43, 0x45,0x45,0x45,0x45,0x49,0x49,0x49,0x49, 0x44,0x4e,0x4f,0x4f,0x4f,0x4f,0x4f,0x20, 0x20,0x55,0x55,0x55,0x55,0x59,0x20,0x20, 0x61,0x61,0x61,0x61,0x61,0x61,0x20,0x63, 0x65,0x65,0x65,0x65,0x69,0x69,0x69,0x69, 0x6f,0x6e,0x6f,0x6f,0x6f,0x6f,0x6f,0x20, 0x20,0x75,0x75,0x75,0x75,0x79,0x20,0x79 }; static const unsigned char old_lcd_ascii[] = { 0x00,0x01,0x02,0x03,0x00,0x84,0x85,0x89, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xec,0xe3,0xe2,0xe1,0xe0,0xdf,0x15,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x24,0x25,0x26,0x37,0x06,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43, 0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b, 0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53, 0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b, 0x5c,0x5d,0x5e,0xa9,0x33,0xce,0x00,0x15, 0x00,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x24,0x24,0x24,0x24,0x24, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7, 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7, 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, 0x45,0x45,0x45,0x45,0x45,0x45,0x24,0x47, 0x49,0x49,0x49,0x49,0x4d,0x4d,0x4d,0x4d, 0x48,0x52,0x53,0x53,0x53,0x53,0x53,0x24, 0x24,0x59,0x59,0x59,0x59,0x5d,0x24,0x24, 0x65,0x65,0x65,0x65,0x65,0x65,0x24,0x67, 0x69,0x69,0x69,0x69,0x6d,0x6d,0x6d,0x6d, 0x73,0x72,0x73,0x73,0x73,0x73,0x73,0x24, 0x24,0x79,0x79,0x79,0x79,0x7d,0x24,0x7d }; static bool new_lcd; unsigned const char *lcd_ascii; static char lcd_contrast_set; static char lcd_cram; static char lcd_pram; static char lcd_iram; #ifndef SIMULATOR void lcd_clear_display(void) { int i; lcd_write(true,LCD_CURSOR(0,0)); for (i=0;i<32;i++) lcd_write(false,lcd_ascii[' ']); } void lcd_puts(int x, int y, unsigned char *string) { int i; lcd_write(true,LCD_CURSOR(x,y)); for (i=0; *string && x++<11; i++) lcd_write(false,lcd_ascii[*(unsigned char*)string++]); for (; x<11; x++) lcd_write(false,lcd_ascii[' ']); } void lcd_putc(int x, int y, unsigned char ch) { lcd_write(true,LCD_CURSOR(x,y)); lcd_write(false,lcd_ascii[ch]); } void lcd_define_pattern (int which,char *pattern,int length) { int i; lcd_write(true,lcd_pram | which); for (i=0;imode == SCROLL_MODE_OFF) { break; } } s->space = 11 - x; lcd_puts(x,y,string); s->textlen = strlen(string); if ( s->textlen > s->space ) { s->mode = SCROLL_MODE_RUN; s->offset=s->space; s->startx=x; s->starty=y; strncpy(s->text,string,sizeof s->text); s->text[sizeof s->text - 1] = 0; memset(s->line, 0, sizeof s->line); strncpy(s->line,string, s->space > (int)sizeof s->line ? (int)sizeof s->line : s->space ); s->line[sizeof s->line - 1] = 0; } } void lcd_stop_scroll(void) { struct scrollinfo* s; int index; for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; if ( s->mode == SCROLL_MODE_RUN || s->mode == SCROLL_MODE_PAUSE ) { /* restore scrolled row */ lcd_puts(s->startx, s->starty, s->text); s->mode = SCROLL_MODE_OFF; } } lcd_update(); } void lcd_stop_scroll_line(int line) { struct scrollinfo* s; int index; for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; if ( s->startx == line && ( s->mode == SCROLL_MODE_RUN || s->mode == SCROLL_MODE_PAUSE )) { /* restore scrolled row */ lcd_puts(s->startx, s->starty, s->text); s->mode = SCROLL_MODE_OFF; } } lcd_update(); } void lcd_scroll_pause(void) { struct scrollinfo* s; int index; for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; if ( s->mode == SCROLL_MODE_RUN ) { s->mode = SCROLL_MODE_PAUSE; } } } void lcd_scroll_pause_line(int line) { struct scrollinfo* s; int index; for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; if ( s->startx == line && s->mode == SCROLL_MODE_RUN ) { s->mode = SCROLL_MODE_PAUSE; } } } void lcd_scroll_resume(void) { struct scrollinfo* s; int index; scroll_start_tick = current_tick + HZ/2; for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; if ( s->mode == SCROLL_MODE_PAUSE ) { s->mode = SCROLL_MODE_RUN; } } } void lcd_scroll_resume_line(int line) { struct scrollinfo* s; int index; scroll_start_tick = current_tick + HZ/2; for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; if ( s->startx == line && s->mode == SCROLL_MODE_PAUSE ) { s->mode = SCROLL_MODE_RUN; } } } void lcd_scroll_speed(int speed) { scroll_speed = speed; } static void scroll_thread(void) { struct scrollinfo* s; int index; int i; bool update; /* initialize scroll struct array */ for (index = 0; index < SCROLLABLE_LINES; index++) { scroll[index].mode = SCROLL_MODE_OFF; } scroll_start_tick = current_tick; while ( 1 ) { update = false; /* wait 0.5s before starting scroll */ if ( TIME_AFTER(current_tick, scroll_start_tick) ) { for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; if ( s->mode == SCROLL_MODE_RUN ) { update = true; for ( i = 0; i < s->space - 1; i++ ) s->line[i] = s->line[i+1]; if ( s->offset < s->textlen ) { s->line[(int)s->space - 1] = s->text[(int)s->offset]; s->offset++; } else { s->line[s->space - 1] = ' '; if ( s->offset < s->textlen + scroll_spacing - 1 ) s->offset++; else s->offset = 0; } lcd_puts(s->startx,s->starty,s->line); } } if (update) { lcd_update(); } } sleep(HZ/scroll_speed); } } #endif /* HAVE_LCD_CHARCELLS */ /* ----------------------------------------------------------------- * local variables: * eval: (load-file "../rockbox-mode.el") * end: */