#include "lpc23xx.h"
#include "uart.h"
#include "ssp.h"
#include "l2f50126.h"

extern int SDRAM_BASE_ADDR;// 0xa0000000

#define SDRAM_PERIOD          13.8  // 72MHz
#define P2C(Period)           (((Period<SDRAM_PERIOD)?0:(unsigned int)((float)Period/SDRAM_PERIOD))+1)

#define SDRAM_REFRESH         7813
#define SDRAM_TRP             20
#define SDRAM_TRAS            45
#define SDRAM_TAPR            1
#define SDRAM_TDAL            3
#define SDRAM_TWR             3
#define SDRAM_TRC             65
#define SDRAM_TRFC            66
#define SDRAM_TXSR            67
#define SDRAM_TRRD            15
#define SDRAM_TMRD            3

void UNDEF_Routine(){
sendstr_uart0("undef");
}
void SWI_Routine(){
sendstr_uart0("swi");
}
void IRQ_Routine(){
sendstr_uart0("irq");
}
void FIQ_Routine(){
sendstr_uart0("fiq");
} 

unsigned char buffer[16384];
/*
void init_ram(void){
	int i;
	int wtemp;
	
	PINSEL5 |= 55010115;
	PINMODE5 |=0xAAAAAAAA;
	
	PINSEL6 = 0x55555555;
	PINMODE6 = 0xAAAAAAAA;
	
	PINSEL7 = 0x55555555;
	PINMODE7 = 0xAAAAAAAA;
	
	//p3.0-15=D0-31,mode=10
	PINSEL8 |= 0x15555555;
	PINMODE8|= 0x2AAAAAAA; //p4.0-4.14=A0-14,mode=10
	
	PINSEL9 |= (1<<18); //WE
	PINMODE9 |= 0xAAAAAAAA;
	
	PCONP|=0x800; //enable EMC power
	EMC_CTRL=1; // enable EMC
	EMC_DYN_RD_CFG=1;//Configures the dynamic memory read strategy(Command delayed strategy)
	EMC_DYN_RASCAS0|=0x200;
	EMC_DYN_RASCAS0&=0xFFFFFEFF;//CAS latency=2
	EMC_DYN_RASCAS0|=0x3; // RAS latency(active to read/write delay)=3
	EMC_DYN_RP= P2C(SDRAM_TRP);
	EMC_DYN_RAS = P2C(SDRAM_TRAS);
	EMC_DYN_SREX = P2C(SDRAM_TXSR);
	EMC_DYN_APR = SDRAM_TAPR;
	EMC_DYN_DAL = SDRAM_TDAL+P2C(SDRAM_TRP);
	EMC_DYN_WR = SDRAM_TWR;
	EMC_DYN_RC = P2C(SDRAM_TRC);
	EMC_DYN_RFC = P2C(SDRAM_TRFC);
	EMC_DYN_XSR = P2C(SDRAM_TXSR);
	EMC_DYN_RRD = P2C(SDRAM_TRRD);
	EMC_DYN_MRD = SDRAM_TMRD;*/
/*	EMC_DYN_CFG0 = (1<<14)|(1<<9)|(1<<8);
	//64 MB (2Mx32), 4 banks, row length = 11, column length = 8

	EMC_DYN_CTRL = 0x0183; // NOP*/
	
	/*for(i = 200*30; i;i--);
	EMC_DYN_CTRL|=0x100; 
	EMC_DYN_CTRL&=0xFFFFFF7F;
	// Issue SDRAM PALL (precharge all) command.
	EMC_DYN_RFSH = 1; //Indicates 1X16 CCLKs between SDRAM refresh cycles.
	for(i= 128; i; --i); // > 128 clk
	EMC_DYN_RFSH = P2C(SDRAM_REFRESH) >> 4;
	// Indicates SDRAM_REFRESH time between SDRAM refresh cycles.
	EMC_DYN_CTRL|=0x80; EMC_DYN_CTRL&=0xFFFFFEFF;
	//Issue SDRAM MODE command.
	//wtemp = *((volatile unsigned short *)(SDRAM_BASE_ADDR | 0x00023000));
	// 8 burst, 2 CAS latency 
	EMC_DYN_CTRL = 0x0000; //Issue SDRAM norm command ;
	//CLKOUT stop; All clock enables low
	EMC_DYN_CFG0|=0x80000; //Buffer enabled for accesses to DCS0 chip
*/	
	
