Skip to content

Commit 66eefdf

Browse files
committed
Merge pull request #1135 from stevew817/master
Silicon Labs - Fix for RTC: could not properly set the time.
2 parents ddca955 + 1442099 commit 66eefdf

File tree

1 file changed

+32
-12
lines changed
  • libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32

1 file changed

+32
-12
lines changed

libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/rtc_api.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,24 @@
2424
#include "sleep_api.h"
2525
#include "sleepmodes.h"
2626

27-
static bool rtc_inited = false;
28-
static time_t time_base = 0;
29-
static uint32_t useflags = 0;
27+
static bool rtc_inited = false;
28+
static time_t time_base = 0;
29+
static uint32_t useflags = 0;
30+
static uint32_t time_extend = 0;
3031

3132
static void (*comp0_handler)(void) = NULL;
3233

33-
#define RTC_LEAST_ACTIVE_SLEEPMODE EM2
34-
34+
#define RTC_LEAST_ACTIVE_SLEEPMODE EM2
35+
#define RTC_NUM_BITS (24)
3536

3637
void RTC_IRQHandler(void)
3738
{
3839
uint32_t flags;
3940
flags = RTC_IntGet();
4041
if (flags & RTC_IF_OF) {
4142
RTC_IntClear(RTC_IF_OF);
42-
/* RTC has overflowed (24 bits). Use time_base as software counter for upper 8 bits. */
43-
time_base += 1 << 24;
43+
/* RTC has overflowed (24 bits). Use time_extend as software counter for 32 more bits. */
44+
time_extend += 1;
4445
}
4546
if (flags & RTC_IF_COMP0) {
4647
RTC_IntClear(RTC_IF_COMP0);
@@ -50,6 +51,20 @@ void RTC_IRQHandler(void)
5051
}
5152
}
5253

54+
uint32_t rtc_get_32bit(void)
55+
{
56+
return (RTC_CounterGet() + (time_extend << RTC_NUM_BITS));
57+
}
58+
59+
uint64_t rtc_get_full(void)
60+
{
61+
uint64_t ticks = 0;
62+
ticks += time_extend;
63+
ticks = ticks << RTC_NUM_BITS;
64+
ticks += RTC_CounterGet();
65+
return ticks;
66+
}
67+
5368
void rtc_set_comp0_handler(uint32_t handler)
5469
{
5570
comp0_handler = (void (*)(void)) handler;
@@ -126,18 +141,23 @@ int rtc_isenabled(void)
126141

127142
time_t rtc_read(void)
128143
{
129-
return (time_t) ((RTC_CounterGet() + time_base) >> RTC_FREQ_SHIFT);
144+
return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT) + time_base;
145+
}
146+
147+
time_t rtc_read_uncompensated(void)
148+
{
149+
return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT);
130150
}
131151

132152
void rtc_write(time_t t)
133153
{
134154
/* We have to check that the RTC did not tick while doing this. */
135155
/* If the RTC ticks we just redo this. */
136-
uint32_t rtc_count;
156+
uint32_t time;
137157
do {
138-
rtc_count = RTC_CounterGet();
139-
time_base = (t << RTC_FREQ_SHIFT) - rtc_count;
140-
} while (rtc_count != RTC_CounterGet());
158+
time = rtc_read_uncompensated();
159+
time_base = t - time;
160+
} while (time != rtc_read_uncompensated());
141161
}
142162

143163
#endif

0 commit comments

Comments
 (0)