xref: /nrf52832-nimble/nordic/nrfx/mdk/system_nrf52810.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_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)60 void SystemCoreClockUpdate(void)
61 {
62     SystemCoreClock = __SYSTEM_CLOCK_64M;
63 }
64 
SystemInit(void)65 void 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)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 #endif
235 
236 #if defined (DEVELOP_IN_NRF52832)
errata_16(void)237 static 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)249 static 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)274 static 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)286 static 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)311 static 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)324 static 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)336 static 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)354 static 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)365 static 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)383 static 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)408 static 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