
#include "lcd.h"
#include "stdlib.h"
#include "string.h"
#include "font.h"
#include "SPI.h"

_lcd_dev lcddev;

uint16_t POINT_COLOR = 0x0000,BACK_COLOR = 0xFFFF;
uint16_t DeviceCode;

void LCD_WR_REG(uint8_t data)
{

    LCD_RS_CLR;
   // HAL_SPI_Transmit(&hspi1, &data, 1, 1000);
    while(!LL_SPI_IsActiveFlag_TXE(SPI1)) {}
	LL_SPI_TransmitData8(SPI1, data);
}

void LCD_WR_DATA(uint8_t data)
{

    LCD_RS_SET;
    while(!LL_SPI_IsActiveFlag_TXE(SPI1)) {}
	LL_SPI_TransmitData8(SPI1, data);            //发送8位数据

}

void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue)
{
    LCD_WR_REG(LCD_Reg);
    LCD_WR_DATA(LCD_RegValue);
}

void LCD_WriteRAM_Prepare(void)
{
    LCD_WR_REG(lcddev.wramcmd);
}

void Lcd_WriteData_16Bit(uint16_t Data)
{
	LCD_RS_SET;
	while(!LL_SPI_IsActiveFlag_TXE(SPI1)) {}
	LL_SPI_TransmitData8(SPI1, Data>>8);
	LL_SPI_TransmitData8(SPI1, Data&0xff);
}


void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t pc)
{
    LCD_SetCursor(x,y);//设置光标位置
    Lcd_WriteData_16Bit(pc);
}

void LCD_Clear(uint16_t Color)
{

    unsigned int i,m;
    LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);
    LCD_RS_SET;
    for(i=0; i<240; i++)
    {
        for(m=0; m<240; m++)
        {
        	  while(!LL_SPI_IsActiveFlag_TXE(SPI1)) {}
        	  LL_SPI_TransmitData8(SPI1, Color>>8);
        	  while(!LL_SPI_IsActiveFlag_TXE(SPI1)) {}
        	  LL_SPI_TransmitData8(SPI1, Color&0xff);
        }
    }

}


void LCD_Init(void)
{

    LCD_RST_CLR;
    HAL_Delay (200);
    LCD_RST_SET;
    HAL_Delay(200);

    LCD_WR_REG(0x36);
    LCD_WR_DATA(0x00);

    LCD_WR_REG(0x3A);
    LCD_WR_DATA(0x05);

    LCD_WR_REG(0xB2);
    LCD_WR_DATA(0x0C);
    LCD_WR_DATA(0x0C);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x33);
    LCD_WR_DATA(0x33);

    LCD_WR_REG(0xB7);
    LCD_WR_DATA(0x35);

    LCD_WR_REG(0xBB);
    LCD_WR_DATA(0x19);

    LCD_WR_REG(0xC0);
    LCD_WR_DATA(0x2C);

    LCD_WR_REG(0xC2);
    LCD_WR_DATA(0x01);

    LCD_WR_REG(0xC3);
    LCD_WR_DATA(0x12);

    LCD_WR_REG(0xC4);
    LCD_WR_DATA(0x20);

    LCD_WR_REG(0xC6);
    LCD_WR_DATA(0x0F);

    LCD_WR_REG(0xD0);
    LCD_WR_DATA(0xA4);
    LCD_WR_DATA(0xA1);

    LCD_WR_REG(0xE0);
    LCD_WR_DATA(0xD0);
    LCD_WR_DATA(0x04);
    LCD_WR_DATA(0x0D);
    LCD_WR_DATA(0x11);
    LCD_WR_DATA(0x13);
    LCD_WR_DATA(0x2B);
    LCD_WR_DATA(0x3F);
    LCD_WR_DATA(0x54);
    LCD_WR_DATA(0x4C);
    LCD_WR_DATA(0x18);
    LCD_WR_DATA(0x0D);
    LCD_WR_DATA(0x0B);
    LCD_WR_DATA(0x1F);
    LCD_WR_DATA(0x23);

    LCD_WR_REG(0xE1);
    LCD_WR_DATA(0xD0);
    LCD_WR_DATA(0x04);
    LCD_WR_DATA(0x0C);
    LCD_WR_DATA(0x11);
    LCD_WR_DATA(0x13);
    LCD_WR_DATA(0x2C);
    LCD_WR_DATA(0x3F);
    LCD_WR_DATA(0x44);
    LCD_WR_DATA(0x51);
    LCD_WR_DATA(0x2F);
    LCD_WR_DATA(0x1F);
    LCD_WR_DATA(0x1F);
    LCD_WR_DATA(0x20);
    LCD_WR_DATA(0x23);

    LCD_WR_REG(0x21);

    LCD_WR_REG(0x11);
    //Delay (120);

    LCD_WR_REG(0x29);
    LCD_direction(USE_HORIZONTAL);//设置LCD显示方向


    LCD_Clear(BLACK);//清全屏白色
}

