1 /*
2
3 Copyright (c) 2009-2023 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_peripherals.h"
30 #include "nrf52_erratas.h"
31 #include "system_nrf52.h"
32 #include "system_nrf52_approtect.h"
33
34 #define __SYSTEM_CLOCK_DEFAULT (64000000UL)
35
36
37 #if defined ( __CC_ARM ) || defined ( __GNUC__ )
38 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_DEFAULT;
39 #elif defined ( __ICCARM__ )
40 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_DEFAULT;
41 #endif
42
43 /* Simplify later device detection macros. Check DEVELOP_IN first, as they take precedence. */
44 #if defined (DEVELOP_IN_NRF52805)
45 #define IS_NRF52805 1
46 #elif defined (DEVELOP_IN_NRF52810)
47 #define IS_NRF52810 1
48 #elif defined (DEVELOP_IN_NRF52811)
49 #define IS_NRF52811 1
50 #elif defined (DEVELOP_IN_NRF52820)
51 #define IS_NRF52820 1
52 #elif defined (DEVELOP_IN_NRF52832)
53 #define IS_NRF52832 1
54 #elif defined (DEVELOP_IN_NRF52833)
55 #define IS_NRF52833 1
56 #elif defined (DEVELOP_IN_NRF52840)
57 #define IS_NRF52840 1
58 #elif defined (NRF52805_XXAA)
59 #define IS_NRF52805 1
60 #elif defined (NRF52810_XXAA)
61 #define IS_NRF52810 1
62 #elif defined (NRF52811_XXAA)
63 #define IS_NRF52811 1
64 #elif defined (NRF52820_XXAA)
65 #define IS_NRF52820 1
66 #elif defined (NRF52832_XXAA) || defined (NRF52832_XXAB)
67 #define IS_NRF52832 1
68 #elif defined (NRF52833_XXAA)
69 #define IS_NRF52833 1
70 #elif defined (NRF52840_XXAA)
71 #define IS_NRF52840 1
72 #else
73 #error "A supported device macro must be defined."
74 #endif
75
76 /* Trace configuration */
77 #define TRACE_PIN_CONFIG ((GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) \
78 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
79 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos))
80
81 #if IS_NRF52832
82 #define TRACECLK_PIN_CNF NRF_P0->PIN_CNF[20]
83 #define TRACEDATA0_PIN_CNF NRF_P0->PIN_CNF[18]
84 #define TRACEDATA1_PIN_CNF NRF_P0->PIN_CNF[16]
85 #define TRACEDATA2_PIN_CNF NRF_P0->PIN_CNF[15]
86 #define TRACEDATA3_PIN_CNF NRF_P0->PIN_CNF[14]
87 #elif IS_NRF52833 || IS_NRF52840
88 #define TRACECLK_PIN_CNF NRF_P0->PIN_CNF[7]
89 #define TRACEDATA0_PIN_CNF NRF_P1->PIN_CNF[0]
90 #define TRACEDATA1_PIN_CNF NRF_P0->PIN_CNF[12]
91 #define TRACEDATA2_PIN_CNF NRF_P0->PIN_CNF[11]
92 #define TRACEDATA3_PIN_CNF NRF_P1->PIN_CNF[9]
93 #else
94 /* No trace supported */
95 #endif
96
97 /* Select correct reset pin */
98 /* Handle DEVELOP_IN-targets first as they take precedence over the later macros */
99 #if IS_NRF52805 || IS_NRF52810 || IS_NRF52811 || IS_NRF52832
100 #define RESET_PIN 21
101 #elif IS_NRF52820 || IS_NRF52833 || IS_NRF52840
102 #define RESET_PIN 18
103 #else
104 #error "A supported device macro must be defined."
105 #endif
106
107 /* -- NVMC utility functions -- */
108 /* Waits until NVMC is done with the current pending action */
nvmc_wait(void)109 void nvmc_wait(void)
110 {
111 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
112 }
113
114 /* Configure the NVMC to "mode".
115 Mode must be an enumerator of field NVMC_CONFIG_WEN */
nvmc_config(uint32_t mode)116 void nvmc_config(uint32_t mode)
117 {
118 NRF_NVMC->CONFIG = mode << NVMC_CONFIG_WEN_Pos;
119 nvmc_wait();
120 }
121
SystemCoreClockUpdate(void)122 void SystemCoreClockUpdate(void)
123 {
124 SystemCoreClock = __SYSTEM_CLOCK_DEFAULT;
125 }
126
SystemInit(void)127 void SystemInit(void)
128 {
129 /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
130 Specification to see which one). */
131 #if defined (ENABLE_SWO) && defined(CLOCK_TRACECONFIG_TRACEMUX_Pos)
132 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
133 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
134 TRACEDATA0_PIN_CNF = TRACE_PIN_CONFIG;
135 #endif
136
137 /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
138 Specification to see which ones). */
139 #if defined (ENABLE_TRACE) && defined(CLOCK_TRACECONFIG_TRACEMUX_Pos)
140 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
141 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
142 TRACECLK_PIN_CNF = TRACE_PIN_CONFIG;
143 TRACEDATA0_PIN_CNF = TRACE_PIN_CONFIG;
144 TRACEDATA1_PIN_CNF = TRACE_PIN_CONFIG;
145 TRACEDATA2_PIN_CNF = TRACE_PIN_CONFIG;
146 TRACEDATA3_PIN_CNF = TRACE_PIN_CONFIG;
147 #endif
148
149 #if NRF52_ERRATA_12_ENABLE_WORKAROUND
150 /* Workaround for Errata 12 "COMP: Reference ladder not correctly calibrated" found at the Errata document
151 for your device located at https://infocenter.nordicsemi.com/index.jsp */
152 if (nrf52_errata_12()){
153 *(volatile uint32_t *)0x40013540 = (*(uint32_t *)0x10000324 & 0x00001F00) >> 8;
154 }
155 #endif
156
157 #if NRF52_ERRATA_16_ENABLE_WORKAROUND
158 /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document
159 for your device located at https://infocenter.nordicsemi.com/index.jsp */
160 if (nrf52_errata_16()){
161 *(volatile uint32_t *)0x4007C074 = 3131961357ul;
162 }
163 #endif
164
165 #if NRF52_ERRATA_31_ENABLE_WORKAROUND
166 /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document
167 for your device located at https://infocenter.nordicsemi.com/index.jsp */
168 if (nrf52_errata_31()){
169 *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13;
170 }
171 #endif
172
173 #if NRF52_ERRATA_32_ENABLE_WORKAROUND
174 /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document
175 for your device located at https://infocenter.nordicsemi.com/index.jsp */
176 if (nrf52_errata_32()){
177 CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
178 }
179 #endif
180
181 #if NRF52_ERRATA_36_ENABLE_WORKAROUND
182 /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
183 for your device located at https://infocenter.nordicsemi.com/index.jsp */
184 if (nrf52_errata_36()){
185 NRF_CLOCK->EVENTS_DONE = 0;
186 NRF_CLOCK->EVENTS_CTTO = 0;
187 NRF_CLOCK->CTIV = 0;
188 }
189 #endif
190
191 #if NRF52_ERRATA_37_ENABLE_WORKAROUND
192 /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document
193 for your device located at https://infocenter.nordicsemi.com/index.jsp */
194 if (nrf52_errata_37()){
195 *(volatile uint32_t *)0x400005A0 = 0x3;
196 }
197 #endif
198
199 #if NRF52_ERRATA_57_ENABLE_WORKAROUND
200 /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document
201 for your device located at https://infocenter.nordicsemi.com/index.jsp */
202 if (nrf52_errata_57()){
203 *(volatile uint32_t *)0x40005610 = 0x00000005;
204 *(volatile uint32_t *)0x40005688 = 0x00000001;
205 *(volatile uint32_t *)0x40005618 = 0x00000000;
206 *(volatile uint32_t *)0x40005614 = 0x0000003F;
207 }
208 #endif
209
210 #if NRF52_ERRATA_66_ENABLE_WORKAROUND
211 /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
212 for your device located at https://infocenter.nordicsemi.com/index.jsp */
213 if (nrf52_errata_66()){
214 NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
215 NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
216 NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
217 NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
218 NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
219 NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
220 NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
221 NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
222 NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
223 NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
224 NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
225 NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
226 NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
227 NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
228 NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
229 NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
230 NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
231 }
232 #endif
233
234 #if NRF52_ERRATA_98_ENABLE_WORKAROUND
235 /* Workaround for Errata 98 "NFCT: Not able to communicate with the peer" found at the Errata document
236 for your device located at https://infocenter.nordicsemi.com/index.jsp */
237 if (nrf52_errata_98()){
238 *(volatile uint32_t *)0x4000568Cul = 0x00038148ul;
239 }
240 #endif
241
242 #if NRF52_ERRATA_103_ENABLE_WORKAROUND && defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos)
243 /* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document
244 for your device located at https://infocenter.nordicsemi.com/index.jsp */
245 if (nrf52_errata_103()){
246 NRF_CCM->MAXPACKETSIZE = 0xFBul;
247 }
248 #endif
249
250 #if NRF52_ERRATA_108_ENABLE_WORKAROUND
251 /* 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
252 for your device located at https://infocenter.nordicsemi.com/index.jsp */
253 if (nrf52_errata_108()){
254 *(volatile uint32_t *)0x40000EE4ul = *(volatile uint32_t *)0x10000258ul & 0x0000004Ful;
255 }
256 #endif
257
258 #if NRF52_ERRATA_115_ENABLE_WORKAROUND
259 /* 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
260 for your device located at https://infocenter.nordicsemi.com/index.jsp */
261 if (nrf52_errata_115()){
262 *(volatile uint32_t *)0x40000EE4 = (*(volatile uint32_t *)0x40000EE4 & 0xFFFFFFF0) | (*(uint32_t *)0x10000258 & 0x0000000F);
263 }
264 #endif
265
266 #if NRF52_ERRATA_120_ENABLE_WORKAROUND
267 /* Workaround for Errata 120 "QSPI: Data read or written is corrupted" found at the Errata document
268 for your device located at https://infocenter.nordicsemi.com/index.jsp */
269 if (nrf52_errata_120()){
270 *(volatile uint32_t *)0x40029640ul = 0x200ul;
271 }
272 #endif
273
274 #if NRF52_ERRATA_136_ENABLE_WORKAROUND
275 /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
276 for your device located at https://infocenter.nordicsemi.com/index.jsp */
277 if (nrf52_errata_136()){
278 if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){
279 NRF_POWER->RESETREAS = ~POWER_RESETREAS_RESETPIN_Msk;
280 }
281 }
282 #endif
283
284 #if NRF52_ERRATA_182_ENABLE_WORKAROUND
285 /* Workaround for Errata 182 "RADIO: Fixes for anomalies #102, #106, and #107 do not take effect" found at the Errata document
286 for your device located at https://infocenter.nordicsemi.com/index.jsp */
287 if (nrf52_errata_182()){
288 *(volatile uint32_t *) 0x4000173C |= (0x1 << 10);
289 }
290 #endif
291
292 #if NRF52_ERRATA_217_ENABLE_WORKAROUND
293 /* Workaround for Errata 217 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document
294 for your device located at https://infocenter.nordicsemi.com/index.jsp */
295 if (nrf52_errata_217()){
296 *(volatile uint32_t *)0x40000EE4ul |= 0x0000000Ful;
297 }
298 #endif
299
300 /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
301 * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
302 * operations are not used in your code. */
303 #if (__FPU_USED == 1)
304 SCB->CPACR |= (3UL << 20) | (3UL << 22);
305 __DSB();
306 __ISB();
307 #endif
308
309 nrf52_handle_approtect();
310
311 #if NRF52_CONFIGURATION_249_ENABLE && (defined(NRF52805_XXAA) || defined(NRF52810_XXAA) || defined(NRF52811_XXAA))
312 if (nrf52_configuration_249() && (NRF_UICR->NRFMDK[0] == 0xFFFFFFFF || NRF_UICR->NRFMDK[1] == 0xFFFFFFFF))
313 {
314 nvmc_config(NVMC_CONFIG_WEN_Wen);
315 NRF_UICR->NRFMDK[0] = 0;
316 nvmc_wait();
317 NRF_UICR->NRFMDK[1] = 0;
318 nvmc_wait();
319 nvmc_config(NVMC_CONFIG_WEN_Ren);
320 }
321 #endif
322
323 /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
324 two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
325 normal GPIOs. */
326 #if defined (CONFIG_NFCT_PINS_AS_GPIOS) && defined(NFCT_PRESENT)
327 if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
328 nvmc_config(NVMC_CONFIG_WEN_Wen);
329 NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
330 nvmc_wait();
331 nvmc_config(NVMC_CONFIG_WEN_Ren);
332 NVIC_SystemReset();
333 }
334 #endif
335
336 /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
337 defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
338 reserved for PinReset and not available as normal GPIO. */
339 #if defined (CONFIG_GPIO_AS_PINRESET)
340 if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
341 ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
342 nvmc_config(NVMC_CONFIG_WEN_Wen);
343 NRF_UICR->PSELRESET[0] = RESET_PIN;
344 nvmc_wait();
345 NRF_UICR->PSELRESET[1] = RESET_PIN;
346 nvmc_wait();
347 nvmc_config(NVMC_CONFIG_WEN_Ren);
348 NVIC_SystemReset();
349 }
350 #endif
351
352 /* When developing for nRF52810 on an nRF52832, or nRF52811 on an nRF52840,
353 make sure NFC pins are mapped as GPIO. */
354 #if defined (DEVELOP_IN_NRF52832) && defined(NRF52810_XXAA) \
355 || defined (DEVELOP_IN_NRF52840) && defined(NRF52811_XXAA)
356 if ((*((uint32_t *)0x1000120C) & (1 << 0)) != 0){
357 nvmc_config(NVMC_CONFIG_WEN_Wen);
358 *((uint32_t *)0x1000120C) = 0;
359 nvmc_wait();
360 nvmc_config(NVMC_CONFIG_WEN_Ren);
361 NVIC_SystemReset();
362 }
363 #endif
364 }
365