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:
- 165:e614a9f1c9e2
- Parent:
- 163:74e0ce7f98e8
- Child:
- 167:e84263d55307
diff -r 289d4deac6e4 -r e614a9f1c9e2 targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c --- a/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c Wed May 10 12:06:41 2017 +0100 +++ b/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c Fri May 26 12:39:01 2017 +0100 @@ -40,10 +40,12 @@ #include "common_rtc.h" #include "app_util.h" #include "nrf_drv_common.h" -#include "nrf_drv_config.h" #include "lp_ticker_api.h" #include "mbed_critical.h" +#if defined(NRF52_ERRATA_20) + #include "softdevice_handler.h" +#endif //------------------------------------------------------------------------------ // Common stuff used also by lp_ticker and rtc_api (see "common_rtc.h"). @@ -82,7 +84,23 @@ lp_ticker_irq_handler(); } #endif +} +// Function for fix errata 20: RTC Register values are invalid +__STATIC_INLINE void errata_20(void) +{ +#if defined(NRF52_ERRATA_20) + if (!softdevice_handler_is_enabled()) + { + NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; + NRF_CLOCK->TASKS_LFCLKSTART = 1; + + while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) + { + } + } + NRF_RTC1->TASKS_STOP = 0; +#endif } #if (defined (__ICCARM__)) && defined(TARGET_MCU_NRF51822)//IAR @@ -96,6 +114,8 @@ return; } + errata_20(); + NVIC_SetVector(RTC1_IRQn, (uint32_t)RTC1_IRQHandler); // RTC is driven by the low frequency (32.768 kHz) clock, a proper request @@ -118,9 +138,9 @@ // events will be enabled or disabled as needed (such approach is more // energy efficient). nrf_rtc_int_enable(COMMON_RTC_INSTANCE, - #if DEVICE_LOWPOWERTIMER +#if DEVICE_LOWPOWERTIMER LP_TICKER_INT_MASK | - #endif +#endif US_TICKER_INT_MASK | NRF_RTC_INT_OVERFLOW_MASK); @@ -129,18 +149,18 @@ nrf_rtc_event_enable(COMMON_RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK); // All other relevant events are initially disabled. nrf_rtc_event_disable(COMMON_RTC_INSTANCE, - #if defined(TARGET_MCU_NRF51822) +#if defined(TARGET_MCU_NRF51822) OS_TICK_INT_MASK | - #endif - #if DEVICE_LOWPOWERTIMER +#endif +#if DEVICE_LOWPOWERTIMER LP_TICKER_INT_MASK | - #endif +#endif US_TICKER_INT_MASK); nrf_drv_common_irq_enable(nrf_drv_get_IRQn(COMMON_RTC_INSTANCE), #ifdef NRF51 APP_IRQ_PRIORITY_LOW -#elif defined(NRF52) +#elif defined(NRF52) || defined(NRF52840_XXAA) APP_IRQ_PRIORITY_LOWEST #endif ); @@ -291,7 +311,9 @@ */ MBED_WEAK uint32_t const os_trv; MBED_WEAK uint32_t const os_clockrate; -MBED_WEAK void OS_Tick_Handler() { } +MBED_WEAK void OS_Tick_Handler(void) +{ +} #if defined (__CC_ARM) /* ARMCC Compiler */ @@ -432,7 +454,8 @@ * Return the next number of clock cycle needed for the next tick. * @note This function has been carrefuly optimized for a systick occuring every 1000us. */ -static uint32_t get_next_tick_cc_delta() { +static uint32_t get_next_tick_cc_delta() +{ uint32_t delta = 0; if (os_clockrate != 1000) { @@ -468,7 +491,8 @@ return delta; } -static inline void clear_tick_interrupt() { +static inline void clear_tick_interrupt() +{ nrf_rtc_event_clear(COMMON_RTC_INSTANCE, OS_TICK_EVENT); nrf_rtc_event_disable(COMMON_RTC_INSTANCE, OS_TICK_INT_MASK); } @@ -480,7 +504,8 @@ * @param val value to check * @return true if the value is included in the range and false otherwise. */ -static inline bool is_in_wrapped_range(uint32_t begin, uint32_t end, uint32_t val) { +static inline bool is_in_wrapped_range(uint32_t begin, uint32_t end, uint32_t val) +{ // regular case, begin < end // return true if begin <= val < end if (begin < end) { @@ -504,7 +529,8 @@ /** * Register the next tick. */ -static void register_next_tick() { +static void register_next_tick() +{ previous_tick_cc_value = nrf_rtc_cc_get(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL); uint32_t delta = get_next_tick_cc_delta(); uint32_t new_compare_value = (previous_tick_cc_value + delta) & MAX_RTC_COUNTER_VAL; @@ -563,8 +589,9 @@ * @note This function is exposed by RTX kernel. * @return 1 if the timer has overflowed and 0 otherwise. */ -uint32_t os_tick_ovf(void) { - uint32_t current_counter = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); +uint32_t os_tick_ovf(void) +{ + uint32_t current_counter = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); uint32_t next_tick_cc_value = nrf_rtc_cc_get(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL); return is_in_wrapped_range(previous_tick_cc_value, next_tick_cc_value, current_counter) ? 0 : 1; @@ -579,8 +606,9 @@ * descending order, even if the internal counter used is an ascending one. * @return the value of the alternative hardware timer. */ -uint32_t os_tick_val(void) { - uint32_t current_counter = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); +uint32_t os_tick_val(void) +{ + uint32_t current_counter = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); uint32_t next_tick_cc_value = nrf_rtc_cc_get(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL); // do not use os_tick_ovf because its counter value can be different