/*****************************************************/
/* Examples Program For "ET-ARM7 BASE LPC2103" Board */
/* Target MCU  : Philips ARM7-LPC2103                */
/*       	   : X-TAL : 19.6608 MHz                 */
/*             : Run Speed 58.9824MHz (With PLL)     */
/* Keil Editor : uVision3 V3.03a                     */
/* Compiler    : Keil CARM V2.50a		             */
/* Create By   : Eakachai Makarn (WWW.ETT.CO.TH)     */
/* Last Update : 17/April/2006                       */
/* Function    : Example Use UART1 Show EINT-0,1,2   */
/*****************************************************/
// Print Message to UART1 (9600,N,8,1)
// IRQ Non Vector Interrupt	Mode Example
// Used GPIO0.16 Trigger Interrupt (IRQ Vector)
// Used GPIO0.14 Trigger Interrupt (IRQ Vector)
// Used GPIO0.15 Trigger Interrupt (IRQ Vector)
// Trigger GPIO0.16 For Trigger External Interrupt-0
// Trigger GPIO0.14 For Trigger External Interrupt-1
// Trigger GPIO0.15 For Trigger External Interrupt-2

// External Interrupt-1 Can Trigger By Press SW-LOAD 

#include <LPC2103.H> 	                                	// LPC2103 MPU Register
#include <stdio.h>											// For Used Function printf 

/* pototype  section */
void init_serial0 (void); 									// Initil UART-0
int putchar (int ch);  										// Put Char to UART-0
int getchar (void);  										// Get Char From Uart-0
void NonVectoredIRQ (void) __irq;							// Non-Vector Interrupt Service

int main(void)
{  
  init_serial0();		   									// Initilial UART0 = 9600,N,8,1
  
  // Initial External Interrupt-0(GPIO0.16) // 
  EXTMODE      |= 0x01;										// Select External Interrupt-1 = Edge Select Trigger
  EXTPOLAR     |= 0x01;										// Select External Interrupt-1 = Rising Edge Trigger
  PINSEL1 	   |= 0x00000001;								// Set GPIO0.16 = EXTINT0 Interrupt
  EXTINT 	   |= 0x00000001;								// Clear External Interrupt-0 Flag 

  // Initial External Interrupt-1(GPIO0.14) // 
  EXTMODE      |= 0x02;										// Select External Interrupt-1 = Edge Select Trigger
  EXTPOLAR     |= 0x02;										// Select External Interrupt-1 = Rising Edge Trigger
  PINSEL0 	   |= 0x10000000;								// Set GPIO0.14 = EXTINT1 Interrupt
  EXTINT 	   |= 0x00000002;								// Clear External Interrupt-1 Flag  

  // Initial External Interrupt-2(GPIO0.15) // 
  EXTMODE      |= 0x04;										// Select External Interrupt-2 = Edge Select Trigger
  EXTPOLAR     |= 0x04;										// Select External Interrupt-2 = Rising Edge Trigger
  PINSEL0 	   |= 0x40000000;								// Set GPIO0.15 = EXTINT2 Interrupt
  EXTINT 	   |= 0x00000004;								// Clear External Interrupt-2 Flag

  // Initial Interrupt Vector
  VICDefVectAddr  = (unsigned)NonVectoredIRQ;				// Set Vector Interrupt Service Routine
  VICIntEnable |= 0x00004000;								// Enable Interrupt-14 (External Interrupt-0)
  VICIntEnable |= 0x00008000;								// Enable Interrupt-15 (External Interrupt-1)
  VICIntEnable |= 0x00010000;								// Enable Interrupt-16 (External Interrupt-2)

  printf("ET-ARM7 BASE LPC2103...Example IRQ Interrupt\n"); // Call Printf Function
  printf("Used IRQ Non Vector Interrupt Mode\n");			// Call Printf Function
  printf("Interrupt-0 Rising Edge Trig By GPIO0.16\n");		// Call Printf Function
  printf("Interrupt-1 Rising Edge Trig By GPIO0.14\n");		// Call Printf Function
  printf("Interrupt-2 Rising Edge Trig By GPIO0.15\n\n");	// Call Printf Function
  printf("Hello From......Main Function\n");				// Call Printf Function

  // Loop Here Wait Interrupt
  while(1);													
}

/******************************/
/* Initial UART0 = 9600,N,8,1 */
/* VPB(pclk) = 29.4912 MHz    */
/******************************/
void init_serial0 (void)  
{
  PINSEL0 &= 0xFFFFFFF0;									// Reset P0.0,P0.1 Pin Config
  PINSEL0 |= 0x00000001;									// Select P0.0 = TxD(UART0)
  PINSEL0 |= 0x00000004;									// Select P0.1 = RxD(UART0)

  U0LCR &= 0xFC;											// Reset Word Select(1:0)
  U0LCR |= 0x03;											// Data Bit = 8 Bit
  U0LCR &= 0xFB;											// Stop Bit = 1 Bit
  U0LCR &= 0xF7;											// Parity = Disable
  U0LCR &= 0xBF;											// Disable Break Control
  U0LCR |= 0x80;											// Enable Programming of Divisor Latches

  // U0DLM:U0DLL = 29.4912MHz / [16 x Baud]
  //             = 29.4912MHz / [16 x 9600]
  //             = 192 = 0x00C0
  U0DLM = 0x00;												// Program Divisor Latch(192) for 9600 Baud
  U0DLL = 0xC0;

  U0LCR &= 0x7F;											// Disable Programming of Divisor Latches

  U0FCR |= 0x01;											// FIF0 Enable
  U0FCR |= 0x02;											// RX FIFO Reset
  U0FCR |= 0x04;											// TX FIFO Reset
  U0FCR &= 0x3F;                      
}

/****************************/
/* Write Character To UART0 */
/****************************/
int putchar (int ch)  
{                  
  if (ch == '\n')  
  {
    while (!(U0LSR & 0x20));  								// Wait TXD Buffer Empty
    U0THR = 0x0D;                          					// Write CR
  }
  while (!(U0LSR & 0x20));									// Wait TXD Buffer Empty
  return (U0THR = ch);										// Write Character
}

/*****************************/
/* Read Character From UART0 */
/*****************************/
int getchar (void)  
{                    
  while (!(U0LSR & 0x01));									// Wait RXD Receive Data Ready
  return (U0RBR);											// Get Receice Data & Return
}

/********************************/
/* Non-Vector Interrupt Service */
/********************************/
void NonVectoredIRQ (void)	__irq
{
  // External-0 Interrupt Serivce //
  if (VICIRQStatus & 0x00004000)
  {
    printf("Hello From......External Interrupt-0\n"); 		// Call Printf Function
    EXTINT |= 0x00000001;									// Clear External Interrupt-0 Flag  
  }

  // External-1 Interrupt Serivce //
  if (VICIRQStatus & 0x00008000)
  {
    printf("Hello From......External Interrupt-1\n"); 		// Call Printf Function
    EXTINT |= 0x00000002;									// Clear External Interrupt-1 Flag  
  }

  // External-2 Interrupt Service //
  if (VICIRQStatus & 0x00010000)
  {
    printf("Hello From......External Interrupt-2\n");		// Call Printf Function
    EXTINT |= 0x00000004;									// Clear External Interrupt-2 Flag
  }

  VICVectAddr = 0x00000000;									// Reset Global Interrupt
}

