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_nrf52810.h" 30 31 /*lint ++flb "Enter library region" */ 32 33 #define __SYSTEM_CLOCK_64M (64000000UL) 34 35 static bool errata_31(void); 36 static bool errata_36(void); 37 static bool errata_66(void); 38 static bool errata_103(void); 39 static bool errata_136(void); 40 41 /* Helper functions for Errata workarounds in nRF52832 */ 42 #if defined (DEVELOP_IN_NRF52832) 43 static bool errata_12(void); 44 static bool errata_16(void); 45 static bool errata_32(void); 46 static bool errata_37(void); 47 static bool errata_57(void); 48 static bool errata_108(void); 49 static bool errata_182(void); 50 #endif 51 52 #if defined ( __CC_ARM ) 53 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; 54 #elif defined ( __ICCARM__ ) 55 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; 56 #elif defined ( __GNUC__ ) 57 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; 58 #endif 59 SystemCoreClockUpdate(void)60void SystemCoreClockUpdate(void) 61 { 62 SystemCoreClock = __SYSTEM_CLOCK_64M; 63 } 64 SystemInit(void)65void SystemInit(void) 66 { 67 /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product 68 Specification to see which one). Only available if the developing environment is an nRF52832 device. */ 69 #if defined (DEVELOP_IN_NRF52832) && defined (ENABLE_SWO) 70 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 71 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; 72 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); 73 #endif 74 75 /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product 76 Specification to see which ones). Only available if the developing environment is an nRF52832 device. */ 77 #if defined (DEVELOP_IN_NRF52832) && defined (ENABLE_TRACE) 78 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 79 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos; 80 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); 81 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); 82 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); 83 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); 84 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); 85 #endif 86 87 #if defined (DEVELOP_IN_NRF52832) 88 /* Workaround for Errata 12 "COMP: Reference ladder not correctly calibrated" found at the Errata document 89 for nRF52832 device located at https://infocenter.nordicsemi.com/ */ 90 if (errata_12()){ 91 *(volatile uint32_t *)0x40013540 = (*(uint32_t *)0x10000324 & 0x00001F00) >> 8; 92 } 93 #endif 94 95 #if defined (DEVELOP_IN_NRF52832) 96 /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document 97 for nRF52832 device located at https://infocenter.nordicsemi.com/ */ 98 if (errata_16()){ 99 *(volatile uint32_t *)0x4007C074 = 3131961357ul; 100 } 101 #endif 102 103 /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document 104 for your device located at https://infocenter.nordicsemi.com/ */ 105 if (errata_31()){ 106 *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13; 107 } 108 109 #if defined (DEVELOP_IN_NRF52832) 110 /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document 111 for nRF52832 device located at https://infocenter.nordicsemi.com/ */ 112 if (errata_32()){ 113 CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; 114 } 115 #endif 116 117 /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document 118 for your device located at https://infocenter.nordicsemi.com/ */ 119 if (errata_36()){ 120 NRF_CLOCK->EVENTS_DONE = 0; 121 NRF_CLOCK->EVENTS_CTTO = 0; 122 NRF_CLOCK->CTIV = 0; 123 } 124 125 #if defined (DEVELOP_IN_NRF52832) 126 /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document 127 for your device located at https://infocenter.nordicsemi.com/ */ 128 if (errata_37()){ 129 *(volatile uint32_t *)0x400005A0 = 0x3; 130 } 131 #endif 132 133 #if defined (DEVELOP_IN_NRF52832) 134 /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document 135 for your device located at https://infocenter.nordicsemi.com/ */ 136 if (errata_57()){ 137 *(volatile uint32_t *)0x40005610 = 0x00000005; 138 *(volatile uint32_t *)0x40005688 = 0x00000001; 139 *(volatile uint32_t *)0x40005618 = 0x00000000; 140 *(volatile uint32_t *)0x40005614 = 0x0000003F; 141 } 142 #endif 143 144 /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document 145 for your device located at https://infocenter.nordicsemi.com/ */ 146 if (errata_66()){ 147 NRF_TEMP->A0 = NRF_FICR->TEMP.A0; 148 NRF_TEMP->A1 = NRF_FICR->TEMP.A1; 149 NRF_TEMP->A2 = NRF_FICR->TEMP.A2; 150 NRF_TEMP->A3 = NRF_FICR->TEMP.A3; 151 NRF_TEMP->A4 = NRF_FICR->TEMP.A4; 152 NRF_TEMP->A5 = NRF_FICR->TEMP.A5; 153 NRF_TEMP->B0 = NRF_FICR->TEMP.B0; 154 NRF_TEMP->B1 = NRF_FICR->TEMP.B1; 155 NRF_TEMP->B2 = NRF_FICR->TEMP.B2; 156 NRF_TEMP->B3 = NRF_FICR->TEMP.B3; 157 NRF_TEMP->B4 = NRF_FICR->TEMP.B4; 158 NRF_TEMP->B5 = NRF_FICR->TEMP.B5; 159 NRF_TEMP->T0 = NRF_FICR->TEMP.T0; 160 NRF_TEMP->T1 = NRF_FICR->TEMP.T1; 161 NRF_TEMP->T2 = NRF_FICR->TEMP.T2; 162 NRF_TEMP->T3 = NRF_FICR->TEMP.T3; 163 NRF_TEMP->T4 = NRF_FICR->TEMP.T4; 164 } 165 166 /* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document 167 for your device located at https://infocenter.nordicsemi.com/ */ 168 if (errata_103()){ 169 NRF_CCM->MAXPACKETSIZE = 0xFBul; 170 } 171 172 #if defined (DEVELOP_IN_NRF52832) 173 /* 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 174 for your device located at https://infocenter.nordicsemi.com/ */ 175 if (errata_108()){ 176 *(volatile uint32_t *)0x40000EE4 = *(volatile uint32_t *)0x10000258 & 0x0000004F; 177 } 178 #endif 179 180 /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document 181 for your device located at https://infocenter.nordicsemi.com/ */ 182 if (errata_136()){ 183 if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){ 184 NRF_POWER->RESETREAS = ~POWER_RESETREAS_RESETPIN_Msk; 185 } 186 } 187 188 #if defined (DEVELOP_IN_NRF52832) 189 /* Workaround for Errata 182 "RADIO: Fixes for anomalies #102, #106, and #107 do not take effect" found at the Errata document 190 for your device located at https://infocenter.nordicsemi.com/ */ 191 if (errata_182()){ 192 *(volatile uint32_t *) 0x4000173C |= (0x1 << 10); 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 #if defined (DEVELOP_IN_NRF52832) errata_12(void)218static 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 #endif 235 236 #if defined (DEVELOP_IN_NRF52832) errata_16(void)237static bool errata_16(void) 238 { 239 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 240 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 241 return true; 242 } 243 } 244 245 return false; 246 } 247 #endif 248 errata_31(void)249static bool errata_31(void) 250 { 251 if ((*(uint32_t *)0x10000130ul == 0xAul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ 252 return true; 253 } 254 255 #if defined (DEVELOP_IN_NRF52832) 256 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 257 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 258 return true; 259 } 260 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 261 return true; 262 } 263 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 264 return true; 265 } 266 } 267 #endif 268 269 /* Fix should always apply. */ 270 return true; 271 } 272 273 #if defined (DEVELOP_IN_NRF52832) errata_32(void)274static bool errata_32(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 } 281 282 return false; 283 } 284 #endif 285 errata_36(void)286static bool errata_36(void) 287 { 288 if ((*(uint32_t *)0x10000130ul == 0xAul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ 289 return true; 290 } 291 292 #if defined (DEVELOP_IN_NRF52832) 293 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 294 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 295 return true; 296 } 297 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 298 return true; 299 } 300 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 301 return true; 302 } 303 } 304 #endif 305 306 /* Fix should always apply. */ 307 return true; 308 } 309 310 #if defined (DEVELOP_IN_NRF52832) errata_37(void)311static bool errata_37(void) 312 { 313 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 314 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 315 return true; 316 } 317 } 318 319 return false; 320 } 321 #endif 322 323 #if defined (DEVELOP_IN_NRF52832) errata_57(void)324static bool errata_57(void) 325 { 326 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 327 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 328 return true; 329 } 330 } 331 332 return false; 333 } 334 #endif 335 errata_66(void)336static bool errata_66(void) 337 { 338 if ((*(uint32_t *)0x10000130ul == 0xAul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ 339 return true; 340 } 341 342 #if defined (DEVELOP_IN_NRF52832) 343 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 344 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 345 return true; 346 } 347 } 348 #endif 349 350 /* Fix should always apply. */ 351 return true; 352 } 353 errata_103(void)354static bool errata_103(void) 355 { 356 if ((*(uint32_t *)0x10000130ul == 0xAul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ 357 return true; 358 } 359 360 /* Fix should always apply. */ 361 return true; 362 } 363 364 #if defined (DEVELOP_IN_NRF52832) errata_108(void)365static bool errata_108(void) 366 { 367 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 368 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 369 return true; 370 } 371 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 372 return true; 373 } 374 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 375 return true; 376 } 377 } 378 379 return false; 380 } 381 #endif 382 errata_136(void)383static bool errata_136(void) 384 { 385 if ((*(uint32_t *)0x10000130ul == 0xAul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ 386 return true; 387 } 388 389 #if defined (DEVELOP_IN_NRF52832) 390 if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ 391 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ 392 return true; 393 } 394 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ 395 return true; 396 } 397 if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ 398 return true; 399 } 400 } 401 #endif 402 403 /* Fix should always apply. */ 404 return true; 405 } 406 407 #if defined (DEVELOP_IN_NRF52832) errata_182(void)408static bool errata_182(void) 409 { 410 if (*(uint32_t *)0x10000130ul == 0x6ul){ 411 if (*(uint32_t *)0x10000134ul == 0x6ul){ 412 return true; 413 } 414 } 415 416 return false; 417 } 418 #endif 419 420 421 /*lint --flb "Leave library region" */ 422