system_nrf9160.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. Copyright (c) 2009-2020 ARM Limited. All rights reserved.
  3. SPDX-License-Identifier: Apache-2.0
  4. Licensed under the Apache License, Version 2.0 (the License); you may
  5. not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an AS IS BASIS, WITHOUT
  10. WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. NOTICE: This file has been modified by Nordic Semiconductor ASA.
  14. */
  15. /* NOTE: Template files (including this one) are application specific and therefore expected to
  16. be copied into the application project folder prior to its use! */
  17. #include <stdint.h>
  18. #include <stdbool.h>
  19. #include "nrf.h"
  20. #include "nrf_erratas.h"
  21. #include "system_nrf9160.h"
  22. /*lint ++flb "Enter library region" */
  23. #define __SYSTEM_CLOCK (64000000UL) /*!< nRF9160 Application core uses a fixed System Clock Frequency of 64MHz */
  24. #define TRACE_PIN_CNF_VALUE ( (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | \
  25. (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | \
  26. (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | \
  27. (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | \
  28. (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) )
  29. #define TRACE_TRACECLK_PIN (21)
  30. #define TRACE_TRACEDATA0_PIN (22)
  31. #define TRACE_TRACEDATA1_PIN (23)
  32. #define TRACE_TRACEDATA2_PIN (24)
  33. #define TRACE_TRACEDATA3_PIN (25)
  34. #if defined ( __CC_ARM )
  35. uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK;
  36. #elif defined ( __ICCARM__ )
  37. __root uint32_t SystemCoreClock = __SYSTEM_CLOCK;
  38. #elif defined ( __GNUC__ )
  39. uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK;
  40. #endif
  41. /* Global values used used in Secure mode SystemInit. */
  42. #if !defined(NRF_TRUSTZONE_NONSECURE)
  43. /* Global values used by UICR erase fix algorithm. */
  44. static uint32_t uicr_erased_value;
  45. static uint32_t uicr_new_value;
  46. #endif
  47. /* Errata are only handled in secure mode since they usually need access to FICR. */
  48. #if !defined(NRF_TRUSTZONE_NONSECURE)
  49. static bool uicr_HFXOSRC_erased(void);
  50. static bool uicr_HFXOCNT_erased(void);
  51. #endif
  52. void SystemCoreClockUpdate(void)
  53. {
  54. SystemCoreClock = __SYSTEM_CLOCK;
  55. }
  56. void SystemInit(void)
  57. {
  58. #if !defined(NRF_TRUSTZONE_NONSECURE)
  59. /* Perform Secure-mode initialization routines. */
  60. /* Set all ARM SAU regions to NonSecure if TrustZone extensions are enabled.
  61. * Nordic SPU should handle Secure Attribution tasks */
  62. #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
  63. SAU->CTRL |= (1 << SAU_CTRL_ALLNS_Pos);
  64. #endif
  65. /* Workaround for Errata 6 "POWER: SLEEPENTER and SLEEPEXIT events asserted after pin reset" found at the Errata document
  66. for your device located at https://infocenter.nordicsemi.com/index.jsp */
  67. if (nrf91_errata_6()){
  68. NRF_POWER_S->EVENTS_SLEEPENTER = (POWER_EVENTS_SLEEPENTER_EVENTS_SLEEPENTER_NotGenerated << POWER_EVENTS_SLEEPENTER_EVENTS_SLEEPENTER_Pos);
  69. NRF_POWER_S->EVENTS_SLEEPEXIT = (POWER_EVENTS_SLEEPEXIT_EVENTS_SLEEPEXIT_NotGenerated << POWER_EVENTS_SLEEPEXIT_EVENTS_SLEEPEXIT_Pos);
  70. }
  71. /* Workaround for Errata 14 "REGULATORS: LDO mode at startup" found at the Errata document
  72. for your device located at https://infocenter.nordicsemi.com/index.jsp */
  73. if (nrf91_errata_14()){
  74. *((volatile uint32_t *)0x50004A38) = 0x01ul;
  75. NRF_REGULATORS_S->DCDCEN = REGULATORS_DCDCEN_DCDCEN_Enabled << REGULATORS_DCDCEN_DCDCEN_Pos;
  76. }
  77. /* Workaround for Errata 15 "REGULATORS: LDO mode at startup" found at the Errata document
  78. for your device located at https://infocenter.nordicsemi.com/index.jsp */
  79. if (nrf91_errata_15()){
  80. NRF_REGULATORS_S->DCDCEN = REGULATORS_DCDCEN_DCDCEN_Enabled << REGULATORS_DCDCEN_DCDCEN_Pos;
  81. }
  82. /* Workaround for Errata 20 "RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document
  83. for your device located at https://infocenter.nordicsemi.com/index.jsp */
  84. if (nrf91_errata_20()){
  85. *((volatile uint32_t *)0x5003AEE4) = 0xE;
  86. }
  87. /* Workaround for Errata 31 "XOSC32k Startup Failure" found at the Errata document
  88. for your device located at https://infocenter.nordicsemi.com/index.jsp */
  89. if (nrf91_errata_31()){
  90. *((volatile uint32_t *)0x5000470Cul) = 0x0;
  91. *((volatile uint32_t *)0x50004710ul) = 0x1;
  92. }
  93. /* Trimming of the device. Copy all the trimming values from FICR into the target addresses. Trim
  94. until one ADDR is not initialized. */
  95. uint32_t index = 0;
  96. for (index = 0; index < 256ul && NRF_FICR_S->TRIMCNF[index].ADDR != 0xFFFFFFFFul; index++){
  97. #if defined ( __ICCARM__ )
  98. #pragma diag_suppress=Pa082
  99. #endif
  100. *(volatile uint32_t *)NRF_FICR_S->TRIMCNF[index].ADDR = NRF_FICR_S->TRIMCNF[index].DATA;
  101. #if defined ( __ICCARM__ )
  102. #pragma diag_default=Pa082
  103. #endif
  104. }
  105. /* Set UICR->HFXOSRC and UICR->HFXOCNT to working defaults if UICR was erased */
  106. if (uicr_HFXOSRC_erased() || uicr_HFXOCNT_erased()) {
  107. /* Wait for pending NVMC operations to finish */
  108. while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
  109. /* Enable write mode in NVMC */
  110. NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Wen;
  111. while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
  112. if (uicr_HFXOSRC_erased()){
  113. /* Write default value to UICR->HFXOSRC */
  114. uicr_erased_value = NRF_UICR_S->HFXOSRC;
  115. uicr_new_value = (uicr_erased_value & ~UICR_HFXOSRC_HFXOSRC_Msk) | UICR_HFXOSRC_HFXOSRC_TCXO;
  116. NRF_UICR_S->HFXOSRC = uicr_new_value;
  117. while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
  118. }
  119. if (uicr_HFXOCNT_erased()){
  120. /* Write default value to UICR->HFXOCNT */
  121. uicr_erased_value = NRF_UICR_S->HFXOCNT;
  122. uicr_new_value = (uicr_erased_value & ~UICR_HFXOCNT_HFXOCNT_Msk) | 0x20;
  123. NRF_UICR_S->HFXOCNT = uicr_new_value;
  124. while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
  125. }
  126. /* Enable read mode in NVMC */
  127. NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Ren;
  128. while (NRF_NVMC_S->READY != NVMC_READY_READY_Ready);
  129. /* Reset to apply clock select update */
  130. NVIC_SystemReset();
  131. }
  132. /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
  133. Specification to see which ones). */
  134. #if defined (ENABLE_TRACE)
  135. // Enable Trace And Debug peripheral
  136. NRF_TAD_S->ENABLE = TAD_ENABLE_ENABLE_Msk;
  137. NRF_TAD_S->CLOCKSTART = TAD_CLOCKSTART_START_Msk;
  138. // Set up Trace pads SPU firewall
  139. NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACECLK_PIN);
  140. NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA0_PIN);
  141. NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA1_PIN);
  142. NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA2_PIN);
  143. NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA3_PIN);
  144. // Configure trace port pads
  145. NRF_P0_S->PIN_CNF[TRACE_TRACECLK_PIN] = TRACE_PIN_CNF_VALUE;
  146. NRF_P0_S->PIN_CNF[TRACE_TRACEDATA0_PIN] = TRACE_PIN_CNF_VALUE;
  147. NRF_P0_S->PIN_CNF[TRACE_TRACEDATA1_PIN] = TRACE_PIN_CNF_VALUE;
  148. NRF_P0_S->PIN_CNF[TRACE_TRACEDATA2_PIN] = TRACE_PIN_CNF_VALUE;
  149. NRF_P0_S->PIN_CNF[TRACE_TRACEDATA3_PIN] = TRACE_PIN_CNF_VALUE;
  150. // Select trace pins
  151. NRF_TAD_S->PSEL.TRACECLK = TRACE_TRACECLK_PIN;
  152. NRF_TAD_S->PSEL.TRACEDATA0 = TRACE_TRACEDATA0_PIN;
  153. NRF_TAD_S->PSEL.TRACEDATA1 = TRACE_TRACEDATA1_PIN;
  154. NRF_TAD_S->PSEL.TRACEDATA2 = TRACE_TRACEDATA2_PIN;
  155. NRF_TAD_S->PSEL.TRACEDATA3 = TRACE_TRACEDATA3_PIN;
  156. // Set trace port speed to 32 MHz
  157. NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_32MHz;
  158. *((uint32_t *)(0xE0053000ul)) = 0x00000001ul;
  159. *((uint32_t *)(0xE005AFB0ul)) = 0xC5ACCE55ul;
  160. *((uint32_t *)(0xE005A000ul)) &= 0xFFFFFF00ul;
  161. *((uint32_t *)(0xE005A004ul)) = 0x00000009ul;
  162. *((uint32_t *)(0xE005A000ul)) = 0x00000303ul;
  163. *((uint32_t *)(0xE005AFB0ul)) = 0x00000000ul;
  164. *((uint32_t *)(0xE005BFB0ul)) = 0xC5ACCE55ul;
  165. *((uint32_t *)(0xE005B000ul)) &= 0xFFFFFF00ul;
  166. *((uint32_t *)(0xE005B004ul)) = 0x00003000ul;
  167. *((uint32_t *)(0xE005B000ul)) = 0x00000308ul;
  168. *((uint32_t *)(0xE005BFB0ul)) = 0x00000000ul;
  169. *((uint32_t *)(0xE0058FB0ul)) = 0xC5ACCE55ul;
  170. *((uint32_t *)(0xE0058000ul)) = 0x00000000ul;
  171. *((uint32_t *)(0xE0058004ul)) = 0x00000000ul;
  172. *((uint32_t *)(0xE0058FB0ul)) = 0x00000000ul;
  173. /* Rom table does not list ETB, or TPIU base addresses.
  174. * Some debug probes may require manual configuration of these peripherals to enable tracing.
  175. * ETB_BASE = 0xE0051000
  176. * TPIU_BASE = 0xE0054000
  177. */
  178. #endif
  179. /* Allow Non-Secure code to run FPU instructions.
  180. * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */
  181. SCB->NSACR |= (3UL << 10);
  182. #endif
  183. /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
  184. * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
  185. * operations are not used in your code. */
  186. #if (__FPU_USED == 1)
  187. SCB->CPACR |= (3UL << 20) | (3UL << 22);
  188. __DSB();
  189. __ISB();
  190. #endif
  191. SystemCoreClockUpdate();
  192. }
  193. #if !defined(NRF_TRUSTZONE_NONSECURE)
  194. bool uicr_HFXOCNT_erased()
  195. {
  196. if (NRF_UICR_S->HFXOCNT == 0xFFFFFFFFul) {
  197. return true;
  198. }
  199. return false;
  200. }
  201. bool uicr_HFXOSRC_erased()
  202. {
  203. if ((NRF_UICR_S->HFXOSRC & UICR_HFXOSRC_HFXOSRC_Msk) != UICR_HFXOSRC_HFXOSRC_TCXO) {
  204. return true;
  205. }
  206. return false;
  207. }
  208. #endif
  209. /*lint --flb "Leave library region" */