/* 
* classTFT.cpp
*
* Created: 04/02/2020 18:29:30
* Author: Ledo
*/


#include "classTFT.h"

// default constructor
classTFT::classTFT()
{
} //classTFT

// default destructor
classTFT::~classTFT()
{
} //~classTFT

void classTFT::Tft_write_cmd(uint8_t cmd)
{
	TFT_DC_LOW();
	//Ponemos el comando en el bus de datos
	PIOD->PIO_ODSR = cmd;
	TFT_CS_LOW();
	TFT_WR_LOW();
	TFT_WR_HIGH();
	TFT_CS_HIGH();
}

uint16_t classTFT::Tft_read(void)
{
	uint16_t d;
	TFT_CS_LOW();
	TFT_RD_LOW();
	delay_us(1); //delay 1 us
	d = PIOD->PIO_ODSR;
	TFT_RD_HIGH();
	TFT_CS_HIGH();
	return d;
}





/*****************************************************************************
 * @name       :uint16_t Tft_RD_DATA(void)
 * @date       :2020-02-04 
 * @function   :Read an 16-bit value from the LCD screen
 * @parameters :None
 * @retvalue   :read value
******************************************************************************/
uint16_t classTFT::Tft_RD_DATA(void)
{
	TFT_DC_HIGH();
	return Tft_read();
}

/*****************************************************************************
 * @name       :void Tft_WR_DATA_16Bit(uint16_t Data)
 * @date       :2020-02-04 
 * @function   :Write an 16-bit data to the LCD screen
 * @parameters :Data:Data to be written
 * @retvalue   :None
******************************************************************************/	 
void classTFT::Tft_WR_DATA_16Bit(uint16_t Data)
{
	TFT_DC_HIGH();
	//Ponemos el dato en el bus de datos
	PIOD->PIO_ODSR = Data;
	TFT_CS_LOW();
	TFT_WR_LOW();
	TFT_WR_HIGH();
	TFT_CS_HIGH();
}

uint16_t classTFT::Color_To_565(uint8_t r, uint8_t g, uint8_t b)
{
	return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}

/*****************************************************************************
 * @name       :uint16_t Tft_ReadData_16Bit(void)
 * @date       :2020-02-04 
 * @function   :Read an 16-bit value from the LCD screen
 * @parameters :None
 * @retvalue   :read value
******************************************************************************/	
uint16_t classTFT::Tft_RD_DATA_16Bit(void)
{
	uint16_t r,g,b;
	TFT_DC_HIGH();
	TFT_CS_LOW();
	
	//dummy data
	TFT_RD_LOW();
	delay_us(1); //delay 1us
	r = PIOD->PIO_ODSR;
	TFT_RD_HIGH();
	
	//8bit:red data
	//16bit:red and green data
	TFT_RD_LOW();
	delay_us(1); //delay 1us
    r = PIOD->PIO_ODSR;	
	TFT_RD_HIGH();
	
	//8bit:green data
	//16bit:blue data
	TFT_RD_LOW();
	delay_us(1); //delay 1us
	g = PIOD->PIO_ODSR;
	TFT_RD_HIGH();
	
		
	TFT_RD_LOW();
	delay_us(1); //delay 1us
	b = PIOD->PIO_ODSR;
	TFT_RD_HIGH();
	b = g>>8;
	g = r&0xFF;
	r = r>>8;
	TFT_CS_HIGH();
	return Color_To_565(r, g, b);
}




/*****************************************************************************
 * @name       :void Tft_Clear(uint16_t Color)
 * @date       :2020-02-04 
 * @function   :Full screen filled LCD screen
 * @parameters :color:Filled color
 * @retvalue   :None
******************************************************************************/	
void classTFT::Tft_Clear(uint16_t Color)
{
	uint16_t i,j;
	Tft_SetWindows(0,0,LCD_W-1,LCD_H-1);	
    for(i=0;i<LCD_W;i++)
	 {
	  for (j=0;j<LCD_H;j++)
        	 Tft_WR_DATA_16Bit(Color);
	 }
}

