1 /* 2 3 Copyright (c) 2009-2018 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 "system_nrf52.h" 30 31 /*lint ++flb "Enter library region" */ 32 33 #define __SYSTEM_CLOCK_64M (64000000UL) 34 35 static bool errata_12(void); 36 static bool errata_16(void); 37 static bool errata_31(void); 38 static bool errata_32(void); 39 static bool errata_36(void); 40 static bool errata_37(void); 41 static bool errata_57(void); 42 static bool errata_66(void); 43 static bool errata_108(void); 44 static bool errata_136(void); 45 static bool errata_182(void); 46 47 48 #if defined ( __CC_ARM ) 49 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; 50 #elif defined ( __ICCARM__ ) 51 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; 52 #elif defined ( __GNUC__ ) 53 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; 54 #endif 55 56 void SystemCoreClockUpdate(void) 57 { 58 SystemCoreClock = __SYSTEM_CLOCK_64M; 59 } 60 61 void SystemInit(void) 62 { 63 /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product 64 Specification to see which one). */ 65 #if defined (ENABLE_SWO) 66 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 67 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; 68 NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 69 #endif 70 71 /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product 72 Specification to see which ones). */ 73 #if defined (ENABLE_TRACE) 74 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 75 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos; 76 NRF_P0->PIN_CNF[14] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 77 NRF_P0->PIN_CNF[15] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 78 NRF_P0->PIN_CNF[16] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 79 NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 80 NRF_P0->PIN_CNF[20] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 81 #endif 82 83 /* Workaround for Errata 12 "COMP: Reference ladder not correctly calibrated" found at the Errata document 84 for your device located at https://infocenter.nordicsemi.com/ */ 85 if (errata_12()){ 86 *(volatile uint32_t *)0x40013540 = (*(uint32_t *)0x10000324 & 0x00001F00) >> 8; 87 } 88 89 /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document 90 for your device located at https://infocenter.nordicsemi.com/ */ 91 if (errata_16()){ 92 *(volatile uint32_t *)0x4007C074 = 3131961357ul; 93 } 94 95 /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document 96 for your device located at https://infocenter.nordicsemi.com/ */ 97 if (errata_31()){ 98 *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13; 99 } 100 101 /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document 102 for your device located at https://infocenter.nordicsemi.com/ */ 103 if (errata_32()){ 104 CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; 105 } 106 107 /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document 108 for your device located at https://infocenter.nordicsemi.com/ */ 109 if (errata_36()){ 110 NRF_CLOCK->EVENTS_DONE = 0; 111 NRF_CLOCK->EVENTS_CTTO = 0; 112 NRF_CLOCK->CTIV = 0; 113 } 114 115 /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document 116 for your device located at https://infocenter.nordicsemi.com/ */ 117 if (errata_37()){ 118 *(volatile uint32_t *)0x400005A0 = 0x3; 119 } 120 121 /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document 122 for your device located at https://infocenter.nordicsemi.com/ */ 123 if (errata_57()){ 124 *(volatile uint32_t *)0x40005610 = 0x00000005; 125 *(volatile uint32_t *)0x40005688 = 0x00000001; 126 *(volatile uint32_t *)0x40005618 = 0x00000000; 127 *(volatile uint32_t *)0x40005614 = 0x0000003F; 128 } 129 130 /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document 131 for your device located at https://infocenter.nordicsemi.com/ */ 132 if (errata_66()){ 133 NRF_TEMP->A0 = NRF_FICR->TEMP.A0; 134 NRF_TEMP->A1 = NRF_FICR->TEMP.A1; 135 NRF_TEMP->A2 = NRF_FICR->TEMP.A2; 136 NRF_TEMP->A3 = NRF_FICR->TEMP.A3; 137 NRF_TEMP->A4 = NRF_FICR->TEMP.A4; 138 NRF_TEMP->A5 = NRF_FICR->TEMP.A5; 139 NRF_TEMP->B0 = NRF_FICR->TEMP.B0; 140 NRF_TEMP->B1 = NRF_FICR->TEMP.B1; 141 NRF_TEMP->B2 = NRF_FICR->TEMP.B2; 142 NRF_TEMP->B3 = NRF_FICR->TEMP.B3; 143 NRF_TEMP->B4 = NRF_FICR->TEMP.B4; 144 NRF_TEMP->B5 = NRF_FICR->TEMP.B5; 145 NRF_TEMP->T0 = NRF_FICR->TEMP.T0; 146 NRF_TEMP->T1 = NRF_FICR->TEMP.T1; 147 NRF_TEMP->T2 = NRF_FICR->TEMP.T2; 148 NRF_TEMP->T3 = NRF_FICR->TEMP.T3; 149 NRF_TEMP->T4 = NRF_FICR->TEMP.T4; 150 } 151 152 /* Workaround for Errata 108 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document 153 for your device located at https://infocenter.nordicsemi.com/ */ 154 if (errata_108()){ 155 *(volatile uint32_t *)0x40000EE4 = *(volatile uint32_t *)0x10000258 & 0x0000004F; 156 } 157 158 /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document 159 for your device located at https://infocenter.nordicsemi.com/ */ 160 if (errata_136()){ 161 if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){ 162 NRF_POWER->RESETREAS = ~POWER_RESETREAS_RESETPIN_Msk; 163 } 164 } 165 166 /* Workaround for Errata 182 "RADIO: Fixes for anomalies #102, #106, and #107 do not take effect" found at the Errata document 167 for your device located at https://infocenter.nordicsemi.com/ */ 168 if (errata_182()){ 169 *(volatile uint32_t *) 0x4000173C |= (0x1 << 10); 170 } 171 172 /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the 173 * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit 174 * operations are not used in your code. */ 175 #if (__FPU_USED == 1) 176 SCB->CPACR |= (3UL << 20) | (3UL << 22); 177 __DSB(); 178 __ISB(); 179 #endif 180 181 /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, 182 two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as 183 normal GPIOs. */ 184 #if defined (CONFIG_NFCT_PINS_AS_GPIOS) 185 if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ 186 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; 187 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 188 NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; 189 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 190 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; 191 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 192 NVIC_SystemReset(); 193 } 194 #endif 195 196 /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not 197 defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be 198 reserved for PinReset and not available as normal GPIO. */ 199 #if defined (CONFIG_GPIO_AS_PINRESET) 200 if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || 201 ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ 202 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; 203 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 204 NRF_UICR->PSELRESET[0] = 21; 205 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 206 NRF_UICR->PSELRESET[1] = 21; 207 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 208 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; 209 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 210 NVIC_SystemReset(); 211 } 212 #endif 213 214 SystemCoreClockUpdate(); 215 } 216 217 218 static bool errata_12(void) 219 { 220 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 221 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 222 return true; 223 } 224 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 225 return true; 226 } 227 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 228 return true; 229 } 230 } 231 232 return false; 233 } 234 235 static bool errata_16(void) 236 { 237 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 238 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 239 return true; 240 } 241 } 242 243 return false; 244 } 245 246 static bool errata_31(void) 247 { 248 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 249 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 250 return true; 251 } 252 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 253 return true; 254 } 255 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 256 return true; 257 } 258 } 259 260 return false; 261 } 262 263 static bool errata_32(void) 264 { 265 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 266 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 267 return true; 268 } 269 } 270 271 return false; 272 } 273 274 static bool errata_36(void) 275 { 276 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 277 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 278 return true; 279 } 280 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 281 return true; 282 } 283 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 284 return true; 285 } 286 } 287 288 return false; 289 } 290 291 static bool errata_37(void) 292 { 293 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 294 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 295 return true; 296 } 297 } 298 299 return false; 300 } 301 302 static bool errata_57(void) 303 { 304 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 305 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 306 return true; 307 } 308 } 309 310 return false; 311 } 312 313 static bool errata_66(void) 314 { 315 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 316 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 317 return true; 318 } 319 } 320 321 return false; 322 } 323 324 325 static bool errata_108(void) 326 { 327 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 328 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 329 return true; 330 } 331 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 332 return true; 333 } 334 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 335 return true; 336 } 337 } 338 339 return false; 340 } 341 342 343 static bool errata_136(void) 344 { 345 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 346 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 347 return true; 348 } 349 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 350 return true; 351 } 352 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 353 return true; 354 } 355 } 356 357 return false; 358 } 359 360 361 static bool errata_182(void) 362 { 363 if (*(uint32_t *)0x10000130ul == 0x6ul){ 364 if (*(uint32_t *)0x10000134ul == 0x6ul){ 365 return true; 366 } 367 } 368 369 return false; 370 } 371 372 373 /*lint --flb "Leave library region" */ 374