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_nrf52840.h" 30 31 /*lint ++flb "Enter library region" */ 32 33 #define __SYSTEM_CLOCK_64M (64000000UL) 34 35 static bool errata_36(void); 36 static bool errata_66(void); 37 static bool errata_98(void); 38 static bool errata_103(void); 39 static bool errata_115(void); 40 static bool errata_120(void); 41 static bool errata_136(void); 42 43 44 #if defined ( __CC_ARM ) 45 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; 46 #elif defined ( __ICCARM__ ) 47 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; 48 #elif defined ( __GNUC__ ) 49 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; 50 #endif 51 SystemCoreClockUpdate(void)52void SystemCoreClockUpdate(void) 53 { 54 SystemCoreClock = __SYSTEM_CLOCK_64M; 55 } 56 SystemInit(void)57void SystemInit(void) 58 { 59 /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product 60 Specification to see which one). */ 61 #if defined (ENABLE_SWO) 62 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 63 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; 64 NRF_P1->PIN_CNF[0] = (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); 65 #endif 66 67 /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product 68 Specification to see which ones). */ 69 #if defined (ENABLE_TRACE) 70 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 71 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos; 72 NRF_P0->PIN_CNF[7] = (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 NRF_P1->PIN_CNF[0] = (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); 74 NRF_P0->PIN_CNF[12] = (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); 75 NRF_P0->PIN_CNF[11] = (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); 76 NRF_P1->PIN_CNF[9] = (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 #endif 78 79 /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document 80 for your device located at https://infocenter.nordicsemi.com/ */ 81 if (errata_36()){ 82 NRF_CLOCK->EVENTS_DONE = 0; 83 NRF_CLOCK->EVENTS_CTTO = 0; 84 NRF_CLOCK->CTIV = 0; 85 } 86 87 /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document 88 for your device located at https://infocenter.nordicsemi.com/ */ 89 if (errata_66()){ 90 NRF_TEMP->A0 = NRF_FICR->TEMP.A0; 91 NRF_TEMP->A1 = NRF_FICR->TEMP.A1; 92 NRF_TEMP->A2 = NRF_FICR->TEMP.A2; 93 NRF_TEMP->A3 = NRF_FICR->TEMP.A3; 94 NRF_TEMP->A4 = NRF_FICR->TEMP.A4; 95 NRF_TEMP->A5 = NRF_FICR->TEMP.A5; 96 NRF_TEMP->B0 = NRF_FICR->TEMP.B0; 97 NRF_TEMP->B1 = NRF_FICR->TEMP.B1; 98 NRF_TEMP->B2 = NRF_FICR->TEMP.B2; 99 NRF_TEMP->B3 = NRF_FICR->TEMP.B3; 100 NRF_TEMP->B4 = NRF_FICR->TEMP.B4; 101 NRF_TEMP->B5 = NRF_FICR->TEMP.B5; 102 NRF_TEMP->T0 = NRF_FICR->TEMP.T0; 103 NRF_TEMP->T1 = NRF_FICR->TEMP.T1; 104 NRF_TEMP->T2 = NRF_FICR->TEMP.T2; 105 NRF_TEMP->T3 = NRF_FICR->TEMP.T3; 106 NRF_TEMP->T4 = NRF_FICR->TEMP.T4; 107 } 108 109 /* Workaround for Errata 98 "NFCT: Not able to communicate with the peer" found at the Errata document 110 for your device located at https://infocenter.nordicsemi.com/ */ 111 if (errata_98()){ 112 *(volatile uint32_t *)0x4000568Cul = 0x00038148ul; 113 } 114 115 /* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document 116 for your device located at https://infocenter.nordicsemi.com/ */ 117 if (errata_103()){ 118 NRF_CCM->MAXPACKETSIZE = 0xFBul; 119 } 120 121 /* Workaround for Errata 115 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document 122 for your device located at https://infocenter.nordicsemi.com/ */ 123 if (errata_115()){ 124 *(volatile uint32_t *)0x40000EE4 = (*(volatile uint32_t *)0x40000EE4 & 0xFFFFFFF0) | (*(uint32_t *)0x10000258 & 0x0000000F); 125 } 126 127 /* Workaround for Errata 120 "QSPI: Data read or written is corrupted" found at the Errata document 128 for your device located at https://infocenter.nordicsemi.com/ */ 129 if (errata_120()){ 130 *(volatile uint32_t *)0x40029640ul = 0x200ul; 131 } 132 133 /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document 134 for your device located at https://infocenter.nordicsemi.com/ */ 135 if (errata_136()){ 136 if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){ 137 NRF_POWER->RESETREAS = ~POWER_RESETREAS_RESETPIN_Msk; 138 } 139 } 140 141 /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the 142 * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit 143 * operations are not used in your code. */ 144 #if (__FPU_USED == 1) 145 SCB->CPACR |= (3UL << 20) | (3UL << 22); 146 __DSB(); 147 __ISB(); 148 #endif 149 150 /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, 151 two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as 152 normal GPIOs. */ 153 #if defined (CONFIG_NFCT_PINS_AS_GPIOS) 154 if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ 155 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; 156 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 157 NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; 158 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 159 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; 160 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 161 NVIC_SystemReset(); 162 } 163 #endif 164 165 /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not 166 defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be 167 reserved for PinReset and not available as normal GPIO. */ 168 #if defined (CONFIG_GPIO_AS_PINRESET) 169 if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || 170 ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ 171 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; 172 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 173 NRF_UICR->PSELRESET[0] = 18; 174 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 175 NRF_UICR->PSELRESET[1] = 18; 176 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 177 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; 178 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 179 NVIC_SystemReset(); 180 } 181 #endif 182 183 SystemCoreClockUpdate(); 184 } 185 186 errata_36(void)187static bool errata_36(void) 188 { 189 if (*(uint32_t *)0x10000130ul == 0x8ul){ 190 if (*(uint32_t *)0x10000134ul == 0x0ul){ 191 return true; 192 } 193 if (*(uint32_t *)0x10000134ul == 0x1ul){ 194 return true; 195 } 196 if (*(uint32_t *)0x10000134ul == 0x2ul){ 197 return true; 198 } 199 if (*(uint32_t *)0x10000134ul == 0x3ul){ 200 return true; 201 } 202 } 203 204 return true; 205 } 206 207 errata_66(void)208static bool errata_66(void) 209 { 210 if (*(uint32_t *)0x10000130ul == 0x8ul){ 211 if (*(uint32_t *)0x10000134ul == 0x0ul){ 212 return true; 213 } 214 if (*(uint32_t *)0x10000134ul == 0x1ul){ 215 return true; 216 } 217 if (*(uint32_t *)0x10000134ul == 0x2ul){ 218 return true; 219 } 220 if (*(uint32_t *)0x10000134ul == 0x3ul){ 221 return true; 222 } 223 } 224 225 return true; 226 } 227 228 errata_98(void)229static bool errata_98(void) 230 { 231 if (*(uint32_t *)0x10000130ul == 0x8ul){ 232 if (*(uint32_t *)0x10000134ul == 0x0ul){ 233 return true; 234 } 235 } 236 237 return false; 238 } 239 240 errata_103(void)241static bool errata_103(void) 242 { 243 if (*(uint32_t *)0x10000130ul == 0x8ul){ 244 if (*(uint32_t *)0x10000134ul == 0x0ul){ 245 return true; 246 } 247 } 248 249 return false; 250 } 251 252 errata_115(void)253static bool errata_115(void) 254 { 255 if (*(uint32_t *)0x10000130ul == 0x8ul){ 256 if (*(uint32_t *)0x10000134ul == 0x0ul){ 257 return true; 258 } 259 } 260 261 return false; 262 } 263 264 errata_120(void)265static bool errata_120(void) 266 { 267 if (*(uint32_t *)0x10000130ul == 0x8ul){ 268 if (*(uint32_t *)0x10000134ul == 0x0ul){ 269 return true; 270 } 271 } 272 273 return false; 274 } 275 276 errata_136(void)277static bool errata_136(void) 278 { 279 if (*(uint32_t *)0x10000130ul == 0x8ul){ 280 if (*(uint32_t *)0x10000134ul == 0x0ul){ 281 return true; 282 } 283 if (*(uint32_t *)0x10000134ul == 0x1ul){ 284 return true; 285 } 286 if (*(uint32_t *)0x10000134ul == 0x2ul){ 287 return true; 288 } 289 if (*(uint32_t *)0x10000134ul == 0x3ul){ 290 return true; 291 } 292 } 293 294 return true; 295 } 296 297 /*lint --flb "Leave library region" */ 298