Skip to content

Commit 78c4850

Browse files
authored
Merge pull request #4016 from nvlsianpu/nrf5_rtc_ovf_bugfix
[NRF5]: fix rtc overflow-while-set-timestamp issue
2 parents a1d1a60 + 4f99aa5 commit 78c4850

File tree

1 file changed

+47
-11
lines changed

1 file changed

+47
-11
lines changed

targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "nrf_drv_common.h"
4343
#include "nrf_drv_config.h"
4444
#include "lp_ticker_api.h"
45+
#include "mbed_critical.h"
4546

4647

4748
//------------------------------------------------------------------------------
@@ -52,12 +53,25 @@
5253
bool m_common_rtc_enabled = false;
5354
uint32_t volatile m_common_rtc_overflows = 0;
5455

56+
__STATIC_INLINE void rtc_ovf_event_check(void)
57+
{
58+
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) {
59+
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW);
60+
// Don't disable this event. It shall occur periodically.
61+
62+
++m_common_rtc_overflows;
63+
}
64+
}
65+
5566
#if defined(TARGET_MCU_NRF51822)
5667
void common_rtc_irq_handler(void)
5768
#else
5869
void COMMON_RTC_IRQ_HANDLER(void)
5970
#endif
6071
{
72+
73+
rtc_ovf_event_check();
74+
6175
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, US_TICKER_EVENT)) {
6276
us_ticker_irq_handler();
6377
}
@@ -69,12 +83,6 @@ void COMMON_RTC_IRQ_HANDLER(void)
6983
}
7084
#endif
7185

72-
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) {
73-
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW);
74-
// Don't disable this event. It shall occur periodically.
75-
76-
++m_common_rtc_overflows;
77-
}
7886
}
7987

8088
#if (defined (__ICCARM__)) && defined(TARGET_MCU_NRF51822)//IAR
@@ -142,13 +150,37 @@ void common_rtc_init(void)
142150
m_common_rtc_enabled = true;
143151
}
144152

153+
__STATIC_INLINE void rtc_ovf_event_safe_check(void)
154+
{
155+
core_util_critical_section_enter();
156+
157+
rtc_ovf_event_check();
158+
159+
core_util_critical_section_exit();
160+
}
161+
162+
145163
uint32_t common_rtc_32bit_ticks_get(void)
146164
{
147-
uint32_t ticks = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
148-
// The counter used for time measurements is less than 32 bit wide,
149-
// so its value is complemented with the number of registered overflows
150-
// of the counter.
151-
ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS);
165+
uint32_t ticks;
166+
uint32_t prev_overflows;
167+
168+
do {
169+
prev_overflows = m_common_rtc_overflows;
170+
171+
ticks = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
172+
// The counter used for time measurements is less than 32 bit wide,
173+
// so its value is complemented with the number of registered overflows
174+
// of the counter.
175+
ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS);
176+
177+
// Check in case that OVF occurred during execution of a RTC handler (apply if call was from RTC handler)
178+
// m_common_rtc_overflows might been updated in this call.
179+
rtc_ovf_event_safe_check();
180+
181+
// If call was made from a low priority level m_common_rtc_overflows might have been updated in RTC handler.
182+
} while (m_common_rtc_overflows != prev_overflows);
183+
152184
return ticks;
153185
}
154186

@@ -185,6 +217,8 @@ void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel,
185217
uint32_t compare_value =
186218
(uint32_t)CEIL_DIV((timestamp64) * RTC_INPUT_FREQ, 1000000);
187219

220+
221+
core_util_critical_section_enter();
188222
// The COMPARE event occurs when the value in compare register is N and
189223
// the counter value changes from N-1 to N. Therefore, the minimal safe
190224
// difference between the compare value to be set and the current counter
@@ -197,6 +231,8 @@ void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel,
197231

198232
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, cc_channel, RTC_WRAP(compare_value));
199233
nrf_rtc_event_enable(COMMON_RTC_INSTANCE, int_mask);
234+
235+
core_util_critical_section_exit();
200236
}
201237
//------------------------------------------------------------------------------
202238

0 commit comments

Comments
 (0)