/*                                             -*- mode:C++; fill-column:100 -*- 
  timer.h -  LPC2xxx-specific hardware access and configuration routines
  Copyright (C) 2009 The Regents of the University of New Mexico.  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  USA

  $Id$
*/

/**
  \file timer.h LPC2xxx-specific hardware access and configuration routines
  \author David H. Ackley
  \date (C) 2009 All rights reserved.
  \lgpl
 */
#ifndef __TIMER_H 
#define __TIMER_H

#include "SFBConstants.h"

/** \cond */
#define CCLK_72MHZ (72000000)
#define CCLK_60MHZ (60000000)

#define CCLK CCLK_72MHZ

/* 
 * For SFB@60MHz: CCLK = 60Mhz, PCLK = 1/4 CCLK, so Fpclk = 15MHz, Fpclk/15000==1KHz.
 * so 1ms = Fpclk/15000, less one for the extra cycle in the timer
 *
 * For SFB@72MHz: CCLK = 72Mhz, PCLK = 1/4 CCLK, so Fpclk = 18MHz, Fpclk/18000==1KHz.
 * so 1ms = Fpclk/18000, less one for the extra cycle in the timer
 *
 * For SFB@72MHz: CCLK = 72Mhz, PCLK = 1/4 CCLK, so Fpclk = 18MHz, Fpclk/18000==1KHz.
 * so 500us = Fpclk/9000, less one for the extra cycle in the timer
 * so 250us = Fpclk/4500, less one for the extra cycle in the timer
 *
 */
/** \cond */
#define TIME_INTERVAL_1KHZ_AT_60MHZ (15000-1)

#define TIME_INTERVAL_1KHZ_AT_72MHZ (18000-1)
#define TIME_INTERVAL_2KHZ_AT_72MHZ (9000-1)
#define TIME_INTERVAL_3KHZ_AT_72MHZ (6000-1)
#define TIME_INTERVAL_4KHZ_AT_72MHZ (4500-1)

extern u32 initTimer0();
extern void enable_timer0();
extern void disable_timer0();
extern void reset_timer0();
/** \endcond */

#include "lpc/LPC23xx.h"

/** \name Timekeeping
 */
/*@{*/
/** The number of microseconds of uptime, rolling over after about 70 minutes. #micros() is extremely
    fast, and very accurate (except that it rolls over so quickly).  For dealing with longer time
    periods at microsecond accuracy, consider #microseconds().  */
#define micros() ((volatile const u32) (T0TC))  

/** The number of milliseconds of uptime, rolling over after about 49 days.  #millis() is much faster
    than #milliseconds(), but is not as accurate; #millis() may miss ticks due to interrupt load */
#define millis() ((volatile const u32) (timer_1msec_counter))
extern uv32 timer_1msec_counter;

/** The number of microseconds of uptime, rolling over after about a half a million years.
    #microseconds() is quite fast, except for the overhead of dealing in \c u64 size, and its value
    is exact, unaffected by interrupt load.  */
extern u64 microseconds();

/** The number of milliseconds of uptime, rolling over after about 49 days. #milliseconds() is
    somewhat slow compared to #millis(), because it performs a non-power-of-2 division, but its
    value is exact, unaffected by interrupt load. */
extern u32 milliseconds();

/** The number of seconds of uptime, rolling over after about 180 years. #seconds is somewhat slow
    (requires a division) but its value is exact, unaffected by interrupt loa. */
extern u32 seconds();
/*@}*/

#endif /* end __TIMER_H */
/*****************************************************************************
**                            End Of File
******************************************************************************/
/** \endcond */
