/*
***********************************************************************************************************************
*                                     TIMER 0 example (TMR0) for LPC2103 using irq
*
* Programmer 	: 	John Leung, TechToys. Hong Kong
* Web presence  : 	www.TechToys.com.hk
* ToolChain		: 	RealView MDK3.22a, evaluation copy
* Hardware		: 	LPC2103 demo board LPC2103 Eval 1A
* Date			: 	13 Sept 2008
* File			: 	tmr0_irq_main.c
* Note			: 	This example uses vectored irq with the highest priority for timer 0 
*					to produce a 50% duty cycle on pin P0_8 (LED) with a period of 200ms. The period
*					is configured in tmrInit(void).
***********************************************************************************************************************
*/  

#include <LPC2103.H>
#include "..\SYSTEM\system.h"
#include "..\IOCONFIG\ioconfig.h"

#define LED				P0_8		 				//LED connected to P0.8

#define LED_OFF			IOSET_bit.LED = 1			//macro to define an LED OFF action
#define LED_ON			IOCLR_bit.LED = 1			//macro to define an LED ON action

void T0isr(void) __irq;
void tmrInit(void);

/*
***********************************************************************************************************************
* Timer 0 interrupt
***********************************************************************************************************************
*/
void T0isr(void) __irq
{
	if(IOPIN_bit.LED==1) 							//toggle the LED pin
		LED_ON;
	else
		LED_OFF;

	T0IR_bit.MR0INT = 1;	  						//clear MR0 interrupt flag
	VICVectAddr = 0;							    //dummy write to clear the vector address
}

/*
***********************************************************************************************************************
* PCKDIV set 4 in system.h, and Fcclk = 1200000*5 in which 1200000 is the external crystal, and 5 is the PLL
* multiplier defined in system.h. As a result, peripheral clock = 60MHz/4 = 15MHz
***********************************************************************************************************************
*/
void tmrInit(void)
{
	T0PR = 149;				//Prescale 150 to obtain a tmr0 rate of 100kHz
	T0MCR_bit.MR0INT = 1;	//enable interrupt on MR0
	T0MCR_bit.MR0RES = 1;	//reset on MR0
	T0MR0 = 10000;			//set match register a value of 10000 for exactly 100 ms timer interval
	T0TCR = 2;				//reset tmr0, when CR bit 1.
	T0TCR = 1;				//start tmr0, and most importantly to release the CR bit in this instruction
							//because the timer remains in reset until the CR bit returns 0
}

/*
***********************************************************************************************************************
* 														MAIN
* This example uses vectored irq with the highest priority for timer 0 
* to produce a 50% duty cycle on pin P0_8 (LED) with a period of 200ms. The period
* is configured in tmrInit(void).
* A syntax like VICVectCntl0_bit.xxx = xxx is possible because of structure definition in ioconfig.h.
* It is alright to use the following syntax to replace 
*		VICVectCntl0_bit.NUMBER = VIC_TIMER0;		//VIC_TIMER0 equals 4 defined in ioconfig.h as well
*		VICVectCntl0_bit.ENABLED = 1;	
*		eq.
**		VICVectCntl0 = 0x24;
***********************************************************************************************************************
*/
int main(void)
{
	sysInit();									//Set CCLK and PCLK to 60MHz 
	tmrInit();									//set timer 0 for an MR interrupt of 100 msec
	LED_OFF;									//set LED off to start with
	IODIR_bit.LED = 1;							//Set LED pin as output

	/* Interrupt definition section */
	VICIntSelect = 0x00000000;					//classify all interrupt sources as IRQ (default upon BOR, therefore it is just for remarks)
	VICVectAddr0 = (int) T0isr;					//this register assigns the address of vectored IRQ to T0isr(void)
	VICVectCntl0_bit.NUMBER = VIC_TIMER0;		//slot 0 has the highest priority, assigned to TIMER 0
	VICVectCntl0_bit.ENABLED = 1;			    //enable the vectored irq and thus produce a unique ISR (VICVectAddr0) when the interrupt is asserted 
	VICIntEnable_bit.TMR0 = 1;					//enable TIMER 0 interrupt

	for(;;);	  								//Please observe that the program halts here but LED satill flashing out of interrupt.
}
