mbed
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