xref: /nrf52832-nimble/nordic/nrfx/mdk/system_nrf9160.c (revision 104654410c56c573564690304ae786df310c91fc)
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