#include "LT738_Lib.h"
//#include "W25QXX.h"

unsigned char CCLK;    // LT738的内核时钟频率    
unsigned char MCLK;    // SDRAM的时钟频率
unsigned char SCLK;    // LCD的扫描时钟频率

//---------------------------------------------------------------------------------------------------------------------------------

//复位LT738
void LT738_HW_Reset(void)
{	
	/*
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;			
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOE, &GPIO_InitStructure);

	GPIO_ResetBits(GPIOE, GPIO_Pin_1);
	Delay_ms(100);				   
	GPIO_SetBits(GPIOE, GPIO_Pin_1 );		 	 
	Delay_ms(100);
    */
	
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;			
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOG, &GPIO_InitStructure);
	
	#if 1
	Delay_ms(100);
	GPIO_SetBits(GPIOG, GPIO_Pin_15);		 	 
	Delay_ms(200);
	GPIO_ResetBits(GPIOG, GPIO_Pin_15);
	Delay_ms(100);				   
	GPIO_SetBits(GPIOG, GPIO_Pin_15);		 	 
	Delay_ms(1000);
	#endif
}

//检查LT738系统
void System_Check_Temp(void)
{
	unsigned char i=0;
	unsigned char temp=0;
	unsigned char system_ok=0;
	do
	{
		if((LCD_StatusRead()&0x02)==0x00)    
		{
			Delay_ms(3);                  //若MCU 速度太快，必要時使用
			LCD_CmdWrite(0x01);
			Delay_ms(3);                  //若MCU 速度太快，必要時使用
			temp =LCD_DataRead();
			if((temp & 0x80)==0x80)       //检测CCR寄存器PLL是否准备好
			{
				system_ok=1;
				i=0;
			}
			else
			{
				Delay_ms(3); //若MCU 速度太快，必要時使用//1ms
				LCD_CmdWrite(0x01);
				Delay_ms(3); //若MCU 速度太快，必要時使用//1ms
				LCD_DataWrite(0x80);
			}
		}
		else
		{
			system_ok=0;
			i++;
		}
		if(system_ok==0 && i==5)
		{
			LT738_HW_Reset(); //note1
			i=0;
		}
	}while(system_ok==0);
}

void LT738_PLL_Initial(void) 
{    
	unsigned int  temp = 0,temp1 =0 ;
	
	unsigned short lpllOD_sclk, lpllOD_cclk, lpllOD_mclk;
	unsigned short lpllR_sclk, lpllR_cclk, lpllR_mclk;
	unsigned short lpllN_sclk, lpllN_cclk, lpllN_mclk;
	
	//temp = (LCD_HBPD + LCD_HFPD + LCD_HSPW + LCD_XSIZE_TFT) * (LCD_VBPD + LCD_VFPD + LCD_VSPW+LCD_YSIZE_TFT) * 60; 
  temp = (LCD_HBPD + LCD_HFPD + LCD_HSPW + LCD_XSIZE_TFT) * (LCD_VBPD + LCD_VFPD + LCD_VSPW+LCD_YSIZE_TFT) * 60;   
	
	temp1=(temp%1000000)/100000;
	if(temp1>=5) 
		 temp = temp / 1000000 + 1;
	else temp = temp / 1000000;
	
	SCLK = temp;
	temp = temp * 2;//2
	MCLK = temp;
	CCLK = temp;
	
	if(CCLK > 100)	CCLK = 100;
	if(MCLK > 100)	MCLK = 100;
	if(SCLK > 65)	 SCLK = 65;
#if 0
	lpllOD_sclk = 2;
	lpllOD_cclk = 2;
	lpllOD_mclk = 2;
	lpllR_sclk  = 5;
	lpllR_cclk  = 5
	lpllR_mclk  = 5;
	lpllN_mclk  = MCLK;      
	lpllN_cclk  = CCLK;    
	lpllN_sclk  = SCLK;
#endif 

#if 1
	lpllOD_sclk = 4;
	lpllOD_cclk = 4;
	lpllOD_mclk = 4;
	lpllR_sclk  = 5;
	lpllR_cclk  = 5;
	lpllR_mclk  = 5;
	lpllN_mclk  = MCLK;      
	lpllN_cclk  = CCLK;    
	lpllN_sclk  = SCLK; 
#endif
      
	LCD_CmdWrite(0x05);
	LCD_DataWrite((lpllOD_sclk<<6) | (lpllR_sclk<<1) | ((lpllN_sclk>>8)&0x1));
	LCD_CmdWrite(0x07);
	LCD_DataWrite((lpllOD_mclk<<6) | (lpllR_mclk<<1) | ((lpllN_mclk>>8)&0x1));
	LCD_CmdWrite(0x09);
	LCD_DataWrite((lpllOD_cclk<<6) | (lpllR_cclk<<1) | ((lpllN_cclk>>8)&0x1));

	LCD_CmdWrite(0x06);
	LCD_DataWrite(lpllN_sclk);
	LCD_CmdWrite(0x08);
	LCD_DataWrite(lpllN_mclk);
	LCD_CmdWrite(0x0a);
	LCD_DataWrite(lpllN_cclk);
      
	LCD_CmdWrite(0x00);
	Delay_us(1);
	LCD_DataWrite(0x80);

	Delay_ms(1);	//单PLL铆
}


