mbed

Fork of mbed-dev by mbed official

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