xref: /nrf52832-nimble/nordic/nrfx/mdk/system_nrf9160.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1*150812a8SEvalZero /*
2*150812a8SEvalZero 
3*150812a8SEvalZero Copyright (c) 2009-2018 ARM Limited. All rights reserved.
4*150812a8SEvalZero 
5*150812a8SEvalZero     SPDX-License-Identifier: Apache-2.0
6*150812a8SEvalZero 
7*150812a8SEvalZero Licensed under the Apache License, Version 2.0 (the License); you may
8*150812a8SEvalZero not use this file except in compliance with the License.
9*150812a8SEvalZero You may obtain a copy of the License at
10*150812a8SEvalZero 
11*150812a8SEvalZero     www.apache.org/licenses/LICENSE-2.0
12*150812a8SEvalZero 
13*150812a8SEvalZero Unless required by applicable law or agreed to in writing, software
14*150812a8SEvalZero distributed under the License is distributed on an AS IS BASIS, WITHOUT
15*150812a8SEvalZero WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*150812a8SEvalZero See the License for the specific language governing permissions and
17*150812a8SEvalZero limitations under the License.
18*150812a8SEvalZero 
19*150812a8SEvalZero NOTICE: This file has been modified by Nordic Semiconductor ASA.
20*150812a8SEvalZero 
21*150812a8SEvalZero */
22*150812a8SEvalZero 
23*150812a8SEvalZero /* NOTE: Template files (including this one) are application specific and therefore expected to
24*150812a8SEvalZero    be copied into the application project folder prior to its use! */
25*150812a8SEvalZero 
26*150812a8SEvalZero #include <stdint.h>
27*150812a8SEvalZero #include <stdbool.h>
28*150812a8SEvalZero #include "nrf.h"
29*150812a8SEvalZero #include "system_nrf9160.h"
30*150812a8SEvalZero 
31*150812a8SEvalZero /*lint ++flb "Enter library region" */
32*150812a8SEvalZero 
33*150812a8SEvalZero 
34*150812a8SEvalZero #define __SYSTEM_CLOCK      (64000000UL)     /*!< nRF9160 Application core uses a fixed System Clock Frequency of 64MHz */
35*150812a8SEvalZero 
36*150812a8SEvalZero 
37*150812a8SEvalZero #if defined ( __CC_ARM )
38*150812a8SEvalZero     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK;
39*150812a8SEvalZero #elif defined ( __ICCARM__ )
40*150812a8SEvalZero     __root uint32_t SystemCoreClock = __SYSTEM_CLOCK;
41*150812a8SEvalZero #elif defined ( __GNUC__ )
42*150812a8SEvalZero     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK;
43*150812a8SEvalZero #endif
44*150812a8SEvalZero 
45*150812a8SEvalZero /* Errata are only handled in secure mode since they usually need access to FICR. */
46*150812a8SEvalZero #if !defined(NRF_TRUSTZONE_NONSECURE)
47*150812a8SEvalZero     static bool errata_6(void);
48*150812a8SEvalZero     static bool errata_14(void);
49*150812a8SEvalZero     static bool errata_15(void);
50*150812a8SEvalZero #endif
51*150812a8SEvalZero 
SystemCoreClockUpdate(void)52*150812a8SEvalZero void SystemCoreClockUpdate(void)
53*150812a8SEvalZero {
54*150812a8SEvalZero     SystemCoreClock = __SYSTEM_CLOCK;
55*150812a8SEvalZero }
56*150812a8SEvalZero 
SystemInit(void)57*150812a8SEvalZero void SystemInit(void)
58*150812a8SEvalZero {
59*150812a8SEvalZero     #if !defined(NRF_TRUSTZONE_NONSECURE)
60*150812a8SEvalZero         /* Perform Secure-mode initialization routines. */
61*150812a8SEvalZero 
62*150812a8SEvalZero         /* Set all ARM SAU regions to NonSecure if TrustZone extensions are enabled.
63*150812a8SEvalZero         * Nordic SPU should handle Secure Attribution tasks */
64*150812a8SEvalZero         #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
65*150812a8SEvalZero           SAU->CTRL |= (1 << SAU_CTRL_ALLNS_Pos);
66*150812a8SEvalZero         #endif
67*150812a8SEvalZero 
68*150812a8SEvalZero         /* Trimming of the device. Copy all the trimming values from FICR into the target addresses. Trim
69*150812a8SEvalZero          until one ADDR is not initialized. */
70*150812a8SEvalZero         uint32_t index = 0;
71*150812a8SEvalZero         for (index = 0; index < 256ul && NRF_FICR_S->TRIMCNF[index].ADDR != 0xFFFFFFFFul; index++){
72*150812a8SEvalZero           #if defined ( __ICCARM__ )
73*150812a8SEvalZero               #pragma diag_suppress=Pa082
74*150812a8SEvalZero           #endif
75*150812a8SEvalZero           *(volatile uint32_t *)NRF_FICR_S->TRIMCNF[index].ADDR = NRF_FICR_S->TRIMCNF[index].DATA;
76*150812a8SEvalZero           #if defined ( __ICCARM__ )
77*150812a8SEvalZero               #pragma diag_default=Pa082
78*150812a8SEvalZero           #endif
79*150812a8SEvalZero         }
80*150812a8SEvalZero 
81*150812a8SEvalZero         /* Make sure UICR->HFXOSRC is set */
82*150812a8SEvalZero         if ((NRF_UICR_S->HFXOSRC & UICR_HFXOSRC_HFXOSRC_Msk) != UICR_HFXOSRC_HFXOSRC_TCXO) {
83*150812a8SEvalZero           /* Wait for pending NVMC operations to finish */
84*150812a8SEvalZero           while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
85*150812a8SEvalZero 
86*150812a8SEvalZero           /* Enable write mode in NVMC */
87*150812a8SEvalZero           NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Wen;
88*150812a8SEvalZero           while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
89*150812a8SEvalZero 
90*150812a8SEvalZero           /* Write new value to UICR->HFXOSRC */
91*150812a8SEvalZero           NRF_UICR_S->HFXOSRC = (NRF_UICR_S->HFXOSRC & ~UICR_HFXOSRC_HFXOSRC_Msk) | UICR_HFXOSRC_HFXOSRC_TCXO;
92*150812a8SEvalZero           while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
93*150812a8SEvalZero 
94*150812a8SEvalZero           /* Enable read mode in NVMC */
95*150812a8SEvalZero           NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Ren;
96*150812a8SEvalZero           while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
97*150812a8SEvalZero 
98*150812a8SEvalZero           /* Reset to apply clock select update */
99*150812a8SEvalZero           NVIC_SystemReset();
100*150812a8SEvalZero         }
101*150812a8SEvalZero 
102*150812a8SEvalZero         if (errata_6()){
103*150812a8SEvalZero             NRF_POWER_S->EVENTS_SLEEPENTER = (POWER_EVENTS_SLEEPENTER_EVENTS_SLEEPENTER_NotGenerated << POWER_EVENTS_SLEEPENTER_EVENTS_SLEEPENTER_Pos);
104*150812a8SEvalZero             NRF_POWER_S->EVENTS_SLEEPEXIT = (POWER_EVENTS_SLEEPEXIT_EVENTS_SLEEPEXIT_NotGenerated << POWER_EVENTS_SLEEPEXIT_EVENTS_SLEEPEXIT_Pos);
105*150812a8SEvalZero         }
106*150812a8SEvalZero 
107*150812a8SEvalZero         if (errata_14()){
108*150812a8SEvalZero             *(uint32_t *)0x50004A38 = 0x01ul;
109*150812a8SEvalZero             NRF_REGULATORS_S->DCDCEN = REGULATORS_DCDCEN_DCDCEN_Enabled << REGULATORS_DCDCEN_DCDCEN_Pos;
110*150812a8SEvalZero         }
111*150812a8SEvalZero 
112*150812a8SEvalZero         if (errata_15()){
113*150812a8SEvalZero             *(uint32_t *)0x50004A38 = 0x00ul;
114*150812a8SEvalZero             NRF_REGULATORS_S->DCDCEN = REGULATORS_DCDCEN_DCDCEN_Enabled << REGULATORS_DCDCEN_DCDCEN_Pos;
115*150812a8SEvalZero         }
116*150812a8SEvalZero 
117*150812a8SEvalZero         /* Allow Non-Secure code to run FPU instructions.
118*150812a8SEvalZero          * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */
119*150812a8SEvalZero         SCB->NSACR |= (3UL << 10);
120*150812a8SEvalZero     #endif
121*150812a8SEvalZero 
122*150812a8SEvalZero     /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
123*150812a8SEvalZero     * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
124*150812a8SEvalZero     * operations are not used in your code. */
125*150812a8SEvalZero     #if (__FPU_USED == 1)
126*150812a8SEvalZero       SCB->CPACR |= (3UL << 20) | (3UL << 22);
127*150812a8SEvalZero       __DSB();
128*150812a8SEvalZero       __ISB();
129*150812a8SEvalZero     #endif
130*150812a8SEvalZero 
131*150812a8SEvalZero     SystemCoreClockUpdate();
132*150812a8SEvalZero }
133*150812a8SEvalZero 
134*150812a8SEvalZero 
135*150812a8SEvalZero #if !defined(NRF_TRUSTZONE_NONSECURE)
errata_6()136*150812a8SEvalZero     bool errata_6()
137*150812a8SEvalZero     {
138*150812a8SEvalZero         if (*(uint32_t *)0x00FF0130 == 0x9ul){
139*150812a8SEvalZero             if (*(uint32_t *)0x00FF0134 == 0x01ul){
140*150812a8SEvalZero                 return true;
141*150812a8SEvalZero             }
142*150812a8SEvalZero             if (*(uint32_t *)0x00FF0134 == 0x02ul){
143*150812a8SEvalZero                 return true;
144*150812a8SEvalZero             }
145*150812a8SEvalZero         }
146*150812a8SEvalZero 
147*150812a8SEvalZero         return false;
148*150812a8SEvalZero     }
149*150812a8SEvalZero 
150*150812a8SEvalZero 
errata_14()151*150812a8SEvalZero     bool errata_14()
152*150812a8SEvalZero     {
153*150812a8SEvalZero         if (*(uint32_t *)0x00FF0130 == 0x9ul){
154*150812a8SEvalZero             if (*(uint32_t *)0x00FF0134 == 0x01ul){
155*150812a8SEvalZero                 return true;
156*150812a8SEvalZero             }
157*150812a8SEvalZero         }
158*150812a8SEvalZero 
159*150812a8SEvalZero         return false;
160*150812a8SEvalZero     }
161*150812a8SEvalZero 
162*150812a8SEvalZero 
errata_15()163*150812a8SEvalZero     bool errata_15()
164*150812a8SEvalZero     {
165*150812a8SEvalZero         if (*(uint32_t *)0x00FF0130 == 0x9ul){
166*150812a8SEvalZero             if (*(uint32_t *)0x00FF0134 == 0x02ul){
167*150812a8SEvalZero                 return true;
168*150812a8SEvalZero             }
169*150812a8SEvalZero         }
170*150812a8SEvalZero 
171*150812a8SEvalZero         return false;
172*150812a8SEvalZero     }
173*150812a8SEvalZero #endif
174*150812a8SEvalZero 
175*150812a8SEvalZero /*lint --flb "Leave library region" */
176