void LT738_SDRAM_initail(unsigned char mclk)
{
	unsigned short sdram_itv;

	LCD_RegisterWrite(0xe0,0x20);
	LCD_RegisterWrite(0xe1,0x03);	//CAS:2=0x02CAS:3=0x03
	sdram_itv = (64000000 / 8192) / (1000/mclk) ;//
	sdram_itv-=2;

	LCD_RegisterWrite(0xe2,sdram_itv);
	LCD_RegisterWrite(0xe3,sdram_itv >>8);
	LCD_RegisterWrite(0xe4,0x01);
	Check_SDRAM_Ready();
	Delay_ms(1);
}


void Set_LCD_Panel(void)
{
	//**[01h]**//
	TFT_24bit();
	Host_Bus_16bit();	//主机总线16bit
      
	//**[02h]**//
	RGB_16b_24bpp_mode1();
  //Panel_Synchronous_Signals();
	
	MemWrite_Left_Right_Top_Down();	
  

#if 0	
	//**[03h]**//
	Graphic_Mode();
	Memory_Select_SDRAM();
     
	//PCLK_Falling();	    //REG[12h]:下降沿	
	PCLK_Rising();
	
	VSCAN_T_to_B();	        //REG[12h]:从上到下
	PDATA_Set_RGB();        //REG[12h]:Select RGB output
	HSYNC_Low_Active();     //REG[13h]:
	//HSYNC_High_Active();     //REG[13h]:
	VSYNC_Low_Active();     //REG[13h]:
	//VSYNC_High_Active();     //REG[13h]:
	//DE_High_Active();       //REG[13h]:
	DE_Low_Active();
	
	
 
	LCD_HorizontalWidth_VerticalHeight(LCD_XSIZE_TFT ,LCD_YSIZE_TFT);	
	LCD_Horizontal_Non_Display(LCD_HBPD);	                            
	LCD_HSYNC_Start_Position(LCD_HFPD);	                              
	LCD_HSYNC_Pulse_Width(LCD_HSPW);		                            	
	LCD_Vertical_Non_Display(LCD_VBPD);	                                
	LCD_VSYNC_Start_Position(LCD_VFPD);	                              
	LCD_VSYNC_Pulse_Width(LCD_VSPW);	

#endif

#if 1
	//**[03h]**//
	Graphic_Mode();
	Memory_Select_SDRAM();
     
	//PCLK_Falling();	       	//REG[12h]:下降沿 
	PCLK_Rising();
	
	VSCAN_T_to_B();	        //REG[12h]:从上到下
	//VSCAN_B_to_T();				//从下到上
 	HSCAN_L_to_R();
	
	PDATA_Set_RGB();        //REG[12h]:Select RGB output
	//PDATA_Set_RBG();
	//PDATA_Set_GRB();
	//PDATA_Set_GBR();
	//PDATA_Set_BRG();
	//PDATA_Set_BGR();

	HSYNC_Low_Active();     //REG[13h]:		  
	//HSYNC_High_Active();
	
	VSYNC_Low_Active();     //REG[13h]:			
	//VSYNC_High_Active();
	
	//DE_High_Active();       //REG[13h]:	
	 DE_Low_Active();
 
	LCD_HorizontalWidth_VerticalHeight(LCD_XSIZE_TFT ,LCD_YSIZE_TFT);	
	LCD_Horizontal_Non_Display(LCD_HBPD);	                            
	LCD_HSYNC_Start_Position(LCD_HFPD);	                              
	LCD_HSYNC_Pulse_Width(LCD_HSPW);		                            	
	LCD_Vertical_Non_Display(LCD_VBPD);	                                
	LCD_VSYNC_Start_Position(LCD_VFPD);	                              
	LCD_VSYNC_Pulse_Width(LCD_VSPW);
	
	#endif 

	Memory_XY_Mode();	//Block mode (X-Y coordination addressing);块模式
	Memory_24bpp_Mode();	
}

