//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Header: S3C6410_display.h
//
// Defines the Display Controller CPU register layout and definitions.
//
#ifndef __LCD_H_
#define __LCD_H_
#define LCD_WINDOW_BUFFER 0x52000000
#define LCD_WIDTH 480
#define LCD_HEIGHT 272
#define RGB(r,g,b) ((uint16)( (((uint16)(r&0xF8))<<8) | (((uint16)(g&0xFC))<<4) | (((uint16)(b&0xF8))>>3) ))
#define BLACK 0x0000 /* 黑色: 0, 0, 0 */
#define NAVY 0x000F /* 深蓝色: 0, 0, 128 */
#define DGREEN 0x03E0 /* 深绿色: 0, 128, 0 */
#define DCYAN 0x03EF /* 深青色: 0, 128, 128 */
#define MAROON 0x7800 /* 深红色:128, 0, 0 */
#define PURPLE 0x780F /* 紫色: 128, 0, 128 */
#define OLIVE 0x7BE0 /* 橄榄绿:128, 128, 0 */
#define LGRAY 0xC618 /* 灰白色:192, 192, 192 */
#define DGRAY 0x7BEF /* 深灰色:128, 128, 128 */
#define BLUE 0x001F /* 蓝色: 0, 0, 255 */
#define GREEN 0x07E0 /* 绿色: 0, 255, 0 */
#define CYAN 0x07FF /* 青色: 0, 255, 255 */
#define RED 0xF800 /* 红色: 255, 0, 0 */
#define MAGENTA 0xF81F /* 品红: 255, 0, 255 */
#define YELLOW 0xFFE0 /* 黄色: 255, 255, 0 */
#define WHITE 0xFFFF /* 白色: 255, 255, 255 */
extern void LCD_Init(void);
//------------------------------------------------------------------------------
// Type: S3C6410_DISPLAY_REG
//
// Display Controller registers. This register bank is located by the constant
// CPU_BASE_REG_XX_DISPLAY in the configuration file cpu_base_reg_cfg.h.
//
#define LCD_REGS_BASE_ADDR 0x77100000
typedef struct
{
uint32 VIDCON0; // 0x00
uint32 VIDCON1; // 0x04
uint32 VIDCON2; // 0x08
uint32 PAD0; // 0x0c
uint32 VIDTCON0; // 0x10
uint32 VIDTCON1; // 0x14
uint32 VIDTCON2; // 0x18
uint32 VIDTCON3; // 0x1c
uint32 WINCON0; // 0x20
uint32 WINCON1; // 0x24
uint32 WINCON2; // 0x28
uint32 WINCON3; // 0x2c
uint32 WINCON4; // 0x30
uint32 PAD2[3]; // 0x34~3f
uint32 VIDOSD0A; // 0x40
uint32 VIDOSD0B; // 0x44
uint32 VIDOSD0C; // 0x48
uint32 PAD3[1]; // 0x4c
uint32 VIDOSD1A; // 0x50
uint32 VIDOSD1B; // 0x54
uint32 VIDOSD1C; // 0x58
uint32 VIDOSD1D; // 0x5c
uint32 VIDOSD2A; // 0x60
uint32 VIDOSD2B; // 0x64
uint32 VIDOSD2C; // 0x68
uint32 VIDOSD2D; // 0x6c
uint32 VIDOSD3A; // 0x70
uint32 VIDOSD3B; // 0x74
uint32 VIDOSD3C; // 0x78
uint32 PAD4[1]; // 0x7c
uint32 VIDOSD4A; // 0x80
uint32 VIDOSD4B; // 0x84
uint32 VIDOSD4C; // 0x88
uint32 PAD5[1]; // 0x8c
uint32 PAD6[4]; // 0x90~9f
uint32 VIDW00ADD0B0; // 0xa0
uint32 VIDW00ADD0B1; // 0xa4
uint32 VIDW01ADD0B0; // 0xa8
uint32 VIDW01ADD0B1; // 0xac
uint32 VIDW02ADD0; // 0xb0
uint32 PAD7[1]; // 0xb4
uint32 VIDW03ADD0; // 0xb8
uint32 PAD8[1]; // 0x8c
uint32 VIDW04ADD0; // 0xc0
uint32 PAD9[3]; // 0xc4 ~ 0xcf
uint32 VIDW00ADD1B0; // 0xd0
uint32 VIDW00ADD1B1; // 0xd4
uint32 VIDW01ADD1B0; // 0xd8
uint32 VIDW01ADD1B1; // 0xdc
uint32 VIDW02ADD1; // 0xe0
uint32 PAD10[1]; // 0xe4
uint32 VIDW03ADD1; // 0xe8
uint32 PAD11[1]; // 0xec
uint32 VIDW04ADD1; // 0xf0
uint32 PAD12[3]; // 0xf4 ~ 0xff
uint32 VIDW00ADD2; // 0x100
uint32 VIDW01ADD2; // 0x104
uint32 VIDW02ADD2; // 0x108
uint32 VIDW03ADD2; // 0x10c
uint32 VIDW04ADD2; // 0x110
uint32 PAD13[3]; // 0x114 ~ 0x11f
uint32 PAD14[4]; // 0x120 ~ 0x12f
uint32 VIDINTCON0; // 0x130
uint32 VIDINTCON1; // 0x134
uint32 PAD15[2]; // 0x138 ~ 0x13f
uint32 W1KEYCON0; // 0x140
uint32 W1KEYCON1; // 0x144
uint32 W2KEYCON0; // 0x148
uint32 W2KEYCON1; // 0x14c
uint32 W3KEYCON0; // 0x150
uint32 W3KEYCON1; // 0x154
uint32 W4KEYCON0; // 0x158
uint32 W4KEYCON1; // 0x15c
uint32 PAD16[4]; // 0x160 ~ 0x16f
uint32 DITHMODE; // 0x170
uint32 PAD17[3]; // 0x174~17f
uint32 WIN0MAP; //0x180,
uint32 WIN1MAP; // 0x184
uint32 WIN2MAP; // 0x188
uint32 WIN3MAP; // 0x18c
uint32 WIN4MAP; //0x190
uint32 PAD18[3]; // 0x194~19f
uint32 WPALCON; //0x1a0
uint32 TRIGCON; //0x1a4
uint32 PAD19[2]; // 0x1a8~17f
uint32 I80IFCONA0; // 0x1b0
uint32 I80IFCONA1; // 0x1b4
uint32 I80IFCONB0; // 0x1b8
uint32 I80IFCONB1; // 0x1bc
uint32 PAD21[4]; // 0x1c0 ~ 0x1cf
uint32 LDI_CMDCON0; // 0x1d0
uint32 LDI_CMDCON1; //0x1d4
uint32 PAD22[2]; // 0x1d8~1df
uint32 SIFCCON0; // 0x1e0
uint32 SIFCCON1; //0x1e4
uint32 SIFCCON2; //0x1e8
uint32 PAD23[1]; //0x1ec
uint32 PAD24[36]; //0x1f0 ~ 0x27f
uint32 LDI_CMD0; //0x280
uint32 LDI_CMD1; //0x284
uint32 LDI_CMD2; //0x288
uint32 LDI_CMD3; //0x28c
uint32 LDI_CMD4; //0x290
uint32 LDI_CMD5; //0x294
uint32 LDI_CMD6; //0x298
uint32 LDI_CMD7; //0x29c
uint32 LDI_CMD8; //0x2a0
uint32 LDI_CMD9; //0x2a4
uint32 LDI_CMD10; //0x2a8
uint32 LDI_CMD11; //0x2ac
uint32 PAD25[20]; //0x2b0 ~ 0x2ff
uint32 W2PDATA01; //0x300
uint32 W2PDATA23; //0x304
uint32 W2PDATA45; //0x308
uint32 W2PDATA67; //0x30c
uint32 W2PDATA89; //0x310
uint32 W2PDATAAB; //0x314
uint32 W2PDATACD; //0x318
uint32 W2PDATAEF; //0x31c
uint32 W3PDATA01; //0x320
uint32 W3PDATA23; //0x324
uint32 W3PDATA45; //0x328
uint32 W3PDATA67; //0x32c
uint32 W3PDATA89; //0x330
uint32 W3PDATAAB; //0x334
uint32 W3PDATACD; //0x338
uint32 W3PDATAEF; //0x33c
uint32 W4PDATA01; //0x340
uint32 W4PDATA23; //0x344
uint32 PAD26[2]; //0x348~0x34f
uint32 PAD27[44]; //0x350~0x3ff
uint32 W0PRAMSTART; //0x400
uint32 PAD28[3]; //0x404~0x40f
uint32 PAD29[252]; //0x410~0x7ff
uint32 W1PRAMSTART; //0x800
} DISPLAY_REGS, *PDISPLAY_REGS;
#define rMOFPCON (*(volatile unsigned int*)0x7410800C)
#define rSPCON (*(volatile unsigned int*)0x7F0081A0)
#endif // __S3C6410_DISPLAY_H
#ifndef __G2D_H_
#define __G2D_H_
#define G2D_REGS_BASE_ADDR 0x76100000 //temporarily used for the IP verfication of 2D v2.0
//------------------------------------------------------------------------------
// Type: G2D_REG
//
// 2D Graphics Acclerator registers. This register bank is located by the constant
// <CPU>_BASE_REG_XX_2DGRAPHICS in the configuration file <cpu>_base_regs.h.
//
void G2D_Init(void);
void G2D_PutPixel(uint32 x,uint32 y,uint16 clr);
typedef struct _reg_g2d_v2
{
// General Registers
uint32 CONTROL; // (G2D_BASE+0x00)
uint32 INTEN; // (G2D_BASE+0x04)
uint32 FIFO_INTC; // (G2D_BASE+0x08)
uint32 INTC_PEND; // (G2D_BASE+0x0c)
uint32 FIFO_STATUS; // (G2D_BASE+0x10)
uint32 PAD1[0x3B];
// Command Registers
uint32 CMDR0; // (G2D_BASE+0x100)
uint32 CMDR1; // (G2D_BASE+0x104)
uint32 CMDR2; // (G2D_BASE+0x108)
uint32 CMDR3; // (G2D_BASE+0x10c)
uint32 CMDR4; // (G2D_BASE+0x110)
uint32 CMDR5; // (G2D_BASE+0x114)
uint32 CMDR6; // (G2D_BASE+0x118)
uint32 CMDR7; // (G2D_BASE+0x11c)
uint32 PAD2[0x38];
// Common Resource Registers
uint32 SRC_RES; // (G2D_BASE+0x200)
uint32 SRC_HORI_RES; // (G2D_BASE+0x204)
uint32 SRC_VERT_RES; // (G2D_BASE+0x208)
uint32 PAD3[1];
uint32 SC_RES; // (G2D_BASE+0x210)
uint32 SC_HORI_RES; // (G2D_BASE+0x214)
uint32 SC_VERT_RES; // (G2D_BASE+0x218)
uint32 PAD4[1];
uint32 CW_LEFT_TOP; // (G2D_BASE+0x220)
uint32 CW_LEFT_TOP_X; // (G2D_BASE+0x224)
uint32 CW_LEFT_TOP_Y; // (G2D_BASE+0x228)
uint32 PAD5[1];
uint32 CW_RIGHT_BOTTOM; // (G2D_BASE+0x230)
uint32 CW_RIGHT_BOTTOM_X; // (G2D_BASE+0x234)
uint32 CW_RIGHT_BOTTOM_Y; // (G2D_BASE+0x238)
uint32 PAD6[0x31];
uint32 COORD0; // (G2D_BASE+0x300)
uint32 COORD0_X; // (G2D_BASE+0x304)
uint32 COORD0_Y; // (G2D_BASE+0x308)
uint32 PAD7[1];
uint32 COORD1; // (G2D_BASE+0x310)
uint32 COORD1_X; // (G2D_BASE+0x314)
uint32 COORD1_Y; // (G2D_BASE+0x318)
uint32 PAD8[1];
uint32 COORD2; // (G2D_BASE+0x320)
uint32 COORD2_X; // (G2D_BASE+0x324)
uint32 COORD2_Y; // (G2D_BASE+0x328)
uint32 PAD9[1];
uint32 COORD3; // (G2D_BASE+0x330)
uint32 COORD3_X; // (G2D_BASE+0x334)
uint32 COORD3_Y; // (G2D_BASE+0x338)
uint32 PAD10[1];
uint32 ROT_OC; // (G2D_BASE+0x340)
uint32 ROT_OC_X; // (G2D_BASE+0x344)
uint32 ROT_OC_Y; // (G2D_BASE+0x348)
uint32 ROT_MODE; // (G2D_BASE+0x34c)
uint32 ENDIAN; // (G2D_BASE+0x350)
uint32 PAD11[0x2b];
uint32 X_INCR; // (G2D_BASE+0x400)
uint32 Y_INCR; // (G2D_BASE+0x404)
uint32 PAD12[2];
uint32 ROP; // (G2D_BASE+0x410)
uint32 PAD13[3];
uint32 ALPHA; // (G2D_BASE+0x420)
uint32 PAD14[0x37];
uint32 FG_COLOR; // (G2D_BASE+0x500)
uint32 BG_COLOR; // (G2D_BASE+0x504)
uint32 BS_COLOR; // (G2D_BASE+0x508)
uint32 PAD141[0x1];
uint32 SRC_COLOR_MODE; // (G2D_BASE+0x510)
uint32 DST_COLOR_MODE; // (G2D_BASE+0x514)
uint32 PAD15[0x3a];
uint32 PATTERN_ADDR[0x20];// (G2D_BASE+0x600~0x67c)
uint32 PAD16[0x20];
uint32 PAT_OFF_XY; // (G2D_BASE+0x700)
uint32 PAT_OFF_X; // (G2D_BASE+0x704)
uint32 PAT_OFF_Y; // (G2D_BASE+0x708)
uint32 PAD17[5];
uint32 COLORKEY_CNTL; // (G2D_BASE+0x720)
uint32 COLORKEY_DR_MIN; // (G2D_BASE+0x724)
uint32 COLORKEY_DR_MAX; // (G2D_BASE+0x728)
uint32 PAD18[1];
uint32 SRC_BASE_ADDR; // (G2D_BASE+0x730)
uint32 DST_BASE_ADDR; // (G2D_BASE+0x734)
}G2D_REGS, *PG2D_REGS;
#endif
1. LCDGPIO和寄存器的初始化
#include "..\inc\config.h"
volatile PDISPLAY_REGS GpDisplayRegs;
void LCD_Init(void)
{
unsigned short *pFB;
int i;
if(!(GpSysRegs->BLK_PWR_STAT & (1<<4))) {
GpSysRegs->NORMAL_CFG |= (1<<14);
while(!(GpSysRegs->BLK_PWR_STAT & (1<<4)));
}
rMOFPCON &= ~(0x01<<3);
rSPCON &= ~(0x03<<0);
rSPCON |= (0x01<<0); //use RGB I/F
GpDisplayRegs = (volatile PDISPLAY_REGS)LCD_REGS_BASE_ADDR;
GpGpioRegs->GPIPUD = 0; // Pull up/down disable
GpGpioRegs->GPICON = 0xAAAAAAAA; // G[5:0], B[4:0]
GpGpioRegs->GPJPUD = 0; // Pull up/down disable
GpGpioRegs->GPJCON = 0xAAAAAAAA; // R[4:0]
GpGpioRegs->GPEPUD &= ~(0x3); // Pull-Up/Down Disable
GpGpioRegs->GPECON &= ~(0xf); // GPE0 -> Output
GpGpioRegs->GPECON |= 0x1;
GpGpioRegs->GPEDAT &= ~(0x1);
GpGpioRegs->GPEDAT |= 0x1;
GpDisplayRegs->VIDCON0 = (0<<29)| //Progressive
(0<<26)| //RGB I/F
(0<<23)| //Only for i80 I/F
(0<<20)| //Only for i80 I/F
(0<<17)| //RGB Parallel format (RGB)
(0<<16)| //
(12<<6)| //VCLK = Video Clock Source / (CLKVAL+1) (HCLK)133Mhz/13 = 10MHz
(0<<5) | //Normal mode ( control by ENVID)
(1<<4) | //Divided by CLKVAL_F
(0<<2) | //HCLK
(0<<1) | //Disable the video output and the Display control signal
(0<<0); //Disable the video output and the Display control signal
GpDisplayRegs->VIDCON1 = (0<<7) | //RGB type LCD driver gets the video data at VCLK falling edge
(1<<6) | //HSYNC inverted
(1<<5) | //VSYNC inverted
(0<<4); //VDEN normal
GpDisplayRegs->VIDCON2 = 0;
GpDisplayRegs->VIDTCON0 = (0<<24)|
(1<<16)|
(1<<8) |
(9<<0);
GpDisplayRegs->VIDTCON1 = (0<<24)|
(1<<16)|
(1<<8) |
(40<<0);
GpDisplayRegs->VIDTCON2 = ((LCD_HEIGHT-1)<<11) |
((LCD_WIDTH-1));
GpDisplayRegs->WINCON0 = (0<<22)| //Dedicated DMA
(0<<20)| //buffer set 0
(0<<19)| //Fixed by BUFSEL
(0<<18)| //Bit swap Disable
(0<<17)| //Byte swaps Disable
(1<<16)| //Half-Word swaps Enable
(0<<9) | //DMA Burst Maximum Length 16 word
(5<<2); //16 BPP (non-palletized, R: 5-G:6-B:5 )
GpDisplayRegs->VIDOSD0A = (0<<11) |
(0<<0);
GpDisplayRegs->VIDOSD0B = ((LCD_WIDTH-1)<<11) |
((LCD_HEIGHT-1)<<0);
GpDisplayRegs->VIDOSD0C = LCD_WIDTH*LCD_HEIGHT;
GpDisplayRegs->VIDW00ADD0B0 = LCD_WINDOW_BUFFER;
GpDisplayRegs->VIDW00ADD1B0 = LCD_WINDOW_BUFFER+LCD_WIDTH*LCD_HEIGHT*2;
GpDisplayRegs->VIDW00ADD2 = (0<<13)|
(LCD_WIDTH*2);
GpDisplayRegs->WINCON0 |= 1<<0;
GpDisplayRegs->VIDCON0 |= ((1<<1) | (1<<0));
pFB = (unsigned short *)LCD_WINDOW_BUFFER;
for (i=0; i<LCD_WIDTH*LCD_HEIGHT; i++) {
*pFB++ = BLACK;
}
}
void LCD_FillScreen(uint16 clr)
{
unsigned short *pFB;
int i;
pFB = (unsigned short *)LCD_WINDOW_BUFFER;
for (i=0; i<LCD_WIDTH*LCD_HEIGHT; i++) {
*pFB++ = clr;
}
}
仅仅测试画线的能力:
#include "..\inc\config.h"
volatile PG2D_REGS GpG2dRegs;
void G2D_Init(void)
{
GpG2dRegs = (volatile PG2D_REGS)G2D_REGS_BASE_ADDR;
GpG2dRegs->ALPHA = ((0<<8) | (0xFF));
GpG2dRegs->ROP = ((1<<13) | (0<<10) | (0<<9) | (0xF0));
GpG2dRegs->ROT_OC_X = (uint32) (0 & 0x000007FF);
GpG2dRegs->ROT_OC_Y = (uint32) (0 & 0x000007FF);
GpG2dRegs->SRC_COLOR_MODE = 0;
GpG2dRegs->SRC_HORI_RES = LCD_WIDTH;
GpG2dRegs->SRC_VERT_RES = LCD_HEIGHT;
GpG2dRegs->SRC_RES = (LCD_HEIGHT<<16)|(LCD_WIDTH);
GpG2dRegs->DST_COLOR_MODE = 0;
GpG2dRegs->SC_HORI_RES = LCD_WIDTH;
GpG2dRegs->SC_VERT_RES = LCD_HEIGHT;
GpG2dRegs->SC_RES = (LCD_HEIGHT<<16)|(LCD_WIDTH);
GpG2dRegs->CW_LEFT_TOP = (0<<16)|(0<<0);
GpG2dRegs->CW_LEFT_TOP_X = 0;
GpG2dRegs->CW_LEFT_TOP_Y = 0;
GpG2dRegs->CW_RIGHT_BOTTOM = ((272-1)<<16)|((480-1));
GpG2dRegs->CW_RIGHT_BOTTOM_X = 480-1;
GpG2dRegs->CW_RIGHT_BOTTOM_Y = 272-1;
GpG2dRegs->SRC_BASE_ADDR = LCD_WINDOW_BUFFER;
GpG2dRegs->DST_BASE_ADDR = LCD_WINDOW_BUFFER;
GpG2dRegs->BG_COLOR = BLACK;
GpG2dRegs->ROT_MODE = 1;
GpG2dRegs->ALPHA = 0;
}
__inline void G2D_WaitAllFin(void)
{
while( (GpG2dRegs->FIFO_STATUS & (1<<9)) == 0 );
}
#define G2D_REND_POINT_BIT (1<<0)
#define G2D_REND_LINE_BIT (1<<1)
void G2D_PutPixel(uint32 x,uint32 y,uint16 clr)
{
GpG2dRegs->COORD0_X = x;
GpG2dRegs->COORD0_Y = y;
GpG2dRegs->FG_COLOR = clr;
GpG2dRegs->CMDR0 = G2D_REND_POINT_BIT;
G2D_WaitAllFin();
}
__inline int __G2D_Abs(int x)
{
if (x < 0) return (0-x);
return x;
}
void G2D_PutLine(uint32 sx,uint32 sy,uint32 ex,uint32 ey,uint16 clr)
{
int nMajorCoordX;
uint32 uHSz, uVSz;
int i;
int nIncr=0;
GpG2dRegs->COORD0_X = sx;
GpG2dRegs->COORD0_Y = sy;
GpG2dRegs->COORD2_X = ex;
GpG2dRegs->COORD2_Y = ey;
GpG2dRegs->FG_COLOR = clr;
uVSz = __G2D_Abs((int)ey - (int)sy);
uHSz = __G2D_Abs((int)ex - (int)sx);
nMajorCoordX = (uHSz>=uVSz);
if(nMajorCoordX) {
for (i=0; i<12; i++) {
uVSz <<= 1;
nIncr <<= 1;
if (uVSz >= uHSz) {
nIncr = nIncr | 1;
uVSz -= uHSz;
}
}
nIncr = (nIncr + 1) >> 1;
if (sy > ey) {
nIncr = (~nIncr) + 1; // 2's complement
}
} else {
for (i=0; i<12; i++) {
uHSz <<= 1;
nIncr <<= 1;
if (uHSz >= uVSz) {
nIncr = nIncr | 1;
uHSz -= uVSz;
}
}
nIncr = (nIncr + 1) >> 1;
if (sx > ex) {
nIncr = (~nIncr) + 1; // 2's complement
}
}
if (nMajorCoordX) {
GpG2dRegs->Y_INCR = (nIncr);
GpG2dRegs->CMDR0 = (1<<1)|(1<<8)|(1<<9);
}else{
GpG2dRegs->X_INCR = (nIncr);
GpG2dRegs->CMDR0 = (1<<1)|(0<<8)|(1<<9);
}
G2D_WaitAllFin();
}