|
|
|
@ -24,6 +24,7 @@
|
|
|
|
|
#include "kernel_types.h"
|
|
|
|
|
|
|
|
|
|
/* cpu */
|
|
|
|
|
#include "periph/rtc.h"
|
|
|
|
|
#include "VIC.h"
|
|
|
|
|
#include "lpc2387.h"
|
|
|
|
|
#include "lpc2387-rtc.h"
|
|
|
|
@ -35,21 +36,25 @@
|
|
|
|
|
#define ENABLE_DEBUG (0)
|
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
|
|
/* Alarm callback */
|
|
|
|
|
static rtc_alarm_cb_t _cb;
|
|
|
|
|
|
|
|
|
|
/* Argument to alarm callback */
|
|
|
|
|
static void *_cb_arg;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief epoch time in hour granularity
|
|
|
|
|
*/
|
|
|
|
|
static volatile time_t epoch;
|
|
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
/**
|
|
|
|
|
* @brief Sets the current time in broken down format directly from to RTC
|
|
|
|
|
* @param[in] localt Pointer to structure with time to set
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
rtc_set_localtime(struct tm *localt)
|
|
|
|
|
int rtc_set_time(struct tm *localt)
|
|
|
|
|
{
|
|
|
|
|
if (localt == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set clock */
|
|
|
|
@ -61,25 +66,26 @@ rtc_set_localtime(struct tm *localt)
|
|
|
|
|
RTC_DOY = localt->tm_yday;
|
|
|
|
|
RTC_MONTH = localt->tm_mon + 1;
|
|
|
|
|
RTC_YEAR = localt->tm_year;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
void rtc_set(time_t time)
|
|
|
|
|
{
|
|
|
|
|
struct tm *localt;
|
|
|
|
|
localt = localtime(&time); /* convert seconds to broken-down time */
|
|
|
|
|
rtc_set_localtime(localt);
|
|
|
|
|
rtc_set_time(localt);
|
|
|
|
|
epoch = time - localt->tm_sec - localt->tm_min * 60;
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
//* set clock to start of unix epoch */
|
|
|
|
|
|
|
|
|
|
/* set clock to start of unix epoch */
|
|
|
|
|
void rtc_reset(void)
|
|
|
|
|
{
|
|
|
|
|
rtc_set(0);
|
|
|
|
|
epoch = 0;
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
void
|
|
|
|
|
rtc_set_alarm(struct tm *localt, enum rtc_alarm_mask mask)
|
|
|
|
|
|
|
|
|
|
int rtc_set_alarm(struct tm *localt, rtc_alarm_cb_t cb, void *arg)
|
|
|
|
|
{
|
|
|
|
|
if (localt != NULL) {
|
|
|
|
|
RTC_ALSEC = localt->tm_sec;
|
|
|
|
@ -90,17 +96,22 @@ rtc_set_alarm(struct tm *localt, enum rtc_alarm_mask mask)
|
|
|
|
|
RTC_ALDOY = localt->tm_yday;
|
|
|
|
|
RTC_ALMON = localt->tm_mon + 1;
|
|
|
|
|
RTC_ALYEAR = localt->tm_year;
|
|
|
|
|
RTC_AMR = ~mask; /* set wich alarm fields to check */
|
|
|
|
|
RTC_AMR = 0; /* set wich alarm fields to check */
|
|
|
|
|
DEBUG("alarm set %2lu.%2lu.%4lu %2lu:%2lu:%2lu\n",
|
|
|
|
|
RTC_ALDOM, RTC_ALMON, RTC_ALYEAR, RTC_ALHOUR, RTC_ALMIN, RTC_ALSEC);
|
|
|
|
|
|
|
|
|
|
_cb = cb;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
RTC_AMR = 0xff;
|
|
|
|
|
else if (cb == NULL) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RTC_AMR = 0xff;
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
enum rtc_alarm_mask
|
|
|
|
|
rtc_get_alarm(struct tm *localt)
|
|
|
|
|
|
|
|
|
|
int rtc_get_alarm(struct tm *localt)
|
|
|
|
|
{
|
|
|
|
|
if (localt != NULL) {
|
|
|
|
|
localt->tm_sec = RTC_ALSEC;
|
|
|
|
@ -112,12 +123,20 @@ rtc_get_alarm(struct tm *localt)
|
|
|
|
|
localt->tm_mon = RTC_ALMON - 1;
|
|
|
|
|
localt->tm_year = RTC_ALYEAR;
|
|
|
|
|
localt->tm_isdst = -1; /* not available */
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (~RTC_AMR) & 0xff; /* return which alarm fields are checked */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
void rtc_clear_alarm(void)
|
|
|
|
|
{
|
|
|
|
|
RTC_AMR = 0xff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RTC_IRQHandler(void) __attribute__((interrupt("IRQ")));
|
|
|
|
|
|
|
|
|
|
void RTC_IRQHandler(void)
|
|
|
|
|
{
|
|
|
|
|
lpm_begin_awake();
|
|
|
|
@ -135,6 +154,9 @@ void RTC_IRQHandler(void)
|
|
|
|
|
else if (RTC_ILR & ILR_RTCALF) {
|
|
|
|
|
RTC_ILR |= ILR_RTCALF;
|
|
|
|
|
RTC_AMR = 0xff; /* disable alarm irq */
|
|
|
|
|
if (_cb) {
|
|
|
|
|
_cb(_cb_arg);
|
|
|
|
|
}
|
|
|
|
|
DEBUG("Ring\n");
|
|
|
|
|
lpm_end_awake();
|
|
|
|
|
}
|
|
|
|
@ -142,9 +164,9 @@ void RTC_IRQHandler(void)
|
|
|
|
|
VICVectAddr = 0; /* Acknowledge Interrupt */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
void rtc_enable(void)
|
|
|
|
|
{
|
|
|
|
|
PCONP |= BIT9;
|
|
|
|
|
RTC_ILR = (ILR_RTSSF | ILR_RTCCIF | ILR_RTCALF); /* clear interrupt flags */
|
|
|
|
|
RTC_CCR |= CCR_CLKEN; /* enable clock */
|
|
|
|
|
install_irq(RTC_INT, &RTC_IRQHandler, IRQP_RTC); /* install interrupt handler */
|
|
|
|
@ -152,7 +174,7 @@ void rtc_enable(void)
|
|
|
|
|
time_t now = rtc_time(NULL);
|
|
|
|
|
epoch = now - (now % 3600);
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
void rtc_init(void)
|
|
|
|
|
{
|
|
|
|
|
PCONP |= BIT9;
|
|
|
|
@ -174,7 +196,7 @@ void rtc_init(void)
|
|
|
|
|
RTC_DOM, RTC_MONTH, RTC_YEAR, RTC_HOUR, RTC_MIN, RTC_SEC,
|
|
|
|
|
epoch);
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
time_t rtc_time(struct timeval *time)
|
|
|
|
|
{
|
|
|
|
|
uint32_t sec;
|
|
|
|
@ -191,8 +213,8 @@ time_t rtc_time(struct timeval *time)
|
|
|
|
|
min = RTC_MIN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sec += min * 60; /* add number of minutes */
|
|
|
|
|
sec += epoch; /* add precalculated epoch in hour granularity */
|
|
|
|
|
sec += min * 60; /* add number of minutes */
|
|
|
|
|
sec += epoch; /* add precalculated epoch in hour granularity */
|
|
|
|
|
|
|
|
|
|
if (time != NULL) {
|
|
|
|
|
usec = usec * 15625;
|
|
|
|
@ -203,16 +225,16 @@ time_t rtc_time(struct timeval *time)
|
|
|
|
|
|
|
|
|
|
return sec;
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
void rtc_disable(void)
|
|
|
|
|
|
|
|
|
|
void rtc_poweroff(void)
|
|
|
|
|
{
|
|
|
|
|
RTC_CCR &= ~CCR_CLKEN; /* disable clock */
|
|
|
|
|
install_irq(RTC_INT, NULL, 0);
|
|
|
|
|
RTC_ILR = 0;
|
|
|
|
|
PCONP &= ~BIT9;
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
void
|
|
|
|
|
rtc_get_localtime(struct tm *localt)
|
|
|
|
|
|
|
|
|
|
int rtc_get_time(struct tm *localt)
|
|
|
|
|
{
|
|
|
|
|
if (localt != NULL) {
|
|
|
|
|
localt->tm_sec = RTC_SEC;
|
|
|
|
@ -224,9 +246,11 @@ rtc_get_localtime(struct tm *localt)
|
|
|
|
|
localt->tm_mon = RTC_MONTH - 1;
|
|
|
|
|
localt->tm_year = RTC_YEAR;
|
|
|
|
|
localt->tm_isdst = -1; /* not available */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
void gettimeofday_r(struct _reent *r, struct timeval *ptimeval, struct timezone *ptimezone)
|
|
|
|
|
{
|
|
|
|
|
(void) ptimezone; /* unused */
|
|
|
|
|