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_nrf5340_application.h"
31 
32 /*lint ++flb "Enter library region" */
33 
34 
35 /* NRF5340 application core uses a variable System Clock Frequency that starts at 64MHz */
36 #define __SYSTEM_CLOCK_MAX      (128000000UL)
37 #define __SYSTEM_CLOCK_INITIAL  ( 64000000UL)
38 
39 #define TRACE_PIN_CNF_VALUE (   (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | \
40                                 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | \
41                                 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | \
42                                 (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | \
43                                 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) | \
44                                 (GPIO_PIN_CNF_MCUSEL_TND << GPIO_PIN_CNF_MCUSEL_Pos))
45 
46 #define TRACE_TRACECLK_PIN   TAD_PSEL_TRACECLK_PIN_Traceclk
47 #define TRACE_TRACEDATA0_PIN TAD_PSEL_TRACEDATA0_PIN_Tracedata0
48 #define TRACE_TRACEDATA1_PIN TAD_PSEL_TRACEDATA1_PIN_Tracedata1
49 #define TRACE_TRACEDATA2_PIN TAD_PSEL_TRACEDATA2_PIN_Tracedata2
50 #define TRACE_TRACEDATA3_PIN TAD_PSEL_TRACEDATA3_PIN_Tracedata3
51 
52 #if defined ( __CC_ARM )
53     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_INITIAL;
54 #elif defined ( __ICCARM__ )
55     __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_INITIAL;
56 #elif defined   ( __GNUC__ )
57     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_INITIAL;
58 #endif
59 
SystemCoreClockUpdate(void)60 void SystemCoreClockUpdate(void)
61 {
62 #if defined(NRF_TRUSTZONE_NONSECURE)
63     SystemCoreClock = __SYSTEM_CLOCK_MAX >> (NRF_CLOCK_NS->HFCLKCTRL & (CLOCK_HFCLKCTRL_HCLK_Msk));
64 #else
65     SystemCoreClock = __SYSTEM_CLOCK_MAX >> (NRF_CLOCK_S->HFCLKCTRL & (CLOCK_HFCLKCTRL_HCLK_Msk));
66 #endif
67 }
68 
SystemInit(void)69 void SystemInit(void)
70 {
71     #if !defined(NRF_TRUSTZONE_NONSECURE)
72         /* Perform Secure-mode initialization routines. */
73 
74         /* Set all ARM SAU regions to NonSecure if TrustZone extensions are enabled.
75         * Nordic SPU should handle Secure Attribution tasks */
76         #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
77           SAU->CTRL |= (1 << SAU_CTRL_ALLNS_Pos);
78         #endif
79 
80         /* Workaround for Errata 97 "ERASEPROTECT, APPROTECT, or startup problems" found at the Errata document
81            for your device located at https://infocenter.nordicsemi.com/index.jsp  */
82         if (nrf53_errata_97())
83         {
84             if (*((volatile uint32_t *)0x50004A20ul) == 0)
85             {
86                 *((volatile uint32_t *)0x50004A20ul) = 0xDul;
87                 *((volatile uint32_t *)0x5000491Cul) = 0x1ul;
88                 *((volatile uint32_t *)0x5000491Cul) = 0x0ul;
89             }
90         }
91 
92         /* Trimming of the device. Copy all the trimming values from FICR into the target addresses. Trim
93          until one ADDR is not initialized. */
94         uint32_t index = 0;
95         for (index = 0; index < 32ul && NRF_FICR_S->TRIMCNF[index].ADDR != (uint32_t *)0xFFFFFFFFul; index++){
96             #if defined ( __ICCARM__ )
97                 /* IAR will complain about the order of volatile pointer accesses. */
98                 #pragma diag_suppress=Pa082
99             #endif
100             *NRF_FICR_S->TRIMCNF[index].ADDR = NRF_FICR_S->TRIMCNF[index].DATA;
101             #if defined ( __ICCARM__ )
102                 #pragma diag_default=Pa082
103             #endif
104         }
105 
106         /* errata 64 must be before errata 42, as errata 42 is dependant on the changes in errata 64*/
107         /* Workaround for Errata 64 "VREGMAIN has invalid configuration when CPU is running at 128 MHz" found at the Errata document
108            for your device located at https://infocenter.nordicsemi.com/index.jsp  */
109         if (nrf53_errata_64())
110         {
111             *((volatile uint32_t *)0x5000470Cul) = 0x29ul;
112             *((volatile uint32_t *)0x5000473Cul) = 0x3ul;
113         }
114 
115         /* Workaround for Errata 42 "Reset value of HFCLKCTRL is invalid" found at the Errata document
116            for your device located at https://infocenter.nordicsemi.com/index.jsp  */
117         if (nrf53_errata_42())
118         {
119             *((volatile uint32_t *)0x50039530ul) = 0xBEEF0044ul;
120             NRF_CLOCK_S->HFCLKCTRL = CLOCK_HFCLKCTRL_HCLK_Div2 << CLOCK_HFCLKCTRL_HCLK_Pos;
121         }
122 
123         /* Workaround for Errata 46 "Higher power consumption of LFRC" found at the Errata document
124            for your device located at https://infocenter.nordicsemi.com/index.jsp  */
125         if (nrf53_errata_46())
126         {
127             *((volatile uint32_t *)0x5003254Cul) = 0;
128         }
129 
130         /* Workaround for Errata 49 "SLEEPENTER and SLEEPEXIT events asserted after pin reset" found at the Errata document
131            for your device located at https://infocenter.nordicsemi.com/index.jsp  */
132         if (nrf53_errata_49())
133         {
134             if (NRF_RESET_S->RESETREAS & RESET_RESETREAS_RESETPIN_Msk)
135             {
136                 NRF_POWER_S->EVENTS_SLEEPENTER = 0;
137                 NRF_POWER_S->EVENTS_SLEEPEXIT = 0;
138             }
139         }
140 
141         /* Workaround for Errata 55 "Bits in RESETREAS are set when they should not be" found at the Errata document
142            for your device located at https://infocenter.nordicsemi.com/index.jsp  */
143         if (nrf53_errata_55())
144         {
145             if (NRF_RESET_S->RESETREAS & RESET_RESETREAS_RESETPIN_Msk){
146                 NRF_RESET_S->RESETREAS = ~RESET_RESETREAS_RESETPIN_Msk;
147             }
148         }
149 
150         /* Workaround for Errata 69 "VREGMAIN configuration is not retained in System OFF" found at the Errata document
151            for your device located at https://infocenter.nordicsemi.com/index.jsp  */
152         if (nrf53_errata_69())
153         {
154             *((volatile uint32_t *)0x5000470Cul) =0x65ul;
155         }
156 
157         #if defined(CONFIG_NFCT_PINS_AS_GPIOS)
158 
159             if ((NRF_UICR_S->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos))
160             {
161                 NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
162 
163                 while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy);
164                 NRF_UICR_S->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
165 
166                 while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy);
167                 NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
168 
169                 while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy);
170                 NVIC_SystemReset();
171             }
172 
173         #endif
174 
175         /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
176            Specification to see which one). */
177         #if defined (ENABLE_SWO)
178             // Enable Trace And Debug peripheral
179             NRF_TAD_S->ENABLE = TAD_ENABLE_ENABLE_Msk;
180             NRF_TAD_S->CLOCKSTART = TAD_CLOCKSTART_START_Msk;
181 
182             // Set up Trace pad SPU firewall
183             NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA0_PIN);
184 
185             // Configure trace port pad
186             NRF_P0_S->PIN_CNF[TRACE_TRACEDATA0_PIN] = TRACE_PIN_CNF_VALUE;
187 
188             // Select trace pin
189             NRF_TAD_S->PSEL.TRACEDATA0 = TRACE_TRACEDATA0_PIN;
190 
191             // Set trace port speed to 64 MHz
192             NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_64MHz;
193         #endif
194 
195         /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
196            Specification to see which ones). */
197         #if defined (ENABLE_TRACE)
198             // Enable Trace And Debug peripheral
199             NRF_TAD_S->ENABLE = TAD_ENABLE_ENABLE_Msk;
200             NRF_TAD_S->CLOCKSTART = TAD_CLOCKSTART_START_Msk;
201 
202             // Set up Trace pads SPU firewall
203             NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACECLK_PIN);
204             NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA0_PIN);
205             NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA1_PIN);
206             NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA2_PIN);
207             NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA3_PIN);
208 
209             // Configure trace port pads
210             NRF_P0_S->PIN_CNF[TRACE_TRACECLK_PIN] =   TRACE_PIN_CNF_VALUE;
211             NRF_P0_S->PIN_CNF[TRACE_TRACEDATA0_PIN] = TRACE_PIN_CNF_VALUE;
212             NRF_P0_S->PIN_CNF[TRACE_TRACEDATA1_PIN] = TRACE_PIN_CNF_VALUE;
213             NRF_P0_S->PIN_CNF[TRACE_TRACEDATA2_PIN] = TRACE_PIN_CNF_VALUE;
214             NRF_P0_S->PIN_CNF[TRACE_TRACEDATA3_PIN] = TRACE_PIN_CNF_VALUE;
215 
216             // Select trace pins
217             NRF_TAD_S->PSEL.TRACECLK   = TRACE_TRACECLK_PIN;
218             NRF_TAD_S->PSEL.TRACEDATA0 = TRACE_TRACEDATA0_PIN;
219             NRF_TAD_S->PSEL.TRACEDATA1 = TRACE_TRACEDATA1_PIN;
220             NRF_TAD_S->PSEL.TRACEDATA2 = TRACE_TRACEDATA2_PIN;
221             NRF_TAD_S->PSEL.TRACEDATA3 = TRACE_TRACEDATA3_PIN;
222 
223             // Set trace port speed to 64 MHz
224             NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_64MHz;
225 
226         #endif
227 
228         /* Allow Non-Secure code to run FPU instructions.
229          * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */
230         SCB->NSACR |= (3UL << 10);
231     #endif
232 
233     /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
234     * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
235     * operations are not used in your code. */
236     #if (__FPU_USED == 1)
237         SCB->CPACR |= (3UL << 20) | (3UL << 22);
238         __DSB();
239         __ISB();
240     #endif
241 
242     SystemCoreClockUpdate();
243 }
244 
245 /*lint --flb "Leave library region" */
246