/*
===============================================================================
 Name        : main.c
 Author      : $(author)
 Version     :
 Copyright   : $(copyright)
 Description : main definition
===============================================================================
*/

#ifdef __USE_CMSIS
#include "LPC11xx.h"
#include "gpio.h"
#include "timer32.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>

// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

// TODO: insert other definitions and declarations here

#define LCD_RESET(x)	(GPIOSetValue(3, 5, x))
#define LCD_RS(x)		(GPIOSetValue(3, 0, x))
#define LCD_WR(x)		(GPIOSetValue(3, 1, x))
#define LCD_RD(x)		(GPIOSetValue(3, 2, x))
#define LCD_CS(x)		(GPIOSetValue(3, 4, x))

void delayms(uint8_t ms) {
	delay32Ms(0, ms);
}

void LED() {
	GPIOSetValue(0, 7, 1);
	delay32Ms(0, 200);
	GPIOSetValue(0, 7, 0);
	delay32Ms(0, 200);
}

void lcd_data(uint16_t data) {
	LCD_RS(1);
	LCD_CS(0);

	LPC_GPIO1->MASKED_ACCESS[0xFF] = (uint8_t)(data >> 8);
	LPC_GPIO2->MASKED_ACCESS[0xFF] = (uint8_t)(data);

	LCD_WR(0);
	LCD_WR(1);
	LCD_CS(1);
}

void lcd_cmd(uint16_t data) {
	LCD_RS(0);
	LCD_CS(0);

	LPC_GPIO1->MASKED_ACCESS[0xFF] = (uint8_t)(data >> 8);
	LPC_GPIO2->MASKED_ACCESS[0xFF] = (uint8_t)(data);

	LCD_WR(0);
	LCD_WR(1);
	LCD_CS(1);
}

void lcd_cpl(uint16_t cmd, uint16_t data) {
	lcd_cmd(cmd);
	lcd_data(data);
}