void LT738_initial(void)
{
	LT738_PLL_Initial();
	LT738_SDRAM_initail(MCLK);
	Set_LCD_Panel();
}


void LT738_Init(void)
{
	Delay_ms(100);                    //delay for LT738 power on
	LT738_HW_Reset();                 //LT738复位
	//test_FSMCIO();
	System_Check_Temp();	            //检测复位是否成功
	Delay_ms(100);
	while(LCD_StatusRead()&0x02);	    //Initial_Display_test	and  set SW2 pin2 = 1
	Delay_ms(100);
	LT738_initial();
	Delay_ms(300);
	//test_FSMCIO();
}


void LT738_DrawSquare_Fill
(
 unsigned short X1                // X1位置
,unsigned short Y1                // Y1位置
,unsigned short X2                // X2位置
,unsigned short Y2                // Y2位置
,unsigned long ForegroundColor    // 背景颜色
)
{
	Foreground_color_16M(ForegroundColor);
	Square_Start_XY(X1,Y1);
	Square_End_XY(X2,Y2);
	Start_Square_Fill();
	Check_2D_Busy();
}

//----------------------------------------------------------------------------------------------------------------------------------

void LT738_PWM0_Init
(
 unsigned char on_off                       // 0：禁止PWM0    1：使能PWM0
,unsigned char Clock_Divided                // PWM时钟分频  取值范围 0~3(1,1/2,1/4,1/8)
,unsigned char Prescalar                    // 时钟分频     取值范围 1~256
,unsigned short Count_Buffer                // 设置PWM的输出周期
,unsigned short Compare_Buffer              // 设置占空比
)
{
	Select_PWM0();
	Set_PWM_Prescaler_1_to_256(Prescalar);

	if(Clock_Divided ==0)	Select_PWM0_Clock_Divided_By_1();
	if(Clock_Divided ==1)	Select_PWM0_Clock_Divided_By_2();
	if(Clock_Divided ==2)	Select_PWM0_Clock_Divided_By_4();
	if(Clock_Divided ==3) Select_PWM0_Clock_Divided_By_8();

	Set_Timer0_Count_Buffer(Count_Buffer);  
	Set_Timer0_Compare_Buffer(Compare_Buffer);	
		
	if (on_off == 1)	Start_PWM0(); 
	if (on_off == 0)	Stop_PWM0();
}


void LT738_PWM0_Duty(unsigned short Compare_Buffer)
{
	Set_Timer0_Compare_Buffer(Compare_Buffer);
}



void LT738_PWM1_Init
(
 unsigned char on_off                       // 0：禁止PWM0    1：使能PWM0
,unsigned char Clock_Divided                // PWM时钟分频  取值范围 0~3(1,1/2,1/4,1/8)
,unsigned char Prescalar                    // 时钟分频     取值范围 1~256
,unsigned short Count_Buffer                // 设置PWM的输出周期
,unsigned short Compare_Buffer              // 设置占空比
)
{
	Select_PWM1();
	Set_PWM_Prescaler_1_to_256(Prescalar);
 
	if(Clock_Divided ==0)	Select_PWM1_Clock_Divided_By_1();
	if(Clock_Divided ==1)	Select_PWM1_Clock_Divided_By_2();
	if(Clock_Divided ==2) Select_PWM1_Clock_Divided_By_4();
	if(Clock_Divided ==3)	Select_PWM1_Clock_Divided_By_8();

	Set_Timer1_Count_Buffer(Count_Buffer); 
	Set_Timer1_Compare_Buffer(Compare_Buffer); 

	if (on_off == 1)	Start_PWM1(); 
	if (on_off == 0)	Stop_PWM1();
}


void LT738_PWM1_Duty(unsigned short Compare_Buffer)
{
	Set_Timer1_Compare_Buffer(Compare_Buffer);
}

