From a6a01903e6d31f16cffd3b2d7d36c43403bdbcb7 Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Fri, 15 Apr 2005 09:42:12 +0000 Subject: [PATCH] Even more updates to the remote LCD driver. Now it actually works... git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6290 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/lcd-h100-remote.c | 192 +++++++++++++++++++++++++++-- firmware/export/lcd-remote.h | 41 ++++++ firmware/export/lcd.h | 3 - 3 files changed, 222 insertions(+), 14 deletions(-) create mode 100644 firmware/export/lcd-remote.h diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c index 10a7c4c897..2eb99ddc88 100644 --- a/firmware/drivers/lcd-h100-remote.c +++ b/firmware/drivers/lcd-h100-remote.c @@ -16,12 +16,20 @@ * KIND, either express or implied. * ****************************************************************************/ + #include "config.h" #include "cpu.h" +#include "lcd-remote.h" #include "kernel.h" #include "thread.h" +#include +#include +#include "file.h" +#include "debug.h" +#include "system.h" +#include "font.h" -#if CONFIG_CPU == MCF5249 +unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]; #define CS_LO GPIO1_OUT &= ~0x00000004 #define CS_HI GPIO1_OUT |= 0x00000004 @@ -149,6 +157,8 @@ void lcd_remote_write_command_ex(int cmd, int data) #define LCD_REMOTE_CNTL_SELECT_REGULATOR 0x20 #define LCD_REMOTE_CNTL_SELECT_BIAS 0xa2 #define LCD_REMOTE_CNTL_SELECT_VOLTAGE 0x81 +#define LCD_REMOTE_CNTL_INIT_LINE 0x40 +#define LCD_REMOTE_CNTL_SET_PAGE_ADDRESS 0xB0 void lcd_remote_powersave(bool on) { @@ -166,6 +176,165 @@ void lcd_remote_set_invert_display(bool yesno) lcd_remote_write_command(LCD_REMOTE_CNTL_REVERSE_ON_OFF | yesno); } +void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny, bool clear) __attribute__ ((section (".icode"))); +void lcd_remote_bitmap(const unsigned char *src, int x, int y, int nx, int ny, bool clear) +{ + const unsigned char *src_col; + unsigned char *dst, *dst_col; + unsigned int data, mask1, mask2, mask3, mask4; + int stride, shift; + + if (((unsigned) x >= LCD_REMOTE_WIDTH) || ((unsigned) y >= LCD_REMOTE_HEIGHT)) + { + return; + } + + stride = nx; /* otherwise right-clipping will destroy the image */ + + if (((unsigned) (x + nx)) >= LCD_REMOTE_WIDTH) + { + nx = LCD_REMOTE_WIDTH - x; + } + + if (((unsigned) (y + ny)) >= LCD_REMOTE_HEIGHT) + { + ny = LCD_REMOTE_HEIGHT - y; + } + + dst = &lcd_remote_framebuffer[y >> 3][x]; + shift = y & 7; + + if (!shift && clear) /* shortcut for byte aligned match with clear */ + { + while (ny >= 8) /* all full rows */ + { + memcpy(dst, src, nx); + src += stride; + dst += LCD_REMOTE_WIDTH; + ny -= 8; + } + if (ny == 0) /* nothing left to do? */ + { + return; + } + /* last partial row to do by default routine */ + } + + ny += shift; + + /* Calculate bit masks */ + mask4 = ~(0xfe << ((ny-1) & 7)); /* data mask for last partial row */ + + if (clear) + { + mask1 = ~(0xff << shift); /* clearing of first partial row */ + mask2 = 0; /* clearing of intermediate (full) rows */ + mask3 = ~mask4; /* clearing of last partial row */ + if (ny <= 8) + { + mask3 |= mask1; + } + } + else + { + mask1 = mask2 = mask3 = 0xff; + } + + /* Loop for each column */ + for (x = 0; x < nx; x++) + { + src_col = src++; + dst_col = dst++; + data = 0; + y = 0; + + if (ny > 8) + { + /* First partial row */ + data = *src_col << shift; + *dst_col = (*dst_col & mask1) | data; + src_col += stride; + dst_col += LCD_REMOTE_WIDTH; + data >>= 8; + + /* Intermediate rows */ + for (y = 8; y < ny-8; y += 8) + { + data |= *src_col << shift; + *dst_col = (*dst_col & mask2) | data; + src_col += stride; + dst_col += LCD_REMOTE_WIDTH; + data >>= 8; + } + } + + /* Last partial row */ + if (y + shift < ny) + { + data |= *src_col << shift; + } + + *dst_col = (*dst_col & mask3) | (data & mask4); + } +} + +void lcd_remote_drawrect(int x, int y, int nx, int ny) +{ + int i; + + if (x > LCD_REMOTE_WIDTH) + { + return; + } + + if (y > LCD_REMOTE_HEIGHT) + { + return; + } + + if (x + nx > LCD_REMOTE_WIDTH) + { + nx = LCD_REMOTE_WIDTH - x; + } + + if (y + ny > LCD_REMOTE_HEIGHT) + { + ny = LCD_REMOTE_HEIGHT - y; + } + + /* vertical lines */ + for (i = 0; i < ny; i++) + { + REMOTE_DRAW_PIXEL(x, (y + i)); + REMOTE_DRAW_PIXEL((x + nx - 1), (y + i)); + } + + /* horizontal lines */ + for (i = 0; i < nx; i++) + { + REMOTE_DRAW_PIXEL((x + i),y); + REMOTE_DRAW_PIXEL((x + i),(y + ny - 1)); + } +} + +void lcd_remote_clear(void) +{ + memset(lcd_remote_framebuffer, 0, sizeof lcd_remote_framebuffer); +} + +void lcd_remote_update(void) +{ + int y; + + /* 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, 0x00); + lcd_remote_write_data(lcd_remote_framebuffer[y], LCD_REMOTE_WIDTH); + } +} + void lcd_remote_init(void) { GPIO_FUNCTION |= 0x10010800; /* GPIO11: Backlight @@ -180,27 +349,28 @@ void lcd_remote_init(void) CLK_LO; CS_HI; - lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_NORMAL); - lcd_remote_write_command(LCD_REMOTE_CNTL_SHL_NORMAL); + 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 | 0x4); + 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); // Select regulator @ 5.0 (default); + lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_REGULATOR | 0x4); // 0x4 Select regulator @ 5.0 (default); lcd_remote_set_contrast(32); sleep(1); - lcd_remote_write_command(0x40); // init line - lcd_remote_write_command(0xB0); // page address - lcd_remote_write_command(0x10); // column - lcd_remote_write_command(0x00); // column + 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(); + lcd_remote_drawrect(0, 0, 10, 20); + lcd_remote_update(); } - -#endif diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h new file mode 100644 index 0000000000..971468f935 --- /dev/null +++ b/firmware/export/lcd-remote.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Richard S. La Charité III + * + * 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. + * + ****************************************************************************/ + +#ifndef __LCD_REMOTE_H__ +#define __LCD_REMOTE_H__ + +#ifdef IRIVER_H100 +#include +#include "cpu.h" +#include "config.h" + +#define REMOTE_DRAW_PIXEL(x,y) lcd_remote_framebuffer[(y)/8][(x)] |= (1<<((y)&7)) +#define REMOTE_CLEAR_PIXEL(x,y) lcd_remote_framebuffer[(y)/8][(x)] &= ~(1<<((y)&7)) +#define REMOTE_INVERT_PIXEL(x,y) lcd_remote_framebuffer[(y)/8][(x)] ^= (1<<((y)&7)) + +extern void lcd_remote_init(void); +extern void lcd_remote_backlight_on(void); +extern void lcd_remote_backlight_off(void); + +extern unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]; + +extern void lcd_remote_bitmap (const unsigned char *src, int x, int y, int nx, int ny, bool clear); + +#endif +#endif diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 9fe3ca2a8a..98e2a58a53 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -65,9 +65,6 @@ extern void lcd_update_rect(int x, int y, int width, int height); #define lcd_update_rect(x,y,w,h) #endif -#ifdef IRIVER_H100 -void lcd_remote_init(void); -#endif #ifdef HAVE_LCD_CHARCELLS /* Icon definitions for lcd_icon() */