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_nrf9160.h" 30 31 /*lint ++flb "Enter library region" */ 32 33 34 #define __SYSTEM_CLOCK (64000000UL) /*!< nRF9160 Application core uses a fixed System Clock Frequency of 64MHz */ 35 36 37 #if defined ( __CC_ARM ) 38 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; 39 #elif defined ( __ICCARM__ ) 40 __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; 41 #elif defined ( __GNUC__ ) 42 uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; 43 #endif 44 45 /* Errata are only handled in secure mode since they usually need access to FICR. */ 46 #if !defined(NRF_TRUSTZONE_NONSECURE) 47 static bool errata_6(void); 48 static bool errata_14(void); 49 static bool errata_15(void); 50 #endif 51 52 void SystemCoreClockUpdate(void) 53 { 54 SystemCoreClock = __SYSTEM_CLOCK; 55 } 56 57 void SystemInit(void) 58 { 59 #if !defined(NRF_TRUSTZONE_NONSECURE) 60 /* Perform Secure-mode initialization routines. */ 61 62 /* Set all ARM SAU regions to NonSecure if TrustZone extensions are enabled. 63 * Nordic SPU should handle Secure Attribution tasks */ 64 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) 65 SAU->CTRL |= (1 << SAU_CTRL_ALLNS_Pos); 66 #endif 67 68 /* Trimming of the device. Copy all the trimming values from FICR into the target addresses. Trim 69 until one ADDR is not initialized. */ 70 uint32_t index = 0; 71 for (index = 0; index < 256ul && NRF_FICR_S->TRIMCNF[index].ADDR != 0xFFFFFFFFul; index++){ 72 #if defined ( __ICCARM__ ) 73 #pragma diag_suppress=Pa082 74 #endif 75 *(volatile uint32_t *)NRF_FICR_S->TRIMCNF[index].ADDR = NRF_FICR_S->TRIMCNF[index].DATA; 76 #if defined ( __ICCARM__ ) 77 #pragma diag_default=Pa082 78 #endif 79 } 80 81 /* Make sure UICR->HFXOSRC is set */ 82 if ((NRF_UICR_S->HFXOSRC & UICR_HFXOSRC_HFXOSRC_Msk) != UICR_HFXOSRC_HFXOSRC_TCXO) { 83 /* Wait for pending NVMC operations to finish */ 84 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 85 86 /* Enable write mode in NVMC */ 87 NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Wen; 88 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 89 90 /* Write new value to UICR->HFXOSRC */ 91 NRF_UICR_S->HFXOSRC = (NRF_UICR_S->HFXOSRC & ~UICR_HFXOSRC_HFXOSRC_Msk) | UICR_HFXOSRC_HFXOSRC_TCXO; 92 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 93 94 /* Enable read mode in NVMC */ 95 NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Ren; 96 while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready); 97 98 /* Reset to apply clock select update */ 99 NVIC_SystemReset(); 100 } 101 102 if (errata_6()){ 103 NRF_POWER_S->EVENTS_SLEEPENTER = (POWER_EVENTS_SLEEPENTER_EVENTS_SLEEPENTER_NotGenerated << POWER_EVENTS_SLEEPENTER_EVENTS_SLEEPENTER_Pos); 104 NRF_POWER_S->EVENTS_SLEEPEXIT = (POWER_EVENTS_SLEEPEXIT_EVENTS_SLEEPEXIT_NotGenerated << POWER_EVENTS_SLEEPEXIT_EVENTS_SLEEPEXIT_Pos); 105 } 106 107 if (errata_14()){ 108 *(uint32_t *)0x50004A38 = 0x01ul; 109 NRF_REGULATORS_S->DCDCEN = REGULATORS_DCDCEN_DCDCEN_Enabled << REGULATORS_DCDCEN_DCDCEN_Pos; 110 } 111 112 if (errata_15()){ 113 *(uint32_t *)0x50004A38 = 0x00ul; 114 NRF_REGULATORS_S->DCDCEN = REGULATORS_DCDCEN_DCDCEN_Enabled << REGULATORS_DCDCEN_DCDCEN_Pos; 115 } 116 117 /* Allow Non-Secure code to run FPU instructions. 118 * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */ 119 SCB->NSACR |= (3UL << 10); 120 #endif 121 122 /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the 123 * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit 124 * operations are not used in your code. */ 125 #if (__FPU_USED == 1) 126 SCB->CPACR |= (3UL << 20) | (3UL << 22); 127 __DSB(); 128 __ISB(); 129 #endif 130 131 SystemCoreClockUpdate(); 132 } 133 134 135 #if !defined(NRF_TRUSTZONE_NONSECURE) 136 bool errata_6() 137 { 138 if (*(uint32_t *)0x00FF0130 == 0x9ul){ 139 if (*(uint32_t *)0x00FF0134 == 0x01ul){ 140 return true; 141 } 142 if (*(uint32_t *)0x00FF0134 == 0x02ul){ 143 return true; 144 } 145 } 146 147 return false; 148 } 149 150 151 bool errata_14() 152 { 153 if (*(uint32_t *)0x00FF0130 == 0x9ul){ 154 if (*(uint32_t *)0x00FF0134 == 0x01ul){ 155 return true; 156 } 157 } 158 159 return false; 160 } 161 162 163 bool errata_15() 164 { 165 if (*(uint32_t *)0x00FF0130 == 0x9ul){ 166 if (*(uint32_t *)0x00FF0134 == 0x02ul){ 167 return true; 168 } 169 } 170 171 return false; 172 } 173 #endif 174 175 /*lint --flb "Leave library region" */ 176