mbed library sources. Supersedes mbed-src.

Fork of mbed by teralytic

Committer:
rodriguise
Date:
Mon Oct 17 18:47:01 2016 +0000
Revision:
148:4802eb17e82b
Parent:
144:ef7eb2e8f9f7
backup

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /* Copyright (c) 2013, Nordic Semiconductor ASA
<> 144:ef7eb2e8f9f7 2 * All rights reserved.
<> 144:ef7eb2e8f9f7 3 *
<> 144:ef7eb2e8f9f7 4 * Redistribution and use in source and binary forms, with or without
<> 144:ef7eb2e8f9f7 5 * modification, are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 6 *
<> 144:ef7eb2e8f9f7 7 * * Redistributions of source code must retain the above copyright notice, this
<> 144:ef7eb2e8f9f7 8 * list of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * * Redistributions in binary form must reproduce the above copyright notice,
<> 144:ef7eb2e8f9f7 11 * this list of conditions and the following disclaimer in the documentation
<> 144:ef7eb2e8f9f7 12 * and/or other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * * Neither the name of Nordic Semiconductor ASA nor the names of its
<> 144:ef7eb2e8f9f7 15 * contributors may be used to endorse or promote products derived from
<> 144:ef7eb2e8f9f7 16 * this software without specific prior written permission.
<> 144:ef7eb2e8f9f7 17 *
<> 144:ef7eb2e8f9f7 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
<> 144:ef7eb2e8f9f7 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
<> 144:ef7eb2e8f9f7 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
<> 144:ef7eb2e8f9f7 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
<> 144:ef7eb2e8f9f7 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
<> 144:ef7eb2e8f9f7 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
<> 144:ef7eb2e8f9f7 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
<> 144:ef7eb2e8f9f7 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
<> 144:ef7eb2e8f9f7 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 28 *
<> 144:ef7eb2e8f9f7 29 */
<> 144:ef7eb2e8f9f7 30
<> 144:ef7eb2e8f9f7 31 /* NOTE: Template files (including this one) are application specific and therefore expected to
<> 144:ef7eb2e8f9f7 32 be copied into the application project folder prior to its use! */
<> 144:ef7eb2e8f9f7 33
<> 144:ef7eb2e8f9f7 34 #include <stdint.h>
<> 144:ef7eb2e8f9f7 35 #include <stdbool.h>
<> 144:ef7eb2e8f9f7 36 #include "nrf.h"
<> 144:ef7eb2e8f9f7 37 #include "nrf_delay.h"
<> 144:ef7eb2e8f9f7 38 #include "system_nrf51.h"
<> 144:ef7eb2e8f9f7 39
<> 144:ef7eb2e8f9f7 40 /*lint ++flb "Enter library region" */
<> 144:ef7eb2e8f9f7 41
<> 144:ef7eb2e8f9f7 42 #define __SYSTEM_CLOCK (16000000UL) /*!< nRF51 devices use a fixed System Clock Frequency of 16MHz */
<> 144:ef7eb2e8f9f7 43
<> 144:ef7eb2e8f9f7 44 static bool is_manual_peripheral_setup_needed(void);
<> 144:ef7eb2e8f9f7 45 static bool is_disabled_in_debug_needed(void);
<> 144:ef7eb2e8f9f7 46 static void init_clock(void);
<> 144:ef7eb2e8f9f7 47
<> 144:ef7eb2e8f9f7 48
<> 144:ef7eb2e8f9f7 49 #if defined ( __CC_ARM )
<> 144:ef7eb2e8f9f7 50 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK;
<> 144:ef7eb2e8f9f7 51 #elif defined ( __ICCARM__ )
<> 144:ef7eb2e8f9f7 52 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK;
<> 144:ef7eb2e8f9f7 53 #elif defined ( __GNUC__ )
<> 144:ef7eb2e8f9f7 54 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK;
<> 144:ef7eb2e8f9f7 55 #endif
<> 144:ef7eb2e8f9f7 56
<> 144:ef7eb2e8f9f7 57 void SystemCoreClockUpdate(void)
<> 144:ef7eb2e8f9f7 58 {
<> 144:ef7eb2e8f9f7 59 SystemCoreClock = __SYSTEM_CLOCK;
<> 144:ef7eb2e8f9f7 60 }
<> 144:ef7eb2e8f9f7 61
<> 144:ef7eb2e8f9f7 62 void SystemInit(void)
<> 144:ef7eb2e8f9f7 63 {
<> 144:ef7eb2e8f9f7 64 #if defined(TARGET_NRF_32MHZ_XTAL)
<> 144:ef7eb2e8f9f7 65 /* For 32MHz HFCLK XTAL such as Taiyo Yuden
<> 144:ef7eb2e8f9f7 66 Physically, tiny footprint XTAL oscillate higher freq. To make BLE modules smaller, some modules
<> 144:ef7eb2e8f9f7 67 are using 32MHz XTAL.
<> 144:ef7eb2e8f9f7 68 This code wriging the value 0xFFFFFF00 to the UICR (User Information Configuration Register)
<> 144:ef7eb2e8f9f7 69 at address 0x10001008, to make nRF51 works with 32MHz system clock. This register will be overwritten
<> 144:ef7eb2e8f9f7 70 by SoftDevice to 0xFFFFFFFF, the default value. Each hex files built with mbed classic online compiler
<> 144:ef7eb2e8f9f7 71 contain SoftDevice, so that, this code run once just after the hex file will be flashed onto nRF51.
<> 144:ef7eb2e8f9f7 72 After changing the value, nRF51 need to reboot. */
<> 144:ef7eb2e8f9f7 73 if (*(uint32_t *)0x10001008 == 0xFFFFFFFF)
<> 144:ef7eb2e8f9f7 74 {
<> 144:ef7eb2e8f9f7 75 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
<> 144:ef7eb2e8f9f7 76 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
<> 144:ef7eb2e8f9f7 77 *(uint32_t *)0x10001008 = 0xFFFFFF00;
<> 144:ef7eb2e8f9f7 78 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
<> 144:ef7eb2e8f9f7 79 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
<> 144:ef7eb2e8f9f7 80 NVIC_SystemReset();
<> 144:ef7eb2e8f9f7 81 while (true){}
<> 144:ef7eb2e8f9f7 82 }
<> 144:ef7eb2e8f9f7 83 #endif
<> 144:ef7eb2e8f9f7 84
<> 144:ef7eb2e8f9f7 85 /* If desired, switch off the unused RAM to lower consumption by the use of RAMON register.
<> 144:ef7eb2e8f9f7 86 It can also be done in the application main() function. */
<> 144:ef7eb2e8f9f7 87
<> 144:ef7eb2e8f9f7 88 /* Prepare the peripherals for use as indicated by the PAN 26 "System: Manual setup is required
<> 144:ef7eb2e8f9f7 89 to enable the use of peripherals" found at Product Anomaly document for your device found at
<> 144:ef7eb2e8f9f7 90 https://www.nordicsemi.com/. The side effect of executing these instructions in the devices
<> 144:ef7eb2e8f9f7 91 that do not need it is that the new peripherals in the second generation devices (LPCOMP for
<> 144:ef7eb2e8f9f7 92 example) will not be available. */
<> 144:ef7eb2e8f9f7 93 if (is_manual_peripheral_setup_needed())
<> 144:ef7eb2e8f9f7 94 {
<> 144:ef7eb2e8f9f7 95 *(uint32_t volatile *)0x40000504 = 0xC007FFDF;
<> 144:ef7eb2e8f9f7 96 *(uint32_t volatile *)0x40006C18 = 0x00008000;
<> 144:ef7eb2e8f9f7 97 }
<> 144:ef7eb2e8f9f7 98
<> 144:ef7eb2e8f9f7 99 /* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG
<> 144:ef7eb2e8f9f7 100 register is incorrect" found at Product Anomaly document four your device found at
<> 144:ef7eb2e8f9f7 101 https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */
<> 144:ef7eb2e8f9f7 102 if (is_disabled_in_debug_needed())
<> 144:ef7eb2e8f9f7 103 {
<> 144:ef7eb2e8f9f7 104 NRF_MPU->DISABLEINDEBUG = MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos;
<> 144:ef7eb2e8f9f7 105 }
<> 144:ef7eb2e8f9f7 106
<> 144:ef7eb2e8f9f7 107 // Start the external 32khz crystal oscillator.
<> 144:ef7eb2e8f9f7 108 init_clock();
<> 144:ef7eb2e8f9f7 109 }
<> 144:ef7eb2e8f9f7 110
<> 144:ef7eb2e8f9f7 111 void init_clock(void)
<> 144:ef7eb2e8f9f7 112 {
<> 144:ef7eb2e8f9f7 113 /* For compatibility purpose, the default behaviour is to first attempt to initialise an
<> 144:ef7eb2e8f9f7 114 external clock, and after a timeout, use the internal RC one. To avoid this wait, boards that
<> 144:ef7eb2e8f9f7 115 don't have an external oscillator can set TARGET_NRF_LFCLK_RC directly. */
<> 144:ef7eb2e8f9f7 116 uint32_t i = 0;
<> 144:ef7eb2e8f9f7 117 const uint32_t polling_period = 200;
<> 144:ef7eb2e8f9f7 118 const uint32_t timeout = 1000000;
<> 144:ef7eb2e8f9f7 119
<> 144:ef7eb2e8f9f7 120 #if defined(TARGET_NRF_LFCLK_RC)
<> 144:ef7eb2e8f9f7 121 NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
<> 144:ef7eb2e8f9f7 122 #else
<> 144:ef7eb2e8f9f7 123 NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
<> 144:ef7eb2e8f9f7 124 #endif
<> 144:ef7eb2e8f9f7 125 NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
<> 144:ef7eb2e8f9f7 126 NRF_CLOCK->TASKS_LFCLKSTART = 1;
<> 144:ef7eb2e8f9f7 127
<> 144:ef7eb2e8f9f7 128 /* Wait for the external oscillator to start up.
<> 144:ef7eb2e8f9f7 129 nRF51822 product specification (8.1.5) gives a typical value of 300ms for external clock
<> 144:ef7eb2e8f9f7 130 startup duration, and a maximum value of 1s. When using the internal RC source, typical delay
<> 144:ef7eb2e8f9f7 131 will be 390µs, so we use a polling period of 200µs.
<> 144:ef7eb2e8f9f7 132
<> 144:ef7eb2e8f9f7 133 We can't use us_ticker at this point, so we have to rely on a less precise method for
<> 144:ef7eb2e8f9f7 134 measuring our timeout. Because of this, the actual timeout will be slightly longer than 1
<> 144:ef7eb2e8f9f7 135 second, which isn't an issue at all, since this fallback should only be used as a safety net.
<> 144:ef7eb2e8f9f7 136 */
<> 144:ef7eb2e8f9f7 137 for (i = 0; i < (timeout / polling_period); i++) {
<> 144:ef7eb2e8f9f7 138 if (NRF_CLOCK->EVENTS_LFCLKSTARTED != 0)
<> 144:ef7eb2e8f9f7 139 return;
<> 144:ef7eb2e8f9f7 140 nrf_delay_us(polling_period);
<> 144:ef7eb2e8f9f7 141 }
<> 144:ef7eb2e8f9f7 142
<> 144:ef7eb2e8f9f7 143 /* Fallback to internal clock. Belt and braces, since the internal clock is used by default
<> 144:ef7eb2e8f9f7 144 whilst no external source is running. This is not only a sanity check, but it also allows
<> 144:ef7eb2e8f9f7 145 code down the road (e.g. ble initialisation) to directly know which clock is used. */
<> 144:ef7eb2e8f9f7 146 NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
<> 144:ef7eb2e8f9f7 147 NRF_CLOCK->TASKS_LFCLKSTART = 1;
<> 144:ef7eb2e8f9f7 148 while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
<> 144:ef7eb2e8f9f7 149 // Do nothing.
<> 144:ef7eb2e8f9f7 150 }
<> 144:ef7eb2e8f9f7 151 }
<> 144:ef7eb2e8f9f7 152
<> 144:ef7eb2e8f9f7 153 static bool is_manual_peripheral_setup_needed(void)
<> 144:ef7eb2e8f9f7 154 {
<> 144:ef7eb2e8f9f7 155 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
<> 144:ef7eb2e8f9f7 156 {
<> 144:ef7eb2e8f9f7 157 if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x00) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
<> 144:ef7eb2e8f9f7 158 {
<> 144:ef7eb2e8f9f7 159 return true;
<> 144:ef7eb2e8f9f7 160 }
<> 144:ef7eb2e8f9f7 161 if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x10) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
<> 144:ef7eb2e8f9f7 162 {
<> 144:ef7eb2e8f9f7 163 return true;
<> 144:ef7eb2e8f9f7 164 }
<> 144:ef7eb2e8f9f7 165 if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
<> 144:ef7eb2e8f9f7 166 {
<> 144:ef7eb2e8f9f7 167 return true;
<> 144:ef7eb2e8f9f7 168 }
<> 144:ef7eb2e8f9f7 169 }
<> 144:ef7eb2e8f9f7 170
<> 144:ef7eb2e8f9f7 171 return false;
<> 144:ef7eb2e8f9f7 172 }
<> 144:ef7eb2e8f9f7 173
<> 144:ef7eb2e8f9f7 174 static bool is_disabled_in_debug_needed(void)
<> 144:ef7eb2e8f9f7 175 {
<> 144:ef7eb2e8f9f7 176 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
<> 144:ef7eb2e8f9f7 177 {
<> 144:ef7eb2e8f9f7 178 if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
<> 144:ef7eb2e8f9f7 179 {
<> 144:ef7eb2e8f9f7 180 return true;
<> 144:ef7eb2e8f9f7 181 }
<> 144:ef7eb2e8f9f7 182 }
<> 144:ef7eb2e8f9f7 183
<> 144:ef7eb2e8f9f7 184 return false;
<> 144:ef7eb2e8f9f7 185 }
<> 144:ef7eb2e8f9f7 186
<> 144:ef7eb2e8f9f7 187 /*lint --flb "Leave library region" */