Skip to content

[Silicon Labs] Fix for RTC: could not properly set the time. #1135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 26, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,24 @@
#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)
{
uint32_t flags;
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);
Expand All @@ -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;
Expand Down Expand Up @@ -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