#include <LPC214X.h>
#include "TFT018.h"
#include "MyType.h"

volatile U8 Font=0;

/*----------------------------------------------------------*\
 | Backlight Initialize                                     |
\*----------------------------------------------------------*/
void BacklightOn(void) {
	PINSEL1 &= 0xFFFFF3FF;
	PINSEL1 |= 0x00000400;
	PWMPR = 0x00;
	PWMMR0 = 50;
	PWMMR5 = 6;
	PWMLER = 0x20;
	PWMPCR = 0x2000;
	PWMTCR = 0x09;
	}

/*----------------------------------------------------------*\
 | Delay                                                    |
\*----------------------------------------------------------*/
void Delay1Ms(unsigned int tmr) {
	while( tmr ) {
		unsigned int i;
		for(i=0;i<10;i++);
		tmr--;
		}
	}
/*----------------------------------------------------------*\
 | BUS simulate                                             |
\*----------------------------------------------------------*/

/* ------ LOW LEVEL OPERATE ------ */
void LCD_Bus_Initial( void ) {
	//PINSEL2 = 0x00000004;
	//SCS=0x03;		//FGPIO
	//FIO0MASK = ~(LCD_BUS_RST | LCD_BUS_CS | LCD_BUS_RD);
	IODIR0 = LCD_BUS_RST | LCD_BUS_CS | LCD_BUS_RD;
	//FIO1MASK = ~(LCD_BUS_RS | LCD_BUS_RW | LCD_BUS_DAT);
	IODIR1 = LCD_BUS_RS | LCD_BUS_RW;

	IOCLR0 = LCD_BUS_RST;
	Delay1Ms( 20 );
	IOSET0 = LCD_BUS_RST | LCD_BUS_CS | LCD_BUS_RD;
	IOSET1 = LCD_BUS_RS | LCD_BUS_RW;
	}

void LCD_Bus_Write_Byte( unsigned char Data ) {
	unsigned int d = (((unsigned int)Data)<<16) & LCD_BUS_DAT;
	IOCLR1 = LCD_BUS_DAT;	// data on bus
	IOSET1 = d;
	//IOPIN1 = ((unsigned int)Data)<<16;
	IOCLR1 =  LCD_BUS_RW;	// RW to LOW
	//Delay1Ms( 1 );
	IOSET1 =  LCD_BUS_RW;	// RW to HIGH
	}

void LCD_Bus_Write_Data( unsigned short Data ) {
	LCD_Bus_Write_Byte( Data>>8 );
	LCD_Bus_Write_Byte( Data );
	}

unsigned int LCD_Bus_Read_Byte( void ) {
	unsigned int BusData;

	IOCLR0 =  LCD_BUS_RD;	// RD to LOW
	BusData = IOPIN1;
	Delay1Ms( 1 );
	IOSET0 =  LCD_BUS_RD;	// RD to HIGH

	return (BusData>>16)&0xFF;
	}

void LCD_Reg_Set(unsigned int Cmd,unsigned int Data) {
	IODIR1 |= LCD_BUS_DAT;

	IOCLR0 =  LCD_BUS_CS;
	IOSET0 =  LCD_BUS_RD;

	IOCLR1 =  LCD_BUS_RS;
	LCD_Bus_Write_Byte( Cmd );

	IOSET1 =  LCD_BUS_RS;
	LCD_Bus_Write_Byte( Data );

	IOSET0 =  LCD_BUS_CS;

	IODIR1 &= ~LCD_BUS_DAT;
	}

