Contiki-NG
Loading...
Searching...
No Matches
system_nrf5340_application.c
1/*
2
3Copyright (c) 2009-2022 ARM Limited. All rights reserved.
4
5 SPDX-License-Identifier: Apache-2.0
6
7Licensed under the Apache License, Version 2.0 (the License); you may
8not use this file except in compliance with the License.
9You may obtain a copy of the License at
10
11 www.apache.org/licenses/LICENSE-2.0
12
13Unless required by applicable law or agreed to in writing, software
14distributed under the License is distributed on an AS IS BASIS, WITHOUT
15WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16See the License for the specific language governing permissions and
17limitations under the License.
18
19NOTICE: 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 "nrf53_erratas.h"
31#include "system_nrf53.h"
32#include "system_nrf53_approtect.h"
33
34/*lint ++flb "Enter library region" */
35
36void SystemStoreFICRNS();
37
38/* NRF5340 application core uses a variable System Clock Frequency that starts at 64MHz */
39#define __SYSTEM_CLOCK_MAX (128000000UL)
40#define __SYSTEM_CLOCK_INITIAL ( 64000000UL)
41
42#define TRACE_PIN_CNF_VALUE ( (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | \
43 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | \
44 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | \
45 (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | \
46 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) | \
47 (GPIO_PIN_CNF_MCUSEL_TND << GPIO_PIN_CNF_MCUSEL_Pos))
48
49#define TRACE_TRACECLK_PIN TAD_PSEL_TRACECLK_PIN_Traceclk
50#define TRACE_TRACEDATA0_PIN TAD_PSEL_TRACEDATA0_PIN_Tracedata0
51#define TRACE_TRACEDATA1_PIN TAD_PSEL_TRACEDATA1_PIN_Tracedata1
52#define TRACE_TRACEDATA2_PIN TAD_PSEL_TRACEDATA2_PIN_Tracedata2
53#define TRACE_TRACEDATA3_PIN TAD_PSEL_TRACEDATA3_PIN_Tracedata3
54
55#if defined ( __CC_ARM )
56 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_INITIAL;
57#elif defined ( __ICCARM__ )
58 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_INITIAL;
59#elif defined ( __GNUC__ )
60 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_INITIAL;
61#endif
62
63void SystemCoreClockUpdate(void)
64{
65#if defined(NRF_TRUSTZONE_NONSECURE)
66 SystemCoreClock = __SYSTEM_CLOCK_MAX >> (NRF_CLOCK_NS->HFCLKCTRL & (CLOCK_HFCLKCTRL_HCLK_Msk));
67#else
68 SystemCoreClock = __SYSTEM_CLOCK_MAX >> (NRF_CLOCK_S->HFCLKCTRL & (CLOCK_HFCLKCTRL_HCLK_Msk));
69#endif
70}
71
72void SystemInit(void)
73{
74 #if !defined(NRF_TRUSTZONE_NONSECURE)
75 /* Perform Secure-mode initialization routines. */
76
77 /* Set all ARM SAU regions to NonSecure if TrustZone extensions are enabled.
78 * Nordic SPU should handle Secure Attribution tasks */
79 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
80 SAU->CTRL |= (1 << SAU_CTRL_ALLNS_Pos);
81 #endif
82
83 /* Workaround for Errata 97 "ERASEPROTECT, APPROTECT, or startup problems" found at the Errata document
84 for your device located at https://infocenter.nordicsemi.com/index.jsp */
85 if (nrf53_errata_97())
86 {
87 if (*((volatile uint32_t *)0x50004A20ul) == 0)
88 {
89 *((volatile uint32_t *)0x50004A20ul) = 0xDul;
90 *((volatile uint32_t *)0x5000491Cul) = 0x1ul;
91 *((volatile uint32_t *)0x5000491Cul) = 0x0ul;
92 }
93 }
94
95 /* Trimming of the device. Copy all the trimming values from FICR into the target addresses. Trim
96 until one ADDR is not initialized. */
97 uint32_t index = 0;
98 /* TRIMCNF[].ADDR is uint32_t in nrfx >=3.x headers (was uint32_t* in 2.10). */
99 for (index = 0; index < 32ul && NRF_FICR_S->TRIMCNF[index].ADDR != 0xFFFFFFFFul; index++){
100 #if defined ( __ICCARM__ )
101 /* IAR will complain about the order of volatile pointer accesses. */
102 #pragma diag_suppress=Pa082
103 #endif
104 *((volatile uint32_t *)NRF_FICR_S->TRIMCNF[index].ADDR) = NRF_FICR_S->TRIMCNF[index].DATA;
105 #if defined ( __ICCARM__ )
106 #pragma diag_default=Pa082
107 #endif
108 }
109
110 /* errata 64 must be before errata 42, as errata 42 is dependant on the changes in errata 64*/
111 /* Workaround for Errata 64 "VREGMAIN has invalid configuration when CPU is running at 128 MHz" found at the Errata document
112 for your device located at https://infocenter.nordicsemi.com/index.jsp */
113 if (nrf53_errata_64())
114 {
115 *((volatile uint32_t *)0x5000470Cul) = 0x29ul;
116 *((volatile uint32_t *)0x5000473Cul) = 0x3ul;
117 }
118
119 /* Workaround for Errata 42 "Reset value of HFCLKCTRL is invalid" found at the Errata document
120 for your device located at https://infocenter.nordicsemi.com/index.jsp */
121 if (nrf53_errata_42())
122 {
123 *((volatile uint32_t *)0x50039530ul) = 0xBEEF0044ul;
124 NRF_CLOCK_S->HFCLKCTRL = CLOCK_HFCLKCTRL_HCLK_Div2 << CLOCK_HFCLKCTRL_HCLK_Pos;
125 }
126
127 /* Workaround for Errata 46 "Higher power consumption of LFRC" found at the Errata document
128 for your device located at https://infocenter.nordicsemi.com/index.jsp */
129 if (nrf53_errata_46())
130 {
131 *((volatile uint32_t *)0x5003254Cul) = 0;
132 }
133
134 /* Workaround for Errata 49 "SLEEPENTER and SLEEPEXIT events asserted after pin reset" found at the Errata document
135 for your device located at https://infocenter.nordicsemi.com/index.jsp */
136 if (nrf53_errata_49())
137 {
138 if (NRF_RESET_S->RESETREAS & RESET_RESETREAS_RESETPIN_Msk)
139 {
140 NRF_POWER_S->EVENTS_SLEEPENTER = 0;
141 NRF_POWER_S->EVENTS_SLEEPEXIT = 0;
142 }
143 }
144
145 /* Workaround for Errata 55 "Bits in RESETREAS are set when they should not be" found at the Errata document
146 for your device located at https://infocenter.nordicsemi.com/index.jsp */
147 if (nrf53_errata_55())
148 {
149 if (NRF_RESET_S->RESETREAS & RESET_RESETREAS_RESETPIN_Msk){
150 NRF_RESET_S->RESETREAS = ~RESET_RESETREAS_RESETPIN_Msk;
151 }
152 }
153
154 /* Workaround for Errata 69 "VREGMAIN configuration is not retained in System OFF" found at the Errata document
155 for your device located at https://infocenter.nordicsemi.com/index.jsp */
156 if (nrf53_errata_69())
157 {
158 *((volatile uint32_t *)0x5000470Cul) =0x65ul;
159 }
160
161 if (nrf53_errata_140())
162 {
163 if (*(volatile uint32_t *)0x50032420 & 0x80000000)
164 {
165 /* Reset occured during calibration */
166 NRF_CLOCK_S->LFCLKSRC = CLOCK_LFCLKSRC_SRC_LFSYNT;
167 NRF_CLOCK_S->TASKS_LFCLKSTART = 1;
168 while (NRF_CLOCK_S->EVENTS_LFCLKSTARTED == 0) {}
169 NRF_CLOCK_S->EVENTS_LFCLKSTARTED = 0;
170 NRF_CLOCK_S->TASKS_LFCLKSTOP = 1;
171 NRF_CLOCK_S->LFCLKSRC = CLOCK_LFCLKSRC_SRC_LFRC;
172 }
173 }
174
175 #if !defined(NRF_SKIP_FICR_NS_COPY_TO_RAM)
176 SystemStoreFICRNS();
177 #endif
178
179 #if defined(CONFIG_NFCT_PINS_AS_GPIOS)
180
181 if ((NRF_UICR_S->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos))
182 {
183 NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
184
185 while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy);
186 NRF_UICR_S->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
187
188 while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy);
189 NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
190
191 while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy);
192 NVIC_SystemReset();
193 }
194
195 #endif
196
197 /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
198 Specification to see which one). */
199 #if defined (ENABLE_SWO)
200 // Enable Trace And Debug peripheral
201 NRF_TAD_S->ENABLE = TAD_ENABLE_ENABLE_Msk;
202 NRF_TAD_S->CLOCKSTART = TAD_CLOCKSTART_START_Msk;
203
204 // Set up Trace pad SPU firewall
205 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA0_PIN);
206
207 // Configure trace port pad
208 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA0_PIN] = TRACE_PIN_CNF_VALUE;
209
210 // Select trace pin
211 NRF_TAD_S->PSEL.TRACEDATA0 = TRACE_TRACEDATA0_PIN;
212
213 // Set trace port speed to 64 MHz
214 NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_64MHz;
215 #endif
216
217 /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
218 Specification to see which ones). */
219 #if defined (ENABLE_TRACE)
220 // Enable Trace And Debug peripheral
221 NRF_TAD_S->ENABLE = TAD_ENABLE_ENABLE_Msk;
222 NRF_TAD_S->CLOCKSTART = TAD_CLOCKSTART_START_Msk;
223
224 // Set up Trace pads SPU firewall
225 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACECLK_PIN);
226 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA0_PIN);
227 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA1_PIN);
228 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA2_PIN);
229 NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA3_PIN);
230
231 // Configure trace port pads
232 NRF_P0_S->PIN_CNF[TRACE_TRACECLK_PIN] = TRACE_PIN_CNF_VALUE;
233 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA0_PIN] = TRACE_PIN_CNF_VALUE;
234 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA1_PIN] = TRACE_PIN_CNF_VALUE;
235 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA2_PIN] = TRACE_PIN_CNF_VALUE;
236 NRF_P0_S->PIN_CNF[TRACE_TRACEDATA3_PIN] = TRACE_PIN_CNF_VALUE;
237
238 // Select trace pins
239 NRF_TAD_S->PSEL.TRACECLK = TRACE_TRACECLK_PIN;
240 NRF_TAD_S->PSEL.TRACEDATA0 = TRACE_TRACEDATA0_PIN;
241 NRF_TAD_S->PSEL.TRACEDATA1 = TRACE_TRACEDATA1_PIN;
242 NRF_TAD_S->PSEL.TRACEDATA2 = TRACE_TRACEDATA2_PIN;
243 NRF_TAD_S->PSEL.TRACEDATA3 = TRACE_TRACEDATA3_PIN;
244
245 // Set trace port speed to 64 MHz
246 NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_64MHz;
247
248 #endif
249
250 /* Allow Non-Secure code to run FPU instructions.
251 * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */
252 SCB->NSACR |= (3UL << 10);
253
254 /* Handle fw-branch APPROTECT setup. */
255 nrf53_handle_approtect();
256
257 #endif
258
259 /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
260 * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
261 * operations are not used in your code. */
262 #if (__FPU_USED == 1)
263 SCB->CPACR |= (3UL << 20) | (3UL << 22);
264 __DSB();
265 __ISB();
266 #endif
267
268 SystemCoreClockUpdate();
269}
270
271/* Workaround to allow NS code to access FICR. Override NRF_FICR_NS to move FICR_NS buffer. */
272#define FICR_SIZE 0x1000ul
273#define RAM_BASE 0x20000000ul
274#define RAM_END 0x2FFFFFFFul
275
276/* Copy FICR_S to FICR_NS RAM region */
277void SystemStoreFICRNS()
278{
279 if ((uint32_t)NRF_FICR_NS < RAM_BASE || (uint32_t)NRF_FICR_NS + FICR_SIZE > RAM_END)
280 {
281 /* FICR_NS is not in RAM. */
282 return;
283 }
284 /* Copy FICR to NS-accessible RAM block. */
285 volatile uint32_t * from = (volatile uint32_t *)((uint32_t)NRF_FICR_S + (FICR_SIZE - sizeof(uint32_t)));
286 volatile uint32_t * to = (volatile uint32_t *)((uint32_t)NRF_FICR_NS + (FICR_SIZE - sizeof(uint32_t)));
287 volatile uint32_t * copy_from_end = (volatile uint32_t *)NRF_FICR_S;
288 while (from >= copy_from_end)
289 {
290 *(to--) = *(from--);
291 }
292
293 /* Make RAM region NS. */
294 uint32_t ram_region = ((uint32_t)NRF_FICR_NS - (uint32_t)RAM_BASE) / SPU_RAMREGION_SIZE;
295 NRF_SPU_S->RAMREGION[ram_region].PERM &= ~(1 << SPU_RAMREGION_PERM_SECATTR_Pos);
296}
297
298/* Block write and execute access to FICR RAM region */
299void SystemLockFICRNS()
300{
301 if ((uint32_t)NRF_FICR_NS < RAM_BASE || (uint32_t)NRF_FICR_NS + FICR_SIZE > RAM_END)
302 {
303 /* FICR_NS is not in RAM. */
304 return;
305 }
306
307 uint32_t ram_region = ((uint32_t)NRF_FICR_NS - (uint32_t)RAM_BASE) / SPU_RAMREGION_SIZE;
308 NRF_SPU_S->RAMREGION[ram_region].PERM &=
309 ~(
310 (1 << SPU_RAMREGION_PERM_WRITE_Pos) |
311 (1 << SPU_RAMREGION_PERM_EXECUTE_Pos)
312 );
313 NRF_SPU_S->RAMREGION[ram_region].PERM |= 1 << SPU_RAMREGION_PERM_LOCK_Pos;
314}
315
316/*lint --flb "Leave library region" */