//}

//int test_ram(void){
//unsigned int i;
/*	// 32 bits access
	for (i = 0; i < 0x200000; i+=sizeof(unsigned int))
	{
		(*(unsigned int *)((unsigned int ) &SDRAM_BASE_ADDR+i)) = i;
	}
		for (i = 0; i < 0x200000; i+=sizeof(unsigned int ))
	{
		if (*(unsigned int *)((unsigned int )&SDRAM_BASE_ADDR+i) != i)
		{
			return(0);
		}
	}
	// 16 bits access
	for (i = 0; i < 0x10000; i+=sizeof(unsigned short))
	{
		*(unsigned short*)((unsigned int)&SDRAM_BASE_ADDR+i) = i;
	}
		for (i = 0; i < 0x10000; i+=sizeof(unsigned short))
	{
		if (*(unsigned short*)((unsigned int)&SDRAM_BASE_ADDR+i) != i)
		{
			return(0);
		}*/
	// 8 bits access
	/*for ( i = 0; i < 0x200; i++)
	{
		(*(volatile unsigned long *)(SDRAM_BASE_ADDR + i)) = i;
	//	*(unsigned char*)((unsigned int)&SDRAM_BASE_ADDR+i) = i;
	}
	for (i = 0; i < 0x200; i++)
	{
		if ((*(volatile unsigned long *)(SDRAM_BASE_ADDR + i)) != i)
		{	
			return(i);
		}
	}*/
/*	for (i = 0; i < 0x4000; i+=sizeof(unsigned int))
  {
    *(unsigned int*)((unsigned int)&SDRAM_BASE_ADDR+i) = i;
  }

  for (i = 0; i < 0x4000; i+=sizeof(unsigned int))
  {
    if (*(unsigned int*)((unsigned int)&SDRAM_BASE_ADDR+i) != i)
    {
      return(i);
    }
  }*/
//	return( 1);
	//}
//}



void init_pll(void){
    SCS|=(1<<5);  			/* Enable main OSC */   
    while(!(SCS&0x40)); 	/* Wait until main OSC is usable */    
    CLKSRCSEL = 0x1;   
	
	PLLCON = 0;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;
	// 4. Disable PLL
	PLLCON = 0;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;
	// 5. Select source clock for PLL
	// 6. Set PLL settings 280.1664 MHz divider = 1 multiplier = 19
	PLLCFG = (1<<16)|18;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;
	// 7. Enable PLL
	PLLCON = 1;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;
	// 8. Wait for the PLL to achieve lock
	while(!(PLLSTAT&(1<<26)));
	// 9. Set clk divider settings
	CCLKCFG   = 4-1;            // 1/4 Fpll - 70.0416 MHz
	//USBCLKCFG = 6-1;            // 1/6 Fpll - 48 MHz
	// 10. Connect the PLL
	PLLCON = 3;
	PLLFEED = 0xAA;
	PLLFEED = 0x55;
	
	PCLKSEL0 = 0x55555555;	//peripherals clock = 70.0416 MHz
	PCLKSEL1 = 0x55555555;
	
	MAMCR = 0x00;                                // Turn MAM off (default)
	MAMTIM = 0x04;                               // Set flash timing to 4 clock cycles
	MAMCR = 0x02;                                // Fully enable the Memory Accleration Module
    return;	
}





int main(void){
	//int i=0;
	init_pll();
	init_uart0(115200);
//	init_ram();
	SCS |= 1; //Enable FGPIO for port 0 and 1 
	init_ssp1();
	lcd_init();
	//fill_screen(RED);
	//displaystr("test",1,1);
	
	//FIO1DIR = (1<<5);
	while(1){
		//sendint4_uart0(i);
		//send_uart0('a');
		//sendstr_uart0("test");
		//FIO1SET = (1<<5);
		//i++;
		sendbyte_ssp(0xffff);
		/*lcd_init();
		fill_screen(RED);
		displaystr("test",1,1);*/
		//FIO1CLR = (1<<5);
	//	sendint4_uart0(0);
	}
	return 0;
}
