#include "lpc111x.h"
#define XTAL_OSC		// External clock reference

void init(void);
//void start(void)
//{
//	init();
//}
void Default_Handler(void);
void UART_interrupt(void);
//void CT16B0_interrupt(void);
//void SVC_interrupt(void);
//void SysTic_interrupt(void);

// The following are 'declared' in the linker script
extern unsigned char  INIT_DATA_VALUES;
extern unsigned char  INIT_DATA_START;
extern unsigned char  INIT_DATA_END;
extern unsigned char  BSS_START;
extern unsigned char  BSS_END;
// the section "vectors" is placed at the beginning of flash 
// by the linker script
extern void CT16B0_int();

const void * Vectors[] __attribute__((section(".vectors"))) ={
	(void *)0x10002000, 	/*  0 Top of stack 	*/ 
	init,   				/*  1 Reset Handler */
	Default_Handler,		/*  2 NMI 			*/
	Default_Handler,		/*  3 Hard Fault 	*/
	0,	                	/*  4 Reserved 		*/
	0,                   	/*  5 Reserved 		*/
	0,                   	/*  6 Reserved 		*/
	0,                   	/*  7 Reserved 		*/
	0,                   	/*  8 Reserved 		*/
	0,                   	/*  9 Reserved 		*/
	0,                   	/* 10 Reserved 		*/
	Default_Handler,			/* 11 SVC 	   		*/
	0,                   	/* 12 Reserved 		*/
	0,                   	/* 13 Reserved 		*/
	Default_Handler,     	/* 14 PendSV   		*/
	Default_Handler,     	/* 15 SysTick  		*/		
/* External interrupt handlers follow */
	Default_Handler, 		/* 16 PIO0_0  ( IRQ0) */
	Default_Handler, 		/* 17 PIO0_1  ( IRQ1) */
	Default_Handler, 		/* 18 PIO0_2  ( IRQ2) */
	Default_Handler, 		/* 19 PIO0_3  ( IRQ3) */
	Default_Handler, 		/* 20 PIO0_4  ( IRQ4) */
	Default_Handler, 		/* 21 PIO0_5  ( IRQ5) */
	Default_Handler, 		/* 22 PIO0_6  ( IRQ6) */
	Default_Handler, 		/* 23 PIO0_7  ( IRQ7) */
	Default_Handler, 		/* 24 PIO0_8  ( IRQ8) */
	Default_Handler, 		/* 25 PIO0_9  ( IRQ9) */
	Default_Handler, 		/* 26 PIO0_10 (IRQ10) */
	Default_Handler, 		/* 27 PIO0_11 (IRQ11) */
	Default_Handler,		/* 28 PIO1_0  (IRQ12) */
	Default_Handler ,  		/* 29 C_CAN   (IRQ13) */
	Default_Handler, 		/* 30 SSP1    (IRQ14) */
	Default_Handler, 		/* 31 I2C     (IRQ15) */
	Default_Handler, 		/* 32 CT16B0  (IRQ16) */
	Default_Handler, 		/* 33 CT16B1  (IRQ17) */
	Default_Handler, 		/* 34 CT32B0  (IRQ18) */
	Default_Handler, 		/* 35 CT32B1  (IRQ19) */
	Default_Handler, 		/* 36 SSP0    (IRQ20) */
	UART_interrupt,			/* 37 UART    (IRQ21) */
	Default_Handler, 		/* 38 RESERVED     	  */
	Default_Handler, 		/* 39 RESERVED     	  */
	Default_Handler, 		/* 40 ADC     (IRQ24) */
	Default_Handler, 		/* 41 WDT     (IRQ25) */
	Default_Handler, 		/* 42 BOD     (IRQ26) */
	Default_Handler, 		/* 43 RESERVED     	  */
	Default_Handler, 		/* 44 PIO3    (IRQ28) */
	Default_Handler, 		/* 45 PIO2    (IRQ29) */
	Default_Handler, 		/* 46 PIO1    (IRQ30) */
	Default_Handler 		/* 47 PIO0    (IRQ31) */
};

void __attribute__((naked)) init()
{
	unsigned char *src;
	unsigned char *dest;
	unsigned len;

/*
// This function sets the main clock to the PLL
// The PLL input is the 12MHz IRC or Crystal oscillator
// depending on XTAL_OSC being defined.
// MSEL = 4, PSEL = 2, sets the PLL factor as x5
// resulting in a 50MHz main clock, and 200MHz CCO (156MHz<fcco<320MHz)
#ifdef XTAL_OSC	
	PDRUNCFG &= ~(BIT7|BIT5); // Power up the PLL & system oscillator.
	SYSPLLCLKSEL = 1; // select system oscillator (crystal)
#else
	PDRUNCFG &= ~BIT7; // Power up the PLL.
	SYSPLLCLKSEL = 0; // select internal RC oscillator
#endif
	SYSPLLCTRL = (4 << 0) | (1 << 5); // set divisors/multipliers (de momento *(3+1))
	SYSPLLCLKUEN = 1; // inform PLL of update

	// If locked in a reasonable time switch to PLL, else keep
	// running on the 12MHz IRC
	for (len=1<<20;len;len--) {
		if (SYSPLLSTAT&1) {	// if locked
			MAINCLKSEL = 3; // Use PLL as main clock
			MAINCLKUEN = 1; // Inform core of clock update
			break;
		}
	} 
*/
	// do global/static data initialization
	src= &INIT_DATA_VALUES;
	dest= &INIT_DATA_START;
	len= &INIT_DATA_END-&INIT_DATA_START;
	while (len--) *dest++ = *src++;
	// zero out the uninitialized global/static variables
	dest = &BSS_START;
	len = &BSS_END - &BSS_START;
	while (len--) *dest++=0;
	// call main
	main();
}

void __attribute__((naked,section(".bcrp"),optimize("Os")))  Default_Handler()
{
	unsigned int i,*sp;
    const static unsigned char * const rnames[8]={
		"  R0","  R1","  R2","  R3"," R12","  LR","  PC","xPSR"
	};
	asm volatile ("mrs %0,psr\n":"=r"(i));
	_printf("\nDefault Handler. Exception_number=%d\n",i&0x3f);
	asm volatile ("mov %0,sp\n":"=r"(sp));
	for(i=0;i<8;i++) _printf("%s = 0x%08x\n",rnames[i],sp[i]);

	// Dummy exit function
	asm volatile (".global exit\nexit:\n");
	while(1);
}