void lcd_init() {
	//LCD_RD(0);
    LCD_RESET(1);
    delayms(5);

    LCD_RESET(0);

	delayms(10);

	LCD_RESET(1);

	delayms(20);

	   //  VENDOR
	lcd_cpl(0x0046,0x00A4);
	lcd_cpl(0x0047,0x0053);
	lcd_cpl(0x0048,0x0000);
	lcd_cpl(0x0049,0x0044);
	lcd_cpl(0x004a,0x0004);
	lcd_cpl(0x004b,0x0067);
	lcd_cpl(0x004c,0x0033);
	lcd_cpl(0x004d,0x0077);
	lcd_cpl(0x004e,0x0012);
	lcd_cpl(0x004f,0x004C);
	lcd_cpl(0x0050,0x0046);
	lcd_cpl(0x0051,0x0044);

	  //240x320 window setting
    lcd_cpl(0x0002,0x0000); // Column address start2
 	lcd_cpl(0x0003,0x0000); // Column address start1
 	lcd_cpl(0x0004,0x0000); // Column address end2
 	lcd_cpl(0x0005,0x00ef); // Column address end1
    lcd_cpl(0x0006,0x0000); // Row address start2
	lcd_cpl(0x0007,0x0000); // Row address start1
	lcd_cpl(0x0008,0x0001); // Row address end2
	lcd_cpl(0x0009,0x003f); // Row address end1

  // Display Setting
	lcd_cpl(0x0001,0x0006); // IDMON=0, INVON=1, NORON=1, PTLON=0
	lcd_cpl(0x0016,0x00C8); // MY=0, MX=0, MV=0, ML=1, BGR=0, TEON=0   0048
	lcd_cpl(0x0023,0x0095); // N_DC=1001 0101
	lcd_cpl(0x0024,0x0095); // PI_DC=1001 0101
	lcd_cpl(0x0025,0x00FF); // I_DC=1111 1111

	lcd_cpl(0x0027,0x0002); // N_BP=0000 0010
	lcd_cpl(0x0028,0x0002); // N_FP=0000 0010
	lcd_cpl(0x0029,0x0002); // PI_BP=0000 0010
	lcd_cpl(0x002a,0x0002); // PI_FP=0000 0010
	lcd_cpl(0x002C,0x0002); // I_BP=0000 0010
	lcd_cpl(0x002d,0x0002); // I_FP=0000 0010

	lcd_cpl(0x003a,0x0001); // N_RTN=0000, N_NW=001    0001
	lcd_cpl(0x003b,0x0000); // P_RTN=0000, P_NW=001
	lcd_cpl(0x003c,0x00f0); // I_RTN=1111, I_NW=000
	lcd_cpl(0x003d,0x0000); // DIV=00
	delayms(1);
	lcd_cpl(0x0035,0x0038); // EQS=38h
	lcd_cpl(0x0036,0x0078); // EQP=78h
	lcd_cpl(0x003E,0x0038); // SON=38h
	lcd_cpl(0x0040,0x000F); // GDON=0Fh
	lcd_cpl(0x0041,0x00F0); // GDOFF

	// Power Supply Setting
	lcd_cpl(0x0019,0x0049); // CADJ=0100, CUADJ=100, OSD_EN=1 ,60Hz
	lcd_cpl(0x0093,0x000F); // RADJ=1111, 100%
	delayms(1);
	lcd_cpl(0x0020,0x0040); // BT=0100
	lcd_cpl(0x001D,0x0007); // VC1=111   0007
	lcd_cpl(0x001E,0x0000); // VC3=000
	lcd_cpl(0x001F,0x0004); // VRH=0011

	//VCOM SETTING
	lcd_cpl(0x0044,0x004D); // VCM=101 0000  4D
	lcd_cpl(0x0045,0x000E); // VDV=1 0001   0011
	delayms(1);
	lcd_cpl(0x001C,0x0004); // AP=100
	delayms(2);

	lcd_cpl(0x001B,0x0018); // GASENB=0, PON=0, DK=1, XDK=0, VLCD_TRI=0, STB=0
	delayms(1);
	lcd_cpl(0x001B,0x0010); // GASENB=0, PON=1, DK=0, XDK=0, VLCD_TRI=0, STB=0
	delayms(1);
	lcd_cpl(0x0043,0x0080); //set VCOMG=1
	delayms(2);

	// Display ON Setting
	lcd_cpl(0x0090,0x007F); // SAP=0111 1111
	lcd_cpl(0x0026,0x0004); //GON=0, DTE=0, D=01
	delayms(1);
	lcd_cpl(0x0026,0x0024); //GON=1, DTE=0, D=01
	lcd_cpl(0x0026,0x002C); //GON=1, DTE=0, D=11
	delayms(1);
	lcd_cpl(0x0026,0x003C); //GON=1, DTE=1, D=11

	// INTERNAL REGISTER SETTING
	lcd_cpl(0x0057,0x0002); // TEST_Mode=1: into TEST mode
	lcd_cpl(0x0095,0x0001); // SET DISPLAY CLOCK AND PUMPING CLOCK TO SYNCHRONIZE
	lcd_cpl(0x0057,0x0000); // TEST_Mode=0: exit TEST mode
	//lcd_cpl(0x0021,0x0000);
	lcd_cmd(0x0022);
}

void lcd_address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
	lcd_cpl(0x0002,x1>>8);	   // Column address start2
	lcd_cpl(0x0003,x1);	   // Column address start1
	lcd_cpl(0x0004,x2>>8);	   // Column address end2
	lcd_cpl(0x0005,x2);	   // Column address end1
	lcd_cpl(0x0006,y1>>8);	   // Row address start2
	lcd_cpl(0x0007,y1);	   // Row address start1
	lcd_cpl(0x0008,y2>>8);	   // Row address end2
	lcd_cpl(0x0009,y2);	   // Row address end1
    lcd_cmd(0x0022);

}

int main(void) {
	
	GPIOInit();
	init_timer32(0, 10);

	GPIOSetDir(0, 7, 1);

	uint8_t i;

	for (i=0;i<8;i++) {
		GPIOSetDir(1, i, 1);
		GPIOSetDir(2, i, 1);
		GPIOSetDir(3, i, 1);
	}

	LCD_RD(1);

	LED();

	delay32Ms(0, 250);

	lcd_init();


	while(1) {
		LED();
		int i,j;
		lcd_address_set(0,0,239,319);

	    for(i=0;i<320;i++) {
		  for (j=0;j<240;j++) {
	         lcd_data(0xFF00);
		   }
		}

	};

	return 0 ;
}
