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
SystemCoreClockUpdate(void)56 void SystemCoreClockUpdate(void)
57 {
58 SystemCoreClock = __SYSTEM_CLOCK_64M;
59 }
60
SystemInit(void)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
errata_12(void)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
errata_16(void)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
errata_31(void)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
errata_32(void)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
errata_36(void)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
errata_37(void)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
errata_57(void)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
errata_66(void)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
errata_108(void)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
errata_136(void)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
errata_182(void)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