/*----------------------------------------------------------*\
 | LCD Initialize                                           |
\*----------------------------------------------------------*/
void LCD_Init( void ) {
	LCD_Bus_Initial();

	//IOCLR =  LCD_BUS_CS;

	//LCD_Reg_Set(0x01,0x00);
	//LCD_Reg_Set(0x02,0x06);
	//LCD_Reg_Set(0x02,0x46);
	LCD_Reg_Set(0x02,0x86);
	LCD_Reg_Set(0x03,0x00);
	LCD_Reg_Set(0x05,0x08);
	LCD_Reg_Set(0x07,0x7F);
	LCD_Reg_Set(0x08,0x17);
	// SRAM control
	LCD_Reg_Set(0x09,0x00);
	LCD_Reg_Set(0x10,0x00);
	LCD_Reg_Set(0x11,0x7F);
	LCD_Reg_Set(0x12,0x9F);
	LCD_Reg_Set(0x14,0x00);
	LCD_Reg_Set(0x16,0x9F);
	LCD_Reg_Set(0x17,0x01);
	LCD_Reg_Set(0x18,0x00);
	LCD_Reg_Set(0x19,0x00);
	// Gamma voltage adjustalbe level
	LCD_Reg_Set(0x21,0x88);
	LCD_Reg_Set(0x22,0x33);
	LCD_Reg_Set(0x23,0xCC);
	LCD_Reg_Set(0x24,0xCC);
	LCD_Reg_Set(0x25,0xBB);
	LCD_Reg_Set(0x26,0xBB);
	LCD_Reg_Set(0x27,0x77);
	LCD_Reg_Set(0x28,0x77);
	LCD_Reg_Set(0x29,0x77);

	LCD_Reg_Set(0x06,0xC7);
	}

void LCD_SetArea( U8 x0, U8 y0, U8 x1, U8 y1 ) {
	// SRAM control
	LCD_Reg_Set(0x09,y0);
	LCD_Reg_Set(0x10,x0);
	LCD_Reg_Set(0x11,y1);
	LCD_Reg_Set(0x12,x1);
							
	LCD_Reg_Set(0x18,y0);
	LCD_Reg_Set(0x19,x0);
	}


void LCD_Rectangle( unsigned short x0, unsigned short y0, unsigned short x1, unsigned short y1, unsigned int Data ) {
	int x,y;

	LCD_SetArea(x0,y0,x1,y1);

	IODIR1 |= LCD_BUS_DAT;

	IOCLR0 =  LCD_BUS_CS;
	IOSET0 =  LCD_BUS_RD;

	IOSET1 =  LCD_BUS_RS;
	for(x=0;x<=x1-x0;x++)
		for(y=0;y<=y1-y0;y++) {
			LCD_Bus_Write_Byte( Data>>8 );
			LCD_Bus_Write_Byte( Data );
			}

	IOSET0 =  LCD_BUS_CS;

	IODIR1 &= ~LCD_BUS_DAT;
	}

void LCD_Clear_Screen( unsigned int Data ) {
	LCD_Rectangle(0,0,159,127, Data );
	}

void LCD_SetPixel(unsigned short x, unsigned short y, unsigned short color) {
	LCD_SetArea(x,y,x,y);

	IODIR1 |= LCD_BUS_DAT;

	IOCLR0 =  LCD_BUS_CS;
	IOSET0 =  LCD_BUS_RD;

	LCD_Bus_Write_Byte( color>>8 );
	LCD_Bus_Write_Byte( color );

	IOSET0 =  LCD_BUS_CS;

	IODIR1 &= ~LCD_BUS_DAT;
	}


#include "8X16.h"

void LCD_PutChar8x16(unsigned short x, unsigned short y, char c, unsigned int f, unsigned int b) {
	register unsigned int i,j;

	LCD_SetArea(x,y,x+8-1,y+16-1);

	IODIR1 |= LCD_BUS_DAT;

	IOCLR0 =  LCD_BUS_CS;
	IOSET0 =  LCD_BUS_RD;
	IOSET1 =  LCD_BUS_RS;

	for(i=0; i<16;i++) {
		unsigned char m=Font8x16[c*16+i];
		for(j=0;j<8;j++) {
			if((m&0x80)==0x80) {
				LCD_Bus_Write_Byte(f>>8);
				LCD_Bus_Write_Byte(f);
				}
			else {
				LCD_Bus_Write_Byte(b>>8);
				LCD_Bus_Write_Byte(b);
				}
			m<<=1;
			}
		}

	IOSET0 =  LCD_BUS_CS;
	IODIR1 &= ~LCD_BUS_DAT;
	}

#include "8X8h.h"

