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)44void SystemCoreClockUpdate(void) 45 { 46 SystemCoreClock = __SYSTEM_CLOCK_64M; 47 } 48 SystemInit(void)49void 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