/*****************************************************************************
 * @name       :void Tft_DrawPoint(uint16_t x,uint16_t y)
 * @date       :2020-02-04 
 * @function   :Write a pixel data at a specified location
 * @parameters :x:the x coordinate of the pixel
                y:the y coordinate of the pixel
 * @retvalue   :None
******************************************************************************/	
void classTFT::Tft_DrawPoint(uint16_t x,uint16_t y)
{
	Tft_SetWindows(x,y,x,y);
	Tft_WR_DATA_16Bit(POINT_COLOR); 	    
} 

/*****************************************************************************
 * @name       :uint16_t Tft_ReadPoint(uint16_t x,uint16_t y)
 * @date       :2020-02-04 
 * @function   :Read a pixel color value at a specified location
 * @parameters :x:the x coordinate of the pixel
                y:the y coordinate of the pixel
 * @retvalue   :the read color value
******************************************************************************/	
uint16_t classTFT::Tft_ReadPoint(uint16_t x,uint16_t y)
{
	uint16_t color;
	if(x>=lcddev.width||y>=lcddev.height)
	{
		return 0;		
	}
	Tft_SetCursor(x,y);
	PIOD->PIO_ODSR = 0xffff;
	color = Tft_RD_DATA_16Bit();
	PIOD->PIO_ODSR = 0xffff;
	return color;
}	

/*****************************************************************************
 * @name       :void Tft_Reset(void)
 * @date       :2020-02-04 
 * @function   :Reset LCD screen
 * @parameters :None
 * @retvalue   :None
******************************************************************************/	
void classTFT::Tft_Reset(void)
{
	delay_ms(50);	
	TFT_RST_ON();
	delay_ms(50);
	TFT_RST_OFF();
	delay_ms(50);
}


/*****************************************************************************
 * @name       :void Tft_Init(void)
 * @date       :2020-02-04 
 * @function   :Initialization LCD screen
 * @parameters :None
 * @retvalue   :None
******************************************************************************/	 	 
void classTFT::Tft_Init(void)
{
	lcddev.width = 800;
	lcddev.height = 480;
	delay_ms(50);
	Tft_Reset(); 
 
	Tft_write_cmd(0x00E2);	//PLL multiplier, set PLL clock to 120M
	Tft_WR_DATA_16Bit(0x0023);	    //N=0x36 for 6.5M, 0x23 for 10M crystal
	Tft_WR_DATA_16Bit(0x0002);
	Tft_WR_DATA_16Bit(0x0054);
	Tft_write_cmd(0x00E0);  // PLL enable
	Tft_WR_DATA_16Bit(0x0001);
	delay_us(10);
	Tft_write_cmd(0x00E0);
	Tft_WR_DATA_16Bit(0x0003);		// now, use PLL output as system clock
	delay_us(10);
	Tft_write_cmd(0x0001);  // software reset
	delay_us(20);
	Tft_write_cmd(0x00E6);	//PLL setting for PCLK, depends on resolution
	Tft_WR_DATA_16Bit(0x0003);
	Tft_WR_DATA_16Bit(0x0033);
	Tft_WR_DATA_16Bit(0x0033);

	Tft_write_cmd(0x00B0);	//LCD SPECIFICATION
	Tft_WR_DATA_16Bit(0x0020); //24 bit TFT panel
	Tft_WR_DATA_16Bit(0x0000); //Hsync+Vsync +DE mode  TFT mode
	Tft_WR_DATA_16Bit((799>>8));  //Set HDP
	Tft_WR_DATA_16Bit(799);
    Tft_WR_DATA_16Bit(479>>8);  //Set VDP
	Tft_WR_DATA_16Bit(479);
    Tft_WR_DATA_16Bit(0x0000);

	Tft_write_cmd(0x00B4);	//HSYNC
	Tft_WR_DATA_16Bit(0x04);  //Set HT
	Tft_WR_DATA_16Bit(0x1f);
	Tft_WR_DATA_16Bit(0x00);  //Set HPS
	Tft_WR_DATA_16Bit(0xd2);
	Tft_WR_DATA_16Bit(0x00);			   //Set HPW
	Tft_WR_DATA_16Bit(0x00);  //Set HPS
	Tft_WR_DATA_16Bit(0x00);
	Tft_WR_DATA_16Bit(0x00);

	Tft_write_cmd(0x00B6);	//VSYNC
	Tft_WR_DATA_16Bit(0x02);   //Set VT
	Tft_WR_DATA_16Bit(0x0c);
	Tft_WR_DATA_16Bit(0x00);  //Set VPS
	Tft_WR_DATA_16Bit(0x22);
	Tft_WR_DATA_16Bit(0x00);		//Set VPW
	Tft_WR_DATA_16Bit(0x00);  //Set FPS
	Tft_WR_DATA_16Bit(0x00);

	Tft_write_cmd(0x00B8);
	Tft_WR_DATA_16Bit(0x000f);    //GPIO is controlled by host GPIO[3:0]=output   GPIO[0]=1  LCD ON  GPIO[0]=1  LCD OFF 
	Tft_WR_DATA_16Bit(0x0001);    //GPIO0 normal

	Tft_write_cmd(0x00BA);
	Tft_WR_DATA_16Bit(0x0001);    //GPIO[0] out 1 --- LCD display on/off control PIN

	Tft_write_cmd(0x0036); //rotation
	Tft_WR_DATA_16Bit(0x0008);//RGB=BGR

	Tft_write_cmd(0x003A); //Set the current pixel format for RGB image data
	Tft_WR_DATA_16Bit(0x0050);//16-bit/pixel

	Tft_write_cmd(0x00F0); //Pixel Data Interface Format
	Tft_WR_DATA_16Bit(0x0003);//16-bit(565 format) data 

	Tft_write_cmd(0x00BC); 
	Tft_WR_DATA_16Bit(0x0040);//contrast value
	Tft_WR_DATA_16Bit(0x0080);//brightness value
	Tft_WR_DATA_16Bit(0x0040);//saturation value
	Tft_WR_DATA_16Bit(0x0001);//Post Processor Enable

	delay_us(5);

	Tft_write_cmd(0x0029); //display on

	Tft_write_cmd(0x00BE); //set PWM for B/L
	Tft_WR_DATA_16Bit(0x0006);
	Tft_WR_DATA_16Bit(0x0080);
	Tft_WR_DATA_16Bit(0x0001);
	Tft_WR_DATA_16Bit(0x00f0);
	Tft_WR_DATA_16Bit(0x0000);
	Tft_WR_DATA_16Bit(0x0000);

	Tft_write_cmd(0x00d0); 
	Tft_WR_DATA_16Bit(0x000d);

    TFT_BKL_ON();
	
}