void LCD_PutChar8x8(unsigned short x, unsigned short y, char c, unsigned int f, unsigned int b) {
	register unsigned int i,j;

	LCD_SetArea(x,y,x+8-1,y+8-1);

	IODIR1 |= LCD_BUS_DAT;

	IOCLR0 =  LCD_BUS_CS;
	IOSET0 =  LCD_BUS_RD;
	IOSET1 =  LCD_BUS_RS;

	for(i=0; i<8;i++) {
		unsigned char m=Font8x8[c][i];
		for(j=0;j<8;j++) {
			if((m&0x80)==0x80) {
				LCD_Bus_Write_Byte(f>>8);
				LCD_Bus_Write_Byte(f);
				}
			else {
				LCD_Bus_Write_Byte(b>>8);
				LCD_Bus_Write_Byte(b);
				}
			m<<=1;
			}
		}

	IOSET0 =  LCD_BUS_CS;
	IODIR1 &= ~LCD_BUS_DAT;
	}

void LCD_PutChar(unsigned short x, unsigned short y, char c, unsigned int f, unsigned int b) {
	if( Font )
		LCD_PutChar8x8( x, y, c, f, b );
	else
		LCD_PutChar8x16( x, y, c, f, b );
	}

#include "GB1616.h"

void PutGB1616h(unsigned short x, unsigned short  y, unsigned char c[2], unsigned int f,unsigned int b, int h){
	unsigned int i,j,k;

	if(h==0){
		LCD_SetArea(x, y, x+16-1, y+8-1);
		i = 0;
		h = 16;
	}
	else{
		LCD_SetArea(x, y+8, x+16-1, y+16-1);
		i = 16;
		h = 32;
	}

	IODIR1 |= LCD_BUS_DAT;

	IOCLR0 =  LCD_BUS_CS;
	IOSET0 =  LCD_BUS_RD;
	IOSET1 =  LCD_BUS_RS;

	for (k=0;k<49;k++) {
	  if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1])){ 
    	for(;i<h;i++) {
		  unsigned short m=codeGB_16[k].Msk[i];
		  for(j=0;j<8;j++) {
			if((m&0x80)==0x80) {
				LCD_Bus_Write_Byte(f>>8);
				LCD_Bus_Write_Byte(f);
				}
			else {
				LCD_Bus_Write_Byte(b>>8);
				LCD_Bus_Write_Byte(b);
				}
			m<<=1;
			} 
		  }
		  break;
		}  
	  }	

	IOSET0 =  LCD_BUS_CS;
	IODIR1 &= ~LCD_BUS_DAT;
	}

void PutGB1616(unsigned short x, unsigned short  y, unsigned char c[2], unsigned int f,unsigned int b)
{
	PutGB1616h(x, y, c, f, b, 0);
	PutGB1616h(x, y, c, f, b, 1);
}

void LCD_PutString(unsigned short x, unsigned short y, char *s, unsigned int f, unsigned int b) {
	register unsigned char l=0;
	while(*s) {
		if( *s < 0x80 ) {
			LCD_PutChar(x+l*8,y,*s,f,b);
			s++;l++;
			}
		else {
			PutGB1616(x+l*8,y,(unsigned char *)s,f,b);
			s+=2;l+=2;
			}
		}
	}

void LCD_BMP( U8 x0, U8 y0, U8 x1, U8 y1 , U16 * Bmp ) {
	S16 i,j;

	LCD_SetArea(x0,y0,x1-1,y1-1);

	IODIR1 |= LCD_BUS_DAT;

	IOCLR0 =  LCD_BUS_CS;
	IOSET0 =  LCD_BUS_RD;
	IOSET1 =  LCD_BUS_RS;

	for( i = 0; i < y1 - y0; i++ )
		for( j = 0; j < x1 - x0; j++ ) {
			U16 Pix = *(Bmp+j*(y1-y0)+i);
			LCD_Bus_Write_Byte(Pix>>8);
			LCD_Bus_Write_Byte(Pix);
			}

	IOSET0 =  LCD_BUS_CS;
	IODIR1 &= ~LCD_BUS_DAT;
	}

unsigned short LCD_Bus_Read_Pixel( void ) {
	unsigned short BusData;

	BusData = LCD_Bus_Read_Byte()<<8;
	BusData |= LCD_Bus_Read_Byte();

	return BusData;
	}

