Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
Diff: targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c
- Revision:
- 163:74e0ce7f98e8
- Parent:
- 160:d5399cc887bb
- Child:
- 165:e614a9f1c9e2
--- 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(); } //------------------------------------------------------------------------------