xref: /nrf52832-nimble/nordic/nrfx/mdk/system_nrf52840.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1*150812a8SEvalZero /*
2*150812a8SEvalZero 
3*150812a8SEvalZero Copyright (c) 2009-2018 ARM Limited. All rights reserved.
4*150812a8SEvalZero 
5*150812a8SEvalZero     SPDX-License-Identifier: Apache-2.0
6*150812a8SEvalZero 
7*150812a8SEvalZero Licensed under the Apache License, Version 2.0 (the License); you may
8*150812a8SEvalZero not use this file except in compliance with the License.
9*150812a8SEvalZero You may obtain a copy of the License at
10*150812a8SEvalZero 
11*150812a8SEvalZero     www.apache.org/licenses/LICENSE-2.0
12*150812a8SEvalZero 
13*150812a8SEvalZero Unless required by applicable law or agreed to in writing, software
14*150812a8SEvalZero distributed under the License is distributed on an AS IS BASIS, WITHOUT
15*150812a8SEvalZero WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*150812a8SEvalZero See the License for the specific language governing permissions and
17*150812a8SEvalZero limitations under the License.
18*150812a8SEvalZero 
19*150812a8SEvalZero NOTICE: This file has been modified by Nordic Semiconductor ASA.
20*150812a8SEvalZero 
21*150812a8SEvalZero */
22*150812a8SEvalZero 
23*150812a8SEvalZero /* NOTE: Template files (including this one) are application specific and therefore expected to
24*150812a8SEvalZero    be copied into the application project folder prior to its use! */
25*150812a8SEvalZero 
26*150812a8SEvalZero #include <stdint.h>
27*150812a8SEvalZero #include <stdbool.h>
28*150812a8SEvalZero #include "nrf.h"
29*150812a8SEvalZero #include "system_nrf52840.h"
30*150812a8SEvalZero 
31*150812a8SEvalZero /*lint ++flb "Enter library region" */
32*150812a8SEvalZero 
33*150812a8SEvalZero #define __SYSTEM_CLOCK_64M      (64000000UL)
34*150812a8SEvalZero 
35*150812a8SEvalZero static bool errata_36(void);
36*150812a8SEvalZero static bool errata_66(void);
37*150812a8SEvalZero static bool errata_98(void);
38*150812a8SEvalZero static bool errata_103(void);
39*150812a8SEvalZero static bool errata_115(void);
40*150812a8SEvalZero static bool errata_120(void);
41*150812a8SEvalZero static bool errata_136(void);
42*150812a8SEvalZero 
43*150812a8SEvalZero 
44*150812a8SEvalZero #if defined ( __CC_ARM )
45*150812a8SEvalZero     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
46*150812a8SEvalZero #elif defined ( __ICCARM__ )
47*150812a8SEvalZero     __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
48*150812a8SEvalZero #elif defined ( __GNUC__ )
49*150812a8SEvalZero     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
50*150812a8SEvalZero #endif
51*150812a8SEvalZero 
SystemCoreClockUpdate(void)52*150812a8SEvalZero void SystemCoreClockUpdate(void)
53*150812a8SEvalZero {
54*150812a8SEvalZero     SystemCoreClock = __SYSTEM_CLOCK_64M;
55*150812a8SEvalZero }
56*150812a8SEvalZero 
SystemInit(void)57*150812a8SEvalZero void SystemInit(void)
58*150812a8SEvalZero {
59*150812a8SEvalZero     /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
60*150812a8SEvalZero        Specification to see which one). */
61*150812a8SEvalZero     #if defined (ENABLE_SWO)
62*150812a8SEvalZero         CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
63*150812a8SEvalZero         NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
64*150812a8SEvalZero         NRF_P1->PIN_CNF[0] = (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);
65*150812a8SEvalZero     #endif
66*150812a8SEvalZero 
67*150812a8SEvalZero     /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
68*150812a8SEvalZero        Specification to see which ones). */
69*150812a8SEvalZero     #if defined (ENABLE_TRACE)
70*150812a8SEvalZero         CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
71*150812a8SEvalZero         NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
72*150812a8SEvalZero         NRF_P0->PIN_CNF[7]  = (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*150812a8SEvalZero         NRF_P1->PIN_CNF[0]  = (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);
74*150812a8SEvalZero         NRF_P0->PIN_CNF[12] = (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);
75*150812a8SEvalZero         NRF_P0->PIN_CNF[11] = (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);
76*150812a8SEvalZero         NRF_P1->PIN_CNF[9]  = (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*150812a8SEvalZero     #endif
78*150812a8SEvalZero 
79*150812a8SEvalZero     /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
80*150812a8SEvalZero        for your device located at https://infocenter.nordicsemi.com/  */
81*150812a8SEvalZero     if (errata_36()){
82*150812a8SEvalZero         NRF_CLOCK->EVENTS_DONE = 0;
83*150812a8SEvalZero         NRF_CLOCK->EVENTS_CTTO = 0;
84*150812a8SEvalZero         NRF_CLOCK->CTIV = 0;
85*150812a8SEvalZero     }
86*150812a8SEvalZero 
87*150812a8SEvalZero     /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
88*150812a8SEvalZero        for your device located at https://infocenter.nordicsemi.com/  */
89*150812a8SEvalZero     if (errata_66()){
90*150812a8SEvalZero         NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
91*150812a8SEvalZero         NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
92*150812a8SEvalZero         NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
93*150812a8SEvalZero         NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
94*150812a8SEvalZero         NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
95*150812a8SEvalZero         NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
96*150812a8SEvalZero         NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
97*150812a8SEvalZero         NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
98*150812a8SEvalZero         NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
99*150812a8SEvalZero         NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
100*150812a8SEvalZero         NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
101*150812a8SEvalZero         NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
102*150812a8SEvalZero         NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
103*150812a8SEvalZero         NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
104*150812a8SEvalZero         NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
105*150812a8SEvalZero         NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
106*150812a8SEvalZero         NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
107*150812a8SEvalZero     }
108*150812a8SEvalZero 
109*150812a8SEvalZero     /* Workaround for Errata 98 "NFCT: Not able to communicate with the peer" found at the Errata document
110*150812a8SEvalZero        for your device located at https://infocenter.nordicsemi.com/  */
111*150812a8SEvalZero     if (errata_98()){
112*150812a8SEvalZero         *(volatile uint32_t *)0x4000568Cul = 0x00038148ul;
113*150812a8SEvalZero     }
114*150812a8SEvalZero 
115*150812a8SEvalZero     /* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document
116*150812a8SEvalZero        for your device located at https://infocenter.nordicsemi.com/  */
117*150812a8SEvalZero     if (errata_103()){
118*150812a8SEvalZero         NRF_CCM->MAXPACKETSIZE = 0xFBul;
119*150812a8SEvalZero     }
120*150812a8SEvalZero 
121*150812a8SEvalZero     /* Workaround for Errata 115 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document
122*150812a8SEvalZero        for your device located at https://infocenter.nordicsemi.com/  */
123*150812a8SEvalZero     if (errata_115()){
124*150812a8SEvalZero         *(volatile uint32_t *)0x40000EE4 = (*(volatile uint32_t *)0x40000EE4 & 0xFFFFFFF0) | (*(uint32_t *)0x10000258 & 0x0000000F);
125*150812a8SEvalZero     }
126*150812a8SEvalZero 
127*150812a8SEvalZero     /* Workaround for Errata 120 "QSPI: Data read or written is corrupted" found at the Errata document
128*150812a8SEvalZero        for your device located at https://infocenter.nordicsemi.com/  */
129*150812a8SEvalZero     if (errata_120()){
130*150812a8SEvalZero         *(volatile uint32_t *)0x40029640ul = 0x200ul;
131*150812a8SEvalZero     }
132*150812a8SEvalZero 
133*150812a8SEvalZero     /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
134*150812a8SEvalZero        for your device located at https://infocenter.nordicsemi.com/  */
135*150812a8SEvalZero     if (errata_136()){
136*150812a8SEvalZero         if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){
137*150812a8SEvalZero             NRF_POWER->RESETREAS =  ~POWER_RESETREAS_RESETPIN_Msk;
138*150812a8SEvalZero         }
139*150812a8SEvalZero     }
140*150812a8SEvalZero 
141*150812a8SEvalZero     /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
142*150812a8SEvalZero      * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
143*150812a8SEvalZero      * operations are not used in your code. */
144*150812a8SEvalZero     #if (__FPU_USED == 1)
145*150812a8SEvalZero         SCB->CPACR |= (3UL << 20) | (3UL << 22);
146*150812a8SEvalZero         __DSB();
147*150812a8SEvalZero         __ISB();
148*150812a8SEvalZero     #endif
149*150812a8SEvalZero 
150*150812a8SEvalZero     /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
151*150812a8SEvalZero        two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
152*150812a8SEvalZero        normal GPIOs. */
153*150812a8SEvalZero     #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
154*150812a8SEvalZero         if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
155*150812a8SEvalZero             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
156*150812a8SEvalZero             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
157*150812a8SEvalZero             NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
158*150812a8SEvalZero             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
159*150812a8SEvalZero             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
160*150812a8SEvalZero             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
161*150812a8SEvalZero             NVIC_SystemReset();
162*150812a8SEvalZero         }
163*150812a8SEvalZero     #endif
164*150812a8SEvalZero 
165*150812a8SEvalZero     /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
166*150812a8SEvalZero       defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
167*150812a8SEvalZero       reserved for PinReset and not available as normal GPIO. */
168*150812a8SEvalZero     #if defined (CONFIG_GPIO_AS_PINRESET)
169*150812a8SEvalZero         if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
170*150812a8SEvalZero             ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
171*150812a8SEvalZero             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
172*150812a8SEvalZero             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
173*150812a8SEvalZero             NRF_UICR->PSELRESET[0] = 18;
174*150812a8SEvalZero             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
175*150812a8SEvalZero             NRF_UICR->PSELRESET[1] = 18;
176*150812a8SEvalZero             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
177*150812a8SEvalZero             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
178*150812a8SEvalZero             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
179*150812a8SEvalZero             NVIC_SystemReset();
180*150812a8SEvalZero         }
181*150812a8SEvalZero     #endif
182*150812a8SEvalZero 
183*150812a8SEvalZero     SystemCoreClockUpdate();
184*150812a8SEvalZero }
185*150812a8SEvalZero 
186*150812a8SEvalZero 
errata_36(void)187*150812a8SEvalZero static bool errata_36(void)
188*150812a8SEvalZero {
189*150812a8SEvalZero     if (*(uint32_t *)0x10000130ul == 0x8ul){
190*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x0ul){
191*150812a8SEvalZero             return true;
192*150812a8SEvalZero         }
193*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x1ul){
194*150812a8SEvalZero             return true;
195*150812a8SEvalZero         }
196*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x2ul){
197*150812a8SEvalZero             return true;
198*150812a8SEvalZero         }
199*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x3ul){
200*150812a8SEvalZero             return true;
201*150812a8SEvalZero         }
202*150812a8SEvalZero     }
203*150812a8SEvalZero 
204*150812a8SEvalZero     return true;
205*150812a8SEvalZero }
206*150812a8SEvalZero 
207*150812a8SEvalZero 
errata_66(void)208*150812a8SEvalZero static bool errata_66(void)
209*150812a8SEvalZero {
210*150812a8SEvalZero     if (*(uint32_t *)0x10000130ul == 0x8ul){
211*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x0ul){
212*150812a8SEvalZero             return true;
213*150812a8SEvalZero         }
214*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x1ul){
215*150812a8SEvalZero             return true;
216*150812a8SEvalZero         }
217*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x2ul){
218*150812a8SEvalZero             return true;
219*150812a8SEvalZero         }
220*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x3ul){
221*150812a8SEvalZero             return true;
222*150812a8SEvalZero         }
223*150812a8SEvalZero     }
224*150812a8SEvalZero 
225*150812a8SEvalZero     return true;
226*150812a8SEvalZero }
227*150812a8SEvalZero 
228*150812a8SEvalZero 
errata_98(void)229*150812a8SEvalZero static bool errata_98(void)
230*150812a8SEvalZero {
231*150812a8SEvalZero     if (*(uint32_t *)0x10000130ul == 0x8ul){
232*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x0ul){
233*150812a8SEvalZero             return true;
234*150812a8SEvalZero         }
235*150812a8SEvalZero     }
236*150812a8SEvalZero 
237*150812a8SEvalZero     return false;
238*150812a8SEvalZero }
239*150812a8SEvalZero 
240*150812a8SEvalZero 
errata_103(void)241*150812a8SEvalZero static bool errata_103(void)
242*150812a8SEvalZero {
243*150812a8SEvalZero     if (*(uint32_t *)0x10000130ul == 0x8ul){
244*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x0ul){
245*150812a8SEvalZero             return true;
246*150812a8SEvalZero         }
247*150812a8SEvalZero     }
248*150812a8SEvalZero 
249*150812a8SEvalZero     return false;
250*150812a8SEvalZero }
251*150812a8SEvalZero 
252*150812a8SEvalZero 
errata_115(void)253*150812a8SEvalZero static bool errata_115(void)
254*150812a8SEvalZero {
255*150812a8SEvalZero     if (*(uint32_t *)0x10000130ul == 0x8ul){
256*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x0ul){
257*150812a8SEvalZero             return true;
258*150812a8SEvalZero         }
259*150812a8SEvalZero     }
260*150812a8SEvalZero 
261*150812a8SEvalZero     return false;
262*150812a8SEvalZero }
263*150812a8SEvalZero 
264*150812a8SEvalZero 
errata_120(void)265*150812a8SEvalZero static bool errata_120(void)
266*150812a8SEvalZero {
267*150812a8SEvalZero     if (*(uint32_t *)0x10000130ul == 0x8ul){
268*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x0ul){
269*150812a8SEvalZero             return true;
270*150812a8SEvalZero         }
271*150812a8SEvalZero     }
272*150812a8SEvalZero 
273*150812a8SEvalZero     return false;
274*150812a8SEvalZero }
275*150812a8SEvalZero 
276*150812a8SEvalZero 
errata_136(void)277*150812a8SEvalZero static bool errata_136(void)
278*150812a8SEvalZero {
279*150812a8SEvalZero     if (*(uint32_t *)0x10000130ul == 0x8ul){
280*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x0ul){
281*150812a8SEvalZero             return true;
282*150812a8SEvalZero         }
283*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x1ul){
284*150812a8SEvalZero             return true;
285*150812a8SEvalZero         }
286*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x2ul){
287*150812a8SEvalZero             return true;
288*150812a8SEvalZero         }
289*150812a8SEvalZero         if (*(uint32_t *)0x10000134ul == 0x3ul){
290*150812a8SEvalZero             return true;
291*150812a8SEvalZero         }
292*150812a8SEvalZero     }
293*150812a8SEvalZero 
294*150812a8SEvalZero     return true;
295*150812a8SEvalZero }
296*150812a8SEvalZero 
297*150812a8SEvalZero /*lint --flb "Leave library region" */
298