// Copyright (c) 2001-2004 Rowley Associates Limited.
//
// This file may be distributed under the terms of the License Agreement
// provided with this software.
//
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
//
//                Sharp LH77790A Timer Interrupt Example
//
// Description
// -----------
// This example demonstrates a simple interrupt handler and setting up a timer.
//
////////////////////////////////////////////////////////////////////////////////

/* Interrupt Controller Registers */
#define ICR0 (*(volatile unsigned long *)0xFFFFA800)
#define ICR1 (*(volatile unsigned long *)0xFFFFA804)
#define ICLR (*(volatile unsigned long *)0xFFFFA808)
#define IRQER (*(volatile unsigned long *)0xFFFFA80C)
#define FIQER (*(volatile unsigned long *)0xFFFFA810)
#define IRQSR (*(volatile unsigned long *)0xFFFFA814)
#define FIQSR (*(volatile unsigned long *)0xFFFFA818)
#define IPR (*(volatile unsigned long *)0xFFFFA81C)

/* Timer Registers */
#define CT_CNTR0 (*(volatile unsigned long *)0xFFFF1800)
#define CT_CNTR1 (*(volatile unsigned long *)0xFFFF1804)
#define CT_CNTR2 (*(volatile unsigned long *)0xFFFF1808)
#define CT_CWR (*(volatile unsigned long *)0xFFFF180C)

#define CT0CCR (*(volatile unsigned long *)0xFFFFAC18)
#define CT1CCR (*(volatile unsigned long *)0xFFFFAC1C)
#define CT2CCR (*(volatile unsigned long *)0xFFFFAC20)

#define TIMER0_INT 6

static int count;

void irq_handler(void) __attribute__ ((interrupt ("IRQ")));

void
irq_handler(void)
{
  unsigned long irq = IRQSR;
  if (irq & (1 << TIMER0_INT))
    count++;
  ICLR = irq; /* Clear interrupt */
}

int
main(void)
{
  __ARMLIB_enableIRQ();
  
  IRQER = 1 << TIMER0_INT; /* Enable Timer0 Interrupt */
  CT0CCR = 0x80; /* XCLK/256 */
  CT_CWR = 0x34; /* Binary Counter, Mode 2, Read/Write LSB & MSB, Counter 0 */
  CT_CNTR0 = 0; /* LSB */
  CT_CNTR0 = 0; /* MSB */

  while (count < 5);

  return 0; 
}
