1 /*
2
3 Copyright (c) 2009-2020 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_erratas.h"
30 #include "system_nrf52.h"
31
32 /*lint ++flb "Enter library region" */
33
34 #define __SYSTEM_CLOCK_64M (64000000UL)
35
36
37 #if defined ( __CC_ARM )
38 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
39 #elif defined ( __ICCARM__ )
40 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
41 #elif defined ( __GNUC__ )
42 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
43 #endif
44
SystemCoreClockUpdate(void)45 void SystemCoreClockUpdate(void)
46 {
47 SystemCoreClock = __SYSTEM_CLOCK_64M;
48 }
49
SystemInit(void)50 void SystemInit(void)
51 {
52 /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
53 Specification to see which one). */
54 #if defined (ENABLE_SWO)
55 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
56 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
57 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);
58 #endif
59
60 /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
61 Specification to see which ones). */
62 #if defined (ENABLE_TRACE)
63 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
64 NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
65 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);
66 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);
67 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);
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 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);
70 #endif
71
72 /* Workaround for Errata 12 "COMP: Reference ladder not correctly calibrated" found at the Errata document
73 for your device located at https://infocenter.nordicsemi.com/index.jsp */
74 if (nrf52_errata_12()){
75 *(volatile uint32_t *)0x40013540 = (*(uint32_t *)0x10000324 & 0x00001F00) >> 8;
76 }
77
78 /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document
79 for your device located at https://infocenter.nordicsemi.com/index.jsp */
80 if (nrf52_errata_16()){
81 *(volatile uint32_t *)0x4007C074 = 3131961357ul;
82 }
83
84 /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document
85 for your device located at https://infocenter.nordicsemi.com/index.jsp */
86 if (nrf52_errata_31()){
87 *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13;
88 }
89
90 /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document
91 for your device located at https://infocenter.nordicsemi.com/index.jsp */
92 if (nrf52_errata_32()){
93 CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
94 }
95
96 /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
97 for your device located at https://infocenter.nordicsemi.com/index.jsp */
98 if (nrf52_errata_36()){
99 NRF_CLOCK->EVENTS_DONE = 0;
100 NRF_CLOCK->EVENTS_CTTO = 0;
101 NRF_CLOCK->CTIV = 0;
102 }
103
104 /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document
105 for your device located at https://infocenter.nordicsemi.com/index.jsp */
106 if (nrf52_errata_37()){
107 *(volatile uint32_t *)0x400005A0 = 0x3;
108 }
109
110 /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document
111 for your device located at https://infocenter.nordicsemi.com/index.jsp */
112 if (nrf52_errata_57()){
113 *(volatile uint32_t *)0x40005610 = 0x00000005;
114 *(volatile uint32_t *)0x40005688 = 0x00000001;
115 *(volatile uint32_t *)0x40005618 = 0x00000000;
116 *(volatile uint32_t *)0x40005614 = 0x0000003F;
117 }
118
119 /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
120 for your device located at https://infocenter.nordicsemi.com/index.jsp */
121 if (nrf52_errata_66()){
122 NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
123 NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
124 NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
125 NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
126 NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
127 NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
128 NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
129 NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
130 NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
131 NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
132 NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
133 NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
134 NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
135 NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
136 NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
137 NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
138 NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
139 }
140
141 /* 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
142 for your device located at https://infocenter.nordicsemi.com/index.jsp */
143 if (nrf52_errata_108()){
144 *(volatile uint32_t *)0x40000EE4ul = *(volatile uint32_t *)0x10000258ul & 0x0000004Ful;
145 }
146
147 /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
148 for your device located at https://infocenter.nordicsemi.com/index.jsp */
149 if (nrf52_errata_136()){
150 if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){
151 NRF_POWER->RESETREAS = ~POWER_RESETREAS_RESETPIN_Msk;
152 }
153 }
154
155 /* Workaround for Errata 182 "RADIO: Fixes for anomalies #102, #106, and #107 do not take effect" found at the Errata document
156 for your device located at https://infocenter.nordicsemi.com/index.jsp */
157 if (nrf52_errata_182()){
158 *(volatile uint32_t *) 0x4000173C |= (0x1 << 10);
159 }
160
161 /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
162 * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
163 * operations are not used in your code. */
164 #if (__FPU_USED == 1)
165 SCB->CPACR |= (3UL << 20) | (3UL << 22);
166 __DSB();
167 __ISB();
168 #endif
169
170 /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
171 two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
172 normal GPIOs. */
173 #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
174 if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
175 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
176 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
177 NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
178 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
179 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
180 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
181 NVIC_SystemReset();
182 }
183 #endif
184
185 /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
186 defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
187 reserved for PinReset and not available as normal GPIO. */
188 #if defined (CONFIG_GPIO_AS_PINRESET)
189 if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
190 ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
191 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
192 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
193 NRF_UICR->PSELRESET[0] = 21;
194 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
195 NRF_UICR->PSELRESET[1] = 21;
196 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
197 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
198 while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
199 NVIC_SystemReset();
200 }
201 #endif
202
203 SystemCoreClockUpdate();
204 }
205
206
207 /*lint --flb "Leave library region" */
208