xref: /nrf52832-nimble/nordic/nrfx/mdk/system_nrf52840.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_nrf52840.h"
30 
31 /*lint ++flb "Enter library region" */
32 
33 #define __SYSTEM_CLOCK_64M      (64000000UL)
34 
35 static bool errata_36(void);
36 static bool errata_66(void);
37 static bool errata_98(void);
38 static bool errata_103(void);
39 static bool errata_115(void);
40 static bool errata_120(void);
41 static bool errata_136(void);
42 
43 
44 #if defined ( __CC_ARM )
45     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
46 #elif defined ( __ICCARM__ )
47     __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
48 #elif defined ( __GNUC__ )
49     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
50 #endif
51 
SystemCoreClockUpdate(void)52 void SystemCoreClockUpdate(void)
53 {
54     SystemCoreClock = __SYSTEM_CLOCK_64M;
55 }
56 
SystemInit(void)57 void SystemInit(void)
58 {
59     /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
60        Specification to see which one). */
61     #if defined (ENABLE_SWO)
62         CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
63         NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
64         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     #endif
66 
67     /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
68        Specification to see which ones). */
69     #if defined (ENABLE_TRACE)
70         CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
71         NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
72         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         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         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         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         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     #endif
78 
79     /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
80        for your device located at https://infocenter.nordicsemi.com/  */
81     if (errata_36()){
82         NRF_CLOCK->EVENTS_DONE = 0;
83         NRF_CLOCK->EVENTS_CTTO = 0;
84         NRF_CLOCK->CTIV = 0;
85     }
86 
87     /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
88        for your device located at https://infocenter.nordicsemi.com/  */
89     if (errata_66()){
90         NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
91         NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
92         NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
93         NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
94         NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
95         NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
96         NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
97         NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
98         NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
99         NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
100         NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
101         NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
102         NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
103         NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
104         NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
105         NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
106         NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
107     }
108 
109     /* Workaround for Errata 98 "NFCT: Not able to communicate with the peer" found at the Errata document
110        for your device located at https://infocenter.nordicsemi.com/  */
111     if (errata_98()){
112         *(volatile uint32_t *)0x4000568Cul = 0x00038148ul;
113     }
114 
115     /* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document
116        for your device located at https://infocenter.nordicsemi.com/  */
117     if (errata_103()){
118         NRF_CCM->MAXPACKETSIZE = 0xFBul;
119     }
120 
121     /* 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        for your device located at https://infocenter.nordicsemi.com/  */
123     if (errata_115()){
124         *(volatile uint32_t *)0x40000EE4 = (*(volatile uint32_t *)0x40000EE4 & 0xFFFFFFF0) | (*(uint32_t *)0x10000258 & 0x0000000F);
125     }
126 
127     /* Workaround for Errata 120 "QSPI: Data read or written is corrupted" found at the Errata document
128        for your device located at https://infocenter.nordicsemi.com/  */
129     if (errata_120()){
130         *(volatile uint32_t *)0x40029640ul = 0x200ul;
131     }
132 
133     /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
134        for your device located at https://infocenter.nordicsemi.com/  */
135     if (errata_136()){
136         if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){
137             NRF_POWER->RESETREAS =  ~POWER_RESETREAS_RESETPIN_Msk;
138         }
139     }
140 
141     /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
142      * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
143      * operations are not used in your code. */
144     #if (__FPU_USED == 1)
145         SCB->CPACR |= (3UL << 20) | (3UL << 22);
146         __DSB();
147         __ISB();
148     #endif
149 
150     /* 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        two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
152        normal GPIOs. */
153     #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
154         if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
155             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
156             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
157             NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
158             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
159             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
160             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
161             NVIC_SystemReset();
162         }
163     #endif
164 
165     /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
166       defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
167       reserved for PinReset and not available as normal GPIO. */
168     #if defined (CONFIG_GPIO_AS_PINRESET)
169         if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
170             ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
171             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
172             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
173             NRF_UICR->PSELRESET[0] = 18;
174             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
175             NRF_UICR->PSELRESET[1] = 18;
176             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
177             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
178             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
179             NVIC_SystemReset();
180         }
181     #endif
182 
183     SystemCoreClockUpdate();
184 }
185 
186 
errata_36(void)187 static bool errata_36(void)
188 {
189     if (*(uint32_t *)0x10000130ul == 0x8ul){
190         if (*(uint32_t *)0x10000134ul == 0x0ul){
191             return true;
192         }
193         if (*(uint32_t *)0x10000134ul == 0x1ul){
194             return true;
195         }
196         if (*(uint32_t *)0x10000134ul == 0x2ul){
197             return true;
198         }
199         if (*(uint32_t *)0x10000134ul == 0x3ul){
200             return true;
201         }
202     }
203 
204     return true;
205 }
206 
207 
errata_66(void)208 static bool errata_66(void)
209 {
210     if (*(uint32_t *)0x10000130ul == 0x8ul){
211         if (*(uint32_t *)0x10000134ul == 0x0ul){
212             return true;
213         }
214         if (*(uint32_t *)0x10000134ul == 0x1ul){
215             return true;
216         }
217         if (*(uint32_t *)0x10000134ul == 0x2ul){
218             return true;
219         }
220         if (*(uint32_t *)0x10000134ul == 0x3ul){
221             return true;
222         }
223     }
224 
225     return true;
226 }
227 
228 
errata_98(void)229 static bool errata_98(void)
230 {
231     if (*(uint32_t *)0x10000130ul == 0x8ul){
232         if (*(uint32_t *)0x10000134ul == 0x0ul){
233             return true;
234         }
235     }
236 
237     return false;
238 }
239 
240 
errata_103(void)241 static bool errata_103(void)
242 {
243     if (*(uint32_t *)0x10000130ul == 0x8ul){
244         if (*(uint32_t *)0x10000134ul == 0x0ul){
245             return true;
246         }
247     }
248 
249     return false;
250 }
251 
252 
errata_115(void)253 static bool errata_115(void)
254 {
255     if (*(uint32_t *)0x10000130ul == 0x8ul){
256         if (*(uint32_t *)0x10000134ul == 0x0ul){
257             return true;
258         }
259     }
260 
261     return false;
262 }
263 
264 
errata_120(void)265 static bool errata_120(void)
266 {
267     if (*(uint32_t *)0x10000130ul == 0x8ul){
268         if (*(uint32_t *)0x10000134ul == 0x0ul){
269             return true;
270         }
271     }
272 
273     return false;
274 }
275 
276 
errata_136(void)277 static bool errata_136(void)
278 {
279     if (*(uint32_t *)0x10000130ul == 0x8ul){
280         if (*(uint32_t *)0x10000134ul == 0x0ul){
281             return true;
282         }
283         if (*(uint32_t *)0x10000134ul == 0x1ul){
284             return true;
285         }
286         if (*(uint32_t *)0x10000134ul == 0x2ul){
287             return true;
288         }
289         if (*(uint32_t *)0x10000134ul == 0x3ul){
290             return true;
291         }
292     }
293 
294     return true;
295 }
296 
297 /*lint --flb "Leave library region" */
298