mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Revision:
603:3c75ef011213
Parent:
598:2d5fc5624619
Child:
620:49241b7c6da5
--- a/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/system_nrf51.c	Wed Aug 05 14:30:08 2015 +0100
+++ b/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/system_nrf51.c	Thu Aug 13 10:30:09 2015 +0100
@@ -34,6 +34,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include "nrf.h"
+#include "nrf_delay.h"
 #include "system_nrf51.h"
 
 /*lint ++flb "Enter library region" */
@@ -42,6 +43,7 @@
 
 static bool is_manual_peripheral_setup_needed(void);
 static bool is_disabled_in_debug_needed(void);
+static void init_clock(void);
 
 
 #if defined ( __CC_ARM )
@@ -82,8 +84,18 @@
     }
 
     // Start the external 32khz crystal oscillator.
+    init_clock();
+}
 
-    /* for Nordic devices without an external LF crystal */
+void init_clock(void)
+{
+    /* For compatibility purpose, the default behaviour is to first attempt to initialise an
+       external clock, and after a timeout, use the internal RC one. To avoid this wait, boards that
+       don't have an external oscillator can set TARGET_NRF_LFCLK_RC directly. */
+    int i = 0;
+    const uint32_t polling_period = 200;
+    const uint32_t timeout = 1000000;
+
 #if defined(TARGET_NRF_LFCLK_RC)
     NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
 #else
@@ -92,7 +104,26 @@
     NRF_CLOCK->EVENTS_LFCLKSTARTED  = 0;
     NRF_CLOCK->TASKS_LFCLKSTART     = 1;
 
-    // Wait for the external oscillator to start up.
+    /* Wait for the external oscillator to start up.
+       nRF51822 product specification (8.1.5) gives a typical value of 300ms for external clock
+       startup duration, and a maximum value of 1s. When using the internal RC source, typical delay
+       will be 390µs, so we use a polling period of 200µs.
+
+       We can't use us_ticker at this point, so we have to rely on a less precise method for
+       measuring our timeout. Because of this, the actual timeout will be slightly longer than 1
+       second, which isn't an issue at all, since this fallback should only be used as a safety net.
+       */
+    for (i = 0; i < (timeout / polling_period); i++) {
+        if (NRF_CLOCK->EVENTS_LFCLKSTARTED != 0)
+            return;
+        nrf_delay_us(polling_period);
+    }
+
+    /* Fallback to internal clock. Belt and braces, since the internal clock is used by default
+       whilst no external source is running. This is not only a sanity check, but it also allows
+       code down the road (e.g. ble initialisation) to directly know which clock is used. */
+    NRF_CLOCK->LFCLKSRC         = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
+    NRF_CLOCK->TASKS_LFCLKSTART = 1;
     while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
         // Do nothing.
     }