//Technical support:goodtft@163.com
// Breakout/Arduino UNO pin usage:
// LCD Data Bit :   7   6   5   4   3   2   1   0
// Uno dig. pin :   7   6   5   4   3   2   9   8
// Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0
// Mega dig. pin:  29  28  27  26  25  24  23  22
#define LCD_RD   A0
#define LCD_WR   A1     
#define LCD_RS   A2        
#define LCD_CS   A3       
#define LCD_REST A4

void Lcd_Writ_Bus(unsigned char d)
{
 PORTD = (PORTD & B00000011) | ((d) & B11111100); 
 PORTB = (PORTB & B11111100) | ((d) & B00000011); 
 *(portOutputRegister(digitalPinToPort(LCD_WR))) &=  ~digitalPinToBitMask(LCD_WR);
 *(portOutputRegister(digitalPinToPort(LCD_WR)))|=  digitalPinToBitMask(LCD_WR);
}


void Lcd_Write_Com(unsigned char VH)  
{   
  *(portOutputRegister(digitalPinToPort(LCD_RS))) &=  ~digitalPinToBitMask(LCD_RS);//LCD_RS=0;
  Lcd_Writ_Bus(VH);
}

void Lcd_Write_Data(unsigned char VH)
{
  *(portOutputRegister(digitalPinToPort(LCD_RS)))|=  digitalPinToBitMask(LCD_RS);//LCD_RS=1;
  Lcd_Writ_Bus(VH);
}

void Lcd_Write_Com_Data(unsigned char com,unsigned char dat)
{
  Lcd_Write_Com(com);
  Lcd_Write_Data(dat);
}

void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
  Lcd_Write_Com_Data(0x0002,x1>>8);
  Lcd_Write_Com_Data(0x0003,x1);
  Lcd_Write_Com_Data(0x0004,x2>>8);
  Lcd_Write_Com_Data(0x0005,x2);
  Lcd_Write_Com_Data(0x0006,y1>>8);
  Lcd_Write_Com_Data(0x0007,y1);
  Lcd_Write_Com_Data(0x0008,y2>>8);
  Lcd_Write_Com_Data(0x0009,y2);		 
  
  Lcd_Write_Com(0x22);
}

