/*********************************************************************
 *
 *                  RTCC Lib definitions
 *
 *********************************************************************
 * FileName:        Rtcc.h
 * Dependencies:	xc.h
 * Processor:       PIC32
 *
 * Compiler:        MPLAB XC32
 *                  MPLAB IDE
 * Company:         Microchip Technology Inc.
 *
 * Software License Agreement
 *
 * The software supplied herewith by Microchip Technology Incorporated
 * (the “Company”) for its PIC32 Microcontroller is intended
 * and supplied to you, the Company’s customer, for use solely and
 * exclusively on Microchip PIC32 Microcontroller products.
 * The software is owned by the Company and/or its supplier, and is
 * protected under applicable copyright laws. All rights are reserved.
 * Any use in violation of the foregoing restrictions may subject the
 * user to criminal sanctions under applicable laws, as well as to
 * civil liability for the breach of the terms and conditions of this
 * license.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 *
 * $Id: Rtcc.h,v 1.10 2007/01/16 20:30:43 C12878 Exp $
 * $Name:  $
 *
 ********************************************************************/


#ifndef _RTCC_H_
#define _RTCC_H_

/*
*  WARNING: All the Peripheral Library (PLIB) functions, including those in this file,
*  will be removed from future releases of MPLAB XC32 C/C++ Compiler.
*  Please refer to the MPLAB Harmony Libraries for new projects.  For legacy support,
*  these PLIB Libraries will be available for download from: www.microchip.com/pic32_peripheral_lib
*/
#ifndef _SUPPRESS_PLIB_WARNING
  #warning The PLIB functions and macros in this file will be removed from the MPLAB XC32 C/C++ Compiler in future releases
#endif


