Merge pull request #1135 from stevew817/master

Silicon Labs - Fix for RTC: could not properly set the time.
pull/1137/head
Martin Kojtal 2015-05-26 10:59:26 +01:00
commit 66eefdfc5e
1 changed files with 32 additions and 12 deletions

View File

@ -24,14 +24,15 @@
#include "sleep_api.h"
#include "sleepmodes.h"
static bool rtc_inited = false;
static time_t time_base = 0;
static uint32_t useflags = 0;
static bool rtc_inited = false;
static time_t time_base = 0;
static uint32_t useflags = 0;
static uint32_t time_extend = 0;
static void (*comp0_handler)(void) = NULL;
#define RTC_LEAST_ACTIVE_SLEEPMODE EM2
#define RTC_LEAST_ACTIVE_SLEEPMODE EM2
#define RTC_NUM_BITS (24)
void RTC_IRQHandler(void)
{
@ -39,8 +40,8 @@ void RTC_IRQHandler(void)
flags = RTC_IntGet();
if (flags & RTC_IF_OF) {
RTC_IntClear(RTC_IF_OF);
/* RTC has overflowed (24 bits). Use time_base as software counter for upper 8 bits. */
time_base += 1 << 24;
/* RTC has overflowed (24 bits). Use time_extend as software counter for 32 more bits. */
time_extend += 1;
}
if (flags & RTC_IF_COMP0) {
RTC_IntClear(RTC_IF_COMP0);
@ -50,6 +51,20 @@ void RTC_IRQHandler(void)
}
}
uint32_t rtc_get_32bit(void)
{
return (RTC_CounterGet() + (time_extend << RTC_NUM_BITS));
}
uint64_t rtc_get_full(void)
{
uint64_t ticks = 0;
ticks += time_extend;
ticks = ticks << RTC_NUM_BITS;
ticks += RTC_CounterGet();
return ticks;
}
void rtc_set_comp0_handler(uint32_t handler)
{
comp0_handler = (void (*)(void)) handler;
@ -126,18 +141,23 @@ int rtc_isenabled(void)
time_t rtc_read(void)
{
return (time_t) ((RTC_CounterGet() + time_base) >> RTC_FREQ_SHIFT);
return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT) + time_base;
}
time_t rtc_read_uncompensated(void)
{
return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT);
}
void rtc_write(time_t t)
{
/* We have to check that the RTC did not tick while doing this. */
/* If the RTC ticks we just redo this. */
uint32_t rtc_count;
uint32_t time;
do {
rtc_count = RTC_CounterGet();
time_base = (t << RTC_FREQ_SHIFT) - rtc_count;
} while (rtc_count != RTC_CounterGet());
time = rtc_read_uncompensated();
time_base = t - time;
} while (time != rtc_read_uncompensated());
}
#endif