/*
 * This file is subject to the terms of the GFX License. If a copy of
 * the license was not distributed with this file, you can obtain one at:
 *
 *              http://ugfx.org/license.html
 */

#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H


/****** 定义LCD接口 *********/
sbit LCD_RS  = P4^5;
sbit LCD_WR  = P4^2;
sbit LCD_CS  = P4^3;
sbit LCD_RST = P4^1;
sfr	 LCD_BUS_H = 0xE8;	//P0--0x80,P1=0x90,P2=0xA0,P3=0x0B0, P6= 0xE8
sfr	 LCD_BUS_L = 0xA0;	//P0--0x80,P1=0x90,P2=0xA0,P3=0x0B0, P6= 0xE8


/**** LCD基本操作宏定义 ***********/

#define LCD_CS_SET()		LCD_CS = 1
#define LCD_CS_CLR()		LCD_CS = 0

#define LCD_RST_SET()		LCD_RST = 1
#define LCD_RST_CLR()		LCD_RST = 0

#define LCD_RS_SET()		LCD_RS = 1
#define LCD_RS_CLR()		LCD_RS = 0

#define LCD_WR_SET()		LCD_WR = 1
#define LCD_WR_CLR()		LCD_WR = 0

#define LCD_RD_SET()		LCD_RD = 1
#define LCD_RD_CLR()		LCD_RD = 0

#define LCD_WriteWord(n) 	LCD_BUS_H = (uint8_t)(n>>8); LCD_BUS_L = (uint8_t)n; NOP(1);	LCD_WR_CLR(); NOP(1);	LCD_WR_SET();	NOP(1);	

#define	LCD_WR_PULSE()		NOP(1);	LCD_WR_CLR(); NOP(1);	LCD_WR_SET()


#define X_DOTS			320		//480: 横看，320：竖看。

#if (X_DOTS == 320)
	#define Y_DOTS			480
#elif (X_DOTS == 480)
	#define Y_DOTS			320
#endif

//画笔颜色
#define WHITE       0xFFFF	//白色
#define BLACK      	0x0000	//黑色	  
#define BLUE       	0x001F	//蓝色  
#define BRED        0XF81F
#define GRED 		0XFFE0
#define GBLUE		0X07FF	//
#define RED         0xF800	//红色
#define MAGENTA     0xF81F	//洋红 品红 紫红
#define GREEN       0x07E0	//绿色
#define CYAN        0x7FFF	//蓝绿色
#define YELLOW      0xFFE0	//黄色
#define BROWN 		0XBC40	//棕色
#define BRRED 		0XFC07	//棕红色
#define GRAY  		0X8430	//灰色


//========================================================================
// 函数: void LCD_delay(uint16_t ms)
// 描述: 延时函数
// 参数: ms 延时时间 1~65535 ms
// 返回: 无
// 版本:
//========================================================================
void LCD_delay(uint16_t ms)
{
    uint16_t i;
	do{
	//	i = MAIN_Fosc / 14000;	//STC12F
	//	i = MAIN_Fosc / 13000;	//STC15F
	//	i = MAIN_Fosc / 10000;	//STC8
		i = MAIN_Fosc / 6000;	//STC32G
		while(--i)	;
    }while(--ms);
}


//========================================================================
// 函数: void LCD_WR_REG(uint8_t cmd)
// 描述: 写一个字节的命令至LCD中的控制寄存器当中
// 参数: cmd: 寄存器命令
// 返回: 无
// 备注: 
// 版本:
//      2007/04/10      First version
//========================================================================
void LCD_WR_REG(uint16_t cmd)
{
	LCD_RS_CLR();			//point to ID register
	LCD_CS_CLR();
	LCD_BUS_H = (uint8_t)(cmd>>8);
	LCD_BUS_L = (uint8_t)cmd;
	LCD_WR_PULSE();
	LCD_RS_SET();			//point to GRAM
	LCD_CS_SET();
}

//=========== 写一个字节的数据至LCD中的控制寄存器当中 ===================
void LCD_WR_DATA(uint16_t dat)
{
//	LCD_RS_SET();			//point to GRAM
	LCD_CS_CLR();
	LCD_BUS_H = (uint8_t)(dat>>8);
	LCD_BUS_L = (uint8_t)dat;
	LCD_WR_PULSE();
	LCD_CS_SET();
}

void	SetView_H(void)		//横屏
{
	LCD_WR_REG(0x36);
//	LCD_WR_DATA(0x28);		//横屏
	LCD_WR_DATA(0x6B);		//横屏 旋转180度

	LCD_WR_REG(0x2A);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(((480-1)>>8));
	LCD_WR_DATA(((480-1)&0xff));

	LCD_WR_REG(0x2B);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(((320-1)>>8));
	LCD_WR_DATA(((320-1)&0xff));
}
void	SetView_V(void)		//竖屏
{
	LCD_WR_REG(0x36);
//	LCD_WR_DATA(0x0A);		//竖屏
	LCD_WR_DATA(0x49);		//竖屏 旋转180度

	LCD_WR_REG(0x2A);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(((320-1)>>8));
	LCD_WR_DATA(((320-1)&0xff));

	LCD_WR_REG(0x2B);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(((480-1)>>8));
	LCD_WR_DATA(((480-1)&0xff));
}


