// 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.
//
////////////////////////////////////////////////////////////////////////////////
//
//                Freescale MC9328MXL Timer Interrupt Example
//
// Description
// -----------
// This example demonstrates a simple interrupt handler and setting up a timer.
//
// Two timer interrupts are setup:
//
// 1. A 1Hz interrupt using general purpose timer 1.
//
// 2. A 500Hz interrupt using the real time clock's SAM7 interrupt.
//
////////////////////////////////////////////////////////////////////////////////

#include <targets/MC9328MXL.h>
#include "../common/interrupt.h"

#define RTC_SAM_INT 18
#define TIMER1_INT 59

#define LEDS ((1 << 2) | (1 << 23))

#define PERCLK1_FREQUENCY 96000000

static int count1, count2;

static void
sam_isr(void)
{
  if (count1++ & 1)
    GPIO_DR_A |= 1 << 2;
  else
    GPIO_DR_A &= ~(1 << 2);

  /* Clear the SAM7 interrupt */
  RTC_RTCISR = RTC_RTCIENR;
}

static void
timer1_isr(void)
{
  if (count2++ & 1)
    GPIO_DR_A |= 1 << 23;
  else
    GPIO_DR_A &= ~(1 << 23);

  /* Clear the TIMER1 interrupt */
  TIMER1_TSTAT &= ~1;
}

int
main(void)
{
  /* Initialise LED */
  GPIO_DDIR_A |= LEDS;
  GPIO_GIUS_A |= 1 << 2;
  GPIO_OCR1_A |= 3 << 4;
  GPIO_OCR2_A |= 3 << 14;

  /* Initialise interrupt vectors */
  interrupt_init();

  /* Setup SAM ISR */
  interrupt_set_isr(RTC_SAM_INT, sam_isr);
  interrupt_enable(RTC_SAM_INT, 0);

  /* Enable SAM7 interrupt */
  RTC_RTCIENR |= 1 << 15;

  /* Setup timer 1 ISR */
  interrupt_set_isr(TIMER1_INT, timer1_isr);
  interrupt_enable(TIMER1_INT, 0);

  /* Reset timer 1 */
  TIMER1_TCTL |= 0x00000001;
  TIMER1_TCTL |= 0x00008000;
  TIMER1_TCTL &= ~0x00000001;

  /* Configure and enable timer 1 */
  TIMER1_TPRER = 0; /* Prescaler = 1 */
  TIMER1_TCMP = PERCLK1_FREQUENCY; /* Generate 1 second timer interrupt */

  TIMER1_TCTL = 0x00000013; /* Enable timer, clock source = PERCLK1, enable interrupt, restart mode */

  while (count1 < 5 || count2 < 5);

  return 0; 
}
