1 /* 2 3 Copyright (c) 2009-2020 ARM Limited. All rights reserved. 4 5 SPDX-License-Identifier: Apache-2.0 6 7 Licensed under the Apache License, Version 2.0 (the License); you may 8 not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an AS IS BASIS, WITHOUT 15 WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 19 NOTICE: This file has been modified by Nordic Semiconductor ASA. 20 21 */ 22 23 /* NOTE: Template files (including this one) are application specific and therefore expected to 24 be copied into the application project folder prior to its use! */ 25 26 #include <stdint.h> 27 #include <stdbool.h> 28 #include "nrf.h" 29 #include "nrf_erratas.h" 30 #include "system_nrf9160.h" 31 32 /*lint ++flb "Enter library region" */ 33 34 35 #define __SYSTEM_CLOCK (64000000UL) /*!< nRF9160 Application core uses a fixed System Clock Frequency of 64MHz */ 36 37 #define TRACE_PIN_CNF_VALUE ( (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | \ 38 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | \ 39 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | \ 40 (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | \ 41 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) ) 42 #define TRACE_TRACECLK_PIN (21) 43 #define TRACE_TRACEDATA0_PIN (22) 44 #define TRACE_TRACEDATA1_PIN (23) 45 #define TRACE_TRACEDATA2_PIN (24) 46 #define TRACE_TRACEDATA3_PIN (25) 47 48 #if defined ( __CC_ARM ) 49 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; 50 #elif defined ( __ICCARM__ ) 51 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; 52 #elif defined ( __GNUC__ ) 53 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; 54 #endif 55 56 /* Global values used used in Secure mode SystemInit. */ 57 #if !defined(NRF_TRUSTZONE_NONSECURE) 58 /* Global values used by UICR erase fix algorithm. */ 59 static uint32_t uicr_erased_value; 60 static uint32_t uicr_new_value; 61 #endif 62 63 /* Errata are only handled in secure mode since they usually need access to FICR. */ 64 #if !defined(NRF_TRUSTZONE_NONSECURE) 65 static bool uicr_HFXOSRC_erased(void); 66 static bool uicr_HFXOCNT_erased(void); 67 #endif 68 SystemCoreClockUpdate(void)69void SystemCoreClockUpdate(void) 70 { 71 SystemCoreClock = __SYSTEM_CLOCK; 72 } 73 SystemInit(void)74void SystemInit(void) 75 { 76 #if !defined(NRF_TRUSTZONE_NONSECURE) 77 /* Perform Secure-mode initialization routines. */ 78 79 /* Set all ARM SAU regions to NonSecure if TrustZone extensions are enabled. 80 * Nordic SPU should handle Secure Attribution tasks */ 81 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) 82 SAU->CTRL |= (1 << SAU_CTRL_ALLNS_Pos); 83 #endif 84 85 /* Workaround for Errata 6 "POWER: SLEEPENTER and SLEEPEXIT events asserted after pin reset" found at the Errata document 86 for your device located at https://infocenter.nordicsemi.com/index.jsp */ 87 if (nrf91_errata_6()){ 88 NRF_POWER_S->EVENTS_SLEEPENTER = (POWER_EVENTS_SLEEPENTER_EVENTS_SLEEPENTER_NotGenerated << POWER_EVENTS_SLEEPENTER_EVENTS_SLEEPENTER_Pos); 89 NRF_POWER_S->EVENTS_SLEEPEXIT = (POWER_EVENTS_SLEEPEXIT_EVENTS_SLEEPEXIT_NotGenerated << POWER_EVENTS_SLEEPEXIT_EVENTS_SLEEPEXIT_Pos); 90 } 91 92 /* Workaround for Errata 14 "REGULATORS: LDO mode at startup" found at the Errata document 93 for your device located at https://infocenter.nordicsemi.com/index.jsp */ 94 if (nrf91_errata_14()){ 95 *((volatile uint32_t *)0x50004A38) = 0x01ul; 96 NRF_REGULATORS_S->DCDCEN = REGULATORS_DCDCEN_DCDCEN_Enabled << REGULATORS_DCDCEN_DCDCEN_Pos; 97 } 98 99 /* Workaround for Errata 15 "REGULATORS: LDO mode at startup" found at the Errata document 100 for your device located at https://infocenter.nordicsemi.com/index.jsp */ 101 if (nrf91_errata_15()){ 102 NRF_REGULATORS_S->DCDCEN = REGULATORS_DCDCEN_DCDCEN_Enabled << REGULATORS_DCDCEN_DCDCEN_Pos; 103 } 104 105 /* Workaround for Errata 20 "RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document 106 for your device located at https://infocenter.nordicsemi.com/index.jsp */ 107 if (nrf91_errata_20()){ 108 *((volatile uint32_t *)0x5003AEE4) = 0xE; 109 } 110 111 /* Workaround for Errata 31 "XOSC32k Startup Failure" found at the Errata document 112 for your device located at https://infocenter.nordicsemi.com/index.jsp */ 113 if (nrf91_errata_31()){ 114 *((volatile uint32_t *)0x5000470Cul) = 0x0; 115 *((volatile uint32_t *)0x50004710ul) = 0x1; 116 } 117 118 /* Trimming of the device. Copy all the trimming values from FICR into the target addresses. Trim 119 until one ADDR is not initialized. */ 120 uint32_t index = 0; 121 for (index = 0; index < 256ul && NRF_FICR_S->TRIMCNF[index].ADDR != 0xFFFFFFFFul; index++){ 122 #if defined ( __ICCARM__ ) 123 #pragma diag_suppress=Pa082 124 #endif 125 *(volatile uint32_t *)NRF_FICR_S->TRIMCNF[index].ADDR = NRF_FICR_S->TRIMCNF[index].DATA; 126 #if defined ( __ICCARM__ ) 127 #pragma diag_default=Pa082 128 #endif 129 } 130 131 /* Set UICR->HFXOSRC and UICR->HFXOCNT to working defaults if UICR was erased */ 132 if (uicr_HFXOSRC_erased() || uicr_HFXOCNT_erased()) { 133 /* Wait for pending NVMC operations to finish */ 134 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 135 136 /* Enable write mode in NVMC */ 137 NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Wen; 138 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 139 140 if (uicr_HFXOSRC_erased()){ 141 /* Write default value to UICR->HFXOSRC */ 142 uicr_erased_value = NRF_UICR_S->HFXOSRC; 143 uicr_new_value = (uicr_erased_value & ~UICR_HFXOSRC_HFXOSRC_Msk) | UICR_HFXOSRC_HFXOSRC_TCXO; 144 NRF_UICR_S->HFXOSRC = uicr_new_value; 145 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 146 } 147 148 if (uicr_HFXOCNT_erased()){ 149 /* Write default value to UICR->HFXOCNT */ 150 uicr_erased_value = NRF_UICR_S->HFXOCNT; 151 uicr_new_value = (uicr_erased_value & ~UICR_HFXOCNT_HFXOCNT_Msk) | 0x20; 152 NRF_UICR_S->HFXOCNT = uicr_new_value; 153 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 154 } 155 156 /* Enable read mode in NVMC */ 157 NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Ren; 158 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 159 160 /* Reset to apply clock select update */ 161 NVIC_SystemReset(); 162 } 163 164 /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product 165 Specification to see which ones). */ 166 #if defined (ENABLE_TRACE) 167 // Enable Trace And Debug peripheral 168 NRF_TAD_S->ENABLE = TAD_ENABLE_ENABLE_Msk; 169 NRF_TAD_S->CLOCKSTART = TAD_CLOCKSTART_START_Msk; 170 171 // Set up Trace pads SPU firewall 172 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACECLK_PIN); 173 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA0_PIN); 174 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA1_PIN); 175 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA2_PIN); 176 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA3_PIN); 177 178 // Configure trace port pads 179 NRF_P0_S->PIN_CNF[TRACE_TRACECLK_PIN] = TRACE_PIN_CNF_VALUE; 180 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA0_PIN] = TRACE_PIN_CNF_VALUE; 181 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA1_PIN] = TRACE_PIN_CNF_VALUE; 182 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA2_PIN] = TRACE_PIN_CNF_VALUE; 183 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA3_PIN] = TRACE_PIN_CNF_VALUE; 184 185 // Select trace pins 186 NRF_TAD_S->PSEL.TRACECLK = TRACE_TRACECLK_PIN; 187 NRF_TAD_S->PSEL.TRACEDATA0 = TRACE_TRACEDATA0_PIN; 188 NRF_TAD_S->PSEL.TRACEDATA1 = TRACE_TRACEDATA1_PIN; 189 NRF_TAD_S->PSEL.TRACEDATA2 = TRACE_TRACEDATA2_PIN; 190 NRF_TAD_S->PSEL.TRACEDATA3 = TRACE_TRACEDATA3_PIN; 191 192 // Set trace port speed to 32 MHz 193 NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_32MHz; 194 195 *((uint32_t *)(0xE0053000ul)) = 0x00000001ul; 196 197 *((uint32_t *)(0xE005AFB0ul)) = 0xC5ACCE55ul; 198 *((uint32_t *)(0xE005A000ul)) &= 0xFFFFFF00ul; 199 *((uint32_t *)(0xE005A004ul)) = 0x00000009ul; 200 *((uint32_t *)(0xE005A000ul)) = 0x00000303ul; 201 *((uint32_t *)(0xE005AFB0ul)) = 0x00000000ul; 202 203 *((uint32_t *)(0xE005BFB0ul)) = 0xC5ACCE55ul; 204 *((uint32_t *)(0xE005B000ul)) &= 0xFFFFFF00ul; 205 *((uint32_t *)(0xE005B004ul)) = 0x00003000ul; 206 *((uint32_t *)(0xE005B000ul)) = 0x00000308ul; 207 *((uint32_t *)(0xE005BFB0ul)) = 0x00000000ul; 208 209 *((uint32_t *)(0xE0058FB0ul)) = 0xC5ACCE55ul; 210 *((uint32_t *)(0xE0058000ul)) = 0x00000000ul; 211 *((uint32_t *)(0xE0058004ul)) = 0x00000000ul; 212 *((uint32_t *)(0xE0058FB0ul)) = 0x00000000ul; 213 214 /* Rom table does not list ETB, or TPIU base addresses. 215 * Some debug probes may require manual configuration of these peripherals to enable tracing. 216 * ETB_BASE = 0xE0051000 217 * TPIU_BASE = 0xE0054000 218 */ 219 #endif 220 221 /* Allow Non-Secure code to run FPU instructions. 222 * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */ 223 SCB->NSACR |= (3UL << 10); 224 #endif 225 226 /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the 227 * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit 228 * operations are not used in your code. */ 229 #if (__FPU_USED == 1) 230 SCB->CPACR |= (3UL << 20) | (3UL << 22); 231 __DSB(); 232 __ISB(); 233 #endif 234 235 SystemCoreClockUpdate(); 236 } 237 238 239 #if !defined(NRF_TRUSTZONE_NONSECURE) 240 uicr_HFXOCNT_erased()241 bool uicr_HFXOCNT_erased() 242 { 243 if (NRF_UICR_S->HFXOCNT == 0xFFFFFFFFul) { 244 return true; 245 } 246 return false; 247 } 248 249 uicr_HFXOSRC_erased()250 bool uicr_HFXOSRC_erased() 251 { 252 if ((NRF_UICR_S->HFXOSRC & UICR_HFXOSRC_HFXOSRC_Msk) != UICR_HFXOSRC_HFXOSRC_TCXO) { 253 return true; 254 } 255 return false; 256 } 257 #endif 258 259 /*lint --flb "Leave library region" */ 260