void Lcd_Init(void)
{
  digitalWrite(LCD_REST,HIGH);
  delay(5); 
  digitalWrite(LCD_REST,LOW);
  delay(15);
  digitalWrite(LCD_REST,HIGH);
  delay(15);

  digitalWrite(LCD_CS,HIGH);
  digitalWrite(LCD_WR,HIGH);
  digitalWrite(LCD_CS,LOW);  //CS

   Lcd_Write_Com_Data(0x2E, 0x89); //write_data(0x00,); //GDOFF
Lcd_Write_Com_Data(0x29, 0X8F); //write_data(0x00); //RTN
Lcd_Write_Com_Data(0x2B, 0X02); //write_data(0x00,); //DUM
Lcd_Write_Com_Data(0xE2, 0X00); //write_data(0x00,); //VREF
Lcd_Write_Com_Data(0xE4, 0X01); //write_data(0x00,); //EQ
Lcd_Write_Com_Data(0xE5, 0X10); //write_data(0x00,); //EQ
Lcd_Write_Com_Data(0xE6, 0X01); //write_data(0x00,); //EQ
Lcd_Write_Com_Data(0xE7, 0X10); //write_data(0x00,); //EQ
Lcd_Write_Com_Data(0xE8, 0X70); //write_data(0x00,); //OPON
Lcd_Write_Com_Data(0xF2, 0X00); //write_data(0x00,); //GEN
Lcd_Write_Com_Data(0xEA, 0X00); //write_data(0x00,); //PTBA
Lcd_Write_Com_Data(0xEB, 0X20); //write_data(0x00,); //PTBA
Lcd_Write_Com_Data(0xEC, 0X3C); //write_data(0x00,); //STBA
Lcd_Write_Com_Data(0xED, 0XC8); //write_data(0x00,); //STBA
Lcd_Write_Com_Data(0xE9, 0X38); //write_data(0x00,); //OPON1
Lcd_Write_Com_Data(0xF1, 0X01); //write_data(0x00,); //OTPS1B
// Gamma 2.8 setting 
Lcd_Write_Com_Data(0x40, 0X00); //write_data(0x00,); //
Lcd_Write_Com_Data(0x41, 0X00); //write_data(0x00,); //
Lcd_Write_Com_Data(0x42, 0X00); //write_data(0x00,); //
Lcd_Write_Com_Data(0x43, 0X15); //write_data(0x00,); //
Lcd_Write_Com_Data(0x44, 0X13); //write_data(0x00,); //
Lcd_Write_Com_Data(0x45, 0X3f); //write_data(0x00,); //
Lcd_Write_Com_Data(0x47, 0X55); //write_data(0x00,); //
Lcd_Write_Com_Data(0x48, 0X00); //write_data(0x00,); //
Lcd_Write_Com_Data(0x49, 0X12); //write_data(0x00,); //
Lcd_Write_Com_Data(0x4A, 0X19); //write_data(0x00,); //
Lcd_Write_Com_Data(0x4B, 0X19); //write_data(0x00,); //
Lcd_Write_Com_Data(0x4C, 0X16); //write_data(0x00,); //
Lcd_Write_Com_Data(0x50, 0X00); //write_data(0x00,); //
Lcd_Write_Com_Data(0x51, 0X2c); //write_data(0x00,); //
Lcd_Write_Com_Data(0x52, 0X2a); //write_data(0x00,); //
Lcd_Write_Com_Data(0x53, 0X3F); //write_data(0x00,); //
Lcd_Write_Com_Data(0x54, 0X3F); //write_data(0x00,); //
Lcd_Write_Com_Data(0x55, 0X3F); //write_data(0x00,); //
Lcd_Write_Com_Data(0x56, 0X2a); //write_data(0x00,); //
Lcd_Write_Com_Data(0x57, 0X7e); //write_data(0x00,); //
Lcd_Write_Com_Data(0x58, 0X09); //write_data(0x00,); //
Lcd_Write_Com_Data(0x59, 0X06); //write_data(0x00,); //
Lcd_Write_Com_Data(0x5A, 0X06); //write_data(0x00,); //
Lcd_Write_Com_Data(0x5B, 0X0d); //write_data(0x00,); //
Lcd_Write_Com_Data(0x5C, 0X1F); //write_data(0x00,); //
Lcd_Write_Com_Data(0x5D, 0XFF); //write_data(0x00,); //
// Power Voltage Setting
Lcd_Write_Com_Data(0x1B, 0X1A); //write_data(0x00);
Lcd_Write_Com_Data(0x1A, 0X02); //write_data(0x00);
Lcd_Write_Com_Data(0x24, 0X61); //write_data(0x00);
Lcd_Write_Com_Data(0x25, 0X5C); //write_data(0x00);
// Vcom offset
// Lcd_Write_Com_Data(0x23,0x8D); // FLICKER ADJUST
Lcd_Write_Com_Data(0x23, 0x62); //write_data(0x00,0X62);
// Power ON Setting
Lcd_Write_Com_Data(0x18, 0X36); //write_data(0x00); //RADJ 70Hz
Lcd_Write_Com_Data(0x19, 0X01); //write_data(0x00,0X01); //OSC_EN=1
Lcd_Write_Com_Data(0x1F, 0X88); //write_data(0x00,0X88); // GAS=1, VOMG=00, PON=0, DK=1, XDK=0, DVDH_TRI=0, STB=0
delay(5);
Lcd_Write_Com_Data(0x1F, 0X80); //write_data(0x00,0X80); // GAS=1, VOMG=00, PON=0, DK=0, XDK=0, DVDH_TRI=0, STB=0
delay(5);
Lcd_Write_Com_Data(0x1F, 0X90); //write_data(0x00,0X90); // GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0
delay(5);
Lcd_Write_Com_Data(0x1F, 0XD4); //write_data(0x00,0XD4); // GAS=1, VOMG=10, PON=1, DK=0, XDK=1, DDVDH_TRI=0, STB=0
delay(5);
//262k/65k color selection
Lcd_Write_Com_Data(0x17, 0X05); //write_data(0x00,0X05); //default 0x06 262k color // 0x05 65k color
//SET PANEL
Lcd_Write_Com_Data(0x36, 0X09); //write_data(0x00,0X09); //SS_P, GS_P,REV_P,BGR_P
//Display ON Setting
Lcd_Write_Com_Data(0x28, 0X38); //write_data(0x00,0X38); //GON=1, DTE=1, D=1000
delay(40);
Lcd_Write_Com_Data(0x28, 0X3C); //write_data(0x00,0X3C); //GON=1, DTE=1, D=1100

}

