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_nrf52833.h"
31 
32 /*lint ++flb "Enter library region" */
33 
34 #define __SYSTEM_CLOCK_64M      (64000000UL)
35 
36 #if defined ( __CC_ARM )
37     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
38 #elif defined ( __ICCARM__ )
39     __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
40 #elif defined ( __GNUC__ )
41     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
42 #endif
43 
SystemCoreClockUpdate(void)44 void SystemCoreClockUpdate(void)
45 {
46     SystemCoreClock = __SYSTEM_CLOCK_64M;
47 }
48 
SystemInit(void)49 void SystemInit(void)
50 {
51     /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
52        Specification to see which one). */
53     #if defined (ENABLE_SWO)
54         CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
55         NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
56         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);
57     #endif
58 
59     /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
60        Specification to see which ones). */
61     #if defined (ENABLE_TRACE)
62         CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
63         NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
64         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);
65         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);
66         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);
67         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);
68         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);
69     #endif
70 
71     /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
72        for your device located at https://infocenter.nordicsemi.com/index.jsp  */
73     if (nrf52_errata_36()){
74         NRF_CLOCK->EVENTS_DONE = 0;
75         NRF_CLOCK->EVENTS_CTTO = 0;
76         NRF_CLOCK->CTIV = 0;
77     }
78 
79     /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
80        for your device located at https://infocenter.nordicsemi.com/index.jsp  */
81     if (nrf52_errata_66()){
82         NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
83         NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
84         NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
85         NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
86         NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
87         NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
88         NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
89         NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
90         NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
91         NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
92         NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
93         NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
94         NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
95         NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
96         NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
97         NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
98         NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
99     }
100 
101     /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
102        for your device located at https://infocenter.nordicsemi.com/index.jsp  */
103     if (nrf52_errata_136()){
104         if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){
105             NRF_POWER->RESETREAS = ~POWER_RESETREAS_RESETPIN_Msk;
106         }
107     }
108 
109     /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
110      * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
111      * operations are not used in your code. */
112     #if (__FPU_USED == 1)
113         SCB->CPACR |= (3UL << 20) | (3UL << 22);
114         __DSB();
115         __ISB();
116     #endif
117 
118     /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
119        two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
120        normal GPIOs. */
121     #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
122         if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
123             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
124             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
125             NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
126             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
127             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
128             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
129             NVIC_SystemReset();
130         }
131     #endif
132 
133     /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
134       defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
135       reserved for PinReset and not available as normal GPIO. */
136     #if defined (CONFIG_GPIO_AS_PINRESET)
137         if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
138             ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
139             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
140             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
141             NRF_UICR->PSELRESET[0] = 18;
142             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
143             NRF_UICR->PSELRESET[1] = 18;
144             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
145             NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
146             while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
147             NVIC_SystemReset();
148         }
149     #endif
150 
151     SystemCoreClockUpdate();
152 }
153 
154 /*lint --flb "Leave library region" */
155