xref: /nrf52832-nimble/nordic/nrfx/mdk/system_nrf51.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_nrf51.h"
30*150812a8SEvalZero 
31*150812a8SEvalZero /*lint ++flb "Enter library region" */
32*150812a8SEvalZero 
33*150812a8SEvalZero 
34*150812a8SEvalZero #define __SYSTEM_CLOCK      (16000000UL)     /*!< nRF51 devices use a fixed System Clock Frequency of 16MHz */
35*150812a8SEvalZero 
36*150812a8SEvalZero static bool is_manual_peripheral_setup_needed(void);
37*150812a8SEvalZero static bool is_disabled_in_debug_needed(void);
38*150812a8SEvalZero static bool is_peripheral_domain_setup_needed(void);
39*150812a8SEvalZero 
40*150812a8SEvalZero 
41*150812a8SEvalZero #if defined ( __CC_ARM )
42*150812a8SEvalZero     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK;
43*150812a8SEvalZero #elif defined ( __ICCARM__ )
44*150812a8SEvalZero     __root uint32_t SystemCoreClock = __SYSTEM_CLOCK;
45*150812a8SEvalZero #elif defined   ( __GNUC__ )
46*150812a8SEvalZero     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK;
47*150812a8SEvalZero #endif
48*150812a8SEvalZero 
SystemCoreClockUpdate(void)49*150812a8SEvalZero void SystemCoreClockUpdate(void)
50*150812a8SEvalZero {
51*150812a8SEvalZero     SystemCoreClock = __SYSTEM_CLOCK;
52*150812a8SEvalZero }
53*150812a8SEvalZero 
SystemInit(void)54*150812a8SEvalZero void SystemInit(void)
55*150812a8SEvalZero {
56*150812a8SEvalZero     /* If desired, switch off the unused RAM to lower consumption by the use of RAMON register.
57*150812a8SEvalZero        It can also be done in the application main() function. */
58*150812a8SEvalZero 
59*150812a8SEvalZero     /* Prepare the peripherals for use as indicated by the PAN 26 "System: Manual setup is required
60*150812a8SEvalZero        to enable the use of peripherals" found at Product Anomaly document for your device found at
61*150812a8SEvalZero        https://www.nordicsemi.com/. The side effect of executing these instructions in the devices
62*150812a8SEvalZero        that do not need it is that the new peripherals in the second generation devices (LPCOMP for
63*150812a8SEvalZero        example) will not be available. */
64*150812a8SEvalZero     if (is_manual_peripheral_setup_needed())
65*150812a8SEvalZero     {
66*150812a8SEvalZero         *(uint32_t volatile *)0x40000504 = 0xC007FFDF;
67*150812a8SEvalZero         *(uint32_t volatile *)0x40006C18 = 0x00008000;
68*150812a8SEvalZero     }
69*150812a8SEvalZero 
70*150812a8SEvalZero     /* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG
71*150812a8SEvalZero        register is incorrect" found at Product Anomaly document for your device found at
72*150812a8SEvalZero        https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */
73*150812a8SEvalZero     if (is_disabled_in_debug_needed())
74*150812a8SEvalZero     {
75*150812a8SEvalZero         NRF_MPU->DISABLEINDEBUG = MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos;
76*150812a8SEvalZero     }
77*150812a8SEvalZero 
78*150812a8SEvalZero     /* Execute the following code to eliminate excessive current in sleep mode with RAM retention in nRF51802 devices,
79*150812a8SEvalZero        as indicated by PAN 76 "System: Excessive current in sleep mode with retention" found at Product Anomaly document
80*150812a8SEvalZero        for your device found at https://www.nordicsemi.com/. */
81*150812a8SEvalZero     if (is_peripheral_domain_setup_needed()){
82*150812a8SEvalZero         if (*(uint32_t volatile *)0x4006EC00 != 1){
83*150812a8SEvalZero             *(uint32_t volatile *)0x4006EC00 = 0x9375;
84*150812a8SEvalZero             while (*(uint32_t volatile *)0x4006EC00 != 1){
85*150812a8SEvalZero             }
86*150812a8SEvalZero         }
87*150812a8SEvalZero         *(uint32_t volatile *)0x4006EC14 = 0xC0;
88*150812a8SEvalZero     }
89*150812a8SEvalZero }
90*150812a8SEvalZero 
91*150812a8SEvalZero 
is_manual_peripheral_setup_needed(void)92*150812a8SEvalZero static bool is_manual_peripheral_setup_needed(void)
93*150812a8SEvalZero {
94*150812a8SEvalZero     if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
95*150812a8SEvalZero     {
96*150812a8SEvalZero         if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x00) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
97*150812a8SEvalZero         {
98*150812a8SEvalZero             return true;
99*150812a8SEvalZero         }
100*150812a8SEvalZero         if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x10) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
101*150812a8SEvalZero         {
102*150812a8SEvalZero             return true;
103*150812a8SEvalZero         }
104*150812a8SEvalZero         if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
105*150812a8SEvalZero         {
106*150812a8SEvalZero             return true;
107*150812a8SEvalZero         }
108*150812a8SEvalZero     }
109*150812a8SEvalZero 
110*150812a8SEvalZero     return false;
111*150812a8SEvalZero }
112*150812a8SEvalZero 
is_disabled_in_debug_needed(void)113*150812a8SEvalZero static bool is_disabled_in_debug_needed(void)
114*150812a8SEvalZero {
115*150812a8SEvalZero     if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
116*150812a8SEvalZero     {
117*150812a8SEvalZero         if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
118*150812a8SEvalZero         {
119*150812a8SEvalZero             return true;
120*150812a8SEvalZero         }
121*150812a8SEvalZero     }
122*150812a8SEvalZero 
123*150812a8SEvalZero     return false;
124*150812a8SEvalZero }
125*150812a8SEvalZero 
is_peripheral_domain_setup_needed(void)126*150812a8SEvalZero static bool is_peripheral_domain_setup_needed(void)
127*150812a8SEvalZero {
128*150812a8SEvalZero     if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
129*150812a8SEvalZero     {
130*150812a8SEvalZero         if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xA0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
131*150812a8SEvalZero         {
132*150812a8SEvalZero             return true;
133*150812a8SEvalZero         }
134*150812a8SEvalZero         if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xD0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
135*150812a8SEvalZero         {
136*150812a8SEvalZero             return true;
137*150812a8SEvalZero         }
138*150812a8SEvalZero     }
139*150812a8SEvalZero 
140*150812a8SEvalZero     return false;
141*150812a8SEvalZero }
142*150812a8SEvalZero 
143*150812a8SEvalZero /*lint --flb "Leave library region" */
144