/*
*********************************************************************************************
*									SYSTEM INITIALIZATION 
*
*
* Programmer 	: 	John Leung, TechToys. Hong Kong
* Web presence  : 	www.TechToys.com.hk
* Hardware		: 	LPC2101/02/03
* Date			:	20th Oct 2007
* File			:	system.c
*
* Note			: 	System configuration such as PLL, VPBDIV and MAM is performed in C code.
* 					Say, if we want the target Processor clock Fcclk to be 60MHz at 
*					crystal frequency Fosc = 12MHz, the following calculation is required:
* 			
*					M=Fcclk/Fosc=60MHz/12MHz=5; Value written to MSEL bits in PLL0CFG is M-1, 
*					i.e. it is 4
* 					PLL0CFG[4:0]=4. There is a current controlled oscillator (CCO) with Fcco 
*					restricted as Fcco=P*Fcclk*2, 156MHz<Fcco<320MHz. 
* 					Now Fcclk=60MHz, thus P=2 by inspection. PSEL=PLL0CFG[6:5]=01
*					(refer to manual for this)
* 					PLL0CFG=0x24
* 					PCLKDIV defines the peripheral clock divider value in 1,2, or 4
* 					It finally defines VPB Divider to allow power savings when an application 
*					does not require any peripherals to run at the full processor rate.
* 					PCLKDIV defines value of 	1 for Pclk=Fcclk;  	full speed
*												2 for Pclk=Fcclk/2; half speed
*												4 for Pclk=Fcclk/4.	quarter speed
*********************************************************************************************
*/

/*
*********************************************************************************************
* Date 			:	21 Oct 2007
*					Add PLL_PLLE & PLL_PLLC for PLL enable/disable and PLL connect/disconnect
*********************************************************************************************
*/

#include <LPC2103.H>
#include "system.h"

#define Fcclk		(Fosc*M)			//system clock, multiple of Fosc from Fosc to 60MHz

/*
*********************************************************************************************
*									SYSTEM INITIALIZATION 
*
* The target CCLK is 60MHz at Fosc = 12MHz
* M=Fcclk/Fosc=60MHz/12MHz=5; Value written to MSEL bits	PLLCFG is M-1, i.e. it is 4
* PLLCFG[4:0]=4
* Fcco=P*Fcclk*2, 156MHz<Fcco<320MHz. 
* Now CCLK=60MHz, P=2 by inspection. PLLCFG[6:5]=01 (refer to data sheet for PLL section)
* PLLCFG=0x24
* Then, the Memory Accelerator Module MAM is also configured here (see src code below)
*********************************************************************************************
*/
void sysInit(void)
{
	if(PLL_PLLE){
	PLLCFG 	= ((PSEL_<<5)|(M-1));	//Set CCLK of 60MHz with an external crystal of 12MHz
	PLLCON 	= PLL_PLLE;				//Activate the PLL						
	PLLFEED 	= 0xAA;				//Update PLL with feed sequence						
	PLLFEED 	= 0x55;
	while(!(PLLSTAT&0x00000400));  	//wait until PLL stablize
	PLLCON 	= PLL_PLLE|PLL_PLLC<<1;	//Connect the PLL as the clock source after PLL FEED below
	PLLFEED 	= 0xAA;
	PLLFEED 	= 0x55;
	}

	//Connect the Processor clock CCLK to Peripheral clock Pclk with a suitable APBDIV divider
	#if PCLKDIV ==1			  			
		APBDIV 		= 1; 				//Pclk = Pcclk
	#else 
	#if PCLKDIV ==2		   				
		APBDIV		= 2;				//Pclk = Pcclk/2
	#else 
	#if PCLKDIV ==4	 				
		APBDIV		= 0;				//Pclk = Pcclk/4
	#endif
	#endif
	#endif
	

	/*
	Memory Accelerator Module (MAM)
	Mode 0: MAM off.
	Mode 1: MAM partially enabled. Sequential instruction accesses are fulfilled from the
	holding latches if the data is present.
	Mode 2: MAM fully enabled.
	*/

  	//For system clock slower than 20 MHz, MAMTIM can be 001. For system clock between
	//20 MHz and 40 MHz, Flash access time is suggested to be 2 CCLKs, while in systems
	//with system clock faster than 40 MHz, 3 CCLKs are proposed.
	MAMCR = 0;						//when changing MAM timing, MAM must first turned off
	#if Fcclk<20000000
		MAMTIM = 1;
	#else
	#if Fcclk<40000000
		MAMTIM = 2;
	#else
		MAMTIM = 3;
	#endif
	#endif
	MAMCR = 2;						//Fully enable the MAM
}

