/*!
  \file
  \brief 周期タイマー制御

  \author Satofumi KAMIMURA

  $Id: timer_control.c 1649 2010-01-27 03:37:43Z satofumi $
*/

#include "timer_control.h"
#include "cpu_aki_sh2.h"


typedef void (*callback_t)(void);
static callback_t CallbackFunction[2];


void timer_initialize(timer_port port, int level, int usec,
                      void (*function)(void))
{
  if (port == TIMER_0) {
    CallbackFunction[TIMER_0] = function;

    CMT0.CMCOR = (usec * MSEC_CNT) >> (10 + 3);

    CMT0.CMCSR.WORD &= ~0x0003;
    INTC.IPRG.WORD &= ~0x00f0;
    INTC.IPRG.WORD |= (level << 4) & 0x00f0;
    CMT0.CMCSR.WORD &= ~0x0080;
    CMT0.CMCSR.WORD |= 0x0040;
  } else if (port == TIMER_1) {
    CallbackFunction[TIMER_1] = function;

    //CMT1.CMCOR = (usec * MSEC_CNT) >> (10 + 3);

    CMT1.CMCSR.WORD &= ~0x0003;
    INTC.IPRG.WORD &= ~0x000f;
    INTC.IPRG.WORD |= level & 0xf;
    CMT1.CMCSR.WORD &= ~0x0080;
    CMT1.CMCSR.WORD |= 0x0040;
  }
}


void timer_start(timer_port port)
{
  if (port == TIMER_0) {
    CMT0.CMCNT = 0;
    CMT.CMSTR.WORD |= 0x0001;

  } else if (port == TIMER_1) {
    CMT1.CMCNT = 0;
    CMT.CMSTR.WORD |= 0x0002;
  }
}


void timer_stop(timer_port port)
{
  if (port == TIMER_0) {
    CMT.CMSTR.WORD &= ~0x0001;

  } else if (port == TIMER_1) {
    CMT.CMSTR.WORD &= ~0x0002;
  }
}


__attribute__((interrupt_handler))
void cmi0(void)
{
  CMT0.CMCSR.WORD &= ~0x0080;

  CallbackFunction[TIMER_0]();
}


__attribute__((interrupt_handler))
void cmi1(void)
{
  CMT1.CMCSR.WORD &= ~0x0080;

  CallbackFunction[TIMER_1]();
}
