/****************************************************************************/
/* Copyright 2010, © Bendor Research Pty. Ltd. All rights reserved.			*/
/* Permission is granted to use this software for any purpose whatsoever	*/
/* as long as this copyright notice is preserved. The code is provided		*/
/* "as is", with no explicit, implicit or implied warranty or guarantee		*/
/* of any kind and Bendor Research Pty. Ltd. can not be held liable for		*/
/* any loss or damages arising out of the use of this software.				*/
/****************************************************************************/
/*																			*/
/*	Include file describing the Philips LPC210x system control block		*/
/*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~		*/
/*																			*/
/*	2011 Jan	ZK		Generated from the LPC23xx version					*/
/*																			*/
/****************************************************************************/

#ifndef	LPC210x_SCB
#define	LPC210x_SCB

/*
*	System control block registers
*/

struct lpc210x_scb {

	unsigned mamcr;			// 000 Memory acceleration module control
	unsigned mamtim;		// 004 Memory acceleration module timing
	unsigned _1[14];
	unsigned memmap;		// 040 Interrupt vector table mapping
	unsigned _2[15];
	unsigned pllcon;		// 080 PLL control
	unsigned pllcfg;		// 084 PLL configuration
	unsigned pllstat;		// 088 PLL status
	unsigned pllfeed;		// 08c PLL feed
	unsigned _3[12];
	unsigned pcon;			// 0c0 Power mode control
	unsigned pconp;			// 0c4 Peripheral power control
	unsigned _4[14];
	unsigned apbdiv;		// 100 APB divider control
	unsigned _5[15];
	unsigned extint;		// 140 External interrupt status flags
	unsigned intwake;		// 144 Wake-up interrupt select
	unsigned extmode;		// 148 External interrupt is edge sensitive
	unsigned extpolar;		// 14c External interrupt is active high
	unsigned _6[12];
	unsigned rsir;			// 180 Reset source identification
	unsigned _7[7];
	unsigned scs;			// 1a0 Micellaneous system control
};

/****************************************************************************/
/*				General system control related definitions					*/
/****************************************************************************/

/*
*	Definitions for the reset source register
*/

#define	SCB_RSIR_POR	0x01		// Power-on reset
#define	SCB_RSIR_EXTR	0x02		// External reset
#define	SCB_RSIR_WDTR	0x04		// Watchdog reset

/*
*	Definitions for the system control register
*/

#define	SCB_SCS_HSPIO	0x01		// High-speed mode GPIO ports 1 & 2

/*
*	Definitions for the map_vect register
*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

#define	SCB_MEMMAP_BOOT		0		// Boot loader mode
#define	SCB_MEMMAP_FLASH	1		// User FLASH mode
#define	SCB_MEMMAP_RAM		2		// Internal RAM mode

/****************************************************************************/
/*				Memory acceleration related definitions						*/
/****************************************************************************/

/*
*	Definitions for the mamcr register
*	Note that mamtim should be set to 1 - 7, the number of CCLK cycles
*	per fetch.
*/

#define	SCB_MAMCR_MODE_NONE	0x00	// Memory acceleration disabled
#define	SCB_MAMCR_MODE_PART	0x01	// Memory acceleration partially enab.
#define	SCB_MAMCR_MODE_FULL	0x02	// Memory acceleration fully enabled

/****************************************************************************/
/*						Clock related definitions							*/
/****************************************************************************/

/*
*	Definitons for the CPU clock divider
*	This register holds the clock divisor for the CPU. It must be an
*	even number and the register should be written with that value - 1.
*	The permitted values range from 2 to 256.
*	If you pass 1 to this macro, then CCLK is the same as HCLK and you
*	must bypass the PLL.
*/

#define	SCB_CCLKCFG(n)		((n)-1)

/*
*	Definitions for the APBDIV register
*/

#define	SCB_APBDIV_4		0x00	// APB clock = 1 * CCLK / 4
#define	SCB_APBDIV_1		0x01	// APB clock = 1 * CCLK / 1
#define	SCB_APBDIV_2		0x02	// APB clock = 1 * CCLK / 2

/****************************************************************************/
/*						PLL related definitions								*/
/****************************************************************************/

/*
*	Definitions for the pllcon register
*/

#define	SCB_PLLCON_PLLE		0x01	// Enable PLL
#define	SCB_PLLCON_PLLC		0x02	// Connect PLL to system clock