void MPU_Memory_Write_Window_8bit//通过设置工作窗口的方法描点画图
(
 unsigned short x			// x坐标
,unsigned short y			// y坐标
,unsigned short w			// 宽度 注意：必须为4的倍数
,unsigned short h			// 高度
,const unsigned char *data	// 数据(8位)
)			
{
	unsigned short i,j,temp;
	Graphic_Mode();
    Active_Window_XY(x,y);
	Active_Window_WH(w,h);
	Goto_Pixel_XY(x,y);
	LCD_CmdWrite(0x04);
	for(i=0;i< h;i++)
	{
		for(j=0;j< w/2;j++)
		{
			Check_Mem_WR_FIFO_not_Full();
			temp = *data;
			data++;
			temp+=(*data<<8);
			LCD_DataWrite_Pixel(temp);
			data++;
			
			temp = *data;
			data++;
			temp+=(*data<<8);
			LCD_DataWrite_Pixel(temp);
			data++;
			
			temp = *data;
			data++;
			temp+=(*data<<8);
			LCD_DataWrite_Pixel(temp);
			data++;
		}
	}
	Check_Mem_WR_FIFO_Empty();
	Active_Window_XY(0,0);
	Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT);
}

void MPU_Memory_Write_Pixel_8bit//通过改变坐标的方法描点画图
(
 unsigned short x			// x坐标
,unsigned short y			// y坐标
,unsigned short w			// 宽度
,unsigned short h			// 高度
,const unsigned char *data	// 数据首地址
)			
{
	unsigned short i,j,temp,two;
	Graphic_Mode();
	two = w % 2;
	for(j=0;j< h;j++)
	{
		for(i=0;i< w/2;i++)//写入一行数据(3个16位数据=2个像素点)
		{
			Goto_Pixel_XY(x+i*2,y+j);//设定坐标
			LCD_CmdWrite(0x04);//写SDRAM寄存器
			temp = *data;
			data++;
			temp+=(*data<<8);
			LCD_DataWrite_Pixel(temp);
			data++;
			
			temp = *data;
			data++;
			temp+=(*data<<8);
			LCD_DataWrite_Pixel(temp);
			data++;
			
			temp = *data;
			data++;
			temp+=(*data<<8);
			LCD_DataWrite_Pixel(temp);
			data++;
		}
		if(two == 1)//若宽度是奇数，补充最后一个像素
		{
			temp = *data;
			data++;
			temp+=(*data<<8);
			LCD_DataWrite_Pixel(temp);
			data++;
			
			temp = *data;
			LCD_DataWrite((u8)temp);
			data++;
		}
	}
	Check_Mem_WR_FIFO_Empty();
}

u8 BUFF[LCD_XSIZE_TFT*3] = {0};


/*

//MCU读取SPI flash描点画图
//x,y:坐标  w,h:宽度和高度  addr:flash地址
void Memory_Write(u16 x,u16 y,u16 w,u16 h,u32 addr)
{
	u16 i,j,color;
	u8 temp;
	temp = w % 2;
	for(i = 0 ; i < h ; i++)
	{
		W25X_Read_Data(BUFF,addr,w*3);//MCU读取图片一行的数据
		Goto_Pixel_XY(x,y+i);
		LCD_CmdWrite(0x04);
		for(j = 0 ; j < w/2 ; j++)//写入一行数据(3个16位数据=2个像素点)
		{
			if((j%32)==0)	Check_Mem_WR_FIFO_not_Full();
			
			color = ((BUFF[j*6+1]<<8)&0xff00)+BUFF[j*6+0];
			LCD_DataWrite_Pixel(color);
			
			color = ((BUFF[j*6+3]<<8)&0xff00)+BUFF[j*6+2];
			LCD_DataWrite_Pixel(color);
			
			color = ((BUFF[j*6+5]<<8)&0xff00)+BUFF[j*6+4];
			LCD_DataWrite_Pixel(color);
		}
		if(temp == 1)//若宽度是奇数，补充最后一个像素
		{
			color = ((BUFF[(w/2)*6+1]<<8)&0xff00)+BUFF[(w/2)*6];
			LCD_DataWrite_Pixel(color);
			
			color = BUFF[(w/2)*6+2];
			LCD_DataWrite((u8)color);
		}
		addr+=w*3;//指向下一行
	}
	Check_Mem_WR_FIFO_Empty();
}

*/


