1
0
Fork 0
forked from len0rd/rockbox

Initial version of iPod greyscale LCD driver from Seven Le Mesle. This is currently written to use vertically-packed mono and native bitmap formats.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8580 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dave Chapman 2006-02-05 16:01:50 +00:00
parent c6c584e4c1
commit e8048cefed
3 changed files with 1002 additions and 13 deletions

View file

@ -29,7 +29,192 @@
#include "kernel.h"
#include "system.h"
/*** definitions ***/
/* check if number of useconds has past */
static int timer_check(int clock_start, int usecs)
{
if ( ((int)(USEC_TIMER - clock_start)) >= usecs ) {
return 1;
} else {
return 0;
}
}
#if (CONFIG_LCD == LCD_IPOD2BPP)
/*** hardware configuration ***/
#define IPOD_LCD_BASE 0xc0001000
#define IPOD_LCD_BUSY_MASK 0x80000000
/* LCD command codes for HD66789R */
#define LCD_CMD 0x08
#define LCD_DATA 0x10
static unsigned int lcd_contrast = 0x6a;
/* wait for LCD with timeout */
static void lcd_wait_write(void)
{
int start = USEC_TIMER;
do {
if ((inl(IPOD_LCD_BASE) & 0x8000) == 0) break;
} while (timer_check(start, 1000) == 0);
}
/* send LCD data */
static void lcd_send_data(int data_lo, int data_hi)
{
lcd_wait_write();
outl(data_lo, IPOD_LCD_BASE + LCD_DATA);
lcd_wait_write();
outl(data_hi, IPOD_LCD_BASE + LCD_DATA);
}
/* send LCD command */
static void lcd_prepare_cmd(int cmd)
{
lcd_wait_write();
outl(0x0, IPOD_LCD_BASE + LCD_CMD);
lcd_wait_write();
outl(cmd, IPOD_LCD_BASE + LCD_CMD);
}
/* send LCD command and data */
static void lcd_cmd_and_data(int cmd, int data_lo, int data_hi)
{
lcd_prepare_cmd(cmd);
lcd_send_data(data_lo, data_hi);
}
int lcd_default_contrast(void)
{
return 28;
}
/**
*
* LCD init
**/
void lcd_init_device(void){
/* driver output control - 160x128 */
lcd_cmd_and_data(0x1, 0x1, 0xf);
lcd_cmd_and_data(0x5, 0x0, 0x10);
}
/*** update functions ***/
/* srccopy bitblt, opcode is currently ignored*/
/* Performance function that works with an external buffer
note that x and bwidtht are in 8-pixel units! */
void lcd_blit(const unsigned char* data, int x, int by, int width,
int bheight, int stride)
{
/* TODO implement this on iPod */
(void)data;
(void)x;
(void)by;
(void)width;
(void)bheight;
(void)stride;
}
/* Rolls up the lcd display by the specified amount of lines.
* Lines that are rolled out over the top of the screen are
* rolled in from the bottom again. This is a hardware
* remapping only and all operations on the lcd are affected.
* ->
* @param int lines - The number of lines that are rolled.
* The value must be 0 <= pixels < LCD_HEIGHT. */
void lcd_roll(int lines)
{
/* TODO Implement lcd_roll() */
lines &= LCD_HEIGHT-1;
}
/*** hardware configuration ***/
/* Update the display.
This must be called after all other LCD functions that change the display. */
void lcd_update(void)
{
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
}
void lcd_set_contrast(int val)
{
lcd_cmd_and_data(0x4, 0x4, val);
lcd_contrast = val;
}
void lcd_update_rect(int x, int y, int width, int height)
{
int cursor_pos, xx;
int ny;
int sx = x, sy = y, mx = width, my = height;
/* only update the ipod if we are writing to the screen */
sx >>= 3;
//mx = (mx+7)>>3;
mx >>= 3;
cursor_pos = sx + (sy << 5);
for ( ny = sy; ny <= my; ny++ ) {
unsigned char * img_data;
// move the cursor
lcd_cmd_and_data(0x11, cursor_pos >> 8, cursor_pos & 0xff);
// setup for printing
lcd_prepare_cmd(0x12);
img_data = &lcd_framebuffer[ny][sx<<1];
// 160/8 -> 20 == loops 20 times
// make sure we loop at least once
for ( xx = sx; xx <= mx; xx++ ) {
// display a character
lcd_send_data(*(img_data+1), *img_data);
img_data += 2;
}
// update cursor pos counter
cursor_pos += 0x20;
}
}
/** Switch on or off the backlight **/
void lcd_enable (bool on){
int lcd_state;
lcd_state = inl(IPOD_LCD_BASE);
if (on){
lcd_state = lcd_state | 0x2;
outl(lcd_state, IPOD_LCD_BASE);
lcd_cmd_and_data(0x7, 0x0, 0x11);
}
else {
lcd_state = lcd_state & ~0x2;
outl(lcd_state, IPOD_LCD_BASE);
lcd_cmd_and_data(0x7, 0x0, 0x9);
}
}
#else
#define IPOD_LCD_BASE 0x70008a0c
#define IPOD_LCD_BUSY_MASK 0x80000000
@ -42,17 +227,6 @@
/*** globals ***/
static int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */
/* check if number of useconds has past */
static inline int timer_check(unsigned long clock_start, unsigned long usecs)
{
if ( (USEC_TIMER - clock_start) >= usecs ) {
return 1;
} else {
return 0;
}
}
static void lcd_wait_write(void)
{
if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) != 0) {
@ -229,7 +403,7 @@ void lcd_update_rect(int x, int y, int width, int height)
/* start vert = max vert */
#if CONFIG_LCD == LCD_IPODCOLOR
x0 = x1;
x0 = x1;
#endif
/* position cursor (set AD0-AD15) */
@ -288,3 +462,4 @@ void lcd_update(void)
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
}
#endif