/*
*	PLL configuration register
*	~~~~~~~~~~~~~~~~~~~~~~~~~~
*	You have to satisfy 2 equations:
*
*		fsys = fosc * M
*		fvco = fsys * 2 * (1<<P)
*
*	where fsys is the system (CPU) frequency, fosc is the frequency of the
*	crystal oscillator and fvco if the frequency of the VCO in the PLL.
*	The M and P values are parameters to be loaded into the PLL control
*	register.
*
*	Valid ranges are:
*
*		fsys:	 10 -  60 MHz
*		fosc:	 10 -  25 MHz
*		fvco:	156 - 320 MHz
*		M:		  1 -  32
*		P:		  0 -   3
*
*	For example, if you have a 10 MHz crystal and want to run on 60 MHz,
*	then you have M = 60 / 10 = 6. The smallest (and actually only) even
*	multiple of 60 MHz in the 156-320 MHz range is 240MHz, hence P must
*	be set to 2.
*/

#define	SCB_PLLCFG_MSEL(m)	((m)-1)			// Sets the M value, 1-32
#define	SCB_PLLCFG_PSEL(p)	((p)<<5)		// Sets the P value, 0-3

/*
*	Definitions for the pll_stat register
*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

#define	SCB_PLLSTAT_MSEL	0x0000001f		// Mask for the M - 1 value
#define	SCB_PLLSTAT_PSEL	0x00000060		// Mask for the P value
#define	SCB_PLLSTAT_PLLE	0x00000100		// PLL is enabled
#define	SCB_PLLSTAT_PLLC	0x00000200		// PLL is connected
#define	SCB_PLLSTAT_PLOCK	0x00000400		// PLL is locked

/*
*	Definitions for the pll_feed register
*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*	To make the PLL work, you have to set it up, wait until it locks,
*	feed it twice (in the proper order) and then you can connect it.
*/

#define	SCB_PLLFEED_FOOD1	0xaa
#define	SCB_PLLFEED_FOOD2	0x55

/****************************************************************************/
/*					Power control related definitions						*/
/****************************************************************************/

/*
*	Definitions for the power control register
*/

#define	SCB_PCON_IDL		0x01			// Idle mode
#define	SCB_PCON_PD			0x02			// Power down mode

/*
*	Definitions for the peripheral power control register
*	This register enables the 'power' (well, the clock, actually) to
*	the on-chip peripherals.
*/

#define	SCB_PCONP_TIM0		0x00000002		// Timer 0 power enable
#define	SCB_PCONP_TIM1		0x00000004		// Timer 1 power enable
#define	SCB_PCONP_SIO0		0x00000008		// UART 0 power enable
#define	SCB_PCONP_SIO1		0x00000010		// UART 1 power enable
#define	SCB_PCONP_I2C0		0x00000080		// I2C bus 0 power enable
#define	SCB_PCONP_SPI		0x00000100		// SPI controller power enable
#define	SCB_PCONP_RTC		0x00000200		// Real-time clock power enable
#define	SCB_PCONP_SSP		0x00000400		// SSP controller 1 power enable
#define	SCB_PCONP_ADC		0x00001000		// A/D converter power enable
#define	SCB_PCONP_I2C1		0x00080000		// I2C bus 1 power enable
#define	SCB_PCONP_TIM2		0x00400000		// Timer 2 power enable
#define	SCB_PCONP_TIM3		0x00800000		// Timer 3 power enable

/****************************************************************************/
/*					 Interrupt related definitions							*/
/****************************************************************************/

/*
*	Definitiosn for the ext???? registers
*/

#define	SCB_EXT_EINT0			0x0001		// External interrupt 0
#define	SCB_EXT_EINT1			0x0002		// External interrupt 1
#define	SCB_EXT_EINT2			0x0004		// External interrupt 2

/*
*	Definitions for the intwake register
*/

#define	SCB_INTWAKE_EXTWAKE0	0x0001		// External interrupt 0
#define	SCB_INTWAKE_EXTWAKE1	0x0002		// External interrupt 1
#define	SCB_INTWAKE_EXTWAKE2	0x0004		// External interrupt 2
#define	SCB_INTWAKE_RTCWAKE		0x8000		// Wake up on RTC request


/*
*	SCB instance
*/

static volatile struct lpc210x_scb * const lpc_scb = (void *) 0xe01fc000;

#endif

