//! \file rtc.h
//! \author tkl
//! \date Jul 8, 2012
//! \brief Header file of the architecture independent rtc implementation.
#ifndef RTC_H_
#define RTC_H_

#include <stdint.h>

//-----------------------------------------------------------------------------
//! \brief Loki time container.
struct loki_time {
	uint32_t sec;	//!< Seconds.	[0-60]
	uint32_t min;	//!< Minutes.	[0-59]
	uint32_t hour;	//!< Hours.		[0-23]
	uint32_t day;	//!< Day.		[1-31]
	uint32_t mon;	//!< Month.		[0-11]
	uint32_t year;	//!< Year.
};


//-----------------------------------------------------------------------------
//! \brief Rtc interrupt interval.
enum rtc_interval {
	RTC_INTERVAL_MINUTE = 0,	//!< rtc interrupt every minute.
	RTC_INTERVAL_HOUR,			//!< rtc interrupt every hour.
	RTC_INTERVAL_MIDNIGHT,		//!< rtc interrupt every day at 00:00.
	RTC_INTERVAL_NOON			//!< rtc interrupt every day at 12:00.
};

//-----------------------------------------------------------------------------
//! \brief Rtc alarm mask.
enum rtc_alarm_mask {
	RTC_ALARM_DISABLED		= 0x00,	//!< Alarm mask disabled.
	RTC_ALARM_MINUTE		= 0x01,	//!< Alarm mask minute.
	RTC_ALARM_HOUR			= 0x02,	//!< Alarm mask hour.
	RTC_ALARM_DAY_OF_WEEK	= 0x04,	//!< Alarm mask day of week.
	RTC_ALARM_DAY_OF_MONTH	= 0x08	//!< Alarm mask day of month.
};

//-----------------------------------------------------------------------------
//! Callback for the open function of the arch depended rtc driver.
typedef int (*rtc_fp_open_t)(const void*);

//! Callback for the close function of the arch depended rtc driver.
typedef int (*rtc_fp_close_t)(const void*);

//! Callback for the time set function of the arch depended rtc driver.
typedef void (*rtc_fp_set_time_t)(const void*, const struct loki_time*);

//! Callback for the time get function of the arch depended rtc driver.
typedef struct loki_time *(*rtc_fp_get_time_t)(const void*, struct loki_time*);

//! Callback for the start interval event function.
typedef int (*rtc_fp_start_interval_event)
		(const void *, enum rtc_interval, const void *, const void *);

//! Callback for the stop interval event.
typedef int (*rtc_fp_stop_interval_event)(const void *);

//! Callback for the start alarm event.
typedef int (*rtc_fp_start_alarm_event)
		(const void *, const struct loki_time*, enum rtc_alarm_mask, const void *, const void *);

//! Callback for the stop alarm event.
typedef int (*rtc_fp_stop_alarm_event)(const void *);

//-----------------------------------------------------------------------------
//! \brief Function pointer to access the rct driver.
struct rtc_fp {
	const rtc_fp_open_t					open;			//!< Function pointer to the open function.
	const rtc_fp_close_t				close;			//!< Function pointer to the close function.
	const rtc_fp_set_time_t				set_time;		//!< Function pointer to the set_time function.
	const rtc_fp_get_time_t				get_time;		//!< Function pointer to the get_time function.
	const rtc_fp_start_interval_event	start_interval;	//!< Function pointer to the start_interval function.
	const rtc_fp_stop_interval_event	stop_interval;	//!< Function pointer to the stop_interval function.
	const rtc_fp_start_alarm_event		start_alarm;	//!< Function pointer to the start_alarm function.
	const rtc_fp_stop_alarm_event		stop_alarm;		//!< Function pointer to the stop_alarm function.
};

//-----------------------------------------------------------------------------
//! \brief Contains the architecture depended device and the access functions to the rtc driver.
struct rtc {
	const void *arch_dep_device;	//!< Architecture depended rtc device (i.e. msp430_rtc_t).
	const struct rtc_fp	*fp;			//!< Function pointer for the rtc driver access.
};

//-----------------------------------------------------------------------------
//! \brief Open a rtc device.
//! \param device The rtc device to open.
//! \retval -1 in error case.
int rtc_open(const struct rtc *device);

//-----------------------------------------------------------------------------
//! \brief Close a rtc device.
//! \param device The rtc device to close.
//! \retval -1 in error case.
int rtc_close(const struct rtc *device);

//-----------------------------------------------------------------------------
//! \brief Set rtc time.
//! \param device The rtc device.
//! \param time The time to set.
void rtc_set_time(const struct rtc *device, const struct loki_time *time);

//-----------------------------------------------------------------------------
//! \brief Get rtc time.
//! \param device The rtc device.
//! \param time The time to get.
//! \retval NULL in error case, otherwise points to time.
struct loki_time *rtc_get_time(const struct rtc *device,
		struct loki_time *time);

//-----------------------------------------------------------------------------
//! \brief Converts a Unix timestamp to a loki_time.
//! \param tick The Unix timestamp.
//! \return the converted time.
struct loki_time tick_to_time(uint32_t tick);

//-----------------------------------------------------------------------------
//! \brief Converts a loki_time to aunix timestamp.
//! \param time The time to convert.
//! \return The converted unix timestamp.
uint32_t time_to_tick(const struct loki_time *time);

//-----------------------------------------------------------------------------
//! \brief Starts a rtc interval event.
//! On every occurance of interval the rtc event gets fired.
//! \param device The rtc device.
//! \param interval The interval of rtc event occurance.
//! \param callback The callback is executed in case of interval event.
//! \param argument The argument for the callback.
//! \retval -1 in error case.
int rtc_start_interval_event(const struct rtc *device, enum rtc_interval interval,
		const void * callback, const void *argument);

//-----------------------------------------------------------------------------
//! \brief Stops a rtc interval event.
//! \param device The rtc device.
//! \retval -1 in error case.
int rtc_stop_interval_event(const struct rtc *device);

//-----------------------------------------------------------------------------
//! \brief Starts a rtc alarm event.
//! \param device The rtc device.
//! \param alarm_time The time to fire the alarm.
//! \param alarm_mask The mask to filter the alarm time.
//! \param callback The callback is executed in case of alarm.
//! \param argument The argument for the callback.
//! \retval -1 in error case.
int rtc_start_alarm_event(const struct rtc *device,
		const struct loki_time *alarm_time, enum rtc_alarm_mask alarm_mask,
		const void * callback, const void *argument);

//-----------------------------------------------------------------------------
//! \brief Stops a rtc alarm.
//! \param device The rtc device.
//! \retval -1 in error case.
int rtc_stop_alarm_event(const struct rtc *device);

#endif /* RTC_H_ */
