#include "def.h"
#include "library.h"
#include "system.h"
#include "sysc.h"
#include "lcd.h"
#include "1wire.h"
#include "logo.h"
//typedef unsigned int u32;
#define GPICON *(volatile u32*)0x7f008100
#define GPJCON *(volatile u32*)0x7f008120
#define GPFCON *(volatile u32*)0x7f0080a0
#define MIFPCON *(volatile u32*)0x7410800c
//LCD_BASE
#define LCD_BASE (0x77100000)
//Timing parameter
#define VBPD ((8-1)&0xff)
#define VFPD ((8-1)&0xff)
#define VSPW ((1)&0xff)
#define HBPD ((40-1)&0xff)
#define HFPD ((5-1)&0xff)
#define HSPW ((1)&0xff)
//LCD 尺寸
#define LCD_X_SIZE (480)
#define LCD_Y_SIZE (272)
//LCD Frame Rate
#define LCD_FRM_RATE 59 //LCD Frame Rate (Hz)
//LCD帧缓冲起始地址
#define LCD_FBUF_ST 0x52000000
//LCD SFR Write/Read, offset 在lcd.h中定义
#define LcdcOutp32(offset, x) Outp32(LCD_BASE+offset, x)
#define LcdcInp32(offset) Inp32(LCD_BASE+offset)
//16位颜色码
#define RED 0xFF0000
#define GREEN 0x00FF00
#define BLUE 0x0000FF
#define WHITE 0xFFFFFF
#define BLACK 0x0
#define GRAY 0x8C51
//函数声明
void delay(int times);
void Paint_Bmp(int x0, int y0, int h, int v, const unsigned char bmp[]);
void LCD_Clear(int color);
void Lcd_Init(void);
//LCD_BUFFER,缓冲区尺寸和LCD尺寸一致
volatile unsigned int (*LCD_BUFFER)[LCD_X_SIZE]
= (volatile unsigned int(*)[LCD_X_SIZE])LCD_FBUF_ST;
/*
* 程序入口
* */
int main(void)
{
//用这个函数主要是获得g_PCLK、g_HCLK的值
SYSC_GetClkInform();
Uart_Printf( "\nLCD 测试, press ESC key to exit !\n" ) ;
Lcd_Init();
one_wire_init(); //背光及触屏均需要一线IO驱动
while (0x1b != Uart_Getch()) {
LCD_Clear(RED);
delay(8000);
LCD_Clear(GREEN);
delay(8000);
LCD_Clear(BLUE);
delay(8000);
LCD_Clear(0xffffff);
delay(8000);
LCD_Clear(0x0);
delay(8000);
LCD_Clear(GRAY);
// Paint_Bmp(90, 80, 300, 112, gImage_logo);
delay(18000);
}
Uart_Printf( "\nLCD 测试结束!\n" ) ;
while(1);
}
/*
* 延时函数
* */
void delay(int times)
{
int i;
for(;times>0;times--)
for(i=0;i<3000;i++);
}
/*
* 在LCD屏幕上指定坐标点画一个指定大小的图片
* */
void Paint_Bmp(int x0, int y0, int h, int v, const unsigned char bmp[])
{
int x, y;
u32 c;
int p = 0;
for(y=y0; y<v+y0; y++) {
for(x=x0; x<h+x0; x++) {
c=bmp[p] | (bmp[p+1]<<8);
if ( (x< LCD_X_SIZE) && (y<LCD_Y_SIZE) )
LCD_BUFFER[y][x] = c;
p = p + 2 ;
}
}
}
/*
* 在LCD屏幕上指定坐标点画一个指定大小的图片
* */
void LCD_Clear(int color)
{
int x,y;
for(y=0; y<LCD_Y_SIZE; y++) {
for(x=0; x<LCD_X_SIZE; x++) {
LCD_BUFFER[y][x] = color;
}
}
}
/*
* 开启Lcd输出函数
* */
void LCD_Start(void)
{
u32 uLcdCon;
uLcdCon = LcdcInp32(rVIDCON0);
uLcdCon |= 0x3<<0;
LcdcOutp32(rVIDCON0, uLcdCon);
}
/*
* 终止Lcd输出函数
* */
void LCD_Stop(void)
{
u32 uLcdCon;
uLcdCon = LcdcInp32(rVIDCON0);
uLcdCon &= ~(0x3<<0);
LcdcOutp32(rVIDCON0, uLcdCon);
while (1) {
uLcdCon=LcdcInp32(rVIDCON0);
// 检测lcd控制信号和视频输出是否确实停止了
if( (uLcdCon&0x03) == 0 )
break;
}
}
/*
* 设置Lcd时钟源为HCLK
* */
static void LCD_SetClkSrc(void)
{
u32 uVidConVal;
uVidConVal = LcdcInp32(rVIDCON0); //HCLK
uVidConVal &= ~(0x3<<2);
uVidConVal |= (0x0<<2);
LcdcOutp32(rVIDCON0, uVidConVal);
}
/*
* 获得LCD时钟ClkVal、ClkDir
* */
void LCD_GetClkValAndClkDir(u32 uLcdHSz, u32 uLcdVSz, u32 *uClkVal, u32 *uClkDir)
{
double dVclkSrc;
LCD_SetClkSrc();
dVclkSrc = g_HCLK;
uLcdHSz+= HBPD + HFPD + HSPW +3;
uLcdVSz+= VBPD + VFPD + VSPW +3;
// Frame Rate = 1/[{(VSPW+1)+(VBPD+1)+(LIINEVAL+1)+(VFPD+1)} x {(HSPW+1)+(HBPD+1)
// +(HFPD+1)+(HOZVAL+1)} x {(CLKVAL+1)/(Frequency of Clock source)}]
//dTmpVal = dVclkSrc/(double)(1*uLcdHSz*uLcdVSz*LCD_FRM_RATE) - 1;
//RGB_VCLK(Hz)=HCLK/(CLKVAL+1)-->CLKVAL=HCLK/RGB_VCLK(Hz)-1
*uClkVal = dVclkSrc/9000000-1;
*uClkDir = (*uClkVal<1) ? 0 : 1;
}
/*
* LCD all Windows On\Off
* */
void LCD_SetAllWinOnOff(u32 uOnOff)
{
u32 uWinTemp[5];
uWinTemp[0]=LcdcInp32(rWINCON0);
uWinTemp[1]=LcdcInp32(rWINCON1);
uWinTemp[2]=LcdcInp32(rWINCON2);
uWinTemp[3]=LcdcInp32(rWINCON3);
uWinTemp[4]=LcdcInp32(rWINCON4);
if (uOnOff) {
LcdcOutp32(rWINCON0, uWinTemp[0]|(1<<0));
LcdcOutp32(rWINCON1, uWinTemp[1]|(1<<0));
LcdcOutp32(rWINCON2, uWinTemp[2]|(1<<0));
LcdcOutp32(rWINCON3, uWinTemp[3]|(1<<0));
LcdcOutp32(rWINCON4, uWinTemp[4]|(1<<0));
} else {
LcdcOutp32(rWINCON0, uWinTemp[0]&~(1<<0));
LcdcOutp32(rWINCON1, uWinTemp[1]&~(1<<0));
LcdcOutp32(rWINCON2, uWinTemp[2]&~(1<<0));
LcdcOutp32(rWINCON3, uWinTemp[3]&~(1<<0));
LcdcOutp32(rWINCON4, uWinTemp[4]&~(1<<0));
}
}
/*
* LCD Win 0 Regs Init
* @因为仅使用了Win 0,所以这里只对Win 0相关寄存器做初始化
* */
void LCD_InitWin0Regs(void)
{
u32 uWinTemp;
u32 uWinConXRegVal;
u32 uLcdEndX, uLcdEndY;
u32 uFbStAddr;
u32 uFbEndAddr;
uWinConXRegVal = 0;
// Input path is DMA
// DMA、BUF0、BUFAUTO DISABLE、BITSWP DISABLE、HAWSWP ENABLE
// MAX_BURSTLEN_16WORD、MIN_BURSTLEN_16WORD、BPPMODE_F_16BPP_565
uWinConXRegVal =
(0<<22) | (0<<20) | (0<<19) | (0<<18) |
(0<<17) | (0<<16) | (0<<11) | (0<<9) |
(0xb<<2) | (0<<0);
LcdcOutp32(rWINCON0, uWinConXRegVal);
//Win 0 size
LcdcOutp32(rVIDOSD0C, LCD_X_SIZE * LCD_Y_SIZE);
uFbStAddr = LCD_FBUF_ST;
uFbEndAddr = uFbStAddr + (LCD_X_SIZE*4)*(LCD_Y_SIZE);
LcdcOutp32(rVIDW00ADD0B0, LCD_FBUF_ST);
LcdcOutp32(rVIDW00ADD1B0, uFbEndAddr);
LcdcOutp32(rVIDW00ADD2, (LCD_X_SIZE*4) );
uLcdEndX = LCD_X_SIZE - 1;
uLcdEndY = LCD_Y_SIZE - 1;
// Progressive mode
LcdcOutp32(rVIDOSD0A, (0<<11) | (0<<0));
LcdcOutp32(rVIDOSD0B, (uLcdEndX<<11) | (uLcdEndY<<0));
// Turn Win 0 on
uWinTemp =LcdcInp32(rWINCON0);
LcdcOutp32(rWINCON0, uWinTemp|(1<<0));
}
/*
* Lcd初始化函数
* */
void Lcd_Port_Init(void)
{
#define rGPICON 0x7F008100
#define rGPJCON 0x7F008120
#define rSPCON 0x7F0081A0
u32 uRegValue;
(*(volatile unsigned *)0x7410800c)=0; //Must be '0' for Normal-path instead of By-pass
//Set LCD Type
uRegValue = Inp32(rSPCON);
uRegValue = (uRegValue & ~(0x3<<0)) | (1<<0);
Outp32(rSPCON, uRegValue);
//Set LCD GPIO Port
Outp32(rGPICON, 0xaaaaaaaa); //GPI[15..0]-> RGB VD[15..0]
Outp32(rGPJCON, 0xaaaaaaaa); //GPJ[7..0]-> RGB VD[23..16], GPJ[11..8]-> VCLK, VDEN, VSYNC, HSYNC
}
/*
* Lcd初始化函数
* */
void Lcd_Init(void)
{
u32 uVidconReg, uILcdIntCon;
u32 uClkVal, uClkDir;
Lcd_Port_Init();
MIFPCON &=~(1<<3);
// IHSYNC_INVERT、IVSYNC_INVERT、IVDEN_NORMAL
LcdcOutp32(rVIDCON1, (0<<7) |(1<<6) | (1<<5) |(0<<4));
LcdcOutp32(rVIDTCON0, (VBPD<<24) | (VBPD<<16) | (VFPD<<8) | (VSPW<<0));
LcdcOutp32(rVIDTCON1, (VFPD<<24) | (HBPD<<16) | (HFPD<<8) | (HSPW<<0));
LcdcOutp32(rVIDTCON2, ((LCD_Y_SIZE-1)<<11) | ((LCD_X_SIZE-1)<<0));
// RDITHPOS_8BIT、GDITHPOS_8BIT、BDITHPOS_8BIT、DITHERING_DISABLE
// LcdcOutp32(rDITHMODE, 0);
LCD_Stop();
//设置LCD时钟源
LCD_GetClkValAndClkDir(LCD_X_SIZE, LCD_Y_SIZE, &uClkVal, &uClkDir);
//Progressive、RGB I/F、16 BPP、RGB Parallel format、CLKVALUP always、VCLKEN_DISABLE
uVidconReg =
(0<<29) | (0<<26) | (0<<23) | (0<<20) | (0<<17) | (0<<16) |
(uClkVal<<6) | (1<<5) | (uClkDir<<4) | (0<<2)| (0<<1) | (0<<0);
LcdcOutp32(rVIDCON0, uVidconReg);
uILcdIntCon =LcdcInp32(rVIDINTCON0);
//FRAMESEL0_BACK、FRAMESEL1_BACK、Interrupt Disable、FIFOSEL_WIN0、FIFOLEVEL_25
//INTFIFOEN_DISABLE、INTEN_DISABLE
LcdcOutp32(rVIDINTCON0, uILcdIntCon | (0<<15) | (0<<13) | (0<<12) |
(1<<5) | (0<<2) | (0<<1) | (0<<0) );
LCD_SetAllWinOnOff(0); // Turn all windows off
LCD_InitWin0Regs(); //初始化(并开启)Win 0
LCD_Start();
return;
}