void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd)
{
    LCD_WR_REG(lcddev.setxcmd);
    LCD_WR_DATA((xStar+lcddev.xoffset)>>8);
    LCD_WR_DATA(xStar+lcddev.xoffset);
    LCD_WR_DATA((xEnd+lcddev.xoffset)>>8);
    LCD_WR_DATA(xEnd+lcddev.xoffset);

    LCD_WR_REG(lcddev.setycmd);
    LCD_WR_DATA((yStar+lcddev.yoffset)>>8);
    LCD_WR_DATA(yStar+lcddev.yoffset);
    LCD_WR_DATA((yEnd+lcddev.yoffset)>>8);
    LCD_WR_DATA(yEnd+lcddev.yoffset);

    LCD_WriteRAM_Prepare();	//开始写入GRAM
}


void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos)
{
    LCD_SetWindows(Xpos,Ypos,Xpos,Ypos);
}

void LCD_direction(uint8_t direction)
{
    lcddev.setxcmd=0x2A;
    lcddev.setycmd=0x2B;
    lcddev.wramcmd=0x2C;
    switch(direction) {
    case 0:
        lcddev.width=LCD_W;
        lcddev.height=LCD_H;
        lcddev.xoffset=0;
        lcddev.yoffset=0;
        LCD_WriteReg(0x36,0);//BGR==1,MY==0,MX==0,MV==0
        break;
    case 1:
        lcddev.width=LCD_H;
        lcddev.height=LCD_W;
        lcddev.xoffset=0;
        lcddev.yoffset=0;
        LCD_WriteReg(0x36,(1<<6)|(1<<5));//BGR==1,MY==1,MX==0,MV==1
        break;
    case 2:
        lcddev.width=LCD_W;
        lcddev.height=LCD_H;
        lcddev.xoffset=0;
        lcddev.yoffset=80;
        LCD_WriteReg(0x36,(1<<6)|(1<<7));//BGR==1,MY==0,MX==0,MV==0
        break;
    case 3:
        lcddev.width=LCD_H;
        lcddev.height=LCD_W;
        lcddev.xoffset=80;
        lcddev.yoffset=0;
        LCD_WriteReg(0x36,(1<<7)|(1<<5));//BGR==1,MY==1,MX==0,MV==1
        break;
    default:
        break;
    }
}


