⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.c

📁 嵌入式系统
💻 C
📖 第 1 页 / 共 5 页
字号:
/*-----------------------------------------------------------------------------
@@
@@ (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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -