Skip to content

Commit 92cfa96

Browse files
nvlsianpuadbridge
authored andcommitted
fix: - rtc overflow-while-set-timestamp issue - timer has a race condition
1 parent 08e79cb commit 92cfa96

File tree

1 file changed

+46
-16
lines changed

1 file changed

+46
-16
lines changed

targets/TARGET_NORDIC/TARGET_NRF5_SDK13/us_ticker.c

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,32 +55,36 @@
5555
bool m_common_rtc_enabled = false;
5656
uint32_t volatile m_common_rtc_overflows = 0;
5757

58+
__STATIC_INLINE void rtc_ovf_event_check(void)
59+
{
60+
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) {
61+
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW);
62+
// Don't disable this event. It shall occur periodically.
63+
64+
++m_common_rtc_overflows;
65+
}
66+
}
67+
5868
#if defined(TARGET_MCU_NRF51822)
5969
void common_rtc_irq_handler(void)
6070
#else
6171
void COMMON_RTC_IRQ_HANDLER(void)
6272
#endif
6373
{
64-
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, US_TICKER_EVENT))
65-
{
74+
75+
rtc_ovf_event_check();
76+
77+
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, US_TICKER_EVENT)) {
6678
us_ticker_irq_handler();
6779
}
6880

6981
#if DEVICE_LOWPOWERTIMER
70-
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, LP_TICKER_EVENT))
71-
{
82+
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, LP_TICKER_EVENT)) {
7283

7384
lp_ticker_irq_handler();
7485
}
7586
#endif
7687

77-
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW))
78-
{
79-
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW);
80-
// Don't disable this event. It shall occur periodically.
81-
82-
++m_common_rtc_overflows;
83-
}
8488
}
8589

8690
// Function for fix errata 20: RTC Register values are invalid
@@ -168,13 +172,37 @@ void common_rtc_init(void)
168172
m_common_rtc_enabled = true;
169173
}
170174

175+
__STATIC_INLINE void rtc_ovf_event_safe_check(void)
176+
{
177+
core_util_critical_section_enter();
178+
179+
rtc_ovf_event_check();
180+
181+
core_util_critical_section_exit();
182+
}
183+
184+
171185
uint32_t common_rtc_32bit_ticks_get(void)
172186
{
173-
uint32_t ticks = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
174-
// The counter used for time measurements is less than 32 bit wide,
175-
// so its value is complemented with the number of registered overflows
176-
// of the counter.
177-
ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS);
187+
uint32_t ticks;
188+
uint32_t prev_overflows;
189+
190+
do {
191+
prev_overflows = m_common_rtc_overflows;
192+
193+
ticks = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
194+
// The counter used for time measurements is less than 32 bit wide,
195+
// so its value is complemented with the number of registered overflows
196+
// of the counter.
197+
ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS);
198+
199+
// Check in case that OVF occurred during execution of a RTC handler (apply if call was from RTC handler)
200+
// m_common_rtc_overflows might been updated in this call.
201+
rtc_ovf_event_safe_check();
202+
203+
// If call was made from a low priority level m_common_rtc_overflows might have been updated in RTC handler.
204+
} while (m_common_rtc_overflows != prev_overflows);
205+
178206
return ticks;
179207
}
180208

@@ -213,6 +241,7 @@ void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel,
213241
uint32_t compare_value =
214242
(uint32_t)CEIL_DIV((timestamp64) * RTC_INPUT_FREQ, 1000000);
215243

244+
core_util_critical_section_enter();
216245
// The COMPARE event occurs when the value in compare register is N and
217246
// the counter value changes from N-1 to N. Therefore, the minimal safe
218247
// difference between the compare value to be set and the current counter
@@ -226,6 +255,7 @@ void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel,
226255

227256
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, cc_channel, RTC_WRAP(compare_value));
228257
nrf_rtc_event_enable(COMMON_RTC_INSTANCE, int_mask);
258+
core_util_critical_section_exit();
229259
}
230260
//------------------------------------------------------------------------------
231261

0 commit comments

Comments
 (0)