mbed
Fork of mbed-dev by
Diff: targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c
- Revision:
- 163:74e0ce7f98e8
- Parent:
- 160:d5399cc887bb
- Child:
- 165:e614a9f1c9e2
diff -r e13f6fdb2ac4 -r 74e0ce7f98e8 targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c --- a/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c Wed Apr 12 16:21:43 2017 +0100 +++ b/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c Fri Apr 28 14:04:18 2017 +0100 @@ -42,6 +42,7 @@ #include "nrf_drv_common.h" #include "nrf_drv_config.h" #include "lp_ticker_api.h" +#include "mbed_critical.h" //------------------------------------------------------------------------------ @@ -52,12 +53,25 @@ bool m_common_rtc_enabled = false; uint32_t volatile m_common_rtc_overflows = 0; +__STATIC_INLINE void rtc_ovf_event_check(void) +{ + if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) { + nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW); + // Don't disable this event. It shall occur periodically. + + ++m_common_rtc_overflows; + } +} + #if defined(TARGET_MCU_NRF51822) void common_rtc_irq_handler(void) #else void COMMON_RTC_IRQ_HANDLER(void) #endif { + + rtc_ovf_event_check(); + if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, US_TICKER_EVENT)) { us_ticker_irq_handler(); } @@ -69,12 +83,6 @@ } #endif - if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) { - nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW); - // Don't disable this event. It shall occur periodically. - - ++m_common_rtc_overflows; - } } #if (defined (__ICCARM__)) && defined(TARGET_MCU_NRF51822)//IAR @@ -142,13 +150,37 @@ m_common_rtc_enabled = true; } +__STATIC_INLINE void rtc_ovf_event_safe_check(void) +{ + core_util_critical_section_enter(); + + rtc_ovf_event_check(); + + core_util_critical_section_exit(); +} + + uint32_t common_rtc_32bit_ticks_get(void) { - uint32_t ticks = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); - // The counter used for time measurements is less than 32 bit wide, - // so its value is complemented with the number of registered overflows - // of the counter. - ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS); + uint32_t ticks; + uint32_t prev_overflows; + + do { + prev_overflows = m_common_rtc_overflows; + + ticks = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); + // The counter used for time measurements is less than 32 bit wide, + // so its value is complemented with the number of registered overflows + // of the counter. + ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS); + + // Check in case that OVF occurred during execution of a RTC handler (apply if call was from RTC handler) + // m_common_rtc_overflows might been updated in this call. + rtc_ovf_event_safe_check(); + + // If call was made from a low priority level m_common_rtc_overflows might have been updated in RTC handler. + } while (m_common_rtc_overflows != prev_overflows); + return ticks; } @@ -185,6 +217,8 @@ uint32_t compare_value = (uint32_t)CEIL_DIV((timestamp64) * RTC_INPUT_FREQ, 1000000); + + core_util_critical_section_enter(); // The COMPARE event occurs when the value in compare register is N and // the counter value changes from N-1 to N. Therefore, the minimal safe // difference between the compare value to be set and the current counter @@ -197,6 +231,8 @@ nrf_rtc_cc_set(COMMON_RTC_INSTANCE, cc_channel, RTC_WRAP(compare_value)); nrf_rtc_event_enable(COMMON_RTC_INSTANCE, int_mask); + + core_util_critical_section_exit(); } //------------------------------------------------------------------------------