/*****************************************************************************
 * @name       :void Tft_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd)
 * @date       :2020 02 04
 * @function   :Setting TFT display window
 * @parameters :xStar:the beginning x coordinate of the LCD display window
								yStar:the beginning y coordinate of the LCD display window
								xEnd:the ending x coordinate of the LCD display window
								yEnd:the ending y coordinate of the LCD display window
 * @retvalue   :None
******************************************************************************/ 
void classTFT::Tft_SetWindows(uint16_t xStart,uint16_t yStart,uint16_t xEnd,uint16_t yEnd)
{	
	 Tft_write_cmd(0x002A);
	 Tft_WR_DATA_16Bit(xStart>>8);
	 Tft_WR_DATA_16Bit(xStart&0x00ff);
	 Tft_WR_DATA_16Bit(xEnd>>8);
	 Tft_WR_DATA_16Bit(xEnd&0x00ff);
	 Tft_write_cmd(0x002b);
	 Tft_WR_DATA_16Bit(yStart>>8);
	 Tft_WR_DATA_16Bit(yStart&0x00ff);
	 Tft_WR_DATA_16Bit(yEnd>>8);
	 Tft_WR_DATA_16Bit(yEnd&0x00ff);
	 Tft_write_cmd(0x002c);

}   

/*****************************************************************************
 * @name       :void Tft_SetCursor(uint16_t Xpos, uint16_t Ypos)
 * @date       :2020 02 04
 * @function   :Set coordinate value
 * @parameters :Xpos:the  x coordinate of the pixel
		        Ypos:the  y coordinate of the pixel
 * @retvalue   :None
******************************************************************************/ 
void classTFT::Tft_SetCursor(uint16_t Xpos, uint16_t Ypos)
{	  	    			
	Tft_SetWindows(Xpos,Ypos,Xpos,Ypos);	
} 


 