#include <xc.h>
#include <peripheral/lock.h>
#ifdef __cplusplus
extern "C"
  {
#endif
#ifdef _RTCC

// RTCC definitions

// union/structure for read/write of time into the RTCC device
typedef union
{
	struct
	{
		unsigned char	rsvd;		// reserved for future use. should be 0
		unsigned char	sec;		// BCD codification for seconds, 00-59
		unsigned char	min;		// BCD codification for minutes, 00-59
		unsigned char	hour;		// BCD codification for hours, 00-24
	};								// field access
	unsigned char		b[4];		// byte access
	unsigned short		w[2];		// 16 bits access
	unsigned long		l;			// 32 bits access
}rtccTime;

// union/structure for read/write of date into the RTCC device
typedef union
{
	struct
	{
		unsigned char	wday;		// BCD codification for day of the week, 00-06
		unsigned char	mday;		// BCD codification for day of the month, 01-31
		unsigned char	mon;		// BCD codification for month, 01-12
		unsigned char	year;		// BCD codification for years, 00-99
	};								// field access
	unsigned char		b[4];		// byte access
	unsigned short		w[2];		// 16 bits access
	unsigned long		l;			// 32 bits access
}rtccDate;

// valid values of alarm repetition for the RTCC device
typedef enum
{
	RTCC_RPT_HALF_SEC,		// repeat alarm every half second
	RTCC_RPT_SEC,			// repeat alarm every second
	RTCC_RPT_TEN_SEC,		// repeat alarm every ten seconds
	RTCC_RPT_MIN,			// repeat alarm every minute
	RTCC_RPT_TEN_MIN,		// repeat alarm every ten minutes
	RTCC_RPT_HOUR,			// repeat alarm every hour
	RTCC_RPT_DAY,			// repeat alarm every day
	RTCC_RPT_WEEK,			// repeat alarm every week
	RTCC_RPT_MON,			// repeat alarm every month
	RTCC_RPT_YEAR			// repeat alarm every year (except when configured for Feb 29th.)
}rtccRepeat;

// results returned by initialization functions
typedef enum
{
	RTCC_CLK_ON,			// success, clock is running
	RTCC_SOSC_NRDY,			// SOSC not running
	RTCC_CLK_NRDY,			// RTCC clock not running
	RTCC_WR_DSBL,			// WR is disabled
}rtccRes;

// RTCC interface functions


// high level control functions

/*********************************************************************
 * Function:        rtccRes RtccInit(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          RTCC_CLK_ON if the RTCC clock is actually running
 * 					a clock status code otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function initializes the RTCC device. It starts the RTCC clock,
 * 					enables the RTCC and disables RTCC write. Disables the Alarm and the OE.
 * 					Clears the alarm interrupt flag and disables the alarm interrupt.
 *
 * Note:            It usually takes 4x256 clock cycles (approx 31.2 ms) for the oscillator signal to be available
 * 					to the RTCC. The user must make sure that the clock is actually running using RtccGetClkStat()
 * 					before expecting the RTCC to count.
 *
 * Example:			rtccRes res=RtccInit();
 ********************************************************************/
rtccRes		RtccInit(void);

/*********************************************************************
 * Function:        rtccRes RtccOpen((unsigned long tm, unsigned long dt, int drift)
 *
 * PreCondition:    tm an unsigned long containing the fields of a valid rtccTime structure:
 * 						- sec:	BCD codification, 00-59
 * 						- min:  BCD codification, 00-59
 * 						- hour: BCD codification, 00-24
 * 			dt is an unsigned long conatining the valid fields of a rtccDate structure:
 * 						- wday:	BCD codification, 00-06
 * 						- mday: BCD codification, 01-31
 * 						- mon: BCD codification, 01-12
 * 						- year: BCD codification, 00-99
 * 			drift has to fit into signed 10 bits representation
 *
 * Input:           	tm - the time value to be set
 * 			dt - the date value to be set
 * 			drift	- value to be added/subtracted to perform calibration
 *
 * Output:          RTCC_CLK_ON if the RTCC clock is actually running
 * 					a clock status code otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function initializes the RTCC device. It starts the RTCC clock, sets the desired time and calibration
 * 					and enables the RTCC. Disables the Alarm and the OE and further RTCC writes.
 * 					Clears the alarm interrupt flag and disables the alarm interrupt.
 *
 * Note:            It usually takes 4x256 clock cycles (approx 31.2 ms) for the oscillator signal to be available
 * 					to the RTCC. The user must make sure that the clock is actually running using RtccGetClkStat()
 * 					before expecting the RTCC to count.
 *
 * Example:		rtccDate dt; dt.wday=05; dt.mday=0x28; dt.mon=0x2; dt.year=0;
 * 			rtccTime tm; tm.sec=0x15; tm.min=0x30; tm.hour=01;
 * 			rtccRes res=RtccOpen(tm.l, dt.l, 10);
 * 					or
 * 			rtccRes res=RtccOpen(0x01301500, 0x00022805, 10);
 ********************************************************************/
rtccRes		RtccOpen(unsigned long tm, unsigned long dt, int drift);

/*********************************************************************
 * Function:        void RtccShutdown(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function shutdowns the RTCC device. It stops the RTCC clock,
 * 					sets the RTCC Off and disables RTCC write. Disables the Alarm and the OE.
 * 					Clears the alarm interrupt flag and disables the alarm interrupt.
 *
 * Note:            None
 *
 * Example:			RtccShutdown();
 ********************************************************************/
void		RtccShutdown(void);


// time and alarm functions

/*********************************************************************
 * Function:        void RtccSetTime(unsigned long tm)
 *
 * PreCondition:    tm an unsigned long containing the fields of a valid rtccTime structure:
 * 						- sec:	BCD codification, 00-59
 * 						- min:  BCD codification, 00-59
 * 						- hour: BCD codification, 00-24
 *
 * Input:           tm - the time value to be set
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the current time in the RTCC device.
 *
 * Note:            - The write is successful only if Wr Enable is set.
 * 					The function will enable the write itself, if needed.
 * 					- The device could be stopped in order
 * 					to safely perform the update of the RTC time register.
 * 					However, the device status will be restored but	the routine won't wait
 * 					for the CLK to be running before returning. User has to check RtccGetClkStat() (will take approx 30us).
 * 					- The routine could disable the interrupts for a very short time to be able
 * 					to update the time and date registers.
 *
 * Example:			rtccTime tm; tm.sec=0x15; tm.min=0x30; tm.hour=01; RtccSetTime(tm.l);
 * 					or
 * 					RtccSetTime(0x01301500);
 *
 ********************************************************************/
void		RtccSetTime(unsigned long tm);

/*********************************************************************
 * Function:        unsigned long RtccGetTime(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          The current value of the time which can be safely casted to an rtccTime structure.
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current time of the RTCC device.
 *
 * Note:            - The function makes sure that the read value is valid.
 * 					It avoids waiting for the RTCSYNC to be clear by
 * 					performing successive reads.
 *
 * Example:			rtccTime tm; tm.l=RtccGetTime();
 ********************************************************************/
extern __inline__ unsigned long __attribute__((always_inline))	RtccGetTime(void)
{
	unsigned int	t0, t1;
	do
	{
		t0=RTCTIME;
		t1=RTCTIME;
	}while(t0!=t1);
	return t0;
}

/*********************************************************************
 * Function:        void RtccSetDate(unsigned long dt)
 *
 * PreCondition:    dt is an unsigned long conatining the valid fields of a rtccDate structure:
 * 						- wday:	BCD codification, 00-06
 * 						- mday: BCD codification, 01-31
 * 						- mon: BCD codification, 01-12
 * 						- year: BCD codification, 00-99
 *
 * Input:           dt - the date value to be set
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the current date in the RTCC device.
 *
 * Note:            - The write is successful only if Wr Enable is set.
 * 					The function will enable the write itself, if needed.
 * 					- The device could be stopped in order
 * 					to safely perform the update of the RTC time register.
 * 					However, the device status will be restored but	the routine won't wait
 * 					for the CLK to be running before returning. User has to check RtccGetClkStat() (will take approx 30us).
 * 					- The routine could disable the interrupts for a very short time to be able
 * 					to update the time and date registers.
 *
 * Example:			rtccDate dt; dt.wday=05; dt.mday=0x28; dt.mon=0x2; dt.year=0; RtccSetDate(dt.l);
 * 					or
 * 					RtccSetDate(0x00022805);
 ********************************************************************/
void		RtccSetDate(unsigned long dt);

/*********************************************************************
 * Function:        unsigned long RtccGetDate(void)
 *
 * PreCondition:    pDt a valid pointer
 *
 * Input:           None
 *
 * Output:          an unsigned long representing the current date.
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current date of the RTCC device. Can be safely cast into rtccDate.
 *
 * Note:            The function makes sure that the read value is valid.
 * 					It avoids waiting for the RTCSYNC to be clear by
 * 					performing successive reads.
 *
 * Example:			rtccDate dt; dt.l=RtccGetDate();
 ********************************************************************/
extern __inline__ unsigned long __attribute__((always_inline))	RtccGetDate(void)
{
	unsigned int	d0, d1;
	do
	{
		d0=RTCDATE;
		d1=RTCDATE;
	}while(d0!=d1);

	return d0;
}

/*********************************************************************
 * Function:        void RtccSetTimeDate(unsigned long tm, unsigned long dt)
 *
 * PreCondition:    tm a valid rtccTime structure having proper halues:
 * 						- sec:	BCD codification, 00-59
 * 						- min:  BCD codification, 00-59
 * 						- hour: BCD codification, 00-24
 * 					date a valid rtccDate structure having proper values
 * 						- wday:	BCD codification, 00-06
 * 						- mday: BCD codification, 01-31
 * 						- mon: BCD codification, 01-12
 * 						- year: BCD codification, 00-99
 *
 * Input:           tm - the time value to be set
 * 					dt - the date value to be set
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the current time and date in the RTCC device.
 *
 * Note:            - The write is successful only if Wr Enable is set.
 * 					The function will enable the write itself, if needed.
 * 					- The device could be stopped in order
 * 					to safely perform the update of the RTC time register.
 * 					However, the device status will be restored but	the routine won't wait
 * 					for the CLK to be running before returning. User has to check RtccGetClkStat() (will take approx 30us).
 * 					- The routine could disable the interrupts for a very short time to be able
 * 					to update the time and date registers.
 *
 * Example:			rtccTime tm; tm.sec=0x15; tm.min=0x59; tm.hour=0x23;
 * 					rtccDate dt; dt.wday=05; dt.mday=0x28; dt.mon=0x2; dt.year=0;
 * 					RtccSetTimeDate(tm, dt);
 * 					or
 * 					RtccSetTimeDate(0x23591500, 0x00022805);
 ********************************************************************/
void		RtccSetTimeDate(unsigned long tm, unsigned long dt);

/*********************************************************************
 * Function:        void RtccGetTimeDate(rtccTime* pTm, rtccDate* pDt)
 *
 * PreCondition:    pTm, pDt valid pointers
 *
 * Input:           pTm - pointer to a rtccTime union to store the current time
 * 					pDt - pointer to a rtccDate union to store the current date
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function updates the user supplied union/structures with
 * 					the current time and date of the RTCC device.
 *
 * Note:            - The function makes sure that the read value is valid.
 * 					It avoids waiting for the RTCSYNC to be clear by
 * 					performing successive reads.
 *
 * Example:			rtccTime tm; rtccDate dt; RtccGetTimeDate(&tm, &dt);
 ********************************************************************/
extern __inline__ void __attribute__((always_inline))	RtccGetTimeDate(rtccTime* pTm, rtccDate* pDt)
{
	rtccTime	t0;
	rtccDate	d0;
	do
	{
		d0.l=RTCDATE;
		t0.l=RTCTIME;
		pTm->l=RTCTIME;
		pDt->l=RTCDATE;
	}while((d0.l!=pDt->l) || (t0.l!=pTm->l));		// update the user requested data
}


/*********************************************************************
 * Function:        void RtccSetAlarmTime(unsigned long tm)
 *
 * PreCondition:    tm a valid rtccTime structure having proper values:
 * 						- sec:	BCD codification, 00-59
 * 						- min:  BCD codification, 00-59
 * 						- hour: BCD codification, 00-24
 *
 * Input:           tm - the alarm time to be set
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the current alarm time in the RTCC device.
 *
 * Note:            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the ALRMTIME register.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			rtccTime tm; tm.sec=0x15; tm.min=0x59; tm.hour=0x23; RtccSetAlarmTime(tm.l);
 * 					or
 * 					RtccSetAlarmTime(0x23591500);
 ********************************************************************/
void		RtccSetAlarmTime(unsigned long tm);

/*********************************************************************
 * Function:        unsigned long RtccGetAlarmTime(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          the current alarm time
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current alarm time of the RTCC device.
 *
 * Note:            None
 *
 * Example:         rtccTime tm; tm.l=RtccGetAlarmTime();
 ********************************************************************/
extern __inline__ unsigned long __attribute__((always_inline))	RtccGetAlarmTime(void)
{
	return	ALRMTIME;
}


/*********************************************************************
 * Function:        void RtccSetAlarmDate(unsigned long dt)
 *
 * PreCondition:    dt a valid rtccDate formatted structure having proper values:
 * 						- wday:	BCD codification, 00-06
 * 						- mday: BCD codification, 01-31
 * 						- mon: BCD codification, 01-12
 *
 * Input:           dt - value of the alarm date
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the alarm date in the RTCC device.
 *
 * Note:            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the ALRMDATE register.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 * 					- Note that the alarm date does not contain a year field.
 *
 * Example:			rtccDate dt; dt.wday=0; dt.mday=0x12; dt.mon=0x12; RtccSetAlarmDate(dt.l);
 * 					or
 * 					RtccSetAlarmDate(0x121200);
 ********************************************************************/
void		RtccSetAlarmDate(unsigned long dt);

/*********************************************************************
 * Function:        unsigned long RtccGetAlarmDate(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          The current alarm date. Can be safely cast into an rtccDate.
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current alarm date of the RTCC device.
 *
 * Note:            None
 *
 * Example:         rtccDate dt; dt.l=RtccGetAlarmDate();
 ********************************************************************/
extern __inline__ unsigned long __attribute__((always_inline))	RtccGetAlarmDate(void)
{
	return	ALRMDATE;
}


/*********************************************************************
 * Function:        void RtccSetAlarmTimeDate(unsigned long tm, unsigned long dt)
 *
 * PreCondition:    tm a valid rtccTime structure having proper values:
 * 						- sec:	BCD codification, 00-59
 * 						- min:  BCD codification, 00-59
 * 						- hour: BCD codification, 00-24
 * 					dt a valid rtccDate structure having proper values:
 * 						- wday:	BCD codification, 00-06
 * 						- mday: BCD codification, 01-31
 * 						- mon: BCD codification, 01-12
 *
 * Input:           tm - the alarm time to be set
 * 					dt - the alarm date to be set
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the current alarm time and date in the RTCC device.
 *
 * Note:            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the ALRMTIME, ALRMDATE registers.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 * 					- Note that the alarm time does not contain a year field.
 *
 * Example:			rtccTime tm; tm.sec=0; tm.min=0x59; tm.hour-0x23;
 * 					rtccDate dt; dt.wday=0; dt.mday=0x12; dt.mon=0x12;
 * 					RtccSetAlarmTimeDate(tm.l, dt.l);
 * 					or
 * 					RtccSetAlarmTimeDate(0x235900, 0x121200);
 ********************************************************************/
void		RtccSetAlarmTimeDate(unsigned long tm, unsigned long dt);

/*********************************************************************
 * Function:        void RtccGetAlarmTimeDate(rtccTime* pTm, rtccDate* pDt)
 *
 * PreCondition:    pTm, pDt valid pointers
 *
 * Input:           pTm - pointer to a rtccTime union to store the alarm time
 * 					pDt - pointer to a rtccDate union to store the alarm date
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function updates the user supplied union/structures with
 * 					the current alarm time and date of the RTCC device.
 *
 * Note:            None
 *
 * Example:			rtccTime tm; rtccDate dt; RtccGetAlarmTimeDate(&tm, &dt);
 ********************************************************************/
extern __inline__ void __attribute__((always_inline))	RtccGetAlarmTimeDate(rtccTime* pTm, rtccDate* pDt)
{
	pTm->l=ALRMTIME;
	pDt->l=ALRMDATE;
}

/*********************************************************************
 * Function:        void RtccAlarmEnable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function enables the alarm of the RTCC device.
 *
 * Note:            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			RtccAlarmEnable();
 ********************************************************************/
 void		RtccAlarmEnable(void);


/*********************************************************************
 * Function:        void RtccAlarmDisable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function disables the alarm of the RTCC device.
 *
 * Note:            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			RtccAlarmDisable();
 ********************************************************************/
 void		RtccAlarmDisable(void);


/*********************************************************************
 * Function:        int RtccGetAlarmEnable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          curent status of the RTCC alarm
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the alarm status of the RTCC device.
 *
 * Note:            None
 *
 * Example:			int isAlrmEnabled=RtccGetAlarmEnable();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline)) RtccGetAlarmEnable(void)
{
	int	isAlrm0, isAlrm1;
	do
	{
		isAlrm0=RTCALRMbits.ALRMEN;
		isAlrm1=RTCALRMbits.ALRMEN;
	}while(isAlrm0!=isAlrm1);

	return isAlrm0;
}


/*********************************************************************
 * Function:        void RtccChimeEnable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function enables the chime alarm of the RTCC device.
 *
 * Note:            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			RtccChimeEnable();
 ********************************************************************/
void		RtccChimeEnable(void);

/*********************************************************************
 * Function:        void RtccChimeDisable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function disables the chime alarm of the RTCC device.
 *
 * Note:            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			RtccChimeDisable();
 ********************************************************************/
void		RtccChimeDisable(void);


/*********************************************************************
 * Function:        int RtccGetChimeEnable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          current status of the alarm chime
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the chime alarm of the RTCC device.
 *
 * Note:            None
 *
 * Example:			int isChimeEnabled=RtccGetChimeEnable();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline)) RtccGetChimeEnable(void)
{
	int	ch0, ch1;
	do
	{
		ch0=RTCALRMbits.CHIME;
		ch1=RTCALRMbits.CHIME;
	}while(ch0!=ch1);

	return ch0;

}

/*********************************************************************
 * Function:        void RtccSetAlarmRpt(rtccRepeat rpt)
 *
 * PreCondition:    rpt has to be a proper rtccRepeat enumeration value
 * Input:           rpt 		- value of the desired alarm repeat rate
 *
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the RTCC alarm repeat rate.
 *
 * Note:            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			RtccSetAlarmRpt(RTCC_RPT_MIN);
 ********************************************************************/
void		RtccSetAlarmRpt(rtccRepeat rpt);

/*********************************************************************
 * Function:        rtccRepeat RtccGetAlarmRpt(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          The value of the current alarm repeat rate.
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current RTCC alarm repeat rate.
 *
 * Note:            None
 *
 * Example:			rtccRepeat rptAlrm=RtccGetAlarmRpt();
 ********************************************************************/
extern __inline__ rtccRepeat __attribute__((always_inline)) RtccGetAlarmRpt(void)
{
	rtccRepeat	r0, r1;

	do
	{
		r0=(rtccRepeat)(RTCALRM&_RTCALRM_AMASK_MASK);
		r1=(rtccRepeat)(RTCALRM&_RTCALRM_AMASK_MASK);
	}while(r0!=r1);

	return (rtccRepeat)(r0>>_RTCALRM_AMASK_POSITION);
}

/*********************************************************************
 * Function:        void RtccSetAlarmRptCount(int rptCnt)
 *
 * PreCondition:    rptCnt has to be a value less then 256
 *
 * Input:           rpt 		- value of the desired alarm repeat rate
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the RTCC alarm repeat count.
 * 					The number of alarm triggers will be rptCnt+1:
 * 						- one alarm trigger if rptCnt==0
 * 						- ....
 * 						- 256 alarm triggers if rptCnt=255
 *
 * Note:            - rptCnt will be truncated to fit into 8 bit representation.
 * 		            - The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					- Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 * 					- If rptCnt is 0, there will be one alarm trigger.
 *
 * Example:			RtccSetAlarmRptCount(10);
 ********************************************************************/
void		RtccSetAlarmRptCount(int rptCnt);

/*********************************************************************
 * Function:        int RtccGetAlarmRptCount(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          the current alarm repeat count
 *
 * Side Effects:    None
 *
 * Overview:        The function reads the RTCC alarm repeat counter.
 *
 * Note:            The reading is affected by the sttatus of RTCALRM.ALRMSYNC bit.
 * 					Double readings are performed.
 *
 * Example:			int alrmRptCnt=RtccGetAlarmRptCount();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline)) RtccGetAlarmRptCount(void)
{
	int	rpt0, rpt1;
	do
	{
		rpt0=RTCALRMbits.ARPT;
		rpt1=RTCALRMbits.ARPT;
	}while(rpt0!=rpt1);

	return rpt0;
}

/*********************************************************************
 * Function:        int	RtccWeekDay(int year, int month, int day)
 *
 * PreCondition:    Date greater than 14 Sep 1752.
 *
 * Input:           year	- year value
 * 					month	- month value, 1-12
 * 					day		- day value, 1-31
 *
 * Output:          the week of the day, 0 for Sun, 1 for Mon and so on
 *
 * Side Effects:    None
 *
 * Overview:        The algorithm calculates the week of the day for new style
 * 					dates, beginning at 14 Sep 1752.
 * 					Based on an algorithm by Lewis Carroll.
 *
 * Note:            None
 *
 * Example:			int weekDay=RtccWeekDay(2004, 02, 28);
 ********************************************************************/
int			RtccWeekDay(int year, int month, int day);


// low level control functions

/*********************************************************************
 * Function:        rtccRes RtccEnable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          RTCC_CLK_ON if the RTCC was enabled and the RTCC clock is running,
 * 					a clock status code otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function enables the RTCC.
 *
 * Note:            - The write operations have to be enabled in order to be able to toggle the ON control bit.
 * 					Otherwise the function will fail.
 * 					See RtccWrEnable() function.
 * 					- The function doesn't wait for the RTC clock to be on.
 *
 * Example:			rtccRes clkStat=RtccEnable();
 ********************************************************************/
rtccRes		RtccEnable(void);


/*********************************************************************
 * Function:        int RtccDisable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          TRUE if the RTCC was disabled,
 * 					FALSE otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function disables the RTCC.
 *
 * Note:            1. The write operations have to be enabled in order to be able to toggle the ON control bit.
 * 					Otherwise the function will fail.
 * 					See RtccWrEnable() function.
 * 					2. When ON control bit is set to 0, RTCCON.RTCSYNC, RTCCON.HALFSEC and
 * 					RTCCON.RTCOE are asynchronously reset.
 * 					- The function waits for the RTC clock to be off.
 *
 * Example:			RtccDisable();
 ********************************************************************/
int		RtccDisable(void);

/*********************************************************************
 * Function:        int RtccGetEnable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          the current enabled/disabled status of the RTCC module.
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the RTCCON.ON bit anded with RTCCLKON.
 *
 * Note:            None
 *
 * Example:         int isEnabled=RtccGetEnable();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline))	RtccGetEnable(void)
{
	return	(RTCCON&(_RTCCON_ON_MASK|_RTCCON_RTCCLKON_MASK));
}

/*********************************************************************
 * Function:        rtccRes RtccGetClkStat(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          RTCC_CLK_ON if the RTCC clock is running (the oscillator output is presented to the RTCC module).
 * 					an clock status otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the RTCCON.ON bit anded with RTCCLKON.
 *
 * Note:            None
 *
 * Example:			int isClkOn=RtccGetClkStat();
 ********************************************************************/
extern __inline__ rtccRes __attribute__((always_inline)) RtccGetClkStat(void)
{

	if( (!(OSCCONbits.SOSCEN)) || (!(OSCCONbits.SOSCRDY)) )
	{
		return RTCC_SOSC_NRDY;
	}
	else if(!(RTCCONbits.RTCCLKON))
	{
		return RTCC_CLK_NRDY;
	}

	return RTCC_CLK_ON;
}


/*********************************************************************
 * Function:        void RtccSetCalibration(int drift)
 *
 * PreCondition:    drift has to fit into signed 10 bits representation
 *
 * Input:           drift	- value to be added/subtracted to perform calibration
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function updates the value that the RTCC uses in the
 * 					auto-adjust feature, once every minute.
 * 					The drift value acts as a signed value, [-512, +511], 0 not having
 * 					any effect.
 *
 * Note:            - Writes to the RTCCON.CAL[9:0] register should  only occur when the timer
 * 					is turned off or immediately or after the edge of the seconds pulse
 * 					(except when SECONDS=00 - due to the possibility of the auto-adjust event).
 * 					In order to speed-up the process, the API function performs the reading
 * 					of the HALFSEC field.
 * 					- The function may block for half a second, worst case, when called
 * 					at the start of the minute.
 * 					- A write to the SECONDS value resets the state of the calibration and the prescaler.
 * 					If calibration just occurred, it will occur again at the prescaler rollover.
 * 					- Interrupts can not be disabled for such a long period. However, long interrupt routines
 * 					can interfere with the proper functioning of the device. Care must be taken.
 *
 * Example:			RtccSetCalibration(10);
 ********************************************************************/
void		RtccSetCalibration(int drift);

/*********************************************************************
 * Function:        int RtccGetCalibration(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          Current value of the RTCC calibration field.
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the value that the RTCC uses in the
 * 					auto-adjust feature, once every minute.
 * 					The calibration value is a signed 10 bits value, [-512, +511].
 *
 * Note:            None
 *
 * Example:         int currCal=RtccGetCalibration();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline))	RtccGetCalibration(void)
{
	return	RTCCONbits.CAL;
}

/*********************************************************************
 * Function:        void RtccWrEnable(int enable)
 *
 * PreCondition:    None
 *
 * Input:           enable - boolean to enable/disable the RTCC updates.
 *
 * Output:          None.
 *
 * Side Effects:    None
 *
 * Overview:        The function enables the updates to the RTCC
 *                  time registers and ON control bit.
 *
 * Note:            - The write can be enabled by performing a specific unlock sequence.
 *                  In order to succeed, this sequence need not be interrupted by other memory accesses
 *                  (DMA transfers, interrupts, etc).
 *                  - Interrupts and DMA transfers that might disrupt the write unlock sequence are disabled
 *                  shortly for properly unlocking the device.
 *
 * Example:        RtccWrEnable(1);
 ********************************************************************/
extern __inline__ void __attribute__((always_inline))	RtccWrEnable(int enable)
{
	if(enable)
	{
		mSysUnlockOpLock(RTCCONSET=_RTCCON_RTCWREN_MASK);
	}
	else
	{
		RTCCONCLR=_RTCCON_RTCWREN_MASK;
	}
}


/*********************************************************************
 * Function:        int RtccGetWrEnable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          TRUE if the RTCC is unlocked, FALSE if locked
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current status of the RTCC write enable bit.
 *
 * Note:            None
 *
 * Example:         int isWrEnabled=RtccGetWrEnable();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline))	RtccGetWrEnable(void)
{
	return	RTCCONbits.RTCWREN!=0;
}

/*********************************************************************
 * Function:        int RtccGetSync(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          TRUE if the SYNC signal is asserted, FALSE otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current status of the RTCCON SYNC bit.
 *
 * Note:            None
 *
 * Example:         int isSync=RtccGetSync();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline))	RtccGetSync(void)
{
	return	RTCCONbits.RTCSYNC!=0;
}


/*********************************************************************
 * Function:        int RtccGetHalfSecond(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          TRUE if the RTCC is in the second HALF SECOND  interval, FALSE otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current status of the RTCCON HALFSEC bit.
 *
 * Note:            None
 *
 * Example:         int is2HalfSec=RtccGetHalfSecond();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline))	RtccGetHalfSecond(void)
{
	return	RTCCONbits.HALFSEC!=0;
}

/*********************************************************************
 * Function:        int RtccGetAlrmSync(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          TRUE if the AlrmSync signal is asserted, FALSE otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current status of the RTCALRM ALRMSYNC bit.
 *
 * Note:            None
 *
 * Example:         int isSync=RtccGetAlrmSync();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline))	RtccGetAlrmSync(void)
{
	return	RTCALRMbits.ALRMSYNC!=0;
}


/*********************************************************************
 * Function:        void RtccSelectPulseOutput(int secPulse)
 *
 * PreCondition:    None
 *
 * Input:           secPulse - boolean to select the seconds/alarm pulse as output
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function selects the seconds clock pulse or the alarm pulse as the function of the RTCC output pin.
 *
 * Note:            The RTCC has to be enabled for the output to actually be active.
 *
 * Example:         RtccSelectPulseOutput(1);
 ********************************************************************/
extern __inline__ void __attribute__((always_inline))	RtccSelectPulseOutput(int secPulse)
{
	if(secPulse)
	{
		RTCCONSET=_RTCCON_RTSECSEL_MASK;
	}
	else
	{
		RTCCONCLR=_RTCCON_RTSECSEL_MASK;
	}
}



/*********************************************************************
 * Function:        void RtccAlarmPulseHigh(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the initial value of the output Alarm Pulse to logic 1.
 *
 * Note:            1. The RTCC has to be enabled for the output to actually be active.
 * 					2. This Alarm Pulse output is writable only when the alarm is disabled.
 *					3. The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					4. Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			RtccAlarmPulseHigh();
 ********************************************************************/
void		RtccAlarmPulseHigh(void);

/*********************************************************************
 * Function:        void RtccAlarmPulseLow(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function sets the initial value of the output Alarm Pulse to logic 0.
 *
 * Note:            1. The RTCC has to be enabled for the output to actually be active.
 * 					2. This Alarm Pulse output is writable only when the alarm is disabled.
*					3. The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					4. Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			RtccAlarmPulseLow();
 ********************************************************************/
void		RtccAlarmPulseLow(void);

/*********************************************************************
 * Function:        void RtccAlarmPulseToggle(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function toggles the value of the output Alarm Pulse.
 *
 * Note:            1. The RTCC has to be enabled for the output to actually be active.
 * 					2. This Alarm Pulse output is writable only when the alarm is disabled.
*					3. The function might wait for the proper Alarm window
 * 					to safely perform the update of the RTCALRM register.
 * 					4. Interrupts are disabled shortly when properly probing the ALRMSYNC needed.
 *
 * Example:			RtccAlarmPulseToggle();
 ********************************************************************/
void		RtccAlarmPulseToggle(void);

/*********************************************************************
 * Function:        int RtccGetAlarmPulse(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          1 if the Alarm Pulse output is asserted
 *                  0 otherwise
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the current state of the output Alarm Pulse.
 *
 * Note:            The alarm has to be enabled for this function to return the current state of the Alarm Pulse output.
 *
 * Example:         int alrmPulse=RtccGetAlarmPulse();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline))	RtccGetAlarmPulse(void)
{
	return RTCALRMbits.PIV!=0;
}


/*********************************************************************
 * Function:        void RtccOutputEnable(int enable)
 *
 * PreCondition:    None
 *
 * Input:           enable -  boolean to enable/disable the RTCC output pin
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        The function enables/disables the Output pin of the RTCC.
 *
 * Note:            The RTCC has to be enabled for the output to actually be active.
 *
 * Example:         RtccOutputEnable(1);
 ********************************************************************/
extern __inline__ void __attribute__((always_inline))	RtccOutputEnable(int enable)
{
	if(enable)
	{
		RTCCONSET=_RTCCON_RTCOE_MASK;
	}
	else
	{
		RTCCONCLR=_RTCCON_RTCOE_MASK;
	}
}

/*********************************************************************
 * Function:        int RtccGetOutputEnable(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          TRUE if Output is enabled, FALSE otherwise.
 *
 * Side Effects:    None
 *
 * Overview:        The function returns the enabled/disabled status of the RTCC Output pin.
 *
 * Note:            None
 *
 * Example:         int isOutEnabled=RtccGetOutputEnable();
 ********************************************************************/
extern __inline__ int __attribute__((always_inline))	RtccGetOutputEnable(void)
{
	return	RTCCONbits.RTCOE!=0;
}


// special purpose functions

/********************************************************************
 * Include legacy RTCC functions
 * New projects should not use them!
 * Note that interrupt functions are no longer provided.
 * The functions in the int.h should be used instead.
 ********************************************************************/
#ifndef _PLIB_DISABLE_LEGACY
	#include <peripheral/legacy/rtcc_legacy.h>
#endif

#endif  // _RTCC

#ifdef __cplusplus
  }
#endif
#endif /*_RTCC_H_*/