void LCD_Fill(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint16_t color)
{
    uint16_t i,j;
    uint16_t width=ex-sx+1; 		//得到填充的宽度
    uint16_t height=ey-sy+1;		//高度
    LCD_SetWindows(sx,sy,ex,ey);//设置显示窗口
    for(i=0; i<height; i++)
    {
        for(j=0; j<width; j++)
            Lcd_WriteData_16Bit(color);	//写入数据
    }
    //LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口设置为全屏
}
void GUI_DrawFont3232(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc,    char str[3] )//显示汉字
{
  uint16_t i, j;
  uint16_t k;
  uint16_t HZnum;
  uint16_t x0 = x;
  HZnum = sizeof(tfont3232) / sizeof(typFNT_GB32_32); //自动统计汉字数目
  for (k = 0; k < HZnum; k++)
  {
	  //LCD_SetWindows(x,y,x+32,y+32);//设置显示窗口
    if ((tfont3232[k].Index[0] == *(str)  ) && (tfont3232[k].Index[1] == *(str + 1)  ) && (tfont3232[k].Index[2] == *(str + 2)  ))
    {
    	 LCD_SetWindows(x,y,x+31,y+31);//设置显示窗口

    	    for(i=0; i<32*4; i++)
    	    {

    	    	        for (j = 0; j < 8; j++)
    	    	        {
    	    	          if (tfont3232 [k].Msk[i] & (0x80 >> j)) {
    	    	        	 // LCD_DrawPoint(x, y , fc);
    	    	        	  Lcd_WriteData_16Bit(fc);	//写入数据
    	    	          }
    	    	          else {

    	    	        	  Lcd_WriteData_16Bit(bc);
    	    	          }

    	    	        }
    	    }

//      for (i = 0; i < 128; i++)
//      {
//        for (j = 0; j < 8; j++)
//        {
//          if (tfont3232 [k].Msk[i] & (0x80 >> j)) {
//        	  LCD_DrawPoint(x, y , fc);
//          }
//          else {
//        	  LCD_DrawPoint(x, y, bc);
//          }
//          x++;
//          if ((x - x0) == 32) {
//            x = x0;
//            y++;
//            break;
//          }
//        }
//      }
    }
    continue;  //查找到对应点阵字库立即退出，防止多个汉字重复取模带来影响
  }
}

void GUI_DrawFont3216(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc,   char str[2] )//显示数字字符
{
  uint16_t i, j;
  uint16_t k;
  uint16_t HZnum;
  uint16_t x0 = x;
  HZnum = sizeof(tfont3216) / sizeof(typFNT_GB32_16); //自动统计汉字数目

  for (k = 0; k < HZnum; k++)
  {
    if ((tfont3216[k].Index[0] == *(str)  ))
    {

   	 LCD_SetWindows(x,y,x+15,y+31);//设置显示窗口

   	    for(i=0; i<32*2; i++)
   	    {
			for (j = 0; j < 8; j++)
			{
			  if (tfont3216 [k].Msk[i] & (0x80 >> j)) {
				  Lcd_WriteData_16Bit(fc);	//写入数据
			  }
			  else {
				  Lcd_WriteData_16Bit(bc);
			  }

			}
   	    }


//      for (i = 0; i < 64; i++)
//      {
//        for (j = 0; j < 8; j++)
//        {
//          if (tfont3216 [k].Msk[i] & (0x80 >> j)) {
//        	  LCD_DrawPoint(x, y , fc);
//          }
//          // else{gfx->drawPixel(x,y,(( gImage_pic[2*(x+(y-24)*320)+1])<<8)|( gImage_pic[2*(x+(y-24)*320)]));}
//          else {
//        	  LCD_DrawPoint(x, y, bc);
//          }
//          x++;
//          if ((x - x0) == 16) {
//            x = x0;
//            y++;
//            break;
//          }
//        }
//      }
    }
    continue;  //查找到对应点阵字库立即退出，防止多个汉字重复取模带来影响
  }
}

void show_string(int32_t x, int32_t y,   char str[], uint32_t length, uint16_t fc,uint16_t bc )//显示字符串
{
  uint8_t i = 0, j = 0;
  for (i = 0; i < length; i++)
  {
    if ((*(str) >= 0x20) && (*(str) <= 0x7e)) //字符
    {
      GUI_DrawFont3216(x, y , fc, bc,str  );
      x  += 16;
      str++;
    }
    else
    {
      GUI_DrawFont3232(x, y , fc,bc, str );//汉字
      x  += 32;
      str += 3;
      i += 2;
    }
  }
}