//========================================================================
// 函数: void LCD480x320_Init(void)
// 描述: LCD初始化程序，在里面会完成LCD初始所需要设置的许多寄存器，具体如果
//		 用户想了解，建议查看DataSheet当中各个寄存器的意义
// 参数: 无 
// 返回: 无
// 版本: V1.0
//========================================================================
void LCD_Init(void)
{
//	P6n_standard(0xff);
//	P2n_standard(0xff);
//	P4n_standard(0x2e);

//	background = 0x00;
//	foreground = 0xffff;

	LCD_RS_SET();
	LCD_CS_SET();
	LCD_BUS_H = 0xFF;
	LCD_BUS_L = 0xFF;
	LCD_WR_SET();

	LCD_RST_SET();
	LCD_delay(150);
	LCD_RST_CLR();
	LCD_delay(150);
	LCD_RST_SET();
	LCD_delay(150);

	//************* ILI9481初始化**********//
	LCD_WR_REG(0x11);
	LCD_delay(20);
	LCD_WR_REG(0xD0);
	LCD_WR_DATA(0x07);
	LCD_WR_DATA(0x42);
	LCD_WR_DATA(0x18);
	
	LCD_WR_REG(0xD1);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x07);//07
	LCD_WR_DATA(0x10);
	
	LCD_WR_REG(0xD2);
	LCD_WR_DATA(0x01);
	LCD_WR_DATA(0x02);
	
	LCD_WR_REG(0xC0);
	LCD_WR_DATA(0x10);
	LCD_WR_DATA(0x3B);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x02);
	LCD_WR_DATA(0x11);
	
	LCD_WR_REG(0xC5);
	LCD_WR_DATA(0x03);
	
	LCD_WR_REG(0xC8);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x32);
	LCD_WR_DATA(0x36);
	LCD_WR_DATA(0x45);
	LCD_WR_DATA(0x06);
	LCD_WR_DATA(0x16);
	LCD_WR_DATA(0x37);
	LCD_WR_DATA(0x75);
	LCD_WR_DATA(0x77);
	LCD_WR_DATA(0x54);
	LCD_WR_DATA(0x0C);
	LCD_WR_DATA(0x00);
	
	LCD_WR_REG(0x36);
	#if (X_DOTS == 320)
		LCD_WR_DATA(0x0A);
	#endif
	#if (X_DOTS == 480)
		LCD_WR_DATA(0x28);
	#endif
	
	LCD_WR_REG(0x3A);
	LCD_WR_DATA(0x55);
	
	LCD_WR_REG(0x2A);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
//	LCD_WR_DATA(0x01);
//	LCD_WR_DATA(0x3F);
	LCD_WR_DATA(((X_DOTS-1)>>8));
	LCD_WR_DATA(((X_DOTS-1)&0xff));
	
	LCD_WR_REG(0x2B);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
//	LCD_WR_DATA(0x01);
//	LCD_WR_DATA(0xE0);
	LCD_WR_DATA(((Y_DOTS-1)>>8));
	LCD_WR_DATA(((Y_DOTS-1)&0xff));

	LCD_delay(120);
	LCD_WR_REG(0x21);	//取反显示, 有的屏要取反才是正常显示
	LCD_WR_REG(0x29);
	LCD_WR_REG(0x2c);

	//设置LCD属性参数
	SetView_V();		//竖屏
}


/*************************************************
函数: void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd)
功能: 设置lcd显示窗口，在此区域写点数据自动换行. 每行从 xStar开始 到yStar结束, 如果xStar==yStar则只写一点便换行, 可以用于画竖线.
入口: xy起点和终点
返回: 无
*************************************************/
void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd)
{
	LCD_WR_REG(0x2a);	
	LCD_WR_DATA((uint8_t)(xStar>>8));
	LCD_WR_DATA((uint8_t)(xStar &0xff));		
	LCD_WR_DATA((uint8_t)(xEnd>>8));
	LCD_WR_DATA((uint8_t)(xEnd &0xff));

	LCD_WR_REG(0x2b);	
	LCD_WR_DATA((uint8_t)(yStar>>8));
	LCD_WR_DATA((uint8_t)(yStar &0xff));		
	LCD_WR_DATA((uint8_t)(yEnd>>8));
	LCD_WR_DATA((uint8_t)(yEnd &0xff)); 

	LCD_WR_REG(0x2c);	//开始写入GRAM
}   

static GFXINLINE void init_board(GDisplay *g) {
	UNUSED(g); /* support KeilC251 */
    LCD_Init();
}

static GFXINLINE void post_init_board(GDisplay *g) {
	UNUSED(g); /* support KeilC251 */
}

static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) {
	UNUSED(g); /* support KeilC251 */
	LCD_RST=!state;
}

static GFXINLINE void set_backlight(GDisplay *g, uint8_t percent) {
	UNUSED(g); /* support KeilC251 */
	UNUSED(percent); /* support KeilC251 */
}

static GFXINLINE void acquire_bus(GDisplay *g) {
	UNUSED(g); /* support KeilC251 */
}

static GFXINLINE void release_bus(GDisplay *g) {
	UNUSED(g); /* support KeilC251 */
}

static GFXINLINE void write_index(GDisplay *g, uint16_t index) {
	UNUSED(g); /* support KeilC251 */
	LCD_WR_REG(index);
}

static GFXINLINE void write_data(GDisplay *g, uint16_t _data_) {
	UNUSED(g); /* support KeilC251 */
	LCD_WR_DATA(_data_);
}

static GFXINLINE void setreadmode(GDisplay *g) {
	UNUSED(g); /* support KeilC251 */
}

static GFXINLINE void setwritemode(GDisplay *g) {
	UNUSED(g); /* support KeilC251 */
}

static GFXINLINE uint16_t read_data(GDisplay *g) {
	UNUSED(g); /* support KeilC251 */
	return 0;
}

#endif /* _GDISP_LLD_BOARD_H */