void H_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c)                   
{	
  unsigned int i,j;
  Lcd_Write_Com(0x02c); //write_memory_start
  digitalWrite(LCD_RS,HIGH);
  digitalWrite(LCD_CS,LOW);
  l=l+x;
  Address_set(x,y,l,y);
  j=l*2;
  for(i=1;i<=j;i++)
  {
    Lcd_Write_Data(c);
  }
  digitalWrite(LCD_CS,HIGH);   
}

void V_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c)                   
{	
  unsigned int i,j;
  Lcd_Write_Com(0x02c); //write_memory_start
  digitalWrite(LCD_RS,HIGH);
  digitalWrite(LCD_CS,LOW);
  l=l+y;
  Address_set(x,y,x,l);
  j=l*2;
  for(i=1;i<=j;i++)
  { 
    Lcd_Write_Data(c);
  }
  digitalWrite(LCD_CS,HIGH);   
}

void Rect(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c)
{
  H_line(x  , y  , w, c);
  H_line(x  , y+h, w, c);
  V_line(x  , y  , h, c);
  V_line(x+w, y  , h, c);
}

void Rectf(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c)
{
  unsigned int i;
  for(i=0;i<h;i++)
  {
    H_line(x  , y  , w, c);
    H_line(x  , y+i, w, c);
  }
}
int RGB(int r,int g,int b)
{return r << 16 | g << 8 | b;
}
void LCD_Clear(unsigned int j)                   
{	
  unsigned int i,m;
 Address_set(0,0,240,320);
  //Lcd_Write_Com(0x02c); //write_memory_start
  //digitalWrite(LCD_RS,HIGH);
  digitalWrite(LCD_CS,LOW);


  for(i=0;i<240;i++)
    for(m=0;m<320;m++)
    {
      Lcd_Write_Data(j>>8);
      Lcd_Write_Data(j);

    }
  digitalWrite(LCD_CS,HIGH);   
}

void setup()
{
  for(int p=0;p<10;p++)
  {
    pinMode(p,OUTPUT);
  }
  pinMode(A0,OUTPUT);
  pinMode(A1,OUTPUT);
  pinMode(A2,OUTPUT);
  pinMode(A3,OUTPUT);
  pinMode(A4,OUTPUT);
  digitalWrite(A0, HIGH);
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A4, HIGH);
  Lcd_Init();
 //LCD_Clear(0xf800);
}

void loop()
{  
   LCD_Clear(0xf800);
   LCD_Clear(0x07E0);
   LCD_Clear(0x001F);
  /*   
  for(int i=0;i<1000;i++)
  {
    Rect(random(300),random(300),random(300),random(300),random(65535)); // rectangle at x, y, with, hight, color
  }*/
  
//  LCD_Clear(0xf800);
}
