// Con un Xtal 14,7456 MHz => configuro el PLL para => CClk=fosc y Pclk = CClk/4 = 3,6864 MHz  TPclk= 272 nSeg (aprox.)
// Pclk es el clock de los puertos, CClk es el clock del Core del ARM
#include <LPC210x.h>
__irq void timer0(void); // Prototipo de la interrupcion
unsigned char toggle=0;
int main(void)
{
	PINSEL0=0;
	PINSEL1=0; // Todos los puertos funcionan como tales.
	IODIR=0x0F000001; // De P27 a P24 y P0 los configuro como puertas de salida
	IOSET=0x0F000001; // Prendo leds
	
	/* Los timers tienen 2 contadores, 1 es el prescaler y el otro es el contador en si mismo, ambos tienen registros son de 32 bits
	   por lo tanto por c/u puedo contar 2^32, osea como maximo podria contar hasta 2^64*272 nSeg = muchos dias :-)
	   El timer seria una cosa asi:  FPclk --> Prescaler --> Contador
	   - Prescaler -> 2 resgistros
	   	  . TxPR: Es el valor de cuenta del prescaler.
	   	  . TxPC: Sirve para indicarle desde donde comienza a contar el prescaler, cuando sea igual a TxPR, desborda y empieza de nuevo, mandandole una cuenta al otro contador
	   - Contador -> 4 registros
	   	  . TxTCR: Es un registro de control, si vale:
		    -0: el contador no cuenta
			-1: el contador cuenta
			-2: reseteo el contador.
			Es como el TRx del 8051.
		  . TxTC: Sirve para indicar el valor de inicio del contador
		  . TxMRx: Son varios registros (segun el timer pueden ser 4 o 3), aca se pondra el valor de la cuenta q se desea alcanzar con el contador, cuando TxTC sea igual se produce un evento.
		    Son varios porq se lo puede configurar para q envie un evento en cuentas distintas, ej:
			- TxMR0 = 34; Al llegar aca se produce un evento, pero el contador sigue
			- TxMR1 = 45; Al llegar aca se produce otro evento
		  . TxMCR: Sirve para configurar q accion tomar cuando se produce un evento, es de 32 bits y c/3bits se cunfigura un MRx distinto:
		  	Si se produce un evento en MRx y TxMCR vale:
			- 001: lanza una interrupcion
			- 010: se resetea el contador
			- 100: se para el contador
			Las 3 acciones se pueden combinar, osea interrumpir y resetear al mismo tiempo.
	*/
	//------------------ Configuracion del Timer -----------------------------------------------//
	T0TCR=0x0; // el contador no cuenta
	T0TC=0x0;  // el contador comienza de 0
	T0PR=3686; // configuro la cuenta del prescaler tal q le mande una cuenta al contador c/ 1 mSeg
	T0PC=0x0;  // el prescaler comienza de 0
	T0MR0=1000; // configuro la cuenta del MR0 tal q cuente 1000 mSeg osea 1 seg
	T0MCR=0x03; // configuro q al producirce un evento en MR0, se lance una interrupcion y se resetee el contador
	//------------------------------------------------------------------------------------------//
	/* Registros de interrupciones:
	   VICIntEnable: habilita las 16 posibles fuentes de interrupciones, tipo un IE del 8051
	   VICIntSelect: configura a las interrupciones como:
	   		- FIQ: interrupciones rapidas
			- IRQ: interrupciones comun, q a su vez pueden ser:
			 	* vectorizadas (igual q en el 8051)
				* no vectorizadas (en teoria no lo veriamos)
	   VICVectCntl_0 al 15: en el se indican los indices de interrupciones habilitadas y si es vectorizada o no.
	   VICVectAddr_0 al 15: la direccion donde se encuentra la rutina de atencion, es como un setvect
	*/
	//------------------------ Configuracion de las interrupciones ------------------------------//
	VICIntSelect=0x0; // Lo configuro como IRQ
	VICIntEnable=0x10; // Interrupcion del Timer 0 activado, su indice es 4 al ser el bit 4	(importante para el reg. q viene)
	VICVectCntl0=0x24; // Los 4 1eros bits sirven para indicar el indice, el 6to bit si vale 1 indica q es vectorizado y si vale 0 q no
	VICVectAddr0= (unsigned long) timer0; // Le digo q la direccion de la subrutina timer0 q funciona como interrupcion
	//--------------------------------------------------------------------------------------------//
	T0TCR=1; // el contador empieza a contar
	while(1);
}
//--------- Rutina de la interrupcion ---------------------//
 __irq void timer0(void)
 {
 	if(toggle==0)
       {
       IOCLR=0x0F000001; // Apago leds
       toggle=1;
       }
    else
       {
       IOSET=0x0F000001; // Prendo leds
       toggle=0;
       }
	T0IR=0x01; // Limpio registro de interrupcion - No tengo idea de donde sale, habria q ver hoja de datos
	VICVectAddr=0xFF;
 }
 //---------------------------------------------------------//