?? lcd.c
字號:
/*
* LCD Driver for M68VZ328
*
*
* COPYRIGHT (c) 2001 - 2010.
* emTech System Corporation.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE.
*/
/* Huangf emcore@263.net
*/
/* LCD screen routine for M68VZ328 */
unsigned short *lcd_base = 0;
unsigned short lcd_vpw = 0; /* count in 16 bits byte,
* for 1 bit mode, it is equal to width/16,
* for 2 bit mode, it is equal to width/8,
* for 4 bit mode, it is equal to width/4
*/
unsigned short lcd_xmax = 0;
unsigned short lcd_ymax = 0;
unsigned long _LCD_START_ADDR = 0;
#define LCD_CURSOR_MODE(x) (((x) & 0x0c000) >> 14)
#define LCD_CURSOR_WIDTH(x) (((x) >> 8) & 0x1f)
#define LCD_CURSOR_HEIGHT(x) ((x) & 0x1f)
#define LCD_CURSOR_BLINK_ENABLED(x) ((x) & 0x80)
unsigned short lcd_cursor_x = 0;
unsigned short lcd_cursor_y = 0;
unsigned short lcd_cursor_wh = 0;
unsigned char lcd_cursor_blink = 0;
#define LSSA *(unsigned long *)0xFFFFFA00
#define LVPW *(unsigned char *)0xFFFFFA05
#define LXMAX *(unsigned short *)0xFFFFFA08
#define LYMAX *(unsigned short *)0xFFFFFA0A
#define LCXP *(unsigned short *)0xFFFFFA18
#define LCYP *(unsigned short *)0xFFFFFA1A
#define LCWCH *(unsigned short *)0xFFFFFA1C
#define LBLCK *(unsigned char *)0xFFFFFA1F
#define LPICF *(unsigned char *)0xFFFFFA20
#define LPOLCF *(unsigned char *)0xFFFFFA21
#define LACDRC *(unsigned char *)0xFFFFFA23
#define LPXCD *(unsigned char *)0xFFFFFA25
#define LCKCON *(unsigned char *)0xFFFFFA27
#define LRRA *(unsigned short *)0xFFFFFA28
#define LPOSR *(unsigned char *)0xFFFFFA2D
#define LGPMR *(unsigned char *)0xFFFFFA33
#define PWMR *(unsigned short *)0xFFFFFA36
#define RMCR *(unsigned char *)0xFFFFFA38
#define DMACR *(unsigned char *)0xFFFFFA39
unsigned short lcd_pixel_mask_1bit[16] = {0x7fff, 0xbfff, 0xdfff, 0xefff, 0xf7ff, 0xfbff, 0xfdff, 0xfeff, 0xff7f, 0xffbf, 0xffdf, 0xffef, 0xfff7, 0xfffb, 0xfffd, 0xfffe};
unsigned short lcd_pixel_mask_2bit[8] = {0x3fff, 0xcfff, 0xf3ff, 0xfcff, 0xff3f, 0xffcf, 0xfff3, 0xfffc};
unsigned short lcd_pixel_mask_4bit[4] = {0x0fff, 0xf0ff, 0xff0f, 0xfff0};
unsigned short *lcd_pixel_mask = lcd_pixel_mask_1bit;
unsigned char lcd_pixel_shift_1bit[16] = {0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x7, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
unsigned char lcd_pixel_shift_2bit[8] = {0x0E, 0x0C, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x00};
unsigned char lcd_pixel_shift_4bit[4] = {0x0C, 0x08, 0x04, 0x00};
unsigned char *lcd_pixel_shift = lcd_pixel_shift_1bit;
unsigned short lcd_color_fullword_1bit[2] = {0x0, 0xffff};
unsigned short lcd_color_fullword_2bit[4] = {0x0, 0x5555, 0xaaaa, 0xffff};
unsigned short lcd_color_fullword_4bit[16] = {0x0, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, 0x9999, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff};
unsigned short *lcd_color_fullword = lcd_color_fullword_1bit;
unsigned char lcd_pixel_color_mask_[3] = {0x01, 0x03, 0x0f};
unsigned char lcd_pixel_color_mask = 0x01;
unsigned char lcd_offset_shift_[3] = {0x04, 0x03, 0x02}; /* /16, /8, /4 */
unsigned char lcd_offset_shift = 0x04;
unsigned char lcd_color_shift_[3] = {0x03, 0x02, 0x0};
unsigned char lcd_color_shift = 0x07;
unsigned char lcd_bits_per_pixel = 1;
#define LCD_PBUS_SIZE 0x02 /* 4 bit panel bus *//* 0x03 for 8 bits panel bus */
int SysPixelPerByte()
{
return 8 / lcd_bits_per_pixel;
}
int SysBytesPerScreen()
{
return (lcd_xmax * lcd_ymax) / SysPixelPerByte();
}
int _lcd_calcmemgcsize(
int l,
int t,
int r,
int b
)
{
int w, h;
h = b - t + 1;
l = l / SysPixelPerByte();
r = (r + SysPixelPerByte() - 1) / SysPixelPerByte();
w = r - l;
return (w * h);
}
void _lcd_savescreen(
unsigned char *base,
unsigned char *dst,
int l,
int t,
int r,
int b
)
{
int w, h;
int pos;
pos = (short)t * (short)lcd_vpw * 2;
l = l / SysPixelPerByte();
r = (r + SysPixelPerByte() - 1) / SysPixelPerByte();
w = r - l;
pos += l;
for (h = t; h <= b; h++){
memcpy(dst, base + pos, w);
dst += w;
pos += (lcd_vpw * 2);
}
}
void _lcd_restorescreen(
unsigned char *base,
unsigned char *dst,
int l,
int t,
int r,
int b
)
{
int w, h;
int pos;
pos = (short)t * (short)lcd_vpw * 2;
l = l / SysPixelPerByte();
r = (r + SysPixelPerByte() - 1) / SysPixelPerByte();
w = r - l;
pos += l;
for (h = t; h <= b; h++){
memcpy(base + pos, dst, w);
dst += w;
pos += (lcd_vpw * 2);
}
}
/* it is very difficult to setup LCD, this function using many default parameters to setup LCD,
* so only a few parameters needed for setup LCD here
*/
int lcd_setup(unsigned long start_addr, unsigned short width, unsigned short xmax, unsigned short ymax, unsigned short bits_per_pixel)
{
/* disable LCD first */
LCKCON = 0x00;
lcd_xmax = xmax;
lcd_ymax = ymax;
/* setup LSSA */
LSSA = start_addr;
{
unsigned char *base = (unsigned char *)start_addr;
int i;
for (i = 0; i < width * ymax; i++){
*base++ = 0xff;
}
}
_LCD_START_ADDR = start_addr;
LXMAX = xmax;
LYMAX = ymax - 1;
switch(bits_per_pixel){
case 1:
LVPW = width / 16;
LPICF = (LCD_PBUS_SIZE << 2);
break;
case 2:
LVPW = width / 8;
LPICF = (LCD_PBUS_SIZE << 2) + 0x01;
break;
case 4:
LVPW = width / 4;
LPICF = (LCD_PBUS_SIZE << 2) + 0x10;
break;
default:
LVPW = width / 16;
LPICF = (LCD_PBUS_SIZE << 2);
}
LPOLCF = 0x01;
LACDRC = 0x00;
LPXCD = 0x02;
LRRA = 0x14;
LPOSR = 0x00;
/* Enable LCD */
LCKCON = 0x00;
LCKCON = 0x80;
return 0;
}
void _lcd_switchbase(
void *base
)
{
lcd_base = base;
/* setup LSSA */
LSSA = (unsigned long)base;
}
int lcd_getdisplay()
{
lcd_base = (unsigned short *)LSSA;
lcd_vpw = LVPW;
{
unsigned char lpicf = LPICF;
switch(lpicf & 0x03){
case 0:
lcd_pixel_mask = lcd_pixel_mask_1bit;
lcd_pixel_shift = lcd_pixel_shift_1bit;
lcd_pixel_color_mask = lcd_pixel_color_mask_[0];
lcd_offset_shift = lcd_offset_shift_[0];
lcd_color_shift = lcd_color_shift_[0];
lcd_color_fullword = lcd_color_fullword_1bit;
lcd_bits_per_pixel = 1;
break;
case 1:
lcd_pixel_mask = lcd_pixel_mask_2bit;
lcd_pixel_shift = lcd_pixel_shift_2bit;
lcd_pixel_color_mask = lcd_pixel_color_mask_[1];
lcd_offset_shift = lcd_offset_shift_[1];
lcd_color_shift = lcd_color_shift_[1];
lcd_color_fullword = lcd_color_fullword_2bit;
lcd_bits_per_pixel = 2;
break;
case 2:
lcd_pixel_mask = lcd_pixel_mask_4bit;
lcd_pixel_shift = lcd_pixel_shift_4bit;
lcd_pixel_color_mask = lcd_pixel_color_mask_[2];
lcd_offset_shift = lcd_offset_shift_[2];
lcd_color_shift = lcd_color_shift_[2];
lcd_color_fullword = lcd_color_fullword_4bit;
lcd_bits_per_pixel = 4;
break;
default:
lcd_pixel_mask = lcd_pixel_mask_1bit;
lcd_pixel_shift = lcd_pixel_shift_1bit;
lcd_pixel_color_mask = lcd_pixel_color_mask_[0];
lcd_offset_shift = lcd_offset_shift_[0];
lcd_color_shift = lcd_color_shift_[0];
lcd_color_fullword = lcd_color_fullword_1bit;
lcd_bits_per_pixel = 1;
}
}
return 0;
}
int lcd_getx()
{
return LXMAX;
}
int lcd_gety()
{
return LYMAX;
}
int lcd_getvx()
{
return lcd_getx();
}
int _lcd_putpixel(unsigned short *_base, short x, short y, unsigned char c, int xorm)
{
unsigned short oldc;
int pos = (short)y * (short)lcd_vpw;
pos += (x >> lcd_offset_shift);
x -= ((x >> lcd_offset_shift) << lcd_offset_shift); /* bits in current bytes */
/* inverse color */
/* c = 15 - c; */
oldc = _base[pos];
if (xorm){ /* usinf XOR mode */
oldc ^= ((c >> lcd_color_shift) << lcd_pixel_shift[x]);
}
else{
oldc &= lcd_pixel_mask[x];
oldc |= ((c >> lcd_color_shift) << lcd_pixel_shift[x]);
}
_base[pos] = oldc;
return 0;
}
int lcd_putpixel(short x, short y, unsigned char c, int xorm)
{
return _lcd_putpixel(
lcd_base,
x,
y,
c,
xorm
);
}
int _lcd_getpixel(unsigned short *_base, short x, short y)
{
unsigned short oldc;
int pos = (short)y * (short)lcd_vpw;
pos += (x >> lcd_offset_shift);
x -= ((x >> lcd_offset_shift) << lcd_offset_shift); /* bits in current bytes */
oldc = _base[pos];
oldc >>= lcd_pixel_shift[x];
oldc &= lcd_pixel_color_mask;
/* inverse color */
return oldc;
}
int lcd_getpixel(
short x,
short y
)
{
return _lcd_getpixel(
lcd_base,
x,
y
);
}
/* quick method for drawing bitmap
*/
int _lcd_bitmap(unsigned short *_base, short x0, short y0, short width, short height, unsigned char *pcc, int xorm)
{
unsigned char *src = pcc;
unsigned char *dst = (unsigned char *)(_base + y0 * lcd_vpw);
unsigned short leng = (width + 31) >> 5;
unsigned short len = ((width) >> 3);
int i, j;
dst += (x0 >> (lcd_offset_shift - 1));
leng <<= 2;
src += leng * (height - 1);
for (i = 0; i < height; i++){
for (j = 0; j < len; j++){
dst[j] = src[j];
}
dst += (lcd_vpw * 2);
src -= leng;
}
return 0;
}
int lcd_bitmap(
short x0,
short y0,
short width,
short height,
unsigned char *pcc,
int xorm
)
{
return _lcd_bitmap(
lcd_base,
x0,
y0,
width,
height,
pcc,
xorm
);
}
/* quick method for hline */
int _lcd_hline(unsigned short *_base, short x1, short y, short x2, unsigned char c, int xorm)
{
/* a very slow version */
int count;
unsigned short oldc;
int pos = (short)y * (short)lcd_vpw;
int pixels_per_word = 1 << lcd_offset_shift;
/* inverse */
/* c = 15 - c; */
if (x2 < x1){
int t = x2;
x2 = x1;
x1 = t;
}
count = x2 - x1;
pos += (x1 >> lcd_offset_shift);
x1 -= ((x1 >> lcd_offset_shift) << lcd_offset_shift); /* bits in current bytes */
if (x1){
/* first part */
oldc = _base[pos];
while((x1 < pixels_per_word) && (count > 0)){
if (xorm){ /* usinf XOR mode */
oldc ^= ((c >> lcd_color_shift) << lcd_pixel_shift[x1]);
}
else{
oldc &= lcd_pixel_mask[x1];
oldc |= ((c >> lcd_color_shift) << lcd_pixel_shift[x1]);
}
x1++;
count--;
}
_base[pos++] = oldc;
}
while(count >= pixels_per_word){
oldc = _base[pos];
if(xorm){
oldc ^= lcd_color_fullword[c >> lcd_color_shift];
}
else{
oldc = lcd_color_fullword[c >> lcd_color_shift];
}
count -= pixels_per_word;
_base[pos++] = oldc;
}
oldc = _base[pos];
x1 = 0;
while(count > 0){
if (xorm){ /* usinf XOR mode */
oldc ^= ((c >> lcd_color_shift) << lcd_pixel_shift[x1]);
}
else{
oldc &= lcd_pixel_mask[x1];
oldc |= ((c >> lcd_color_shift) << lcd_pixel_shift[x1]);
}
x1++;
count--;
}
_base[pos] = oldc;
return 0;
/*
for (i = x1; i <= x2; i++){
lcd_putpixel(i, y, c, xorm);
}
return 0;
*/
}
int lcd_hline(
short x1,
short y,
short x2,
unsigned char c,
int xorm
)
{
return _lcd_hline(
lcd_base,
x1,
y,
x2,
c,
xorm
);
}
/* quick method for vline */
int _lcd_vline(unsigned short *_base, short x, short y1, short y2, unsigned char c, int xorm)
{
/* a very slow version */
int i;
int pos;
unsigned short oldc, color;
if (y2 < y1){
int t = y2;
y2 = y1;
y1 = t;
}
/* inverse color */
/* c = 15 - c; */
pos = (short)y1 * (short)lcd_vpw;
pos += (x >> lcd_offset_shift);
x -= ((x >> lcd_offset_shift) << lcd_offset_shift); /* bits in current bytes */
color = ((c >> lcd_color_shift) << lcd_pixel_shift[x]);
for (i = y1; i <= y2; i++){
oldc = _base[pos];
if (xorm){ /* usinf XOR mode */
oldc ^= color;
}
else{
oldc &= lcd_pixel_mask[x];
oldc |= color;
}
_base[pos] = oldc;
pos += lcd_vpw;
}
return 0;
}
int lcd_vline(
short x,
short y1,
short y2,
unsigned char c,
int xorm
)
{
return _lcd_vline(
lcd_base,
x,
y1,
y2,
c,
xorm
);
}
int _lcd_fillrect(unsigned short *_base, short x1, short y1, short x2, short y2, int c)
{
int y;
if (x2 < x1){
int t = x2;
x2 = x1;
x1 = t;
}
if (y2 < y1){
int t = y2;
y2 = y1;
y1 = t;
}
for (y = y1; y <= y2; y++){
_lcd_hline(
_base,
x1,
y,
x2,
c,
0
);
}
return 0;
}
int lcd_fillrect(short x1, short y1, short x2, short y2, int c)
{
return _lcd_fillrect(
lcd_base,
x1,
y1,
x2,
y2,
c
);
}
#if 0
int __main()
{
return 0;
}
main()
{
lcd_setup(0x200000, 160, 160, 240, 2);
lcd_getdisplay();
lcd_fillrect(0, 0, 159, 9, 0);
lcd_hline(0, 10, 120, 0, 0);
lcd_putpixel(0, 100, 1, 0);
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -