?? lcd.c
字號(hào):
/*-----------------------------------------------------------------------------
@@
@@ (Summary) : Driver for LCD Controller
@@
@@ (Comment) :
@@
@@ (Author) :
@@
@@ (History) : Date Modifier Comment
@@
@@ (RCS ID) :
@@
-----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <string.h>
#include "type_def.h"
#include "amba_io.h"
#include "dev_def.h"
#include "lcd_sys_def.h"
#include "lcd_mem.h" /* LCDMemsetWord, LCDMemcpyWord */
#include "lcd_param.h"
#include "lcd_pattern.h"
#include "lcd_def.h"
#include "lcd.h"
#include "font.h"
#define CHARHEIGHT 8
#define CHARWIDTH 8
#ifdef WIN32
#include "lcdcemu.h"
#endif//WIN32
volatile unsigned int *video_ptr = VIDEO_RAM;
/*****************************************************************************
* Definition value
*****************************************************************************/
#define DEF_LINE_PAT 0xFF /* Regular line pattern value */
#define LINEBYTE 160
/*****************************************************************************
* static variable
*****************************************************************************/
static unsigned long LCD_DRAW_UPBASE; /* Base address of RAM area to draw LCD upper panel */
static unsigned long LCD_DRAW_LPBASE; /* Base address of RAM area to draw LCD lower panel */
static APD_LCD_GC current_gc; /* The current value of LCD graphic context */
static unsigned char current_line_pat = DEF_LINE_PAT; /* Bit patter of the current line type */
volatile unsigned char LineData[(APD_LCD_WIDTH * APD_LCD_BPP) / 8]; /* The buffer to read one horizontal data */
/*****************************************************************************
* prototype declaration
*****************************************************************************/
static void LCDDrawVline(APD_LCD_POINT *, unsigned short, unsigned char *);
#if (APD_LCD_BPP <= 8)
static void LCDDrawHline(unsigned long *, unsigned char, unsigned char, unsigned char,
short);
#endif
static void LCDFillHline(unsigned long *, unsigned char, unsigned char, unsigned char,
short);
static void LCDOverwriteHline(unsigned long *, unsigned char, unsigned char,
unsigned char, short, unsigned long);
#include "lcd_palette.h"
#include "lcd_pixel.h"
/******************************************************************************
@@
@@ [Name] : LCDInit
@@
@@ [Summary] : Initialize LCD driver
@@
@@ [Argument] : None
@@
@@ [Return] : None
@@
@@ [Desc] : Initialize LCD controller register according to LCD panel
@@ definition.
@@
@@ [History] : Date Modifier Comment
@@
@@ [END]
******************************************************************************/
void LCDInit(void)
{
#ifndef WIN32
unsigned long reg;
/* Set LCDTiming0 */
reg = 0;
reg |= APD_LCD_HBP << 24; //apd_lcd_hbp 0x14
reg |= APD_LCD_HFP << 16; //apd_lcd_hfp 0x14
reg |= APD_LCD_HSW << 8; //apd_lcd_hsw 0x28
reg |= APD_LCD_PPL << 2; //apd_lcd_ppl ((APD_LCD_WIDTH/16) - 1) = 0x
apd_WriteReg(LCDC_Timing0, reg);
/* Set LCDTiming1 */
reg = 0;
reg |= APD_LCD_VBP << 24; //apd_lcd_vbp 0x04
reg |= APD_LCD_VFP << 16; //apd_lcd_vfp 0x0f
reg |= APD_LCD_VSW << 10; //apd_lcd_vsw 0x03
reg |= APD_LCD_LPP; //apd_lcd_lpp (APD_LCD_HEIGHT - 1) = 239 = 0xef
apd_WriteReg(LCDC_Timing1, reg);
/* Set LCDTiming2 */
reg = 0;
reg |= APD_LCD_BCD << 26; //apd_lcd_bcd 0x00
reg |= APD_LCD_CPL << 16; //APD_LCD_CPL=(APD_LCD_WIDTH * 3 / 8 - 1)=119
reg |= APD_LCD_IOE << 14; //APD_LCD_IOE 0x00
reg |= APD_LCD_IPC << 13; //APD_LCD_IPC 0x01
reg |= APD_LCD_IHS << 12; //APD_LCD_IHS 0x01
reg |= APD_LCD_IVS << 11; //APD_LCD_IVS 0x01
reg |= APD_LCD_ACB << 6; //APD_LCD_ACB 0x00
reg |= APD_LCD_CLKSEL << 5; //APD_LCD_CLKSEL 0x00
reg |= APD_LCD_PCD;
apd_WriteReg(LCDC_Timing2, reg);
/* Set LCDTiming3 */
reg = 0;
reg |= APD_LCD_LEE << 16; //APD_LCD_LEE 0x00
reg |= APD_LCD_LED; //APD_LCD_LED 0x00
apd_WriteReg(LCDC_Timing3, reg);
/* Set LCDIntrEnable */
reg = 0;
apd_WriteReg(LCDC_IntrEnable, reg);
/* Set LCDControl */
reg = 0;
reg |= APD_LCD_WML << 16; //APD_LCD_WML 0x01
reg |= APD_LCD_FIFOTEST << 15; //APD_LCD_FIFOTEST 0x00
// reg |= APD_LCD_VCI << 12; //start of active video
#ifdef APD_LCD_BEPO //not define
reg |= 1 << 10;
#endif
#ifdef APD_LCD_BEBO //not define
reg |= 1 << 9;
#endif
#ifdef APD_LCD_BGR //not define
reg |= 1 << 8;
#endif
reg |= APD_LCD_DUAL << 7; //APD_LCD_DUAL 0x00
reg |= APD_LCD_STNIF << 6; //APD_LCD_STNIF 0x00
reg |= APD_LCD_STN << 5; //APD_LCD_STN 0x01
reg |= APD_LCD_BW << 4; //APD_LCD_BW 0x00
reg |= LCD_SETBPP; //LCD_SETBPP 0x08
apd_WriteReg(LCDC_Control, reg);
/* Set LCDStatus. Clear all interrupt factor */
reg = 0x1E;
apd_WriteReg(LCDC_Status, reg);
#else//WIN32
LCD_DRAW_UPBASE = (unsigned short*)lcdemu_GetVideoRam();
LCD_DRAW_LPBASE = (unsigned short*)lcdemu_GetVideoRamLow();
#endif//WIN32
return;
}
/******************************************************************************
@@
@@ [Name] : apd_LCDDrawPixel
@@
@@ [Summary] : Draw a pixel
@@
@@ [Argument] : point : Coordinate data
@@
@@ [Return] : None
@@
@@ [Desc] : Draw the corresponding pixel of specific coordinate
@@ according to the current attribute
@@ Valid attribute : Color, Raster operation
@@
@@ [History] : Date Modifier Comment
@@
@@ [END]
******************************************************************************/
void apd_LCDDrawPixel(APD_LCD_POINT *point)
{
//unsigned long *adrs; /* The address to write pixel data */
//unsigned char hword, byte, bit; /* Half word, byte and bit offset */
/* Check the area to draw */
// if (point->x < 0 || point->x >= APD_LCD_WIDTH ||
// point->y < 0 || point->y >= APD_LCD_HEIGHT)
// return;
// LCDGetPixelAdrs(point, &adrs, &hword, &byte, &bit);
// LCDWritePixel(adrs, hword, byte, bit, current_gc.c);
// return;
unsigned long *adrs;
unsigned char hword, byte, bit;
APD_LCD_COLOR tmp_color;
tmp_color=current_gc.c;
if (point->x < 0 || point->x >= APD_LCD_WIDTH ||
point->y < 0 || point->y >= APD_LCD_HEIGHT)
return;
LCDGetPixelAdrs(point, &adrs, &hword, &byte, &bit);
tmp_color=current_gc.c;
if(hword)
{
tmp_color = 0;
//adrs--;
tmp_color = (APD_LCD_COLOR)*adrs;
tmp_color=((current_gc.c<<16)|tmp_color);
}
apd_LCDSetColor(tmp_color);
LCDSetPixelByWord(adrs,tmp_color);
return;
}
/******************************************************************************
@@
@@ [Name] : LCDDrawVline
@@
@@ [Summary] : Draw vertical line
@@
@@ [Argument] : sp : Coordinate data of the start point
@@ ep : Y coordinate data of the end point
@@ bit_mask : The initialize value of line type bit mask
@@
@@ [Return] : None
@@
@@ [Desc] : Draw the specific vertical data according to the current
@@ attribute.
@@ Valid atteribute : Color, Raster operation, Line width,
@@ Line type
@@
@@ [History] : Date Modifier Comment
@@
@@ [END]
******************************************************************************/
static void LCDDrawVline
(
APD_LCD_POINT *sp,
unsigned short yp,
unsigned char *bit_mask
)
{
unsigned short y;
unsigned long *adrs; /* The address to write pixel data */
unsigned char hword, byte, bit; /* Half word, byte, bit offset */
/* Case of less than 1 line width */
if (current_gc.lw <= 1) {
/* Get the address to write pixel data */
LCDGetPixelAdrs(sp, &adrs, &hword, &byte, &bit);
/* Write the address pixel data */
for ( y = sp->y; y <= yp; y++) {
if (current_line_pat & *bit_mask)
//LCDSetPixelByShort(adrs, current_gc.c);
LCDWritePixel(adrs, hword, byte, bit, current_gc.c);
adrs += LCD_OFSTPL/2;
#if ((APD_LCD_WIDTH*APD_LCD_BPP % 32) != 0)
hword = (0 == hword) ? 1 : 0;
#endif/*(((APD_LCD_WIDTH*LCDRAM_PIXEL_BYTES) % 4) == 2)*/
*bit_mask >>= 1;
if(*bit_mask == 0) *bit_mask = LCD_PAT_MASK;
}
}
else {
APD_LCD_POINT p1, p2;
APD_LCD_LINE_TYPE lt_bak;
unsigned char lp_bak;
APD_LCD_LINE_WIDTH lw_bak;
/* Set horizontal line for line width */
if (sp->x < (current_gc.lw >> 1))
p1.x = 0;
else
p1.x = sp->x - (current_gc.lw >> 1);
p2.x = sp->x + (current_gc.lw & 0x01);
/* Save line type and width */
lt_bak = current_gc.lt;
lp_bak = current_line_pat;
lw_bak = current_gc.lw;
#if (APD_LCD_BPP == 16)
current_line_pat = LCD_LINE_PAT[APD_LCD_LINE_SOLID];
#else
current_gc.lt = APD_LCD_LINE_SOLID;
#endif
current_gc.lw = APD_LCD_LINE_THIN;
/* Draw horizontal line for line width */
for ( y = sp->y; y <= yp; y++) {
p1.y = p2.y = y;
if (lp_bak & *bit_mask)
apd_LCDDrawHline(&p1, &p2);
*bit_mask >>= 1;
if (*bit_mask == 0)
*bit_mask = LCD_PAT_MASK;
}
/* Return line type and width */
current_gc.lt = lt_bak;
current_line_pat = lp_bak;
current_gc.lw = lw_bak;
}
return;
}
/******************************************************************************
@@
@@ [Name] : apd_LCDDrawVline
@@
@@ [Summary] : Draw Vertical line segment
@@
@@ [Argument] : sp : Coordinate data of the start point
@@ ep : Coordinate data of the end point
@@
@@ [Return] : None
@@
@@ [Desc] : Draw the specific vertical segment data according to
@@ the current attribute.
@@ Include the start point in line segment, but not
@@ the end point
@@ Valid attribute : Color, Raster operation, Line width,
@@ Line type
@@
@@ [History] : Date Modifier Comment
@@
@@ [END]
******************************************************************************/
void apd_LCDDrawVline(APD_LCD_POINT *sp,APD_LCD_POINT *ep)
{
APD_LCD_POINT p1, p2;
unsigned char bit_mask;
/* Exchange the start point for the end point */
if(sp->y > ep->y) {
p1.x = ep->x;
p1.y = ep->y;
p2.x = sp->x;
p2.y = sp->y;
}
else {
p1.x = sp->x;
p1.y = sp->y;
p2.x = ep->x;
p2.y = ep->y;
}
/* Check the area to draw */
/* Include the start point */
if (p1.x < 0 || p1.y >= APD_LCD_HEIGHT || p1.x >= APD_LCD_WIDTH ||
p2.y < 0)
return;
if (p1.y < 0)
p1.y = 0;
/* Not include the end point */
if (p2.y >= APD_LCD_HEIGHT)
p2.y = APD_LCD_HEIGHT - 1;
/* Draw vartical line for DPSTN */
#ifdef APD_LCD_DPSTN
if (p1.y < APD_LCD_LPP && p2.y >= APD_LCD_LPP) {
APD_LCD_POINT mp;
/* Set line type pattern */
bit_mask = LCD_PAT_MASK;
/* Draw part of vertical line */
LCDDrawVline(&p1, APD_LCD_LPP, &bit_mask);
/* Set the boundary coordinate between upper panel and lower panel */
mp.x = p1.x;
mp.y = APD_LCD_LPP;
/* Draw part of vertical line */
LCDDrawVline(&mp, p2.y, &bit_mask);
}
else {
/* Set line type pattern */
bit_mask = LCD_PAT_MASK;
/* Draw part of vertical line */
LCDDrawVline(&p1, p2.y, &bit_mask);
}
/* Draw vertical line for single panel */
#else
/* Set line type pattern */
bit_mask = LCD_PAT_MASK;
/* Draw part of vertical line */
LCDDrawVline(&p1, p2.y, &bit_mask);
#endif /* APD_LCD_DPSTN */
return;
}
/******************************************************************************
@@
@@ [Name] : apd_LCDDrawHline
@@
@@ [Summary] : Draw horizontal line segment
@@
@@ [Argument] : sp : Coordinate data of the start point
@@ ep : Coordinate data of the end point
@@ [Return] : None
@@
@@ [Desc] : Draw the specific horizontal line data according to
@@ the current attribute.
@@ Include the start point in line segment,
@@ but not the end point.
@@ Valid attribute : Color, Raster operation, Line width,
@@ Line type
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -