/* ʹõĿ: STM32F407 Ƶõ168MHz ʹFSMCʽ*/

#define LCD_DATA    ((u32)0x60020000)    	//disp Data ADDR
#define LCD_CMD     ((u32)0x60000000)	 		//disp Reg ADDR

#define White          0xFFFF
#define Black          0x0000
#define Grey           0xF7DE
#define Blue           0x001F
#define Blue2          0x051F
#define Red            0xF800
#define Magenta        0xF81F
#define Green          0x07E0
#define Cyan           0x7FFF
#define Yellow         0xFFE0

static volatile u32 TimingDelay;	//ʱõı

void LCD_GPIOInit(void)
{
	/*  FSMC */
  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  p;
  GPIO_InitTypeDef GPIO_InitStructure; 
  /* ʹGPIOʱ */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOB, ENABLE);
  /* ʹFSMCʱ */
  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); 
  /* GPIOD , ΪFSMC */
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC); 
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4  | GPIO_Pin_5  | GPIO_Pin_7  | 
																GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_14 | 
																GPIO_Pin_15;															
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  /* GPIOE  */
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7  | GPIO_Pin_8  | GPIO_Pin_9  | GPIO_Pin_10 |
                                GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
                                GPIO_Pin_15;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
	/* λܽ */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;	
	GPIO_Init(GPIOB, &GPIO_InitStructure);

/*-- FSMC  ------------------------------------------------------*/
  p.FSMC_AddressSetupTime = 0x1;		
  p.FSMC_AddressHoldTime = 0x0;		
  p.FSMC_DataSetupTime = 0x5;				
  p.FSMC_BusTurnAroundDuration = 0x0;
  p.FSMC_CLKDivision = 0x0;				
  p.FSMC_DataLatency = 0x0;					
  p.FSMC_AccessMode = FSMC_AccessMode_B;

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;  
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 
  /* ʹ FSMC Bank1_SRAM1 Bank */
  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); 
}
/* ---------------------------------------------------------- */
/* СδΪʹSystickȷʱĺ ^_^ */

/* stm32f4xx_it.cļ޸Ĵ˺ */
void SysTick_Handler(void)
{
	TimingDelay_Decrement();
}

/*  Systick */
void SysTick_Configuration(void)
{
  if (SysTick_Config(SystemCoreClock / 1000))
  { 
    while (1);
  }
  NVIC_SetPriority(SysTick_IRQn, 0x0);//жȼ
}
/* ж */
void InterruptConfig(void)
{
	NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
}
/* ʱ */
void Delay_ms(u32 nTime)
{ 
  TimingDelay = nTime;

  while(TimingDelay != 0);
}
/* ʱӺ */
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  { 
    TimingDelay--;
  }
}
/* --------------------------------------------------------- */
void LCD_WriteReg(u16 Command)
{
	/* д HX8357 */
  *(volatile u16 *) (LCD_CMD)= Command;   
}

void LCD_WriteData(u16 Data)
{
	/* дݵ HX8357 */
	*(volatile u16 *) (LCD_DATA)= Data; 
}

void LCD_Reset(void)
{
	/* LCD λ */
	RST_HIGH();
	Delay_ms(1);//ע˴ Delay_ms Ǿȷ ms ʱ							
	RST_LOW();
	Delay_ms(1);
	RST_HIGH();
	Delay_ms(5);//ײ⣬λʱ4msϲſ
}

void LCD_Init(void)
{
	/* LCD ʼ */
	LCD_GPIOInit();																// GPIO ʼ
	LCD_Reset();																	// LCD λ
	LCD_WriteReg(0x00ff);LCD_WriteData(0x0000);		// Command page select
	LCD_WriteReg(0x0072);LCD_WriteData(0x00f6);		// SUB_PANEL Control
	//power saving for HX8357-A
	LCD_WriteReg(0x00ff);LCD_WriteData(0x0000);		// Command page select 
	LCD_WriteReg(0X00f2);LCD_WriteData(0x0000);		
	LCD_WriteReg(0X00e4);LCD_WriteData(0x0000);
	LCD_WriteReg(0X00e5);LCD_WriteData(0x001c);
	LCD_WriteReg(0X00e6);LCD_WriteData(0x0000);
	LCD_WriteReg(0X00e7);LCD_WriteData(0x001c);
	LCD_WriteReg(0x00ee);LCD_WriteData(0x0042);
	LCD_WriteReg(0x00ef);LCD_WriteData(0x00db);
	LCD_WriteReg(0x002e);LCD_WriteData(0x0098);
	//Gamma 
	LCD_WriteReg(0X0040);LCD_WriteData(0x0007);
	LCD_WriteReg(0x0041);LCD_WriteData(0x002e);
	LCD_WriteReg(0x0042);LCD_WriteData(0x002c);
	LCD_WriteReg(0x0043);LCD_WriteData(0x003d);
	LCD_WriteReg(0x0044);LCD_WriteData(0x0038);
	LCD_WriteReg(0x0045);LCD_WriteData(0x003d);
	LCD_WriteReg(0x0046);LCD_WriteData(0x0027);
	LCD_WriteReg(0x0047);LCD_WriteData(0x0076);
	LCD_WriteReg(0x0048);LCD_WriteData(0x0008);
	LCD_WriteReg(0x0049);LCD_WriteData(0x0006);
	LCD_WriteReg(0x004a);LCD_WriteData(0x0006);
	LCD_WriteReg(0x004b);LCD_WriteData(0x000c);
	LCD_WriteReg(0x004c);LCD_WriteData(0x0017);
	
	LCD_WriteReg(0x0050);LCD_WriteData(0x0002);
	LCD_WriteReg(0x0051);LCD_WriteData(0x0007);
	LCD_WriteReg(0x0052);LCD_WriteData(0x0002);
	LCD_WriteReg(0x0053);LCD_WriteData(0x0013);
	LCD_WriteReg(0x0054);LCD_WriteData(0x0011);
	LCD_WriteReg(0x0055);LCD_WriteData(0x003d);
	LCD_WriteReg(0x0056);LCD_WriteData(0x0009);
	LCD_WriteReg(0x0057);LCD_WriteData(0x0058);
	LCD_WriteReg(0x0058);LCD_WriteData(0x0008);
	LCD_WriteReg(0x0059);LCD_WriteData(0x0013);
	LCD_WriteReg(0x005a);LCD_WriteData(0x0019);
	LCD_WriteReg(0x005b);LCD_WriteData(0x0019);
	LCD_WriteReg(0x005c);LCD_WriteData(0x0017);
	LCD_WriteReg(0x005d);LCD_WriteData(0x003c);
	
	//Set GRAM area 320*480
	LCD_WriteReg(0x0002);LCD_WriteData(0x0000);
	LCD_WriteReg(0x0003);LCD_WriteData(0x0000);
	LCD_WriteReg(0x0004);LCD_WriteData(0x0001);
	LCD_WriteReg(0x0005);LCD_WriteData(0x003f);
	LCD_WriteReg(0x0006);LCD_WriteData(0x0000);
	LCD_WriteReg(0x0007);LCD_WriteData(0x0000);
	LCD_WriteReg(0x0008);LCD_WriteData(0x0001);
	LCD_WriteReg(0x0009);LCD_WriteData(0x00df);
	//power setting
	LCD_WriteReg(0x0024);LCD_WriteData(0x0064);
	LCD_WriteReg(0x0025);LCD_WriteData(0x0071);
	LCD_WriteReg(0x0023);LCD_WriteData(0x0052);
	LCD_WriteReg(0x001b);LCD_WriteData(0x001e);
	LCD_WriteReg(0x001d);LCD_WriteData(0x0011);
	//power on setting
	LCD_WriteReg(0x0019);LCD_WriteData(0x0001);
	LCD_WriteReg(0x001c);LCD_WriteData(0x0003);
	LCD_WriteReg(0x0001);LCD_WriteData(0x0000);
	LCD_WriteReg(0x001f);LCD_WriteData(0x0080);
	Delay_ms(5);
	LCD_WriteReg(0x001f);LCD_WriteData(0x0090);
	Delay_ms(5);
	LCD_WriteReg(0x001f);LCD_WriteData(0x00d4);
	Delay_ms(5);
	//Display on setting
	LCD_WriteReg(0x0028);LCD_WriteData(0x0008);
	Delay_ms(40);
	LCD_WriteReg(0x0028);
	LCD_WriteData(0x0038);
	Delay_ms(40);
	LCD_WriteReg(0x0028);
	LCD_WriteData(0x003c);	
	LCD_WriteReg(0x0017);
	LCD_WriteData(0x0005);	// ڴ˴õɫλ 0x0005Ϊ16λ(565)ģʽ	
	LCD_WriteReg(0x0016);		// Memory access control register
	LCD_WriteData(0x0009);	// ڴ˴ LCD shift directionԼRGB(BGR)
}

void LCD_SetXY(u16 x,u16 y)
{
	/* LCD  */
	LCD_WriteReg(0x0080);
	LCD_WriteData(x>>8);
	LCD_WriteReg(0x0081);
	LCD_WriteData(x);
	LCD_WriteReg(0x0082);
	LCD_WriteData(y>>8);
	LCD_WriteReg(0x0083);
	LCD_WriteData(y);
//	LCD_WriteReg(0x0022);
}

void LCD_Clear(u16 color)
{	
	/* LCD ,  color ɫĻ */
	u32 i;
	LCD_SetXY(0,0);
	LCD_WriteReg(0x0022);//
	for(i=0;i<0x25800;i++)
	LCD_WriteData(color);
}

void LCD_WritePixel(u16 X,u16 Y,u16 color)
{
	/* LCD дһ㺯 */
	if(X<480&&Y<320)
	{
//		LCD_SetXY(Y,479-X);/* Ļת */
		LCD_SetXY(319-Y,X);	 //ڴ˴ڰĻã
		LCD_WriteReg(0x0022);
		LCD_WriteData(color);
	}
}
	/*  */
int main()
{
//	USART2_Init();
	InterruptConfig();				//ж
	SysTick_Configuration();  //SysTick
	LCD_Init();								//LCD ʼ
/*		
	LCD_WriteReg(0x0000);
	printf("LCD ID: 0x%x\r\n",LCD_ReadData()); 	
//ȡLCD IDֵʼûзӦδעȥ룬ֵǲ 0x57 ǣ˵Ӳû
*/
	while(1)
	{
		/* ÿһѭʾ  ɫ */
		LCD_Clear(Red);
		Delay_ms(1000);
		LCD_Clear(Green);
		Delay_ms(1000);
		LCD_Clear(Blue);
		Delay_ms(1000);
	}
}
