/****************************************************************************/
/* Copyright 2010, © Bendor Research Pty. Ltd. All rights reserved.			*/
/* Permission is granted to use this software for any purpose whatsoever	*/
/* as long as this copyright notice is preserved. The code is provided		*/
/* "as is", with no explicit, implicit or implied warranty or guarantee		*/
/* of any kind and Bendor Research Pty. Ltd. can not be held liable for		*/
/* any loss or damages arising out of the use of this software.				*/
/****************************************************************************/
/*																			*/
/*	Include file describing the NXP LPC23xx real-time clock module			*/
/*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~			*/
/*																			*/
/*	2010 Mar	ZK		Original											*/
/*	2010 May	ZK		Modified to match NXP's names						*/
/*																			*/
/****************************************************************************/

#ifndef _LPC23XX_RTC
#define _LPC23XX_RTC

struct	lpc23xx_rtc {

	unsigned ilr;					// 000 Interrupt location reg
	unsigned ctc;					// 004 Clock tick counter (15bit, 1/32768s)
	unsigned ccr;					// 008 Clock control reg
	unsigned ciir;					// 00c Count increment interrupt reg
	unsigned amr;					// 010 Alarm mask reg
	unsigned ctime[ 3 ];			// 014 Consolidated time
	unsigned sec;					// 020 Seconds
	unsigned min;					// 024 Minutes
	unsigned hour;					// 028 Hours
	unsigned dom;					// 02c Day of month
	unsigned dow;					// 030 Day of week
	unsigned doy;					// 034 Day of year
	unsigned month;					// 038 Month
	unsigned year;					// 03c Year
	unsigned ciss;					// 040 Counter increment select for sub-sec IRQ
	unsigned _1[8];
	unsigned alsec;					// 060 Alarm seconds
	unsigned almin;					// 064 Alarm minutes
	unsigned alhour;				// 068 Alarm hours
	unsigned aldom;					// 06c Alarm day of month
	unsigned aldow;					// 070 Alarm day of week
	unsigned aldoy;					// 074 Alarm day of year
	unsigned almonth;				// 078 Alarm month
	unsigned alyear;				// 07c Alarm year
	unsigned preint;				// 080 Prescaler integer value
	unsigned prefrac;				// 084 Prescaler fractional value
};

/*
*	Interrupt source register
*	Indicates the interrupt source. Writing a 1 to a bit clears the given
*	interrupt.
*/

#define	RTC_ILR_RTCCIF	0x01		// Counter increment interrupt
#define	RTC_ILR_RTCALF	0x02		// Alarm interrupt
#define RTC_ILR_RTSSF	0x04		// Sub-second interrupt

/*
*	RTC control register
*/

#define	RTC_CCR_CLKEN	0x01		// Enable RTC
#define	RTC_CCR_CTCRST	0x02		// Reset RTC (must be cleared manually)
#define	RTC_CCR_CLKSRC	0x04		// Clock source (0:prescaler 1:xtal)

/*
*	Count increment interrupt register
*	This register contains a bitmap. In the ciir register if a bit is
*	set, then an interrupt is generated whenever the counter corresponding
*	to the bit is incremented.
*/

#define RTC_CIIR_IMSEC	0x01		// Bit mask for seconds
#define	RTC_CIIR_IMMIN	0x02		// Bit mask for minutes
#define	RTC_CIIR_IMHOUR	0x04		// Bit mask for hours
#define	RTC_CIIR_IMDOM	0x08		// Bit mask for months
#define	RTC_CIIR_IMDOW	0x10		// Bit mask for weeks
#define	RTC_CIIR_IMDOY	0x20		// Bit mask for years
#define	RTC_CIIR_IMMON	0x40		// Bit mask for months
#define	RTC_CIIR_IMYEAR	0x80		// Bit mask for years

/*
*	Definitions for the AMR register.
*	It is a bit mask. If a bit is set, then the alarm will *not* check
*	that field of the time when checking whether an alarm should be
*	generated. Very tricky :-)
*/

#define RTC_AMR_SEC		0x01		// Bit mask for seconds
#define	RTC_AMR_MIN		0x02		// Bit mask for minutes
#define	RTC_AMR_HOUR	0x04		// Bit mask for hours
#define	RTC_AMR_DOM		0x08		// Bit mask for months
#define	RTC_AMR_DOW		0x10		// Bit mask for weeks
#define	RTC_AMR_DOY		0x20		// Bit mask for years
#define	RTC_AMR_MON		0x40		// Bit mask for months
#define	RTC_AMR_YEAR	0x80		// Bit mask for years

/*
*	Sub-second interrupt select mask register
*/

#define	RTC_CISS_SUBSECSEL(n) (n)	// Sub-second interrupt frequency
#define	RTC_CISS_ENA		  0x80	// Sub-second interrupt is enabled

#define	RTC_SUBSECSEL_16		0	// IRQ at every   16 clock ticks
#define	RTC_SUBSECSEL_32		1	// IRQ at every   32 clock ticks
#define	RTC_SUBSECSEL_64		2	// IRQ at every   64 clock ticks
#define	RTC_SUBSECSEL_128		3	// IRQ at every  128 clock ticks
#define	RTC_SUBSECSEL_256		4	// IRQ at every  256 clock ticks
#define	RTC_SUBSECSEL_512		5	// IRQ at every  512 clock ticks
#define	RTC_SUBSECSEL_1024		6	// IRQ at every 1024 clock ticks
#define	RTC_SUBSECSEL_2048		7	// IRQ at every 1048 clock ticks

/*
*	Prescaler integer and fractional counters
*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*	If you run the RTC from the system clock and not the 32.768kHz crystal,
*	then these two registers can generate the required 32.768kHz clock
*	for the RTC from the PCLK (perpheral bus clock) of the CPU.
*	As long as PCLK is >= 65.536kHz and evenly divides the second, then
*	the prescaler can generate clock for the RTC which is precise for
*	the second.
*	These macros generate the values from the PCLK frequency (in Hz).
*/

#define	RTC_PREINT(f)	(((f)>>15)-1)
#define	RTC_PREFRAC(f)	((f)&7fff)

/*
*	RTC instance
*/

static volatile struct lpc23xx_rtc * const lpc_rtc = (void *) 0xe0024000;

#endif

