xref: /nrf52832-nimble/nordic/nrfx/mdk/system_nrf52.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
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